[PATCH v2 20/22 EXPERIMENTAL] drm: Use vga_switcheroo active client as proxy when reading DDC/AUX

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The retina MacBook Pro uses an eDP panel and a gmux controller to switch
the panel between its two GPUs. Unfortunately it seems that it cannot
switch the AUX channel separately from the main link.

But we can emulate switching of DDC/AUX in software by using the active
client as a proxy to talk to the panel.

When reading the DPCD or EDID, store the struct drm_dp_aux and struct
i2c_adapter (for DDC) in vga_switcheroo. Retrieve the active client's
structures and use them in lieu of the client's own structures.

To avoid using proxying with external DP-connected displays, this is
constrained to eDP connectors and further constrained by vga_switcheroo
to its clients.

Based (loosely) on patches by Matthew Garrett <mjg59@xxxxxxxxxxxxx>
who used stashing instead of proxying and changed each driver rather
than the generic helper functions:
http://www.codon.org.uk/~mjg59/tmp/retina_patches/0025-i915-Use-vga_switcheroo-to-obtain-and-stash-EDID-DPC.patch
http://www.codon.org.uk/~mjg59/tmp/retina_patches/0026-nouveau-Use-vga_switcheroo-to-obtain-and-stash-EDID-.patch

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115
Tested-by: Paul Hordiienko <pvt.gord@xxxxxxxxx>
    [MBP  6,2 2010  intel ILK + nvidia GT216  pre-retina]
Tested-by: William Brown <william@xxxxxxxxxxxxxxxx>
    [MBP  8,2 2011  intel SNB + amd turks     pre-retina]
Tested-by: Lukas Wunner <lukas@xxxxxxxxx>
    [MBP  9,1 2012  intel IVB + nvidia GK107  pre-retina]
Tested-by: Bruno Bierbaumer <bruno@xxxxxxxxxxxxxx>
    [MBP 11,3 2013  intel HSW + nvidia GK107  retina -- work in progress]

Signed-off-by: Lukas Wunner <lukas@xxxxxxxxx>
---
 drivers/gpu/drm/drm_dp_helper.c | 14 ++++++++++++++
 drivers/gpu/drm/drm_edid.c      | 12 ++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 80a02a4..f34622f 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -27,6 +27,7 @@
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/i2c.h>
+#include <linux/vga_switcheroo.h>
 #include <drm/drm_dp_helper.h>
 #include <drm/drmP.h>
 
@@ -239,6 +240,19 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request,
 ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
 			 void *buffer, size_t size)
 {
+	struct pci_dev *pdev = to_pci_dev(aux->dev);
+	struct drm_dp_aux *proxy_aux;
+
+	if (aux->connector &&
+	    aux->connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+		vga_switcheroo_set_aux(pdev, aux);
+		proxy_aux = vga_switcheroo_get_aux(pdev);
+		if (proxy_aux && proxy_aux != aux) {
+			DRM_DEBUG_KMS("Using vga_switcheroo active client as proxy\n");
+			aux = proxy_aux;
+		}
+	}
+
 	return drm_dp_dpcd_access(aux, DP_AUX_NATIVE_READ, offset, buffer,
 				  size);
 }
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index cdb2fa1..b4b0e01 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1379,6 +1379,18 @@ struct edid *drm_get_edid(struct drm_connector *connector,
 {
 	struct edid *edid;
 	struct pci_dev *pdev = connector->dev->pdev;
+	struct i2c_adapter *proxy_ddc;
+
+	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
+	    connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+		vga_switcheroo_set_ddc(pdev, adapter);
+		proxy_ddc = vga_switcheroo_get_ddc(pdev);
+		if (proxy_ddc && proxy_ddc != adapter) {
+			DRM_DEBUG_KMS("Using vga_switcheroo active client as proxy\n");
+			adapter = proxy_ddc;
+			pdev = to_pci_dev(proxy_ddc->dev.parent);
+		}
+	}
 
 	vga_switcheroo_lock_ddc(pdev);
 
-- 
1.8.5.2 (Apple Git-48)

_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/dri-devel




[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux