Some Apple hybrid graphics machines do not have the LVDS panel connected
to the integrated GPU at boot and also do not supply a VBT. The LVDS
connector is not registered as a result, making it impossible to support
graphics switching.

This patch changes intel_lvds_init() to register the connector even if
we can't find any panel modes. This makes it necessary to always check
intel_lvds->fixed_mode before use, as it could now be NULL.

Signed-off-by: Seth Forshee <seth.forshee at canonical.com>
---
 drivers/gpu/drm/i915/intel_lvds.c |   48 +++++++++++++++----------------------
 1 file changed, 19 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_lvds.c 
b/drivers/gpu/drm/i915/intel_lvds.c
index 5069137..c1ab632 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -161,6 +161,8 @@ static int intel_lvds_mode_valid(struct drm_connector 
*connector,
        struct intel_lvds *intel_lvds = intel_attached_lvds(connector);
        struct drm_display_mode *fixed_mode = intel_lvds->fixed_mode;

+       if (!fixed_mode)
+               return MODE_PANEL;
        if (mode->hdisplay > fixed_mode->hdisplay)
                return MODE_PANEL;
        if (mode->vdisplay > fixed_mode->vdisplay)
@@ -262,7 +264,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder 
*encoder,
         * with the panel scaling set up to source from the H/VDisplay
         * of the original mode.
         */
-       intel_fixed_panel_mode(intel_lvds->fixed_mode, adjusted_mode);
+       if (intel_lvds->fixed_mode)
+               intel_fixed_panel_mode(intel_lvds->fixed_mode, adjusted_mode);

        if (HAS_PCH_SPLIT(dev)) {
                intel_pch_panel_fitting(dev, intel_lvds->fitting_mode,
@@ -461,12 +464,13 @@ static int intel_lvds_get_modes(struct drm_connector 
*connector)
 {
        struct intel_lvds *intel_lvds = intel_attached_lvds(connector);
        struct drm_device *dev = connector->dev;
-       struct drm_display_mode *mode;
+       struct drm_display_mode *mode = NULL;

        if (intel_lvds->edid)
                return drm_add_edid_modes(connector, intel_lvds->edid);

-       mode = drm_mode_duplicate(dev, intel_lvds->fixed_mode);
+       if (intel_lvds->fixed_mode)
+               mode = drm_mode_duplicate(dev, intel_lvds->fixed_mode);
        if (mode == NULL)
                return 0;

@@ -1073,26 +1077,21 @@ bool intel_lvds_init(struct drm_device *dev)
         */

        /* Ironlake: FIXME if still fail, not try pipe mode now */
-       if (HAS_PCH_SPLIT(dev))
-               goto failed;
-
-       lvds = I915_READ(LVDS);
-       pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
-       crtc = intel_get_crtc_for_pipe(dev, pipe);
-
-       if (crtc && (lvds & LVDS_PORT_EN)) {
-               intel_lvds->fixed_mode = intel_crtc_mode_get(dev, crtc);
-               if (intel_lvds->fixed_mode) {
-                       intel_lvds->fixed_mode->type |=
-                               DRM_MODE_TYPE_PREFERRED;
-                       goto out;
+       if (!HAS_PCH_SPLIT(dev)) {
+               lvds = I915_READ(LVDS);
+               pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0;
+               crtc = intel_get_crtc_for_pipe(dev, pipe);
+
+               if (crtc && (lvds & LVDS_PORT_EN)) {
+                       intel_lvds->fixed_mode = intel_crtc_mode_get(dev, crtc);
+                       if (intel_lvds->fixed_mode) {
+                               intel_lvds->fixed_mode->type |=
+                                       DRM_MODE_TYPE_PREFERRED;
+                               goto out;
+                       }
                }
        }

-       /* If we still don't have a mode after all that, give up. */
-       if (!intel_lvds->fixed_mode)
-               goto failed;
-
 out:
        /*
         * Unlock registers and just
@@ -1116,13 +1115,4 @@ out:
        intel_panel_setup_backlight(dev);

        return true;
-
-failed:
-       DRM_DEBUG_KMS("No LVDS modes found, disabling.\n");
-       dev_priv->int_lvds_connector = NULL;
-       drm_connector_cleanup(connector);
-       drm_encoder_cleanup(encoder);
-       kfree(intel_lvds);
-       kfree(intel_connector);
-       return false;
 }
-- 
1.7.9.5

Reply via email to