From patchwork Fri Sep 1 07:27:43 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Axtens X-Patchwork-Id: 9933687 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 5DB4F6038C for ; Fri, 1 Sep 2017 07:39:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4550528583 for ; Fri, 1 Sep 2017 07:39:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 39BD92858A; Fri, 1 Sep 2017 07:39:56 +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,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C71AD28585 for ; Fri, 1 Sep 2017 07:39:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=OL/vGhg4WyXpf8fNPElHFKo+SCku/T2RgillfPWCkMo=; b=siNsmRdE8yEC98Loye4G27xUkO tnHX/w4Ao82Fj5bw2LMYYxo8p/NPoIdz0583+fBFJMEJ+8WJhRXx4RrsyCcREHDmvblrdF6sC/fF5 Yu2IT2EdpH4E0TJGov9/Pi7i+ObQdhxRHAT+25CB20g6/tWxrKKYNEEdpaaM2AuosRqy/OKHkKp8b Zt8vLm9G0R8pN09veJv8oXRDOUhPGwSyR/fgIpFwbnIp4bY6kJJ4oLVe2f5nY5xbnxQSX9/Wp4n38 kGksBKZn7bwW5f12Vm7UwE9j5/1y1qbUHNDV/zOZit6ym0j2d5iQE1jDn8vL9fz8akLTrtBdNoQvN N/Y/ufWQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dngY9-0001Fn-Jp; Fri, 01 Sep 2017 07:39:33 +0000 Received: from mail-pg0-x241.google.com ([2607:f8b0:400e:c05::241]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dngNl-0002SD-Nx for linux-arm-kernel@lists.infradead.org; Fri, 01 Sep 2017 07:28:57 +0000 Received: by mail-pg0-x241.google.com with SMTP id 63so1249655pgc.1 for ; Fri, 01 Sep 2017 00:28:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axtens.net; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=wnD4PPKKYv/V53yhQhN0UzLmztzhzz/GAnd2khbo4L8=; b=ByoVjlt3ySIGfavIGSU2wdm95L+g9XCtiJou+7cMIlFr/nV9K/7smV7uuI3wtZ1dRa 9FXxW8OZ2mzowpEQRfEB/TlyV7Ps2Ta5IE9RWJ6J21O0gkb/Prbt7/mX+fUUKw/g1j7X HN/k2IDrr4pLPWzOtRiuODoxOzLi8ZzVY1oY4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=wnD4PPKKYv/V53yhQhN0UzLmztzhzz/GAnd2khbo4L8=; b=OwFSXJ20/D/u7EKqi7V0jd7kNvGzaY1swgn3NgPQ8QHEdUSsTe0GS0JEPftEh5zJfh t5X3Ap8JOkaZV/AsCG73TtajoDycEKtA4f9F0QCmXZQ8EdW50Q933aLIrmcooTo/AxcQ 6moYNyrnNE+u2KqWz7vszd5wuMgIbK/nSTY2e4y5rf/IOekZkRsJXLPplxxeAfMh68hB ZvWzXmHobKt57y2mGVPgJofEBjrvNdtpSKg4MykMvP6X6W5FyWlvx51YH2Sp05JSI14q SHWqpdgDvkd9Eha4Y/x59N/vSBtAUKXvlpePi78O1cfEOZRGr9RQF0s3BuWk46+b34eu A4KA== X-Gm-Message-State: AHPjjUiUGICLmPZ2/+NM/c2EjjLX8p82GOwFg2CYO8d1oo4SDNpKBU8X ChKLZWz0pLvzBwrp X-Google-Smtp-Source: ADKCNb5G47z8NOzuV/WeooAYxaoGWu6SXt4g8gRYioqvc5CB27cgtFx6+P+cIgy9IkCwU5+OzPvTsg== X-Received: by 10.98.59.11 with SMTP id i11mr1242701pfa.237.1504250912740; Fri, 01 Sep 2017 00:28:32 -0700 (PDT) Received: from localhost.localdomain (124-171-202-56.dyn.iinet.net.au. [124.171.202.56]) by smtp.gmail.com with ESMTPSA id l30sm2430300pgc.61.2017.09.01.00.28.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Sep 2017 00:28:32 -0700 (PDT) From: Daniel Axtens To: linux-pci@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH v3 2/3] drm: add fallback default device detection Date: Fri, 1 Sep 2017 17:27:43 +1000 Message-Id: <20170901072744.2409-3-dja@axtens.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170901072744.2409-1-dja@axtens.net> References: <20170901072744.2409-1-dja@axtens.net> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170901_002850_039740_207E4CDB X-CRM114-Status: GOOD ( 19.97 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lorenzo.pieralisi@arm.com, gabriele.paoloni@huawei.com, ard.biesheuvel@linaro.org, airlied@linux.ie, benh@kernel.crashing.org, will.deacon@arm.com, dri-devel@lists.freedesktop.org, z.liuxinliang@hisilicon.com, alex.williamson@redhat.com, lukas@wunner.de, helgaas@kernel.org, catalin.marinas@arm.com, zourongrong@gmail.com, daniel.vetter@intel.com, Daniel Axtens MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The VGA arbiter selects a default VGA device that is enabled and reachable via the legacy VGA resources (mem 0xa0000-0xbffff, io 0x3b0-0x3bb, io 0x3c0-0x3df, etc). (As a special case for x86 and IA64, this can be overridden by EFI.) If there is no such device, e.g., because there's no enabled VGA device, the host bridge doesn't support access to those legacy resources, or a PCI-PCI bridge doesn't have VGA Enable set, a platform may select an arbitrary device by calling pci_set_default_display(). powerpc does this, for example. If there is also no platform hook, there will be no default device nominated. This is not necessarily what we want. Add handling for devices that aren't handled by the vga arbiter or platform by adding a late initcall and a class enable hook. If there is no default from vgaarb or the platform then the first VGA card that is enabled, has a driver bound, and can decode memory or I/O will be marked as default. This means single-card setups on systems without access to legacy areas and without arch hooks will work. Multi-card setups on these systems will nominate an arbitrary device, rather than no devices. Signed-off-by: Daniel Axtens Tested-by: Andrew Donnellan --- v3: Split out from re-organisation for simplicity. Add better description and better documentaion. Thanks to (in no particular order), Daniel Vetter, Lorenzo Pieralisi, Ard Biesheuvel and Dave Airlie. Special thanks to Ben Herrenschmidt and Bjorn Helgass, whose prose I have borrowed. v1: Tested on: - x86_64 laptop - arm64 D05 board with hibmc card - qemu powerpc with tcg and bochs std-vga I know this adds another config option and that's a bit sad, but we can't include it unconditionally as it depends on PCI. Suggestions welcome. --- drivers/gpu/vga/default_display.c | 77 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/drivers/gpu/vga/default_display.c b/drivers/gpu/vga/default_display.c index 99e4723360da..b8e4a5af38e8 100644 --- a/drivers/gpu/vga/default_display.c +++ b/drivers/gpu/vga/default_display.c @@ -42,6 +42,10 @@ * * 2) Anything specified by an arch hook, * e.g. arch/powerpc/kernel/pci-common.c::fixup_vga() + * + * 3) If neither of those, then we still want to pick something. For + * now, pick the first PCI VGA device with a driver bound and with + * memory or I/O control on. */ #include @@ -53,6 +57,12 @@ static struct pci_dev *vga_default; +/* + * only go active after the late initcall so as not to interfere with + * the arbiter + */ +static bool vga_default_active = false; + /** * pci_default_display - return the default display device * @@ -84,3 +94,70 @@ void pci_set_default_display(struct pci_dev *pdev) pci_dev_put(vga_default); vga_default = pci_dev_get(pdev); } + +static bool vga_default_try_device(struct pci_dev *pdev) +{ + u16 cmd; + + /* Only deal with VGA class devices */ + if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) + return false; + + /* Only deal with devices with drivers bound */ + if (!pdev->driver) + return false; + + /* Require I/O or memory control */ + pci_read_config_word(pdev, PCI_COMMAND, &cmd); + if (!(cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY))) + return false; + + dev_info(&pdev->dev, "vga_default: setting as default device\n"); + pci_set_default_display(pdev); + return true; +} + +static int __init vga_default_init(void) +{ + struct pci_dev *pdev; + + vga_default_active = true; + + if (pci_default_display()) + return 0; + + pdev = NULL; + while ((pdev = + pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_ANY_ID, pdev)) != NULL) { + if (vga_default_try_device(pdev)) + return 0; + } + + return 0; +} +late_initcall(vga_default_init); + +/* + * A driver could be loaded much later than late_initcall, for example + * if it's in a module. + * + * We want to pick that up. However, we want to make sure this does + * not interfere with the arbiter - it should only activate if the + * arbiter has already had a chance to operate. To ensure this, we set + * vga_default_active in the late_initcall: as the vga arbiter is a + * subsys initcall, it is guaranteed to fire first. + */ +static void vga_default_enable_hook(struct pci_dev *pdev) +{ + if (!vga_default_active) + return; + + if (pci_default_display()) + return; + + vga_default_try_device(pdev); +} +DECLARE_PCI_FIXUP_CLASS_ENABLE(PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_DISPLAY_VGA, 8, + vga_default_enable_hook)