summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c16
-rw-r--r--drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-common.h1
-rw-r--r--drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c3
-rw-r--r--drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c28
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);