[PATCH] drm: introduce DRM_CONNECTOR_POLL_FORCE

Daniel Vetter daniel.vetter at ffwll.ch
Fri May 25 03:54:38 PDT 2012


Useful for ->detect functions that have different behaviour if force
is set. This way probe_single_connector can avoid to do the expensive
edid dance on connectors where this is not needed.

I've checked through all drivers and set this flag everywhere where
the connector->detect function has different behaviour if force is
set. For nouveau and radeon I've got lost in the code traces, so I've
set this flag unconditionally.

Note that we also need to update the poll_execute function to now
also ignore connectors which have only this new flag set.

v2: Change POLL_HDP checks so that they ignore POLL_FORCE for both the
poll and the hpd handling code.

v3: Sprinkle POLL_FORCE more liberally over drivers. It should be now
everywhere where a non-intel driver can return anything else than
connector_status_connected in its detect callback.

v4: Fixup psb compile fail.

Signed-Off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
---
 drivers/gpu/drm/drm_crtc_helper.c             |    6 ++++--
 drivers/gpu/drm/exynos/exynos_drm_connector.c |    2 ++
 drivers/gpu/drm/gma500/cdv_intel_crt.c        |    2 ++
 drivers/gpu/drm/gma500/cdv_intel_hdmi.c       |    2 ++
 drivers/gpu/drm/gma500/mdfld_dsi_output.c     |    1 +
 drivers/gpu/drm/gma500/oaktrail_hdmi.c        |    2 ++
 drivers/gpu/drm/gma500/psb_intel_sdvo.c       |    2 ++
 drivers/gpu/drm/i915/intel_crt.c              |    3 ++-
 drivers/gpu/drm/i915/intel_tv.c               |    3 ++-
 drivers/gpu/drm/nouveau/nouveau_connector.c   |    1 +
 drivers/gpu/drm/radeon/radeon_connectors.c    |    5 +++++
 drivers/gpu/drm/udl/udl_connector.c           |    2 ++
 drivers/staging/omapdrm/omap_connector.c      |    2 ++
 include/drm/drm_crtc.h                        |    4 ++++
 14 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index b1d643d..8ea1c1e 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -944,7 +944,9 @@ static void output_poll_execute(struct work_struct *work)
 
 		/* Ignore HDP capable connectors and connectors where we don't
 		 * want any hotplug detection at all for polling. */
-		if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD)
+		if (!connector->polled ||
+		    connector->polled == DRM_CONNECTOR_POLL_FORCE ||
+		    (connector->polled & DRM_CONNECTOR_POLL_HPD))
 			continue;
 
 		else if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT))
@@ -1029,7 +1031,7 @@ void drm_helper_hpd_irq_event(struct drm_device *dev)
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
 
 		/* Only handle HPD capable connectors. */
-		if (connector->polled != DRM_CONNECTOR_POLL_HPD)
+		if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
 			continue;
 
 		old_status = connector->status;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c
index bf791fa..e5a8a27 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
@@ -327,6 +327,8 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
 	drm_connector_init(dev, connector, &exynos_connector_funcs, type);
 	drm_connector_helper_add(connector, &exynos_connector_helper_funcs);
 
+	connector->polled |= DRM_CONNECTOR_POLL_FORCE;
+
 	err = drm_sysfs_connector_add(connector);
 	if (err)
 		goto err_connector;
diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c b/drivers/gpu/drm/gma500/cdv_intel_crt.c
index 1874220..e6b2e49 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_crt.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c
@@ -313,6 +313,8 @@ void cdv_intel_crt_init(struct drm_device *dev,
 	drm_connector_helper_add(connector,
 					&cdv_intel_crt_connector_helper_funcs);
 
+	connector->polled |= DRM_CONNECTOR_POLL_FORCE;
+
 	drm_sysfs_connector_add(connector);
 
 	return;
diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
index 88b59d4..766aec8 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
@@ -373,6 +373,8 @@ void cdv_hdmi_init(struct drm_device *dev,
 	hdmi_priv->hdmi_i2c_adapter =
 				&(psb_intel_encoder->i2c_bus->adapter);
 	hdmi_priv->dev = dev;
+	connector->polled |= DRM_CONNECTOR_POLL_FORCE;
+
 	drm_sysfs_connector_add(connector);
 	return;
 
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_output.c b/drivers/gpu/drm/gma500/mdfld_dsi_output.c
index 5675d93..0e97a91 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_output.c
+++ b/drivers/gpu/drm/gma500/mdfld_dsi_output.c
@@ -604,6 +604,7 @@ void mdfld_dsi_output_init(struct drm_device *dev,
 	dsi_config->encoder = encoder;
 	encoder->base.type = (pipe == 0) ? INTEL_OUTPUT_MIPI :
 		INTEL_OUTPUT_MIPI2;
+	connector->polled |= DRM_CONNECTOR_POLL_FORCE;
 	drm_sysfs_connector_add(connector);
 	return;
 
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
index c10899c..23b8d52 100644
--- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c
+++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
@@ -349,6 +349,8 @@ void oaktrail_hdmi_init(struct drm_device *dev,
 	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 	connector->interlace_allowed = false;
 	connector->doublescan_allowed = false;
+	connector->polled |= DRM_CONNECTOR_POLL_FORCE;
+
 	drm_sysfs_connector_add(connector);
 
 	return;
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
index d39b15b..fdfc4a0 100644
--- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c
+++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
@@ -2028,6 +2028,8 @@ psb_intel_sdvo_connector_init(struct psb_intel_sdvo_connector *connector,
 	connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;
 
 	psb_intel_connector_attach_encoder(&connector->base, &encoder->base);
+	connector->base.base.polled |= DRM_CONNECTOR_POLL_FORCE;
+
 	drm_sysfs_connector_add(&connector->base.base);
 }
 
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 75a70c4..a60d131 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -639,7 +639,8 @@ void intel_crt_init(struct drm_device *dev)
 	if (I915_HAS_HOTPLUG(dev))
 		connector->polled = DRM_CONNECTOR_POLL_HPD;
 	else
-		connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+		connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+				    DRM_CONNECTOR_POLL_FORCE;
 
 	/*
 	 * Configure the automatic hotplug detection stuff
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index a233a51..dad7d8e 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1614,7 +1614,8 @@ intel_tv_init(struct drm_device *dev)
 	 *
 	 * More recent chipsets favour HDMI rather than integrated S-Video.
 	 */
-	connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+	connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+			    DRM_CONNECTOR_POLL_FORCE;
 
 	drm_connector_init(dev, connector, &intel_tv_connector_funcs,
 			   DRM_MODE_CONNECTOR_SVIDEO);
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index fa86035..780d608 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -1085,6 +1085,7 @@ nouveau_connector_create(struct drm_device *dev, int index)
 		if (ret == 0)
 			connector->polled = DRM_CONNECTOR_POLL_HPD;
 	}
+	connector->polled |= DRM_CONNECTOR_POLL_FORCE;
 
 	drm_sysfs_connector_add(connector);
 	return connector;
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 2914c57..c64ecc9 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1830,6 +1830,8 @@ radeon_add_atom_connector(struct drm_device *dev,
 	} else
 		connector->polled = DRM_CONNECTOR_POLL_HPD;
 
+	connector->polled |= DRM_CONNECTOR_POLL_FORCE;
+
 	connector->display_info.subpixel_order = subpixel_order;
 	drm_sysfs_connector_add(connector);
 	return;
@@ -1987,6 +1989,9 @@ radeon_add_legacy_connector(struct drm_device *dev,
 			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
 	} else
 		connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+	connector->polled |= DRM_CONNECTOR_POLL_FORCE;
+
 	connector->display_info.subpixel_order = subpixel_order;
 	drm_sysfs_connector_add(connector);
 	if (connector_type == DRM_MODE_CONNECTOR_LVDS) {
diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c
index ba055e9..838dc71 100644
--- a/drivers/gpu/drm/udl/udl_connector.c
+++ b/drivers/gpu/drm/udl/udl_connector.c
@@ -131,6 +131,8 @@ int udl_connector_init(struct drm_device *dev, struct drm_encoder *encoder)
 	drm_connector_init(dev, connector, &udl_connector_funcs, DRM_MODE_CONNECTOR_DVII);
 	drm_connector_helper_add(connector, &udl_connector_helper_funcs);
 
+	connector->polled |= DRM_CONNECTOR_POLL_FORCE;
+
 	drm_sysfs_connector_add(connector);
 	drm_mode_connector_attach_encoder(connector, encoder);
 
diff --git a/drivers/staging/omapdrm/omap_connector.c b/drivers/staging/omapdrm/omap_connector.c
index 5e2856c..bb8b134 100644
--- a/drivers/staging/omapdrm/omap_connector.c
+++ b/drivers/staging/omapdrm/omap_connector.c
@@ -358,6 +358,8 @@ struct drm_connector *omap_connector_init(struct drm_device *dev,
 	connector->interlace_allowed = 1;
 	connector->doublescan_allowed = 0;
 
+	connector->polled |= DRM_CONNECTOR_POLL_FORCE;
+
 	drm_sysfs_connector_add(connector);
 
 	return connector;
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index d59bb7d..4417da2 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -514,6 +514,10 @@ enum drm_connector_force {
 /* can cleanly poll for disconnections without flickering the screen */
 /* DACs should rarely do this without a lot of testing */
 #define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2)
+/* connector's ->detect function needs to be called when userspace forces
+ * detection. Should only be used if the detect function has special handling
+ * when force is set to avoid spurious re-reading of the edid. */
+#define DRM_CONNECTOR_POLL_FORCE (1 << 3)
 
 #define MAX_ELD_BYTES	128
 
-- 
1.7.7.6



More information about the dri-devel mailing list