From a2b9f241bbd383ee4157f7b4e3ec993f7b66f325 Mon Sep 17 00:00:00 2001 From: Cristian Ciocaltea Date: Wed, 4 Dec 2024 14:09:35 +0200 Subject: [PATCH 099/110] [WIP-YUV420] drm/rockchip: dw_hdmi_qp: Add YUV420 output format support Program the necessary bridge registers to allow using the YUV420 color format. Signed-off-by: Cristian Ciocaltea --- .../gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c index 81f106ac7b56..75a0ea019ede 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include #include @@ -140,6 +142,14 @@ dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder, union phy_configure_opts phy_cfg = {}; int ret; + switch (conn_state->hdmi.output_format) { + case HDMI_COLORSPACE_YUV420: + s->output_mode = ROCKCHIP_OUT_MODE_YUV420; + break; + default: + s->output_mode = ROCKCHIP_OUT_MODE_AAAA; + } + if (hdmi->tmds_char_rate == conn_state->hdmi.tmds_char_rate && s->output_bpc == conn_state->hdmi.output_bpc) return 0; @@ -150,9 +160,13 @@ dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder, ret = phy_configure(hdmi->phy, &phy_cfg); if (!ret) { hdmi->tmds_char_rate = conn_state->hdmi.tmds_char_rate; - s->output_mode = ROCKCHIP_OUT_MODE_AAAA; s->output_type = DRM_MODE_CONNECTOR_HDMIA; s->output_bpc = conn_state->hdmi.output_bpc; + /* + * TODO: Adapt for vop2_convert_csc_mode() which uses v4l2_colorspace + * instead of drm_colorspace. + */ + s->color_space = rockchip_drm_colorimetry_to_v4l_colorspace(conn_state->colorspace); } else { dev_err(hdmi->dev, "Failed to configure phy: %d\n", ret); } @@ -403,6 +417,11 @@ static void dw_hdmi_qp_rk3576_enc_init(struct rockchip_hdmi_qp *hdmi, val = HIWORD_UPDATE(FIELD_PREP(RK3576_COLOR_DEPTH_MASK, RK3576_8BPC), RK3576_COLOR_DEPTH_MASK); + if (state->output_mode == ROCKCHIP_OUT_MODE_YUV420) + val |= FIELD_PREP_WM16(RK3576_COLOR_FORMAT_MASK, RK3576_YUV420); + else + val |= FIELD_PREP_WM16(RK3576_COLOR_FORMAT_MASK, RK3576_RGB); + regmap_write(hdmi->vo_regmap, RK3576_VO0_GRF_SOC_CON8, val); } @@ -418,6 +437,11 @@ static void dw_hdmi_qp_rk3588_enc_init(struct rockchip_hdmi_qp *hdmi, val = HIWORD_UPDATE(FIELD_PREP(RK3588_COLOR_DEPTH_MASK, RK3588_8BPC), RK3588_COLOR_DEPTH_MASK); + if (state->output_mode == ROCKCHIP_OUT_MODE_YUV420) + val |= FIELD_PREP_WM16(RK3588_COLOR_FORMAT_MASK, RK3588_YUV420); + else + val |= FIELD_PREP_WM16(RK3588_COLOR_FORMAT_MASK, RK3588_RGB); + regmap_write(hdmi->vo_regmap, hdmi->port_id ? RK3588_GRF_VO1_CON6 : RK3588_GRF_VO1_CON3, val); @@ -526,6 +550,8 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master, plat_data.phy_ops = cfg->phy_ops; plat_data.phy_data = hdmi; + plat_data.supported_formats = BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV420); plat_data.max_bpc = 10; encoder = &hdmi->encoder.encoder; -- 2.34.1