diff mbox series

[4/6] i915: implement vga-switcheroo reprobe() callback

Message ID 20200727205112.27698-5-ddadap@nvidia.com (mailing list archive)
State New, archived
Headers show
Series [1/6] vga-switcheroo: add new "immediate" switch event type | expand

Commit Message

Daniel Dadap July 27, 2020, 8:51 p.m. UTC
Add a vga-switcheroo callback for reprobing displays. Use this new
callback to retrain the link on all DP encoders after a mux switch.

Signed-off-by: Daniel Dadap <ddadap@nvidia.com>
---
 drivers/gpu/drm/i915/i915_switcheroo.c | 27 +++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/i915_switcheroo.c b/drivers/gpu/drm/i915/i915_switcheroo.c
index ed69b5d4a375..fa388de03cf6 100644
--- a/drivers/gpu/drm/i915/i915_switcheroo.c
+++ b/drivers/gpu/drm/i915/i915_switcheroo.c
@@ -7,6 +7,8 @@ 
 
 #include "i915_drv.h"
 #include "i915_switcheroo.h"
+#include "display/intel_display_types.h"
+#include "display/intel_dp.h"
 
 static void i915_switcheroo_set_state(struct pci_dev *pdev,
 				      enum vga_switcheroo_state state)
@@ -46,9 +48,32 @@  static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
 	return i915 && atomic_read(&i915->drm.open_count) == 0;
 }
 
+static void i915_switcheroo_reprobe(struct pci_dev *pdev)
+{
+	struct drm_i915_private *i915 = pdev_to_i915(pdev);
+	struct intel_encoder *encoder;
+
+	for_each_intel_dp(&i915->drm, encoder) {
+		int ret = -EDEADLK;
+		struct drm_modeset_acquire_ctx ctx;
+
+		drm_modeset_acquire_init(&ctx, 0);
+
+		while (ret == -EDEADLK) {
+			ret = intel_dp_retrain_link(encoder, &ctx);
+
+			if (ret == -EDEADLK)
+				drm_modeset_backoff(&ctx);
+		}
+
+		drm_modeset_drop_locks(&ctx);
+		drm_modeset_acquire_fini(&ctx);
+	}
+}
+
 static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
 	.set_gpu_state = i915_switcheroo_set_state,
-	.reprobe = NULL,
+	.reprobe = i915_switcheroo_reprobe,
 	.can_switch = i915_switcheroo_can_switch,
 };