drm/rockchip: vop2: rk3588 add support dual connector split mode

example:
    VP2 -> DSI0 -> LCD(show left  half image)
        -> eDP1 -> LCD(show right half image)

Signed-off-by: Sandy Huang <hjc@rock-chips.com>
Change-Id: Ifdfb837a2b9cba198c8637a275125e25b9922f2c
This commit is contained in:
Sandy Huang
2023-06-14 15:37:07 +08:00
committed by Tao Huang
parent 54313858e8
commit 079bbda800
3 changed files with 35 additions and 7 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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;