From 3ba080da107959ca5a63f10131e00cc9db1cfe80 Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Mon, 6 May 2024 11:04:31 +0800 Subject: [PATCH] drm/rockchip: vop2: add split mode for rk3576 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. dts config example for hdmi+dp split, and hdmi at left display: ┌────┬────┐ │ │ │ VP ───►│hdmi│ dp │ │ │ │ └────┴────┘ &dp { status = "okay"; rockchip,dual-connector-split; }; &hdmi { status = "okay" rockchip,dual-connector-split; rockchip,left-display; }; 2. dts config example for hdmi+dp split, and dp at left display: ┌────┬────┐ │ │ │ VP ───►│ dp │hdmi│ │ │ │ └────┴────┘ &dp { status = "okay"; rockchip,dual-connector-split; rockchip,left-display; }; &hdmi { status = "okay" rockchip,dual-connector-split; }; Signed-off-by: Sandy Huang Change-Id: I2df45b47b75943ac91561e0a6af509cdb8215f07 --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 59 +++++++++++++++----- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 7458e4dcf869..b35ab6780a88 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -4884,8 +4884,10 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc, vcstate->dsc_enable = false; } - if (vp->output_if & VOP_OUTPUT_IF_eDP0) + if (vp->output_if & VOP_OUTPUT_IF_eDP0) { VOP_GRF_SET(vop2, grf, grf_edp0_en, 0); + VOP_CTRL_SET(vop2, edp0_data1_sel, 0); + } if (vp->output_if & VOP_OUTPUT_IF_eDP1) { VOP_GRF_SET(vop2, grf, grf_edp1_en, 0); @@ -4896,6 +4898,7 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc, if (vp->output_if & VOP_OUTPUT_IF_HDMI0) { VOP_GRF_SET(vop2, grf, grf_hdmi0_dsc_en, 0); VOP_GRF_SET(vop2, grf, grf_hdmi0_en, 0); + VOP_CTRL_SET(vop2, hdmi0_data1_sel, 0); } if (vp->output_if & VOP_OUTPUT_IF_HDMI1) { @@ -4905,9 +4908,15 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc, VOP_CTRL_SET(vop2, hdmi_dual_en, 0); } + if (vcstate->output_if & VOP_OUTPUT_IF_DP0) + VOP_CTRL_SET(vop2, dp0_data1_sel, 0); + if ((vcstate->output_if & VOP_OUTPUT_IF_DP1) && dual_channel) VOP_CTRL_SET(vop2, dp_dual_en, 0); + if (vcstate->output_if & VOP_OUTPUT_IF_MIPI0) + VOP_CTRL_SET(vop2, mipi0_data1_sel, 0); + if ((vcstate->output_if & VOP_OUTPUT_IF_MIPI1) && dual_channel) VOP_CTRL_SET(vop2, mipi_dual_en, 0); @@ -8648,7 +8657,8 @@ static void vop2_setup_dual_channel_if(struct drm_crtc *crtc) struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); struct vop2 *vop2 = vp->vop2; - if (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE) { + if (output_if_is_lvds(vcstate->output_if) && + (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE)) { VOP_CTRL_SET(vop2, lvds_dual_en, 1); VOP_CTRL_SET(vop2, lvds_dual_mode, 0); if (vcstate->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) @@ -8660,21 +8670,40 @@ static void vop2_setup_dual_channel_if(struct drm_crtc *crtc) if (vcstate->output_flags & ROCKCHIP_OUTPUT_DATA_SWAP) VOP_MODULE_SET(vop2, vp, dual_channel_swap, 1); + /* + * For RK3588, at dual_channel/split mode, the DP1/eDP1/HDMI1/MIPI1 data + * only can be from data1[vp left half screen is data0, right half screen + * is data1]. + * From RK3576, the connector can select from data0 or data1. + */ + if (vcstate->output_if & VOP_OUTPUT_IF_DP0 && + !vop2_mark_as_left_panel(vcstate, VOP_OUTPUT_IF_DP0)) + VOP_CTRL_SET(vop2, dp0_data1_sel, 1); + if (vcstate->output_if & VOP_OUTPUT_IF_eDP0 && + !vop2_mark_as_left_panel(vcstate, VOP_OUTPUT_IF_eDP0)) + VOP_CTRL_SET(vop2, edp0_data1_sel, 1); + if (vcstate->output_if & VOP_OUTPUT_IF_HDMI0 && + !vop2_mark_as_left_panel(vcstate, VOP_OUTPUT_IF_HDMI0)) + VOP_CTRL_SET(vop2, hdmi0_data1_sel, 1); + if (vcstate->output_if & VOP_OUTPUT_IF_MIPI0 && + !vop2_mark_as_left_panel(vcstate, VOP_OUTPUT_IF_MIPI0)) + VOP_CTRL_SET(vop2, mipi0_data1_sel, 1); + /* Todo for LVDS0 */ if (vcstate->output_if & VOP_OUTPUT_IF_DP1 && !vop2_mark_as_left_panel(vcstate, VOP_OUTPUT_IF_DP1)) - VOP_CTRL_SET(vop2, dp_dual_en, 1); - else if (vcstate->output_if & VOP_OUTPUT_IF_eDP1 && - !vop2_mark_as_left_panel(vcstate, VOP_OUTPUT_IF_eDP1)) - VOP_CTRL_SET(vop2, edp_dual_en, 1); - else if (vcstate->output_if & VOP_OUTPUT_IF_HDMI1 && - !vop2_mark_as_left_panel(vcstate, VOP_OUTPUT_IF_HDMI1)) - VOP_CTRL_SET(vop2, hdmi_dual_en, 1); - else if (vcstate->output_if & VOP_OUTPUT_IF_MIPI1 && - !vop2_mark_as_left_panel(vcstate, VOP_OUTPUT_IF_MIPI1)) - VOP_CTRL_SET(vop2, mipi_dual_en, 1); - else if (vcstate->output_if & VOP_OUTPUT_IF_LVDS1) { - VOP_CTRL_SET(vop2, lvds_dual_en, 1); - VOP_CTRL_SET(vop2, lvds_dual_mode, 1); + VOP_CTRL_SET(vop2, dp_dual_en, 1);/* rk3588 only */ + if (vcstate->output_if & VOP_OUTPUT_IF_eDP1 && + !vop2_mark_as_left_panel(vcstate, VOP_OUTPUT_IF_eDP1)) + VOP_CTRL_SET(vop2, edp_dual_en, 1);/* rk3588 only */ + if (vcstate->output_if & VOP_OUTPUT_IF_HDMI1 && + !vop2_mark_as_left_panel(vcstate, VOP_OUTPUT_IF_HDMI1)) + VOP_CTRL_SET(vop2, hdmi_dual_en, 1);/* rk3588 only */ + if (vcstate->output_if & VOP_OUTPUT_IF_MIPI1 && + !vop2_mark_as_left_panel(vcstate, VOP_OUTPUT_IF_MIPI1)) + VOP_CTRL_SET(vop2, mipi_dual_en, 1);/* rk3588 only */ + if (vcstate->output_if & VOP_OUTPUT_IF_LVDS1) { + VOP_CTRL_SET(vop2, lvds_dual_en, 1);/* rk3568 only */ + VOP_CTRL_SET(vop2, lvds_dual_mode, 1);/* rk3568 only */ } }