diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index b26de3a437b3..30a1a035562e 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -40,6 +40,15 @@ #define WIN_FEATURE_AFBDC BIT(3) #define WIN_FEATURE_CLUSTER_MAIN BIT(4) #define WIN_FEATURE_CLUSTER_SUB BIT(5) +/* a mirror win can only get fb address + * from source win: + * Cluster1---->Cluster0 + * Esmart1 ---->Esmart0 + * Smart1 ---->Smart0 + * This is a feather on rk3566 + */ +#define WIN_FEATURE_MIRROR BIT(6) + #define VOP2_SOC_VARIANT 4 diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 94e18b9fd3bb..a80f1c352c35 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -711,6 +711,11 @@ static bool vop2_soc_is_rk3566(void) return soc_is_rk3566(); } +static bool vop2_is_mirror_win(struct vop2_win *win) +{ + return soc_is_rk3566() && (win->feature & WIN_FEATURE_MIRROR); +} + static uint64_t vop2_soc_id_fixup(uint64_t soc_id) { switch (soc_id) { @@ -6077,6 +6082,7 @@ static int vop2_create_crtc(struct vop2 *vop2) const struct vop2_video_port_data *vp_data; uint32_t possible_crtcs; uint64_t soc_id; + uint32_t registered_num_crtcs = 0; char dclk_name[9]; int i = 0, j = 0, k = 0; int ret = 0; @@ -6230,6 +6236,7 @@ static int vop2_create_crtc(struct vop2 *vop2) drm_object_attach_property(&crtc->base, drm_dev->mode_config.tv_bottom_margin_property, 100); vop2_crtc_create_plane_mask_property(vop2, crtc); + registered_num_crtcs++; } /* @@ -6260,6 +6267,11 @@ static int vop2_create_crtc(struct vop2 *vop2) if (win->type != DRM_PLANE_TYPE_OVERLAY) continue; + /* + * Only dual display(which need two crtcs) need mirror win + */ + if (registered_num_crtcs < 2 && vop2_is_mirror_win(win)) + continue; ret = vop2_plane_init(vop2, win, possible_crtcs); if (ret) @@ -6338,6 +6350,7 @@ static int vop2_win_init(struct vop2 *vop2) area->regs = regs; area->type = DRM_PLANE_TYPE_OVERLAY; area->formats = win->formats; + area->feature = win->feature; area->nformats = win->nformats; area->format_modifiers = win->format_modifiers; area->max_upscale_factor = win_data->max_upscale_factor; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c index 59c101307eed..7b76e5e6ed0b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c @@ -1043,6 +1043,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = { .max_upscale_factor = 8, .max_downscale_factor = 8, .dly = { 20, 47, 41 }, + .feature = WIN_FEATURE_MIRROR, }, { @@ -1065,6 +1066,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = { .max_upscale_factor = 8, .max_downscale_factor = 8, .dly = { 20, 47, 41 }, + .feature = WIN_FEATURE_MIRROR, }, { @@ -1150,7 +1152,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = { .max_upscale_factor = 4, .max_downscale_factor = 4, .dly = { 0, 27, 21 }, - .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER_MAIN, + .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER_MAIN | WIN_FEATURE_MIRROR, }, { @@ -1170,7 +1172,7 @@ static const struct vop2_win_data rk3568_vop_win_data[] = { .type = DRM_PLANE_TYPE_OVERLAY, .max_upscale_factor = 4, .max_downscale_factor = 4, - .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER_SUB, + .feature = WIN_FEATURE_AFBDC | WIN_FEATURE_CLUSTER_SUB | WIN_FEATURE_MIRROR, }, };