All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Noralf Trønnes" <noralf@tronnes.org>
To: dri-devel@lists.freedesktop.org
Cc: intel-gfx@lists.freedesktop.org, "Noralf Trønnes" <noralf@tronnes.org>
Subject: [RFC v4 15/25] drm/fb-helper: Move modeset config code to drm_client
Date: Sat, 14 Apr 2018 13:53:08 +0200	[thread overview]
Message-ID: <20180414115318.14500-16-noralf@tronnes.org> (raw)
In-Reply-To: <20180414115318.14500-1-noralf@tronnes.org>

Call the function drm_client_find_display().
No functional change apart from making width/height arguments optional.
Some function name/signature changes and whitespace adjustments.

Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
---
 drivers/gpu/drm/drm_client.c    | 399 ++++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_fb_helper.c | 371 +------------------------------------
 include/drm/drm_client.h        |   2 +
 include/drm/drm_fb_helper.h     |   4 -
 4 files changed, 403 insertions(+), 373 deletions(-)

diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index c85c13568cf9..27818a467b09 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -18,6 +18,10 @@
 #include <drm/drm_device.h>
 #include <drm/drm_modes.h>
 
+struct drm_client_display_offset {
+	int x, y;
+};
+
 /**
  * drm_client_display_create() - Create display structure
  * @dev: DRM device
@@ -359,3 +363,398 @@ void drm_client_display_dpms(struct drm_client_display *display, int mode)
 		drm_client_display_dpms_legacy(display, mode);
 }
 EXPORT_SYMBOL(drm_client_display_dpms);
+
+static int drm_client_probe_connector_modes(struct drm_device *dev,
+					    u32 max_width, u32 max_height)
+{
+	struct drm_connector_list_iter conn_iter;
+	struct drm_connector *connector;
+	int count = 0;
+
+	drm_connector_list_iter_begin(dev, &conn_iter);
+	drm_for_each_connector_iter(connector, &conn_iter) {
+		count += connector->funcs->fill_modes(connector, max_width, max_height);
+	}
+	drm_connector_list_iter_end(&conn_iter);
+
+	return count;
+}
+
+static bool drm_target_cloned(struct drm_device *dev,
+			      struct drm_connector **connectors,
+			      unsigned int connector_count,
+			      struct drm_display_mode **modes,
+			      struct drm_client_display_offset *offsets,
+			      bool *enabled, int width, int height)
+{
+	int count, i, j;
+	bool can_clone = false;
+	struct drm_display_mode *dmt_mode, *mode;
+
+	/* only contemplate cloning in the single crtc case */
+	if (dev->mode_config.num_crtc > 1)
+		return false;
+
+	count = 0;
+	for (i = 0; i < connector_count; i++) {
+		if (enabled[i])
+			count++;
+	}
+
+	/* only contemplate cloning if more than one connector is enabled */
+	if (count <= 1)
+		return false;
+
+	/* check the command line or if nothing common pick 1024x768 */
+	can_clone = true;
+	for (i = 0; i < connector_count; i++) {
+		if (!enabled[i])
+			continue;
+		modes[i] = drm_connector_pick_cmdline_mode(connectors[i]);
+		if (!modes[i]) {
+			can_clone = false;
+			break;
+		}
+		for (j = 0; j < i; j++) {
+			if (!enabled[j])
+				continue;
+			if (!drm_mode_equal(modes[j], modes[i]))
+				can_clone = false;
+		}
+	}
+
+	if (can_clone) {
+		DRM_DEBUG_KMS("can clone using command line\n");
+		return true;
+	}
+
+	/* try and find a 1024x768 mode on each connector */
+	can_clone = true;
+	dmt_mode = drm_mode_find_dmt(dev, 1024, 768, 60, false);
+
+	for (i = 0; i < connector_count; i++) {
+		if (!enabled[i])
+			continue;
+
+		list_for_each_entry(mode, &connectors[i]->modes, head) {
+			if (drm_mode_equal(mode, dmt_mode))
+				modes[i] = mode;
+		}
+		if (!modes[i])
+			can_clone = false;
+	}
+
+	if (can_clone) {
+		DRM_DEBUG_KMS("can clone using 1024x768\n");
+		return true;
+	}
+	DRM_INFO("kms: can't enable cloning when we probably wanted to.\n");
+
+	return false;
+}
+
+static void drm_get_tile_offsets(struct drm_connector **connectors,
+				 unsigned int connector_count,
+				 struct drm_display_mode **modes,
+				 struct drm_client_display_offset *offsets,
+				 int idx,
+				 int h_idx, int v_idx)
+{
+	int i;
+	int hoffset = 0, voffset = 0;
+
+	for (i = 0; i < connector_count; i++) {
+		struct drm_connector *connector = connectors[i];
+
+		if (!connector->has_tile)
+			continue;
+
+		if (!modes[i] && (h_idx || v_idx)) {
+			DRM_DEBUG_KMS("no modes for connector tiled %d %d\n", i,
+				      connector->base.id);
+			continue;
+		}
+		if (connector->tile_h_loc < h_idx)
+			hoffset += modes[i]->hdisplay;
+
+		if (connector->tile_v_loc < v_idx)
+			voffset += modes[i]->vdisplay;
+	}
+	offsets[idx].x = hoffset;
+	offsets[idx].y = voffset;
+	DRM_DEBUG_KMS("returned %d %d for %d %d\n", hoffset, voffset, h_idx, v_idx);
+}
+
+static bool drm_target_preferred(struct drm_connector **connectors,
+				 unsigned int connector_count,
+				 struct drm_display_mode **modes,
+				 struct drm_client_display_offset *offsets,
+				 bool *enabled, int width, int height)
+{
+	const u64 mask = BIT_ULL(connector_count) - 1;
+	u64 conn_configured = 0;
+	int tile_pass = 0;
+	int i;
+
+retry:
+	for (i = 0; i < connector_count; i++) {
+		struct drm_connector *connector = connectors[i];
+
+		if (conn_configured & BIT_ULL(i))
+			continue;
+
+		if (!enabled[i]) {
+			conn_configured |= BIT_ULL(i);
+			continue;
+		}
+
+		/* first pass over all the untiled connectors */
+		if (tile_pass == 0 && connector->has_tile)
+			continue;
+
+		if (tile_pass == 1) {
+			if (connector->tile_h_loc != 0 ||
+			    connector->tile_v_loc != 0)
+				continue;
+
+		} else {
+			if (connector->tile_h_loc != tile_pass - 1 &&
+			    connector->tile_v_loc != tile_pass - 1)
+			/* if this tile_pass doesn't cover any of the tiles - keep going */
+				continue;
+
+			/*
+			 * find the tile offsets for this pass - need to find
+			 * all tiles left and above
+			 */
+			drm_get_tile_offsets(connectors, connector_count, modes, offsets,
+					     i, connector->tile_h_loc, connector->tile_v_loc);
+		}
+		DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n", connector->base.id);
+
+		/* got for command line mode first */
+		modes[i] = drm_connector_pick_cmdline_mode(connector);
+		if (!modes[i]) {
+			DRM_DEBUG_KMS("looking for preferred mode on connector %d %d\n",
+				      connector->base.id,
+				      connector->tile_group ? connector->tile_group->id : 0);
+			modes[i] = drm_connector_has_preferred_mode(connector, width, height);
+		}
+		/* No preferred modes, pick one off the list */
+		if (!modes[i])
+			modes[i] = list_first_entry_or_null(&connector->modes,
+							    struct drm_display_mode, head);
+
+		DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name : "none");
+		conn_configured |= BIT_ULL(i);
+	}
+
+	if ((conn_configured & mask) != mask) {
+		tile_pass++;
+		goto retry;
+	}
+	return true;
+}
+
+static int drm_pick_crtcs(struct drm_client_display *display,
+			  struct drm_connector **connectors,
+			  unsigned int connector_count,
+			  struct drm_crtc **best_crtcs,
+			  struct drm_display_mode **modes,
+			  int n, int width, int height)
+{
+	struct drm_device *dev = display->dev;
+	int o, my_score, best_score, score;
+	struct drm_connector *connector;
+	struct drm_mode_set *modeset;
+	struct drm_encoder *encoder;
+	struct drm_crtc **crtcs;
+
+	if (n == connector_count)
+		return 0;
+
+	connector = connectors[n];
+
+	best_crtcs[n] = NULL;
+	best_score = drm_pick_crtcs(display, connectors, connector_count,
+				    best_crtcs, modes, n + 1, width, height);
+	if (!modes[n])
+		return best_score;
+
+	crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
+	if (!crtcs)
+		return best_score;
+
+	my_score = 1;
+	if (connector->status == connector_status_connected)
+		my_score++;
+	if (connector->cmdline_mode.specified)
+		my_score++;
+	if (drm_connector_has_preferred_mode(connector, width, height))
+		my_score++;
+
+	/*
+	 * If the DRM device implements atomic hooks and ->best_encoder() is
+	 * NULL we fallback to the default drm_atomic_helper_best_encoder()
+	 * helper.
+	 */
+	if (drm_drv_uses_atomic_modeset(dev) &&
+	    !connector->helper_private->best_encoder)
+		encoder = drm_atomic_helper_best_encoder(connector);
+	else
+		encoder = connector->helper_private->best_encoder(connector);
+
+	if (!encoder)
+		goto out;
+
+	/*
+	 * select a crtc for this connector and then attempt to configure
+	 * remaining connectors
+	 */
+	drm_client_display_for_each_modeset(modeset, display) {
+		struct drm_crtc *crtc = modeset->crtc;
+
+		if ((encoder->possible_crtcs & drm_crtc_mask(crtc)) == 0)
+			continue;
+
+		for (o = 0; o < n; o++)
+			if (best_crtcs[o] == crtc)
+				break;
+
+		if (o < n) {
+			/* ignore cloning unless only a single crtc */
+			if (dev->mode_config.num_crtc > 1)
+				continue;
+
+			if (!drm_mode_equal(modes[o], modes[n]))
+				continue;
+		}
+
+		crtcs[n] = crtc;
+		memcpy(crtcs, best_crtcs, n * sizeof(*crtcs));
+		score = my_score + drm_pick_crtcs(display, connectors, connector_count,
+						  crtcs, modes, n + 1, width, height);
+		if (score > best_score) {
+			best_score = score;
+			memcpy(best_crtcs, crtcs,
+			       connector_count * sizeof(*crtcs));
+		}
+	}
+out:
+	kfree(crtcs);
+
+	return best_score;
+}
+
+/**
+ * drm_client_find_display() - Find display
+ * @dev: DRM device
+ * @width: Maximum display mode width (optional)
+ * @height: Maximum display mode height (optional)
+ *
+ * This function returns a display the client can use if available.
+ *
+ * Free resources by calling drm_client_display_free().
+ *
+ * Returns:
+ * A &drm_client_display on success, NULL if no connectors are found
+ * or error pointer on failure.
+ */
+struct drm_client_display *
+drm_client_find_display(struct drm_device *dev, unsigned int width, unsigned int height)
+{
+	struct drm_client_display_offset *offsets;
+	struct drm_client_display *display;
+	struct drm_connector **connectors;
+	struct drm_display_mode **modes;
+	struct drm_crtc **crtcs;
+	int i, connector_count;
+	bool *enabled;
+
+	DRM_DEBUG_KMS("\n");
+
+	if (!width)
+		width = dev->mode_config.max_width;
+	if (!height)
+		height = dev->mode_config.max_height;
+
+	mutex_lock(&dev->mode_config.mutex);
+	if (!drm_client_probe_connector_modes(dev, width, height))
+		DRM_DEBUG_KMS("No connectors reported connected with modes\n");
+
+	if (dev->driver->initial_client_display) {
+		display = dev->driver->initial_client_display(dev, width, height);
+		if (display) {
+			mutex_unlock(&dev->mode_config.mutex);
+			return display;
+		}
+	}
+
+	connector_count = drm_connector_get_all(dev, &connectors);
+	if (connector_count < 1)
+		return NULL;
+
+	enabled = drm_connector_get_enabled_status(connectors, connector_count);
+	crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
+	modes = kcalloc(connector_count, sizeof(*modes), GFP_KERNEL);
+	offsets = kcalloc(connector_count, sizeof(*offsets), GFP_KERNEL);
+	if (!crtcs || !modes || !enabled || !offsets) {
+		DRM_ERROR("Memory allocation failed\n");
+		display = ERR_PTR(-ENOMEM);
+		goto out;
+	}
+
+	display = drm_client_display_create(dev);
+	if (IS_ERR(display))
+		goto out;
+
+	if (!drm_target_cloned(dev, connectors, connector_count,
+			       modes, offsets, enabled, width, height) &&
+	    !drm_target_preferred(connectors, connector_count,
+				  modes, offsets, enabled, width, height))
+		DRM_ERROR("Unable to find initial modes\n");
+
+	DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n", width, height);
+
+	drm_pick_crtcs(display, connectors, connector_count, crtcs, modes, 0, width, height);
+
+	/* need to set the modesets up here for use later */
+	/* fill out the connector<->crtc mappings into the modesets */
+
+	for (i = 0; i < connector_count; i++) {
+		struct drm_client_display_offset *offset = &offsets[i];
+		struct drm_connector *connector = connectors[i];
+		struct drm_display_mode *mode = modes[i];
+		struct drm_crtc *crtc = crtcs[i];
+
+		if (mode && crtc) {
+			struct drm_mode_set *modeset;
+
+			modeset = drm_client_display_find_modeset(display, crtc);
+			if (WARN_ON(!modeset)) {
+				drm_client_display_free(display);
+				display = ERR_PTR(-EINVAL);
+				goto out;
+			}
+
+			DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n",
+				      mode->name, modeset->crtc->base.id, offset->x, offset->y);
+
+			modeset->mode = drm_mode_duplicate(dev, mode);
+			drm_connector_get(connector);
+			modeset->connectors[modeset->num_connectors++] = connector;
+			modeset->x = offset->x;
+			modeset->y = offset->y;
+		}
+	}
+out:
+	mutex_unlock(&dev->mode_config.mutex);
+	drm_connector_put_all(connectors, connector_count);
+	kfree(crtcs);
+	kfree(modes);
+	kfree(offsets);
+	kfree(enabled);
+
+	return display;
+}
+EXPORT_SYMBOL(drm_client_find_display);
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 6ee61f195321..01d8840930a3 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1558,386 +1558,19 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe
 }
 EXPORT_SYMBOL(drm_fb_helper_fill_var);
 
