From c1483412f9a2fecac2e31d24bdf83bc77d8e4860 Mon Sep 17 00:00:00 2001 From: Damon Ding Date: Thu, 1 Aug 2024 14:32:43 +0800 Subject: [PATCH] drm/rockchip: vop: add support to assign mcu bypass timing in dts Use user-defined mcu bypass timing if mcu-bypass-timing node has been found in dts, otherwise setup the default timing which can meet the read/write timing requirements of most mcu panel. Change-Id: I1225eed1e9dbca5adafd2d674bc9b6c709b2b1dd Signed-off-by: Damon Ding --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 48 ++++++++++++++++++--- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 4f24351c5cef..48e70d34d96b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -304,6 +304,7 @@ struct vop { struct rockchip_dclk_pll *pll; struct rockchip_mcu_timing mcu_timing; + struct rockchip_mcu_timing mcu_bypass_timing; struct vop_win win[]; }; @@ -3138,13 +3139,27 @@ static void vop_mcu_bypass_mode_setup(struct drm_crtc *crtc) VOP_CTRL_SET(vop, mcu_type, 1); VOP_CTRL_SET(vop, mcu_hold_mode, 1); - VOP_CTRL_SET(vop, mcu_pix_total, mcu_timing->mcu_pix_total); - VOP_CTRL_SET(vop, mcu_cs_pst, mcu_timing->mcu_cs_pst); - VOP_CTRL_SET(vop, mcu_cs_pend, mcu_timing->mcu_cs_pend); - VOP_CTRL_SET(vop, mcu_rw_pst, mcu_timing->mcu_rw_pst); - VOP_CTRL_SET(vop, mcu_rw_pend, mcu_timing->mcu_rw_pend); + /* + * Use user-defined mcu bypass timing if mcu-bypass-timing + * node has been found in dts, otherwise setup the default + * timing which can meet the read/write timing requirements + * of most mcu panel. + */ + if (vop->mcu_bypass_timing.mcu_pix_total) { + VOP_CTRL_SET(vop, mcu_pix_total, vop->mcu_bypass_timing.mcu_pix_total); + VOP_CTRL_SET(vop, mcu_cs_pst, vop->mcu_bypass_timing.mcu_cs_pst); + VOP_CTRL_SET(vop, mcu_cs_pend, vop->mcu_bypass_timing.mcu_cs_pend); + VOP_CTRL_SET(vop, mcu_rw_pst, vop->mcu_bypass_timing.mcu_rw_pst); + VOP_CTRL_SET(vop, mcu_rw_pend, vop->mcu_bypass_timing.mcu_rw_pend); + } else { + VOP_CTRL_SET(vop, mcu_pix_total, mcu_timing->mcu_pix_total); + VOP_CTRL_SET(vop, mcu_cs_pst, mcu_timing->mcu_cs_pst); + VOP_CTRL_SET(vop, mcu_cs_pend, mcu_timing->mcu_cs_pend); + VOP_CTRL_SET(vop, mcu_rw_pst, mcu_timing->mcu_rw_pst); + VOP_CTRL_SET(vop, mcu_rw_pend, mcu_timing->mcu_rw_pend); - clk_set_rate(vop->dclk, vop->data->mcu_bypass_cfg->dclk_rate); + clk_set_rate(vop->dclk, vop->data->mcu_bypass_cfg->dclk_rate); + } } static void vop_mcu_mode_setup(struct drm_crtc *crtc) @@ -5389,6 +5404,27 @@ static int vop_bind(struct device *dev, struct device *master, void *data) vop->mcu_timing.mcu_hold_mode = val; } + mcu = of_get_child_by_name(dev->of_node, "mcu-bypass-timing"); + if (!mcu) { + dev_dbg(dev, "no mcu-bypass-timing node found in %s\n", + dev->of_node->full_name); + } else { + u32 val; + + if (!of_property_read_u32(mcu, "mcu-pix-total", &val)) + vop->mcu_bypass_timing.mcu_pix_total = val; + if (!of_property_read_u32(mcu, "mcu-cs-pst", &val)) + vop->mcu_bypass_timing.mcu_cs_pst = val; + if (!of_property_read_u32(mcu, "mcu-cs-pend", &val)) + vop->mcu_bypass_timing.mcu_cs_pend = val; + if (!of_property_read_u32(mcu, "mcu-rw-pst", &val)) + vop->mcu_bypass_timing.mcu_rw_pst = val; + if (!of_property_read_u32(mcu, "mcu-rw-pend", &val)) + vop->mcu_bypass_timing.mcu_rw_pend = val; + if (!of_property_read_u32(mcu, "mcu-hold-mode", &val)) + vop->mcu_bypass_timing.mcu_hold_mode = val; + } + dual_channel_swap = of_property_read_bool(dev->of_node, "rockchip,dual-channel-swap"); vop->dual_channel_swap = dual_channel_swap;