cache.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * (C) Copyright 2011, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
  3. * (C) Copyright 2011, Julius Baxter <julius@opencores.org>
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <common.h>
  8. #include <asm/system.h>
  9. void flush_dcache_range(unsigned long addr, unsigned long stop)
  10. {
  11. ulong block_size = (mfspr(SPR_DCCFGR) & SPR_DCCFGR_CBS) ? 32 : 16;
  12. while (addr < stop) {
  13. mtspr(SPR_DCBFR, addr);
  14. addr += block_size;
  15. }
  16. }
  17. void invalidate_dcache_range(unsigned long addr, unsigned long stop)
  18. {
  19. ulong block_size = (mfspr(SPR_DCCFGR) & SPR_DCCFGR_CBS) ? 32 : 16;
  20. while (addr < stop) {
  21. mtspr(SPR_DCBIR, addr);
  22. addr += block_size;
  23. }
  24. }
  25. static void invalidate_icache_range(unsigned long addr, unsigned long stop)
  26. {
  27. ulong block_size = (mfspr(SPR_ICCFGR) & SPR_ICCFGR_CBS) ? 32 : 16;
  28. while (addr < stop) {
  29. mtspr(SPR_ICBIR, addr);
  30. addr += block_size;
  31. }
  32. }
  33. void flush_cache(unsigned long addr, unsigned long size)
  34. {
  35. flush_dcache_range(addr, addr + size);
  36. invalidate_icache_range(addr, addr + size);
  37. }
  38. int icache_status(void)
  39. {
  40. return mfspr(SPR_SR) & SPR_SR_ICE;
  41. }
  42. int checkicache(void)
  43. {
  44. unsigned long iccfgr;
  45. unsigned long cache_set_size;
  46. unsigned long cache_ways;
  47. unsigned long cache_block_size;
  48. iccfgr = mfspr(SPR_ICCFGR);
  49. cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
  50. cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
  51. cache_block_size = (iccfgr & SPR_ICCFGR_CBS) ? 32 : 16;
  52. return cache_set_size * cache_ways * cache_block_size;
  53. }
  54. int dcache_status(void)
  55. {
  56. return mfspr(SPR_SR) & SPR_SR_DCE;
  57. }
  58. int checkdcache(void)
  59. {
  60. unsigned long dccfgr;
  61. unsigned long cache_set_size;
  62. unsigned long cache_ways;
  63. unsigned long cache_block_size;
  64. dccfgr = mfspr(SPR_DCCFGR);
  65. cache_ways = 1 << (dccfgr & SPR_DCCFGR_NCW);
  66. cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
  67. cache_block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16;
  68. return cache_set_size * cache_ways * cache_block_size;
  69. }
  70. void dcache_enable(void)
  71. {
  72. mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_DCE);
  73. asm volatile("l.nop");
  74. asm volatile("l.nop");
  75. asm volatile("l.nop");
  76. asm volatile("l.nop");
  77. asm volatile("l.nop");
  78. asm volatile("l.nop");
  79. asm volatile("l.nop");
  80. asm volatile("l.nop");
  81. }
  82. void dcache_disable(void)
  83. {
  84. mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_DCE);
  85. }
  86. void icache_enable(void)
  87. {
  88. mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_ICE);
  89. asm volatile("l.nop");
  90. asm volatile("l.nop");
  91. asm volatile("l.nop");
  92. asm volatile("l.nop");
  93. asm volatile("l.nop");
  94. asm volatile("l.nop");
  95. asm volatile("l.nop");
  96. asm volatile("l.nop");
  97. }
  98. void icache_disable(void)
  99. {
  100. mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_ICE);
  101. }
  102. int cache_init(void)
  103. {
  104. if (mfspr(SPR_UPR) & SPR_UPR_ICP) {
  105. icache_disable();
  106. invalidate_icache_range(0, checkicache());
  107. icache_enable();
  108. }
  109. if (mfspr(SPR_UPR) & SPR_UPR_DCP) {
  110. dcache_disable();
  111. invalidate_dcache_range(0, checkdcache());
  112. dcache_enable();
  113. }
  114. return 0;
  115. }