From: Bjorn Helgaas <helgaas@kernel.org>
To: David Airlie <airlied@linux.ie>, Daniel Vetter <daniel@ffwll.ch>
Cc: Xuefeng Li <lixuefeng@loongson.cn>,
Huacai Chen <chenhuacai@gmail.com>,
Huacai Chen <chenhuacai@loongson.cn>,
linux-pci@vger.kernel.org, dri-devel@lists.freedesktop.org,
linux-kernel@vger.kernel.org, Bjorn Helgaas <bhelgaas@google.com>,
Huacai Chen <chenhuacai@kernel.org>
Subject: [PATCH v8 03/10] vgaarb: Factor out default VGA device selection
Date: Wed, 5 Jan 2022 18:06:51 -0600 [thread overview]
Message-ID: <20220106000658.243509-4-helgaas@kernel.org> (raw)
In-Reply-To: <20220106000658.243509-1-helgaas@kernel.org>
From: Bjorn Helgaas <bhelgaas@google.com>
Default VGA device selection fails when PCI devices are enumerated after
the vga_arb_device_init() subsys_initcall.
vga_arbiter_add_pci_device() selects the first fully enabled device to
which legacy VGA resources are routed as the default VGA device. This is
an ADD_DEVICE notifier, so it runs after every PCI device is enumerated.
vga_arb_select_default_device() may select framebuffer devices, partially
enabled GPUs, or non-legacy devices that don't have legacy VGA resources
routed to them as the default VGA device. But this only happens once, from
the vga_arb_device_init() subsys_initcall, so it doesn't consider devices
enumerated after that:
acpi_init
acpi_scan_init
acpi_pci_root_init # PCI device enumeration (ACPI systems)
vga_arb_device_init
for_each_pci_device
vga_arbiter_add_pci_device # ADD_DEVICE notifier
if (VGA-owner)
vga_set_default_device <-- set default VGA
vga_arb_select_default_device # only called ONCE
for_each_vga_device
if (framebuffer)
vga_set_default_device <-- set default VGA to framebuffer
if (!vga_default_device())
if (non-legacy, integrated GPU, etc)
vga_set_default_device <-- set default VGA
if (!vga_default_device())
vga_set_default_device <-- set default VGA
pcibios_init
pcibios_scanbus # PCI device enumeration (non-ACPI systems)
...
vga_arbiter_add_pci_device # ADD_DEVICE notification
if (VGA-owner)
vga_set_default_device <-- set default VGA
Note that on non-ACPI systems, vga_arb_select_default_device() runs before
pcibios_init(), so it sees no VGA devices and can never set a framebuffer
device, a non-legacy integrated GPU, etc., as the default device.
Factor out the default VGA device selection to vga_is_boot_device(), called
from vga_arbiter_add_pci_device().
Then we can migrate the default device selection from
vga_arb_select_default_device() to the vga_arbiter_add_pci_device() path.
Link: https://lore.kernel.org/r/20211015061512.2941859-4-chenhuacai@loongson.cn
Based-on-patch-by: Huacai Chen <chenhuacai@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/gpu/vga/vgaarb.c | 45 ++++++++++++++++++++++++++++++++++------
1 file changed, 39 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
index 36d9140c64f6..b0ae0f177c6f 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -628,6 +628,41 @@ static bool vga_arb_integrated_gpu(struct device *dev)
#endif
}
+/*
+ * Return true if vgadev is a better default VGA device than the best one
+ * we've seen so far.
+ */
+static bool vga_is_boot_device(struct vga_device *vgadev)
+{
+ struct vga_device *boot_vga = vgadev_find(vga_default_device());
+
+ /*
+ * We select the default VGA device in this order:
+ * Firmware framebuffer (see vga_arb_select_default_device())
+ * Legacy VGA device (owns VGA_RSRC_LEGACY_MASK)
+ * Non-legacy integrated device (see vga_arb_select_default_device())
+ * Non-legacy discrete device (see vga_arb_select_default_device())
+ * Other device (see vga_arb_select_default_device())
+ */
+
+ /*
+ * A legacy VGA device has MEM and IO enabled and any bridges
+ * leading to it have PCI_BRIDGE_CTL_VGA enabled so the legacy
+ * resources ([mem 0xa0000-0xbffff], [io 0x3b0-0x3bb], etc) are
+ * routed to it.
+ *
+ * We use the first one we find, so if we've already found one,
+ * vgadev is no better.
+ */
+ if (boot_vga)
+ return false;
+
+ if ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)
+ return true;
+
+ return false;
+}
+
/*
* Rules for using a bridge to control a VGA descendant decoding: if a bridge
* has only one VGA descendant then it can be used to control the VGA routing
@@ -755,12 +790,10 @@ static bool vga_arbiter_add_pci_device(struct pci_dev *pdev)
bus = bus->parent;
}
- /* Deal with VGA default device. Use first enabled one
- * by default if arch doesn't have it's own hook
- */
- if (vga_default == NULL &&
- ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)) {
- vgaarb_info(&pdev->dev, "setting as boot VGA device\n");
+ if (vga_is_boot_device(vgadev)) {
+ vgaarb_info(&pdev->dev, "setting as boot VGA device%s\n",
+ vga_default_device() ?
+ " (overriding previous)" : "");
vga_set_default_device(pdev);
}
--
2.25.1
WARNING: multiple messages have this Message-ID (diff)
From: Bjorn Helgaas <helgaas@kernel.org>
To: David Airlie <airlied@linux.ie>, Daniel Vetter <daniel@ffwll.ch>
Cc: linux-pci@vger.kernel.org, Huacai Chen <chenhuacai@kernel.org>,
linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org,
Bjorn Helgaas <bhelgaas@google.com>,
Xuefeng Li <lixuefeng@loongson.cn>,
Huacai Chen <chenhuacai@loongson.cn>
Subject: [PATCH v8 03/10] vgaarb: Factor out default VGA device selection
Date: Wed, 5 Jan 2022 18:06:51 -0600 [thread overview]
Message-ID: <20220106000658.243509-4-helgaas@kernel.org> (raw)
In-Reply-To: <20220106000658.243509-1-helgaas@kernel.org>
From: Bjorn Helgaas <bhelgaas@google.com>
Default VGA device selection fails when PCI devices are enumerated after
the vga_arb_device_init() subsys_initcall.
vga_arbiter_add_pci_device() selects the first fully enabled device to
which legacy VGA resources are routed as the default VGA device. This is
an ADD_DEVICE notifier, so it runs after every PCI device is enumerated.
vga_arb_select_default_device() may select framebuffer devices, partially
enabled GPUs, or non-legacy devices that don't have legacy VGA resources
routed to them as the default VGA device. But this only happens once, from
the vga_arb_device_init() subsys_initcall, so it doesn't consider devices
enumerated after that:
acpi_init
acpi_scan_init
acpi_pci_root_init # PCI device enumeration (ACPI systems)
vga_arb_device_init
for_each_pci_device
vga_arbiter_add_pci_device # ADD_DEVICE notifier
if (VGA-owner)
vga_set_default_device <-- set default VGA
vga_arb_select_default_device # only called ONCE
for_each_vga_device
if (framebuffer)
vga_set_default_device <-- set default VGA to framebuffer
if (!vga_default_device())
if (non-legacy, integrated GPU, etc)
vga_set_default_device <-- set default VGA
if (!vga_default_device())
vga_set_default_device <-- set default VGA
pcibios_init
pcibios_scanbus # PCI device enumeration (non-ACPI systems)
...
vga_arbiter_add_pci_device # ADD_DEVICE notification
if (VGA-owner)
vga_set_default_device <-- set default VGA
Note that on non-ACPI systems, vga_arb_select_default_device() runs before
pcibios_init(), so it sees no VGA devices and can never set a framebuffer
device, a non-legacy integrated GPU, etc., as the default device.
Factor out the default VGA device selection to vga_is_boot_device(), called
from vga_arbiter_add_pci_device().
Then we can migrate the default device selection from
vga_arb_select_default_device() to the vga_arbiter_add_pci_device() path.
Link: https://lore.kernel.org/r/20211015061512.2941859-4-chenhuacai@loongson.cn
Based-on-patch-by: Huacai Chen <chenhuacai@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
---
drivers/gpu/vga/vgaarb.c | 45 ++++++++++++++++++++++++++++++++++------
1 file changed, 39 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
index 36d9140c64f6..b0ae0f177c6f 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -628,6 +628,41 @@ static bool vga_arb_integrated_gpu(struct device *dev)
#endif
}
+/*
+ * Return true if vgadev is a better default VGA device than the best one
+ * we've seen so far.
+ */
+static bool vga_is_boot_device(struct vga_device *vgadev)
+{
+ struct vga_device *boot_vga = vgadev_find(vga_default_device());
+
+ /*
+ * We select the default VGA device in this order:
+ * Firmware framebuffer (see vga_arb_select_default_device())
+ * Legacy VGA device (owns VGA_RSRC_LEGACY_MASK)
+ * Non-legacy integrated device (see vga_arb_select_default_device())
+ * Non-legacy discrete device (see vga_arb_select_default_device())
+ * Other device (see vga_arb_select_default_device())
+ */
+
+ /*
+ * A legacy VGA device has MEM and IO enabled and any bridges
+ * leading to it have PCI_BRIDGE_CTL_VGA enabled so the legacy
+ * resources ([mem 0xa0000-0xbffff], [io 0x3b0-0x3bb], etc) are
+ * routed to it.
+ *
+ * We use the first one we find, so if we've already found one,
+ * vgadev is no better.
+ */
+ if (boot_vga)
+ return false;
+
+ if ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)
+ return true;
+
+ return false;
+}
+
/*
* Rules for using a bridge to control a VGA descendant decoding: if a bridge
* has only one VGA descendant then it can be used to control the VGA routing
@@ -755,12 +790,10 @@ static bool vga_arbiter_add_pci_device(struct pci_dev *pdev)
bus = bus->parent;
}
- /* Deal with VGA default device. Use first enabled one
- * by default if arch doesn't have it's own hook
- */
- if (vga_default == NULL &&
- ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)) {
- vgaarb_info(&pdev->dev, "setting as boot VGA device\n");
+ if (vga_is_boot_device(vgadev)) {
+ vgaarb_info(&pdev->dev, "setting as boot VGA device%s\n",
+ vga_default_device() ?
+ " (overriding previous)" : "");
vga_set_default_device(pdev);
}
--
2.25.1
next prev parent reply other threads:[~2022-01-06 0:07 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-06 0:06 [PATCH v8 00/10] vgaarb: Rework default VGA device selection Bjorn Helgaas
2022-01-06 0:06 ` Bjorn Helgaas
2022-01-06 0:06 ` [PATCH v8 01/10] vgaarb: Move vga_arb_integrated_gpu() earlier in file Bjorn Helgaas
2022-01-06 0:06 ` Bjorn Helgaas
2022-01-06 0:06 ` [PATCH v8 02/10] vgaarb: Factor out vga_select_framebuffer_device() Bjorn Helgaas
2022-01-06 0:06 ` Bjorn Helgaas
2022-01-06 0:06 ` Bjorn Helgaas [this message]
2022-01-06 0:06 ` [PATCH v8 03/10] vgaarb: Factor out default VGA device selection Bjorn Helgaas
2022-01-06 0:06 ` [PATCH v8 04/10] vgaarb: Move framebuffer detection to ADD_DEVICE path Bjorn Helgaas
2022-01-06 0:06 ` Bjorn Helgaas
2022-01-06 6:44 ` Huacai Chen
2022-01-06 6:44 ` Huacai Chen
2022-01-06 16:20 ` Bjorn Helgaas
2022-01-06 16:20 ` Bjorn Helgaas
2022-01-25 2:51 ` Huacai Chen
2022-01-25 2:51 ` Huacai Chen
2022-01-25 15:38 ` Bjorn Helgaas
2022-01-25 15:38 ` Bjorn Helgaas
2022-01-26 2:25 ` Huacai Chen
2022-01-26 2:25 ` Huacai Chen
2022-01-06 0:06 ` [PATCH v8 05/10] vgaarb: Move non-legacy VGA " Bjorn Helgaas
2022-01-06 0:06 ` Bjorn Helgaas
2022-01-06 0:06 ` [PATCH v8 06/10] vgaarb: Move disabled VGA device " Bjorn Helgaas
2022-01-06 0:06 ` Bjorn Helgaas
2022-01-06 0:06 ` [PATCH v8 07/10] vgaarb: Remove empty vga_arb_device_card_gone() Bjorn Helgaas
2022-01-06 0:06 ` Bjorn Helgaas
2022-01-06 0:06 ` [PATCH v8 08/10] vgaarb: Log bridge control messages when adding devices Bjorn Helgaas
2022-01-06 0:06 ` Bjorn Helgaas
2022-01-06 0:06 ` [PATCH v8 09/10] vgaarb: Use unsigned format string to print lock counts Bjorn Helgaas
2022-01-06 0:06 ` Bjorn Helgaas
2022-01-06 0:06 ` [PATCH v8 10/10] vgaarb: Replace full MIT license text with SPDX identifier Bjorn Helgaas
2022-01-06 0:06 ` Bjorn Helgaas
2022-01-06 16:30 ` [PATCH v8 00/10] vgaarb: Rework default VGA device selection Bjorn Helgaas
2022-01-06 16:30 ` Bjorn Helgaas
2022-01-08 3:26 ` Huacai Chen
2022-01-08 3:26 ` Huacai Chen
2022-01-31 22:23 ` Bjorn Helgaas
2022-02-01 15:46 ` Maarten Lankhorst
2022-02-07 17:59 ` Bjorn Helgaas
2022-02-07 17:59 ` Bjorn Helgaas
2022-02-08 2:14 ` Huacai Chen
2022-02-08 2:14 ` Huacai Chen
2022-02-14 16:19 ` Bjorn Helgaas
2022-02-14 16:19 ` Bjorn Helgaas
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=20220106000658.243509-4-helgaas@kernel.org \
--to=helgaas@kernel.org \
--cc=airlied@linux.ie \
--cc=bhelgaas@google.com \
--cc=chenhuacai@gmail.com \
--cc=chenhuacai@kernel.org \
--cc=chenhuacai@loongson.cn \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lixuefeng@loongson.cn \
/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: link
Be 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.