[PATCH 10/11] drm/i915: Reprobe connectors if vga_switcheroo handler registers late

Lukas Wunner lukas at wunner.de
Sun Apr 19 08:01:17 PDT 2015


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 at wunner.de>
---
 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)



More information about the dri-devel mailing list