drivers: display: display_mcux_elcdif: Add PXP flip feature
display_write() can leverage PXP to flip the image. Signed-off-by: Derek Snell <derek.snell@nxp.com>
This commit is contained in:
parent
2b601fa3a0
commit
200a669dd2
2 changed files with 44 additions and 6 deletions
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2019,2023 NXP
|
||||
# Copyright 2019,2023-2024 NXP
|
||||
# Copyright (c) 2022, Basalte bv
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
|
|
@ -105,6 +105,33 @@ config MCUX_ELCDIF_PXP_ROTATE_270
|
|||
|
||||
endchoice
|
||||
|
||||
choice MCUX_ELCDIF_PXP_FLIP_DIRECTION
|
||||
default MCUX_ELCDIF_PXP_FLIP_DISABLE
|
||||
prompt "Flip direction of PXP"
|
||||
help
|
||||
Set flip direction of PXP. The ELCDIF cannot detect the correct
|
||||
rotation angle based on the call to display_write, so the user should
|
||||
configure it here. In order for PXP flip to work, calls to
|
||||
display_write MUST supply a framebuffer equal in size to screen width
|
||||
and height (without flip applied). Note that the width and
|
||||
height settings of the screen in devicetree should not be modified
|
||||
from their values in the default screen orientation when using this
|
||||
functionality.
|
||||
|
||||
config MCUX_ELCDIF_PXP_FLIP_DISABLE
|
||||
bool "Do not flip display"
|
||||
|
||||
config MCUX_ELCDIF_PXP_FLIP_HORIZONTAL
|
||||
bool "Flip display horizontally"
|
||||
|
||||
config MCUX_ELCDIF_PXP_FLIP_VERTICAL
|
||||
bool "Flip display vertically"
|
||||
|
||||
config MCUX_ELCDIF_PXP_FLIP_BOTH
|
||||
bool "Flib display both horizontally and vertically"
|
||||
|
||||
endchoice
|
||||
|
||||
endif # MCUX_ELCDIF_PXP
|
||||
|
||||
endif # DISPLAY_MCUX_ELCDIF
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2019-23, NXP
|
||||
* Copyright 2019-24, NXP
|
||||
* Copyright (c) 2022, Basalte bv
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
|
|
@ -54,7 +54,7 @@ struct mcux_elcdif_data {
|
|||
/* Tracks index of next active driver framebuffer */
|
||||
uint8_t next_idx;
|
||||
#ifdef CONFIG_MCUX_ELCDIF_PXP
|
||||
/* Given to when PXP completes rotation */
|
||||
/* Given to when PXP completes operation */
|
||||
struct k_sem pxp_done;
|
||||
#endif
|
||||
};
|
||||
|
|
@ -138,12 +138,12 @@ static int mcux_elcdif_write(const struct device *dev, const uint16_t x, const u
|
|||
|
||||
#ifdef CONFIG_MCUX_ELCDIF_PXP
|
||||
if (full_fb) {
|
||||
/* Configure PXP using DMA API, and rotate frame */
|
||||
/* Configure PXP using DMA API, and rotate/flip frame */
|
||||
struct dma_config pxp_dma = {0};
|
||||
struct dma_block_config pxp_block = {0};
|
||||
|
||||
/* Source buffer is input to display_write, we will
|
||||
* place rotated output into a driver framebuffer.
|
||||
* place modified output into a driver framebuffer.
|
||||
*/
|
||||
dev_data->active_fb = dev_data->fb[dev_data->next_idx];
|
||||
pxp_block.source_address = (uint32_t)buf;
|
||||
|
|
@ -171,6 +171,17 @@ static int mcux_elcdif_write(const struct device *dev, const uint16_t x, const u
|
|||
pxp_dma.dma_slot |= DMA_MCUX_PXP_CMD(DMA_MCUX_PXP_CMD_ROTATE_0);
|
||||
}
|
||||
|
||||
/* DMA linked_channel sets the flip direction */
|
||||
if (IS_ENABLED(CONFIG_MCUX_ELCDIF_PXP_FLIP_HORIZONTAL)) {
|
||||
pxp_dma.linked_channel |= DMA_MCUX_PXP_FLIP(DMA_MCUX_PXP_FLIP_HORIZONTAL);
|
||||
} else if (IS_ENABLED(CONFIG_MCUX_ELCDIF_PXP_FLIP_VERTICAL)) {
|
||||
pxp_dma.linked_channel |= DMA_MCUX_PXP_FLIP(DMA_MCUX_PXP_FLIP_VERTICAL);
|
||||
} else if (IS_ENABLED(CONFIG_MCUX_ELCDIF_PXP_FLIP_BOTH)) {
|
||||
pxp_dma.linked_channel |= DMA_MCUX_PXP_FLIP(DMA_MCUX_PXP_FLIP_BOTH);
|
||||
} else {
|
||||
pxp_dma.linked_channel |= DMA_MCUX_PXP_FLIP(DMA_MCUX_PXP_FLIP_DISABLE);
|
||||
}
|
||||
|
||||
pxp_dma.channel_direction = MEMORY_TO_MEMORY;
|
||||
pxp_dma.source_data_size = desc->width * dev_data->pixel_bytes;
|
||||
pxp_dma.dest_data_size = config->rgb_mode.panelWidth * dev_data->pixel_bytes;
|
||||
|
|
@ -191,7 +202,7 @@ static int mcux_elcdif_write(const struct device *dev, const uint16_t x, const u
|
|||
}
|
||||
k_sem_take(&dev_data->pxp_done, K_FOREVER);
|
||||
} else {
|
||||
LOG_WRN("PXP rotation will not work correctly unless a full sized "
|
||||
LOG_WRN("PXP rotation/flip will not work correctly unless a full sized "
|
||||
"framebuffer is provided");
|
||||
}
|
||||
#endif /* CONFIG_MCUX_ELCDIF_PXP */
|
||||
|
|
|
|||
Loading…
Reference in a new issue