summaryrefslogtreecommitdiff
path: root/drivers/tty/serial/8250
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@orcam.me.uk>2021-06-10 21:38:28 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-06-16 10:20:29 +0300
commitb1691bd04952bc6cbb7d75b1758c73942133c8ba (patch)
tree298f29778c51241b667d4ad738a4b45b4e4c0004 /drivers/tty/serial/8250
parent1882441cd788a496b378f4d2684fa66cec195051 (diff)
downloadlinux-b1691bd04952bc6cbb7d75b1758c73942133c8ba.tar.xz
serial: 8250: Document SMSC Super I/O UART peculiarities
Contrary to what SMSC documentation says and unlike NS16C550A UARTs the SMSC Super I/O IC claims compatibility with the SMSC UART implementation does not support dividing the internal PLL clock by any divisor from 1 to 65535[1], with the exception of two magic divisors of 32769 and 32770 used respectively to select the high-speed data rates of 460800bps and 230400bps[2] if enabled on a port-by-port basis in with the Serial Port Mode Register in the Device Configuration Space[3][4]. Instead empirical evidence indicates that the divisor, as stored in the DLL and DLM register pair, has the range of 1 to 32767 only, and bit 7 of the DLM register (bit 15 of the divisor) effectively serves as a selection bit for the prescaler from the base frequency of 7.3728MHz, either 4 if the bit is 0, or 1 if the bit is 1 and high-speed operation has been enabled with the Serial Port Mode Register. So if high-speed operation has not been enabled, then say the values of 1 and 32769 (0x8001) written into the combined DLL and DLM register pair both select the divisor of 1 and the baud rate of 115200bps. [1] "FDC37M81x, PC98/99 Compliant Enhanced Super I/O Controller with Keyboard/Mouse Wake-Up", Standard Microsystems Corporation, Rev. 03/27/2000, Section "Programmable Baud Rate Generator (and Divisor Latches DLH, DLL)", p. 75 [2] same, Table 31 - "Baud Rates", p. 77 [3] same, Table 60 - "Serial Port 1, Logical Device 4 [Logical Device Number = 0x04]", p. 153 [4] same, Table 61 - "Serial Port 2, Logical Device 5 [Logical Device Number = 0x05]", p. 153 Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk> Link: https://lore.kernel.org/r/alpine.DEB.2.21.2106092330530.5469@angie.orcam.me.uk Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/8250')
-rw-r--r--drivers/tty/serial/8250/8250_port.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index fc5ab2032282..b96562102b43 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -2516,9 +2516,36 @@ static unsigned int serial8250_do_get_divisor(struct uart_port *port,
unsigned int quot;
/*
- * Handle magic divisors for baud rates above baud_base on
- * SMSC SuperIO chips.
+ * Handle magic divisors for baud rates above baud_base on SMSC
+ * Super I/O chips. We clamp custom rates from clk/6 and clk/12
+ * up to clk/4 (0x8001) and clk/8 (0x8002) respectively. These
+ * magic divisors actually reprogram the baud rate generator's
+ * reference clock derived from chips's 14.318MHz clock input.
*
+ * Documentation claims that with these magic divisors the base
+ * frequencies of 7.3728MHz and 3.6864MHz are used respectively
+ * for the extra baud rates of 460800bps and 230400bps rather
+ * than the usual base frequency of 1.8462MHz. However empirical
+ * evidence contradicts that.
+ *
+ * Instead bit 7 of the DLM register (bit 15 of the divisor) is
+ * effectively used as a clock prescaler selection bit for the
+ * base frequency of 7.3728MHz, always used. If set to 0, then
+ * the base frequency is divided by 4 for use by the Baud Rate
+ * Generator, for the usual arrangement where the value of 1 of
+ * the divisor produces the baud rate of 115200bps. Conversely,
+ * if set to 1 and high-speed operation has been enabled with the
+ * Serial Port Mode Register in the Device Configuration Space,
+ * then the base frequency is supplied directly to the Baud Rate
+ * Generator, so for the divisor values of 0x8001, 0x8002, 0x8003,
+ * 0x8004, etc. the respective baud rates produced are 460800bps,
+ * 230400bps, 153600bps, 115200bps, etc.
+ *
+ * In all cases only low 15 bits of the divisor are used to divide
+ * the baud base and therefore 32767 is the maximum divisor value
+ * possible, even though documentation says that the programmable
+ * Baud Rate Generator is capable of dividing the internal PLL
+ * clock by any divisor from 1 to 65535.
*/
if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
baud == (port->uartclk/4))