cache.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <config.h>
  7. #include <asm/arcregs.h>
  8. #include <asm/cache.h>
  9. /* Bit values in IC_CTRL */
  10. #define IC_CTRL_CACHE_DISABLE (1 << 0)
  11. /* Bit values in DC_CTRL */
  12. #define DC_CTRL_CACHE_DISABLE (1 << 0)
  13. #define DC_CTRL_INV_MODE_FLUSH (1 << 6)
  14. #define DC_CTRL_FLUSH_STATUS (1 << 8)
  15. #define CACHE_VER_NUM_MASK 0xF
  16. int icache_status(void)
  17. {
  18. /* If no cache in CPU exit immediately */
  19. if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK))
  20. return 0;
  21. return (read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE) !=
  22. IC_CTRL_CACHE_DISABLE;
  23. }
  24. void icache_enable(void)
  25. {
  26. /* If no cache in CPU exit immediately */
  27. if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK))
  28. return;
  29. write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) &
  30. ~IC_CTRL_CACHE_DISABLE);
  31. }
  32. void icache_disable(void)
  33. {
  34. /* If no cache in CPU exit immediately */
  35. if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK))
  36. return;
  37. write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) |
  38. IC_CTRL_CACHE_DISABLE);
  39. }
  40. void invalidate_icache_all(void)
  41. {
  42. /* If no cache in CPU exit immediately */
  43. if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK))
  44. return;
  45. /* Any write to IC_IVIC register triggers invalidation of entire I$ */
  46. write_aux_reg(ARC_AUX_IC_IVIC, 1);
  47. }
  48. int dcache_status(void)
  49. {
  50. /* If no cache in CPU exit immediately */
  51. if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK))
  52. return 0;
  53. return (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE) !=
  54. DC_CTRL_CACHE_DISABLE;
  55. }
  56. void dcache_enable(void)
  57. {
  58. /* If no cache in CPU exit immediately */
  59. if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK))
  60. return;
  61. write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) &
  62. ~(DC_CTRL_INV_MODE_FLUSH | DC_CTRL_CACHE_DISABLE));
  63. }
  64. void dcache_disable(void)
  65. {
  66. /* If no cache in CPU exit immediately */
  67. if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK))
  68. return;
  69. write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) |
  70. DC_CTRL_CACHE_DISABLE);
  71. }
  72. void flush_dcache_all(void)
  73. {
  74. /* If no cache in CPU exit immediately */
  75. if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK))
  76. return;
  77. /* Do flush of entire cache */
  78. write_aux_reg(ARC_AUX_DC_FLSH, 1);
  79. /* Wait flush end */
  80. while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS)
  81. ;
  82. }
  83. #ifndef CONFIG_SYS_DCACHE_OFF
  84. static void dcache_flush_line(unsigned addr)
  85. {
  86. #if (CONFIG_ARC_MMU_VER == 3)
  87. write_aux_reg(ARC_AUX_DC_PTAG, addr);
  88. #endif
  89. write_aux_reg(ARC_AUX_DC_FLDL, addr);
  90. /* Wait flush end */
  91. while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS)
  92. ;
  93. #ifndef CONFIG_SYS_ICACHE_OFF
  94. /*
  95. * Invalidate I$ for addresses range just flushed from D$.
  96. * If we try to execute data flushed above it will be valid/correct
  97. */
  98. #if (CONFIG_ARC_MMU_VER == 3)
  99. write_aux_reg(ARC_AUX_IC_PTAG, addr);
  100. #endif
  101. write_aux_reg(ARC_AUX_IC_IVIL, addr);
  102. #endif /* CONFIG_SYS_ICACHE_OFF */
  103. }
  104. #endif /* CONFIG_SYS_DCACHE_OFF */
  105. void flush_dcache_range(unsigned long start, unsigned long end)
  106. {
  107. #ifndef CONFIG_SYS_DCACHE_OFF
  108. unsigned int addr;
  109. start = start & (~(CONFIG_SYS_CACHELINE_SIZE - 1));
  110. end = end & (~(CONFIG_SYS_CACHELINE_SIZE - 1));
  111. for (addr = start; addr <= end; addr += CONFIG_SYS_CACHELINE_SIZE)
  112. dcache_flush_line(addr);
  113. #endif /* CONFIG_SYS_DCACHE_OFF */
  114. }
  115. void invalidate_dcache_range(unsigned long start, unsigned long end)
  116. {
  117. #ifndef CONFIG_SYS_DCACHE_OFF
  118. unsigned int addr;
  119. start = start & (~(CONFIG_SYS_CACHELINE_SIZE - 1));
  120. end = end & (~(CONFIG_SYS_CACHELINE_SIZE - 1));
  121. for (addr = start; addr <= end; addr += CONFIG_SYS_CACHELINE_SIZE) {
  122. #if (CONFIG_ARC_MMU_VER == 3)
  123. write_aux_reg(ARC_AUX_DC_PTAG, addr);
  124. #endif
  125. write_aux_reg(ARC_AUX_DC_IVDL, addr);
  126. }
  127. #endif /* CONFIG_SYS_DCACHE_OFF */
  128. }
  129. void invalidate_dcache_all(void)
  130. {
  131. /* If no cache in CPU exit immediately */
  132. if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK))
  133. return;
  134. /* Write 1 to DC_IVDC register triggers invalidation of entire D$ */
  135. write_aux_reg(ARC_AUX_DC_IVDC, 1);
  136. }
  137. void flush_cache(unsigned long start, unsigned long size)
  138. {
  139. flush_dcache_range(start, start + size);
  140. }