soc_memctrl.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * Copyright (c) 2019 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file memory controller interface
  8. */
  9. #include <kernel.h>
  10. #include <soc.h>
  11. #include "soc_memctrl.h"
  12. #define SOC_MEMCTRL_TEMP_MAP_CPU_ADDR 0x13800000
  13. void soc_memctrl_set_mapping(int idx, u32_t map_addr, u32_t nor_bus_addr)
  14. {
  15. u32_t bus_addr;
  16. if (idx >= CACHE_MAPPING_ITEM_NUM)
  17. return;
  18. bus_addr = soc_memctrl_cpu_addr_to_bus_addr(map_addr);
  19. /* default: mapping size: 32MB */
  20. sys_write32((bus_addr & ~0x3f) | 0x1f, SPI_CACHE_MAPPING_ADDR0 + idx * 8);
  21. /*set entry must afer mapping set*/
  22. sys_write32(nor_bus_addr, SPI_CACHE_ADDR0_ENTRY + idx * 8);
  23. }
  24. int soc_memctrl_item_is_free(int idx)
  25. {
  26. u32_t map_reg_val;
  27. map_reg_val = sys_read32(SPI_CACHE_MAPPING_ADDR0 + idx * 8);
  28. return (map_reg_val ? 0 : 1);
  29. }
  30. void soc_memctrl_cache_invalid(void)
  31. {
  32. sys_write32(1, SPICACHE_INVALIDATE);
  33. while ((sys_read32(SPICACHE_INVALIDATE) & 0x1) == 1)
  34. ;
  35. }
  36. int soc_memctrl_mapping(u32_t map_addr, u32_t nor_phy_addr, int enable_crc)
  37. {
  38. u32_t nor_bus_addr;
  39. int i;
  40. if (nor_phy_addr % 0x1000) {
  41. printk("invalid nor phy addr 0x%x\n", nor_phy_addr);
  42. return -EINVAL;
  43. }
  44. if (map_addr & (0x1ffff0)) {
  45. printk("invalid cpu addr 0x%x for mapping to 2MB, bit[4~20] must be 0\n", map_addr);
  46. return -EINVAL;
  47. }
  48. nor_bus_addr = nor_phy_addr;
  49. if (enable_crc) {
  50. nor_bus_addr |= (1 << 31);
  51. }
  52. for (i = CACHE_MAPPING_ITEM_NUM - 1; i >= 0; i--) {
  53. if (soc_memctrl_item_is_free(i)) {
  54. printk("slot=%d to map nor phy addr 0x%x, map=0x%x\n", i, nor_phy_addr, map_addr);
  55. soc_memctrl_set_mapping(i, map_addr, nor_bus_addr);
  56. soc_memctrl_cache_invalid();
  57. return 0;
  58. }
  59. }
  60. printk("cannot found slot to map nor phy addr 0x%x\n", nor_phy_addr);
  61. return -ENOENT;
  62. }
  63. int soc_memctrl_unmapping(u32_t map_addr)
  64. {
  65. u32_t bus_addr, map_reg_val;
  66. int i;
  67. bus_addr = soc_memctrl_cpu_addr_to_bus_addr(map_addr);
  68. for (i = CACHE_MAPPING_ITEM_NUM - 1; i >= 0; i--) {
  69. map_reg_val = sys_read32(SPI_CACHE_MAPPING_ADDR0 + i * 8);
  70. if (map_reg_val == 0)
  71. continue;
  72. if ((map_reg_val & ~0x3F) == bus_addr) {
  73. sys_write32(0x0, SPI_CACHE_ADDR0_ENTRY + i * 8);
  74. sys_write32(0x0, SPI_CACHE_MAPPING_ADDR0 + i * 8);
  75. soc_memctrl_cache_invalid();
  76. return 0;
  77. }
  78. }
  79. printk("cannot found slot to map cpu addr 0x%x\n", map_addr);
  80. return -ENOENT;
  81. }
  82. void *soc_memctrl_create_temp_mapping(u32_t nor_phy_addr, int enable_crc)
  83. {
  84. u32_t tmp_cpu_addr = SOC_MEMCTRL_TEMP_MAP_CPU_ADDR;
  85. int err;
  86. printk("%s: create temp mapping 0x%x, nor_phy_addr 0x%x, enable_crc %d\n", __func__,
  87. tmp_cpu_addr, nor_phy_addr, enable_crc);
  88. err = soc_memctrl_mapping(tmp_cpu_addr, nor_phy_addr, enable_crc);
  89. if (err < 0)
  90. return NULL;
  91. return (void *)tmp_cpu_addr;
  92. }
  93. void soc_memctrl_clear_temp_mapping(void *cpu_addr)
  94. {
  95. soc_memctrl_unmapping((u32_t)cpu_addr);
  96. }
  97. #if 0
  98. u32_t soc_memctrl_cpu_to_nor_phy_addr(u32_t cpu_addr)
  99. {
  100. u32_t map_reg_val, map_start_addr, map_end_addr;
  101. u32_t nor_reg_val, nor_addr, bus_addr, bus_offset;
  102. int i;
  103. bus_addr = soc_memctrl_cpu_addr_to_bus_addr(cpu_addr);
  104. for (i = 0; i < CACHE_MAPPING_ITEM_NUM; i++) {
  105. map_reg_val = sys_read32(MAPPING_ADDR0 + i * 8);
  106. if (map_reg_val == 0)
  107. continue;
  108. map_start_addr = map_reg_val & ~0xfffff;
  109. map_end_addr = map_start_addr + (((map_reg_val & 0xf) + 1) << 20);
  110. if (bus_addr >= map_start_addr && bus_addr < map_end_addr) {
  111. nor_reg_val = sys_read32(ADDR0_ENTRY + i * 8);
  112. bus_offset = bus_addr - map_start_addr;
  113. nor_addr = (nor_reg_val & 0xffffff) + bus_offset;
  114. if (nor_reg_val >> 31) {
  115. /* crc is enabled for this mapping */
  116. nor_addr = (nor_reg_val & 0xffffff) + (bus_offset / 32 * 34) + (bus_offset % 32);
  117. }
  118. return nor_addr;
  119. }
  120. }
  121. return -1;
  122. }
  123. __ramfunc void soc_memctrl_config_cache_size(int cache_size_mode)
  124. {
  125. if (cache_size_mode == CACHE_SIZE_16KB) {
  126. sys_write32(sys_read32(SPICACHE_CTL) | (1 << SPICACHE_CTL_CACHE_SIZE_MODE), SPICACHE_CTL);
  127. k_busy_wait(10);
  128. while (1) {
  129. if ((sys_read32(SPICACHE_CTL) & (1 << SPICACHE_CTL_CACHE_AUTO_INVALID_FLAG)) == 0)
  130. break;
  131. }
  132. sys_write32(sys_read32(CMU_MEMCLKEN) | (1 << 8), CMU_MEMCLKEN);
  133. k_busy_wait(10);
  134. }
  135. }
  136. #endif