2727
2828LOG_MODULE_REGISTER (display_mcux_elcdif , CONFIG_DISPLAY_LOG_LEVEL );
2929
30+ /* Define the heap size. 512 bytes of padding are included for kernel heap structures */
31+ K_HEAP_DEFINE (display_heap , CONFIG_MCUX_ELCDIF_FB_NUM * CONFIG_MCUX_ELCDIF_FB_SIZE + 512 );
32+
3033static const uint32_t supported_fmts = PIXEL_FORMAT_BGR_565 | PIXEL_FORMAT_ARGB_8888 ;
3134
3235struct mcux_elcdif_config {
3336 LCDIF_Type * base ;
3437 void (* irq_config_func )(const struct device * dev );
3538 elcdif_rgb_mode_config_t rgb_mode ;
36- enum display_pixel_format pixel_format ;
37- size_t pixel_bytes ;
38- size_t fb_bytes ;
3939 const struct pinctrl_dev_config * pincfg ;
4040 const struct gpio_dt_spec backlight_gpio ;
41- uint8_t * fb_ptr ;
4241 const struct device * pxp ;
4342};
4443
@@ -47,6 +46,10 @@ struct mcux_elcdif_data {
4746 const uint8_t * active_fb ;
4847 /* Pointers to driver allocated framebuffers */
4948 uint8_t * fb [CONFIG_MCUX_ELCDIF_FB_NUM ];
49+ enum display_pixel_format pixel_format ;
50+ size_t pixel_bytes ;
51+ size_t fb_bytes ;
52+ elcdif_rgb_mode_config_t rgb_mode ;
5053 struct k_sem sem ;
5154 /* Tracks index of next active driver framebuffer */
5255 uint8_t next_idx ;
@@ -77,7 +80,7 @@ static int mcux_elcdif_write(const struct device *dev, const uint16_t x, const u
7780 int ret = 0 ;
7881 bool full_fb = false;
7982
80- __ASSERT ((config -> pixel_bytes * desc -> pitch * desc -> height ) <= desc -> buf_size ,
83+ __ASSERT ((dev_data -> pixel_bytes * desc -> pitch * desc -> height ) <= desc -> buf_size ,
8184 "Input buffer too small" );
8285
8386 LOG_DBG ("W=%d, H=%d, @%d,%d" , desc -> width , desc -> height , x , y );
@@ -110,17 +113,17 @@ static int mcux_elcdif_write(const struct device *dev, const uint16_t x, const u
110113 */
111114 src = dev_data -> active_fb ;
112115 dst = dev_data -> fb [dev_data -> next_idx ];
113- memcpy (dst , src , config -> fb_bytes );
116+ memcpy (dst , src , dev_data -> fb_bytes );
114117 }
115118 /* Now, write the display update into active framebuffer */
116119 src = buf ;
117120 dst = dev_data -> fb [dev_data -> next_idx ];
118- dst += config -> pixel_bytes * (y * config -> rgb_mode .panelWidth + x );
121+ dst += dev_data -> pixel_bytes * (y * config -> rgb_mode .panelWidth + x );
119122
120123 for (h_idx = 0 ; h_idx < desc -> height ; h_idx ++ ) {
121- memcpy (dst , src , config -> pixel_bytes * desc -> width );
122- src += config -> pixel_bytes * desc -> pitch ;
123- dst += config -> pixel_bytes * config -> rgb_mode .panelWidth ;
124+ memcpy (dst , src , dev_data -> pixel_bytes * desc -> width );
125+ src += dev_data -> pixel_bytes * desc -> pitch ;
126+ dst += dev_data -> pixel_bytes * config -> rgb_mode .panelWidth ;
124127 }
125128
126129 LOG_DBG ("Setting FB from %p->%p" , (void * )dev_data -> active_fb ,
@@ -130,7 +133,7 @@ static int mcux_elcdif_write(const struct device *dev, const uint16_t x, const u
130133 }
131134
132135#ifdef CONFIG_HAS_MCUX_CACHE
133- DCACHE_CleanByRange ((uint32_t )dev_data -> active_fb , config -> fb_bytes );
136+ DCACHE_CleanByRange ((uint32_t )dev_data -> active_fb , dev_data -> fb_bytes );
134137#endif
135138
136139#ifdef CONFIG_MCUX_ELCDIF_PXP
@@ -148,11 +151,11 @@ static int mcux_elcdif_write(const struct device *dev, const uint16_t x, const u
148151 pxp_block .block_size = desc -> buf_size ;
149152
150153 /* DMA slot sets pixel format and rotation angle */
151- if (config -> pixel_format == PIXEL_FORMAT_BGR_565 ) {
154+ if (dev_data -> pixel_format == PIXEL_FORMAT_BGR_565 ) {
152155 pxp_dma .dma_slot = DMA_MCUX_PXP_FMT (DMA_MCUX_PXP_FMT_RGB565 );
153- } else if (config -> pixel_format == PIXEL_FORMAT_RGB_888 ) {
156+ } else if (dev_data -> pixel_format == PIXEL_FORMAT_RGB_888 ) {
154157 pxp_dma .dma_slot = DMA_MCUX_PXP_FMT (DMA_MCUX_PXP_FMT_RGB888 );
155- } else if (config -> pixel_format == PIXEL_FORMAT_ARGB_8888 ) {
158+ } else if (dev_data -> pixel_format == PIXEL_FORMAT_ARGB_8888 ) {
156159 pxp_dma .dma_slot = DMA_MCUX_PXP_FMT (DMA_MCUX_PXP_FMT_ARGB8888 );
157160 } else {
158161 /* Cannot rotate */
@@ -169,8 +172,8 @@ static int mcux_elcdif_write(const struct device *dev, const uint16_t x, const u
169172 }
170173
171174 pxp_dma .channel_direction = MEMORY_TO_MEMORY ;
172- pxp_dma .source_data_size = desc -> width * config -> pixel_bytes ;
173- pxp_dma .dest_data_size = config -> rgb_mode .panelWidth * config -> pixel_bytes ;
175+ pxp_dma .source_data_size = desc -> width * dev_data -> pixel_bytes ;
176+ pxp_dma .dest_data_size = config -> rgb_mode .panelWidth * dev_data -> pixel_bytes ;
174177 /* Burst lengths are heights of source/dest buffer in pixels */
175178 pxp_dma .source_burst_length = desc -> height ;
176179 pxp_dma .dest_burst_length = config -> rgb_mode .panelHeight ;
@@ -221,13 +224,42 @@ static int mcux_elcdif_display_blanking_on(const struct device *dev)
221224static int mcux_elcdif_set_pixel_format (const struct device * dev ,
222225 const enum display_pixel_format pixel_format )
223226{
227+ struct mcux_elcdif_data * dev_data = dev -> data ;
224228 const struct mcux_elcdif_config * config = dev -> config ;
225229
226- if (pixel_format == config -> pixel_format ) {
227- return 0 ;
230+ if (!(pixel_format & supported_fmts )) {
231+ LOG_ERR ("Unsupported pixel format" );
232+ return - ENOTSUP ;
228233 }
229- LOG_ERR ("Pixel format change not implemented" );
230- return - ENOTSUP ;
234+
235+ dev_data -> pixel_format = pixel_format ;
236+ dev_data -> pixel_bytes = DISPLAY_BITS_PER_PIXEL (pixel_format ) / 8 ;
237+ dev_data -> fb_bytes =
238+ config -> rgb_mode .panelWidth * config -> rgb_mode .panelHeight * dev_data -> pixel_bytes ;
239+
240+ for (int i = 0 ; i < CONFIG_MCUX_ELCDIF_FB_NUM ; i ++ ) {
241+ k_heap_free (& display_heap , dev_data -> fb [i ]);
242+ dev_data -> fb [i ] =
243+ k_heap_aligned_alloc (& display_heap , 64 , dev_data -> fb_bytes , K_FOREVER );
244+ if (dev_data -> fb [i ] == NULL ) {
245+ LOG_ERR ("Could not allocate memory for framebuffers" );
246+ return - ENOMEM ;
247+ }
248+ memset (dev_data -> fb [i ], 0 , dev_data -> fb_bytes );
249+ }
250+
251+ dev_data -> rgb_mode = config -> rgb_mode ;
252+ if (pixel_format == PIXEL_FORMAT_BGR_565 ) {
253+ dev_data -> rgb_mode .pixelFormat = kELCDIF_PixelFormatRGB565 ;
254+ } else if (pixel_format == PIXEL_FORMAT_RGB_888 ) {
255+ dev_data -> rgb_mode .pixelFormat = kELCDIF_PixelFormatRGB888 ;
256+ } else if (pixel_format == PIXEL_FORMAT_ARGB_8888 ) {
257+ dev_data -> rgb_mode .pixelFormat = kELCDIF_PixelFormatXRGB8888 ;
258+ }
259+
260+ ELCDIF_RgbModeSetPixelFormat (config -> base , dev_data -> rgb_mode .pixelFormat );
261+
262+ return 0 ;
231263}
232264
233265static int mcux_elcdif_set_orientation (const struct device * dev ,
@@ -249,7 +281,7 @@ static void mcux_elcdif_get_capabilities(const struct device *dev,
249281 capabilities -> x_resolution = config -> rgb_mode .panelWidth ;
250282 capabilities -> y_resolution = config -> rgb_mode .panelHeight ;
251283 capabilities -> supported_pixel_formats = supported_fmts ;
252- capabilities -> current_pixel_format = config -> pixel_format ;
284+ capabilities -> current_pixel_format = (( struct mcux_elcdif_data * ) dev -> data ) -> pixel_format ;
253285 capabilities -> current_orientation = DISPLAY_ORIENTATION_NORMAL ;
254286}
255287
@@ -286,25 +318,6 @@ static int mcux_elcdif_init(const struct device *dev)
286318 return err ;
287319 }
288320
289- elcdif_rgb_mode_config_t rgb_mode = config -> rgb_mode ;
290-
291- /* Set the Pixel format */
292- if (config -> pixel_format == PIXEL_FORMAT_BGR_565 ) {
293- rgb_mode .pixelFormat = kELCDIF_PixelFormatRGB565 ;
294- } else if (config -> pixel_format == PIXEL_FORMAT_RGB_888 ) {
295- rgb_mode .pixelFormat = kELCDIF_PixelFormatRGB888 ;
296- } else if (config -> pixel_format == PIXEL_FORMAT_ARGB_8888 ) {
297- rgb_mode .pixelFormat = kELCDIF_PixelFormatXRGB8888 ;
298- }
299-
300- for (int i = 0 ; i < CONFIG_MCUX_ELCDIF_FB_NUM ; i ++ ) {
301- /* Record pointers to each driver framebuffer */
302- dev_data -> fb [i ] = config -> fb_ptr + (config -> fb_bytes * i );
303- }
304-
305- rgb_mode .bufferAddr = (uint32_t )config -> fb_ptr ;
306- dev_data -> active_fb = config -> fb_ptr ;
307-
308321 k_sem_init (& dev_data -> sem , 0 , 1 );
309322#ifdef CONFIG_MCUX_ELCDIF_PXP
310323 k_sem_init (& dev_data -> pxp_done , 0 , 1 );
@@ -316,7 +329,12 @@ static int mcux_elcdif_init(const struct device *dev)
316329
317330 config -> irq_config_func (dev );
318331
319- ELCDIF_RgbModeInit (config -> base , & rgb_mode );
332+ /* Set default pixel format obtained from device tree */
333+ mcux_elcdif_set_pixel_format (dev , dev_data -> pixel_format );
334+
335+ dev_data -> active_fb = dev_data -> fb [0 ];
336+
337+ ELCDIF_RgbModeInit (config -> base , & dev_data -> rgb_mode );
320338 ELCDIF_RgbModeStart (config -> base );
321339
322340 return 0 ;
@@ -331,14 +349,9 @@ static const struct display_driver_api mcux_elcdif_api = {
331349 .set_orientation = mcux_elcdif_set_orientation ,
332350};
333351
334- #define MCUX_ELCDIF_PIXEL_BYTES (id ) (DISPLAY_BITS_PER_PIXEL(DT_INST_PROP(id, pixel_format)) / 8)
335-
336352#define MCUX_ELCDIF_DEVICE_INIT (id ) \
337353 PINCTRL_DT_INST_DEFINE(id); \
338354 static void mcux_elcdif_config_func_##id(const struct device *dev); \
339- static uint8_t __aligned(64) \
340- frame_buffer_##id[CONFIG_MCUX_ELCDIF_FB_NUM * DT_INST_PROP(id, width) * \
341- DT_INST_PROP(id, height) * MCUX_ELCDIF_PIXEL_BYTES(id)]; \
342355 static const struct mcux_elcdif_config mcux_elcdif_config_##id = { \
343356 .base = (LCDIF_Type *)DT_INST_REG_ADDR(id), \
344357 .irq_config_func = mcux_elcdif_config_func_##id, \
@@ -369,17 +382,13 @@ static const struct display_driver_api mcux_elcdif_api = {
369382 .dataBus = LCDIF_CTRL_LCD_DATABUS_WIDTH( \
370383 DT_INST_ENUM_IDX(id, data_bus_width)), \
371384 }, \
372- .pixel_format = DT_INST_PROP(id, pixel_format), \
373- .pixel_bytes = MCUX_ELCDIF_PIXEL_BYTES(id), \
374- .fb_bytes = DT_INST_PROP(id, width) * DT_INST_PROP(id, height) * \
375- MCUX_ELCDIF_PIXEL_BYTES(id), \
376385 .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(id), \
377386 .backlight_gpio = GPIO_DT_SPEC_INST_GET(id, backlight_gpios), \
378- .fb_ptr = frame_buffer_##id, \
379387 IF_ENABLED(CONFIG_MCUX_ELCDIF_PXP, \
380388 (.pxp = DEVICE_DT_GET(DT_INST_PHANDLE(id, nxp_pxp)),))}; \
381389 static struct mcux_elcdif_data mcux_elcdif_data_##id = { \
382390 .next_idx = 0, \
391+ .pixel_format = DT_INST_PROP(id, pixel_format), \
383392 }; \
384393 DEVICE_DT_INST_DEFINE(id, &mcux_elcdif_init, NULL, &mcux_elcdif_data_##id, \
385394 &mcux_elcdif_config_##id, POST_KERNEL, CONFIG_DISPLAY_INIT_PRIORITY, \
0 commit comments