serial: a37xx: Reset whole UART when changing parent clock from TBG to XTAL
authorPali Rohár <pali@kernel.org>
Mon, 15 Nov 2021 12:48:06 +0000 (13:48 +0100)
committerStefan Roese <sr@denx.de>
Tue, 30 Nov 2021 07:31:04 +0000 (08:31 +0100)
commit5db5815e997ae8cf0a3bba6a25652d8b6fd5edd1
treeecdf38db014c5eee6ebe0c36c554b827cd243ff4
parent10c3befc682d8be2f5200db31333d88b4ac16d8c
serial: a37xx: Reset whole UART when changing parent clock from TBG to XTAL

Sometimes UART stops transmitting characters after UART clock is changed
back to XTAL. In this state UART fifo is always full. Kernel during early
boot wants to print output on UART and is waiting for non-empty UART fifo.
Which leads to CPU hangup without any (debug) output on UART.

Marvell Armada 3700 Functional Specifications says that for programming
fractional divisor registers it is required to disable UART, enable
loopback mode, reset fifos, program registers, disable loopback mode,
release reset of fifos and enable UART.

But these steps do not fix above mentioned issue that UART hangup. Also
gating UART clock does not help. And even resetting UART state machines do
not help.

Experiments showed that UART fifo is unblocked after board is being reset
(during board reset UART HW transmit UART fifo even CPU is not executing
kernel/bootloader anymore).

And another experiments showed that same workaround can be achieved also
by external reset of UART HW (without need to reset board).

So do not implement any of "Marvell recommended" steps from Functional
Specifications as they do not work. And rather prior changing parent clock
back to XTAL, do external reset of UART HW. This operation also resets all
UART registers, so basically it also sets UART clock to default, which is
XTAL. It is unknown why UART hangups and enters such broken state.

Signed-off-by: Pali Rohár <pali@kernel.org>
Reviewed-by: Stefan Roese <sr@denx.de>
drivers/serial/serial_mvebu_a3700.c