From patchwork Fri Feb 24 19:19:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Wunner X-Patchwork-Id: 9591065 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0F75B6020A for ; Fri, 24 Feb 2017 19:30:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F133E2877F for ; Fri, 24 Feb 2017 19:30:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E5D5D28931; Fri, 24 Feb 2017 19:30:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 924B82877F for ; Fri, 24 Feb 2017 19:30:57 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C97B16ECFC; Fri, 24 Feb 2017 19:30:55 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org X-Greylist: delayed 640 seconds by postgrey-1.35 at gabe; Fri, 24 Feb 2017 19:30:54 UTC Received: from mailout2.hostsharing.net (mailout2.hostsharing.net [83.223.90.233]) by gabe.freedesktop.org (Postfix) with ESMTPS id 150F66ECFA for ; Fri, 24 Feb 2017 19:30:54 +0000 (UTC) Received: from h08.hostsharing.net (h08.hostsharing.net [83.223.95.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mailout2.hostsharing.net (Postfix) with ESMTPS id BD0DF1037F6B9; Fri, 24 Feb 2017 20:20:10 +0100 (CET) Received: from localhost (5-38-90-81.adsl.cmo.de [81.90.38.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by h08.hostsharing.net (Postfix) with ESMTPSA id DB7016045F79; Fri, 24 Feb 2017 20:20:08 +0100 (CET) X-Mailbox-Line: From 8c06c7eaf3d4a6ec3e2d75191ef26ebd554c24db Mon Sep 17 00:00:00 2001 Message-Id: <8c06c7eaf3d4a6ec3e2d75191ef26ebd554c24db.1487938188.git.lukas@wunner.de> In-Reply-To: References: From: Lukas Wunner Date: Fri, 24 Feb 2017 20:19:45 +0100 Subject: [PATCH 2/5] apple-gmux: Don't switch external DP port on 2011+ MacBook Pros To: dri-devel@lists.freedesktop.org Cc: Bjorn Helgaas , Darren Hart , Andy Shevchenko , platform-driver-x86@vger.kernel.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP On MacBook Pros introduced 2011 and onward, external DP ports are combined DP/Thunderbolt ports that are no longer fully switchable between GPUs, they can only be driven by the discrete GPU. More specifically, the Main Link pins (which transport the actual video and audio streams) are soldered to the discrete GPU, whereas the AUX Channel pins are switchable. Because the integrated GPU is missing the Main Link, external displays appear to it as phantoms which fail to link-train. Force the AUX channel to the discrete GPU on these models to avoid any confusion. Document the switching policy implemented by this commit. Signed-off-by: Lukas Wunner --- drivers/platform/x86/apple-gmux.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index a66be137324c..623d322447a2 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c @@ -60,6 +60,7 @@ struct apple_gmux_data { /* switcheroo data */ acpi_handle dhandle; int gpe; + bool external_switchable; enum vga_switcheroo_client_id switch_state_display; enum vga_switcheroo_client_id switch_state_ddc; enum vga_switcheroo_client_id switch_state_external; @@ -358,6 +359,19 @@ static const struct backlight_ops gmux_bl_ops = { * ports while the discrete GPU is asleep, but currently we do not make use * of this feature. * + * Our switching policy for the external port is that on those generations + * which are able to switch it fully, the port is switched together with the + * panel when IGD / DIS commands are issued to vga_switcheroo. It is thus + * possible to drive e.g. a beamer on battery power with the integrated GPU. + * The user may manually switch to the discrete GPU if more performance is + * needed. + * + * On all newer generations, the external port can only be driven by the + * discrete GPU. If a display is plugged in while the panel is switched to + * the integrated GPU, *both* GPUs will be in use for maximum performance. + * To decrease power consumption, the user may manually switch to the + * discrete GPU, thereby suspending the integrated GPU. + * * gmux' initial switch state on bootup is user configurable via the EFI * variable ``gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9`` (5th byte, * 1 = IGD, 0 = DIS). Based on this setting, the EFI firmware tells gmux to @@ -414,7 +428,8 @@ static int gmux_switchto(enum vga_switcheroo_client_id id) { apple_gmux_data->switch_state_ddc = id; apple_gmux_data->switch_state_display = id; - apple_gmux_data->switch_state_external = id; + if (apple_gmux_data->external_switchable) + apple_gmux_data->switch_state_external = id; gmux_write_switch_state(apple_gmux_data); @@ -601,6 +616,11 @@ static struct pci_dev *gmux_get_io_pdev(void) return NULL; } +static int is_thunderbolt(struct device *dev, void *data) +{ + return to_pci_dev(dev)->is_thunderbolt; +} + static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) { struct apple_gmux_data *gmux_data; @@ -755,6 +775,15 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) gmux_data->gpe = -1; } + /* + * If Thunderbolt is present, the external DP port is not fully + * switchable. Force its AUX channel to the discrete GPU. + */ + gmux_data->external_switchable = + !bus_for_each_dev(&pci_bus_type, NULL, NULL, is_thunderbolt); + if (!gmux_data->external_switchable) + gmux_write8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3); + apple_gmux_data = gmux_data; init_completion(&gmux_data->powerchange_done); gmux_enable_interrupts(gmux_data);