From: Bjorn Helgaas <helgaas@kernel.org> To: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>, Maxime Ripard <mripard@kernel.org>, Thomas Zimmermann <tzimmermann@suse.de> Cc: David Airlie <airlied@linux.ie>, Daniel Vetter <daniel@ffwll.ch>, Xuefeng Li <lixuefeng@loongson.cn>, Huacai Chen <chenhuacai@loongson.cn>, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Daniel Axtens <dja@axtens.net>, Zhou Wang <wangzhou1@hisilicon.com> Subject: [PATCH v9 06/11] PCI/VGA: Move non-legacy VGA detection to ADD_DEVICE path Date: Thu, 24 Feb 2022 16:47:48 -0600 [thread overview] Message-ID: <20220224224753.297579-7-helgaas@kernel.org> (raw) In-Reply-To: <20220224224753.297579-1-helgaas@kernel.org> From: Huacai Chen <chenhuacai@loongson.cn> a37c0f48950b ("vgaarb: Select a default VGA device even if there's no legacy VGA") extended the vga_arb_device_init() subsys_initcall so it could select a non-legacy VGA device as the default. That failed to consider that PCI devices may be enumerated after vga_arb_device_init(), e.g., hot-added devices or non-ACPI systems that do PCI enumeration in pcibios_init(). Devices found then could never be selected as the default. One system where this is a problem is the MIPS-based Loongson where an ASpeed AST2500 VGA device is behind a bridge that doesn't implement the VGA Enable bit, so legacy resources are not routed to the VGA device. [1] Fix this by moving the non-legacy VGA device selection from vga_arb_select_default_device() to vga_arbiter_add_pci_device(), which is called after every PCI device is enumerated, either by the vga_arb_device_init() subsys_initcall or as an ADD_DEVICE notifier. [1] https://lore.kernel.org/r/20210514080025.1828197-6-chenhuacai@loongson.cn [bhelgaas: commit log, restructure] Link: https://lore.kernel.org/r/20211015061512.2941859-5-chenhuacai@loongson.cn Link: https://lore.kernel.org/r/20211015061512.2941859-7-chenhuacai@loongson.cn Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> Cc: Daniel Axtens <dja@axtens.net> Cc: Zhou Wang <wangzhou1@hisilicon.com> --- drivers/pci/vgaarb.c | 54 ++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c index c3323ab4f98e..e36ccbfdbd89 100644 --- a/drivers/pci/vgaarb.c +++ b/drivers/pci/vgaarb.c @@ -624,6 +624,7 @@ static bool vga_is_boot_device(struct vga_device *vgadev) { struct vga_device *boot_vga = vgadev_find(vga_default_device()); struct pci_dev *pdev = vgadev->pdev; + u16 cmd, boot_cmd; /* * We select the default VGA device in this order: @@ -661,6 +662,37 @@ static bool vga_is_boot_device(struct vga_device *vgadev) if ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK) return true; + /* + * If we haven't found a legacy VGA device, accept a non-legacy + * device. It may have either IO or MEM enabled, and bridges may + * not have PCI_BRIDGE_CTL_VGA enabled, so it may not be able to + * use legacy VGA resources. Prefer an integrated GPU over others. + */ + pci_read_config_word(pdev, PCI_COMMAND, &cmd); + if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { + + /* + * An integrated GPU overrides a previous non-legacy + * device. We expect only a single integrated GPU, but if + * there are more, we use the *last* because that was the + * previous behavior. + */ + if (vga_arb_integrated_gpu(&pdev->dev)) + return true; + + /* + * We prefer the first non-legacy discrete device we find. + * If we already found one, vgadev is no better. + */ + if (boot_vga) { + pci_read_config_word(boot_vga->pdev, PCI_COMMAND, + &boot_cmd); + if (boot_cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) + return false; + } + return true; + } + return false; } @@ -1529,30 +1561,8 @@ static struct miscdevice vga_arb_device = { static void __init vga_arb_select_default_device(void) { - struct pci_dev *pdev, *found = NULL; struct vga_device *vgadev; - if (!vga_default_device()) { - list_for_each_entry_reverse(vgadev, &vga_list, list) { - struct device *dev = &vgadev->pdev->dev; - u16 cmd; - - pdev = vgadev->pdev; - pci_read_config_word(pdev, PCI_COMMAND, &cmd); - if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { - found = pdev; - if (vga_arb_integrated_gpu(dev)) - break; - } - } - } - - if (found) { - vgaarb_info(&found->dev, "setting as boot device (VGA legacy resources not available)\n"); - vga_set_default_device(found); - return; - } - if (!vga_default_device()) { vgadev = list_first_entry_or_null(&vga_list, struct vga_device, list); -- 2.25.1
WARNING: multiple messages have this Message-ID (diff)
From: Bjorn Helgaas <helgaas@kernel.org> To: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>, Maxime Ripard <mripard@kernel.org>, Thomas Zimmermann <tzimmermann@suse.de> Cc: David Airlie <airlied@linux.ie>, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Zhou Wang <wangzhou1@hisilicon.com>, Daniel Axtens <dja@axtens.net>, Xuefeng Li <lixuefeng@loongson.cn>, Huacai Chen <chenhuacai@loongson.cn> Subject: [PATCH v9 06/11] PCI/VGA: Move non-legacy VGA detection to ADD_DEVICE path Date: Thu, 24 Feb 2022 16:47:48 -0600 [thread overview] Message-ID: <20220224224753.297579-7-helgaas@kernel.org> (raw) In-Reply-To: <20220224224753.297579-1-helgaas@kernel.org> From: Huacai Chen <chenhuacai@loongson.cn> a37c0f48950b ("vgaarb: Select a default VGA device even if there's no legacy VGA") extended the vga_arb_device_init() subsys_initcall so it could select a non-legacy VGA device as the default. That failed to consider that PCI devices may be enumerated after vga_arb_device_init(), e.g., hot-added devices or non-ACPI systems that do PCI enumeration in pcibios_init(). Devices found then could never be selected as the default. One system where this is a problem is the MIPS-based Loongson where an ASpeed AST2500 VGA device is behind a bridge that doesn't implement the VGA Enable bit, so legacy resources are not routed to the VGA device. [1] Fix this by moving the non-legacy VGA device selection from vga_arb_select_default_device() to vga_arbiter_add_pci_device(), which is called after every PCI device is enumerated, either by the vga_arb_device_init() subsys_initcall or as an ADD_DEVICE notifier. [1] https://lore.kernel.org/r/20210514080025.1828197-6-chenhuacai@loongson.cn [bhelgaas: commit log, restructure] Link: https://lore.kernel.org/r/20211015061512.2941859-5-chenhuacai@loongson.cn Link: https://lore.kernel.org/r/20211015061512.2941859-7-chenhuacai@loongson.cn Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> Cc: Daniel Axtens <dja@axtens.net> Cc: Zhou Wang <wangzhou1@hisilicon.com> --- drivers/pci/vgaarb.c | 54 ++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c index c3323ab4f98e..e36ccbfdbd89 100644 --- a/drivers/pci/vgaarb.c +++ b/drivers/pci/vgaarb.c @@ -624,6 +624,7 @@ static bool vga_is_boot_device(struct vga_device *vgadev) { struct vga_device *boot_vga = vgadev_find(vga_default_device()); struct pci_dev *pdev = vgadev->pdev; + u16 cmd, boot_cmd; /* * We select the default VGA device in this order: @@ -661,6 +662,37 @@ static bool vga_is_boot_device(struct vga_device *vgadev) if ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK) return true; + /* + * If we haven't found a legacy VGA device, accept a non-legacy + * device. It may have either IO or MEM enabled, and bridges may + * not have PCI_BRIDGE_CTL_VGA enabled, so it may not be able to + * use legacy VGA resources. Prefer an integrated GPU over others. + */ + pci_read_config_word(pdev, PCI_COMMAND, &cmd); + if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { + + /* + * An integrated GPU overrides a previous non-legacy + * device. We expect only a single integrated GPU, but if + * there are more, we use the *last* because that was the + * previous behavior. + */ + if (vga_arb_integrated_gpu(&pdev->dev)) + return true; + + /* + * We prefer the first non-legacy discrete device we find. + * If we already found one, vgadev is no better. + */ + if (boot_vga) { + pci_read_config_word(boot_vga->pdev, PCI_COMMAND, + &boot_cmd); + if (boot_cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) + return false; + } + return true; + } + return false; } @@ -1529,30 +1561,8 @@ static struct miscdevice vga_arb_device = { static void __init vga_arb_select_default_device(void) { - struct pci_dev *pdev, *found = NULL; struct vga_device *vgadev; - if (!vga_default_device()) { - list_for_each_entry_reverse(vgadev, &vga_list, list) { - struct device *dev = &vgadev->pdev->dev; - u16 cmd; - - pdev = vgadev->pdev; - pci_read_config_word(pdev, PCI_COMMAND, &cmd); - if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { - found = pdev; - if (vga_arb_integrated_gpu(dev)) - break; - } - } - } - - if (found) { - vgaarb_info(&found->dev, "setting as boot device (VGA legacy resources not available)\n"); - vga_set_default_device(found); - return; - } - if (!vga_default_device()) { vgadev = list_first_entry_or_null(&vga_list, struct vga_device, list); -- 2.25.1
next prev parent reply other threads:[~2022-02-24 22:48 UTC|newest] Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-02-24 22:47 [PATCH v9 00/11] vgaarb: Rework default VGA device selection Bjorn Helgaas 2022-02-24 22:47 ` Bjorn Helgaas 2022-02-24 22:47 ` [PATCH v9 01/11] PCI/VGA: Move vgaarb to drivers/pci Bjorn Helgaas 2022-02-24 22:47 ` Bjorn Helgaas 2022-02-24 22:47 ` [PATCH v9 02/11] PCI/VGA: Move vga_arb_integrated_gpu() earlier in file Bjorn Helgaas 2022-02-24 22:47 ` Bjorn Helgaas 2022-02-24 22:47 ` [PATCH v9 03/11] PCI/VGA: Factor out vga_select_framebuffer_device() Bjorn Helgaas 2022-02-24 22:47 ` Bjorn Helgaas 2022-02-24 22:47 ` [PATCH v9 04/11] PCI/VGA: Factor out default VGA device selection Bjorn Helgaas 2022-02-24 22:47 ` Bjorn Helgaas 2022-02-24 22:47 ` [PATCH v9 05/11] PCI/VGA: Move firmware default device detection to ADD_DEVICE path Bjorn Helgaas 2022-02-24 22:47 ` Bjorn Helgaas 2022-02-24 22:47 ` Bjorn Helgaas [this message] 2022-02-24 22:47 ` [PATCH v9 06/11] PCI/VGA: Move non-legacy VGA " Bjorn Helgaas 2022-02-24 22:47 ` [PATCH v9 07/11] PCI/VGA: Move disabled VGA device " Bjorn Helgaas 2022-02-24 22:47 ` Bjorn Helgaas 2022-02-24 22:47 ` [PATCH v9 08/11] PCI/VGA: Remove empty vga_arb_device_card_gone() Bjorn Helgaas 2022-02-24 22:47 ` Bjorn Helgaas 2022-02-24 22:47 ` [PATCH v9 09/11] PCI/VGA: Log bridge control messages when adding devices Bjorn Helgaas 2022-02-24 22:47 ` Bjorn Helgaas 2022-02-24 22:47 ` [PATCH v9 10/11] PCI/VGA: Use unsigned format string to print lock counts Bjorn Helgaas 2022-02-24 22:47 ` Bjorn Helgaas 2022-02-24 22:47 ` [PATCH v9 11/11] PCI/VGA: Replace full MIT license text with SPDX identifier Bjorn Helgaas 2022-02-24 22:47 ` Bjorn Helgaas 2022-02-25 22:15 ` [PATCH v9 00/11] vgaarb: Rework default VGA device selection Bjorn Helgaas 2022-03-09 16:29 ` Bjorn Helgaas 2022-03-10 3:56 ` Huacai Chen 2022-03-10 3:56 ` Huacai Chen
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220224224753.297579-7-helgaas@kernel.org \ --to=helgaas@kernel.org \ --cc=airlied@linux.ie \ --cc=chenhuacai@loongson.cn \ --cc=daniel@ffwll.ch \ --cc=dja@axtens.net \ --cc=dri-devel@lists.freedesktop.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-pci@vger.kernel.org \ --cc=lixuefeng@loongson.cn \ --cc=maarten.lankhorst@linux.intel.com \ --cc=mripard@kernel.org \ --cc=tzimmermann@suse.de \ --cc=wangzhou1@hisilicon.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.