Lukas Wunner
2015-Oct-12 17:14 UTC
[Nouveau] [PATCH v4 0/6] Enable gpu switching on the MacBook Pro
Changes since v3:
* Previously when switching the display, the DDC lines were switched
as well. But actually this is not necessary: If a GPU probes EDID,
DDC must be switched and locked to the GPU anyway, so why switch
DDC preemptively? Also, previously the DDC lines were switched back
to the previous owner on unlock. This is unnecessary for the same
reason. So I did away with all that and it simplifies the code
considerably. This works fine as long as anything accessing DDC
calls vga_switcheroo_lock_ddc() first. If something in the kernel
or a VM or in user space accesses DDC and omits locking it first,
things may go awry. (However, if locking is omitted, things could
go awry with the previous behaviour as well.) I'm curious if this
new behaviour provokes objections.
* I now have conclusive evidence that only the pre-retina MacBook Pro
can switch DDC. The mux in the retina is incapable of that. So the
->switch_ddc callback is no longer advertised to vga_switcheroo
on retinas.
Also available on GitHub for easier reviewing:
https://github.com/l1k/linux/commits/mbp_switcheroo_v4
For those who haven't been following this series so far:
The pre-retina MacBook Pro uses an LVDS panel and a gmux controller
to switch the panel between its two GPUs. The panel mode in VBIOS
is notoriously bogus on these machines and some models have no
VBIOS at all, so the inactive GPU cannot set up its LVDS output.
Extend vga_switcheroo to support switching only the DDC lines.
Introduce a drm_get_edid_switcheroo() helper which uses this feature.
Amend i915, nouveau and radeon to call it for LVDS connectors.
This only enables EDID probing on the pre-retina MBP (2008 - 2013),
and only under the condition that apple-gmux loads before the DRM
drivers. Later patches will address reprobing of the DRM drivers
if apple-gmux loads late.
The retina MBP (2012 - present) uses eDP and is apparently not
capable of switching AUX separately from the main link.
This will also be addressed in later patches.
Previous installments:
v1: http://lists.freedesktop.org/archives/dri-devel/2015-April/081515.html
v2: http://lists.freedesktop.org/archives/dri-devel/2015-August/088156.html
v3: http://lists.freedesktop.org/archives/dri-devel/2015-October/091741.html
Lukas Wunner (6):
vga_switcheroo: Add support for switching only the DDC
apple-gmux: Add switch_ddc support
drm/edid: Switch DDC when reading the EDID
drm/i915: Switch DDC when reading the EDID
drm/nouveau: Switch DDC when reading the EDID
drm/radeon: Switch DDC when reading the EDID
drivers/gpu/drm/drm_edid.c | 26 ++++++++++++
drivers/gpu/drm/i915/intel_lvds.c | 3 +-
drivers/gpu/drm/nouveau/nouveau_connector.c | 13 +++++-
drivers/gpu/drm/radeon/radeon_connectors.c | 4 ++
drivers/gpu/vga/vga_switcheroo.c | 66 ++++++++++++++++++++++++++++-
drivers/platform/x86/apple-gmux.c | 21 ++++++++-
include/drm/drm_crtc.h | 2 +
include/linux/vga_switcheroo.h | 15 +++++--
8 files changed, 141 insertions(+), 9 deletions(-)
--
1.8.5.2 (Apple Git-48)
Lukas Wunner
2015-Oct-12 18:37 UTC
[Nouveau] [PATCH v4 5/6] drm/nouveau: Switch DDC when reading the EDID
The pre-retina MacBook Pro uses an LVDS panel and a gmux controller
to switch the panel between its two GPUs. The panel mode in VBIOS
is notoriously bogus on these machines.
Use drm_get_edid_switcheroo() in lieu of drm_get_edid() on LVDS.
This allows us to retrieve the EDID if the outputs are currently
muxed to the other GPU by temporarily switching the panel's DDC
lines. Likewise, ask vga_switcheroo to switch DDC before probing
LVDS connectors.
This only enables EDID probing on the pre-retina MBP (2008 - 2013).
The retina MBP (2012 - present) uses eDP and gmux is not capable
of switching AUX separately from the main link on these models.
This will be addressed in later patches.
List of pre-retina MBPs with dual GPUs, either or both Nvidia:
[MBP 5,1 2008 nvidia MCP79 + G96 pre-retina 15"]
[MBP 5,2 2009 nvidia MCP79 + G96 pre-retina 17"]
[MBP 5,3 2009 nvidia MCP79 + G96 pre-retina 15"]
[MBP 6,2 2010 intel ILK + nvidia GT216 pre-retina 15"]
[MBP 6,1 2010 intel ILK + nvidia GT216 pre-retina 17"]
[MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina 15"]
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88861
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115
Tested-by: Lukas Wunner <lukas at wunner.de>
[MBP 9,1 2012 intel IVB + nvidia GK107 pre-retina 15"]
Signed-off-by: Lukas Wunner <lukas at wunner.de>
---
drivers/gpu/drm/nouveau/nouveau_connector.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c
b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 2e7cbe9..fb12c9e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -27,6 +27,7 @@
#include <acpi/button.h>
#include <linux/pm_runtime.h>
+#include <linux/vga_switcheroo.h>
#include <drm/drmP.h>
#include <drm/drm_edid.h>
@@ -148,7 +149,13 @@ nouveau_connector_ddc_detect(struct drm_connector
*connector)
break;
} else
if (nv_encoder->i2c) {
- if (nvkm_probe_i2c(nv_encoder->i2c, 0x50))
+ int ret;
+ if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS)
+ vga_switcheroo_lock_ddc(dev->pdev);
+ ret = nvkm_probe_i2c(nv_encoder->i2c, 0x50);
+ if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS)
+ vga_switcheroo_unlock_ddc();
+ if (ret)
break;
}
}
@@ -259,7 +266,9 @@ nouveau_connector_detect(struct drm_connector *connector,
bool force)
nv_encoder = nouveau_connector_ddc_detect(connector);
if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) {
- nv_connector->edid = drm_get_edid(connector, i2c);
+ nv_connector->edid = nv_encoder->dcb->type == DCB_OUTPUT_LVDS ?
+ drm_get_edid_switcheroo(connector, i2c) :
+ drm_get_edid(connector, i2c);
drm_mode_connector_update_edid_property(connector,
nv_connector->edid);
if (!nv_connector->edid) {
--
1.8.5.2 (Apple Git-48)