drm/mediatek: dpi: Add YUV422 output support
authorBo-Chen Chen <rex-bc.chen@mediatek.com>
Tue, 5 Jul 2022 10:25:26 +0000 (18:25 +0800)
committerChun-Kuang Hu <chunkuang.hu@kernel.org>
Wed, 6 Jul 2022 14:22:10 +0000 (22:22 +0800)
Dp_intf supports YUV422 as output format. In MT8195 Chrome project,
YUV422 output format is used for 4K resolution.

To support this, it is also needed to support color format transfer.
Color format transfer is a new feature for both dpi and dpintf of MT8195.

The input format could be RGB888 and output format for dp_intf should be
YUV422. Therefore, we add a mtk_dpi_matrix_sel() helper to update the
DPI_MATRIX_SET register depending on the color format.

Signed-off-by: Guillaume Ranquet <granquet@baylibre.com>
Signed-off-by: Bo-Chen Chen <rex-bc.chen@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20220705102530.1344-2-rex-bc.chen@mediatek.com/
Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
drivers/gpu/drm/mediatek/mtk_dpi.c
drivers/gpu/drm/mediatek/mtk_dpi_regs.h

index ea8d866e67bc5e8d0345b22d7cf94bbde5445673..5ee74209a279c6843a30acae74117b3de9583d38 100644 (file)
@@ -54,7 +54,8 @@ enum mtk_dpi_out_channel_swap {
 };
 
 enum mtk_dpi_out_color_format {
-       MTK_DPI_COLOR_FORMAT_RGB
+       MTK_DPI_COLOR_FORMAT_RGB,
+       MTK_DPI_COLOR_FORMAT_YCBCR_422
 };
 
 struct mtk_dpi {
@@ -409,12 +410,25 @@ static void mtk_dpi_config_disable_edge(struct mtk_dpi *dpi)
 static void mtk_dpi_config_color_format(struct mtk_dpi *dpi,
                                        enum mtk_dpi_out_color_format format)
 {
-       /* only support RGB888 */
-       mtk_dpi_config_yuv422_enable(dpi, false);
-       mtk_dpi_config_csc_enable(dpi, false);
-       if (dpi->conf->swap_input_support)
-               mtk_dpi_config_swap_input(dpi, false);
        mtk_dpi_config_channel_swap(dpi, MTK_DPI_OUT_CHANNEL_SWAP_RGB);
+
+       if (format == MTK_DPI_COLOR_FORMAT_YCBCR_422) {
+               mtk_dpi_config_yuv422_enable(dpi, true);
+               mtk_dpi_config_csc_enable(dpi, true);
+
+               /*
+                * If height is smaller than 720, we need to use RGB_TO_BT601
+                * to transfer to yuv422. Otherwise, we use RGB_TO_JPEG.
+                */
+               mtk_dpi_mask(dpi, DPI_MATRIX_SET, dpi->mode.hdisplay <= 720 ?
+                            MATRIX_SEL_RGB_TO_BT601 : MATRIX_SEL_RGB_TO_JPEG,
+                            INT_MATRIX_SEL_MASK);
+       } else {
+               mtk_dpi_config_yuv422_enable(dpi, false);
+               mtk_dpi_config_csc_enable(dpi, false);
+               if (dpi->conf->swap_input_support)
+                       mtk_dpi_config_swap_input(dpi, false);
+       }
 }
 
 static void mtk_dpi_dual_edge(struct mtk_dpi *dpi)
@@ -648,7 +662,10 @@ static int mtk_dpi_bridge_atomic_check(struct drm_bridge *bridge,
        dpi->bit_num = MTK_DPI_OUT_BIT_NUM_8BITS;
        dpi->channel_swap = MTK_DPI_OUT_CHANNEL_SWAP_RGB;
        dpi->yc_map = MTK_DPI_OUT_YC_MAP_RGB;
-       dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
+       if (out_bus_format == MEDIA_BUS_FMT_YUYV8_1X16)
+               dpi->color_format = MTK_DPI_COLOR_FORMAT_YCBCR_422;
+       else
+               dpi->color_format = MTK_DPI_COLOR_FORMAT_RGB;
 
        return 0;
 }
index 3a02fabe16627a3e6419675586d40c0a8a8598d8..9ce300313f3ed38f3e3d77f96ec4775a9f6a02a8 100644 (file)
 
 #define EDGE_SEL_EN                    BIT(5)
 #define H_FRE_2N                       BIT(25)
+
+#define DPI_MATRIX_SET         0xB4
+#define INT_MATRIX_SEL_MASK            GENMASK(4, 0)
+#define MATRIX_SEL_RGB_TO_JPEG         0
+#define MATRIX_SEL_RGB_TO_BT601                2
+
 #endif /* __MTK_DPI_REGS_H */