drm/radeon: Switch DDC when reading the EDID
authorLukas Wunner <lukas@wunner.de>
Mon, 11 Jan 2016 19:09:20 +0000 (20:09 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 9 Feb 2016 10:21:11 +0000 (11:21 +0100)
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
if the vga_switcheroo handler is capable of temporarily switching
the panel's DDC lines to the discrete GPU. This allows us to retrieve
the EDID if the panel is currently muxed to the integrated GPU.

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, one of them AMD:
    [MBP  8,2 2011  intel SNB + amd turks     pre-retina  15"]
    [MBP  8,3 2011  intel SNB + amd turks     pre-retina  17"]

v3: Commit newly added due to introduction of drm_get_edid_switcheroo()
    wrapper which drivers need to opt-in to.

v5: Rebase on "vga_switcheroo: Add handler flags infrastructure",
    i.e. call drm_get_edid_switcheroo() only if the handler
    indicates that DDC is switchable.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=61115
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/dae71655e8c484fbef492d3389c157975f9622c9.1452525860.git.lukas@wunner.de
drivers/gpu/drm/radeon/radeon_connectors.c

index 340f3f549f295314788fbf9b3052880b8095a7f1..cfcc099c537d0475da7eb6d6ce4576cc7a116b98 100644 (file)
@@ -34,6 +34,7 @@
 #include "atom.h"
 
 #include <linux/pm_runtime.h>
+#include <linux/vga_switcheroo.h>
 
 static int radeon_dp_handle_hpd(struct drm_connector *connector)
 {
@@ -344,6 +345,11 @@ static void radeon_connector_get_edid(struct drm_connector *connector)
                else if (radeon_connector->ddc_bus)
                        radeon_connector->edid = drm_get_edid(&radeon_connector->base,
                                                              &radeon_connector->ddc_bus->adapter);
+       } else if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC &&
+                  connector->connector_type == DRM_MODE_CONNECTOR_LVDS &&
+                  radeon_connector->ddc_bus) {
+               radeon_connector->edid = drm_get_edid_switcheroo(&radeon_connector->base,
+                                                                &radeon_connector->ddc_bus->adapter);
        } else if (radeon_connector->ddc_bus) {
                radeon_connector->edid = drm_get_edid(&radeon_connector->base,
                                                      &radeon_connector->ddc_bus->adapter);