Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 98f00ec1 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm-lease: fixup crtc primary plane assignment"

parents 496daa01 dbbb4043
Loading
Loading
Loading
Loading
+81 −15
Original line number Diff line number Diff line
/* Copyright (c) 2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017 Keith Packard <keithp@keithp.com>
 *
 * This program is free software; you can redistribute it and/or modify
@@ -322,7 +322,7 @@ static long msm_lease_ioctl(struct file *filp,
}

static int msm_lease_add_connector(struct drm_device *dev, const char *name,
		u32 *object_ids, int *object_count, struct drm_plane *primary)
		u32 *object_ids, int *object_count)
{
	struct drm_connector *connector;
	struct drm_encoder *encoder;
@@ -373,10 +373,6 @@ static int msm_lease_add_connector(struct drm_device *dev, const char *name,
		if (_obj_is_leased(crtc->base.id, object_ids, *object_count))
			continue;

		/* re-initialize crtc primary for legacy set_mode */
		crtc->primary = primary;
		primary->crtc = crtc;

		crtc_id = crtc->base.id;
		break;
	}
@@ -397,8 +393,7 @@ static int msm_lease_add_connector(struct drm_device *dev, const char *name,
}

static int msm_lease_add_plane(struct drm_device *dev, const char *name,
		u32 *object_ids, int *object_count,
		struct drm_plane **planes, int *plane_count)
		u32 *object_ids, int *object_count)
{
	struct drm_plane *plane, *added_plane;
	int plane_id = -1;
@@ -429,18 +424,83 @@ static int msm_lease_add_plane(struct drm_device *dev, const char *name,
	}

	object_ids[(*object_count)++] = plane_id;
	planes[(*plane_count)++] = added_plane;

	return 0;
}

static void msm_lease_fixup_crtc_primary(struct drm_device *dev,
	u32 *object_ids, int object_count)
{
	struct drm_mode_object *obj;
	struct drm_plane *planes[MAX_LEASE_OBJECT_COUNT];
	struct drm_crtc *crtcs[MAX_LEASE_OBJECT_COUNT];
	struct drm_plane *plane;
	struct drm_crtc *crtc;
	int i, plane_count = 0, crtc_count = 0;

	/* get all the leased crtcs and planes */
	for (i = 0; i < object_count; i++) {
		obj = drm_mode_object_find(dev, NULL, object_ids[i],
				DRM_MODE_OBJECT_ANY);
		if (!obj)
			continue;

		if (obj->type == DRM_MODE_OBJECT_PLANE)
			planes[plane_count++] = obj_to_plane(obj);
		else if (obj->type == DRM_MODE_OBJECT_CRTC)
			crtcs[crtc_count++] = obj_to_crtc(obj);
	}

	/* reset previous primary planes */
	for (i = 0; i < plane_count; i++) {
		if (planes[i]->type == DRM_PLANE_TYPE_PRIMARY) {
			drm_for_each_crtc(crtc, dev) {
				if (crtc->primary == planes[i]) {
					crtc->primary = NULL;
					planes[i]->crtc = NULL;
					break;
				}
			}
			planes[i]->type = DRM_PLANE_TYPE_OVERLAY;
			dev->mode_config.num_overlay_plane++;
		}
	}

	/* setup new primary planes */
	for (i = 0; i < crtc_count; i++) {
		if (crtcs[i]->primary) {
			crtcs[i]->primary->type = DRM_PLANE_TYPE_OVERLAY;
			dev->mode_config.num_overlay_plane++;
		}
		crtcs[i]->primary = planes[i];
		planes[i]->crtc = crtcs[i];
		planes[i]->type = DRM_PLANE_TYPE_PRIMARY;
		dev->mode_config.num_overlay_plane--;
	}

	/* assign primary planes for reset crtcs */
	drm_for_each_crtc(crtc, dev) {
		if (crtc->primary)
			continue;

		drm_for_each_plane(plane, dev) {
			if (plane->type == DRM_PLANE_TYPE_OVERLAY) {
				crtc->primary = plane;
				plane->type = DRM_PLANE_TYPE_PRIMARY;
				plane->crtc = crtc;
				dev->mode_config.num_overlay_plane--;
				break;
			}
		}
	}
}

static int msm_lease_parse_objs(struct drm_device *dev,
		struct device_node *of_node,
		u32 *object_ids, int *object_count)
{
	const char *name;
	struct drm_plane *planes[MAX_LEASE_OBJECT_COUNT];
	int count, rc, i, plane_count = 0;
	int count, rc, i;

	count = of_property_count_strings(of_node, "qcom,lease-planes");
	if (!count) {
@@ -452,8 +512,7 @@ static int msm_lease_parse_objs(struct drm_device *dev,
		of_property_read_string_index(of_node, "qcom,lease-planes",
				i, &name);
		rc = msm_lease_add_plane(dev, name,
				object_ids, object_count,
				planes, &plane_count);
				object_ids, object_count);
		if (rc)
			return rc;
	}
@@ -464,12 +523,16 @@ static int msm_lease_parse_objs(struct drm_device *dev,
		return -EINVAL;
	}

	if (count > *object_count) {
		DRM_ERROR("connectors are more than planes\n");
		return -EINVAL;
	}

	for (i = 0; i < count; i++) {
		of_property_read_string_index(of_node, "qcom,lease-connectors",
				i, &name);
		rc = msm_lease_add_connector(dev, name,
				object_ids, object_count,
				i < plane_count ? planes[i] : planes[0]);
				object_ids, object_count);
		if (rc)
			return rc;
	}
@@ -577,6 +640,9 @@ static int msm_lease_probe(struct platform_device *pdev)
	memcpy(lease_drv->object_ids, object_ids, sizeof(u32) * object_count);
	list_add_tail(&lease_drv->head, &g_lease_list);

	/* fixup crtcs' primary planes */
	msm_lease_fixup_crtc_primary(master_ddev, object_ids, object_count);

	/* hook open/close function */
	if (!g_master_open && !g_master_postclose) {
		g_master_open = master_ddev->driver->open;
+49 −1
Original line number Diff line number Diff line
@@ -170,6 +170,7 @@ static int shd_display_init_base_crtc(struct drm_device *dev,
{
	struct drm_crtc *crtc = NULL;
	struct msm_drm_private *priv;
	struct drm_plane *primary;
	int crtc_idx;
	int i;

@@ -193,6 +194,23 @@ static int shd_display_init_base_crtc(struct drm_device *dev,
			return -ENOENT;
	}

	if (priv->num_planes >= MAX_PLANES)
		return -ENOENT;

	/* create dummy primary plane for base crtc */
	primary = sde_plane_init(dev, SSPP_DMA0, true, 0, 0);
	if (IS_ERR(primary))
		return -ENOMEM;
	priv->planes[priv->num_planes++] = primary;
	if (primary->funcs->reset)
		primary->funcs->reset(primary);

	SDE_DEBUG("create dummay plane%d free plane%d\n",
			DRMID(primary), DRMID(crtc->primary));

	crtc->primary = primary;
	primary->crtc = crtc;

	/* disable crtc from other encoders */
	for (i = 0; i < priv->num_encoders; i++) {
		if (priv->encoders[i] != base->encoder)
@@ -721,6 +739,7 @@ static int shd_drm_obj_init(struct shd_display *display)
	struct msm_drm_private *priv;
	struct drm_device *dev;
	struct drm_crtc *crtc;
	struct drm_plane *primary;
	struct drm_encoder *encoder;
	struct drm_connector *connector;
	struct sde_crtc *sde_crtc;
@@ -752,6 +771,35 @@ static int shd_drm_obj_init(struct shd_display *display)
		goto end;
	}

	/* search plane that doesn't belong to any crtc */
	primary = NULL;
	for (i = 0; i < priv->num_planes; i++) {
		bool found = false;

		drm_for_each_crtc(crtc, dev) {
			if (crtc->primary == priv->planes[i]) {
				found = true;
				break;
			}
		}

		if (!found) {
			primary = priv->planes[i];
			if (primary->type == DRM_PLANE_TYPE_OVERLAY)
				dev->mode_config.num_overlay_plane--;
			primary->type = DRM_PLANE_TYPE_PRIMARY;
			break;
		}
	}

	if (!primary) {
		SDE_ERROR("failed to find primary plane\n");
		rc = -ENOENT;
		goto end;
	}

	SDE_DEBUG("find primary plane %d\n", DRMID(primary));

	memset(&info, 0x0, sizeof(info));
	rc = shd_connector_get_info(NULL, &info, display);
	if (rc) {
@@ -795,7 +843,7 @@ static int shd_drm_obj_init(struct shd_display *display)

	SDE_DEBUG("create connector %d\n", DRMID(connector));

	crtc = sde_crtc_init(dev, priv->planes[0]);
	crtc = sde_crtc_init(dev, primary);
	if (IS_ERR(crtc)) {
		rc = PTR_ERR(crtc);
		goto end;