mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 19:08:57 +09:00
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:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user