drm/rockchip: vop2: Register the primary plane and overlay plane separately

In the upcoming VOP of rk3576, a Window cannot attach to all Video Ports,
so make sure all VP find it's suitable primary plane, then register the
remain windows as overlay plane will make code easier.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Tested-by: Michael Riesch <michael.riesch@wolfvision.net> # on RK3568
Tested-by: Detlev Casanova <detlev.casanova@collabora.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20250303034436.192400-2-andyshrk@163.com
This commit is contained in:
Andy Yan 2025-03-03 11:44:15 +08:00 committed by Heiko Stuebner
parent 4d2a877cc0
commit 6fd4f8a26a

View file

@ -2264,22 +2264,29 @@ static int vop2_plane_init(struct vop2 *vop2, struct vop2_win *win,
return 0;
}
static struct vop2_video_port *find_vp_without_primary(struct vop2 *vop2)
/*
* On RK3566 these windows don't have an independent
* framebuffer. They can only share/mirror the framebuffer
* with smart0, esmart0 and cluster0 respectively.
* And RK3566 share the same vop version with Rk3568, so we
* need to use soc_id for identification here.
*/
static bool vop2_is_mirror_win(struct vop2_win *win)
{
int i;
struct vop2 *vop2 = win->vop2;
for (i = 0; i < vop2->data->nr_vps; i++) {
struct vop2_video_port *vp = &vop2->vps[i];
if (!vp->crtc.port)
continue;
if (vp->primary_plane)
continue;
return vp;
if (vop2->data->soc_id == 3566) {
switch (win->data->phys_id) {
case ROCKCHIP_VOP2_SMART1:
case ROCKCHIP_VOP2_ESMART1:
case ROCKCHIP_VOP2_CLUSTER1:
return true;
default:
return false;
}
} else {
return false;
}
return NULL;
}
static int vop2_create_crtcs(struct vop2 *vop2)
@ -2290,7 +2297,9 @@ static int vop2_create_crtcs(struct vop2 *vop2)
struct drm_plane *plane;
struct device_node *port;
struct vop2_video_port *vp;
int i, nvp, nvps = 0;
struct vop2_win *win;
u32 possible_crtcs;
int i, j, nvp, nvps = 0;
int ret;
for (i = 0; i < vop2_data->nr_vps; i++) {
@ -2326,42 +2335,54 @@ static int vop2_create_crtcs(struct vop2 *vop2)
}
nvp = 0;
for (i = 0; i < vop2->registered_num_wins; i++) {
struct vop2_win *win = &vop2->win[i];
u32 possible_crtcs = 0;
/* Register a primary plane for every crtc */
for (i = 0; i < vop2_data->nr_vps; i++) {
vp = &vop2->vps[i];
if (vop2->data->soc_id == 3566) {
/*
* On RK3566 these windows don't have an independent
* framebuffer. They share the framebuffer with smart0,
* esmart0 and cluster0 respectively.
*/
switch (win->data->phys_id) {
case ROCKCHIP_VOP2_SMART1:
case ROCKCHIP_VOP2_ESMART1:
case ROCKCHIP_VOP2_CLUSTER1:
if (!vp->crtc.port)
continue;
for (j = 0; j < vop2->registered_num_wins; j++) {
win = &vop2->win[j];
/* Aready registered as primary plane */
if (win->base.type == DRM_PLANE_TYPE_PRIMARY)
continue;
}
}
if (win->type == DRM_PLANE_TYPE_PRIMARY) {
vp = find_vp_without_primary(vop2);
if (vp) {
if (vop2_is_mirror_win(win))
continue;
if (win->type == DRM_PLANE_TYPE_PRIMARY) {
possible_crtcs = BIT(nvp);
vp->primary_plane = win;
ret = vop2_plane_init(vop2, win, possible_crtcs);
if (ret)
return dev_err_probe(drm->dev, ret,
"failed to init primary plane %s\n",
win->data->name);
nvp++;
} else {
/* change the unused primary window to overlay window */
win->type = DRM_PLANE_TYPE_OVERLAY;
break;
}
}
}
if (win->type == DRM_PLANE_TYPE_OVERLAY)
possible_crtcs = (1 << nvps) - 1;
/* Register all unused window as overlay plane */
for (i = 0; i < vop2->registered_num_wins; i++) {
win = &vop2->win[i];
/* Aready registered as primary plane */
if (win->base.type == DRM_PLANE_TYPE_PRIMARY)
continue;
if (vop2_is_mirror_win(win))
continue;
win->type = DRM_PLANE_TYPE_OVERLAY;
possible_crtcs = (1 << nvps) - 1;
ret = vop2_plane_init(vop2, win, possible_crtcs);
if (ret)
return dev_err_probe(drm->dev, ret, "failed to init plane %s\n",
return dev_err_probe(drm->dev, ret, "failed to init overlay plane %s\n",
win->data->name);
}