[RFC][PATCH 08/11] drm: Add drm_connector_fill_modes()

Ville Syrjala ville.syrjala at linux.intel.com
Tue Feb 27 12:56:57 UTC 2018


From: Ville Syrjälä <ville.syrjala at linux.intel.com>

Wrap the ->fill_modes() call in a small helper that first clears out the
stale data from connector->display_info. This should guarantee that we
get consistent display_info whether or not the drivers use the EDID
based stuff to clear and fill it.

TODO: what about just after init, before anyone has called
->fill_modes()? In that case userspace could see stale data if they do
the cheap getconnector ioctl. Not sure if that's a valid concern though.

Cc: Keith Packard <keithp at keithp.com>
Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 drivers/gpu/drm/drm_connector.c | 44 +++++++++++++++++++++++++++++++++++++----
 drivers/gpu/drm/drm_edid.c      | 14 +------------
 drivers/gpu/drm/drm_fb_helper.c |  2 +-
 drivers/gpu/drm/drm_sysfs.c     |  6 +++---
 include/drm/drm_connector.h     |  3 +++
 include/drm/drm_edid.h          |  1 -
 6 files changed, 48 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index d8c3ef4f17da..2bf19a37dbac 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1389,7 +1389,7 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
 	 * duplicate it rather than attempt to ensure some arbitrary
 	 * ordering of calls.
 	 */
-	drm_reset_display_info(connector);
+	drm_connector_reset_display_info(connector);
 	if (edid && drm_edid_is_valid(edid))
 		drm_add_display_info(connector, edid);
 
@@ -1594,9 +1594,9 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
 
 	mutex_lock(&dev->mode_config.mutex);
 	if (out_resp->count_modes == 0) {
-		connector->funcs->fill_modes(connector,
-					     dev->mode_config.max_width,
-					     dev->mode_config.max_height);
+		drm_connector_fill_modes(connector,
+					 dev->mode_config.max_width,
+					 dev->mode_config.max_height);
 	}
 
 	out_resp->mm_width = connector->display_info.width_mm;
@@ -1759,3 +1759,39 @@ struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
 	return tg;
 }
 EXPORT_SYMBOL(drm_mode_create_tile_group);
+
+/**
+ * drm_connector_reset_display_info - reset the connector's display info
+ * @connector: DRM connector
+ *
+ * Clear the old display info for @connector allowing the driver to
+ * repopulate it based on fresh data.
+ */
+void drm_connector_reset_display_info(struct drm_connector *connector)
+{
+	struct drm_display_info *info = &connector->display_info;
+
+	memset(info, 0, sizeof(*info));
+}
+EXPORT_SYMBOL_GPL(drm_connector_reset_display_info);
+
+/**
+ * drm_connector_fill_modes - fill connector mode list and dynamic display info
+ * @connector: DRM connector
+ * @max_width: max width for modes
+ * @max_height: max height for modes
+ *
+ * Reset the display info and calls &drm_connector_funcs.fill_modes() vfunc
+ * repopulate it and and the mode list.
+ *
+ * RETURNS:
+ * The number of modes found on @connector.
+ */
+int drm_connector_fill_modes(struct drm_connector *connector,
+			     unsigned int max_width, unsigned int max_height)
+{
+	drm_connector_reset_display_info(connector);
+
+	return connector->funcs->fill_modes(connector, max_width, max_height);
+}
+EXPORT_SYMBOL(drm_connector_fill_modes);
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 78c1f37be3db..618093c4a039 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4435,18 +4435,6 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
 	}
 }
 
-/* A connector has no EDID information, so we've got no EDID to compute quirks from. Reset
- * all of the values which would have been set from EDID
- */
-void
-drm_reset_display_info(struct drm_connector *connector)
-{
-	struct drm_display_info *info = &connector->display_info;
-
-	memset(info, 0, sizeof(*info));
-}
-EXPORT_SYMBOL_GPL(drm_reset_display_info);
-
 u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid)
 {
 	struct drm_display_info *info = &connector->display_info;
@@ -4665,7 +4653,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
 	int num_modes = 0;
 	u32 quirks;
 
-	drm_reset_display_info(connector);
+	drm_connector_reset_display_info(connector);
 
 	if (edid == NULL) {
 		clear_eld(connector);
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 18cb63b30e33..f3eddbbd0616 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -2027,7 +2027,7 @@ static int drm_fb_helper_probe_connector_modes(struct drm_fb_helper *fb_helper,
 
 	drm_fb_helper_for_each_connector(fb_helper, i) {
 		connector = fb_helper->connector_info[i]->connector;
-		count += connector->funcs->fill_modes(connector, maxX, maxY);
+		count += drm_connector_fill_modes(connector, maxX, maxY);
 	}
 
 	return count;
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 1c5b5ce1fd7f..3c6e800b66a0 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -130,9 +130,9 @@ static ssize_t status_store(struct device *device,
 			      connector->name,
 			      old_force, connector->force);
 
-		connector->funcs->fill_modes(connector,
-					     dev->mode_config.max_width,
-					     dev->mode_config.max_height);
+		drm_connector_fill_modes(connector,
+					 dev->mode_config.max_width,
+					 dev->mode_config.max_height);
 	}
 
 	mutex_unlock(&dev->mode_config.mutex);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 8815ef1ce429..bf14474c83f5 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1124,6 +1124,9 @@ void drm_mode_connector_set_link_status_property(struct drm_connector *connector
 						 uint64_t link_status);
 int drm_connector_init_panel_orientation_property(
 	struct drm_connector *connector, int width, int height);
+void drm_connector_reset_display_info(struct drm_connector *connector);
+int drm_connector_fill_modes(struct drm_connector *connector,
+			     unsigned int max_width, unsigned int max_height);
 
 /**
  * struct drm_tile_group - Tile group metadata
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 8d89a9c3748d..db5e6a990c2d 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -465,7 +465,6 @@ struct edid *drm_get_edid(struct drm_connector *connector,
 struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,
 				     struct i2c_adapter *adapter);
 struct edid *drm_edid_duplicate(const struct edid *edid);
-void drm_reset_display_info(struct drm_connector *connector);
 u32 drm_add_display_info(struct drm_connector *connector, const struct edid *edid);
 int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
 
-- 
2.13.6



More information about the dri-devel mailing list