de_leopard.c 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624
  1. /*
  2. * Copyright (c) 2020 Actions Technology Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <soc.h>
  7. #include <spicache.h>
  8. #include <drivers/display.h>
  9. #include <drivers/display/display_controller.h>
  10. #include <drivers/display/display_engine.h>
  11. #include <assert.h>
  12. #include <string.h>
  13. #include <sys/byteorder.h>
  14. #include <tracing/tracing.h>
  15. #include "../de_common.h"
  16. #include "../de_device.h"
  17. #include "de_leopard.h"
  18. #define DEV_DBG(...) //printk("[DE][D]: " __VA_ARGS__);
  19. #define DEV_INF(...) //printk("[DE][I]: " __VA_ARGS__);
  20. #define DEV_WRN(...) printk("[DE][W]: " __VA_ARGS__);
  21. #define DEV_ERR(...) printk("[DE][E]: " __VA_ARGS__);
  22. #define CONFIG_DE_RESET_DEV_AFTER_WB 1
  23. #define CONFIG_DE_USE_DEV_HALFULL 0 /* using halfull interrupt to post display */
  24. #define CONFIG_DE_ALPHA_SSAA 0
  25. #ifdef CONFIG_LCDC_Y_FLIP
  26. # define CONFIG_DE_DEV_Y_FLIP CONFIG_LCDC_Y_FLIP
  27. #else
  28. # define CONFIG_DE_DEV_Y_FLIP 0
  29. #endif
  30. #define CONFIG_DE_WB_Y_FLIP 0
  31. #define MAX_NUM_OVERLAYS 5
  32. #define MAX_WIDTH 512
  33. #define MAX_HEIGHT 512
  34. #define MAX_PITCH 4095
  35. #define MIN_WB_WIDTH 2
  36. #define SSAA_PIXEL_FORMATS \
  37. (PIXEL_FORMAT_A2 | PIXEL_FORMAT_A1 | PIXEL_FORMAT_A1_LE)
  38. #define ALPHA_PIXEL_FORMATS \
  39. (PIXEL_FORMAT_A8 | PIXEL_FORMAT_A4 | PIXEL_FORMAT_A4_LE | \
  40. PIXEL_FORMAT_A2 | PIXEL_FORMAT_A1 | PIXEL_FORMAT_A1_LE)
  41. #define ABMP_BITS_PIXEL_FORMATS \
  42. (PIXEL_FORMAT_A4 | PIXEL_FORMAT_A4_LE | PIXEL_FORMAT_A2 | \
  43. PIXEL_FORMAT_A1 | PIXEL_FORMAT_A1_LE | PIXEL_FORMAT_I4 | \
  44. PIXEL_FORMAT_I2 | PIXEL_FORMAT_I1)
  45. #define ABMP_PIXEL_FORMATS \
  46. (ALPHA_PIXEL_FORMATS | PIXEL_FORMAT_I8 | \
  47. PIXEL_FORMAT_I4 | PIXEL_FORMAT_I2 | PIXEL_FORMAT_I1)
  48. #define SUPPORTED_SCALING_PIXEL_FORMATS \
  49. (SUPPORTED_OUTPUT_PIXEL_FORMATS | ABMP_PIXEL_FORMATS | PIXEL_FORMAT_BGR_888 | \
  50. PIXEL_FORMAT_BGRA_5658 | PIXEL_FORMAT_BGRA_6666 | PIXEL_FORMAT_RGBA_6666 | PIXEL_FORMAT_BGR_565)
  51. #define SUPPORTED_ROTATE_PIXEL_FORMATS (PIXEL_FORMAT_ARGB_8888 | PIXEL_FORMAT_XRGB_8888 | PIXEL_FORMAT_BGR_565)
  52. #define SUPPORTED_OUTPUT_PIXEL_FORMATS \
  53. (PIXEL_FORMAT_ARGB_8888 | PIXEL_FORMAT_XRGB_8888 | PIXEL_FORMAT_RGB_888 | PIXEL_FORMAT_BGR_565)
  54. #define SUPPORTED_INPUT_PIXEL_FORMATS \
  55. (SUPPORTED_SCALING_PIXEL_FORMATS | PIXEL_FORMAT_BGRA_5551)
  56. #define GUESS_PITCH(buffer, bits_per_pixel) \
  57. ((buffer)->desc.pitch > 0 ? (buffer)->desc.pitch : ((buffer)->desc.width * (bits_per_pixel) / 8))
  58. #define GUESS_PITCH_BYTES(buffer, bytes_per_pixel) \
  59. ((buffer)->desc.pitch > 0 ? (buffer)->desc.pitch : ((buffer)->desc.width * (bytes_per_pixel)))
  60. struct de_priv_data {
  61. #if CONFIG_DE_RESET_DEV_AFTER_WB
  62. bool last_ovl_is_wb;
  63. #endif
  64. int8_t clken_count;
  65. bool nor_locked;
  66. };
  67. #define DE ((DE_Type *)DE_REG_BASE)
  68. static DE_LAYER_Type * const DE_LX[3] = {
  69. &DE->LX_CTL[0], &DE->LX_CTL[1], &DE->L2_CTL,
  70. };
  71. static struct de_priv_data de_priv_data __in_section_unique(ram.noinit.drv_de.data);
  72. __de_func static void de_clk_set_en(bool en)
  73. {
  74. unsigned int key = irq_lock();
  75. if (en) {
  76. if (de_priv_data.clken_count++ == 0)
  77. acts_clock_peripheral_enable(CLOCK_ID_DE);
  78. } else {
  79. if (--de_priv_data.clken_count == 0)
  80. acts_clock_peripheral_disable(CLOCK_ID_DE);
  81. }
  82. DEV_DBG("de: clk en %d, cnt %d\n", en, clken_count);
  83. irq_unlock(key);
  84. }
  85. __de_func static void de_set_nor_locked(bool locked)
  86. {
  87. if (locked != de_priv_data.nor_locked) {
  88. nor_xip_set_locked(locked);
  89. de_priv_data.nor_locked = locked;
  90. DEV_DBG("de: nor locked %d\n", locked);
  91. }
  92. }
  93. static void de_reset(struct de_data *data)
  94. {
  95. acts_reset_peripheral_assert(RESET_ID_DE);
  96. de_clk_set_en(true);
  97. acts_reset_peripheral_deassert(RESET_ID_DE);
  98. #if CONFIG_DE_RESET_DEV_AFTER_WB
  99. de_priv_data.last_ovl_is_wb = false;
  100. #endif
  101. DE->MEM_OPT = (DE->MEM_OPT & ~DE_MEM_BURST_LEN_MASK) | DE_MEM_BURST_32;
  102. DE->ALPHA_POS = DE_ALPHA_POS(0, 0);
  103. #if CONFIG_DE_USE_DEV_HALFULL
  104. DE->IRQ_CTL = data->display_sync_en ?
  105. DE_IRQ_WB_FTC | DE_IRQ_DEV_FTC | DE_IRQ_DEV_FIFO_HF | DE_IRQ_DEV_FIFO_UDF :
  106. DE_IRQ_WB_FTC | DE_IRQ_DEV_FTC | DE_IRQ_DEV_FIFO_HF;
  107. #else
  108. DE->IRQ_CTL = data->display_sync_en ?
  109. DE_IRQ_WB_FTC | DE_IRQ_DEV_FTC | DE_IRQ_DEV_FIFO_UDF :
  110. DE_IRQ_WB_FTC | DE_IRQ_DEV_FTC;
  111. #endif /* CONFIG_DE_USE_DEV_HALFULL */
  112. /* keep clock disabled */
  113. de_clk_set_en(false);
  114. }
  115. static int de_open(const struct device *dev, uint32_t flags)
  116. {
  117. struct de_data *data = dev->data;
  118. int inst = -EMFILE;
  119. if (data->display_sync_en && !(flags & DISPLAY_ENGINE_FLAG_POST)) {
  120. DEV_WRN("de busy in lcd-sync\n");
  121. return -1;
  122. }
  123. k_mutex_lock(&data->mutex, K_FOREVER);
  124. inst = de_alloc_instance(flags);
  125. if (inst < 0)
  126. goto out_unlock;
  127. if (data->open_count++ == 0) {
  128. de_reset(data);
  129. }
  130. out_unlock:
  131. k_mutex_unlock(&data->mutex);
  132. return inst;
  133. }
  134. static int de_close(const struct device *dev, int inst)
  135. {
  136. struct de_data *data = dev->data;
  137. int ret = -EBUSY;
  138. ret = de_instance_poll(inst, -1);
  139. if (ret < 0)
  140. return ret;
  141. k_mutex_lock(&data->mutex, K_FOREVER);
  142. de_free_instance(inst);
  143. k_mutex_unlock(&data->mutex);
  144. return 0;
  145. }
  146. void de_dump(void)
  147. {
  148. int i;
  149. de_clk_set_en(true);
  150. printk("de regs:\n");
  151. printk("\t ctl 0x%08x\n", DE->CTL);
  152. printk("\t gate_ctl 0x%08x\n", DE->GAT_CTL);
  153. printk("\t reg_ud 0x%08x\n", DE->REG_UD);
  154. printk("\t irq_ctl 0x%08x\n", DE->IRQ_CTL);
  155. printk("\t bg_size 0x%08x\n", DE->BG_SIZE);
  156. printk("\t bg_color 0x%08x\n", DE->BG_COLOR);
  157. printk("\t mem_opt 0x%08x\n", DE->MEM_OPT);
  158. printk("\t en 0x%08x\n", DE->EN);
  159. printk("\t ctl2 0x%08x\n", DE->CTL2);
  160. printk("\t ctl1 0x%08x\n", DE->CTL1);
  161. for (i = 0; i < ARRAY_SIZE(DE_LX); i++) {
  162. printk("\t l%d_pos 0x%08x\n", i, DE_LX[i]->POS);
  163. printk("\t l%d_size 0x%08x\n", i, DE_LX[i]->SIZE);
  164. printk("\t l%d_addr 0x%08x\n", i, DE_LX[i]->ADDR);
  165. printk("\t l%d_stride 0x%08x\n", i, DE_LX[i]->STRIDE);
  166. printk("\t l%d_length 0x%08x\n", i, DE_LX[i]->LENGTH);
  167. printk("\t l%d_def_color 0x%08x\n", i, DE_LX[i]->DEF_COLOR);
  168. }
  169. printk("\t alpha_ctl 0x%08x\n", DE->ALPHA_CTL);
  170. printk("\t alpha_pos 0x%08x\n", DE->ALPHA_POS);
  171. printk("\t alpha_size 0x%08x\n", DE->ALPHA_SIZE);
  172. printk("\t sta 0x%08x\n", DE->STA);
  173. printk("\t wb_addr 0x%08x\n", DE->WB_MEM_ADR);
  174. printk("\t wb_stride 0x%08x\n", DE->WB_MEM_STRIDE);
  175. printk("\t color_fill_pos 0x%08x\n", DE->COLOR_FILL_POS);
  176. printk("\t color_fill_size 0x%08x\n", DE->COLOR_FILL_SIZE);
  177. printk("\t fill_color 0x%08x\n", DE->FILL_COLOR);
  178. printk("\t lx_abmp_ctl 0x%08x\n", DE->LX_ABMP_CTL);
  179. printk("\t sc_lx_src_img_size 0x%08x\n", DE->SC_LX_SRC_IMG_SIZE);
  180. printk("\t sc_lx_rate 0x%08x\n", DE->SC_LX_RATE);
  181. printk("\t sc_lx_pos 0x%08x\n", DE->SC_LX_POS);
  182. #if 1
  183. printk("\t rt_ctl 0x%08x\n", DE->RT_CTL);
  184. printk("\t rt_img_size 0x%08x\n", DE->RT_IMG_SIZE);
  185. printk("\t rt_src_addr 0x%08x\n", DE->RT_SRC_ADDR);
  186. printk("\t rt_src_stride 0x%08x\n", DE->RT_SRC_STRIDE);
  187. printk("\t rt_dst_addr 0x%08x\n", DE->RT_DST_ADDR);
  188. printk("\t rt_dst_stride 0x%08x\n", DE->RT_DST_STRIDE);
  189. printk("\t rt_start_height 0x%08x\n", DE->RT_START_HEIGHT);
  190. printk("\t rt_sw_x_xy 0x%08x\n", DE->RT_SW_X_XY);
  191. printk("\t rt_sw_y_xy 0x%08x\n", DE->RT_SW_Y_XY);
  192. printk("\t rt_sw_x0 0x%08x\n", DE->RT_SW_X0);
  193. printk("\t rt_sw_y0 0x%08x\n", DE->RT_SW_Y0);
  194. printk("\t rt_sw_first_dist 0x%08x\n", DE->RT_SW_FIRST_DIST);
  195. printk("\t rt_r1m2 0x%08x\n", DE->RT_R1M2);
  196. printk("\t rt_r0m2 0x%08x\n", DE->RT_R0M2);
  197. printk("\t rt_fill_color 0x%08x\n", DE->RT_FILL_COLOR);
  198. printk("\t rt_src_img_size 0x%08x\n", DE->RT_SRC_IMG_SIZE);
  199. #endif
  200. de_clk_set_en(false);
  201. }
  202. __de_func static void de_apply_overlay(struct de_data *data, struct de_command_entry *entry)
  203. {
  204. de_overlay_cfg_t *cfg = (de_overlay_cfg_t *)entry->cfg;
  205. display_rect_t area = {
  206. .x = cfg->x, .y = cfg->y,
  207. .w = cfg->w, .h = cfg->h,
  208. };
  209. int8_t idx;
  210. sys_trace_u32x3(SYS_TRACE_ID_DE_DRAW, entry->cmd, cfg->w, cfg->h);
  211. if (cfg->wb_addr == 0) {
  212. #if CONFIG_DE_RESET_DEV_AFTER_WB
  213. if (de_priv_data.last_ovl_is_wb) {
  214. de_priv_data.last_ovl_is_wb = false;
  215. de_reset(data);
  216. }
  217. #endif
  218. if (data->prepare_fn)
  219. data->prepare_fn(data->prepare_fn_arg, &area);
  220. } else {
  221. #if CONFIG_DE_RESET_DEV_AFTER_WB
  222. de_priv_data.last_ovl_is_wb = true;
  223. #endif
  224. DE->WB_MEM_ADR = cfg->wb_addr;
  225. DE->WB_MEM_STRIDE = cfg->wb_stride;
  226. }
  227. if (cfg->ctl & DE_CTL_OUT_COLOR_FILL_EN) {
  228. DE->FILL_COLOR = cfg->fill_color;
  229. DE->COLOR_FILL_POS = cfg->color_fill_pos;
  230. DE->COLOR_FILL_SIZE = cfg->color_fill_size;
  231. }
  232. /* set default bg */
  233. DE->CTL = cfg->ctl;
  234. DE->CTL1 = cfg->ctl1;
  235. DE->GAT_CTL = DE_OVERLAY_GAT_EN;
  236. DE->BG_COLOR = cfg->bg_color;
  237. DE->BG_SIZE = DE_BG_SIZE(cfg->w, cfg->h);
  238. DE->ALPHA_CTL = cfg->alpha_ctl;
  239. if (cfg->n_layers == 0) {
  240. goto out_exit;
  241. }
  242. #if 0
  243. if (cfg->blend_idx > 0) {
  244. /* keep the same as blend layer area */
  245. DE->ALPHA_POS = cfg->layers[cfg->blend_idx].pos;
  246. DE->ALPHA_SIZE = cfg->layers[cfg->blend_idx].size;
  247. }
  248. #else
  249. DE->ALPHA_SIZE = DE_BG_SIZE(cfg->w, cfg->h);
  250. #endif
  251. DE->LX_ABMP_CTL = cfg->lx_abmp_ctl;
  252. for (idx = 2; cfg->n_layers > 0; cfg->n_layers--, idx--) {
  253. DE_LX[idx]->POS = cfg->layers[idx].pos;
  254. DE_LX[idx]->SIZE = cfg->layers[idx].size;
  255. DE_LX[idx]->ADDR = cfg->layers[idx].addr;
  256. DE_LX[idx]->STRIDE = cfg->layers[idx].stride;
  257. DE_LX[idx]->LENGTH = cfg->layers[idx].length;
  258. DE_LX[idx]->DEF_COLOR = cfg->layers[idx].def_color;
  259. }
  260. /* only one rotation regs mapping */
  261. if (cfg->has_rotation) {
  262. DE_LX[2]->RT_SRC_SIZE = cfg->rotate.src_size;
  263. DE_LX[2]->RT_SW_X_XY = cfg->rotate.sw_x_xy;
  264. DE_LX[2]->RT_SW_Y_XY = cfg->rotate.sw_y_xy;
  265. DE_LX[2]->RT_SW_X0 = cfg->rotate.sw_x0;
  266. DE_LX[2]->RT_SW_Y0 = cfg->rotate.sw_y0;
  267. }
  268. if (cfg->has_scaling) {
  269. DE->SC_LX_SRC_IMG_SIZE = cfg->scaling.sc_lx_src_size;
  270. DE->SC_LX_RATE = cfg->scaling.sc_lx_rate;
  271. DE->SC_LX_POS = cfg->scaling.sc_lx_pos;
  272. }
  273. if (cfg->has_nor_access)
  274. de_set_nor_locked(true);
  275. out_exit:
  276. /*
  277. * sequence:
  278. * 1) modify configuration registers
  279. * 2) modify REG_UD=1
  280. * 3) modify EN=1
  281. * 4) make sure EN is really 1 (read and compare with 1)
  282. * 5) REG_UD becomes 0
  283. * 6) hw START
  284. **/
  285. DE->REG_UD = 1;
  286. if (DE->EN == 0) {
  287. if (data->display_sync_en == 0) {
  288. k_work_schedule(&data->timeout_work,
  289. K_MSEC(CONFIG_DISPLAY_ENGINE_COMMAND_TIMEOUT_MS));
  290. }
  291. DE->EN = 1;
  292. while (DE->EN == 0);
  293. /* REG_UD (active after EN) and CTL2 written must be close enough */
  294. DE->CTL2 = DE_CTL2_RGB_CVT_LOW | DE_CTL2_START;
  295. #if CONFIG_DE_USE_DEV_HALFULL == 0
  296. if (cfg->wb_addr == 0 && data->start_fn) {
  297. data->start_fn(data->start_fn_arg);
  298. }
  299. #endif /* CONFIG_DE_USE_DEV_HALFULL */
  300. }
  301. }
  302. __de_func static void de_apply_transform(struct de_data *data, struct de_command_entry *entry)
  303. {
  304. de_transform_cfg_t *cfg = (de_transform_cfg_t *)entry->cfg;
  305. sys_trace_u32x3(SYS_TRACE_ID_DE_DRAW, DE_CMD_ROTATE_CIRCLE,
  306. cfg->img_size & 0x1FF, (cfg->img_size >> 16) - cfg->start_height);
  307. DE->GAT_CTL = DE_ROTATE_GAT_EN;
  308. DE->EN = 1;
  309. DE->RT_DST_ADDR = cfg->dst_addr;
  310. DE->RT_DST_STRIDE = cfg->dst_stride;
  311. DE->RT_FILL_COLOR = cfg->fill_color;
  312. DE->RT_IMG_SIZE = cfg->img_size;
  313. if (entry->cmd != DE_CMD_ROTATE_FILL) {
  314. if (entry->cmd == DE_CMD_ROTATE_RECT) {
  315. DE->RT_SRC_IMG_SIZE = cfg->src_img_size;
  316. DE->RT_START_HEIGHT = 0;
  317. } else {
  318. DE->RT_R1M2 = cfg->r1m2;
  319. DE->RT_R0M2 = cfg->r0m2;
  320. DE->RT_SW_FIRST_DIST = cfg->sw_first_dist;
  321. DE->RT_START_HEIGHT = cfg->start_height;
  322. }
  323. DE->RT_SRC_ADDR = cfg->src_addr;
  324. DE->RT_SRC_STRIDE = cfg->src_stride;
  325. DE->RT_SW_X_XY = cfg->sw_x_xy;
  326. DE->RT_SW_Y_XY = cfg->sw_y_xy;
  327. DE->RT_SW_X0 = cfg->sw_x0;
  328. DE->RT_SW_Y0 = cfg->sw_y0;
  329. }
  330. k_work_schedule(&data->timeout_work,
  331. K_MSEC(CONFIG_DISPLAY_ENGINE_COMMAND_TIMEOUT_MS));
  332. DE->RT_CTL = cfg->ctl;
  333. }
  334. __de_func static void de_apply_clut(struct de_data *data, struct de_command_entry *entry)
  335. {
  336. de_clut_cfg_t *cfg = (de_clut_cfg_t *)entry->cfg;
  337. //DE->GAT_CTL = DE_OVERLAY_GAT_EN;
  338. //DE->LX_ABMP_CTL = BIT(3) | BIT(11) | BIT(19); /* all layer clut enabled */
  339. DE->CLUT_CTL = DE_CLUT_TAB_SEL(cfg->layer_idx) | DE_CLUT_TAB_IDX(0);
  340. for (; cfg->size > 0; cfg->size--) {
  341. DE->CLUT_DATA = *cfg->clut++;
  342. }
  343. //DE->GAT_CTL = 0;
  344. }
  345. __de_func static void de_process_next_cmd(struct de_data *data, bool skipped)
  346. {
  347. struct de_command_entry *entry;
  348. sys_snode_t *node = NULL;
  349. bool is_sw_cmd;
  350. do {
  351. is_sw_cmd = skipped;
  352. #ifdef CONFIG_DISPLAY_ENGINE_HIHG_PRIO_INSTANCE
  353. if (data->cmd_node) {
  354. node = sys_slist_peek_head(&data->high_cmd_list);
  355. if (node == data->cmd_node) {
  356. sys_slist_remove(&data->high_cmd_list, NULL, data->cmd_node);
  357. } else {
  358. assert(data->cmd_node == sys_slist_peek_head(&data->cmd_list));
  359. sys_slist_remove(&data->cmd_list, NULL, data->cmd_node);
  360. }
  361. data->cmd_num--;
  362. }
  363. #else /* CONFIG_DISPLAY_ENGINE_HIHG_PRIO_INSTANCE */
  364. if (data->cmd_node) {
  365. assert(data->cmd_node == sys_slist_peek_head(&data->cmd_list));
  366. sys_slist_remove(&data->cmd_list, NULL, data->cmd_node);
  367. data->cmd_num--;
  368. }
  369. #endif /* CONFIG_DISPLAY_ENGINE_HIHG_PRIO_INSTANCE */
  370. /* find and execute next command */
  371. #ifdef CONFIG_DISPLAY_ENGINE_HIHG_PRIO_INSTANCE
  372. node = sys_slist_peek_head(&data->high_cmd_list);
  373. if (!node)
  374. node = sys_slist_peek_head(&data->cmd_list);
  375. #else /* CONFIG_DISPLAY_ENGINE_HIHG_PRIO_INSTANCE */
  376. node = sys_slist_peek_head(&data->cmd_list);
  377. #endif /* CONFIG_DISPLAY_ENGINE_HIHG_PRIO_INSTANCE */
  378. /* unlock nor access */
  379. de_set_nor_locked(false);
  380. if (node) {
  381. if (data->cmd_node == NULL) /* new command from idle */
  382. de_clk_set_en(true);
  383. entry = CONTAINER_OF(node, struct de_command_entry, node);
  384. if (skipped == false) {
  385. switch (entry->cmd) {
  386. case DE_CMD_ROTATE_FILL:
  387. case DE_CMD_ROTATE_RECT:
  388. case DE_CMD_ROTATE_CIRCLE:
  389. de_apply_transform(data, entry);
  390. break;
  391. case DE_CMD_SET_CLUT:
  392. de_apply_clut(data, entry);
  393. data->cmd_status = 0;
  394. is_sw_cmd = true;
  395. break;
  396. default:
  397. de_apply_overlay(data, entry);
  398. break;
  399. }
  400. }
  401. } else { /* no more commands, become idle */
  402. de_clk_set_en(false);
  403. if (data->waiting) {
  404. data->waiting = 0;
  405. k_sem_give(&data->wait_sem);
  406. }
  407. }
  408. /* free previous command entry */
  409. if (data->cmd_node) {
  410. entry = CONTAINER_OF(data->cmd_node, struct de_command_entry, node);
  411. de_instance_notify(entry, data->cmd_status);
  412. de_instance_free_entry(entry);
  413. }
  414. /* point to the new command */
  415. data->cmd_node = node;
  416. } while (is_sw_cmd);
  417. }
  418. __de_func static void de_complete_cmd(struct de_data *data, int status)
  419. {
  420. sys_trace_end_call(SYS_TRACE_ID_DE_DRAW);
  421. if (data->display_sync_en == 0) {
  422. DE->EN = 0;
  423. DE->RT_CTL = RT_STAT_COMPLETE;
  424. DE->GAT_CTL = 0;
  425. }
  426. data->cmd_status = status;
  427. de_process_next_cmd(data, false);
  428. }
  429. static void de_cleanup_all_cmd(struct de_data *data)
  430. {
  431. unsigned int key = irq_lock();
  432. while (data->cmd_num > 0) {
  433. de_process_next_cmd(data, true);
  434. }
  435. irq_unlock(key);
  436. }
  437. __de_func static void de_append_cmd(struct de_data *data, struct de_command_entry *entry, bool high_prio)
  438. {
  439. unsigned int key = irq_lock();
  440. #ifdef CONFIG_DISPLAY_ENGINE_HIHG_PRIO_INSTANCE
  441. if (high_prio) {
  442. sys_slist_append(&data->high_cmd_list, &entry->node);
  443. } else {
  444. sys_slist_append(&data->cmd_list, &entry->node);
  445. }
  446. #else
  447. sys_slist_append(&data->cmd_list, &entry->node);
  448. #endif
  449. if (++data->cmd_num == 1) {
  450. de_process_next_cmd(data, false);
  451. }
  452. irq_unlock(key);
  453. }
  454. __de_func static int _validate_layers(const display_layer_t *layers, uint8_t num_ovls, bool *allow_ssaa)
  455. {
  456. bool has_rotation = false;
  457. bool has_scaling = false;
  458. uint8_t bpp;
  459. /* validate layer parameters */
  460. for (int i = 0; i < num_ovls; i++) {
  461. if (!layers[i].buffer) {
  462. continue;
  463. }
  464. if ((layers[i].buffer->desc.pixel_format & SUPPORTED_INPUT_PIXEL_FORMATS) == 0) {
  465. DEV_WRN("L%d format 0x%x unsupported\n", i, layers[i].buffer->desc.pixel_format);
  466. return -EINVAL;
  467. }
  468. if (layers[i].buffer->desc.width > MAX_WIDTH ||
  469. layers[i].buffer->desc.height > MAX_HEIGHT ||
  470. layers[i].buffer->desc.pitch > MAX_PITCH) {
  471. DEV_WRN("L%d size %dx%d pitch %d too large\n", i, layers[i].buffer->desc.width,
  472. layers[i].buffer->desc.height, layers[i].buffer->desc.pitch);
  473. return -EINVAL;
  474. }
  475. bpp = display_format_get_bits_per_pixel(layers[i].buffer->desc.pixel_format);
  476. if ((bpp == 16 && ((layers[i].buffer->addr & 0x1) || (layers[i].buffer->desc.pitch & 0x1))) ||
  477. (bpp == 32 && ((layers[i].buffer->addr & 0x3) || (layers[i].buffer->desc.pitch & 0x3)))) {
  478. DEV_WRN("L%d format 0x%x addr 0x%x pitch %d unaligned\n", i,
  479. layers[i].buffer->desc.pixel_format, layers[i].buffer->addr,
  480. layers[i].buffer->desc.pitch);
  481. return -EINVAL;
  482. }
  483. if (layers[i].frame.w <= 0 || layers[i].frame.w > MAX_WIDTH ||
  484. layers[i].frame.h <= 0 || layers[i].frame.h > MAX_HEIGHT) {
  485. DEV_WRN("L%d size %u x %u invalid\n", i, layers[i].frame.w, layers[i].frame.h);
  486. return -EINVAL;
  487. }
  488. if (layers[i].matrix) {
  489. if (has_rotation || (i == 0 && num_ovls >= 3)) {
  490. DEV_WRN("L%d already has or unsupport rotation\n", i);
  491. return -EINVAL;
  492. }
  493. if ((layers[i].buffer->desc.pixel_format & SUPPORTED_ROTATE_PIXEL_FORMATS) == 0) {
  494. DEV_WRN("L%d format 0x%x not support rotation\n", i, layers[i].buffer->desc.pixel_format);
  495. return -EINVAL;
  496. }
  497. has_rotation = true;
  498. /* no need to check scaling */
  499. continue;
  500. }
  501. if (layers[i].frame.w != layers[i].buffer->desc.width ||
  502. layers[i].frame.h != layers[i].buffer->desc.height) {
  503. if (has_scaling || (i == 0 && num_ovls >= 3)) {
  504. DEV_WRN("L%d already has or unsupport scaling\n", i);
  505. return -EINVAL;
  506. }
  507. if ((layers[i].buffer->desc.pixel_format & SUPPORTED_SCALING_PIXEL_FORMATS) == 0) {
  508. DEV_WRN("L%d format 0x%x not support scaling\n", i, layers[i].buffer->desc.pixel_format);
  509. return -EINVAL;
  510. }
  511. /* only need to check scaling down factor */
  512. if (layers[i].frame.w * 15 < layers[i].buffer->desc.width ||
  513. layers[i].frame.h * 15 < layers[i].buffer->desc.height) {
  514. DEV_WRN("L%d scaling exceed [1/15, 4096]: (%u, %u) -> (%u, %u)\n", i,
  515. layers[i].buffer->desc.width, layers[i].buffer->desc.height,
  516. layers[i].frame.w, layers[i].frame.h);
  517. return -EINVAL;
  518. }
  519. if (layers[i].buffer->desc.pixel_format & ABMP_BITS_PIXEL_FORMATS) {
  520. uint16_t width_bits = layers[i].buffer->desc.width * bpp;
  521. if (layers[i].buffer->desc.pitch == 0 && (width_bits & 0x7)) {
  522. DEV_WRN("L%d format %x not support both scaling and no-stride\n", i,
  523. layers[i].buffer->desc.pixel_format);
  524. return -EINVAL;
  525. }
  526. }
  527. has_scaling = true;
  528. }
  529. if (layers[i].buffer->desc.pixel_format & ABMP_BITS_PIXEL_FORMATS) {
  530. if (layers[i].buffer->px_ofs * bpp >= 8 ||
  531. (layers[i].buffer->px_ofs > 0 && layers[i].buffer->desc.pitch == 0)) {
  532. DEV_WRN("L%d format %x px_ofs %u invalid\n", i,
  533. layers[i].buffer->desc.pixel_format, layers[i].buffer->px_ofs);
  534. return -EINVAL;
  535. }
  536. }
  537. }
  538. #if CONFIG_DE_ALPHA_SSAA
  539. *allow_ssaa = !has_scaling;
  540. #endif
  541. return 0;
  542. }
  543. __de_func static void _config_layer_scaling(de_overlay_cfg_t *cfg, const display_layer_t *layer, uint8_t idx)
  544. {
  545. uint16_t x_off = 0;
  546. uint16_t y_off = 0;
  547. uint16_t h_rate = 4096, v_rate = 4096;
  548. if (layer->buffer->desc.width == layer->frame.w && layer->buffer->desc.height == layer->frame.h) {
  549. x_off = 1024; /* SSAA: offset 1/4 pixel */
  550. y_off = 1024;
  551. } else {
  552. if (layer->frame.w > 1)
  553. h_rate = ((layer->buffer->desc.width - 1) * 4096 - x_off) / (layer->frame.w - 1);
  554. if (layer->frame.h > 1)
  555. v_rate = ((layer->buffer->desc.height - 1) * 4096 - y_off) / (layer->frame.h - 1);
  556. }
  557. cfg->scaling.sc_lx_rate = SC_LX_RATE(h_rate, v_rate);
  558. cfg->scaling.sc_lx_src_size = SC_LX_SRC_IMG_SIZE(layer->buffer->desc.width, layer->buffer->desc.height);
  559. cfg->scaling.sc_lx_pos = SC_LX_POS(x_off, y_off);
  560. cfg->has_scaling = 1;
  561. }
  562. __de_func static void _config_layer_rotation(de_overlay_cfg_t *cfg, const display_layer_t *layer,
  563. uint8_t idx, uint8_t bpp, bool y_flip)
  564. {
  565. const display_matrix_t *matrix = layer->matrix;
  566. const display_buffer_t *buffer = layer->buffer;
  567. int32_t pitch = GUESS_PITCH(buffer, bpp);
  568. if (y_flip) {
  569. cfg->rotate.sw_x0 = matrix->tx + (layer->frame.h - 1) * matrix->shx;
  570. cfg->rotate.sw_y0 = matrix->ty + (layer->frame.h - 1) * matrix->sy;
  571. cfg->rotate.sw_y_xy = DE_LX_RT_DELTA_XY(-matrix->shx, -matrix->sy);
  572. } else {
  573. cfg->rotate.sw_x0 = matrix->tx;
  574. cfg->rotate.sw_y0 = matrix->ty;
  575. cfg->rotate.sw_y_xy = DE_LX_RT_DELTA_XY(matrix->shx, matrix->sy);
  576. }
  577. cfg->rotate.sw_x_xy = DE_LX_RT_DELTA_XY(matrix->sx, matrix->shy);
  578. cfg->layers[idx].addr += (cfg->rotate.sw_y0 >> 12) * pitch +
  579. (cfg->rotate.sw_x0 >> 12) * bpp / 8;
  580. cfg->rotate.src_size = DE_LX_RT_SRC_SIZE(buffer->desc.width, buffer->desc.height);
  581. cfg->has_rotation = 1;
  582. }
  583. __de_func static void _config_layers(de_overlay_cfg_t *cfg, const display_layer_t *layer,
  584. uint8_t idx, bool y_flip, bool allow_ssaa)
  585. {
  586. static const struct {
  587. uint32_t pixel_format;
  588. uint32_t lx_format[3];
  589. uint32_t abmp_format[3];
  590. uint8_t bpp;
  591. } layer_formats[] = {
  592. {
  593. PIXEL_FORMAT_ARGB_8888,
  594. { DE_L0_FORMAT_ARGB_8888, DE_L1_FORMAT_ARGB_8888, DE_L2_FORMAT_ARGB_8888 },
  595. { 0, 0, 0 }, 32,
  596. },
  597. {
  598. PIXEL_FORMAT_XRGB_8888,
  599. { DE_L0_FORMAT_XRGB_8888, DE_L1_FORMAT_XRGB_8888, DE_L2_FORMAT_XRGB_8888 },
  600. { 0, 0, 0 }, 32,
  601. },
  602. {
  603. PIXEL_FORMAT_BGRA_5658,
  604. { DE_L0_FORMAT_ARGB_8565, DE_L1_FORMAT_ARGB_8565, DE_L2_FORMAT_ARGB_8565 },
  605. { 0, 0, 0 }, 24,
  606. },
  607. {
  608. PIXEL_FORMAT_BGRA_6666,
  609. { DE_L0_FORMAT_ARGB_6666, DE_L1_FORMAT_ARGB_6666, DE_L2_FORMAT_ARGB_6666 },
  610. { 0, 0, 0 }, 24,
  611. },
  612. {
  613. PIXEL_FORMAT_RGBA_6666,
  614. { DE_L0_FORMAT_ABGR_6666, DE_L1_FORMAT_ABGR_6666, DE_L2_FORMAT_ABGR_6666 },
  615. { 0, 0, 0 }, 24,
  616. },
  617. {
  618. PIXEL_FORMAT_BGR_565,
  619. { DE_L0_FORMAT_RGB_565, DE_L1_FORMAT_RGB_565, DE_L2_FORMAT_RGB_565 },
  620. { 0, 0, 0 }, 16,
  621. },
  622. {
  623. PIXEL_FORMAT_RGB_565,
  624. { DE_L0_FORMAT_RGB_565_SWAP, DE_L1_FORMAT_RGB_565_SWAP, DE_L2_FORMAT_RGB_565_SWAP },
  625. { 0, 0, 0 }, 16,
  626. },
  627. {
  628. PIXEL_FORMAT_RGB_888,
  629. { DE_L0_FORMAT_RGB_888, DE_L1_FORMAT_RGB_888, DE_L2_FORMAT_RGB_888 },
  630. { 0, 0, 0 }, 24,
  631. },
  632. {
  633. PIXEL_FORMAT_BGR_888,
  634. { DE_L0_FORMAT_BGR_888, DE_L1_FORMAT_BGR_888, DE_L2_FORMAT_BGR_888 },
  635. { 0, 0, 0 }, 24,
  636. },
  637. {
  638. PIXEL_FORMAT_BGRA_5551,
  639. { DE_L0_FORMAT_ARGB_1555, DE_L1_FORMAT_ARGB_1555, DE_L2_FORMAT_ARGB_1555 },
  640. { 0, 0, 0 }, 16,
  641. },
  642. {
  643. PIXEL_FORMAT_I8,
  644. { DE_L0_FORMAT_ABMP_INDEX, DE_L1_FORMAT_ABMP_INDEX, DE_L2_FORMAT_ABMP_INDEX },
  645. { DE_L0_INDEX_8, DE_L1_INDEX_8, DE_L2_INDEX_8 },
  646. 8,
  647. },
  648. {
  649. PIXEL_FORMAT_I4,
  650. { DE_L0_FORMAT_ABMP_INDEX, DE_L1_FORMAT_ABMP_INDEX, DE_L2_FORMAT_ABMP_INDEX },
  651. { DE_L0_INDEX_4, DE_L1_INDEX_4, DE_L2_INDEX_4 },
  652. 4,
  653. },
  654. {
  655. PIXEL_FORMAT_I2,
  656. { DE_L0_FORMAT_ABMP_INDEX, DE_L1_FORMAT_ABMP_INDEX, DE_L2_FORMAT_ABMP_INDEX },
  657. { DE_L0_INDEX_2, DE_L1_INDEX_2, DE_L2_INDEX_2 },
  658. 2,
  659. },
  660. {
  661. PIXEL_FORMAT_I1,
  662. { DE_L0_FORMAT_ABMP_INDEX, DE_L1_FORMAT_ABMP_INDEX, DE_L2_FORMAT_ABMP_INDEX },
  663. { DE_L0_INDEX_1, DE_L1_INDEX_1, DE_L2_INDEX_1 },
  664. 1,
  665. },
  666. {
  667. PIXEL_FORMAT_A8,
  668. { DE_L0_FORMAT_ABMP_INDEX, DE_L1_FORMAT_ABMP_INDEX, DE_L2_FORMAT_ABMP_INDEX },
  669. { DE_L0_ALPHA_8, DE_L1_ALPHA_8, DE_L2_ALPHA_8 },
  670. 8,
  671. },
  672. {
  673. PIXEL_FORMAT_A4,
  674. { DE_L0_FORMAT_ABMP_INDEX, DE_L1_FORMAT_ABMP_INDEX, DE_L2_FORMAT_ABMP_INDEX },
  675. { DE_L0_ALPHA_4, DE_L1_ALPHA_4, DE_L2_ALPHA_4 },
  676. 4,
  677. },
  678. {
  679. PIXEL_FORMAT_A2,
  680. { DE_L0_FORMAT_ABMP_INDEX, DE_L1_FORMAT_ABMP_INDEX, DE_L2_FORMAT_ABMP_INDEX },
  681. { DE_L0_ALPHA_2, DE_L1_ALPHA_2, DE_L2_ALPHA_2 },
  682. 2,
  683. },
  684. {
  685. PIXEL_FORMAT_A1,
  686. { DE_L0_FORMAT_ABMP_INDEX, DE_L1_FORMAT_ABMP_INDEX, DE_L2_FORMAT_ABMP_INDEX },
  687. { DE_L0_ALPHA_1, DE_L1_ALPHA_1, DE_L2_ALPHA_1 },
  688. 1,
  689. },
  690. {
  691. PIXEL_FORMAT_A4_LE,
  692. { DE_L0_FORMAT_ABMP_INDEX, DE_L1_FORMAT_ABMP_INDEX, DE_L2_FORMAT_ABMP_INDEX },
  693. { DE_L0_ALPHA_4_LE, DE_L1_ALPHA_4_LE, DE_L2_ALPHA_4_LE },
  694. 4,
  695. },
  696. {
  697. PIXEL_FORMAT_A1_LE,
  698. { DE_L0_FORMAT_ABMP_INDEX, DE_L1_FORMAT_ABMP_INDEX, DE_L2_FORMAT_ABMP_INDEX },
  699. { DE_L0_ALPHA_1_LE, DE_L1_ALPHA_1_LE, DE_L2_ALPHA_1_LE },
  700. 1,
  701. },
  702. };
  703. const display_buffer_t *buffer = layer->buffer;
  704. bool has_transform = false;
  705. uint32_t lx_format = 0;
  706. uint32_t abmp_format = 0;
  707. uint8_t fill_en = 0;
  708. uint8_t no_stride_en = 0;
  709. uint8_t abmp_bitofs = 0;
  710. uint8_t i;
  711. if (buffer) {
  712. uint16_t pitch_bits, width_bits;
  713. for (i = 0; i < ARRAY_SIZE(layer_formats); i++) {
  714. if (buffer->desc.pixel_format == layer_formats[i].pixel_format) {
  715. break;
  716. }
  717. }
  718. __ASSERT(i < ARRAY_SIZE(layer_formats), "format 0x%x support not added", buffer->desc.pixel_format);
  719. if (i >= ARRAY_SIZE(layer_formats)) { /* Make Klocwork Static Code check happpy */
  720. k_panic();
  721. return;
  722. }
  723. lx_format = layer_formats[i].lx_format[idx];
  724. abmp_format = layer_formats[i].abmp_format[idx];
  725. has_transform = layer->matrix || (buffer->desc.width != layer->frame.w) ||
  726. (buffer->desc.height != layer->frame.h);
  727. if ((buffer->desc.pixel_format & ABMP_BITS_PIXEL_FORMATS))
  728. abmp_bitofs = buffer->px_ofs * layer_formats[i].bpp;
  729. width_bits = buffer->desc.width * layer_formats[i].bpp;
  730. pitch_bits = (buffer->desc.pitch > 0) ? (buffer->desc.pitch * 8) : width_bits;
  731. #if CONFIG_DE_ALPHA_SSAA
  732. if (!has_transform && (buffer->desc.pixel_format & SSAA_PIXEL_FORMATS)) {
  733. if (allow_ssaa && !cfg->has_scaling && idx > 0 && !(pitch_bits & 0x7)) {
  734. has_transform = true;
  735. }
  736. }
  737. #endif
  738. no_stride_en = (!y_flip && !has_transform && pitch_bits == width_bits && abmp_bitofs == 0);
  739. cfg->lx_abmp_ctl |= abmp_format;
  740. if (buf_is_nor((void *)buffer->addr)) {
  741. cfg->has_nor_access = 1;
  742. cfg->layers[idx].addr = (uint32_t)cache_to_uncache_by_master(
  743. (void *)buffer->addr, SPI0_CACHE_MASTER_DE);
  744. } else {
  745. cfg->layers[idx].addr = (uint32_t)cache_to_uncache((void *)buffer->addr);
  746. }
  747. cfg->layers[idx].stride = pitch_bits / 8; /* only used by stride mode */
  748. cfg->layers[idx].length = ((uint32_t)pitch_bits * buffer->desc.height + 7) / 8; /* only used by no-stride mode */
  749. cfg->layers[idx].def_color = (layer->color.full & 0xFFFFFF); /* donot double use the alpha for the global alpha */
  750. } else {
  751. fill_en = 1;
  752. cfg->layers[idx].addr = 0;
  753. cfg->layers[idx].def_color = layer->color.full;
  754. }
  755. if (idx == 0) {
  756. cfg->lx_abmp_ctl |= DE_L0_ABMP_BITOFS(abmp_bitofs);
  757. cfg->ctl |= DE_L0_EN | lx_format | DE_L0_NO_STRIDE_EN(no_stride_en) | DE_L0_COLOR_FILL_EN(fill_en);
  758. } else {
  759. if (idx == 1) {
  760. cfg->lx_abmp_ctl |= DE_L1_ABMP_BITOFS(abmp_bitofs);
  761. cfg->ctl |= DE_L1_EN | lx_format | DE_L1_NO_STRIDE_EN(no_stride_en) | DE_L1_COLOR_FILL_EN(fill_en);
  762. if (has_transform)
  763. cfg->ctl |= layer->matrix ? DE_L1_RT_EN : DE_L1_SC_EN;
  764. } else {
  765. cfg->lx_abmp_ctl |= DE_L2_ABMP_BITOFS(abmp_bitofs);
  766. cfg->ctl1 = DE_L2_EN | lx_format | DE_L2_NO_STRIDE_EN(no_stride_en) | DE_L2_COLOR_FILL_EN(fill_en);
  767. if (has_transform)
  768. cfg->ctl1 |= layer->matrix ? DE_L2_RT_EN : DE_L2_SC_EN;
  769. }
  770. /* configure blending */
  771. if (layer->blending != DISPLAY_BLENDING_NONE) {
  772. if (cfg->blend_idx == 0) {
  773. uint32_t alpha_mode = (layer->blending == DISPLAY_BLENDING_PREMULT) ?
  774. DE_ALPHA_PREMULTIPLIED : DE_ALPHA_COVERAGE;
  775. /* don't double use the color alpha */
  776. uint8_t alpha = buffer ? layer->color.a : 255;
  777. /* DE will only blend the pixels both inside ALPHA_AREA and L0 & L1 & L2 */
  778. cfg->alpha_ctl = DE_ALPHA_EN | alpha_mode | DE_ALPHA_PLANE_ALPHA(alpha);
  779. cfg->blend_idx = idx;
  780. }
  781. }
  782. }
  783. if (y_flip) {
  784. cfg->layers[idx].pos = DE_LX_POS(layer->frame.x - cfg->x,
  785. cfg->h - (layer->frame.y - cfg->y) - layer->frame.h);
  786. if (buffer && layer->matrix == NULL) {
  787. cfg->layers[idx].addr += cfg->layers[idx].stride * (buffer->desc.height - 1);
  788. }
  789. } else {
  790. cfg->layers[idx].pos = DE_LX_POS(layer->frame.x - cfg->x, layer->frame.y - cfg->y);
  791. }
  792. cfg->layers[idx].size = DE_LX_SIZE(layer->frame.w, layer->frame.h);
  793. if (has_transform) {
  794. if (layer->matrix) {
  795. _config_layer_rotation(cfg, layer, idx, layer_formats[i].bpp, y_flip);
  796. } else {
  797. _config_layer_scaling(cfg, layer, idx);
  798. }
  799. }
  800. }
  801. __de_func static void _config_overlay_output(struct de_data *data, de_overlay_cfg_t *cfg,
  802. const display_buffer_t *dest,
  803. struct display_rect *area, bool y_flip)
  804. {
  805. uint32_t out_format;
  806. if (dest) {
  807. uint8_t bytes_per_pixel = display_format_get_bits_per_pixel(dest->desc.pixel_format) / 8;
  808. uint16_t pitch = GUESS_PITCH_BYTES(dest, bytes_per_pixel);
  809. uint8_t no_stride_en = 0;
  810. cfg->wb_stride = pitch;
  811. cfg->wb_addr = dest->addr + area->y * cfg->wb_stride + area->x * bytes_per_pixel;
  812. cfg->wb_addr = (uint32_t)cache_to_uncache((void *)cfg->wb_addr);
  813. if (y_flip) {
  814. cfg->wb_addr += cfg->wb_stride * (area->h - 1);
  815. } else {
  816. /* no-stride requires both the address and stride 4-byte aligned */
  817. no_stride_en = !(cfg->wb_addr & 0x3) && !(cfg->wb_stride & 0x3) &&
  818. (cfg->wb_stride == area->w * bytes_per_pixel);
  819. }
  820. cfg->ctl = DE_CTL_TRANSFER_MODE_TRIGGER | DE_CTL_OUT_MODE_WB |
  821. DE_CTL_WB_NO_STRIDE_EN(no_stride_en) | DE_CTL_OUT_WB_YFLIP_EN(y_flip);
  822. out_format = dest->desc.pixel_format;
  823. } else {
  824. cfg->wb_addr = 0; /* flag */
  825. cfg->ctl = DE_CTL_OUT_MODE_DISPLAY | (data->display_sync_en ?
  826. DE_CTL_TRANSFER_MODE_CONTINUE : DE_CTL_TRANSFER_MODE_TRIGGER) |
  827. DE_CTL_OUT_DISPLY_YFLIP_EN(y_flip);
  828. out_format = data->display_format;
  829. }
  830. switch (out_format) {
  831. case PIXEL_FORMAT_BGR_565:
  832. cfg->ctl |= DE_CTL_OUT_FORMAT_RGB565;
  833. break;
  834. case PIXEL_FORMAT_ARGB_8888:
  835. cfg->ctl |= DE_CTL_OUT_FORMAT_RGB888_WB_ARGB8888;
  836. break;
  837. case PIXEL_FORMAT_XRGB_8888:
  838. cfg->ctl |= DE_CTL_OUT_FORMAT_RGB888_WB_XRGB8888;
  839. break;
  840. case PIXEL_FORMAT_RGB_888:
  841. default:
  842. cfg->ctl |= DE_CTL_OUT_FORMAT_RGB888;
  843. break;
  844. }
  845. /* set default bg */
  846. cfg->w = area->w;
  847. cfg->h = area->h;
  848. }
  849. __de_func static int de_insert_overlay_cmd(const struct device *dev, int inst,
  850. const display_buffer_t *dest,
  851. const display_layer_t *layers, uint8_t num_ovls,
  852. uint8_t cmd)
  853. {
  854. struct de_data *data = dev->data;
  855. struct de_command_entry *entry;
  856. de_overlay_cfg_t *cfg;
  857. struct display_rect dest_rect;
  858. int8_t top_idx = num_ovls - 1;
  859. /* FIXME: writeback never uses y-flip ? */
  860. bool wb_y_flip = dest ? CONFIG_DE_WB_Y_FLIP : false;
  861. bool dev_y_flip = dest ? false : CONFIG_DE_DEV_Y_FLIP;
  862. bool allow_ssaa = false; /* using bilinear interpolation */
  863. int i;
  864. if (sizeof(de_overlay_cfg_t) > sizeof(((struct de_command_entry *)0)->cfg)) {
  865. DEV_ERR("must increase command cfg size to %u\n", sizeof(de_overlay_cfg_t));
  866. return -ENOMEM;
  867. }
  868. if (dest != NULL && data->op_mode != DISPLAY_ENGINE_MODE_DEFAULT) {
  869. DEV_WRN("de display-only\n");
  870. return -EBUSY;
  871. }
  872. if (_validate_layers(layers, num_ovls, &allow_ssaa)) {
  873. return -EINVAL;
  874. }
  875. /* validate dest area */
  876. memcpy(&dest_rect, &layers[0].frame, sizeof(dest_rect));
  877. for (i = 1; i < num_ovls; i++) {
  878. display_rect_merge(&dest_rect, &layers[i].frame);
  879. }
  880. if (display_rect_get_width(&dest_rect) < MIN_WB_WIDTH) {
  881. DEV_INF("bg width less than 2\n");
  882. return -EINVAL;
  883. }
  884. /* validate dest parameters */
  885. if (dest) {
  886. if ((dest->desc.pixel_format & SUPPORTED_OUTPUT_PIXEL_FORMATS) == 0) {
  887. DEV_WRN("dest format 0x%x unsupported\n", dest->desc.pixel_format);
  888. return -EINVAL;
  889. }
  890. if (dest->desc.width > MAX_WIDTH || dest->desc.height > MAX_HEIGHT || dest->desc.pitch > MAX_PITCH) {
  891. DEV_WRN("dest size %dx%d pitch %d too large\n", dest->desc.width,
  892. dest->desc.height, dest->desc.pitch);
  893. return -EINVAL;
  894. }
  895. } else {
  896. if (data->display_format == 0) {
  897. DEV_WRN("display mode not configured\n");
  898. return -EINVAL;
  899. }
  900. }
  901. entry = de_instance_alloc_entry(inst);
  902. if (!entry)
  903. return -EBUSY;
  904. cfg = (de_overlay_cfg_t *)entry->cfg;
  905. cfg->x = dest_rect.x;
  906. cfg->y = dest_rect.y;
  907. cfg->n_layers = 0;
  908. cfg->blend_idx = 0;
  909. cfg->has_rotation = 0;
  910. cfg->has_scaling = 0;
  911. cfg->has_nor_access = 0;
  912. cfg->bg_color = 0;
  913. cfg->ctl1 = 0;
  914. cfg->alpha_ctl = 0;
  915. cfg->lx_abmp_ctl = DE_LX_AA_P0_COFF_3_4;
  916. _config_overlay_output(data, cfg, dest, &dest_rect, wb_y_flip || dev_y_flip);
  917. /* 1 fill color layer */
  918. if (layers[top_idx].buffer == NULL &&
  919. (top_idx == 0 || layers[top_idx].blending == DISPLAY_BLENDING_NONE)) {
  920. cfg->ctl |= DE_CTL_OUT_COLOR_FILL_EN;
  921. cfg->fill_color = layers[top_idx].color.full;
  922. if (dev_y_flip) {
  923. cfg->color_fill_pos = DE_COLOR_FILL_POS(layers[top_idx].frame.x - dest_rect.x,
  924. cfg->h - (layers[top_idx].frame.y - dest_rect.y) - layers[top_idx].frame.h);
  925. } else {
  926. cfg->color_fill_pos = DE_COLOR_FILL_POS(layers[top_idx].frame.x - dest_rect.x,
  927. layers[top_idx].frame.y - dest_rect.y);
  928. }
  929. cfg->color_fill_size = DE_COLOR_FILL_SIZE(
  930. layers[top_idx].frame.w, layers[top_idx].frame.h);
  931. if (--top_idx < 0)
  932. goto out_exit;
  933. }
  934. /* 1 background layer */
  935. if (layers[0].buffer == NULL &&
  936. (top_idx == 0 || layers[1].blending == DISPLAY_BLENDING_NONE)) {
  937. cfg->bg_color = layers[0].color.full;
  938. layers++;
  939. if (--top_idx < 0)
  940. goto out_exit;
  941. }
  942. for (int8_t layer_idx = 2; layer_idx >= 0 && top_idx >= 0; top_idx--, layer_idx--) {
  943. _config_layers(cfg, &layers[top_idx], layer_idx, dev_y_flip, allow_ssaa);
  944. cfg->n_layers++;
  945. }
  946. if (cfg->blend_idx > 0 && dest == NULL)
  947. cfg->alpha_ctl |= DE_ALPHA_FCV_EN;
  948. out_exit:
  949. entry->cmd = cmd;
  950. de_append_cmd(data, entry, de_instance_has_flag(inst, DISPLAY_ENGINE_FLAG_HIGH_PRIO));
  951. return entry->seq;
  952. }
  953. __de_func static int de_fill(const struct device *dev, int inst, const display_buffer_t *dest,
  954. display_color_t color)
  955. {
  956. struct de_data *data = dev->data;
  957. display_layer_t layer = {
  958. .buffer = NULL,
  959. .color = color,
  960. .frame = (display_rect_t) { 0, 0, dest->desc.width, dest->desc.height },
  961. };
  962. if (data->op_mode != DISPLAY_ENGINE_MODE_DEFAULT) {
  963. DEV_WRN("de display-only\n");
  964. return -EBUSY;
  965. }
  966. if (dest->desc.pixel_format == PIXEL_FORMAT_BGR_565) {
  967. uint16_t pitch;
  968. if (dest->desc.width < 2 || (dest->desc.pitch & 0x1)) {
  969. DEV_INF("fill width less than 2\n");
  970. return -EINVAL;
  971. }
  972. pitch = GUESS_PITCH_BYTES(dest, 2);
  973. if (!(pitch & 0x3) && !(dest->addr & 0x3) &&
  974. !(dest->desc.width & 0x1) && (dest->desc.width >= MIN_WB_WIDTH * 2)) {
  975. display_buffer_t dest_argb8888 = {
  976. .addr = dest->addr,
  977. .desc = {
  978. .pixel_format = PIXEL_FORMAT_ARGB_8888,
  979. .width = dest->desc.width / 2,
  980. .height = dest->desc.height,
  981. .pitch = pitch,
  982. },
  983. };
  984. layer.frame.w = dest_argb8888.desc.width;
  985. layer.color.c16[0] = ((color.r & 0xf8) << 8) | ((color.g & 0xfc) << 3) | (color.b >> 3);
  986. layer.color.c16[1] = layer.color.c16[0];
  987. return de_insert_overlay_cmd(dev, inst, &dest_argb8888, &layer, 1, DE_CMD_FILL);
  988. }
  989. /* BUGFIX: cannot access crossing RAM9 and RAM10 (0x30000000 - ?) */
  990. uint32_t dst_end = dest->addr + (dest->desc.height - 1) * pitch + dest->desc.width * 2;
  991. if (dest->addr >= 0x30000000 || dst_end <= 0x30000000) {
  992. struct de_command_entry *entry = de_instance_alloc_entry(inst);
  993. if (!entry)
  994. return -EBUSY;
  995. de_transform_cfg_t *cfg = (de_transform_cfg_t *)entry->cfg;
  996. cfg->img_size = RT_IMG_WIDTH(dest->desc.width) | RT_END_HEIGHT(dest->desc.height);
  997. cfg->dst_addr = (uint32_t)cache_to_uncache((void *)dest->addr);
  998. cfg->dst_stride = pitch;
  999. cfg->fill_color = RT_COLOR_RGB_565(color.r, color.g, color.b);
  1000. cfg->ctl = RT_EN | RT_IRQ_EN | RT_COLOR_FILL_START | RT_COLOR_FILL_BURST_16;
  1001. entry->cmd = DE_CMD_ROTATE_FILL;
  1002. de_append_cmd(data, entry, de_instance_has_flag(inst, DISPLAY_ENGINE_FLAG_HIGH_PRIO));
  1003. return entry->seq;
  1004. }
  1005. }
  1006. return de_insert_overlay_cmd(dev, inst, dest, &layer, 1, DE_CMD_FILL);
  1007. }
  1008. __de_func static int de_blit(const struct device *dev, int inst, const display_buffer_t *dest,
  1009. const display_buffer_t *src)
  1010. {
  1011. display_layer_t layer = {
  1012. .buffer = src,
  1013. .color = { .a = 0xff, .r = 0, .g = 0, .b = 0, },
  1014. .frame = { 0, 0, dest->desc.width, dest->desc.height },
  1015. };
  1016. return de_insert_overlay_cmd(dev, inst, dest, &layer, 1, DE_CMD_BLIT);
  1017. }
  1018. __de_func static int de_blend(const struct device *dev, int inst, const display_buffer_t *dest,
  1019. const display_buffer_t *fg, display_color_t fg_color,
  1020. const display_buffer_t *bg, display_color_t bg_color)
  1021. {
  1022. display_layer_t layers[2] = {
  1023. {
  1024. .buffer = bg,
  1025. .color = bg_color,
  1026. .frame = { 0, 0, dest->desc.width, dest->desc.height },
  1027. },
  1028. {
  1029. .buffer = fg,
  1030. .color = fg_color,
  1031. .blending = DISPLAY_BLENDING_COVERAGE,
  1032. .frame = { 0, 0, dest->desc.width, dest->desc.height },
  1033. },
  1034. };
  1035. return de_insert_overlay_cmd(dev, inst, dest, layers, 2, fg ? DE_CMD_BLEND : DE_CMD_BLEND_FG);
  1036. }
  1037. __de_func static int de_compose(const struct device *dev, int inst, const display_buffer_t *dest,
  1038. const display_layer_t *layers, int num_ovls)
  1039. {
  1040. uint8_t cmd = dest ? DE_CMD_COMPOSE_WB : DE_CMD_COMPOSE;
  1041. if (num_ovls > MAX_NUM_OVERLAYS || num_ovls <= 0) {
  1042. DEV_WRN("unsupported ovl num %d\n", num_ovls);
  1043. return -EINVAL;
  1044. }
  1045. return de_insert_overlay_cmd(dev, inst, dest, layers, num_ovls, cmd);
  1046. }
  1047. __de_func static int de_transform(const struct device *dev, int inst, const display_buffer_t *dest,
  1048. const display_buffer_t *src,
  1049. const display_engine_transform_param_t *param)
  1050. {
  1051. struct de_data *data = dev->data;
  1052. struct de_command_entry *entry;
  1053. de_transform_cfg_t *cfg;
  1054. uint8_t bytes_per_pixel;
  1055. if (data->op_mode != DISPLAY_ENGINE_MODE_DEFAULT) {
  1056. DEV_WRN("de display-only\n");
  1057. return -EBUSY;
  1058. }
  1059. if ((src->desc.pixel_format & SUPPORTED_ROTATE_PIXEL_FORMATS) == 0) {
  1060. DEV_WRN("unsupported rotation format %u\n", src->desc.pixel_format);
  1061. return -EINVAL;
  1062. }
  1063. if (param->is_circle) {
  1064. if (src->desc.pixel_format != PIXEL_FORMAT_BGR_565 || (src->desc.width & 0x1)) {
  1065. DEV_WRN("src width %d and format 0x%x must meet circle rotation\n",
  1066. src->desc.width, src->desc.pixel_format);
  1067. return -EINVAL;
  1068. }
  1069. if (src->desc.pixel_format != dest->desc.pixel_format ||
  1070. src->desc.width != dest->desc.width ||
  1071. src->desc.width != src->desc.height) {
  1072. DEV_WRN("src and dest must meet circle rotation\n");
  1073. return -EINVAL;
  1074. }
  1075. if (param->circle.line_start + dest->desc.height > src->desc.width) {
  1076. DEV_WRN("circle rotation line range exceed\n");
  1077. return -EINVAL;
  1078. }
  1079. } else {
  1080. bool use_layer = param->blend_en || (src->desc.pixel_format != dest->desc.pixel_format) ||
  1081. (src->desc.pixel_format != PIXEL_FORMAT_BGR_565) || (dest->desc.width & 0x1);
  1082. if (use_layer) {
  1083. display_layer_t layers[2] = {
  1084. {
  1085. .buffer = dest,
  1086. .frame = { 0, 0, dest->desc.width, dest->desc.height },
  1087. },
  1088. {
  1089. .buffer = src,
  1090. .blending = param->blend_en ? DISPLAY_BLENDING_COVERAGE : DISPLAY_BLENDING_NONE,
  1091. .frame = { 0, 0, dest->desc.width, dest->desc.height },
  1092. .matrix = &param->matrix,
  1093. .color = param->color,
  1094. },
  1095. };
  1096. return de_insert_overlay_cmd(dev, inst, dest, layers, 2, DE_CMD_BLEND);
  1097. }
  1098. }
  1099. entry = de_instance_alloc_entry(inst);
  1100. if (!entry)
  1101. return -EBUSY;
  1102. cfg = (de_transform_cfg_t *)entry->cfg;
  1103. if (param->is_circle) {
  1104. uint16_t outer_diameter = src->desc.width - 1;
  1105. cfg->start_height = param->circle.line_start;
  1106. cfg->r1m2 = param->circle.outer_radius_sq;
  1107. cfg->r0m2 = param->circle.inner_radius_sq;
  1108. cfg->sw_first_dist = outer_diameter * outer_diameter +
  1109. (outer_diameter - 2 * param->circle.line_start) *
  1110. (outer_diameter - 2 * param->circle.line_start);
  1111. cfg->ctl = RT_MODE_CIRCLE | RT_EN | RT_IRQ_EN | RT_FILTER_BILINEAR | RT_COLOR_FILL_BURST_16;
  1112. } else {
  1113. cfg->start_height = 0;
  1114. cfg->src_img_size = RT_SRC_IMG_SIZE(src->desc.width, src->desc.height);
  1115. cfg->ctl = RT_MODE_RECT | RT_EN | RT_IRQ_EN | RT_FILTER_BILINEAR | RT_COLOR_FILL_BURST_16;
  1116. }
  1117. cfg->img_size = RT_IMG_WIDTH(dest->desc.width) |
  1118. RT_END_HEIGHT(cfg->start_height + dest->desc.height);
  1119. cfg->sw_x0 = param->matrix.tx;
  1120. cfg->sw_y0 = param->matrix.ty;
  1121. cfg->sw_x_xy = RT_SW_DELTA_XY(param->matrix.sx, param->matrix.shy);
  1122. cfg->sw_y_xy = RT_SW_DELTA_XY(param->matrix.shx, param->matrix.sy);
  1123. bytes_per_pixel = display_format_get_bits_per_pixel(src->desc.pixel_format) / 8;
  1124. cfg->src_stride = GUESS_PITCH_BYTES(src, bytes_per_pixel);
  1125. cfg->src_addr = buf_is_nor((void *)src->addr) ?
  1126. (uint32_t)cache_to_uncache_by_master((void *)src->addr, SPI0_CACHE_MASTER_DE) :
  1127. (uint32_t)cache_to_uncache((void *)src->addr);
  1128. cfg->src_addr += (cfg->sw_y0 >> 12) * (int32_t)cfg->src_stride + (cfg->sw_x0 >> 12) * bytes_per_pixel;
  1129. cfg->dst_stride = GUESS_PITCH_BYTES(dest, bytes_per_pixel);
  1130. cfg->dst_addr = (uint32_t)cache_to_uncache((void *)dest->addr);
  1131. cfg->fill_color = param->color.full & 0xFFFFFF;
  1132. if (src->desc.pixel_format == PIXEL_FORMAT_BGR_565) {
  1133. cfg->ctl |= RT_FORMAT_RGB565 | RT_COLOR_FILL_EN;
  1134. } else {
  1135. cfg->ctl |= RT_FORMAT_ARGB8888 | RT_COLOR_FILL_EN;
  1136. }
  1137. entry->cmd = param->is_circle ? DE_CMD_ROTATE_CIRCLE : DE_CMD_ROTATE_RECT;
  1138. de_append_cmd(data, entry, de_instance_has_flag(inst, DISPLAY_ENGINE_FLAG_HIGH_PRIO));
  1139. return entry->seq;
  1140. }
  1141. __de_func static int de_set_clut(const struct device *dev, int inst, uint16_t layer_idx,
  1142. uint16_t size, const uint32_t *clut)
  1143. {
  1144. struct de_data *data = dev->data;
  1145. struct de_command_entry *entry;
  1146. de_clut_cfg_t *cfg;
  1147. if (data->op_mode != DISPLAY_ENGINE_MODE_DEFAULT) {
  1148. DEV_WRN("de display-only\n");
  1149. return -EBUSY;
  1150. }
  1151. if (clut == NULL || layer_idx >= 3/*MAX_NUM_OVERLAYS*/ || size > 256) {
  1152. DEV_WRN("invalid clut %p, idx %d, size %u\n", clut, layer_idx, size);
  1153. return -EINVAL;
  1154. }
  1155. entry = de_instance_alloc_entry(inst);
  1156. if (!entry)
  1157. return -EBUSY;
  1158. cfg = (de_clut_cfg_t *)entry->cfg;
  1159. cfg->layer_idx = layer_idx;
  1160. cfg->size = size;
  1161. cfg->clut = clut;
  1162. entry->cmd = DE_CMD_SET_CLUT;
  1163. de_append_cmd(data, entry, de_instance_has_flag(inst, DISPLAY_ENGINE_FLAG_HIGH_PRIO));
  1164. return entry->seq;
  1165. }
  1166. static int de_poll(const struct device *dev, int inst, int timeout_ms)
  1167. {
  1168. if (inst >= 0) {
  1169. return de_instance_poll(inst, timeout_ms);
  1170. }
  1171. return -EINVAL;
  1172. }
  1173. static int de_register_callback(const struct device *dev,
  1174. int inst, display_engine_instance_callback_t callback, void *user_data)
  1175. {
  1176. struct de_data *data = dev->data;
  1177. int res;
  1178. k_mutex_lock(&data->mutex, K_FOREVER);
  1179. res = de_instance_register_callback(inst, callback, user_data);
  1180. k_mutex_unlock(&data->mutex);
  1181. return res;
  1182. }
  1183. static void de_get_capabilities(const struct device *dev,
  1184. struct display_engine_capabilities *capabilities)
  1185. {
  1186. capabilities->max_width = MAX_WIDTH;
  1187. capabilities->max_height = MAX_HEIGHT;
  1188. capabilities->max_pitch = MAX_PITCH;
  1189. capabilities->num_overlays = 3;/*MAX_NUM_OVERLAYS*/;
  1190. capabilities->support_fill = 1;
  1191. capabilities->support_blend = 1;
  1192. capabilities->support_blend_fg = 1;
  1193. capabilities->support_blend_bg = 0;
  1194. capabilities->supported_output_pixel_formats = SUPPORTED_OUTPUT_PIXEL_FORMATS;
  1195. capabilities->supported_input_pixel_formats = SUPPORTED_INPUT_PIXEL_FORMATS;
  1196. capabilities->supported_rotate_pixel_formats = SUPPORTED_ROTATE_PIXEL_FORMATS;
  1197. }
  1198. static int de_control(const struct device *dev, int cmd, void *arg1, void *arg2)
  1199. {
  1200. struct de_data *data = dev->data;
  1201. int ret = 0;
  1202. switch (cmd) {
  1203. case DISPLAY_ENGINE_CTRL_DISPLAY_PREPARE_CB:
  1204. data->prepare_fn_arg = arg2;
  1205. data->prepare_fn = arg1;
  1206. break;
  1207. case DISPLAY_ENGINE_CTRL_DISPLAY_START_CB:
  1208. data->start_fn_arg = arg2;
  1209. data->start_fn = arg1;
  1210. break;
  1211. case DISPLAY_ENGINE_CTRL_DISPLAY_MODE:
  1212. data->display_format = ((struct display_videomode *)arg1)->pixel_format;
  1213. data->display_bytes_per_pixel = display_format_get_bits_per_pixel(data->display_format) / 8;
  1214. break;
  1215. case DISPLAY_ENGINE_CTRL_DISPLAY_PORT:
  1216. data->display_sync_en =
  1217. (((struct display_videoport *)arg1)->type == DISPLAY_PORT_QSPI_SYNC);
  1218. if (data->display_sync_en) {
  1219. data->op_mode = DISPLAY_ENGINE_MODE_DISPLAY_ONLY;
  1220. }
  1221. break;
  1222. case DISPLAY_ENGINE_CTRL_DISPLAY_SYNC_STOP:
  1223. if (data->display_sync_en) {
  1224. int32_t wait_ms = (int32_t)arg1;
  1225. /* wait command queue empty */
  1226. data->display_sync_en = 0;
  1227. while (data->cmd_num > 0 && wait_ms > 0) {
  1228. k_msleep(2);
  1229. wait_ms -= 2;
  1230. }
  1231. if (data->cmd_num > 0) {
  1232. DEV_ERR("de sync stop timeout (stat=0x%x)\n", DE->STA);
  1233. de_cleanup_all_cmd(data);
  1234. ret = -ETIME;
  1235. }
  1236. data->display_sync_en = 1;
  1237. /* FIXME: any better way to do this ? */
  1238. de_reset(data);
  1239. }
  1240. break;
  1241. case DISPLAY_ENGINE_CTRL_WORK_MODE:
  1242. if (!data->display_sync_en) {
  1243. uint8_t mode = (uint8_t)((intptr_t)arg1);
  1244. if (mode != data->op_mode) {
  1245. data->op_mode = mode;
  1246. if (mode == DISPLAY_ENGINE_MODE_DISPLAY_ONLY) {
  1247. unsigned int key = irq_lock();
  1248. data->waiting = (data->cmd_num > 0);
  1249. irq_unlock(key);
  1250. if (data->waiting) {
  1251. k_sem_take(&data->wait_sem, K_MSEC(5000));
  1252. }
  1253. }
  1254. }
  1255. }
  1256. break;
  1257. default:
  1258. return -EINVAL;
  1259. }
  1260. return ret;
  1261. }
  1262. __de_func void de_isr(const void *arg)
  1263. {
  1264. const struct device *dev = arg;
  1265. struct de_data *data = dev->data;
  1266. uint32_t status = DE->STA;
  1267. uint32_t rt_stat = DE->RT_CTL;
  1268. bool completed = false;
  1269. DE->STA = status;
  1270. DEV_DBG("de sta 0x%08x\n", status);
  1271. if (rt_stat & RT_STAT_COMPLETE) {
  1272. DEV_DBG("de rt complete 0x%08x\n", rt_stat);
  1273. completed = true;
  1274. }
  1275. if (status & (DE_STAT_WB_FTC | DE_STAT_DEV_FTC)) {
  1276. DEV_DBG("de ovl complete 0x%08x\n", status);
  1277. completed = true;
  1278. }
  1279. if (completed) {
  1280. if (data->display_sync_en == 0)
  1281. k_work_cancel_delayable(&data->timeout_work);
  1282. if (data->display_sync_en == 0 || data->cmd_num > 1)
  1283. de_complete_cmd(data, 0);
  1284. }
  1285. if (status & DE_STAT_DEV_FIFO_HF) {
  1286. DEV_DBG("de dev halfull\n");
  1287. #if CONFIG_DE_USE_DEV_HALFULL
  1288. if (data->start_fn) {
  1289. data->start_fn(data->start_fn_arg);
  1290. }
  1291. #endif /* CONFIG_DE_USE_DEV_HALFULL */
  1292. }
  1293. if (status & DE_STAT_DEV_FIFO_UDF) {
  1294. if (data->display_sync_en) {
  1295. DEV_ERR("de dev underflow 0x%08x\n", status);
  1296. de_reset(data);
  1297. de_complete_cmd(data, DE_STAT_DEV_FIFO_UDF);
  1298. }
  1299. }
  1300. /* RGB and SPI_QUAD_SYNC have vsync signal*/
  1301. if (status & DE_STAT_DEV_VSYNC) {
  1302. /* TODO: refresh frames */
  1303. DEV_DBG("vsync arrived\n");
  1304. }
  1305. /* update frames for those do not have vsync signal */
  1306. if (status & DE_STAT_PRELINE) {
  1307. /* TODO: refresh frames */
  1308. DEV_DBG("preline arrived\n");
  1309. }
  1310. }
  1311. static void de_timeout_work_handler(struct k_work *work)
  1312. {
  1313. struct de_data *data = CONTAINER_OF(work, struct de_data, timeout_work);
  1314. printk("de timeout\n");
  1315. de_dump();
  1316. de_complete_cmd(data, -ETIME);
  1317. }
  1318. int de_init(const struct device *dev)
  1319. {
  1320. struct de_data *data = dev->data;
  1321. memset(data, 0, sizeof(*data));
  1322. memset(&de_priv_data, 0, sizeof(de_priv_data));
  1323. k_sem_init(&data->wait_sem, 0, 1);
  1324. k_mutex_init(&data->mutex);
  1325. k_work_init_delayable(&data->timeout_work, de_timeout_work_handler);
  1326. sys_slist_init(&data->cmd_list);
  1327. #ifdef CONFIG_DISPLAY_ENGINE_HIHG_PRIO_INSTANCE
  1328. sys_slist_init(&data->high_cmd_list);
  1329. #endif
  1330. de_command_pools_init();
  1331. return 0;
  1332. }
  1333. #ifdef CONFIG_PM_DEVICE
  1334. int de_pm_control(const struct device *dev, enum pm_device_action action)
  1335. {
  1336. struct de_data *data = dev->data;
  1337. int ret = 0;
  1338. switch (action) {
  1339. case PM_DEVICE_ACTION_SUSPEND:
  1340. case PM_DEVICE_ACTION_FORCE_SUSPEND:
  1341. ret = (data->cmd_num > 0) ? -EBUSY : 0;
  1342. break;
  1343. case PM_DEVICE_ACTION_RESUME:
  1344. de_reset(data);
  1345. break;
  1346. default:
  1347. break;
  1348. }
  1349. return ret;
  1350. }
  1351. #endif /* CONFIG_PM_DEVICE */
  1352. const struct display_engine_driver_api de_drv_api = {
  1353. .control = de_control,
  1354. .open = de_open,
  1355. .close = de_close,
  1356. .get_capabilities = de_get_capabilities,
  1357. .register_callback = de_register_callback,
  1358. .fill = de_fill,
  1359. .blit = de_blit,
  1360. .blend = de_blend,
  1361. .compose = de_compose,
  1362. .transform = de_transform,
  1363. .set_clut = de_set_clut,
  1364. .poll = de_poll,
  1365. };
  1366. struct de_data de_drv_data __in_section_unique(ram.noinit.drv_de.data);