[Intel-gfx] [PATCH 09/10] drm/i015: Share the EDID caching logic and mode query between LVDS and eDP

Chris Wilson chris at chris-wilson.co.uk
Fri Apr 22 11:19:17 CEST 2011


Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/intel_dp.c    |   54 +++++++++++++++++------------------
 drivers/gpu/drm/i915/intel_drv.h   |    3 ++
 drivers/gpu/drm/i915/intel_lvds.c  |   33 ++++++---------------
 drivers/gpu/drm/i915/intel_panel.c |   19 ++++++++++++
 4 files changed, 58 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 4c42f39..31b0774 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1622,37 +1622,14 @@ intel_dp_detect(struct drm_connector *connector, bool force)
 static int intel_dp_get_modes(struct drm_connector *connector)
 {
 	struct intel_dp *intel_dp = intel_attached_dp(connector);
-	struct drm_device *dev = intel_dp->base.base.dev;
-	int ret;
 
 	/* We should parse the EDID data and find out if it has an audio sink
 	 */
 
-	ret = intel_ddc_get_modes(connector, &intel_dp->adapter);
-	if (ret) {
-		if (is_edp(intel_dp) && !intel_dp->panel.fixed_mode) {
-			struct drm_display_mode *newmode;
-			list_for_each_entry(newmode, &connector->probed_modes,
-					    head) {
-				if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
-					intel_dp->panel.fixed_mode =
-						drm_mode_duplicate(dev, newmode);
-					break;
-				}
-			}
-		}
+	if (intel_dp->panel.connector)
+		return intel_panel_get_modes(&intel_dp->panel);
 
-		return ret;
-	}
-
-	/* if eDP has no EDID, try to use fixed panel mode from VBT */
-	if (intel_dp->panel.fixed_mode != NULL) {
-		struct drm_display_mode *mode;
-		mode = drm_mode_duplicate(dev, intel_dp->panel.fixed_mode);
-		drm_mode_probed_add(connector, mode);
-		return 1;
-	}
-	return 0;
+	return intel_ddc_get_modes(connector, &intel_dp->adapter);
 }
 
 static bool
@@ -1967,9 +1944,30 @@ intel_dp_init(struct drm_device *dev, int output_reg)
 
 	if (is_edp(intel_dp)) {
 		struct drm_display_mode *fixed_mode = NULL;
+		struct drm_display_mode *scan;
+		struct edid *edid;
+
+		edid = drm_get_edid(connector, &intel_dp->adapter);
+		if (edid) {
+			if (drm_add_edid_modes(connector, edid)) {
+				drm_mode_connector_update_edid_property(connector,
+									edid);
+			} else {
+				kfree(edid);
+				edid = NULL;
+			}
+		}
+
+		/* Downclock? */
+		list_for_each_entry(scan, &connector->probed_modes, head) {
+			if (scan->type & DRM_MODE_TYPE_PREFERRED) {
+				fixed_mode = drm_mode_duplicate(dev, scan);
+				break;
+			}
+		}
 
 		/* initialize panel mode from VBT if available for eDP */
-		if (dev_priv->lfp_lvds_vbt_mode) {
+		if (fixed_mode == NULL && dev_priv->lfp_lvds_vbt_mode) {
 			fixed_mode =
 				drm_mode_duplicate(dev,
 						   dev_priv->lfp_lvds_vbt_mode);
@@ -1979,7 +1977,7 @@ intel_dp_init(struct drm_device *dev, int output_reg)
 
 		intel_panel_init(&intel_dp->panel,
 				 intel_connector,
-				 fixed_mode);
+				 edid, fixed_mode);
 	}
 
 	intel_dp_add_properties(intel_dp, connector);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 09bfc6b0..b4e9e54 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -259,13 +259,16 @@ extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder);
 /* intel_panel.c */
 struct intel_panel {
 	struct intel_connector *connector;
+	struct edid *edid;
 	struct drm_display_mode *fixed_mode;
 	struct notifier_block lid_notifier;
 };
 extern int intel_panel_init(struct intel_panel *panel,
 			    struct intel_connector *connector,
+			    struct edid *edid,
 			    struct drm_display_mode *fixed_mode);
 extern void intel_panel_fini(struct intel_panel *panel);
+extern int intel_panel_get_modes(struct intel_panel *panel);
 
 extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
 				   struct drm_display_mode *adjusted_mode);
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 68f03ea..98e75d1 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -43,8 +43,6 @@ struct intel_lvds_connector {
 	struct intel_connector base;
 	struct intel_panel panel;
 
-	struct edid *edid;
-
 	int fitting_mode;
 };
 
@@ -492,18 +490,7 @@ intel_lvds_connector_detect(struct drm_connector *connector, bool force)
 static int intel_lvds_connector_get_modes(struct drm_connector *connector)
 {
 	struct intel_lvds_connector *lvds_connector = to_lvds_connector(connector);
-	struct drm_device *dev = connector->dev;
-	struct drm_display_mode *mode;
-
-	if (lvds_connector->edid)
-		return drm_add_edid_modes(connector, lvds_connector->edid);
-
-	mode = drm_mode_duplicate(dev, lvds_connector->panel.fixed_mode);
-	if (mode == NULL)
-		return 0;
-
-	drm_mode_probed_add(connector, mode);
-	return 1;
+	return intel_panel_get_modes(&lvds_connector->panel);
 }
 
 /**
@@ -787,6 +774,7 @@ bool intel_lvds_init(struct drm_device *dev)
 	struct drm_display_mode *scan; /* *modes, *bios_mode; */
 	struct drm_display_mode *fixed_mode = NULL;
 	struct drm_crtc *crtc;
+	struct edid *edid;
 	u32 lvds;
 	int pipe;
 	u8 pin;
@@ -884,18 +872,17 @@ bool intel_lvds_init(struct drm_device *dev)
 	 * Attempt to get the fixed panel mode from DDC.  Assume that the
 	 * preferred mode is the right one.
 	 */
-	lvds_connector->edid = drm_get_edid(connector,
-					    &dev_priv->gmbus[pin].adapter);
-	if (lvds_connector->edid) {
-		if (drm_add_edid_modes(connector, lvds_connector->edid)) {
+	edid = drm_get_edid(connector, &dev_priv->gmbus[pin].adapter);
+	if (edid) {
+		if (drm_add_edid_modes(connector, edid)) {
 			drm_mode_connector_update_edid_property(connector,
-								lvds_connector->edid);
+								edid);
 		} else {
-			kfree(lvds_connector->edid);
-			lvds_connector->edid = NULL;
+			kfree(edid);
+			edid = NULL;
 		}
 	}
-	if (!lvds_connector->edid) {
+	if (!edid) {
 		/* Didn't get an EDID, so
 		 * Set wide sync ranges so we get all modes
 		 * handed to valid_mode for checking
@@ -991,7 +978,7 @@ out:
 
 	intel_panel_init(&lvds_connector->panel,
 			 &lvds_connector->base,
-			 fixed_mode);
+			 edid, fixed_mode);
 	drm_sysfs_connector_add(connector);
 	return true;
 
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index b7329be..b49aad7 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -185,9 +185,11 @@ static int intel_panel_lid_notify(struct notifier_block *nb, unsigned long val,
 
 int intel_panel_init(struct intel_panel *panel,
 		     struct intel_connector *connector,
+		     struct edid *edid,
 		     struct drm_display_mode *fixed_mode)
 {
 	panel->connector = connector;
+	panel->edid = edid;
 	panel->fixed_mode = fixed_mode;
 
 	panel->lid_notifier.notifier_call = intel_panel_lid_notify;
@@ -209,6 +211,23 @@ void intel_panel_fini(struct intel_panel *panel)
 				 panel->fixed_mode);
 }
 
+int intel_panel_get_modes(struct intel_panel *panel)
+{
+	struct drm_connector *connector = &panel->connector->base;
+	struct drm_device *dev = connector->dev;
+	struct drm_display_mode *mode;
+
+	if (panel->edid)
+		return drm_add_edid_modes(connector, panel->edid);
+
+	mode = drm_mode_duplicate(dev, panel->fixed_mode);
+	if (mode == NULL)
+		return 0;
+
+	drm_mode_probed_add(connector, mode);
+	return 1;
+}
+
 /* Panel backlight controls */
 
 static int is_backlight_combination_mode(struct drm_device *dev)
-- 
1.7.4.1




More information about the Intel-gfx mailing list