ui_memsetcpy.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. /*
  2. * Copyright (c) 2020 Actions Technology Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /*********************
  7. * INCLUDES
  8. *********************/
  9. #include <assert.h>
  10. #include <display/ui_memsetcpy.h>
  11. #include <memory/mem_cache.h>
  12. #ifdef CONFIG_DMA2D_HAL
  13. # include <dma2d_hal.h>
  14. #endif
  15. /**********************
  16. * STATIC VARIABLES
  17. **********************/
  18. #ifdef CONFIG_DMA2D_HAL
  19. static bool dma2d_inited = false;
  20. static hal_dma2d_handle_t hdma2d __in_section_unique(ram.noinit.surface);
  21. #endif
  22. /**********************
  23. * STATIC FUNCTIONS
  24. **********************/
  25. #ifdef CONFIG_DMA2D_HAL
  26. static int dma_transfer_init(void)
  27. {
  28. int ret = 0;
  29. if (dma2d_inited)
  30. return 0;
  31. if ((ret = hal_dma2d_init(&hdma2d, HAL_DMA2D_M2M)) == 0) {
  32. /* initialize dma2d constant fields */
  33. hdma2d.output_cfg.mode = HAL_DMA2D_M2M;
  34. hdma2d.layer_cfg[1].alpha_mode = HAL_DMA2D_NO_MODIF_ALPHA;
  35. dma2d_inited = true;
  36. }
  37. return 0;
  38. }
  39. #endif /* CONFIG_DMA2D_HAL */
  40. static void ui_memset_sw(void * buf, uint8_t c, size_t size)
  41. {
  42. buf = mem_addr_to_uncache(buf);
  43. memset(buf, c, size);
  44. mem_writebuf_clean_all();
  45. }
  46. static void ui_memset32_sw(void * buf, uint32_t c32, size_t n32)
  47. {
  48. uint32_t *buf32 = mem_addr_to_uncache(buf);
  49. assert(((uintptr_t)buf32 & 0x3) == 0);
  50. for (; n32 >= 8; n32 -= 8) {
  51. *buf32++ = c32;
  52. *buf32++ = c32;
  53. *buf32++ = c32;
  54. *buf32++ = c32;
  55. *buf32++ = c32;
  56. *buf32++ = c32;
  57. *buf32++ = c32;
  58. *buf32++ = c32;
  59. }
  60. for (; n32 >= 4; n32 -= 4) {
  61. *buf32++ = c32;
  62. *buf32++ = c32;
  63. *buf32++ = c32;
  64. *buf32++ = c32;
  65. }
  66. for (; n32 > 0; n32 -= 1) {
  67. *buf32++ = c32;
  68. }
  69. mem_writebuf_clean_all();
  70. }
  71. static void ui_memset16_sw(void * buf, uint16_t c16, size_t n16)
  72. {
  73. uint32_t *buf16 = mem_addr_to_uncache(buf);
  74. assert(((uintptr_t)buf16 & 0x1) == 0);
  75. if (n16 == 0)
  76. return;
  77. /* unaligned head */
  78. if ((uintptr_t)buf16 & 0x3) {
  79. *buf16++ = c16;
  80. n16--;
  81. }
  82. if (n16 >= 2) {
  83. uint32_t c32 = ((uint32_t)c16 << 16) | c16;
  84. ui_memset32_sw(buf16, c32, n16 >> 1);
  85. }
  86. /* unaligned tail */
  87. if (n16 & 0x1) {
  88. buf16 += n16 & ~0x1;
  89. *buf16 = c16;
  90. }
  91. mem_writebuf_clean_all();
  92. }
  93. void ui_memset24_sw(void * buf, const uint8_t c24[3], size_t n24)
  94. {
  95. uint8_t *buf8 = mem_addr_to_uncache(buf);
  96. size_t ofs = (4 - ((uintptr_t)buf8 & 0x3)) & 0x3;
  97. size_t bytes = n24 * 3;
  98. union {
  99. uint32_t v32[3];
  100. uint8_t v8[12];
  101. } pattern;
  102. uint32_t i;
  103. if (bytes == 0)
  104. return;
  105. /* unaligned head */
  106. for (i = 0; i < ofs; i++) {
  107. buf8[i] = c24[i];
  108. }
  109. buf8 += ofs;
  110. bytes -= ofs;
  111. if (bytes == 0)
  112. return;
  113. /* create pattern */
  114. for (i = 0; i < 12; i++, ofs++) {
  115. if (ofs >= 3) ofs = 0;
  116. pattern.v8[i] = c24[ofs];
  117. }
  118. if (bytes >= 12) {
  119. uint32_t *buf32 = (uint32_t *)buf8;
  120. for (; bytes >= 12; bytes -= 12) {
  121. *buf32++ = pattern.v32[0];
  122. *buf32++ = pattern.v32[1];
  123. *buf32++ = pattern.v32[2];
  124. }
  125. buf8 = (uint8_t *)buf32;
  126. }
  127. /* unaligned tail */
  128. for (i = 0; bytes > 0; bytes--, i++) {
  129. *buf8++ = pattern.v8[i];
  130. }
  131. mem_writebuf_clean_all();
  132. }
  133. static void ui_memset2d_sw(void * buf, uint16_t stride, uint8_t c, uint16_t len, uint16_t lines)
  134. {
  135. uint8_t *buf8 = mem_addr_to_uncache(buf);
  136. if (len == stride) {
  137. memset(buf8, c, (uint32_t)len * lines);
  138. } else {
  139. for (; lines > 0; lines--) {
  140. memset(buf8, c, len);
  141. buf8 += stride;
  142. }
  143. }
  144. mem_writebuf_clean_all();
  145. }
  146. static void ui_memset2d_16_sw(void * buf, uint16_t stride, uint16_t c16, uint16_t len16, uint16_t lines)
  147. {
  148. if (len16 * 2 == stride) {
  149. ui_memset16_sw(buf, c16, (uint32_t)len16 * lines);
  150. } else {
  151. uint8_t *buf16 = buf;
  152. for (; lines > 0; lines--) {
  153. ui_memset16_sw(buf16, c16, len16);
  154. buf16 += stride;
  155. }
  156. }
  157. }
  158. static void ui_memset2d_24_sw(void * buf, uint16_t stride, const uint8_t c24[3], uint16_t len24, uint16_t lines)
  159. {
  160. if (len24 * 3 == stride) {
  161. ui_memset24_sw(buf, c24, (uint32_t)len24 * lines);
  162. } else {
  163. uint8_t *buf8 = buf;
  164. for (; lines > 0; lines--) {
  165. ui_memset24_sw(buf8, c24, len24);
  166. buf8 += stride;
  167. }
  168. }
  169. }
  170. static void ui_memset2d_32_sw(void * buf, uint16_t stride, uint32_t c32, uint16_t len32, uint16_t lines)
  171. {
  172. if (len32 * 4 == stride) {
  173. ui_memset16_sw(buf, c32, (uint32_t)len32 * lines);
  174. } else {
  175. uint8_t *buf32 = buf;
  176. for (; lines > 0; lines--) {
  177. ui_memset32_sw(buf32, c32, len32);
  178. buf32 += stride;
  179. }
  180. }
  181. }
  182. static void ui_memcpy_sw(void * dest, const void * src, size_t size)
  183. {
  184. dest = mem_addr_to_uncache(dest);
  185. memcpy(dest, src, size);
  186. mem_writebuf_clean_all();
  187. }
  188. static void ui_memcpy2d_sw(void * dest, uint16_t dest_stride, const void * src,
  189. uint16_t src_stride, uint16_t len, uint16_t lines)
  190. {
  191. uint8_t *dest8 = mem_addr_to_uncache(dest);
  192. const uint8_t *src8 = src;
  193. if (len == dest_stride && len == src_stride) {
  194. memcpy(dest8, src8, (uint32_t)len * lines);
  195. } else {
  196. for (; lines > 0; lines--) {
  197. memcpy(dest8, src8, len);
  198. dest8 += dest_stride;
  199. src8 += src_stride;
  200. }
  201. }
  202. mem_writebuf_clean_all();
  203. }
  204. /**********************
  205. * GLOBAL FUNCTIONS
  206. **********************/
  207. #ifdef CONFIG_DMA2D_HAL
  208. static int ui_memset_hw(void * buf, uint8_t c, size_t len, uint16_t lines, size_t stride)
  209. {
  210. if (dma_transfer_init() == 0) {
  211. hdma2d.output_cfg.mode = HAL_DMA2D_R2M;
  212. hdma2d.output_cfg.color_format = HAL_PIXEL_FORMAT_A8;
  213. hdma2d.output_cfg.output_pitch = stride;
  214. hal_dma2d_config_output(&hdma2d);
  215. return hal_dma2d_start(&hdma2d, (uint32_t)c << 24, (uint32_t)buf, len, lines);
  216. }
  217. return -ENOTSUP;
  218. }
  219. static int ui_memset16_hw(void * buf, uint16_t c16, size_t len16, uint16_t lines, size_t stride)
  220. {
  221. if (dma_transfer_init() == 0) {
  222. hdma2d.output_cfg.mode = HAL_DMA2D_R2M;
  223. hdma2d.output_cfg.color_format = HAL_PIXEL_FORMAT_RGB_565;
  224. hdma2d.output_cfg.output_pitch = stride;
  225. hal_dma2d_config_output(&hdma2d);
  226. uint32_t c32 = ((c16 & 0xf800) << 8) | ((c16 & 0x07e0) << 5) | ((c16 & 0x001f) << 3);
  227. return hal_dma2d_start(&hdma2d, c32, (uint32_t)buf, len16, lines);
  228. }
  229. return -ENOTSUP;
  230. }
  231. static int ui_memset24_hw(void * buf, const uint8_t c24[3], size_t len24, uint16_t lines, size_t stride)
  232. {
  233. if (dma_transfer_init() == 0) {
  234. hdma2d.output_cfg.mode = HAL_DMA2D_R2M;
  235. hdma2d.output_cfg.color_format = HAL_PIXEL_FORMAT_BGR_888;
  236. hdma2d.output_cfg.output_pitch = stride;
  237. hal_dma2d_config_output(&hdma2d);
  238. uint32_t c32 = ((uint32_t)c24[0] << 16) | ((uint32_t)c24[1] << 8) | c24[2];
  239. return hal_dma2d_start(&hdma2d, c32, (uint32_t)buf, len24, lines);
  240. }
  241. return -ENOTSUP;
  242. }
  243. static int ui_memset32_hw(void * buf, uint32_t c32, size_t len32, uint16_t lines, size_t stride)
  244. {
  245. if (dma_transfer_init() == 0) {
  246. hdma2d.output_cfg.mode = HAL_DMA2D_R2M;
  247. hdma2d.output_cfg.color_format = HAL_PIXEL_FORMAT_ARGB_8888;
  248. hdma2d.output_cfg.output_pitch = stride;
  249. hal_dma2d_config_output(&hdma2d);
  250. return hal_dma2d_start(&hdma2d, c32, (uint32_t)buf, len32, lines);
  251. }
  252. return -ENOTSUP;
  253. }
  254. void ui_memset(void * buf, uint8_t c, size_t n)
  255. {
  256. if (ui_memset_hw(buf, c, n, 1, n) < 0) {
  257. ui_memset_sw(buf, c, n);
  258. }
  259. }
  260. void ui_memset16(void * buf, uint16_t c16, size_t n16)
  261. {
  262. if (ui_memset16_hw(buf, c16, n16, 1, n16 * 2) < 0) {
  263. ui_memset16_sw(buf, c16, n16);
  264. }
  265. }
  266. void ui_memset24(void * buf, const uint8_t c24[3], size_t n24)
  267. {
  268. if (ui_memset24_hw(buf, c24, n24, 1, n24 * 3) < 0) {
  269. ui_memset24_sw(buf, c24, n24);
  270. }
  271. }
  272. void ui_memset32(void * buf, uint32_t c32, size_t n32)
  273. {
  274. if (ui_memset32_hw(buf, c32, n32, 1, n32 * 4) < 0) {
  275. ui_memset32_sw(buf, c32, n32);
  276. }
  277. }
  278. void ui_memset2d(void * buf, uint16_t stride, uint8_t c, uint16_t len, uint16_t lines)
  279. {
  280. if (ui_memset_hw(buf, c, len, lines, stride) < 0) {
  281. ui_memset2d_sw(buf, stride, c, len, lines);
  282. }
  283. }
  284. void ui_memset2d_16(void * buf, uint16_t stride, uint16_t c16, uint16_t len16, uint16_t lines)
  285. {
  286. if (ui_memset16_hw(buf, c16, len16, lines, stride) < 0) {
  287. ui_memset2d_16_sw(buf, stride, c16, len16, lines);
  288. }
  289. }
  290. void ui_memset2d_24(void * buf, uint16_t stride, const uint8_t c24[3], uint16_t len24, uint16_t lines)
  291. {
  292. if (ui_memset24_hw(buf, c24, len24, lines, stride) < 0) {
  293. ui_memset2d_24_sw(buf, stride, c24, len24, lines);
  294. }
  295. }
  296. void ui_memset2d_32(void * buf, uint16_t stride, uint32_t c32, uint16_t len32, uint16_t lines)
  297. {
  298. if (ui_memset32_hw(buf, c32, len32, lines, stride) < 0) {
  299. ui_memset2d_32_sw(buf, stride, c32, len32, lines);
  300. }
  301. }
  302. void ui_memcpy(void * dest, const void * src, size_t n)
  303. {
  304. int res = -ENOTSUP;
  305. if (dma_transfer_init() == 0) {
  306. hdma2d.output_cfg.mode = HAL_DMA2D_M2M;
  307. hdma2d.output_cfg.output_pitch = n;
  308. hdma2d.output_cfg.color_format = HAL_PIXEL_FORMAT_A8;
  309. hal_dma2d_config_output(&hdma2d);
  310. hdma2d.layer_cfg[1].color_format = HAL_PIXEL_FORMAT_A8;
  311. hdma2d.layer_cfg[1].input_pitch = n;
  312. hdma2d.layer_cfg[1].input_width = n;
  313. hdma2d.layer_cfg[1].input_height = 1;
  314. hal_dma2d_config_layer(&hdma2d, HAL_DMA2D_FOREGROUND_LAYER);
  315. res = hal_dma2d_start(&hdma2d, (uint32_t)src, (uint32_t)dest, n, 1);
  316. }
  317. if (res < 0) {
  318. ui_memcpy_sw(dest, src, n);
  319. }
  320. }
  321. void ui_memcpy2d(void * dest, uint16_t dest_stride, const void * src,
  322. uint16_t src_stride, uint16_t len, uint16_t lines)
  323. {
  324. int res = -ENOTSUP;
  325. if (dma_transfer_init() == 0) {
  326. hdma2d.output_cfg.mode = HAL_DMA2D_M2M;
  327. hdma2d.output_cfg.output_pitch = dest_stride;
  328. hdma2d.output_cfg.color_format = HAL_PIXEL_FORMAT_A8;
  329. hal_dma2d_config_output(&hdma2d);
  330. hdma2d.layer_cfg[1].color_format = HAL_PIXEL_FORMAT_A8;
  331. hdma2d.layer_cfg[1].input_pitch = src_stride;
  332. hdma2d.layer_cfg[1].input_width = len;
  333. hdma2d.layer_cfg[1].input_height = lines;
  334. hal_dma2d_config_layer(&hdma2d, HAL_DMA2D_FOREGROUND_LAYER);
  335. res = hal_dma2d_start(&hdma2d, (uint32_t)src, (uint32_t)dest, len, lines);
  336. }
  337. if (res < 0) {
  338. ui_memcpy2d_sw(dest, dest_stride, src, src_stride, len, lines);
  339. }
  340. }
  341. int ui_memsetcpy_wait_finish(int timeout_ms)
  342. {
  343. if (dma2d_inited) {
  344. return hal_dma2d_poll_transfer(&hdma2d, timeout_ms);
  345. }
  346. return 0;
  347. }
  348. #else /* CONFIG_DMA2D_HAL */
  349. void ui_memset(void * buf, uint8_t c, size_t n)
  350. {
  351. ui_memset_sw(buf, c, n);
  352. }
  353. void ui_memset16(void * buf, uint16_t c16, size_t n16)
  354. {
  355. ui_memset16_sw(buf, c16, n16);
  356. }
  357. void ui_memset24(void * buf, const uint8_t c24[3], size_t n24)
  358. {
  359. ui_memset24_sw(buf, c24, n24);
  360. }
  361. void ui_memset32(void * buf, uint32_t c32, size_t n32)
  362. {
  363. ui_memset32_sw(buf, c32, n32);
  364. }
  365. void ui_memset2d(void * buf, uint16_t stride, uint8_t c, uint16_t len, uint16_t lines)
  366. {
  367. ui_memset2d_sw(buf, stride, c, len, lines);
  368. }
  369. void ui_memset2d_16(void * buf, uint16_t stride, uint16_t c16, uint16_t len16, uint16_t lines)
  370. {
  371. ui_memset2d_16_sw(buf, stride, c16, len16, lines);
  372. }
  373. void ui_memset2d_24(void * buf, uint16_t stride, const uint8_t c24[3], uint16_t len24, uint16_t lines)
  374. {
  375. ui_memset2d_24_sw(buf, stride, c24, len24, lines);
  376. }
  377. void ui_memset2d_32(void * buf, uint16_t stride, uint32_t c32, uint16_t len32, uint16_t lines)
  378. {
  379. ui_memset2d_32_sw(buf, stride, c32, len32, lines);
  380. }
  381. void ui_memcpy(void * dest, const void * src, size_t n)
  382. {
  383. ui_memcpy_sw(dest, src, n);
  384. }
  385. void ui_memcpy2d(void * dest, uint16_t dest_stride, const void * src,
  386. uint16_t src_stride, uint16_t len, uint16_t lines)
  387. {
  388. ui_memcpy2d_sw(dest, dest_stride, src, src_stride, len, lines);
  389. }
  390. int ui_memsetcpy_wait_finish(int timeout_ms)
  391. {
  392. return 0;
  393. }
  394. #endif /* CONFIG_DMA2D_HAL */