Centos-kernel-stream-9/Documentation/tty
Andrew Halaney dd36ce11e5 serial: 8250: Add proper clock handling for OxSemi PCIe devices
JIRA: https://issues.redhat.com/browse/RHEL-24205

commit 366f6c955d4d1a5125ffcd6875ead26a3c7a2a1c
Author: Maciej W. Rozycki <macro@orcam.me.uk>
Date:   Mon Apr 18 16:27:33 2022 +0100

    serial: 8250: Add proper clock handling for OxSemi PCIe devices

    Oxford Semiconductor PCIe (Tornado) 950 serial port devices are driven
    by a fixed 62.5MHz clock input derived from the 100MHz PCI Express clock.

    We currently drive the device using its default oversampling rate of 16
    and the clock prescaler disabled, consequently yielding the baud base of
    3906250.  This base is inadequate for some of the high-speed baud rates
    such as 460800bps, for which the closest rate possible can be obtained
    by dividing the baud base by 8, yielding the baud rate of 488281.25bps,
    which is off by 5.9638%.  This is enough for data communication to break
    with the remote end talking actual 460800bps, where missed stop bits
    have been observed.

    We can do better however, by taking advantage of a reduced oversampling
    rate, which can be set to any integer value from 4 to 16 inclusive by
    programming the TCR register, and by using the clock prescaler, which
    can be set to any value from 1 to 63.875 in increments of 0.125 in the
    CPR/CPR2 register pair.  The prescaler has to be explicitly enabled
    though by setting bit 7 in the MCR or otherwise it is bypassed (in the
    enhanced mode that we enable) as if the value of 1 was used.

    Make use of these features then as follows:

    - Set the baud base to 15625000, reflecting the minimum oversampling
      rate of 4 with the clock prescaler and divisor both set to 1.

    - Override the `set_mctrl' and set the MCR shadow there so as to have
      MCR[7] always set and have the 8250 core propagate these settings.

    - Override the `get_divisor' handler and determine a good combination of
      parameters by using a lookup table with predetermined value pairs of
      the oversampling rate and the clock prescaler and finding a pair that
      divides the input clock such that the quotient, when rounded to the
      nearest integer, deviates the least from the exact result.  Calculate
      the clock divisor accordingly.

      Scale the resulting oversampling rate (only by powers of two) if
      possible so as to maximise it, reducing the divisor accordingly, and
      avoid a divisor overflow for very low baud rates by scaling the
      oversampling rate and/or the prescaler even if that causes some
      accuracy loss.

      Also handle the historic spd_cust feature so as to allow one to set
      all the three parameters manually to arbitrary values, by keeping the
      low 16 bits for the divisor and then putting TCR in bits 19:16 and
      CPR/CPR2 in bits 28:20, sanitising the bit pattern supplied such as
      to clamp CPR/CPR2 values between 0.000 and 0.875 inclusive to 33.875.
      This preserves compatibility with any existing setups, that is where
      requesting a custom divisor that only has any bits set among the low
      16 the oversampling rate of 16 and the clock prescaler of 33.875 will
      be used as with the original 8250.

      Finally abuse the `frac' argument to store the determined bit patterns
      for the TCR, CPR and CPR2 registers.

    - Override the `set_divisor' handler so as to set the TCR, CPR and CPR2
      registers from the `frac' value supplied.  Set the divisor as usual.

    With the baud base set to 15625000 and the unsigned 16-bit UART_DIV_MAX
    limitation imposed by `serial8250_get_baud_rate' standard baud rates
    below 300bps become unavailable in the regular way, e.g. the rate of
    200bps requires the baud base to be divided by 78125 and that is beyond
    the unsigned 16-bit range.  The historic spd_cust feature can still be
    used to obtain such rates if so required.

    See Documentation/tty/device_drivers/oxsemi-tornado.rst for more details.

    Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
    Link: https://lore.kernel.org/r/alpine.DEB.2.21.2204181519450.9383@angie.orcam.me.uk
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Signed-off-by: Andrew Halaney <ahalaney@redhat.com>
2024-05-09 11:24:43 -04:00
..
device_drivers serial: 8250: Add proper clock handling for OxSemi PCIe devices 2024-05-09 11:24:43 -04:00
index.rst Documentation: add TTY chapter 2024-05-09 11:24:24 -04:00
n_tty.rst Documentation: add TTY chapter 2024-05-09 11:24:24 -04:00
tty_buffer.rst Documentation: add TTY chapter 2024-05-09 11:24:24 -04:00
tty_driver.rst Documentation: add TTY chapter 2024-05-09 11:24:24 -04:00
tty_internals.rst Documentation: add TTY chapter 2024-05-09 11:24:24 -04:00
tty_ldisc.rst Documentation: add TTY chapter 2024-05-09 11:24:24 -04:00
tty_port.rst Documentation: add TTY chapter 2024-05-09 11:24:24 -04:00
tty_struct.rst Documentation: add TTY chapter 2024-05-09 11:24:24 -04:00