Commit 6fd4f8a2 authored by Andy Yan's avatar Andy Yan Committed by Heiko Stuebner
Browse files

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: default avatarAndy Yan <andy.yan@rock-chips.com>
Tested-by: Michael Riesch <michael.riesch@wolfvision.net> # on RK3568
Tested-by: default avatarDetlev Casanova <detlev.casanova@collabora.com>
Signed-off-by: default avatarHeiko Stuebner <heiko@sntech.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20250303034436.192400-2-andyshrk@163.com
parent 4d2a877c
Loading
Loading
Loading
Loading
+60 −39
Original line number Diff line number Diff line
@@ -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;

	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;
	struct vop2 *vop2 = win->vop2;

		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 (vop2_is_mirror_win(win))
				continue;
			}
		}

			if (win->type == DRM_PLANE_TYPE_PRIMARY) {
			vp = find_vp_without_primary(vop2);
			if (vp) {
				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);
	}