diff options
author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2012-08-17 19:47:00 +0800 |
---|---|---|
committer | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2012-09-11 12:48:34 +0800 |
commit | 75a0136ccae3899aee91f1d8d38274c426f99175 (patch) | |
tree | 2d717500e0dcad0ddbadf263d9717886586af9cc /drivers/serial/amba-pl011.c | |
parent | 09d593b6706a09b22d41cb831548a6b08289660a (diff) | |
download | barebox-75a0136ccae3899aee91f1d8d38274c426f99175.tar.gz barebox-75a0136ccae3899aee91f1d8d38274c426f99175.tar.xz |
amba-pl011: add st specific init
This is need on the new IP for ux500
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Diffstat (limited to 'drivers/serial/amba-pl011.c')
-rw-r--r-- | drivers/serial/amba-pl011.c | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 77f8c8ad92..b62dc9ff3c 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c @@ -45,6 +45,23 @@ struct amba_uart_port { struct console_device uart; /* uart */ struct clk *clk; /* uart clock */ u32 uartclk; + struct vendor_data *vendor; +}; + +/* There is by now at least one vendor with differing details, so handle it */ +struct vendor_data { + unsigned int lcrh_tx; + unsigned int lcrh_rx; +}; + +static struct vendor_data vendor_arm = { + .lcrh_tx = UART011_LCRH, + .lcrh_rx = UART011_LCRH, +}; + +static struct vendor_data vendor_st = { + .lcrh_tx = ST_UART011_LCRH_TX, + .lcrh_rx = ST_UART011_LCRH_RX, }; static inline struct amba_uart_port * @@ -117,6 +134,23 @@ static int pl011_tstc(struct console_device *cdev) return !(readl(uart->base + UART01x_FR) & UART01x_FR_RXFE); } +static void pl011_rlcr(struct amba_uart_port *uart, u32 lcr) +{ + struct vendor_data *vendor = uart->vendor; + + writew(lcr, uart->base + vendor->lcrh_rx); + if (vendor->lcrh_tx != vendor->lcrh_rx) { + int i; + /* + * Wait 10 PCLKs before writing LCRH_TX register, + * to get this delay write read only register 10 times + */ + for (i = 0; i < 10; ++i) + writew(0xff, uart->base + UART011_MIS); + writew(lcr, uart->base + vendor->lcrh_tx); + } +} + int pl011_init_port (struct console_device *cdev) { struct amba_uart_port *uart = to_amba_uart_port(cdev); @@ -140,8 +174,7 @@ int pl011_init_port (struct console_device *cdev) /* ** Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled. */ - writel((UART01x_LCRH_WLEN_8 | UART01x_LCRH_FEN), - uart->base + UART011_LCRH); + pl011_rlcr(uart, UART01x_LCRH_WLEN_8 | UART01x_LCRH_FEN); /* ** Finally, enable the UART @@ -160,6 +193,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) uart = xzalloc(sizeof(struct amba_uart_port)); uart->clk = clk_get(&dev->dev, NULL); uart->base = amba_get_mem_region(dev); + uart->vendor = (void*)id->data; if (IS_ERR(uart->clk)) return PTR_ERR(uart->clk); @@ -185,10 +219,12 @@ static struct amba_id pl011_ids[] = { { .id = 0x00041011, .mask = 0x000fffff, + .data = &vendor_arm, }, { .id = 0x00380802, .mask = 0x00ffffff, + .data = &vendor_st, }, { 0, 0 }, }; |