git: 987dc68e66b7 - main - uart: Implement SPCR rev 3 and 4 for PreciseBaudrate and UartClkFreq
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 15 Oct 2024 11:01:18 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=987dc68e66b747815c7a78e3c3e2b5f64e885791
commit 987dc68e66b747815c7a78e3c3e2b5f64e885791
Author: Warner Losh <imp@FreeBSD.org>
AuthorDate: 2024-10-15 11:00:11 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-10-15 11:00:11 +0000
uart: Implement SPCR rev 3 and 4 for PreciseBaudrate and UartClkFreq
If we have a new enough SPCR, then use it when it provides a
PreciseBaudrate and/or a UartClkFreq.
Sponsored by: Netflix
Reviewed by: andrew,adrian
Differential Revision: https://reviews.freebsd.org/D47097
---
sys/dev/uart/uart_cpu_acpi.c | 60 ++++++++++++++++++++++++++++----------------
1 file changed, 39 insertions(+), 21 deletions(-)
diff --git a/sys/dev/uart/uart_cpu_acpi.c b/sys/dev/uart/uart_cpu_acpi.c
index 816738ec31d5..ce00a09fee33 100644
--- a/sys/dev/uart/uart_cpu_acpi.c
+++ b/sys/dev/uart/uart_cpu_acpi.c
@@ -167,28 +167,46 @@ uart_cpu_acpi_spcr(int devtype, struct uart_devinfo *di)
if (error != 0)
goto out;
- switch (spcr->BaudRate) {
- case 0:
- /* Special value; means "keep current value unchanged". */
- di->baudrate = 0;
- break;
- case 3:
- di->baudrate = 9600;
- break;
- case 4:
- di->baudrate = 19200;
- break;
- case 6:
- di->baudrate = 57600;
- break;
- case 7:
- di->baudrate = 115200;
- break;
- default:
- printf("SPCR has reserved BaudRate value: %d!\n",
- (int)spcr->BaudRate);
- goto out;
+ /*
+ * SPCR Rev 4 and newer allow a precise baudrate to be passed in for
+ * things like 1.5M or 2.0M. If we have that, then use that value,
+ * otherwise try to decode the older enumeration.
+ */
+ if (spcr->Header.Revision >= 4 && spcr->PreciseBaudrate != 0) {
+ di->baudrate = spcr->PreciseBaudrate;
+ } else {
+ switch (spcr->BaudRate) {
+ case 0:
+ /* Special value; means "keep current value unchanged". */
+ di->baudrate = 0;
+ break;
+ case 3:
+ di->baudrate = 9600;
+ break;
+ case 4:
+ di->baudrate = 19200;
+ break;
+ case 6:
+ di->baudrate = 57600;
+ break;
+ case 7:
+ di->baudrate = 115200;
+ break;
+ default:
+ printf("SPCR has reserved BaudRate value: %d!\n",
+ (int)spcr->BaudRate);
+ goto out;
+ }
}
+
+ /*
+ * Rev 3 and newer can specify a rclk, use it if it's there. It's
+ * defined to be 0 when it's not known, and we've initialized rclk to 0
+ * in uart_cpu_acpi_init_devinfo, so we don't have to test for it.
+ */
+ if (spcr->Header.Revision >= 3)
+ di->bas.rclk = spcr->UartClkFreq;
+
/*
* If no rclk is set, then we will assume the BIOS has configured the
* hardware at the stated baudrate, so we can use it to guess the rclk