Skip to content

Video: Display: NXP: Decouple PxP from eLCDIF. Make a new driver for PxP in video m2m category #92366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 0 additions & 80 deletions drivers/display/Kconfig.mcux_elcdif
Original file line number Diff line number Diff line change
Expand Up @@ -43,84 +43,4 @@ config MCUX_ELCDIF_FB_SIZE
4-bytes pixel format, e.g. ARGB8888. Applications should change this value
according to the actual used resolution and format to optimize the heap size.

config MCUX_ELCDIF_PXP
bool "Use PXP for display rotation"
depends on MCUX_PXP
depends on (MCUX_ELCDIF_FB_NUM > 0)
help
Use the PXP for display rotation. This requires the LCDIF node
have a "nxp,pxp" devicetree property pointing to the PXP device node.
The ELCDIF will only utilize the PXP to rotate frames if
display_write is called with a framebuffer equal in size to the
display.

if MCUX_ELCDIF_PXP

choice MCUX_ELCDIF_PXP_ROTATE_DIRECTION
default MCUX_ELCDIF_PXP_ROTATE_0
prompt "Rotation angle of PXP"
help
Set rotation angle 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 rotation to work, calls to
display_write MUST supply a framebuffer equal in size to screen width
and height (without rotation 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_ROTATE_0
bool "Rotate display by 0 degrees"
help
Rotate display by 0 degrees. Primarily useful for testing,
production applications should simply disable the PXP.

config MCUX_ELCDIF_PXP_ROTATE_90
bool "Rotate display by 90 degrees"
help
Rotate display counter-clockwise by 90 degrees.
For LVGL, this corresponds to a rotation of 270 degrees

config MCUX_ELCDIF_PXP_ROTATE_180
bool "Rotate display by 180 degrees"
help
Rotate display counter-clockwise by 180 degrees

config MCUX_ELCDIF_PXP_ROTATE_270
bool "Rotate display by 270 degrees"
help
Rotate display counter-clockwise by 270 degrees
For LVGL, this corresponds to a rotation of 90 degrees

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
110 changes: 1 addition & 109 deletions drivers/display/display_mcux_elcdif.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@
#include <fsl_cache.h>
#endif

#ifdef CONFIG_MCUX_ELCDIF_PXP
#include <zephyr/drivers/dma.h>
#include <zephyr/drivers/dma/dma_mcux_pxp.h>
#endif

#include <zephyr/logging/log.h>
#include <zephyr/irq.h>

Expand All @@ -39,7 +34,6 @@ struct mcux_elcdif_config {
elcdif_rgb_mode_config_t rgb_mode;
const struct pinctrl_dev_config *pincfg;
const struct gpio_dt_spec backlight_gpio;
const struct device *pxp;
};

struct mcux_elcdif_data {
Expand All @@ -54,22 +48,8 @@ struct mcux_elcdif_data {
struct k_sem sem;
/* Tracks index of next active driver framebuffer */
uint8_t next_idx;
#ifdef CONFIG_MCUX_ELCDIF_PXP
/* Given to when PXP completes operation */
struct k_sem pxp_done;
#endif
};

#ifdef CONFIG_MCUX_ELCDIF_PXP
static void mcux_elcdif_pxp_callback(const struct device *dma_dev, void *user_data,
uint32_t channel, int ret)
{
struct mcux_elcdif_data *data = user_data;

k_sem_give(&data->pxp_done);
}
#endif /* CONFIG_MCUX_ELCDIF_PXP */

static int mcux_elcdif_write(const struct device *dev, const uint16_t x, const uint16_t y,
const struct display_buffer_descriptor *desc, const void *buf)
{
Expand All @@ -92,15 +72,6 @@ static int mcux_elcdif_write(const struct device *dev, const uint16_t x, const u
LOG_DBG("Setting FB from %p->%p", (void *)dev_data->active_fb, (void *)buf);
dev_data->active_fb = buf;
full_fb = true;
} else if ((x == 0) && (y == 0) && (desc->width == config->rgb_mode.panelHeight) &&
(desc->height == config->rgb_mode.panelWidth) && (desc->pitch == desc->width) &&
IS_ENABLED(CONFIG_MCUX_ELCDIF_PXP)) {
/* With the PXP, we can rotate this display buffer to align
* with output dimensions
*/
LOG_DBG("Setting FB from %p->%p", (void *)dev_data->active_fb, (void *)buf);
dev_data->active_fb = buf;
full_fb = true;
} else {
/* We must use partial framebuffer copy */
if (CONFIG_MCUX_ELCDIF_FB_NUM == 0) {
Expand Down Expand Up @@ -137,77 +108,6 @@ static int mcux_elcdif_write(const struct device *dev, const uint16_t x, const u
DCACHE_CleanByRange((uint32_t)dev_data->active_fb, dev_data->fb_bytes);
#endif

#ifdef CONFIG_MCUX_ELCDIF_PXP
if (full_fb) {
/* 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 modified output into a driver framebuffer.
*/
dev_data->active_fb = dev_data->fb[dev_data->next_idx];
pxp_block.source_address = (uint32_t)buf;
pxp_block.dest_address = (uint32_t)dev_data->active_fb;
pxp_block.block_size = desc->buf_size;

/* DMA slot sets pixel format and rotation angle */
if (dev_data->pixel_format == PIXEL_FORMAT_BGR_565) {
pxp_dma.dma_slot = DMA_MCUX_PXP_FMT(DMA_MCUX_PXP_FMT_RGB565);
} else if (dev_data->pixel_format == PIXEL_FORMAT_RGB_888) {
pxp_dma.dma_slot = DMA_MCUX_PXP_FMT(DMA_MCUX_PXP_FMT_RGB888);
} else if (dev_data->pixel_format == PIXEL_FORMAT_ARGB_8888) {
pxp_dma.dma_slot = DMA_MCUX_PXP_FMT(DMA_MCUX_PXP_FMT_ARGB8888);
} else {
/* Cannot rotate */
return -ENOTSUP;
}
if (IS_ENABLED(CONFIG_MCUX_ELCDIF_PXP_ROTATE_90)) {
pxp_dma.dma_slot |= DMA_MCUX_PXP_CMD(DMA_MCUX_PXP_CMD_ROTATE_90);
} else if (IS_ENABLED(CONFIG_MCUX_ELCDIF_PXP_ROTATE_180)) {
pxp_dma.dma_slot |= DMA_MCUX_PXP_CMD(DMA_MCUX_PXP_CMD_ROTATE_180);
} else if (IS_ENABLED(CONFIG_MCUX_ELCDIF_PXP_ROTATE_270)) {
pxp_dma.dma_slot |= DMA_MCUX_PXP_CMD(DMA_MCUX_PXP_CMD_ROTATE_270);
} else {
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;
/* Burst lengths are heights of source/dest buffer in pixels */
pxp_dma.source_burst_length = desc->height;
pxp_dma.dest_burst_length = config->rgb_mode.panelHeight;
pxp_dma.head_block = &pxp_block;
pxp_dma.dma_callback = mcux_elcdif_pxp_callback;
pxp_dma.user_data = dev_data;

ret = dma_config(config->pxp, 0, &pxp_dma);
if (ret < 0) {
return ret;
}
ret = dma_start(config->pxp, 0);
if (ret < 0) {
return ret;
}
k_sem_take(&dev_data->pxp_done, K_FOREVER);
} else {
LOG_WRN("PXP rotation/flip will not work correctly unless a full sized "
"framebuffer is provided");
}
#endif /* CONFIG_MCUX_ELCDIF_PXP */

/* Queue next framebuffer */
ELCDIF_SetNextBufferAddr(config->base, (uint32_t)dev_data->active_fb);

Expand Down Expand Up @@ -348,13 +248,6 @@ static int mcux_elcdif_init(const struct device *dev)
#endif /* DT_ANY_INST_HAS_PROP_STATUS_OKAY(backlight_gpios) */

k_sem_init(&dev_data->sem, 0, 1);
#ifdef CONFIG_MCUX_ELCDIF_PXP
k_sem_init(&dev_data->pxp_done, 0, 1);
if (!device_is_ready(config->pxp)) {
LOG_ERR("PXP device is not ready");
return -ENODEV;
}
#endif

config->irq_config_func(dev);

Expand Down Expand Up @@ -413,8 +306,7 @@ static DEVICE_API(display, mcux_elcdif_api) = {
}, \
.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(id), \
.backlight_gpio = GPIO_DT_SPEC_INST_GET_OR(id, backlight_gpios, {0}), \
IF_ENABLED(CONFIG_MCUX_ELCDIF_PXP, \
(.pxp = DEVICE_DT_GET(DT_INST_PHANDLE(id, nxp_pxp)),))}; \
}; \
static struct mcux_elcdif_data mcux_elcdif_data_##id = { \
.next_idx = 0, \
.pixel_format = DT_INST_PROP(id, pixel_format), \
Expand Down
1 change: 0 additions & 1 deletion drivers/dma/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ zephyr_library_sources_ifdef(CONFIG_DMA_MCHP_XEC dma_mchp_xec.c)
zephyr_library_sources_ifdef(CONFIG_DMA_XMC4XXX dma_xmc4xxx.c)
zephyr_library_sources_ifdef(CONFIG_DMA_RPI_PICO dma_rpi_pico.c)
zephyr_library_sources_ifdef(CONFIG_DMA_RENESAS_RZ dma_renesas_rz.c)
zephyr_library_sources_ifdef(CONFIG_MCUX_PXP dma_mcux_pxp.c)
zephyr_library_sources_ifdef(CONFIG_DMA_MAX32 dma_max32.c)
zephyr_library_sources_ifdef(CONFIG_DMA_MCUX_SMARTDMA dma_mcux_smartdma.c)
zephyr_library_sources_ifdef(CONFIG_DMA_ANDES_ATCDMAC300 dma_andes_atcdmac300.c)
Expand Down
2 changes: 0 additions & 2 deletions drivers/dma/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ source "drivers/dma/Kconfig.ifx_cat1"

source "drivers/dma/Kconfig.intel_lpss"

source "drivers/dma/Kconfig.mcux_pxp"

source "drivers/dma/Kconfig.max32"

source "drivers/dma/Kconfig.mcux_smartdma"
Expand Down
10 changes: 0 additions & 10 deletions drivers/dma/Kconfig.mcux_pxp

This file was deleted.

Loading