mem_cache.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * Copyright (c) 2020 Actions Technology Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <zephyr.h>
  7. #include <spicache.h>
  8. #include <memory/mem_cache.h>
  9. static K_MUTEX_DEFINE(cache_mutex);
  10. static inline void _mem_dcache_ops_unlocked(uint8_t ops, const void *addr, uint32_t length)
  11. {
  12. spi1_cache_ops(ops, (void *)addr, length);
  13. }
  14. static void _mem_dcache_ops(uint8_t ops, const void *addr, uint32_t length)
  15. {
  16. k_mutex_lock(&cache_mutex, K_FOREVER);
  17. _mem_dcache_ops_unlocked(ops, addr, length);
  18. k_mutex_unlock(&cache_mutex);
  19. }
  20. bool mem_dcache_invalidate(const void *addr, uint32_t length)
  21. {
  22. if (buf_is_psram(addr)) {
  23. _mem_dcache_ops(SPI_CACHE_INVALIDATE, addr, length);
  24. }
  25. return false;
  26. }
  27. bool mem_dcache_invalidate_all(void)
  28. {
  29. _mem_dcache_ops(SPI_CACHE_INVALID_ALL, (void *)SPI1_BASE_ADDR, 0);
  30. return false;
  31. }
  32. bool mem_dcache_clean(const void *addr, uint32_t length)
  33. {
  34. bool ret = false;
  35. k_mutex_lock(&cache_mutex, K_FOREVER);
  36. if (buf_is_psram_cache(addr)) {
  37. _mem_dcache_ops_unlocked(SPI_WRITEBUF_FLUSH, addr, length);
  38. _mem_dcache_ops_unlocked(SPI_CACHE_FLUSH, addr, length);
  39. ret = true;
  40. } else if (buf_is_psram_wt_wna(addr) || buf_is_psram_un(addr)) {
  41. _mem_dcache_ops_unlocked(SPI_WRITEBUF_FLUSH, addr, length);
  42. }
  43. k_mutex_unlock(&cache_mutex);
  44. return ret;
  45. }
  46. bool mem_dcache_clean_all(void)
  47. {
  48. k_mutex_lock(&cache_mutex, K_FOREVER);
  49. _mem_dcache_ops_unlocked(SPI_WRITEBUF_FLUSH, (void *)SPI1_UNCACHE_ADDR, 0);
  50. _mem_dcache_ops_unlocked(SPI_CACHE_FLUSH_ALL, (void *)SPI1_BASE_ADDR, 0);
  51. k_mutex_unlock(&cache_mutex);
  52. return true;
  53. }
  54. bool mem_dcache_flush(const void *addr, uint32_t length)
  55. {
  56. k_mutex_lock(&cache_mutex, K_FOREVER);
  57. if (buf_is_psram(addr)) {
  58. _mem_dcache_ops_unlocked(SPI_WRITEBUF_FLUSH, addr, length);
  59. _mem_dcache_ops_unlocked(SPI_CACHE_FLUSH_INVALID, addr, length);
  60. } else if (buf_is_psram_un(addr)) {
  61. _mem_dcache_ops_unlocked(SPI_WRITEBUF_FLUSH, addr, length);
  62. }
  63. k_mutex_unlock(&cache_mutex);
  64. return false;
  65. }
  66. bool mem_dcache_flush_all(void)
  67. {
  68. k_mutex_lock(&cache_mutex, K_FOREVER);
  69. _mem_dcache_ops_unlocked(SPI_WRITEBUF_FLUSH, (void *)SPI1_UNCACHE_ADDR, 0);
  70. _mem_dcache_ops_unlocked(SPI_CACHE_FLUSH_INVALID_ALL, (void *)SPI1_BASE_ADDR, 0);
  71. k_mutex_unlock(&cache_mutex);
  72. return true;
  73. }
  74. bool mem_writebuf_clean(const void *addr, uint32_t length)
  75. {
  76. if (buf_is_psram(addr) || buf_is_psram_un(addr)) {
  77. _mem_dcache_ops(SPI_WRITEBUF_FLUSH, addr, length);
  78. }
  79. return false;
  80. }
  81. bool mem_writebuf_clean_all(void)
  82. {
  83. _mem_dcache_ops(SPI_WRITEBUF_FLUSH, (void *)SPI1_UNCACHE_ADDR, 0);
  84. return false;
  85. }
  86. void mem_dcache_sync(void)
  87. {
  88. k_mutex_lock(&cache_mutex, K_FOREVER);
  89. spi1_cache_ops_wait_finshed();
  90. k_mutex_unlock(&cache_mutex);
  91. }
  92. void * mem_addr_to_uncache(const void * addr)
  93. {
  94. if (buf_is_psram(addr)) {
  95. return cache_to_uncache((void *)addr);
  96. } else {
  97. return (void *)addr;
  98. }
  99. }
  100. void * mem_addr_to_cache(const void * addr)
  101. {
  102. if (buf_is_psram_wt_wna(addr)) {
  103. return wt_wna_cache_to_cache((void *)addr);
  104. } else if (buf_is_psram_un(addr)) {
  105. return uncache_to_cache((void *)addr);
  106. } else {
  107. return (void *)addr;
  108. }
  109. }
  110. void * mem_addr_to_cache_wt(const void * addr)
  111. {
  112. if (buf_is_psram_cache(addr)) {
  113. return cache_to_wt_wna_cache((void *)addr);
  114. } else if (buf_is_psram_un(addr)) {
  115. return uncache_to_wt_wna_cache((void *)addr);
  116. } else {
  117. return (void *)addr;
  118. }
  119. }
  120. bool mem_is_cacheable(const void *addr)
  121. {
  122. return buf_is_psram(addr);
  123. }
  124. bool mem_is_bufferable(const void *addr)
  125. {
  126. return buf_is_psram_un(addr) || buf_is_psram_wt_wna(addr);
  127. }