diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h index a8f758834122..8161b97f9285 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h @@ -264,6 +264,7 @@ struct rockchip_crtc_state { int afbdc_win_yoffset; int dsp_layer_sel; u32 output_if; + u32 output_if_left_panel; u32 bus_format; u32 bus_flags; int yuv_overlay; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index b2f2ddcdf97e..b6e12d297d45 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -31,11 +31,15 @@ #define VOP_VERSION_RK3568 VOP2_VERSION(0x40, 0x15, 0x8023) #define VOP_VERSION_RK3588 VOP2_VERSION(0x40, 0x17, 0x6786) +/* register one connector */ #define ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE BIT(0) +/* register one connector */ #define ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE BIT(1) #define ROCKCHIP_OUTPUT_DATA_SWAP BIT(2) /* MIPI DSI DataStream(cmd) mode on rk3588 */ #define ROCKCHIP_OUTPUT_MIPI_DS_MODE BIT(3) +/* register two connector */ +#define ROCKCHIP_OUTPUT_DUAL_CONNECTOR_SPLIT_MODE BIT(4) #define AFBDC_FMT_RGB565 0x0 #define AFBDC_FMT_U8U8U8U8 0x5 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 3f269384484c..bf312b8d87e0 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -4363,8 +4363,11 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc, if (vp->output_if & VOP_OUTPUT_IF_eDP0) VOP_GRF_SET(vop2, grf, grf_edp0_en, 0); - if (vp->output_if & VOP_OUTPUT_IF_eDP1) + if (vp->output_if & VOP_OUTPUT_IF_eDP1) { VOP_GRF_SET(vop2, grf, grf_edp1_en, 0); + if (dual_channel) + VOP_CTRL_SET(vop2, edp_dual_en, 0); + } if (vp->output_if & VOP_OUTPUT_IF_HDMI0) { VOP_GRF_SET(vop2, grf, grf_hdmi0_dsc_en, 0); @@ -4374,8 +4377,16 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc, if (vp->output_if & VOP_OUTPUT_IF_HDMI1) { VOP_GRF_SET(vop2, grf, grf_hdmi1_dsc_en, 0); VOP_GRF_SET(vop2, grf, grf_hdmi1_en, 0); + if (dual_channel) + VOP_CTRL_SET(vop2, hdmi_dual_en, 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_MIPI1) && dual_channel) + VOP_CTRL_SET(vop2, mipi_dual_en, 0); + VOP_MODULE_SET(vop2, vp, dual_channel_en, 0); VOP_MODULE_SET(vop2, vp, dual_channel_swap, 0); @@ -7319,6 +7330,11 @@ static void vop2_crtc_enable_dsc(struct drm_crtc *crtc, struct drm_crtc_state *o dsc->enabled = true; } +static inline bool vop2_mark_as_left_panel(struct rockchip_crtc_state *vcstate, u32 output_if) +{ + return vcstate->output_if_left_panel & output_if; +} + static void vop2_setup_dual_channel_if(struct drm_crtc *crtc) { struct vop2_video_port *vp = to_vop2_video_port(crtc); @@ -7329,13 +7345,17 @@ 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); - if (vcstate->output_if & VOP_OUTPUT_IF_DP1) + 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) + 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) + 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) + 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); } @@ -7550,9 +7570,9 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state vop2_set_system_status(vop2); vop2_lock(vop2); - DRM_DEV_INFO(vop2->dev, "Update mode to %dx%d%s%d, type: %d(if:%x) for vp%d dclk: %d\n", + DRM_DEV_INFO(vop2->dev, "Update mode to %dx%d%s%d, type: %d(if:%x, flag:0x%x) for vp%d dclk: %d\n", hdisplay, adjusted_mode->vdisplay, interlaced ? "i" : "p", - vop2_get_vrefresh(vp, adjusted_mode), vcstate->output_type, vcstate->output_if, + vop2_get_vrefresh(vp, adjusted_mode), vcstate->output_type, vcstate->output_if, vcstate->output_flags, vp->id, adjusted_mode->crtc_clock * 1000); if (adjusted_mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) { @@ -7564,6 +7584,9 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state vop2->active_vp_mask |= BIT(splice_vp->id); } + if (vcstate->output_flags & ROCKCHIP_OUTPUT_DUAL_CONNECTOR_SPLIT_MODE) + vcstate->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE; + if (vcstate->dsc_enable) { int k = 1;