@@ -173,6 +173,7 @@
#define MIPI_CSIS_ISPCFG_PIXEL_MODE_SINGLE (0 << 12)
#define MIPI_CSIS_ISPCFG_PIXEL_MODE_DUAL (1 << 12)
#define MIPI_CSIS_ISPCFG_PIXEL_MODE_QUAD (2 << 12) /* i.MX8M[MNP] only */
+#define MIPI_CSIS_ISPCFG_PIXEL_MASK (3 << 12)
#define MIPI_CSIS_ISPCFG_ALIGN_32BIT BIT(11)
#define MIPI_CSIS_ISPCFG_FMT(fmt) ((fmt) << 2)
#define MIPI_CSIS_ISPCFG_FMT_MASK (0x3f << 2)
@@ -506,7 +507,25 @@ static void __mipi_csis_set_format(struct csi_state *state)
/* Color format */
val = mipi_csis_read(state, MIPI_CSIS_ISP_CONFIG_CH(0));
- val &= ~(MIPI_CSIS_ISPCFG_ALIGN_32BIT | MIPI_CSIS_ISPCFG_FMT_MASK);
+ val &= ~(MIPI_CSIS_ISPCFG_ALIGN_32BIT | MIPI_CSIS_ISPCFG_FMT_MASK
+ | MIPI_CSIS_ISPCFG_PIXEL_MASK);
+
+ /*
+ * YUV 4:2:2 can be transferred with 8 or 16 bits per clock sample
+ * (referred to in the documentation as single and dual pixel modes
+ * respectively, although the 8-bit mode transfers half a pixel per
+ * clock sample and the 16-bit mode one pixel). While both mode work
+ * when the CSIS is connected to a receiver that supports either option,
+ * single pixel mode requires clock rates twice as high. As all SoCs
+ * that integrate the CSIS can operate in 16-bit bit mode, and some do
+ * not support 8-bit mode (this is the case of the i.MX8MP), use dual
+ * pixel mode unconditionally.
+ *
+ * TODO: Verify which other formats require DUAL (or QUAD) modes.
+ */
+ if (state->csis_fmt->data_type == MIPI_CSI2_DATA_TYPE_YUV422_8)
+ val |= MIPI_CSIS_ISPCFG_PIXEL_MODE_DUAL;
+
val |= MIPI_CSIS_ISPCFG_FMT(state->csis_fmt->data_type);
mipi_csis_write(state, MIPI_CSIS_ISP_CONFIG_CH(0), val);