[PATCH] drm/rockchip: rk3288-lvds: honor DCLK edge via GRF CON15

Christoph Fritz chf.fritz at googlemail.com
Mon Sep 15 10:35:22 PDT 2025


Set the DCLK edge (normal or invert) via GRF_SOC_CON15 when the specific
drm_bus_flag is enabled. Keep track of the vop source in use so that the
right DCLK (BIG: dclk0 or LIT: dclk1) gets set.

This change is especially necessary for RGB output configurations to
actually propagate the DCLK inversion.

Signed-off-by: Christoph Fritz <chf.fritz at googlemail.com>
---
 drivers/gpu/drm/rockchip/rockchip_lvds.c | 17 +++++++++++++++++
 drivers/gpu/drm/rockchip/rockchip_lvds.h |  4 ++++
 2 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c
index 2411260db51d7..08784c3ecf703 100644
--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c
+++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c
@@ -58,6 +58,7 @@ struct rockchip_lvds {
 	struct drm_bridge *bridge;
 	struct rockchip_encoder encoder;
 	struct dev_pin_info *pins;
+	bool use_vop_lit; /* true if CON6 selects VOP_LIT */
 };
 
 static inline struct rockchip_lvds *brige_to_lvds(struct drm_bridge *bridge)
@@ -235,8 +236,11 @@ static int rk3288_lvds_grf_config(struct drm_encoder *encoder,
 				  struct drm_display_mode *mode)
 {
 	struct rockchip_lvds *lvds = encoder_to_lvds(encoder);
+	u32 bus_flgs = lvds->connector.display_info.bus_flags;
+	u8 con15_dclk = (bus_flgs & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) ? 1 : 0;
 	u8 pin_hsync = (mode->flags & DRM_MODE_FLAG_PHSYNC) ? 1 : 0;
 	u8 pin_dclk = (mode->flags & DRM_MODE_FLAG_PCSYNC) ? 1 : 0;
+	unsigned int con15_dclk_mask;
 	u32 val;
 	int ret;
 
@@ -260,6 +264,17 @@ static int rk3288_lvds_grf_config(struct drm_encoder *encoder,
 	if (ret)
 		DRM_DEV_ERROR(lvds->dev, "Could not write to GRF: %d\n", ret);
 
+	/* SOC_CON15 DCLK normal/invert */
+	con15_dclk_mask = lvds->use_vop_lit ?
+		RK3288_LVDS_SOC_CON15_LIT_DCLK1_INVERT :
+		RK3288_LVDS_SOC_CON15_BIG_DCLK0_INVERT;
+
+	val = con15_dclk ? con15_dclk_mask : 0;
+	val |= con15_dclk_mask << 16;
+	ret = regmap_write(lvds->grf, RK3288_LVDS_GRF_SOC_CON15, val);
+	if (ret)
+		DRM_DEV_ERROR(lvds->dev, "Could not write to CON15: %d\n", ret);
+
 	return ret;
 }
 
@@ -273,6 +288,8 @@ static int rk3288_lvds_set_vop_source(struct rockchip_lvds *lvds,
 	if (ret < 0)
 		return ret;
 
+	lvds->use_vop_lit = !!ret;
+
 	val = RK3288_LVDS_SOC_CON6_SEL_VOP_LIT << 16;
 	if (ret)
 		val |= RK3288_LVDS_SOC_CON6_SEL_VOP_LIT;
diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.h b/drivers/gpu/drm/rockchip/rockchip_lvds.h
index 2d92447d819be..81081b84eea6a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_lvds.h
+++ b/drivers/gpu/drm/rockchip/rockchip_lvds.h
@@ -77,6 +77,10 @@
 
 #define RK3288_LVDS_GRF_SOC_CON6		0x025C
 #define RK3288_LVDS_GRF_SOC_CON7		0x0260
+#define RK3288_LVDS_GRF_SOC_CON15		0x03a4
+
+#define RK3288_LVDS_SOC_CON15_BIG_DCLK0_INVERT	BIT(13)
+#define RK3288_LVDS_SOC_CON15_LIT_DCLK1_INVERT	BIT(15)
 
 /* fbdiv value is split over 2 registers, with bit8 in reg2 */
 #define RK3288_LVDS_PLL_FBDIV_REG2(_fbd) \
-- 
2.39.5





More information about the linux-arm-kernel mailing list