-static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper,
-						uint32_t maxX,
-						uint32_t maxY)
-{
-	struct drm_connector_list_iter conn_iter;
-	struct drm_connector *connector;
-	int count = 0;
-
-	drm_connector_list_iter_begin(fb_helper->dev, &conn_iter);
-	drm_for_each_connector_iter(connector, &conn_iter) {
-		count += connector->funcs->fill_modes(connector, maxX, maxY);
-	}
-	drm_connector_list_iter_end(&conn_iter);
-
-	return count;
-}
-
-static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
-			      struct drm_connector **connectors,
-			      unsigned int connector_count,
-			      struct drm_display_mode **modes,
-			      struct drm_fb_offset *offsets,
-			      bool *enabled, int width, int height)
-{
-	int count, i, j;
-	bool can_clone = false;
-	struct drm_display_mode *dmt_mode, *mode;
-
-	/* only contemplate cloning in the single crtc case */
-	if (fb_helper->dev->mode_config.num_crtc > 1)
-		return false;
-
-	count = 0;
-	for (i = 0; i < connector_count; i++) {
-		if (enabled[i])
-			count++;
-	}
-
-	/* only contemplate cloning if more than one connector is enabled */
-	if (count <= 1)
-		return false;
-
-	/* check the command line or if nothing common pick 1024x768 */
-	can_clone = true;
-	for (i = 0; i < connector_count; i++) {
-		if (!enabled[i])
-			continue;
-		modes[i] = drm_connector_pick_cmdline_mode(connectors[i]);
-		if (!modes[i]) {
-			can_clone = false;
-			break;
-		}
-		for (j = 0; j < i; j++) {
-			if (!enabled[j])
-				continue;
-			if (!drm_mode_equal(modes[j], modes[i]))
-				can_clone = false;
-		}
-	}
-
-	if (can_clone) {
-		DRM_DEBUG_KMS("can clone using command line\n");
-		return true;
-	}
-
-	/* try and find a 1024x768 mode on each connector */
-	can_clone = true;
-	dmt_mode = drm_mode_find_dmt(fb_helper->dev, 1024, 768, 60, false);
-
-	for (i = 0; i < connector_count; i++) {
-		if (!enabled[i])
-			continue;
-
-		list_for_each_entry(mode, &connectors[i]->modes, head) {
-			if (drm_mode_equal(mode, dmt_mode))
-				modes[i] = mode;
-		}
-		if (!modes[i])
-			can_clone = false;
-	}
-
-	if (can_clone) {
-		DRM_DEBUG_KMS("can clone using 1024x768\n");
-		return true;
-	}
-	DRM_INFO("kms: can't enable cloning when we probably wanted to.\n");
-	return false;
-}
-
-static int drm_get_tile_offsets(struct drm_connector **connectors,
-				unsigned int connector_count,
-				struct drm_display_mode **modes,
-				struct drm_fb_offset *offsets,
-				int idx,
-				int h_idx, int v_idx)
-{
-	int i;
-	int hoffset = 0, voffset = 0;
-
-	for (i = 0; i < connector_count; i++) {
-		struct drm_connector *connector = connectors[i];
-
-		if (!connector->has_tile)
-			continue;
-
-		if (!modes[i] && (h_idx || v_idx)) {
-			DRM_DEBUG_KMS("no modes for connector tiled %d %d\n", i,
-				      connector->base.id);
-			continue;
-		}
-		if (connector->tile_h_loc < h_idx)
-			hoffset += modes[i]->hdisplay;
-
-		if (connector->tile_v_loc < v_idx)
-			voffset += modes[i]->vdisplay;
-	}
-	offsets[idx].x = hoffset;
-	offsets[idx].y = voffset;
-	DRM_DEBUG_KMS("returned %d %d for %d %d\n", hoffset, voffset, h_idx, v_idx);
-	return 0;
-}
-
-static bool drm_target_preferred(struct drm_connector **connectors,
-				 unsigned int connector_count,
-				 struct drm_display_mode **modes,
-				 struct drm_fb_offset *offsets,
-				 bool *enabled, int width, int height)
-{
-	const u64 mask = BIT_ULL(connector_count) - 1;
-	u64 conn_configured = 0;
-	int tile_pass = 0;
-	int i;
-
-retry:
-	for (i = 0; i < connector_count; i++) {
-		struct drm_connector *connector = connectors[i];
-
-		if (conn_configured & BIT_ULL(i))
-			continue;
-
-		if (enabled[i] == false) {
-			conn_configured |= BIT_ULL(i);
-			continue;
-		}
-
-		/* first pass over all the untiled connectors */
-		if (tile_pass == 0 && connector->has_tile)
-			continue;
-
-		if (tile_pass == 1) {
-			if (connector->tile_h_loc != 0 ||
-			    connector->tile_v_loc != 0)
-				continue;
-
-		} else {
-			if (connector->tile_h_loc != tile_pass - 1 &&
-			    connector->tile_v_loc != tile_pass - 1)
-			/* if this tile_pass doesn't cover any of the tiles - keep going */
-				continue;
-
-			/*
-			 * find the tile offsets for this pass - need to find
-			 * all tiles left and above
-			 */
-			drm_get_tile_offsets(connectors, connector_count, modes, offsets,
-					     i, connector->tile_h_loc, connector->tile_v_loc);
-		}
-		DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n",
-			      connector->base.id);
-
-		/* got for command line mode first */
-		modes[i] = drm_connector_pick_cmdline_mode(connector);
-		if (!modes[i]) {
-			DRM_DEBUG_KMS("looking for preferred mode on connector %d %d\n",
-				      connector->base.id, connector->tile_group ? connector->tile_group->id : 0);
-			modes[i] = drm_connector_has_preferred_mode(connector, width, height);
-		}
-		/* No preferred modes, pick one off the list */
-		if (!modes[i])
-			modes[i] = list_first_entry_or_null(&connector->modes, struct drm_display_mode, head);
-
-		DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name :
-			  "none");
-		conn_configured |= BIT_ULL(i);
-	}
-
-	if ((conn_configured & mask) != mask) {
-		tile_pass++;
-		goto retry;
-	}
-	return true;
-}
-
-static int drm_pick_crtcs(struct drm_client_display *display,
-			  struct drm_connector **connectors,
-			  unsigned int connector_count,
-			  struct drm_crtc **best_crtcs,
-			  struct drm_display_mode **modes,
-			  int n, int width, int height)
-{
-	struct drm_device *dev = display->dev;
-	int o, my_score, best_score, score;
-	struct drm_connector *connector;
-	const struct drm_connector_helper_funcs *connector_funcs;
-	struct drm_mode_set *modeset;
-	struct drm_encoder *encoder;
-	struct drm_crtc **crtcs;
-
-	if (n == connector_count)
-		return 0;
-
-	connector = connectors[n];
-
-	best_crtcs[n] = NULL;
-	best_score = drm_pick_crtcs(display, connectors, connector_count,
-				    best_crtcs, modes, n + 1, width, height);
-	if (modes[n] == NULL)
-		return best_score;
-
-	crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
-	if (!crtcs)
-		return best_score;
-
-	my_score = 1;
-	if (connector->status == connector_status_connected)
-		my_score++;
-	if (connector->cmdline_mode.specified)
-		my_score++;
-	if (drm_connector_has_preferred_mode(connector, width, height))
-		my_score++;
-
-	connector_funcs = connector->helper_private;
-
-	/*
-	 * If the DRM device implements atomic hooks and ->best_encoder() is
-	 * NULL we fallback to the default drm_atomic_helper_best_encoder()
-	 * helper.
-	 */
-	if (drm_drv_uses_atomic_modeset(dev) &&
-	    !connector_funcs->best_encoder)
-		encoder = drm_atomic_helper_best_encoder(connector);
-	else
-		encoder = connector_funcs->best_encoder(connector);
-
-	if (!encoder)
-		goto out;
-
-	/*
-	 * select a crtc for this connector and then attempt to configure
-	 * remaining connectors
-	 */
-	drm_client_display_for_each_modeset(modeset, display) {
-		struct drm_crtc *crtc = modeset->crtc;
-
-		if ((encoder->possible_crtcs & drm_crtc_mask(crtc)) == 0)
-			continue;
-
-		for (o = 0; o < n; o++)
-			if (best_crtcs[o] == crtc)
-				break;
-
-		if (o < n) {
-			/* ignore cloning unless only a single crtc */
-			if (dev->mode_config.num_crtc > 1)
-				continue;
-
-			if (!drm_mode_equal(modes[o], modes[n]))
-				continue;
-		}
-
-		crtcs[n] = crtc;
-		memcpy(crtcs, best_crtcs, n * sizeof(*crtcs));
-		score = my_score + drm_pick_crtcs(display, connectors, connector_count,
-						  crtcs, modes, n + 1, width, height);
-		if (score > best_score) {
-			best_score = score;
-			memcpy(best_crtcs, crtcs,
-			       connector_count * sizeof(*crtcs));
-		}
-	}
-out:
-	kfree(crtcs);
-	return best_score;
-}
-
 static void drm_setup_crtcs(struct drm_fb_helper *fb_helper,
 			    u32 width, u32 height)
 {
-	struct drm_device *dev = fb_helper->dev;
 	struct drm_client_display *display;
-	struct drm_connector **connectors;
-	struct drm_display_mode **modes;
-	struct drm_fb_offset *offsets;
-	struct drm_crtc **crtcs;
-	int i, connector_count;
-	bool *enabled;
 
-	DRM_DEBUG_KMS("\n");
-	/* prevent concurrent modification of connector_count by hotplug */
 	lockdep_assert_held(&fb_helper->lock);
 
-	mutex_lock(&dev->mode_config.mutex);
-	if (drm_fb_helper_probe_connector_modes(fb_helper, width, height) == 0)
-		DRM_DEBUG_KMS("No connectors reported connected with modes\n");
-
-	if (dev->driver->initial_client_display) {
-		display = dev->driver->initial_client_display(dev, width, height);
-		if (display) {
-			drm_client_display_free(fb_helper->display);
-			fb_helper->display = display;
-			mutex_unlock(&dev->mode_config.mutex);
-			return;
-		}
-	}
-
-	connector_count = drm_connector_get_all(dev, &connectors);
-	if (connector_count < 1)
+	display = drm_client_find_display(fb_helper->dev, width, height);
+	if (IS_ERR_OR_NULL(display))
 		return;
 
-	enabled = drm_connector_get_enabled_status(connectors, connector_count);
-	crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL);
-	modes = kcalloc(connector_count, sizeof(*modes), GFP_KERNEL);
-	offsets = kcalloc(connector_count, sizeof(*offsets), GFP_KERNEL);
-	if (!crtcs || !modes || !enabled || !offsets) {
-		DRM_ERROR("Memory allocation failed\n");
-		goto out;
-	}
-
-	display = drm_client_display_create(dev);
-	if (IS_ERR(display))
-		goto out;
-
-	if (!drm_target_cloned(fb_helper, connectors, connector_count,
-			       modes, offsets, enabled, width, height) &&
-	    !drm_target_preferred(connectors, connector_count,
-				  modes, offsets, enabled, width, height))
-		DRM_ERROR("Unable to find initial modes\n");
-
-	DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n", width, height);
-
-	drm_pick_crtcs(display, connectors, connector_count, crtcs, modes, 0, width, height);
-
-	/* need to set the modesets up here for use later */
-	/* fill out the connector<->crtc mappings into the modesets */
-
-	for (i = 0; i < connector_count; i++) {
-		struct drm_connector *connector = connectors[i];
-		struct drm_display_mode *mode = modes[i];
-		struct drm_crtc *crtc = crtcs[i];
-		struct drm_fb_offset *offset = &offsets[i];
-
-		if (mode && crtc) {
-			struct drm_mode_set *modeset;
-
-			modeset = drm_client_display_find_modeset(display, crtc);
-			if (WARN_ON(!modeset)) {
-				drm_client_display_free(display);
-				goto out;
-			}
-
-			DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n",
-				      mode->name, modeset->crtc->base.id, offset->x, offset->y);
-
-			modeset->mode = drm_mode_duplicate(dev, mode);
-			drm_connector_get(connector);
-			modeset->connectors[modeset->num_connectors++] = connector;
-			modeset->x = offset->x;
-			modeset->y = offset->y;
-		}
-	}
-
 	drm_client_display_free(fb_helper->display);
 	fb_helper->display = display;
