mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
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:
parent
4d2a877cc0
commit
6fd4f8a26a
1 changed files with 59 additions and 38 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue