Signed-off-by: Chris Wilson <ch...@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 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx