[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