All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dave Airlie <airlied@gmail.com>
To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org
Subject: [PATCH 08/11] drm/crtc: attempt to set tiled modes from userspace
Date: Tue,  9 Sep 2014 16:28:13 +1000	[thread overview]
Message-ID: <1410244096-9854-9-git-send-email-airlied@gmail.com> (raw)
In-Reply-To: <1410244096-9854-1-git-send-email-airlied@gmail.com>

From: Dave Airlie <airlied@redhat.com>

So when userspace asks us to set a mode on a tiled crtc,
split it up and find the actual modes and attempt to set them.

Also disable crtcs when no longer in tiled group.

Signed-off-by: Dave Airlie <airlied@redhat.com>
---
 drivers/gpu/drm/drm_crtc.c            | 51 ++++++++++++++++++++++++++++++++---
 drivers/gpu/drm/drm_dp_mst_topology.c |  6 +++++
 include/drm/drm_crtc.h                |  8 ++++++
 3 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 99fa259..628f3af 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -764,6 +764,9 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
 	crtc->funcs = funcs;
 	crtc->invert_dimensions = false;
 
+	INIT_LIST_HEAD(&crtc->tile_crtc_list);
+	crtc->tile_master = NULL;
+
 	drm_modeset_lock_all(dev);
 	drm_modeset_lock_init(&crtc->mutex);
 	/* dropped by _unlock_all(): */
@@ -2520,7 +2523,7 @@ static int drm_mode_setcrtc_tiled(struct drm_mode_set *orig_set)
 	list_for_each_entry(crtc2, &dev->mode_config.crtc_list, head) {
 		if (crtc2 == orig_set->crtc)
 			continue;
-		if (crtc2->enabled)
+		if (crtc2->enabled && !crtc2->tile_master)
 			continue;
 		pick_crtc = crtc2;
 		break;
@@ -2583,14 +2586,26 @@ static int drm_mode_setcrtc_tiled(struct drm_mode_set *orig_set)
 	set[1].x = orig_set->x + ((pick_conn[1]->tile_h_loc == 1) ? pick_conn[0]->tile_h_size + 1 : 0);
 	set[1].y = orig_set->y + ((pick_conn[1]->tile_v_loc == 1) ? pick_conn[0]->tile_v_size + 1 : 0);
 
+	if (set[1].crtc->tile_master) {
+		list_del(&set[1].crtc->tile);
+		set[1].crtc->tile_master = NULL;
+	}
+	list_add_tail(&set[1].crtc->tile, &set[0].crtc->tile_crtc_list);
+	set[1].crtc->tile_master = set[0].crtc;
 	/* find a mode to use on each head */
 	set[0].mode = pick_modes[0];
 	set[1].mode = pick_modes[1];
 
 	ret = drm_mode_set_config_internal(&set[0]);
 
-	ret = drm_mode_set_config_internal(&set[1]);
+	if (!ret) {
+		ret = drm_mode_set_config_internal(&set[1]);
+	}
 
+	if (ret) {
+		set[1].crtc->tile_master = NULL;
+		list_del(&set[1].crtc->tile);
+	}
 	return ret;
 }
 /**
@@ -2637,6 +2652,15 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 	}
 	DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id);
 
+	if (crtc->tile_master) {
+		if (crtc_req->mode_valid)
+			ret = -EBUSY;
+		else
+			ret = 0;
+		DRM_DEBUG_KMS("[CRTC:%d] refused due to tile %d\n", crtc->base.id, ret);
+		goto out;
+	}
+
 	if (crtc_req->mode_valid) {
 		/* If we have a mode we need a framebuffer. */
 		/* If we pass -1, set the mode with the currently bound fb */
@@ -2748,9 +2772,25 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
 
 	if (num_tiles > 1) {
 		ret = drm_mode_setcrtc_tiled(&set);
-	} else
-		ret = drm_mode_set_config_internal(&set);
+	} else {
+		if (!list_empty(&crtc->tile_crtc_list)) {
+			struct drm_crtc *tile_crtc, *t;
+
+			list_for_each_entry_safe(tile_crtc, t, &crtc->tile_crtc_list, tile) {
+				struct drm_mode_set set2;
+
+				tile_crtc->tile_master = NULL;
+				list_del(&tile_crtc->tile);
 
+				DRM_DEBUG_KMS("disabling crtc %p due to no longer needing tiling %p\n", tile_crtc, tile_crtc->primary);
+				memset(&set2, 0, sizeof(struct drm_mode_set));
+				set2.crtc = tile_crtc;
+				set2.fb = NULL;
+				ret = drm_mode_set_config_internal(&set2);
+			}
+		}
+		ret = drm_mode_set_config_internal(&set);
+	}
 out:
 	if (fb)
 		drm_framebuffer_unreference(fb);
@@ -4226,6 +4266,9 @@ static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
 	int ret = -EINVAL;
 	struct drm_connector *connector = obj_to_connector(obj);
 
+	if (connector->has_tile && connector->tile_is_single_monitor &&
+	    (connector->tile_h_loc || connector->tile_v_loc))
+		return 0;
 	/* Do DPMS ourselves */
 	if (property == connector->dev->mode_config.dpms_property) {
 		if (connector->funcs->dpms)
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 08b7140..ca5eee6 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -2190,6 +2190,12 @@ enum drm_connector_status drm_dp_mst_detect_port(struct drm_connector *connector
 		if (port->port_num >= 8 && !port->cached_edid) {
 			port->cached_edid = drm_get_edid(connector, &port->aux.ddc);
 		}
+
+		if (connector->has_tile && connector->tile_group_id == 0)
+			connector->tile_group_id = port->parent->conn_base_id;
+		if (connector->has_tile && (connector->tile_h_loc || connector->tile_v_loc))
+			status = connector_status_disconnected;
+
 		break;
 	case DP_PEER_DEVICE_DP_LEGACY_CONV:
 		if (port->ldps)
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 67c06bd..6041acd 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -375,6 +375,14 @@ struct drm_crtc {
 	void *helper_private;
 
 	struct drm_object_properties properties;
+
+	/* crtcs this one is using for tiling */
+	struct list_head tile_crtc_list;
+
+	/* tile list entry */
+	struct list_head tile;
+
+	struct drm_crtc *tile_master;
 };
 
 
-- 
1.9.3

  parent reply	other threads:[~2014-09-09  6:28 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-09  6:28 [RFC] attempting to hide 30" monitor in kernel (raw) Dave Airlie
2014-09-09  6:28 ` [PATCH 01/11] drm/mst: rework payload table allocation to conform better Dave Airlie
2014-09-09  6:28 ` [PATCH 02/11] drm/i915: add config option to enable/disable DP MST Dave Airlie
2014-09-09  7:51   ` Jani Nikula
2014-09-09  6:28 ` [PATCH 03/11] drm/mst: start caching edid for logical ports Dave Airlie
2014-09-09  6:28 ` [PATCH 04/11] drm/displayid: add some DisplayID related defines/structs Dave Airlie
2014-09-09  6:28 ` [PATCH 05/11] drm/dp/mst: add concept of base connector id Dave Airlie
2014-09-09  6:28 ` [PATCH 06/11] drm/tile: attempt to set tiled crtcs up Dave Airlie
2014-09-09  6:28 ` [PATCH 07/11] drm/edid: allow patching the EDID to report monster mode Dave Airlie
2014-09-09  6:28 ` Dave Airlie [this message]
2014-09-09  6:28 ` [PATCH 09/11] drm/crtc: workaround userspace trying to derail crtc stealing Dave Airlie
2014-09-09  6:28 ` [PATCH 10/11] drm/tiled: add page_flip support for multi-crtc monitors Dave Airlie
2014-09-09  6:28 ` [PATCH 11/11] drm/tiled: vague attempt at waving at cursors Dave Airlie
2014-09-09  8:54 ` [RFC] attempting to hide 30" monitor in kernel (raw) Daniel Vetter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1410244096-9854-9-git-send-email-airlied@gmail.com \
    --to=airlied@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.