123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486 |
- /*
- * Copyright (c) 2020 Actions Technology Co., Ltd
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- /*********************
- * INCLUDES
- *********************/
- #include <assert.h>
- #include <display/ui_memsetcpy.h>
- #include <memory/mem_cache.h>
- #ifdef CONFIG_DMA2D_HAL
- # include <dma2d_hal.h>
- #endif
- /**********************
- * STATIC VARIABLES
- **********************/
- #ifdef CONFIG_DMA2D_HAL
- static bool dma2d_inited = false;
- static hal_dma2d_handle_t hdma2d __in_section_unique(ram.noinit.surface);
- #endif
- /**********************
- * STATIC FUNCTIONS
- **********************/
- #ifdef CONFIG_DMA2D_HAL
- static int dma_transfer_init(void)
- {
- int ret = 0;
- if (dma2d_inited)
- return 0;
- if ((ret = hal_dma2d_init(&hdma2d, HAL_DMA2D_M2M)) == 0) {
- /* initialize dma2d constant fields */
- hdma2d.output_cfg.mode = HAL_DMA2D_M2M;
- hdma2d.layer_cfg[1].alpha_mode = HAL_DMA2D_NO_MODIF_ALPHA;
- dma2d_inited = true;
- }
- return 0;
- }
- #endif /* CONFIG_DMA2D_HAL */
- static void ui_memset_sw(void * buf, uint8_t c, size_t size)
- {
- buf = mem_addr_to_uncache(buf);
- memset(buf, c, size);
- mem_writebuf_clean_all();
- }
- static void ui_memset32_sw(void * buf, uint32_t c32, size_t n32)
- {
- uint32_t *buf32 = mem_addr_to_uncache(buf);
- assert(((uintptr_t)buf32 & 0x3) == 0);
- for (; n32 >= 8; n32 -= 8) {
- *buf32++ = c32;
- *buf32++ = c32;
- *buf32++ = c32;
- *buf32++ = c32;
- *buf32++ = c32;
- *buf32++ = c32;
- *buf32++ = c32;
- *buf32++ = c32;
- }
- for (; n32 >= 4; n32 -= 4) {
- *buf32++ = c32;
- *buf32++ = c32;
- *buf32++ = c32;
- *buf32++ = c32;
- }
- for (; n32 > 0; n32 -= 1) {
- *buf32++ = c32;
- }
- mem_writebuf_clean_all();
- }
- static void ui_memset16_sw(void * buf, uint16_t c16, size_t n16)
- {
- uint32_t *buf16 = mem_addr_to_uncache(buf);
- assert(((uintptr_t)buf16 & 0x1) == 0);
- if (n16 == 0)
- return;
- /* unaligned head */
- if ((uintptr_t)buf16 & 0x3) {
- *buf16++ = c16;
- n16--;
- }
- if (n16 >= 2) {
- uint32_t c32 = ((uint32_t)c16 << 16) | c16;
- ui_memset32_sw(buf16, c32, n16 >> 1);
- }
- /* unaligned tail */
- if (n16 & 0x1) {
- buf16 += n16 & ~0x1;
- *buf16 = c16;
- }
- mem_writebuf_clean_all();
- }
- void ui_memset24_sw(void * buf, const uint8_t c24[3], size_t n24)
- {
- uint8_t *buf8 = mem_addr_to_uncache(buf);
- size_t ofs = (4 - ((uintptr_t)buf8 & 0x3)) & 0x3;
- size_t bytes = n24 * 3;
- union {
- uint32_t v32[3];
- uint8_t v8[12];
- } pattern;
- uint32_t i;
- if (bytes == 0)
- return;
- /* unaligned head */
- for (i = 0; i < ofs; i++) {
- buf8[i] = c24[i];
- }
- buf8 += ofs;
- bytes -= ofs;
- if (bytes == 0)
- return;
- /* create pattern */
- for (i = 0; i < 12; i++, ofs++) {
- if (ofs >= 3) ofs = 0;
- pattern.v8[i] = c24[ofs];
- }
- if (bytes >= 12) {
- uint32_t *buf32 = (uint32_t *)buf8;
- for (; bytes >= 12; bytes -= 12) {
- *buf32++ = pattern.v32[0];
- *buf32++ = pattern.v32[1];
- *buf32++ = pattern.v32[2];
- }
- buf8 = (uint8_t *)buf32;
- }
- /* unaligned tail */
- for (i = 0; bytes > 0; bytes--, i++) {
- *buf8++ = pattern.v8[i];
- }
- mem_writebuf_clean_all();
- }
- static void ui_memset2d_sw(void * buf, uint16_t stride, uint8_t c, uint16_t len, uint16_t lines)
- {
- uint8_t *buf8 = mem_addr_to_uncache(buf);
- if (len == stride) {
- memset(buf8, c, (uint32_t)len * lines);
- } else {
- for (; lines > 0; lines--) {
- memset(buf8, c, len);
- buf8 += stride;
- }
- }
- mem_writebuf_clean_all();
- }
- static void ui_memset2d_16_sw(void * buf, uint16_t stride, uint16_t c16, uint16_t len16, uint16_t lines)
- {
- if (len16 * 2 == stride) {
- ui_memset16_sw(buf, c16, (uint32_t)len16 * lines);
- } else {
- uint8_t *buf16 = buf;
- for (; lines > 0; lines--) {
- ui_memset16_sw(buf16, c16, len16);
- buf16 += stride;
- }
- }
- }
- static void ui_memset2d_24_sw(void * buf, uint16_t stride, const uint8_t c24[3], uint16_t len24, uint16_t lines)
- {
- if (len24 * 3 == stride) {
- ui_memset24_sw(buf, c24, (uint32_t)len24 * lines);
- } else {
- uint8_t *buf8 = buf;
- for (; lines > 0; lines--) {
- ui_memset24_sw(buf8, c24, len24);
- buf8 += stride;
- }
- }
- }
- static void ui_memset2d_32_sw(void * buf, uint16_t stride, uint32_t c32, uint16_t len32, uint16_t lines)
- {
- if (len32 * 4 == stride) {
- ui_memset16_sw(buf, c32, (uint32_t)len32 * lines);
- } else {
- uint8_t *buf32 = buf;
- for (; lines > 0; lines--) {
- ui_memset32_sw(buf32, c32, len32);
- buf32 += stride;
- }
- }
- }
- static void ui_memcpy_sw(void * dest, const void * src, size_t size)
- {
- dest = mem_addr_to_uncache(dest);
- memcpy(dest, src, size);
- mem_writebuf_clean_all();
- }
- static void ui_memcpy2d_sw(void * dest, uint16_t dest_stride, const void * src,
- uint16_t src_stride, uint16_t len, uint16_t lines)
- {
- uint8_t *dest8 = mem_addr_to_uncache(dest);
- const uint8_t *src8 = src;
- if (len == dest_stride && len == src_stride) {
- memcpy(dest8, src8, (uint32_t)len * lines);
- } else {
- for (; lines > 0; lines--) {
- memcpy(dest8, src8, len);
- dest8 += dest_stride;
- src8 += src_stride;
- }
- }
- mem_writebuf_clean_all();
- }
- /**********************
- * GLOBAL FUNCTIONS
- **********************/
- #ifdef CONFIG_DMA2D_HAL
- static int ui_memset_hw(void * buf, uint8_t c, size_t len, uint16_t lines, size_t stride)
- {
- if (dma_transfer_init() == 0) {
- hdma2d.output_cfg.mode = HAL_DMA2D_R2M;
- hdma2d.output_cfg.color_format = HAL_PIXEL_FORMAT_A8;
- hdma2d.output_cfg.output_pitch = stride;
- hal_dma2d_config_output(&hdma2d);
- return hal_dma2d_start(&hdma2d, (uint32_t)c << 24, (uint32_t)buf, len, lines);
- }
- return -ENOTSUP;
- }
- static int ui_memset16_hw(void * buf, uint16_t c16, size_t len16, uint16_t lines, size_t stride)
- {
- if (dma_transfer_init() == 0) {
- hdma2d.output_cfg.mode = HAL_DMA2D_R2M;
- hdma2d.output_cfg.color_format = HAL_PIXEL_FORMAT_RGB_565;
- hdma2d.output_cfg.output_pitch = stride;
- hal_dma2d_config_output(&hdma2d);
- uint32_t c32 = ((c16 & 0xf800) << 8) | ((c16 & 0x07e0) << 5) | ((c16 & 0x001f) << 3);
- return hal_dma2d_start(&hdma2d, c32, (uint32_t)buf, len16, lines);
- }
- return -ENOTSUP;
- }
- static int ui_memset24_hw(void * buf, const uint8_t c24[3], size_t len24, uint16_t lines, size_t stride)
- {
- if (dma_transfer_init() == 0) {
- hdma2d.output_cfg.mode = HAL_DMA2D_R2M;
- hdma2d.output_cfg.color_format = HAL_PIXEL_FORMAT_BGR_888;
- hdma2d.output_cfg.output_pitch = stride;
- hal_dma2d_config_output(&hdma2d);
- uint32_t c32 = ((uint32_t)c24[0] << 16) | ((uint32_t)c24[1] << 8) | c24[2];
- return hal_dma2d_start(&hdma2d, c32, (uint32_t)buf, len24, lines);
- }
- return -ENOTSUP;
- }
- static int ui_memset32_hw(void * buf, uint32_t c32, size_t len32, uint16_t lines, size_t stride)
- {
- if (dma_transfer_init() == 0) {
- hdma2d.output_cfg.mode = HAL_DMA2D_R2M;
- hdma2d.output_cfg.color_format = HAL_PIXEL_FORMAT_ARGB_8888;
- hdma2d.output_cfg.output_pitch = stride;
- hal_dma2d_config_output(&hdma2d);
- return hal_dma2d_start(&hdma2d, c32, (uint32_t)buf, len32, lines);
- }
- return -ENOTSUP;
- }
- void ui_memset(void * buf, uint8_t c, size_t n)
- {
- if (ui_memset_hw(buf, c, n, 1, n) < 0) {
- ui_memset_sw(buf, c, n);
- }
- }
- void ui_memset16(void * buf, uint16_t c16, size_t n16)
- {
- if (ui_memset16_hw(buf, c16, n16, 1, n16 * 2) < 0) {
- ui_memset16_sw(buf, c16, n16);
- }
- }
- void ui_memset24(void * buf, const uint8_t c24[3], size_t n24)
- {
- if (ui_memset24_hw(buf, c24, n24, 1, n24 * 3) < 0) {
- ui_memset24_sw(buf, c24, n24);
- }
- }
- void ui_memset32(void * buf, uint32_t c32, size_t n32)
- {
- if (ui_memset32_hw(buf, c32, n32, 1, n32 * 4) < 0) {
- ui_memset32_sw(buf, c32, n32);
- }
- }
- void ui_memset2d(void * buf, uint16_t stride, uint8_t c, uint16_t len, uint16_t lines)
- {
- if (ui_memset_hw(buf, c, len, lines, stride) < 0) {
- ui_memset2d_sw(buf, stride, c, len, lines);
- }
- }
- void ui_memset2d_16(void * buf, uint16_t stride, uint16_t c16, uint16_t len16, uint16_t lines)
- {
- if (ui_memset16_hw(buf, c16, len16, lines, stride) < 0) {
- ui_memset2d_16_sw(buf, stride, c16, len16, lines);
- }
- }
- void ui_memset2d_24(void * buf, uint16_t stride, const uint8_t c24[3], uint16_t len24, uint16_t lines)
- {
- if (ui_memset24_hw(buf, c24, len24, lines, stride) < 0) {
- ui_memset2d_24_sw(buf, stride, c24, len24, lines);
- }
- }
- void ui_memset2d_32(void * buf, uint16_t stride, uint32_t c32, uint16_t len32, uint16_t lines)
- {
- if (ui_memset32_hw(buf, c32, len32, lines, stride) < 0) {
- ui_memset2d_32_sw(buf, stride, c32, len32, lines);
- }
- }
- void ui_memcpy(void * dest, const void * src, size_t n)
- {
- int res = -ENOTSUP;
- if (dma_transfer_init() == 0) {
- hdma2d.output_cfg.mode = HAL_DMA2D_M2M;
- hdma2d.output_cfg.output_pitch = n;
- hdma2d.output_cfg.color_format = HAL_PIXEL_FORMAT_A8;
- hal_dma2d_config_output(&hdma2d);
- hdma2d.layer_cfg[1].color_format = HAL_PIXEL_FORMAT_A8;
- hdma2d.layer_cfg[1].input_pitch = n;
- hdma2d.layer_cfg[1].input_width = n;
- hdma2d.layer_cfg[1].input_height = 1;
- hal_dma2d_config_layer(&hdma2d, HAL_DMA2D_FOREGROUND_LAYER);
- res = hal_dma2d_start(&hdma2d, (uint32_t)src, (uint32_t)dest, n, 1);
- }
- if (res < 0) {
- ui_memcpy_sw(dest, src, n);
- }
- }
- void ui_memcpy2d(void * dest, uint16_t dest_stride, const void * src,
- uint16_t src_stride, uint16_t len, uint16_t lines)
- {
- int res = -ENOTSUP;
- if (dma_transfer_init() == 0) {
- hdma2d.output_cfg.mode = HAL_DMA2D_M2M;
- hdma2d.output_cfg.output_pitch = dest_stride;
- hdma2d.output_cfg.color_format = HAL_PIXEL_FORMAT_A8;
- hal_dma2d_config_output(&hdma2d);
- hdma2d.layer_cfg[1].color_format = HAL_PIXEL_FORMAT_A8;
- hdma2d.layer_cfg[1].input_pitch = src_stride;
- hdma2d.layer_cfg[1].input_width = len;
- hdma2d.layer_cfg[1].input_height = lines;
- hal_dma2d_config_layer(&hdma2d, HAL_DMA2D_FOREGROUND_LAYER);
- res = hal_dma2d_start(&hdma2d, (uint32_t)src, (uint32_t)dest, len, lines);
- }
- if (res < 0) {
- ui_memcpy2d_sw(dest, dest_stride, src, src_stride, len, lines);
- }
- }
- int ui_memsetcpy_wait_finish(int timeout_ms)
- {
- if (dma2d_inited) {
- return hal_dma2d_poll_transfer(&hdma2d, timeout_ms);
- }
- return 0;
- }
- #else /* CONFIG_DMA2D_HAL */
- void ui_memset(void * buf, uint8_t c, size_t n)
- {
- ui_memset_sw(buf, c, n);
- }
- void ui_memset16(void * buf, uint16_t c16, size_t n16)
- {
- ui_memset16_sw(buf, c16, n16);
- }
- void ui_memset24(void * buf, const uint8_t c24[3], size_t n24)
- {
- ui_memset24_sw(buf, c24, n24);
- }
- void ui_memset32(void * buf, uint32_t c32, size_t n32)
- {
- ui_memset32_sw(buf, c32, n32);
- }
- void ui_memset2d(void * buf, uint16_t stride, uint8_t c, uint16_t len, uint16_t lines)
- {
- ui_memset2d_sw(buf, stride, c, len, lines);
- }
- void ui_memset2d_16(void * buf, uint16_t stride, uint16_t c16, uint16_t len16, uint16_t lines)
- {
- ui_memset2d_16_sw(buf, stride, c16, len16, lines);
- }
- void ui_memset2d_24(void * buf, uint16_t stride, const uint8_t c24[3], uint16_t len24, uint16_t lines)
- {
- ui_memset2d_24_sw(buf, stride, c24, len24, lines);
- }
- void ui_memset2d_32(void * buf, uint16_t stride, uint32_t c32, uint16_t len32, uint16_t lines)
- {
- ui_memset2d_32_sw(buf, stride, c32, len32, lines);
- }
- void ui_memcpy(void * dest, const void * src, size_t n)
- {
- ui_memcpy_sw(dest, src, n);
- }
- void ui_memcpy2d(void * dest, uint16_t dest_stride, const void * src,
- uint16_t src_stride, uint16_t len, uint16_t lines)
- {
- ui_memcpy2d_sw(dest, dest_stride, src, src_stride, len, lines);
- }
- int ui_memsetcpy_wait_finish(int timeout_ms)
- {
- return 0;
- }
- #endif /* CONFIG_DMA2D_HAL */
|