-out:
-	mutex_unlock(&dev->mode_config.mutex);
-	drm_connector_put_all(connectors, connector_count);
-	kfree(crtcs);
-	kfree(modes);
-	kfree(offsets);
-	kfree(enabled);
 }
 
 /*
diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h
index ed028f5877d0..27d2a46cd94a 100644
--- a/include/drm/drm_client.h
+++ b/include/drm/drm_client.h
@@ -48,5 +48,7 @@ bool drm_client_display_panel_rotation(struct drm_connector *connector,
 				       unsigned int *rotation);
 int drm_client_display_restore(struct drm_client_display *display);
 void drm_client_display_dpms(struct drm_client_display *display, int mode);
+struct drm_client_display *
+drm_client_find_display(struct drm_device *dev, unsigned int width, unsigned int height);
 
 #endif
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index a1e1ab1247c5..5f66f253a97b 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -41,10 +41,6 @@ enum mode_set_atomic {
 	ENTER_ATOMIC_MODE_SET,
 };
 
-struct drm_fb_offset {
-	int x, y;
-};
-
 /**
  * struct drm_fb_helper_surface_size - describes fbdev size and scanout surface size
  * @fb_width: fbdev width
-- 
2.15.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2018-04-14 11:53 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-14 11:52 [RFC v4 00/25] drm: Add generic fbdev emulation Noralf Trønnes
2018-04-14 11:52 ` [RFC v4 01/25] drm: provide management functions for drm_file Noralf Trønnes
2018-04-14 11:52 ` [RFC v4 02/25] drm/file: Don't set master on in-kernel clients Noralf Trønnes
2018-04-14 11:52 ` [RFC v4 03/25] drm/fb-helper: No need to cache rotation and sw_rotations Noralf Trønnes
2018-04-14 11:52 ` [RFC v4 04/25] drm/fb-helper: Remove drm_fb_helper_debug_enter/leave() Noralf Trønnes
2018-04-14 11:52 ` [RFC v4 05/25] drm/fb-helper: dpms_legacy(): Only set on connectors in use Noralf Trønnes
2018-04-14 11:52 ` [RFC v4 06/25] drm/atomic: Move __drm_atomic_helper_disable_plane/set_config() Noralf Trønnes
2018-04-16  8:30   ` Daniel Vetter
2018-04-14 11:53 ` [RFC v4 07/25] drm: Begin an API for in-kernel clients Noralf Trønnes
2018-04-14 11:53 ` [RFC v4 08/25] drm/fb-helper: Use struct drm_client_display Noralf Trønnes
2018-04-14 11:53 ` [RFC v4 09/25] drm/fb-helper: Move modeset commit code to drm_client Noralf Trønnes
2018-04-14 11:53 ` [RFC v4 10/25] drm/connector: Add drm_connector_has_preferred_mode/pick_cmdline_mode() Noralf Trønnes
2018-04-14 11:53 ` [RFC v4 11/25] drm/connector: Add connector array functions Noralf Trønnes
2018-04-16  8:33   ` Daniel Vetter
2018-04-14 11:53 ` [RFC v4 12/25] drm/i915: Add drm_driver->initial_client_display callback Noralf Trønnes
2018-04-16  8:38   ` Daniel Vetter
2019-03-01 11:46     ` [Intel-gfx] " Noralf Trønnes
2019-03-01 11:51       ` Daniel Vetter
2018-04-14 11:53 ` [RFC v4 13/25] drm/fb-helper: Remove struct drm_fb_helper_crtc Noralf Trønnes
2018-04-14 11:53 ` [RFC v4 14/25] drm/fb-helper: Remove struct drm_fb_helper_connector Noralf Trønnes
2018-04-14 11:53 ` Noralf Trønnes [this message]
2018-04-14 11:53 ` [RFC v4 16/25] drm: Make ioctls available for in-kernel clients Noralf Trønnes
2018-04-16  9:04   ` Daniel Vetter
2018-04-14 11:53 ` [RFC v4 17/25] drm/client: Bail out if there's a DRM master Noralf Trønnes
2018-04-16  8:45   ` Daniel Vetter
2018-04-14 11:53 ` [RFC v4 18/25] drm/client: Make the display modes available to clients Noralf Trønnes
2018-04-14 11:53 ` [RFC v4 19/25] drm/client: Finish the in-kernel client API Noralf Trønnes
2018-04-16  8:27   ` [Intel-gfx] " Daniel Vetter
2018-04-16 15:58     ` Noralf Trønnes
2018-04-17  8:08       ` Daniel Vetter
2018-04-14 11:53 ` [RFC v4 20/25] drm/prime: Don't pin module on export for in-kernel clients Noralf Trønnes
2018-04-14 11:53 ` [RFC v4 21/25] drm/fb-helper: Add drm_fb_helper_fb_open/release() Noralf Trønnes
2018-04-16  8:46   ` Daniel Vetter
2018-04-16 16:10     ` Noralf Trønnes
2018-04-17  8:14       ` [Intel-gfx] " Daniel Vetter
2018-04-14 11:53 ` [RFC v4 22/25] drm/fb-helper: Add generic fbdev emulation Noralf Trønnes
2018-04-16  8:52   ` Daniel Vetter
2018-04-14 11:53 ` [RFC v4 23/25] drm: Add DRM device registered notifier Noralf Trønnes
2018-04-17 10:16   ` Daniel Vetter
2018-04-14 11:53 ` [RFC v4 24/25] drm/client: Hack: Add bootsplash Noralf Trønnes
2018-04-14 11:53 ` [RFC v4 25/25] drm/client: Hack: Add DRM VT console client Noralf Trønnes
2018-04-14 15:30 ` ✗ Fi.CI.CHECKPATCH: warning for drm: Add generic fbdev emulation Patchwork
2018-04-14 15:36 ` ✗ Fi.CI.SPARSE: " Patchwork
2018-04-14 15:46 ` ✓ Fi.CI.BAT: success " Patchwork
2018-04-14 16:31 ` ✓ Fi.CI.IGT: " Patchwork
2018-04-16  8:21 ` [RFC v4 00/25] " Daniel Vetter
2018-04-16 18:49   ` Noralf Trønnes
2018-04-17  8:10     ` [Intel-gfx] " Daniel Vetter
  -- strict thread matches above, loose matches on Subject: below --
2018-04-13 16:53 Noralf Trønnes
2018-04-13 16:53 ` [RFC v4 15/25] drm/fb-helper: Move modeset config code to drm_client Noralf Trønnes
2018-04-12 16:12 [RFC v4 12/25] drm/i915: Add drm_driver->initial_client_display callback Noralf Trønnes
2018-04-12 16:12 ` [RFC v4 15/25] drm/fb-helper: Move modeset config code to drm_client Noralf Trønnes

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=20180414115318.14500-16-noralf@tronnes.org \
    --to=noralf@tronnes.org \
    --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.