aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/uart
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2025-01-15 02:17:46 +0000
committerWarner Losh <imp@FreeBSD.org>2025-01-15 02:24:35 +0000
commitdea3eef94cafb3bb1e5f04bc96b5636ffca92ee7 (patch)
treef1ee3f8962f9a2c2defc0462dfffb2ea9adde195 /sys/dev/uart
parent02703de8bcae3b45e6d96e8467d5fa512d62cc3d (diff)
Diffstat (limited to 'sys/dev/uart')
-rw-r--r--sys/dev/uart/uart_dev_pl011.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/sys/dev/uart/uart_dev_pl011.c b/sys/dev/uart/uart_dev_pl011.c
index 4f946f7c5f36..e7a2ff7a85f1 100644
--- a/sys/dev/uart/uart_dev_pl011.c
+++ b/sys/dev/uart/uart_dev_pl011.c
@@ -172,6 +172,27 @@ static int
uart_pl011_probe(struct uart_bas *bas)
{
+ /*
+ * Versions of QEMU before 41f7b58b634e (8.3) reported bogus values for
+ * this tabel. The PL011 IP is always 32-bits wide and should be shifted
+ * 2 to match the 4-byte size of the data. QEMU reported these values
+ * incorrectly before that.
+ * https://github.com/qemu/qemu/commit/41f7b58b634ec3b60ae874375d2bbb61d790971e
+ *
+ * In additon, other hardware vendors also reported this value
+ * incorrectly. It's not tied to what the ACPI device node is, but was a
+ * misunderstanding coupled with a Linux driver that didn't need the
+ * right values. Quirks used to be used to ignore the bad values, now we
+ * detect the historic mistake and override (to allow for a future where
+ * we may need to override these values).
+ *
+ * PL011 Docs: https://developer.arm.com/documentation/ddi0183/latest/
+ */
+ if (bas->regshft == 0 || bas->regiowidth == 1) {
+ bas->regshft = 2;
+ bas->regiowidth = 4;
+ }
+
return (0);
}
@@ -356,7 +377,8 @@ static struct uart_class uart_pl011_class = {
.uc_ops = &uart_pl011_ops,
.uc_range = 0x48,
.uc_rclk = 0,
- .uc_rshift = 2
+ .uc_rshift = 2,
+ .uc_riowidth = 4,
};
UART_CLASS(uart_pl011_class);