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