cache_llc.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * Copyright (C) 2018 Marvell International Ltd.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. * https://spdx.org/licenses
  6. */
  7. /* LLC driver is the Last Level Cache (L3C) driver
  8. * for Marvell SoCs in AP806, AP807, and AP810
  9. */
  10. #include <assert.h>
  11. #include <arch_helpers.h>
  12. #include <drivers/marvell/cache_llc.h>
  13. #include <drivers/marvell/ccu.h>
  14. #include <lib/mmio.h>
  15. #include <mvebu_def.h>
  16. #define CCU_HTC_CR(ap_index) (MVEBU_CCU_BASE(ap_index) + 0x200)
  17. #define CCU_SET_POC_OFFSET 5
  18. extern void ca72_l2_enable_unique_clean(void);
  19. void llc_cache_sync(int ap_index)
  20. {
  21. mmio_write_32(LLC_SYNC(ap_index), 0);
  22. /* Atomic write, no need to wait */
  23. }
  24. void llc_flush_all(int ap_index)
  25. {
  26. mmio_write_32(LLC_CLEAN_INV_WAY(ap_index), LLC_ALL_WAYS_MASK);
  27. llc_cache_sync(ap_index);
  28. }
  29. void llc_clean_all(int ap_index)
  30. {
  31. mmio_write_32(LLC_CLEAN_WAY(ap_index), LLC_ALL_WAYS_MASK);
  32. llc_cache_sync(ap_index);
  33. }
  34. void llc_inv_all(int ap_index)
  35. {
  36. mmio_write_32(LLC_INV_WAY(ap_index), LLC_ALL_WAYS_MASK);
  37. llc_cache_sync(ap_index);
  38. }
  39. void llc_disable(int ap_index)
  40. {
  41. llc_flush_all(ap_index);
  42. mmio_write_32(LLC_CTRL(ap_index), 0);
  43. dsbishst();
  44. }
  45. void llc_enable(int ap_index, int excl_mode)
  46. {
  47. uint32_t val;
  48. dsbsy();
  49. llc_inv_all(ap_index);
  50. dsbsy();
  51. val = LLC_CTRL_EN;
  52. if (excl_mode)
  53. val |= LLC_EXCLUSIVE_EN;
  54. mmio_write_32(LLC_CTRL(ap_index), val);
  55. dsbsy();
  56. }
  57. int llc_is_exclusive(int ap_index)
  58. {
  59. uint32_t reg;
  60. reg = mmio_read_32(LLC_CTRL(ap_index));
  61. if ((reg & (LLC_CTRL_EN | LLC_EXCLUSIVE_EN)) ==
  62. (LLC_CTRL_EN | LLC_EXCLUSIVE_EN))
  63. return 1;
  64. return 0;
  65. }
  66. void llc_runtime_enable(int ap_index)
  67. {
  68. uint32_t reg;
  69. reg = mmio_read_32(LLC_CTRL(ap_index));
  70. if (reg & LLC_CTRL_EN)
  71. return;
  72. INFO("Enabling LLC\n");
  73. /*
  74. * Enable L2 UniqueClean evictions with data
  75. * Note: this configuration assumes that LLC is configured
  76. * in exclusive mode.
  77. * Later on in the code this assumption will be validated
  78. */
  79. ca72_l2_enable_unique_clean();
  80. llc_enable(ap_index, 1);
  81. /* Set point of coherency to DDR.
  82. * This is required by units which have SW cache coherency
  83. */
  84. reg = mmio_read_32(CCU_HTC_CR(ap_index));
  85. reg |= (0x1 << CCU_SET_POC_OFFSET);
  86. mmio_write_32(CCU_HTC_CR(ap_index), reg);
  87. }
  88. #if LLC_SRAM
  89. int llc_sram_enable(int ap_index, int size)
  90. {
  91. uint32_t tc, way, ways_to_allocate;
  92. uint32_t way_addr;
  93. if ((size <= 0) || (size > LLC_SIZE) || (size % LLC_WAY_SIZE))
  94. return -1;
  95. llc_enable(ap_index, 1);
  96. llc_inv_all(ap_index);
  97. ways_to_allocate = size / LLC_WAY_SIZE;
  98. /* Lockdown all available ways for all traffic classes */
  99. for (tc = 0; tc < LLC_TC_NUM; tc++)
  100. mmio_write_32(LLC_TCN_LOCK(ap_index, tc), LLC_ALL_WAYS_MASK);
  101. /* Clear the high bits of SRAM address */
  102. mmio_write_32(LLC_BANKED_MNT_AHR(ap_index), 0);
  103. way_addr = PLAT_MARVELL_TRUSTED_RAM_BASE;
  104. for (way = 0; way < ways_to_allocate; way++) {
  105. /* Trigger allocation block command */
  106. mmio_write_32(LLC_BLK_ALOC(ap_index),
  107. LLC_BLK_ALOC_BASE_ADDR(way_addr) |
  108. LLC_BLK_ALOC_WAY_DATA_SET |
  109. LLC_BLK_ALOC_WAY_ID(way));
  110. way_addr += LLC_WAY_SIZE;
  111. }
  112. return 0;
  113. }
  114. void llc_sram_disable(int ap_index)
  115. {
  116. uint32_t tc;
  117. /* Disable the line lockings */
  118. for (tc = 0; tc < LLC_TC_NUM; tc++)
  119. mmio_write_32(LLC_TCN_LOCK(ap_index, tc), 0);
  120. /* Invalidate all ways */
  121. llc_inv_all(ap_index);
  122. }
  123. int llc_sram_test(int ap_index, int size, char *msg)
  124. {
  125. uintptr_t addr, end_addr;
  126. uint32_t data = 0;
  127. if ((size <= 0) || (size > LLC_SIZE))
  128. return -1;
  129. INFO("=== LLC SRAM WRITE test %s\n", msg);
  130. for (addr = PLAT_MARVELL_TRUSTED_RAM_BASE,
  131. end_addr = PLAT_MARVELL_TRUSTED_RAM_BASE + size;
  132. addr < end_addr; addr += 4) {
  133. mmio_write_32(addr, addr);
  134. }
  135. INFO("=== LLC SRAM WRITE test %s PASSED\n", msg);
  136. INFO("=== LLC SRAM READ test %s\n", msg);
  137. for (addr = PLAT_MARVELL_TRUSTED_RAM_BASE,
  138. end_addr = PLAT_MARVELL_TRUSTED_RAM_BASE + size;
  139. addr < end_addr; addr += 4) {
  140. data = mmio_read_32(addr);
  141. if (data != addr) {
  142. INFO("=== LLC SRAM READ test %s FAILED @ 0x%08lx)\n",
  143. msg, addr);
  144. return -1;
  145. }
  146. }
  147. INFO("=== LLC SRAM READ test %s PASSED (last read = 0x%08x)\n",
  148. msg, data);
  149. return 0;
  150. }
  151. #endif /* LLC_SRAM */