spicache.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /*
  2. * Copyright (c) 2017 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file
  8. * @brief SPICACHE profile interface for Actions SoC
  9. */
  10. #include <errno.h>
  11. #include <kernel.h>
  12. #include "soc.h"
  13. #include "spicache.h"
  14. #include "board_cfg.h"
  15. #define SPI1_CACHE_SIZE (1024*32)
  16. #ifdef CONFIG_SOC_SPICACHE_PROFILE
  17. static void spicache_update_profile_data(struct spicache_profile *profile)
  18. {
  19. if (!profile->spi_id) {
  20. profile->hit_cnt = sys_read32(SPICACHE_RANGE_ADDR_HIT_COUNT);
  21. profile->miss_cnt = sys_read32(SPICACHE_RANGE_ADDR_MISS_COUNT);
  22. profile->total_hit_cnt = sys_read32(SPICACHE_TOTAL_HIT_COUNT);
  23. profile->total_miss_cnt = sys_read32(SPICACHE_TOTAL_MISS_COUNT);
  24. } else {
  25. profile->hit_cnt = sys_read32(SPI1_CACHE_MCPU_HIT_COUNT);
  26. profile->miss_cnt = sys_read32(SPI1_CACHE_MCPU_MISS_COUNT);
  27. profile->dma_hit_cnt = sys_read32(SPI1_CACHE_DMA_HIT_COUNT);
  28. profile->dma_miss_cnt = sys_read32(SPI1_CACHE_DMA_MISS_COUNT);
  29. }
  30. }
  31. int spicache_profile_get_data(struct spicache_profile *profile)
  32. {
  33. if (!profile)
  34. return -EINVAL;
  35. spicache_update_profile_data(profile);
  36. return 0;
  37. }
  38. int spicache_profile_stop(struct spicache_profile *profile)
  39. {
  40. if (!profile)
  41. return -EINVAL;
  42. profile->end_time = k_cycle_get_32();
  43. spicache_update_profile_data(profile);
  44. if (!profile->spi_id)
  45. sys_write32(sys_read32(SPICACHE_CTL) & ~(1 << 4), SPICACHE_CTL);
  46. else
  47. sys_write32(sys_read32(SPI1_CACHE_CTL) & ~(1 << 4), SPI1_CACHE_CTL);
  48. return 0;
  49. }
  50. int spicache_profile_start(struct spicache_profile *profile)
  51. {
  52. if (!profile)
  53. return -EINVAL;
  54. if (!profile->spi_id) {
  55. sys_write32(profile->start_addr, SPICACHE_PROFILE_ADDR_START);
  56. sys_write32(profile->end_addr, SPICACHE_PROFILE_ADDR_END);
  57. } else {
  58. sys_write32(profile->start_addr, SPI1_CACHE_PROFILE_ADDR_START);
  59. sys_write32(profile->end_addr, SPI1_CACHE_PROFILE_ADDR_END);
  60. }
  61. profile->start_time = k_cycle_get_32();
  62. if (!profile->spi_id)
  63. sys_write32(sys_read32(SPICACHE_CTL) | (1 << 4), SPICACHE_CTL);
  64. else
  65. sys_write32(sys_read32(SPI1_CACHE_CTL) | (1 << 4), SPI1_CACHE_CTL);
  66. return 0;
  67. }
  68. #endif
  69. int spicache_master_enable(int spi_id, SPI_CACHE_MASTER master_id)
  70. {
  71. if (!spi_id) {
  72. if ((master_id >= SPI0_CACHE_MASTER_DMA) && (master_id <= SPI0_CACHE_MASTER_DE))
  73. sys_write32(sys_read32(SPICACHE_CTL) | (1<<((master_id - SPI0_CACHE_MASTER_DMA) + 9)), SPICACHE_CTL);
  74. } else {
  75. if ((master_id >= SPI1_CACHE_MASTER_GPU) && (master_id <= SPI1_CACHE_MASTER_DE))
  76. sys_write32(sys_read32(SPI1_CACHE_CTL) | (1<<((master_id - SPI1_CACHE_MASTER_GPU) + 8)), SPI1_CACHE_CTL);
  77. }
  78. return 0;
  79. }
  80. int spicache_master_disable(int spi_id, SPI_CACHE_MASTER master_id)
  81. {
  82. if (!spi_id) {
  83. if ((master_id >= SPI0_CACHE_MASTER_DMA) && (master_id<=SPI0_CACHE_MASTER_DE))
  84. sys_write32(sys_read32(SPICACHE_CTL) & ~(1<<((master_id - SPI0_CACHE_MASTER_DMA) + 9)), SPICACHE_CTL);
  85. } else {
  86. if ((master_id >= SPI1_CACHE_MASTER_GPU) && (master_id <= SPI1_CACHE_MASTER_DE))
  87. sys_write32(sys_read32(SPI1_CACHE_CTL) & ~(1<<((master_id - SPI1_CACHE_MASTER_GPU) + 8)), SPI1_CACHE_CTL);
  88. }
  89. return 0;
  90. }
  91. int spicache_set_priority(int spi_id, SPI_CACHE_PRIORITY priority)
  92. {
  93. if (!spi_id) {
  94. sys_write32((sys_read32(SPICACHE_CTL) & ~(0xf<<20)) | ((priority - SPI0_CACHE_PRIORITY_POLL)<<20), SPICACHE_CTL);
  95. } else {
  96. sys_write32((sys_read32(SPI1_CACHE_CTL) & ~(0xf<<20)) | ((priority - SPI1_CACHE_PRIORITY_POLL)<<20), SPI1_CACHE_CTL);
  97. }
  98. return 0;
  99. }
  100. void spi1_cache_ops_wait_finshed(void)
  101. {
  102. while(sys_test_bit(SPI1_CACHE_OPERATE, 0));
  103. }
  104. void spi1_cache_ops(SPI_CACHE_OPS ops, void* addr, int size)
  105. {
  106. // uint32_t end;
  107. uint32_t off = (uint32_t)addr;
  108. uint32_t op;
  109. if((off < SPI1_CACHE_WT_WNA_ADDR) || (off > SPI1_UNCACHE_END_ADDR))
  110. return;
  111. spi1_cache_ops_wait_finshed();
  112. switch(ops){
  113. case SPI_CACHE_FLUSH:
  114. sys_write32((uint32_t)addr, CACHE_OPERATE_ADDR_START);
  115. sys_write32((uint32_t)addr + size - 1, CACHE_OPERATE_ADDR_END);
  116. op = 0x13; // write back // configurable address space mode
  117. sys_write32(op, SPI1_CACHE_OPERATE);
  118. spi1_cache_ops_wait_finshed();
  119. return;
  120. case SPI_CACHE_INVALIDATE:
  121. sys_write32((uint32_t)addr, CACHE_OPERATE_ADDR_START);
  122. sys_write32((uint32_t)addr + size - 1, CACHE_OPERATE_ADDR_END);
  123. op = 0x0b; // invalid // configurable address space mode
  124. sys_write32(op, SPI1_CACHE_OPERATE);
  125. spi1_cache_ops_wait_finshed();
  126. return;
  127. case SPI_WRITEBUF_FLUSH:
  128. sys_write32(0x1f, SPI1_CACHE_OPERATE);
  129. spi1_cache_ops_wait_finshed();
  130. return;
  131. case SPI_CACHE_FLUSH_ALL://flush all
  132. sys_write32(0x11, SPI1_CACHE_OPERATE);
  133. return ;
  134. case SPI_CACHE_INVALID_ALL: //invalid all
  135. sys_write32(0x9, SPI1_CACHE_OPERATE);
  136. spi1_cache_ops_wait_finshed();
  137. return ;
  138. case SPI_CACHE_FLUSH_INVALID:
  139. sys_write32((uint32_t)addr, CACHE_OPERATE_ADDR_START);
  140. sys_write32((uint32_t)addr + size - 1, CACHE_OPERATE_ADDR_END);
  141. op = 0x1b; // writeback & invalid // configurable address space mode
  142. sys_write32(op, SPI1_CACHE_OPERATE);
  143. spi1_cache_ops_wait_finshed();
  144. return;
  145. case SPI_CACHE_FLUSH_INVALID_ALL:
  146. sys_write32(0x19, SPI1_CACHE_OPERATE); //flush and invalid all
  147. return ;
  148. default:
  149. return;
  150. }
  151. // /*address mode operate*/
  152. // off = (off - SPI1_BASE_ADDR);
  153. // end = off + size;
  154. // off &= (~0x1f);
  155. // /*not flush all*/
  156. // while(off < end) {
  157. // sys_write32(op|off, SPI1_CACHE_OPERATE);
  158. // off+= 0x20;
  159. // //while(sys_test_bit(SPI1_CACHE_OPERATE, 0));
  160. // spi1_cache_ops_wait_finshed();
  161. // }
  162. }
  163. static uint32_t system_phy_addr, sdfs_phy_addr;
  164. static uint32_t get_system_phy_addr(void)
  165. {
  166. if (system_phy_addr == 0) {
  167. system_phy_addr = soc_boot_get_info()->system_phy_addr;
  168. }
  169. return system_phy_addr;
  170. }
  171. #include <partition/partition.h>
  172. static uint32_t get_sdfs_phy_addr(void)
  173. {
  174. const struct partition_entry *part;
  175. if (sdfs_phy_addr == 0) {
  176. part = partition_get_part(PARTITION_FILE_ID_SDFS);
  177. if (part) {
  178. sdfs_phy_addr = part->file_offset;
  179. }
  180. }
  181. return sdfs_phy_addr;
  182. }
  183. void * cache_to_uncache(void *vaddr)
  184. {
  185. void *pvadr = vaddr;
  186. if (buf_is_nor(vaddr)) {
  187. pvadr = (void *) (SPI0_UNCACHE_ADDR + (((uint32_t)vaddr) - SPI0_BASE_ADDR));
  188. } else if (buf_is_psram_cache(vaddr)) {
  189. pvadr = (void *) (SPI1_UNCACHE_ADDR + (((uint32_t)vaddr) - SPI1_BASE_ADDR));
  190. } else if (buf_is_psram_wt_wna(vaddr)) {
  191. pvadr = (void *) (SPI1_UNCACHE_ADDR + (((uint32_t)vaddr) - SPI1_CACHE_WT_WNA_ADDR));
  192. }
  193. return pvadr;
  194. }
  195. void * cache_to_unmap_uncache(void *vaddr)
  196. {
  197. void *pvadr = vaddr;
  198. if (buf_is_nor(vaddr)) {
  199. uint32_t vaddr_val = (uint32_t)vaddr;
  200. if ((vaddr_val & 0xff000000) == CONFIG_FLASH_BASE_ADDRESS) {
  201. pvadr = (void *) (SPI0_UNCACHE_ADDR + (vaddr_val - CONFIG_FLASH_BASE_ADDRESS + get_system_phy_addr()));
  202. } else if ((vaddr_val & 0xff000000) == CONFIG_SPI_XIP_VADDR) {
  203. pvadr = (void *) ((vaddr_val - CONFIG_SPI_XIP_VADDR + SPI0_UNCACHE_ADDR));
  204. }
  205. }
  206. return pvadr;
  207. }
  208. void * cache_to_uncache_by_master(void *vaddr, SPI_CACHE_MASTER master_id)
  209. {
  210. if ((master_id >= SPI0_CACHE_MASTER_DMA) && (master_id<=SPI0_CACHE_MASTER_DE))
  211. return cache_to_unmap_uncache(vaddr);
  212. return cache_to_uncache(vaddr);
  213. }
  214. void * uncache_to_cache(void *paddr)
  215. {
  216. void *vaddr = paddr;
  217. if (buf_is_nor_un(paddr)) {
  218. vaddr = (void *) (SPI0_BASE_ADDR + (((uint32_t)paddr) - SPI0_UNCACHE_ADDR));
  219. } else if (buf_is_psram_un(paddr)) {
  220. vaddr = (void *) (SPI1_BASE_ADDR + (((uint32_t)paddr) - SPI1_UNCACHE_ADDR));
  221. }
  222. return vaddr;
  223. }
  224. void * unmap_uncache_to_cache(void *paddr)
  225. {
  226. void *vaddr = paddr;
  227. if (buf_is_nor_un(paddr)) {
  228. uint32_t offs = (uint32_t)paddr - SPI0_UNCACHE_ADDR;
  229. if ((offs >= get_system_phy_addr()) && (offs < get_sdfs_phy_addr())) {
  230. vaddr = (void *) (SPI0_BASE_ADDR + (offs- get_system_phy_addr()));
  231. } else if (offs >= get_sdfs_phy_addr()) {
  232. vaddr = (void *) (CONFIG_SD_FS_VADDR_START + (offs - get_sdfs_phy_addr()));
  233. }
  234. }
  235. return vaddr;
  236. }
  237. void * uncache_to_cache_by_master(void *paddr, SPI_CACHE_MASTER master_id)
  238. {
  239. if ((master_id >= SPI0_CACHE_MASTER_DMA) && (master_id<=SPI0_CACHE_MASTER_DE))
  240. return unmap_uncache_to_cache(paddr);
  241. return uncache_to_cache(paddr);
  242. }
  243. void * uncache_to_wt_wna_cache(void *paddr)
  244. {
  245. void *vaddr = paddr;
  246. if (buf_is_psram_un(paddr)) {
  247. vaddr = (void *) (SPI1_CACHE_WT_WNA_ADDR + (((uint32_t)paddr) - SPI1_UNCACHE_ADDR));
  248. }
  249. return vaddr;
  250. }
  251. void * cache_to_wt_wna_cache(void *vaddr)
  252. {
  253. void *pvadr = vaddr;
  254. if (buf_is_psram_cache(vaddr)) {
  255. pvadr = (void *) (SPI1_CACHE_WT_WNA_ADDR + (((uint32_t)vaddr) - SPI1_BASE_ADDR));
  256. }
  257. return pvadr;
  258. }
  259. void * wt_wna_cache_to_cache(void *vaddr)
  260. {
  261. void *pvadr = vaddr;
  262. if (buf_is_psram_wt_wna(vaddr)) {
  263. pvadr = (void *) (SPI1_BASE_ADDR + (((uint32_t)vaddr) - SPI1_CACHE_WT_WNA_ADDR));
  264. }
  265. return pvadr;
  266. }