uart/ns16550: support divisor latch fraction (DLF)
The UART on Quark SE and D2000 supports fractional clock divider. It is used to limit frequency error for supported baud rates. Change-Id: I1f39a95db09f4a5a4116edc700a10e4b9ecfa2bd Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
parent
0ad859aaf3
commit
b9c70ce76a
|
@ -67,6 +67,9 @@ endif # PINMUX
|
|||
|
||||
if UART_NS16550
|
||||
|
||||
config UART_NS16550_DLF
|
||||
def_bool y
|
||||
|
||||
config UART_NS16550_PORT_0
|
||||
def_bool y
|
||||
|
||||
|
@ -86,6 +89,8 @@ config UART_NS16550_PORT_0_CLK_FREQ
|
|||
default 32000000
|
||||
config UART_NS16550_PORT_0_OPTIONS
|
||||
default 0
|
||||
config UART_NS16550_PORT_0_DLF
|
||||
default 0x06
|
||||
|
||||
endif # UART_NS16550_PORT_0
|
||||
|
||||
|
@ -108,6 +113,8 @@ config UART_NS16550_PORT_1_CLK_FREQ
|
|||
default 32000000
|
||||
config UART_NS16550_PORT_1_OPTIONS
|
||||
default 0
|
||||
config UART_NS16550_PORT_1_DLF
|
||||
default 0x06
|
||||
|
||||
endif # UART_NS16550_PORT_1
|
||||
|
||||
|
|
|
@ -48,17 +48,9 @@ static int quark_d2000_init(struct device *arg)
|
|||
/* enable clock gating */
|
||||
#ifdef CONFIG_UART_NS16550_PORT_0
|
||||
sys_set_bit(CLOCK_PERIPHERAL_BASE_ADDR, 17);
|
||||
|
||||
*((unsigned char *)(CONFIG_UART_NS16550_PORT_0_BASE_ADDR
|
||||
+ SYNOPSIS_UART_DLF_OFFSET)) =
|
||||
COM1_DLF;
|
||||
#endif
|
||||
#ifdef CONFIG_UART_NS16550_PORT_1
|
||||
sys_set_bit(CLOCK_PERIPHERAL_BASE_ADDR, 18);
|
||||
|
||||
*((unsigned char *)(CONFIG_UART_NS16550_PORT_1_BASE_ADDR
|
||||
+ SYNOPSIS_UART_DLF_OFFSET)) =
|
||||
COM2_DLF;
|
||||
#endif
|
||||
sys_set_bit(CLOCK_PERIPHERAL_BASE_ADDR, 1);
|
||||
#endif /* CONFIG_UART_NS16550 */
|
||||
|
|
|
@ -115,14 +115,6 @@ struct scss_interrupt {
|
|||
#define LOAPIC_IRQ_COUNT 1
|
||||
#define LOAPIC_LVT_REG_SPACING 0x10
|
||||
|
||||
/* serial port (aka COM port) information */
|
||||
#define SYNOPSIS_UART_DLF_OFFSET 0xc0
|
||||
#define SYNOPSIS_UART_DLF_115200_VAL 0x06
|
||||
|
||||
#define COM1_DLF SYNOPSIS_UART_DLF_115200_VAL
|
||||
|
||||
#define COM2_DLF SYNOPSIS_UART_DLF_115200_VAL
|
||||
|
||||
/* UART uses level triggered interrupt, low level */
|
||||
#define UART_IOAPIC_FLAGS (IOAPIC_LEVEL)
|
||||
|
||||
|
|
|
@ -37,6 +37,16 @@ choice
|
|||
|
||||
endchoice
|
||||
|
||||
config UART_NS16550_DLF
|
||||
bool "Enable Divisor Latch Fraction (DLF) support"
|
||||
default n
|
||||
depends on UART_NS16550 && UART_NS16550_ACCESS_MMIO
|
||||
help
|
||||
This enables support for divisor latch fraction (DLF).
|
||||
It is used to limit frequency error.
|
||||
|
||||
Says n if you are not sure if hardware supports this.
|
||||
|
||||
# ---------- Port 0 ----------
|
||||
|
||||
menuconfig UART_NS16550_PORT_0
|
||||
|
@ -108,6 +118,13 @@ config UART_NS16550_PORT_0_OPTIONS
|
|||
help
|
||||
Options used for port initialization.
|
||||
|
||||
config UART_NS16550_PORT_0_DLF
|
||||
hex "Port 0 DLF value"
|
||||
default 0x0
|
||||
depends on UART_NS16550_PORT_0 && UART_NS16550_DLF
|
||||
help
|
||||
Value for DLF register.
|
||||
|
||||
config UART_NS16550_PORT_0_PCI
|
||||
bool "Port 0 is PCI-based"
|
||||
default n
|
||||
|
@ -237,6 +254,13 @@ config UART_NS16550_PORT_1_OPTIONS
|
|||
help
|
||||
Options used for port initialization.
|
||||
|
||||
config UART_NS16550_PORT_1_DLF
|
||||
hex "Port 1 DLF value"
|
||||
default 0x0
|
||||
depends on UART_NS16550_PORT_1 && UART_NS16550_DLF
|
||||
help
|
||||
Value for DLF register.
|
||||
|
||||
config UART_NS16550_PORT_1_PCI
|
||||
bool "Port 1 is PCI-based"
|
||||
default n
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#define REG_MDC 0x04 /* Modem control reg. */
|
||||
#define REG_LSR 0x05 /* Line status reg. */
|
||||
#define REG_MSR 0x06 /* Modem status reg. */
|
||||
#define REG_DLF 0xC0 /* Divisor Latch Fraction */
|
||||
|
||||
/* equates for interrupt enable register */
|
||||
|
||||
|
@ -183,6 +184,7 @@
|
|||
#define MDC(dev) (DEV_CFG(dev)->port + REG_MDC * UART_REG_ADDR_INTERVAL)
|
||||
#define LSR(dev) (DEV_CFG(dev)->port + REG_LSR * UART_REG_ADDR_INTERVAL)
|
||||
#define MSR(dev) (DEV_CFG(dev)->port + REG_MSR * UART_REG_ADDR_INTERVAL)
|
||||
#define DLF(dev) (DEV_CFG(dev)->port + REG_DLF)
|
||||
|
||||
#define IIRC(dev) (DEV_DATA(dev)->iir_cache)
|
||||
|
||||
|
@ -201,10 +203,21 @@
|
|||
/** Device data structure */
|
||||
struct uart_ns16550_dev_data_t {
|
||||
uint8_t iir_cache; /**< cache of IIR since it clears when read */
|
||||
uint8_t dlf; /**< DLF value */
|
||||
};
|
||||
|
||||
static struct uart_driver_api uart_ns16550_driver_api;
|
||||
|
||||
#ifdef CONFIG_UART_NS16550_DLF
|
||||
static inline void set_dlf(struct device *dev, uint32_t val)
|
||||
{
|
||||
struct uart_ns16550_dev_data_t * const dev_data = DEV_DATA(dev);
|
||||
|
||||
OUTBYTE(DLF(dev), val);
|
||||
dev_data->dlf = val;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_UART_NS16550_PCI)
|
||||
|
||||
static inline int ns16550_pci_uart_scan(struct device *dev)
|
||||
|
@ -274,6 +287,10 @@ static int uart_ns16550_init(struct device *dev)
|
|||
OUTBYTE(BRDH(dev), (unsigned char)((divisor >> 8) & 0xff));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_UART_NS16550_DLF
|
||||
set_dlf(dev, dev_data->dlf);
|
||||
#endif
|
||||
|
||||
/* 8 data bits, 1 stop bit, no parity, clear DLAB */
|
||||
OUTBYTE(LCR(dev), LCR_CS8 | LCR_1_STB | LCR_PDIS);
|
||||
|
||||
|
@ -576,7 +593,11 @@ struct uart_device_config uart_ns16550_dev_cfg_0 = {
|
|||
#endif /* CONFIG_UART_NS16550_PORT_0_PCI */
|
||||
};
|
||||
|
||||
static struct uart_ns16550_dev_data_t uart_ns16550_dev_data_0;
|
||||
static struct uart_ns16550_dev_data_t uart_ns16550_dev_data_0 = {
|
||||
#ifdef CONFIG_UART_NS16550_PORT_0_DLF
|
||||
.dlf = CONFIG_UART_NS16550_PORT_0_DLF,
|
||||
#endif
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_INIT_CONFIG(uart_ns16550_0,
|
||||
CONFIG_UART_NS16550_PORT_0_NAME,
|
||||
|
@ -610,7 +631,11 @@ struct uart_device_config uart_ns16550_dev_cfg_1 = {
|
|||
#endif /* CONFIG_UART_NS16550_PORT_1_PCI */
|
||||
};
|
||||
|
||||
static struct uart_ns16550_dev_data_t uart_ns16550_dev_data_1;
|
||||
static struct uart_ns16550_dev_data_t uart_ns16550_dev_data_1 = {
|
||||
#ifdef CONFIG_UART_NS16550_PORT_1_DLF
|
||||
.dlf = CONFIG_UART_NS16550_PORT_1_DLF,
|
||||
#endif
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_INIT_CONFIG(uart_ns16550_1,
|
||||
CONFIG_UART_NS16550_PORT_1_NAME,
|
||||
|
|
Loading…
Reference in a new issue