MacBook Pro hybrid graphics use a gmux chip to switch DDC lines between gpus. It may register after the i915 driver, necessitating a reprobe of the connectors and reinitialization of the fbdev. Inspired by Matthew Garrett, who duplicated intel_setup_outputs() and reduced it to just the eDP probing portion (which is not sufficient since pre-retina MBPs used LVDS): http://www.codon.org.uk/~mjg59/tmp/retina_patches/0024-i915-Add-support-for-reprobing-for-a-panel.patch Commit 92122789b2d699a1e82dca502940e0dd37bf6f3b (drm/i915: preserve SSC if previously set v3) sets lvds_use_ssc to 0, it must be reset to 1 so that the SSC gets used on the panel. Signed-off-by: Lukas Wunner <lukas@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_dma.c | 40 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_display.c | 2 +- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 68e0c85..86726b7 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -379,9 +379,49 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev) return dev->open_count == 0; } +static void i915_switcheroo_reprobe_connectors(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_encoder *encoder; + + /* + * Check whether we've already found a panel. + * If so, we don't need to reprobe + */ + for_each_intel_encoder(dev, encoder) + if (encoder->type == INTEL_OUTPUT_LVDS || + encoder->type == INTEL_OUTPUT_EDP) + return; + + /* + * intel_modeset_gem_init() sets lvds_use_ssc to 0, + * reset to 1 so that the SSC gets used on the panel + */ + dev_priv->vbt.lvds_use_ssc = + !(i915.panel_use_ssc == 0 || + dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE); + intel_setup_outputs(dev); + + /* Destroy default 1024x768 fbdev and reinitialize */ + intel_fbdev_fini(dev); + if (intel_fbdev_init(dev)) + goto cleanup_gem; + async_schedule(intel_fbdev_initial_config, dev_priv); + return; + +cleanup_gem: + DRM_ERROR("failed to reinitialize fbdev\n"); + mutex_lock(&dev->struct_mutex); + i915_gem_cleanup_ringbuffer(dev); + i915_gem_context_fini(dev); + mutex_unlock(&dev->struct_mutex); +} + static const struct vga_switcheroo_client_ops i915_switcheroo_ops = { .set_gpu_state = i915_switcheroo_set_state, .reprobe = NULL, + .reprobe_connectors = i915_switcheroo_reprobe_connectors, .can_switch = i915_switcheroo_can_switch, }; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e326ac9..7f58858 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3120,6 +3120,7 @@ extern void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, extern void intel_detect_pch(struct drm_device *dev); extern int intel_trans_dp_port_sel(struct drm_crtc *crtc); extern int intel_enable_rc6(const struct drm_device *dev); +extern void intel_setup_outputs(struct drm_device *dev); extern bool i915_semaphore_is_enabled(struct drm_device *dev); int i915_reg_read_ioctl(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d547d9c8..9481206 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13027,7 +13027,7 @@ static bool intel_crt_present(struct drm_device *dev) return true; } -static void intel_setup_outputs(struct drm_device *dev) +void intel_setup_outputs(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_encoder *encoder; -- 1.8.5.2 (Apple Git-48) _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel