1 /*
2  * Copyright (c) 2023 Renesas Electronics Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT  renesas_smartbond_display
8 
9 #include <zephyr/drivers/pinctrl.h>
10 #include <zephyr/drivers/gpio.h>
11 #include <zephyr/irq.h>
12 #include <zephyr/kernel.h>
13 #include <zephyr/device.h>
14 #include <zephyr/drivers/clock_control.h>
15 #include <zephyr/drivers/clock_control/smartbond_clock_control.h>
16 #include <zephyr/drivers/display.h>
17 #include <zephyr/sys/util.h>
18 #include <zephyr/drivers/dma.h>
19 #include <da1469x_lcdc.h>
20 #include <DA1469xAB.h>
21 #include <da1469x_pd.h>
22 #include <zephyr/linker/devicetree_regions.h>
23 #include <zephyr/pm/device.h>
24 #include <zephyr/pm/policy.h>
25 
26 #include <zephyr/logging/log.h>
27 LOG_MODULE_REGISTER(smartbond_display, CONFIG_DISPLAY_LOG_LEVEL);
28 
29 #define SMARTBOND_IRQN		DT_INST_IRQN(0)
30 #define SMARTBOND_IRQ_PRIO  DT_INST_IRQ(0, priority)
31 
32 #define LCDC_SMARTBOND_CLK_DIV(_freq)                           \
33 	((32000000U % (_freq)) ? (96000000U / (_freq)) : (32000000U / (_freq)))
34 
35 #define LCDC_SMARTBOND_IS_PLL_REQUIRED \
36 	!!(32000000U % DT_PROP(DT_INST_CHILD(0, display_timings), clock_frequency))
37 
38 #define DISPLAY_SMARTBOND_IS_DMA_PREFETCH_ENABLED \
39 	DT_INST_ENUM_IDX_OR(0, dma_prefetch, 0)
40 
41 #define LCDC_LAYER0_OFFSETX_REG_SET_FIELD(_field, _var, _val)\
42 	((_var)) =	\
43 	((_var) & ~(LCDC_LCDC_LAYER0_OFFSETX_REG_ ## _field ## _Msk)) |	\
44 	(((_val) << LCDC_LCDC_LAYER0_OFFSETX_REG_ ## _field ## _Pos) &	\
45 	LCDC_LCDC_LAYER0_OFFSETX_REG_ ## _field ## _Msk)
46 
47 #define DISPLAY_SMARTBOND_PIXEL_SIZE(inst)	\
48 	(DISPLAY_BITS_PER_PIXEL(DT_INST_PROP(inst, pixel_format)) / 8)
49 
50 #if CONFIG_DISPLAY_RENESAS_LCDC_BUFFER_PSRAM
51 #define DISPLAY_BUFFER_LINKER_SECTION \
52 	Z_GENERIC_SECTION(LINKER_DT_NODE_REGION_NAME(DT_NODELABEL(psram)))
53 #else
54 #define DISPLAY_BUFFER_LINKER_SECTION
55 #endif
56 
57 struct display_smartbond_data {
58 	/* Provide mutual exclusion when a display operation is requested. */
59 	struct k_sem device_sem;
60 	/* Frame update synchronization token */
61 	struct k_sem sync_sem;
62 	/* Flag indicating whether or not an underflow took place */
63 	volatile bool underflow_flag;
64 	/* Layer settings */
65 	lcdc_smartbond_layer_cfg layer;
66 	/* Frame buffer */
67 	uint8_t *buffer;
68 	/* DMA device */
69 	const struct device *dma;
70 	/* DMA configuration structures */
71 	struct dma_config dma_cfg;
72 	struct dma_block_config dma_block_cfg;
73 	/* DMA memory transfer synchronization token */
74 	struct k_sem dma_sync_sem;
75 	/* Granted DMA channel used for memory transfers */
76 	int dma_channel;
77 #if defined(CONFIG_PM_DEVICE)
78 	ATOMIC_DEFINE(pm_policy_state_flag, 1);
79 #endif
80 };
81 
82 struct display_smartbond_config {
83 	/* Reference to device instance's pinctrl configurations */
84 	const struct pinctrl_dev_config *pcfg;
85 	/* Display ON/OFF GPIO */
86 	const struct gpio_dt_spec disp;
87 	/* Host controller's timing settings */
88 	lcdc_smartbond_timing_cfg timing_cfg;
89 	/* Parallel interface settings */
90 	lcdc_smartbond_mode_cfg mode;
91 	/* Background default color configuration */
92 	lcdc_smartbond_bgcolor_cfg bgcolor_cfg;
93 	/* Display dimensions */
94 	const uint16_t x_res;
95 	const uint16_t y_res;
96 	/* Pixel size in bytes */
97 	uint8_t pixel_size;
98 	enum display_pixel_format pixel_format;
99 };
100 
lcdc_smartbond_pm_policy_state_lock_get(struct display_smartbond_data * data)101 static inline void lcdc_smartbond_pm_policy_state_lock_get(struct display_smartbond_data *data)
102 {
103 #ifdef CONFIG_PM_DEVICE
104 	if (atomic_test_and_set_bit(data->pm_policy_state_flag, 0) == 0) {
105 		/*
106 		 * Prevent the SoC from etering the normal sleep state as PDC does not support
107 		 * waking up the application core following LCDC events.
108 		 */
109 		pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
110 	}
111 #endif
112 }
113 
lcdc_smartbond_pm_policy_state_lock_put(struct display_smartbond_data * data)114 static inline void lcdc_smartbond_pm_policy_state_lock_put(struct display_smartbond_data *data)
115 {
116 #ifdef CONFIG_PM_DEVICE
117 	if (atomic_test_and_clear_bit(data->pm_policy_state_flag, 0) == 1) {
118 		/* Allow the SoC to enter the nornmal sleep state once LCDC is inactive */
119 		pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
120 	}
121 #endif
122 }
123 
124 /* Display pixel to layer color format translation */
lcdc_smartbond_pixel_to_lcm(enum display_pixel_format pixel_format)125 static uint8_t lcdc_smartbond_pixel_to_lcm(enum display_pixel_format pixel_format)
126 {
127 	switch (pixel_format) {
128 	case PIXEL_FORMAT_RGB_565:
129 		return (uint8_t)LCDC_SMARTBOND_L0_RGB565;
130 	case PIXEL_FORMAT_ARGB_8888:
131 		return (uint8_t)LCDC_SMARTBOND_L0_ARGB8888;
132 	default:
133 		LOG_ERR("Unsupported pixel format");
134 		return 0;
135 	};
136 }
137 
display_smartbond_configure(const struct device * dev)138 static int display_smartbond_configure(const struct device *dev)
139 {
140 	uint8_t clk_div =
141 		LCDC_SMARTBOND_CLK_DIV(DT_PROP(DT_INST_CHILD(0, display_timings), clock_frequency));
142 
143 	const struct display_smartbond_config *config = dev->config;
144 	struct display_smartbond_data *data = dev->data;
145 
146 	int ret = 0;
147 
148 	/* First enable the controller so registers can be written. */
149 	da1469x_lcdc_set_status(true, LCDC_SMARTBOND_IS_PLL_REQUIRED, clk_div);
150 
151 	if (!da1469x_lcdc_check_id()) {
152 		LOG_ERR("Invalid LCDC ID");
153 		da1469x_lcdc_set_status(false, false, 0);
154 		return -EINVAL;
155 	}
156 
157 	da1469x_lcdc_parallel_interface_configure((lcdc_smartbond_mode_cfg *)&config->mode);
158 	da1469x_lcdc_bgcolor_configure((lcdc_smartbond_bgcolor_cfg *)&config->bgcolor_cfg);
159 
160 	/*
161 	 * Partial update is not supported and so timing and layer settings can be configured
162 	 * once at initialization.
163 	 */
164 	ret = da1469x_lcdc_timings_configure(config->x_res, config->y_res,
165 						(lcdc_smartbond_timing_cfg *)&config->timing_cfg);
166 	if (ret < 0) {
167 		LOG_ERR("Unable to configure timing settings");
168 		da1469x_lcdc_set_status(false, false, 0);
169 		return ret;
170 	}
171 
172 	/*
173 	 * Stride should be updated at the end of a frame update (typically in ISR context).
174 	 * It's OK to update stride here as continuous mode should not be enabled yet.
175 	 */
176 	data->layer.color_format =
177 		lcdc_smartbond_pixel_to_lcm(config->pixel_format);
178 	data->layer.stride =
179 		da1469x_lcdc_stride_calculation(data->layer.color_format, config->x_res);
180 
181 	ret = da1469x_lcdc_layer_configure(&data->layer);
182 	if (ret < 0) {
183 		LOG_ERR("Unable to configure layer settings");
184 		da1469x_lcdc_set_status(false, false, 0);
185 	}
186 
187 	LCDC_LAYER0_OFFSETX_REG_SET_FIELD(LCDC_L0_DMA_PREFETCH,
188 		LCDC->LCDC_LAYER0_OFFSETX_REG, DISPLAY_SMARTBOND_IS_DMA_PREFETCH_ENABLED);
189 
190 	LCDC->LCDC_MODE_REG |= LCDC_LCDC_MODE_REG_LCDC_MODE_EN_Msk;
191 
192 	return ret;
193 }
194 
smartbond_display_isr(const void * arg)195 static void smartbond_display_isr(const void *arg)
196 {
197 	struct display_smartbond_data *data =  ((const struct device *)arg)->data;
198 
199 	data->underflow_flag = LCDC_STATUS_REG_GET_FIELD(LCDC_STICKY_UNDERFLOW);
200 
201 	/*
202 	 * Underflow sticky bit will remain high until cleared by writing
203 	 * any value to LCDC_INTERRUPT_REG.
204 	 */
205 	LCDC->LCDC_INTERRUPT_REG &= ~LCDC_LCDC_INTERRUPT_REG_LCDC_VSYNC_IRQ_EN_Msk;
206 
207 	/* Notify that current frame update is completed */
208 	k_sem_give(&data->sync_sem);
209 }
210 
display_smartbond_dma_cb(const struct device * dma,void * arg,uint32_t id,int status)211 static void display_smartbond_dma_cb(const struct device *dma, void *arg,
212 				uint32_t id, int status)
213 {
214 	struct display_smartbond_data *data = arg;
215 
216 	if (status < 0) {
217 		LOG_WRN("DMA transfer did not complete");
218 	}
219 
220 	k_sem_give(&data->dma_sync_sem);
221 }
222 
display_smartbond_dma_config(const struct device * dev)223 static int display_smartbond_dma_config(const struct device *dev)
224 {
225 	struct display_smartbond_data *data = dev->data;
226 
227 	data->dma = DEVICE_DT_GET(DT_NODELABEL(dma));
228 	if (!device_is_ready(data->dma)) {
229 		LOG_ERR("DMA device is not ready");
230 		return -ENODEV;
231 	}
232 
233 	data->dma_cfg.channel_direction = MEMORY_TO_MEMORY;
234 	data->dma_cfg.user_data = data;
235 	data->dma_cfg.dma_callback = display_smartbond_dma_cb;
236 	data->dma_cfg.block_count = 1;
237 	data->dma_cfg.head_block = &data->dma_block_cfg;
238 	data->dma_cfg.error_callback_dis = 1;
239 
240 	/* Request an arbitrary DMA channel */
241 	data->dma_channel = dma_request_channel(data->dma, NULL);
242 	if (data->dma_channel < 0) {
243 		LOG_ERR("Could not acquire a DMA channel");
244 		return -EIO;
245 	}
246 
247 	return 0;
248 }
249 
display_smartbond_resume(const struct device * dev)250 static int display_smartbond_resume(const struct device *dev)
251 {
252 	const struct display_smartbond_config *config = dev->config;
253 	int ret;
254 
255 	/* Select default state */
256 	ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
257 	if (ret < 0) {
258 		LOG_ERR("Could not apply LCDC pins' default state (%d)", ret);
259 		return -EIO;
260 	}
261 
262 #if LCDC_SMARTBOND_IS_PLL_REQUIRED
263 	const struct device *clock_dev = DEVICE_DT_GET(DT_NODELABEL(osc));
264 
265 	if (!device_is_ready(clock_dev)) {
266 		LOG_WRN("Clock device is not ready");
267 		return -ENODEV;
268 	}
269 
270 	ret = z_smartbond_select_sys_clk(SMARTBOND_CLK_PLL96M);
271 	if (ret < 0) {
272 		LOG_WRN("Could not switch to PLL");
273 		return -EIO;
274 	}
275 #endif
276 
277 	ret = display_smartbond_dma_config(dev);
278 	if (ret < 0) {
279 		return ret;
280 	}
281 
282 	return display_smartbond_configure(dev);
283 }
284 
285 #if defined(CONFIG_PM_DEVICE)
display_smartbond_dma_deconfig(const struct device * dev)286 static void display_smartbond_dma_deconfig(const struct device *dev)
287 {
288 	struct display_smartbond_data *data = dev->data;
289 
290 	__ASSERT(data->dma, "DMA should be already initialized");
291 
292 	dma_release_channel(data->dma, data->dma_channel);
293 }
294 
display_smartbond_suspend(const struct device * dev)295 static int display_smartbond_suspend(const struct device *dev)
296 {
297 	const struct display_smartbond_config *config = dev->config;
298 	int ret;
299 
300 	/* Select sleep state; it's OK if settings fails for any reason */
301 	ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
302 	if (ret < 0) {
303 		LOG_WRN("Could not apply DISPLAY pins' sleep state");
304 	}
305 
306 	/* Disable host controller to minimize power consumption */
307 	da1469x_lcdc_set_status(false, false, 0);
308 
309 	display_smartbond_dma_deconfig(dev);
310 
311 	return 0;
312 }
313 #endif
314 
display_smartbond_init(const struct device * dev)315 static int display_smartbond_init(const struct device *dev)
316 {
317 	const struct display_smartbond_config *config = dev->config;
318 	struct display_smartbond_data *data = dev->data;
319 	int ret;
320 
321 	/* Device should be ready to be acquired */
322 	k_sem_init(&data->device_sem, 1, 1);
323 	/* Event should be signaled by LCDC ISR */
324 	k_sem_init(&data->sync_sem, 0, 1);
325 	/* Event should be signaled by DMA ISR */
326 	k_sem_init(&data->dma_sync_sem, 0, 1);
327 
328 	/* As per docs, display port should be enabled by default. */
329 	if (gpio_is_ready_dt(&config->disp)) {
330 		ret = gpio_pin_configure_dt(&config->disp, GPIO_OUTPUT_ACTIVE);
331 		if (ret < 0) {
332 			LOG_ERR("Could not activate display port");
333 			return -EIO;
334 		}
335 	}
336 
337 	IRQ_CONNECT(SMARTBOND_IRQN, SMARTBOND_IRQ_PRIO, smartbond_display_isr,
338 								DEVICE_DT_INST_GET(0), 0);
339 
340 	/*
341 	 * Currently, there is no API to explicitly enable/disable the display controller.
342 	 * At the same time, the controller is set to continuous mode meaning that
343 	 * as long as a display panel is turned on, frame updates should happen all
344 	 * the time (otherwise contents on the display pane will be lost as the latter
345 	 * does not integrate an SDRAM memory to keep its frame).
346 	 * As such, resume/suspend operations are bound to blanking operations.
347 	 * That is, when the display is blanked on we can safely consider that display
348 	 * is no longer functional and thus, the controller can be suspended (allowing the
349 	 * SoC to enter the sleep state). Once the display is blanked off, then we consider
350 	 * that the controller should be resumed and sleep should be prevented at all
351 	 * (this is because the controller is powered by the same power domain used to
352 	 * power the application core). Side effect of the above is that the controller
353 	 * should be configured at initialization phase as display operations might
354 	 * be requested before the display is blanked off for the very first time.
355 	 */
356 	ret = display_smartbond_resume(dev);
357 	if (ret == 0) {
358 		/* Display port should be enabled at this moment and so sleep is not allowed. */
359 		lcdc_smartbond_pm_policy_state_lock_get(data);
360 	}
361 
362 	return ret;
363 }
364 
display_smartbond_blanking_on(const struct device * dev)365 static int display_smartbond_blanking_on(const struct device *dev)
366 {
367 	const struct display_smartbond_config *config = dev->config;
368 	struct display_smartbond_data *data = dev->data;
369 	int ret = 0;
370 
371 	k_sem_take(&data->device_sem, K_FOREVER);
372 
373 	/*
374 	 * This bit will force LCD controller's output to blank that is,
375 	 * the controller will keep operating without outputting any
376 	 * pixel data.
377 	 */
378 	LCDC->LCDC_MODE_REG |= LCDC_LCDC_MODE_REG_LCDC_FORCE_BLANK_Msk;
379 
380 	/* If enabled, disable display port. */
381 	if (gpio_is_ready_dt(&config->disp)) {
382 		ret = gpio_pin_configure_dt(&config->disp, GPIO_OUTPUT_INACTIVE);
383 		if (ret < 0) {
384 			LOG_WRN("Display port could not be de-activated");
385 		}
386 	}
387 
388 	/*
389 	 * At this moment the display panel should be turned off and so the device
390 	 * can enter the suspend state.
391 	 */
392 	lcdc_smartbond_pm_policy_state_lock_put(data);
393 
394 	k_sem_give(&data->device_sem);
395 
396 	return ret;
397 }
398 
display_smartbond_blanking_off(const struct device * dev)399 static int display_smartbond_blanking_off(const struct device *dev)
400 {
401 	const struct display_smartbond_config *config = dev->config;
402 	struct display_smartbond_data *data = dev->data;
403 	int ret = 0;
404 
405 	k_sem_take(&data->device_sem, K_FOREVER);
406 
407 	/* If used, enable display port */
408 	if (gpio_is_ready_dt(&config->disp)) {
409 		ret = gpio_pin_configure_dt(&config->disp, GPIO_OUTPUT_ACTIVE);
410 		if (ret < 0) {
411 			LOG_WRN("Display port could not be activated");
412 		}
413 	}
414 
415 	/*
416 	 * This bit will force LCD controller's output to blank that is,
417 	 * the controller will keep operating without outputting any
418 	 * pixel data.
419 	 */
420 	LCDC->LCDC_MODE_REG &= ~LCDC_LCDC_MODE_REG_LCDC_FORCE_BLANK_Msk;
421 
422 	/*
423 	 * At this moment the display should be turned on and so the device
424 	 * cannot enter the suspend state.
425 	 */
426 	lcdc_smartbond_pm_policy_state_lock_get(data);
427 
428 	k_sem_give(&data->device_sem);
429 
430 	return ret;
431 }
432 
display_smartbond_get_framebuffer(const struct device * dev)433 static void *display_smartbond_get_framebuffer(const struct device *dev)
434 {
435 	struct display_smartbond_data *data = dev->data;
436 
437 	return ((void *)data->buffer);
438 }
439 
display_smartbond_get_capabilities(const struct device * dev,struct display_capabilities * capabilities)440 static void display_smartbond_get_capabilities(const struct device *dev,
441 			struct display_capabilities *capabilities)
442 {
443 	memset(capabilities, 0, sizeof(*capabilities));
444 
445 	/*
446 	 * Multiple color formats should be supported by LCDC. Currently, RGB56 and ARGB888
447 	 * exposed by display API are supported. In the future we should consider supporting
448 	 * more color formats which should require changes in LVGL porting.
449 	 * Here, only one color format should be supported as the frame buffer is accessed
450 	 * directly by LCDC and is allocated statically during device initialization. The color
451 	 * format is defined based on the pixel-format property dictated by lcd-controller
452 	 * bindings.
453 	 */
454 	capabilities->supported_pixel_formats = DT_INST_PROP(0, pixel_format);
455 	capabilities->current_orientation = DISPLAY_ORIENTATION_NORMAL;
456 	capabilities->current_pixel_format = DT_INST_PROP(0, pixel_format);
457 	capabilities->x_resolution = DT_INST_PROP(0, width);
458 	capabilities->y_resolution = DT_INST_PROP(0, height);
459 }
460 
display_smartbond_read(const struct device * dev,const uint16_t x,const uint16_t y,const struct display_buffer_descriptor * desc,void * buf)461 static int display_smartbond_read(const struct device *dev,
462 			const uint16_t x, const uint16_t y,
463 			const struct display_buffer_descriptor *desc,
464 			void *buf)
465 {
466 	struct display_smartbond_data *data = dev->data;
467 	const struct display_smartbond_config *config = dev->config;
468 	uint8_t *dst = buf;
469 	const uint8_t *src = data->buffer;
470 
471 	k_sem_take(&data->device_sem, K_FOREVER);
472 
473 	/* pointer to upper left pixel of the rectangle */
474 	src += (x * config->pixel_size);
475 	src += (y * data->layer.stride);
476 
477 	data->dma_block_cfg.block_size = desc->width * config->pixel_size;
478 	/*
479 	 * Source and destination base address is word aligned.
480 	 * Data size should be selected based on color depth as
481 	 * cursor is shifted multiple of pixel color depth.
482 	 */
483 	data->dma_cfg.source_data_size = data->dma_cfg.dest_data_size =
484 			!(config->pixel_size & 3) ? 4 :
485 			!(config->pixel_size & 1) ? 2 : 1;
486 
487 	data->dma_cfg.dest_burst_length = data->dma_cfg.source_burst_length =
488 		!((data->dma_block_cfg.block_size / data->dma_cfg.source_data_size) & 7) ? 8 :
489 		!((data->dma_block_cfg.block_size / data->dma_cfg.source_data_size) & 3) ? 4 : 1;
490 
491 	for (int row = 0; row < desc->height; row++) {
492 
493 		data->dma_block_cfg.dest_address = (uint32_t)dst;
494 		data->dma_block_cfg.source_address = (uint32_t)src;
495 
496 		if (dma_config(data->dma, data->dma_channel, &data->dma_cfg)) {
497 			LOG_ERR("Could not configure DMA");
498 			k_sem_give(&data->device_sem);
499 			return -EIO;
500 		}
501 
502 		if (dma_start(data->dma, data->dma_channel)) {
503 			LOG_ERR("Could not start DMA");
504 			k_sem_give(&data->device_sem);
505 			return -EIO;
506 		}
507 
508 		k_sem_take(&data->dma_sync_sem, K_FOREVER);
509 
510 		src += data->layer.stride;
511 		dst += (desc->pitch * config->pixel_size);
512 	}
513 
514 	if (dma_stop(data->dma, data->dma_channel)) {
515 		LOG_WRN("Could not stop DMA");
516 	}
517 
518 	k_sem_give(&data->device_sem);
519 
520 	return 0;
521 }
522 
display_smartbond_write(const struct device * dev,const uint16_t x,const uint16_t y,const struct display_buffer_descriptor * desc,const void * buf)523 static int display_smartbond_write(const struct device *dev,
524 				const uint16_t x, const uint16_t y,
525 				const struct display_buffer_descriptor *desc,
526 				const void *buf)
527 {
528 	struct display_smartbond_data *data = dev->data;
529 	const struct display_smartbond_config *config = dev->config;
530 	uint8_t *dst = data->buffer;
531 	const uint8_t *src = buf;
532 
533 	k_sem_take(&data->device_sem, K_FOREVER);
534 
535 	/* pointer to upper left pixel of the rectangle */
536 	dst += (x * config->pixel_size);
537 	dst += (y * data->layer.stride);
538 
539 	/*
540 	 * Wait for the current frame to finish. Do not disable continuous mode as this
541 	 * will have visual artifacts.
542 	 */
543 	LCDC->LCDC_INTERRUPT_REG |= LCDC_LCDC_INTERRUPT_REG_LCDC_VSYNC_IRQ_EN_Msk;
544 	k_sem_take(&data->sync_sem, K_FOREVER);
545 
546 	data->dma_block_cfg.block_size = desc->width * config->pixel_size;
547 	/*
548 	 * Source and destination base address is word aligned.
549 	 * Data size should be selected based on color depth as
550 	 * cursor is shifted multiple of pixel color depth.
551 	 */
552 	data->dma_cfg.source_data_size = data->dma_cfg.dest_data_size =
553 			!(config->pixel_size & 3) ? 4 :
554 			!(config->pixel_size & 1) ? 2 : 1;
555 
556 	data->dma_cfg.dest_burst_length = data->dma_cfg.source_burst_length =
557 		!((data->dma_block_cfg.block_size / data->dma_cfg.source_data_size) & 7) ? 8 :
558 		!((data->dma_block_cfg.block_size / data->dma_cfg.source_data_size) & 3) ? 4 : 1;
559 
560 	for (int row = 0; row < desc->height; row++) {
561 
562 		data->dma_block_cfg.dest_address = (uint32_t)dst;
563 		data->dma_block_cfg.source_address = (uint32_t)src;
564 
565 		if (dma_config(data->dma, data->dma_channel, &data->dma_cfg)) {
566 			LOG_ERR("Could not configure DMA");
567 			k_sem_give(&data->device_sem);
568 			return -EIO;
569 		}
570 
571 		if (dma_start(data->dma, data->dma_channel)) {
572 			LOG_ERR("Could not start DMA");
573 			k_sem_give(&data->device_sem);
574 			return -EIO;
575 		}
576 
577 		k_sem_take(&data->dma_sync_sem, K_FOREVER);
578 
579 		dst += data->layer.stride;
580 		src += (desc->pitch * config->pixel_size);
581 	}
582 
583 	if (dma_stop(data->dma, data->dma_channel)) {
584 		LOG_WRN("Could not stop DMA");
585 	}
586 
587 	k_sem_give(&data->device_sem);
588 
589 	return 0;
590 }
591 
592 #if defined(CONFIG_PM_DEVICE)
display_smartbond_pm_action(const struct device * dev,enum pm_device_action action)593 static int display_smartbond_pm_action(const struct device *dev, enum pm_device_action action)
594 {
595 	int ret = 0;
596 
597 	switch (action) {
598 	case PM_DEVICE_ACTION_SUSPEND:
599 		/* A non-zero value should not affect sleep */
600 		(void)display_smartbond_suspend(dev);
601 		break;
602 	case PM_DEVICE_ACTION_RESUME:
603 		/*
604 		 * The resume error code should not be taken into consideration
605 		 * by the PM subsystem
606 		 */
607 		ret = display_smartbond_resume(dev);
608 		break;
609 	default:
610 		ret = -ENOTSUP;
611 	}
612 
613 	return ret;
614 }
615 #endif
616 
617 static const struct display_driver_api display_smartbond_driver_api = {
618 	.write =  display_smartbond_write,
619 	.read = display_smartbond_read,
620 	.get_framebuffer = display_smartbond_get_framebuffer,
621 	.get_capabilities = display_smartbond_get_capabilities,
622 	.blanking_off = display_smartbond_blanking_off,
623 	.blanking_on = display_smartbond_blanking_on
624 };
625 
626 #define SMARTBOND_DISPLAY_INIT(inst)	\
627 	PINCTRL_DT_INST_DEFINE(inst);	\
628 	PM_DEVICE_DT_INST_DEFINE(inst, display_smartbond_pm_action);	\
629 									\
630 	__aligned(4) static uint8_t buffer_ ## inst[(((DT_INST_PROP(inst, width) * \
631 	DISPLAY_SMARTBOND_PIXEL_SIZE(inst)) + 0x3) & ~0x3) *	\
632 	DT_INST_PROP(inst, height)] DISPLAY_BUFFER_LINKER_SECTION;	\
633                                             \
634 	static const struct display_smartbond_config display_smartbond_config_## inst = {  \
635 		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst),	\
636 		.disp = GPIO_DT_SPEC_INST_GET_OR(inst, disp_gpios, {}), \
637 		.timing_cfg.vsync_len =	\
638 			DT_PROP(DT_INST_CHILD(inst, display_timings), vsync_len),	\
639 		.timing_cfg.hsync_len =	\
640 			DT_PROP(DT_INST_CHILD(inst, display_timings), hsync_len),	\
641 		.timing_cfg.hfront_porch =	\
642 			DT_PROP(DT_INST_CHILD(inst, display_timings), hfront_porch),	\
643 		.timing_cfg.vfront_porch =	\
644 			DT_PROP(DT_INST_CHILD(inst, display_timings), vfront_porch),	\
645 		.timing_cfg.hback_porch =	\
646 			DT_PROP(DT_INST_CHILD(inst, display_timings), hback_porch),	\
647 		.timing_cfg.vback_porch =	\
648 			DT_PROP(DT_INST_CHILD(inst, display_timings), vback_porch),	\
649 		.bgcolor_cfg = {0xFF, 0xFF, 0xFF, 0}, \
650 		.x_res = DT_INST_PROP(inst, width), \
651 		.y_res = DT_INST_PROP(inst, height),	\
652 		.pixel_size = DISPLAY_SMARTBOND_PIXEL_SIZE(inst),	\
653 		.pixel_format = DT_INST_PROP(0, pixel_format),	\
654 		.mode.vsync_pol =	\
655 			DT_PROP(DT_INST_CHILD(inst, display_timings), vsync_active) ? 0 : 1,	\
656 		.mode.hsync_pol =	\
657 			DT_PROP(DT_INST_CHILD(inst, display_timings), vsync_active) ? 0 : 1,	\
658 		.mode.de_pol =	\
659 			DT_PROP(DT_INST_CHILD(inst, display_timings), de_active) ? 0 : 1,	\
660 		.mode.pixelclk_pol =	\
661 			DT_PROP(DT_INST_CHILD(inst, display_timings), pixelclk_active) ? 0 : 1,	\
662 	};							\
663 								\
664 	static struct display_smartbond_data display_smartbond_data_## inst = {	\
665 		.buffer = buffer_ ##inst,	\
666 		.layer.start_x = 0, \
667 		.layer.start_y = 0, \
668 		.layer.size_x = DT_INST_PROP(inst, width),	\
669 		.layer.size_y = DT_INST_PROP(inst, height),	\
670 		.layer.frame_buf = (uint32_t)buffer_ ## inst, \
671 	}; \
672 							\
673 							\
674 	DEVICE_DT_INST_DEFINE(inst, display_smartbond_init, PM_DEVICE_DT_INST_GET(inst), \
675 				&display_smartbond_data_## inst,	\
676 				&display_smartbond_config_## inst,	\
677 				POST_KERNEL,	\
678 				CONFIG_DISPLAY_INIT_PRIORITY,	\
679 				&display_smartbond_driver_api);
680 
681 SMARTBOND_DISPLAY_INIT(0);
682