The MediaTek UART is a 16550 with 32-bit spaced registers and an
extended baud rate generator. In mode 3 a bit lasts
DLM:DLL * (SAMPLE_COUNT + 1) clock cycles, and the fractional divider
registers add one sample period to selected bits of a frame. Use that
for the baud rate and the ns8250 code for everything else.
The fraction is spread over the bits the hardware can extend. Measured
on the MT7986, these are the data bits, the parity bit, and a stop bit
only with two stop bits. MediaTek's tables also use the stop bit with
8N1, where it has no effect. With five data bits, two stop bits are
one sample period short, and the stop bit extension is not used.
RATEFIX_AD, which divides the clock by 2 or 4, is cleared. At 26 and
40 MHz, 8N1 rates up to 921600 baud are within 0.1 %.
The divisor calculation reproduces Table 2-6 of the reference manual
[1], except at 7200 baud, where it picks a closer fraction.
The driver uses the generic FDT attachment. The clocks come from the
clock framework and are taken and enabled in UART_PROBE, once the core
knows whether the port is the console. They are kept per port outside
the softc, so a repeated probe or a failed attach does not leak them,
and detach releases them. The console and debug port keep their
firmware clock setup and their clocks. Other ports apply their
assigned clocks to their own clocks only, since a shared parent may
also feed the console.
Pins are set through fdt_pinctrl. Until there is an MT7986 pinctrl
driver, UART1 and UART2 rely on the firmware's pin setup.
[1] MT7986A Reference Manual for BPI-R3, v1.0, section 2.6, Tables 2-5
and 2-6. Distributed by Banana Pi: https://wiki.banana-pi.org/Banana_Pi_BPI-R3
Sponsored by: Alchemilla Ventures Private Limited