mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-24 05:54:08 +00:00

Sometimes when changing UART clock from TBG to XTAL, UART HW enters into some broken state. It does not transit characters from TX FIFO anymore and TX FIFO stays always empty. TX FIFO reset does not recover UART HW from this broken state. Experiments show that external reset can fix UART HW from this broken state. TF-A fatal error handler calls console_a3700_core_init() function to initialize UART HW. This handler may be called anytime during CPU runtime, also when kernel is running. U-Boot or Linux kernel may change UART clock to TBG to achieve higher baudrates. During initialization, console_a3700_core_init() resets UART configuration to default settings, which means that it also changes UART clock from TBG to XTAL. Do an external reset of UART via North Bridge Peripheral reset register to prevent this UART hangup. Signed-off-by: Pali Rohár <pali@kernel.org> Change-Id: I8990bce24d1a6fd8ccc47a2cd0a5ff932fcfcf14
74 lines
2.4 KiB
C
74 lines
2.4 KiB
C
/*
|
|
* Copyright (C) 2016 Marvell International Ltd.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
* https://spdx.org/licenses
|
|
*/
|
|
|
|
#ifndef A3700_CONSOLE_H
|
|
#define A3700_CONSOLE_H
|
|
|
|
#include <drivers/console.h>
|
|
#include <platform_def.h>
|
|
|
|
/* MVEBU UART Registers */
|
|
#define UART_RX_REG 0x00
|
|
#define UART_TX_REG 0x04
|
|
#define UART_CTRL_REG 0x08
|
|
#define UART_STATUS_REG 0x0c
|
|
#define UART_BAUD_REG 0x10
|
|
#define UART_POSSR_REG 0x14
|
|
|
|
/* FIFO Control Register bits */
|
|
#define UARTFCR_FIFOMD_16450 (0 << 6)
|
|
#define UARTFCR_FIFOMD_16550 (1 << 6)
|
|
#define UARTFCR_RXTRIG_1 (0 << 6)
|
|
#define UARTFCR_RXTRIG_4 (1 << 6)
|
|
#define UARTFCR_RXTRIG_8 (2 << 6)
|
|
#define UARTFCR_RXTRIG_16 (3 << 6)
|
|
#define UARTFCR_TXTRIG_1 (0 << 4)
|
|
#define UARTFCR_TXTRIG_4 (1 << 4)
|
|
#define UARTFCR_TXTRIG_8 (2 << 4)
|
|
#define UARTFCR_TXTRIG_16 (3 << 4)
|
|
#define UARTFCR_DMAEN (1 << 3) /* Enable DMA mode */
|
|
#define UARTFCR_TXCLR (1 << 2) /* Clear contents of Tx FIFO */
|
|
#define UARTFCR_RXCLR (1 << 1) /* Clear contents of Rx FIFO */
|
|
#define UARTFCR_FIFOEN (1 << 0) /* Enable the Tx/Rx FIFO */
|
|
|
|
/* Line Control Register bits */
|
|
#define UARTLCR_DLAB (1 << 7) /* Divisor Latch Access */
|
|
#define UARTLCR_SETB (1 << 6) /* Set BREAK Condition */
|
|
#define UARTLCR_SETP (1 << 5) /* Set Parity to LCR[4] */
|
|
#define UARTLCR_EVEN (1 << 4) /* Even Parity Format */
|
|
#define UARTLCR_PAR (1 << 3) /* Parity */
|
|
#define UARTLCR_STOP (1 << 2) /* Stop Bit */
|
|
#define UARTLCR_WORDSZ_5 0 /* Word Length of 5 */
|
|
#define UARTLCR_WORDSZ_6 1 /* Word Length of 6 */
|
|
#define UARTLCR_WORDSZ_7 2 /* Word Length of 7 */
|
|
#define UARTLCR_WORDSZ_8 3 /* Word Length of 8 */
|
|
|
|
/* Line Status Register bits */
|
|
#define UARTLSR_TXFIFOFULL (1 << 11) /* Tx Fifo Full */
|
|
#define UARTLSR_TXEMPTY (1 << 6) /* Tx Empty */
|
|
#define UARTLSR_RXRDY (1 << 4) /* Rx Ready */
|
|
|
|
/* UART Control Register bits */
|
|
#define UART_CTRL_RXFIFO_RESET (1 << 14)
|
|
#define UART_CTRL_TXFIFO_RESET (1 << 15)
|
|
|
|
#ifndef __ASSEMBLER__
|
|
|
|
#include <stdint.h>
|
|
|
|
/*
|
|
* Initialize a new a3700 console instance and register it with the console
|
|
* framework. The |console| pointer must point to storage that will be valid
|
|
* for the lifetime of the console, such as a global or static local variable.
|
|
* Its contents will be reinitialized from scratch.
|
|
*/
|
|
int console_a3700_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
|
|
console_t *console);
|
|
|
|
#endif /*__ASSEMBLER__*/
|
|
|
|
#endif /* A3700_CONSOLE_H */
|