diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index e17286cd6541..cb5a67eac61b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -635,6 +635,7 @@ struct vop2_video_port_regs { struct vop_reg dsp_interlace; struct vop_reg dsp_filed_pol; struct vop_reg dsp_data_swap; + struct vop_reg dsp_x_mir_en; struct vop_reg post_dsp_out_r2y; struct vop_reg pre_scan_htiming; struct vop_reg htotal_pw; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index d092877295b0..9dbd88daed2a 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -503,6 +503,7 @@ struct vop2_video_port { struct clk *dclk_parent; uint8_t id; bool layer_sel_update; + bool xmirror_en; const struct vop2_video_port_regs *regs; struct completion dsp_hold_completion; @@ -6852,6 +6853,9 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state act_end = vact_end; } + if (vp->xmirror_en) + VOP_MODULE_SET(vop2, vp, dsp_x_mir_en, 1); + VOP_INTR_SET(vop2, intr, line_flag_num[0], act_end); VOP_INTR_SET(vop2, intr, line_flag_num[1], act_end); @@ -9652,6 +9656,8 @@ static int vop2_bind(struct device *dev, struct device *master, void *data) else vop2->vps[vp_id].primary_plane_phy_id = ROCKCHIP_VOP2_PHY_ID_INVALID; + vop2->vps[vp_id].xmirror_en = of_property_read_bool(child, "xmirror-enable"); + ret = of_clk_set_defaults(child, false); if (ret) { DRM_DEV_ERROR(dev, "Failed to set clock defaults %d\n", ret); diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c index de5f9bd44e4e..050ea4f65c3d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -702,6 +702,7 @@ static const struct vop2_video_port_regs rk3568_vop_vp0_regs = { .dsp_filed_pol = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 6), .dsp_interlace = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 7), .dsp_data_swap = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1f, 8), + .dsp_x_mir_en = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 13), .post_dsp_out_r2y = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 15), .pre_scan_htiming = VOP_REG(RK3568_VP0_PRE_SCAN_HTIMING, 0x1fff1fff, 0), .bg_dly = VOP_REG(RK3568_VP0_BG_MIX_CTRL, 0xff, 24), @@ -785,6 +786,7 @@ static const struct vop2_video_port_regs rk3568_vop_vp1_regs = { .dsp_filed_pol = VOP_REG(RK3568_VP1_DSP_CTRL, 0x1, 6), .dsp_interlace = VOP_REG(RK3568_VP1_DSP_CTRL, 0x1, 7), .dsp_data_swap = VOP_REG(RK3568_VP1_DSP_CTRL, 0x1f, 8), + .dsp_x_mir_en = VOP_REG(RK3568_VP1_DSP_CTRL, 0x1, 13), .post_dsp_out_r2y = VOP_REG(RK3568_VP1_DSP_CTRL, 0x1, 15), .pre_scan_htiming = VOP_REG(RK3568_VP1_PRE_SCAN_HTIMING, 0x1fff1fff, 0), .bg_dly = VOP_REG(RK3568_VP1_BG_MIX_CTRL, 0xff, 24), @@ -835,6 +837,7 @@ static const struct vop2_video_port_regs rk3568_vop_vp2_regs = { .dsp_filed_pol = VOP_REG(RK3568_VP2_DSP_CTRL, 0x1, 6), .dsp_interlace = VOP_REG(RK3568_VP2_DSP_CTRL, 0x1, 7), .dsp_data_swap = VOP_REG(RK3568_VP2_DSP_CTRL, 0x1f, 8), + .dsp_x_mir_en = VOP_REG(RK3568_VP2_DSP_CTRL, 0x1, 13), .post_dsp_out_r2y = VOP_REG(RK3568_VP2_DSP_CTRL, 0x1, 15), .pre_scan_htiming = VOP_REG(RK3568_VP2_PRE_SCAN_HTIMING, 0x1fff1fff, 0), .bg_dly = VOP_REG(RK3568_VP2_BG_MIX_CTRL, 0xff, 24), @@ -917,6 +920,7 @@ static const struct vop2_video_port_regs rk3588_vop_vp0_regs = { .dsp_filed_pol = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 6), .dsp_interlace = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 7), .dsp_data_swap = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1f, 8), + .dsp_x_mir_en = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 13), .post_dsp_out_r2y = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 15), .pre_dither_down_en = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 16), .dither_down_en = VOP_REG(RK3568_VP0_DSP_CTRL, 0x1, 17), @@ -1012,6 +1016,7 @@ static const struct vop2_video_port_regs rk3588_vop_vp1_regs = { .dsp_filed_pol = VOP_REG(RK3568_VP1_DSP_CTRL, 0x1, 6), .dsp_interlace = VOP_REG(RK3568_VP1_DSP_CTRL, 0x1, 7), .dsp_data_swap = VOP_REG(RK3568_VP1_DSP_CTRL, 0x1f, 8), + .dsp_x_mir_en = VOP_REG(RK3568_VP1_DSP_CTRL, 0x1, 13), .post_dsp_out_r2y = VOP_REG(RK3568_VP1_DSP_CTRL, 0x1, 15), .pre_dither_down_en = VOP_REG(RK3568_VP1_DSP_CTRL, 0x1, 16), .dither_down_en = VOP_REG(RK3568_VP1_DSP_CTRL, 0x1, 17), @@ -1100,6 +1105,7 @@ static const struct vop2_video_port_regs rk3588_vop_vp2_regs = { .dsp_filed_pol = VOP_REG(RK3568_VP2_DSP_CTRL, 0x1, 6), .dsp_interlace = VOP_REG(RK3568_VP2_DSP_CTRL, 0x1, 7), .dsp_data_swap = VOP_REG(RK3568_VP2_DSP_CTRL, 0x1f, 8), + .dsp_x_mir_en = VOP_REG(RK3568_VP2_DSP_CTRL, 0x1, 13), .post_dsp_out_r2y = VOP_REG(RK3568_VP2_DSP_CTRL, 0x1, 15), .pre_dither_down_en = VOP_REG(RK3568_VP2_DSP_CTRL, 0x1, 16), .dither_down_en = VOP_REG(RK3568_VP2_DSP_CTRL, 0x1, 17), @@ -1159,6 +1165,7 @@ static const struct vop2_video_port_regs rk3588_vop_vp3_regs = { .dsp_filed_pol = VOP_REG(RK3588_VP3_DSP_CTRL, 0x1, 6), .dsp_interlace = VOP_REG(RK3588_VP3_DSP_CTRL, 0x1, 7), .dsp_data_swap = VOP_REG(RK3588_VP3_DSP_CTRL, 0x1f, 8), + .dsp_x_mir_en = VOP_REG(RK3588_VP3_DSP_CTRL, 0x1, 13), .post_dsp_out_r2y = VOP_REG(RK3588_VP3_DSP_CTRL, 0x1, 15), .pre_dither_down_en = VOP_REG(RK3588_VP3_DSP_CTRL, 0x1, 16), .dither_down_en = VOP_REG(RK3588_VP3_DSP_CTRL, 0x1, 17),