drivers: uart: Add support for UART_NS16550 TI K3 variant

TI K3 family of SoCs requires an extended set of registers to operate.
Extended functionality of the current driver to support the variant.

Signed-off-by: L Lakshmanan <l-lakshmanan@ti.com>
This commit is contained in:
L Lakshmanan 2023-07-13 14:17:11 +05:30 committed by Carles Cufí
parent c15e3d448c
commit 24759511f4
2 changed files with 32 additions and 0 deletions

View file

@ -82,6 +82,13 @@ config UART_NS16550_PARENT_INIT_LEVEL
only post kernel and hence such platforms the UART driver instance init
should be invoked only post kernel in case parent node is PCI.
config UART_NS16550_TI_K3
bool "Add support for NS16550 variant specific to TI K3 SoCs"
help
Enabling this configuration allows the users to use the UART port in
Texas Instruments K3 SoCs by enabling a vendor specific extended register
set.
menu "NS16550 Workarounds"
config UART_NS16550_WA_ISR_REENABLE_INTERRUPT

View file

@ -68,6 +68,7 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE");
#define REG_MSR 0x06 /* Modem status reg. */
#define REG_DLF 0xC0 /* Divisor Latch Fraction */
#define REG_PCP 0x200 /* PRV_CLOCK_PARAMS (Apollo Lake) */
#define REG_MDR1 0x08 /* Mode control reg. (TI_K3) */
/* equates for interrupt enable register */
@ -99,6 +100,22 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE");
#define PCP_UPDATE 0x80000000 /* update clock */
#define PCP_EN 0x00000001 /* enable clock output */
/* Fields for TI K3 UART module */
#define MDR1_MODE_SELECT_FIELD_MASK BIT_MASK(3)
#define MDR1_MODE_SELECT_FIELD_SHIFT BIT_MASK(0)
/* Modes available for TI K3 UART module */
#define MDR1_STD_MODE (0)
#define MDR1_SIR_MODE (1)
#define MDR1_UART_16X (2)
#define MDR1_UART_13X (3)
#define MDR1_MIR_MODE (4)
#define MDR1_FIR_MODE (5)
#define MDR1_CIR_MODE (6)
#define MDR1_DISABLE (7)
/*
* Per PC16550D (Literature Number: SNLS378B):
*
@ -199,6 +216,7 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE");
#define MDC(dev) (get_port(dev) + REG_MDC * reg_interval(dev))
#define LSR(dev) (get_port(dev) + REG_LSR * reg_interval(dev))
#define MSR(dev) (get_port(dev) + REG_MSR * reg_interval(dev))
#define MDR1(dev) (get_port(dev) + REG_MDR1 * reg_interval(dev))
#define DLF(dev) (get_port(dev) + REG_DLF)
#define PCP(dev) (get_port(dev) + REG_PCP)
@ -421,6 +439,13 @@ static int uart_ns16550_configure(const struct device *dev,
}
#endif
#ifdef CONFIG_UART_NS16550_TI_K3
uint32_t mdr = ns16550_inbyte(dev_cfg, MDR1(dev));
mdr = ((mdr & ~MDR1_MODE_SELECT_FIELD_MASK) | ((((MDR1_STD_MODE) <<
MDR1_MODE_SELECT_FIELD_SHIFT)) & MDR1_MODE_SELECT_FIELD_MASK));
ns16550_outbyte(dev_cfg, MDR1(dev), mdr);
#endif
/*
* set clock frequency from clock_frequency property if valid,
* otherwise, get clock frequency from clock manager