diff options
4 files changed, 38 insertions, 10 deletions
diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c index 5fcd5123136f..f61618e12322 100644 --- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c +++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c @@ -25,6 +25,7 @@ #define DCMIPP_P0SCSZR_HSIZE_SHIFT 0 #define DCMIPP_P0SCSZR_VSIZE_SHIFT 16 #define DCMIPP_P0PPCR 0x5c0 +#define DCMIPP_P0PPCR_SWAPYUV BIT(0) #define DCMIPP_P0PPCR_BSM_1_2 0x1 #define DCMIPP_P0PPCR_BSM_1_4 0x2 #define DCMIPP_P0PPCR_BSM_2_4 0x3 @@ -428,9 +429,11 @@ static int dcmipp_byteproc_configure_scale_crop if (!vpix) return -EINVAL; - /* clear decimation/crop */ + /* clear decimation/crop/swap yuv */ reg_clear(byteproc, DCMIPP_P0PPCR, DCMIPP_P0PPCR_BSM_MASK); reg_clear(byteproc, DCMIPP_P0PPCR, DCMIPP_P0PPCR_LSM); + if (byteproc->ved.dcmipp->pipe_cfg->has_swapyuv) + reg_clear(byteproc, DCMIPP_P0PPCR, DCMIPP_P0PPCR_SWAPYUV); reg_write(byteproc, DCMIPP_P0SCSTR, 0); reg_write(byteproc, DCMIPP_P0SCSZR, 0); @@ -451,6 +454,17 @@ static int dcmipp_byteproc_configure_scale_crop if (vprediv == 2) val |= DCMIPP_P0PPCR_LSM | DCMIPP_P0PPCR_OELS; + /* + * Perform a SWAP YUV if input is parallel since in this mode + * the DCMIPP will swap YUV by default + */ + if (byteproc->ved.dcmipp->pipe_cfg->has_swapyuv && + (sink_fmt->code == MEDIA_BUS_FMT_YUYV8_2X8 || + sink_fmt->code == MEDIA_BUS_FMT_YVYU8_2X8 || + sink_fmt->code == MEDIA_BUS_FMT_UYVY8_2X8 || + sink_fmt->code == MEDIA_BUS_FMT_VYUY8_2X8)) + val |= DCMIPP_P0PPCR_SWAPYUV; + /* decimate using bytes and lines skipping */ if (val) { reg_set(byteproc, DCMIPP_P0PPCR, val); diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-common.h b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-common.h index b94a9c87f56e..b491ce00c656 100644 --- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-common.h +++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-common.h @@ -118,6 +118,7 @@ struct dcmipp_pipeline_config { u32 hw_revision; bool has_csi2; bool needs_mclk; + bool has_swapyuv; }; /** diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c index 8f7e131238fc..a4dc9da70cd6 100644 --- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c +++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c @@ -108,7 +108,8 @@ static const struct dcmipp_pipeline_config stm32mp25_pipe_cfg = { .num_links = ARRAY_SIZE(stm32mp25_ent_links), .hw_revision = DCMIPP_STM32MP25_VERR, .has_csi2 = true, - .needs_mclk = true + .needs_mclk = true, + .has_swapyuv = true }; #define LINK_FLAG_TO_STR(f) ((f) == 0 ? "" :\ diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c index 564f37e2e1dd..75421035cfad 100644 --- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c +++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c @@ -80,15 +80,15 @@ static const struct dcmipp_inp_pix_map dcmipp_inp_pix_map_list[] = { PIXMAP_SINK_SRC_PRCR_SWAP(RGB888_3X8, RGB888_3X8, RGB888, 0, MIPI_CSI2_DT_RGB888), PIXMAP_SINK_SRC_PRCR_SWAP(RGB888_1X24, RGB888_1X24, RGB888, 0, MIPI_CSI2_DT_RGB888), /* YUV422 */ - PIXMAP_SINK_SRC_PRCR_SWAP(YUYV8_2X8, YUYV8_2X8, YUV422, 1, MIPI_CSI2_DT_YUV422_8B), + PIXMAP_SINK_SRC_PRCR_SWAP(YUYV8_2X8, YUYV8_2X8, YUV422, 0, MIPI_CSI2_DT_YUV422_8B), PIXMAP_SINK_SRC_PRCR_SWAP(YUYV8_1X16, YUYV8_1X16, YUV422, 0, MIPI_CSI2_DT_YUV422_8B), - PIXMAP_SINK_SRC_PRCR_SWAP(YUYV8_2X8, UYVY8_2X8, YUV422, 0, MIPI_CSI2_DT_YUV422_8B), - PIXMAP_SINK_SRC_PRCR_SWAP(UYVY8_2X8, UYVY8_2X8, YUV422, 1, MIPI_CSI2_DT_YUV422_8B), + PIXMAP_SINK_SRC_PRCR_SWAP(YUYV8_2X8, UYVY8_2X8, YUV422, 1, MIPI_CSI2_DT_YUV422_8B), + PIXMAP_SINK_SRC_PRCR_SWAP(UYVY8_2X8, UYVY8_2X8, YUV422, 0, MIPI_CSI2_DT_YUV422_8B), PIXMAP_SINK_SRC_PRCR_SWAP(UYVY8_1X16, UYVY8_1X16, YUV422, 0, MIPI_CSI2_DT_YUV422_8B), - PIXMAP_SINK_SRC_PRCR_SWAP(UYVY8_2X8, YUYV8_2X8, YUV422, 0, MIPI_CSI2_DT_YUV422_8B), - PIXMAP_SINK_SRC_PRCR_SWAP(YVYU8_2X8, YVYU8_2X8, YUV422, 1, MIPI_CSI2_DT_YUV422_8B), + PIXMAP_SINK_SRC_PRCR_SWAP(UYVY8_2X8, YUYV8_2X8, YUV422, 1, MIPI_CSI2_DT_YUV422_8B), + PIXMAP_SINK_SRC_PRCR_SWAP(YVYU8_2X8, YVYU8_2X8, YUV422, 0, MIPI_CSI2_DT_YUV422_8B), PIXMAP_SINK_SRC_PRCR_SWAP(YVYU8_1X16, YVYU8_1X16, YUV422, 0, MIPI_CSI2_DT_YUV422_8B), - PIXMAP_SINK_SRC_PRCR_SWAP(VYUY8_2X8, VYUY8_2X8, YUV422, 1, MIPI_CSI2_DT_YUV422_8B), + PIXMAP_SINK_SRC_PRCR_SWAP(VYUY8_2X8, VYUY8_2X8, YUV422, 0, MIPI_CSI2_DT_YUV422_8B), PIXMAP_SINK_SRC_PRCR_SWAP(VYUY8_1X16, VYUY8_1X16, YUV422, 0, MIPI_CSI2_DT_YUV422_8B), /* GREY */ PIXMAP_SINK_SRC_PRCR_SWAP(Y8_1X8, Y8_1X8, G8, 0, MIPI_CSI2_DT_RAW8), @@ -356,8 +356,20 @@ static int dcmipp_inp_configure_parallel(struct dcmipp_inp_device *inp, val |= vpix->prcr_format << DCMIPP_PRCR_FORMAT_SHIFT; /* swap cycles */ - if (vpix->prcr_swapcycles) - val |= DCMIPP_PRCR_SWAPCYCLES; + /* + * Table dcmipp_inp_pix_map_list take into consideration that SWAPYUV + * bit is available when dealing with 16bit YUV formats. If it is not + * available (such as on stm32mp13), swapcycle setting should be + * reversed + */ + if (!inp->ved.dcmipp->pipe_cfg->has_swapyuv && + (src_fmt->code == MEDIA_BUS_FMT_YUYV8_2X8 || + src_fmt->code == MEDIA_BUS_FMT_YVYU8_2X8 || + src_fmt->code == MEDIA_BUS_FMT_UYVY8_2X8 || + src_fmt->code == MEDIA_BUS_FMT_VYUY8_2X8)) + val |= (!vpix->prcr_swapcycles ? DCMIPP_PRCR_SWAPCYCLES : 0); + else + val |= (vpix->prcr_swapcycles ? DCMIPP_PRCR_SWAPCYCLES : 0); reg_write(inp, DCMIPP_PRCR, val); |
