Files
LibreELEC.tv/packages/linux/patches/rockchip/rockchip-0099-WIP-YUV420-drm-rockchip-dw_hdmi_qp-Add-YUV420-output.patch
Christian Hewitt 5b2b97c29c linux: update rockchip to Linux 6.17-rc6
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
2025-09-16 15:18:29 +00:00

94 lines
3.4 KiB
Diff

From a2b9f241bbd383ee4157f7b4e3ec993f7b66f325 Mon Sep 17 00:00:00 2001
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
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 <cristian.ciocaltea@collabora.com>
---
.../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 <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/gpio/consumer.h>
+#include <linux/hdmi.h>
+#include <linux/hw_bitfield.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -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