summaryrefslogtreecommitdiffstats
path: root/drivers/serial/amba-pl011.c
diff options
context:
space:
mode:
authorJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2012-08-17 19:47:00 +0800
committerJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2012-09-11 12:48:34 +0800
commit75a0136ccae3899aee91f1d8d38274c426f99175 (patch)
tree2d717500e0dcad0ddbadf263d9717886586af9cc /drivers/serial/amba-pl011.c
parent09d593b6706a09b22d41cb831548a6b08289660a (diff)
downloadbarebox-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.c40
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 },
};