regdma_link.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #pragma once
  7. #include <stdint.h>
  8. #include <stddef.h>
  9. #include "esp_bit_defs.h"
  10. #include "soc/soc_caps.h"
  11. #if SOC_PAU_SUPPORTED
  12. #include "esp_regdma.h"
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif
  16. #define FILL_PLINK_HEAD(_pl, _len, _mode, _branch, _sr, _sb, _eof) { \
  17. _pl->head.length = _len; \
  18. _pl->head.mode = _mode; \
  19. _pl->head.branch = _branch; \
  20. _pl->head.skip_r = _sr; \
  21. _pl->head.skip_b = _sb; \
  22. _pl->head.eof = _eof; \
  23. }
  24. #define FILL_PLINK_STAT(_pl, _ref, _id, _module) { \
  25. _pl->stat.ref = _ref; \
  26. _pl->stat.id = _id; \
  27. _pl->stat.module = _module; \
  28. }
  29. static inline void * regdma_link_init_continuous(
  30. regdma_link_continuous_t *plink, void *buff, void *backup, int len,
  31. void *restore, void *next, bool skip_b, bool skip_r, int id, uint32_t module)
  32. {
  33. assert(plink != NULL);
  34. assert(buff !=NULL);
  35. FILL_PLINK_HEAD(plink, len, REGDMA_LINK_MODE_CONTINUOUS, 0, skip_r, skip_b, !next);
  36. plink->body.next = next;
  37. plink->body.backup = backup;
  38. plink->body.restore = restore;
  39. plink->body.mem = buff;
  40. FILL_PLINK_STAT(plink, 0, (uint16_t)id, module);
  41. return (void *)plink;
  42. }
  43. static inline int regdma_link_addr_map_count(uint32_t bitmap[4])
  44. {
  45. return __builtin_popcount(bitmap[0]) + \
  46. __builtin_popcount(bitmap[1]) + \
  47. __builtin_popcount(bitmap[2]) + \
  48. __builtin_popcount(bitmap[3]);
  49. }
  50. static inline void * regdma_link_init_addr_map(
  51. regdma_link_addr_map_t *plink, void *buff, void *backup, uint32_t bitmap[4],
  52. int len, void *restore, void *next, bool skip_b, bool skip_r, int id, uint32_t module)
  53. {
  54. assert(plink != NULL);
  55. assert(buff != NULL);
  56. assert(len == regdma_link_addr_map_count(bitmap));
  57. FILL_PLINK_HEAD(plink, len, REGDMA_LINK_MODE_ADDR_MAP, 0, skip_r, skip_b, !next);
  58. plink->body.next = next;
  59. plink->body.backup = backup;
  60. plink->body.restore = restore;
  61. plink->body.mem = buff;
  62. plink->body.map[0] = bitmap[0];
  63. plink->body.map[1] = bitmap[1];
  64. plink->body.map[2] = bitmap[2];
  65. plink->body.map[3] = bitmap[3];
  66. FILL_PLINK_STAT(plink, 0, (uint16_t)id, module);
  67. return (void *)plink;
  68. }
  69. static inline void * regdma_link_init_write(
  70. regdma_link_write_wait_t *plink, void *backup, uint32_t value,
  71. uint32_t mask, void *next, bool skip_b, bool skip_r, int id,
  72. uint32_t module)
  73. {
  74. assert(plink != NULL);
  75. FILL_PLINK_HEAD(plink, 0, REGDMA_LINK_MODE_WRITE, 0, skip_r, skip_b, !next);
  76. plink->body.next = next;
  77. plink->body.backup = backup;
  78. plink->body.value = value;
  79. plink->body.mask = mask;
  80. FILL_PLINK_STAT(plink, 0, (uint16_t)id, module);
  81. return (void *)plink;
  82. }
  83. static inline void * regdma_link_init_wait(
  84. regdma_link_write_wait_t *plink, void *backup, uint32_t value,
  85. uint32_t mask, void *next, bool skip_b, bool skip_r, int id,
  86. uint32_t module)
  87. {
  88. assert(plink != NULL);
  89. FILL_PLINK_HEAD(plink, 0, REGDMA_LINK_MODE_WAIT, 0, skip_r, skip_b, !next);
  90. plink->body.next = next;
  91. plink->body.backup = backup;
  92. plink->body.value = value;
  93. plink->body.mask = mask;
  94. FILL_PLINK_STAT(plink, 0, (uint16_t)id, module);
  95. return (void *)plink;
  96. }
  97. static inline void * regdma_link_init_branch_continuous(
  98. regdma_link_branch_continuous_t *plink, void *buff, void *backup, int len, void *restore,
  99. regdma_entry_buf_t *next, bool skip_b, bool skip_r, int id, uint32_t module)
  100. {
  101. assert(plink != NULL);
  102. assert(buff !=NULL);
  103. FILL_PLINK_HEAD(plink, len, REGDMA_LINK_MODE_CONTINUOUS, 1, skip_r, skip_b, 0);
  104. plink->body.backup = backup;
  105. plink->body.restore = restore;
  106. plink->body.mem = buff;
  107. for (int i = 0; i < REGDMA_LINK_ENTRY_NUM; i++) {
  108. plink->body.next[i] = (*next)[i];
  109. }
  110. FILL_PLINK_STAT(plink, 0, (uint16_t)id, module);
  111. return (void *)plink;
  112. }
  113. static inline void * regdma_link_init_branch_addr_map(
  114. regdma_link_branch_addr_map_t *plink, void *buff, void *backup, uint32_t bitmap[4],
  115. int len, void *restore, regdma_entry_buf_t *next, bool skip_b, bool skip_r, int id,
  116. uint32_t module)
  117. {
  118. assert(plink != NULL);
  119. assert(buff != NULL);
  120. FILL_PLINK_HEAD(plink, len, REGDMA_LINK_MODE_ADDR_MAP, 1, skip_r, skip_b, 0);
  121. plink->body.backup = backup;
  122. plink->body.restore = restore;
  123. plink->body.mem = buff;
  124. memcpy(plink->body.next, *next, REGDMA_LINK_ENTRY_NUM * sizeof((*next)[0]));
  125. plink->body.map[0] = bitmap[0];
  126. plink->body.map[1] = bitmap[1];
  127. plink->body.map[2] = bitmap[2];
  128. plink->body.map[3] = bitmap[3];
  129. FILL_PLINK_STAT(plink, 0, (uint16_t)id, module);
  130. return (void *)plink;
  131. }
  132. static inline void * regdma_link_init_branch_write(
  133. regdma_link_branch_write_wait_t *plink, void *backup, uint32_t value, uint32_t mask,
  134. regdma_entry_buf_t *next, bool skip_b, bool skip_r, int id, uint32_t module)
  135. {
  136. assert(plink != NULL);
  137. FILL_PLINK_HEAD(plink, 0, REGDMA_LINK_MODE_WRITE, 1, skip_r, skip_b, 0);
  138. plink->body.backup = backup;
  139. plink->body.value = value;
  140. plink->body.mask = mask;
  141. for (int i = 0; i < REGDMA_LINK_ENTRY_NUM; i++) {
  142. plink->body.next[i] = (*next)[i];
  143. }
  144. FILL_PLINK_STAT(plink, 0, (uint16_t)id, module);
  145. return (void *)plink;
  146. }
  147. static inline void * regdma_link_init_branch_wait(
  148. regdma_link_branch_write_wait_t *plink, void *backup, uint32_t value, uint32_t mask,
  149. regdma_entry_buf_t *next, bool skip_b, bool skip_r, int id, uint32_t module)
  150. {
  151. assert(plink != NULL);
  152. FILL_PLINK_HEAD(plink, 0, REGDMA_LINK_MODE_WAIT, 1, skip_r, skip_b, 0);
  153. plink->body.backup = backup;
  154. plink->body.value = value;
  155. plink->body.mask = mask;
  156. for (int i = 0; i < REGDMA_LINK_ENTRY_NUM; i++) {
  157. plink->body.next[i] = (*next)[i];
  158. }
  159. FILL_PLINK_STAT(plink, 0, (uint16_t)id, module);
  160. return (void *)plink;
  161. }
  162. static inline void regdma_link_update_stats(regdma_link_stats_t *stats, int entry, int depth)
  163. {
  164. assert(stats != NULL);
  165. stats->ref |= BIT(entry);
  166. }
  167. #ifdef __cplusplus
  168. }
  169. #endif
  170. #endif // SOC_PAU_SUPPORTED