cache.c 4.1 KB

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