ARM: PL011: add DMA burst threshold support for ST variants
authorRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 22 Dec 2010 17:59:16 +0000 (17:59 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 5 Jan 2011 16:58:53 +0000 (16:58 +0000)
ST Micro variants has some specific dma burst threshold compensation,
which allows them to make better use of a DMA controller.  Add support
to set this up.

Based on a patch from Linus Walleij.

Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
drivers/serial/amba-pl011.c
include/linux/amba/serial.h

index ab025dc52fa462c08d1cc062258e86a0c5f413e1..e76d7d000128f9060a2993c7912cc8e18b70d6c2 100644 (file)
@@ -74,6 +74,7 @@ struct vendor_data {
        unsigned int            lcrh_tx;
        unsigned int            lcrh_rx;
        bool                    oversampling;
+       bool                    dma_threshold;
 };
 
 static struct vendor_data vendor_arm = {
@@ -82,6 +83,7 @@ static struct vendor_data vendor_arm = {
        .lcrh_tx                = UART011_LCRH,
        .lcrh_rx                = UART011_LCRH,
        .oversampling           = false,
+       .dma_threshold          = false,
 };
 
 static struct vendor_data vendor_st = {
@@ -90,6 +92,7 @@ static struct vendor_data vendor_st = {
        .lcrh_tx                = ST_UART011_LCRH_TX,
        .lcrh_rx                = ST_UART011_LCRH_RX,
        .oversampling           = true,
+       .dma_threshold          = true,
 };
 
 /* Deals with DMA transactions */
@@ -527,6 +530,15 @@ static void pl011_dma_startup(struct uart_amba_port *uap)
        /* Turn on DMA error (RX/TX will be enabled on demand) */
        uap->dmacr |= UART011_DMAONERR;
        writew(uap->dmacr, uap->port.membase + UART011_DMACR);
+
+       /*
+        * ST Micro variants has some specific dma burst threshold
+        * compensation. Set this to 16 bytes, so burst will only
+        * be issued above/below 16 bytes.
+        */
+       if (uap->vendor->dma_threshold)
+               writew(ST_UART011_DMAWM_RX_16 | ST_UART011_DMAWM_TX_16,
+                              uap->port.membase + ST_UART011_DMAWM);
 }
 
 static void pl011_dma_shutdown(struct uart_amba_port *uap)
index 577f22eb922525250d3f5460c3cd9521a5cbd8ff..5479fdc849e9432d9b162c399205c59faf8250c6 100644 (file)
 #define UART01x_LCRH_PEN       0x02
 #define UART01x_LCRH_BRK       0x01
 
+#define ST_UART011_DMAWM_RX_1  (0 << 3)
+#define ST_UART011_DMAWM_RX_2  (1 << 3)
+#define ST_UART011_DMAWM_RX_4  (2 << 3)
+#define ST_UART011_DMAWM_RX_8  (3 << 3)
+#define ST_UART011_DMAWM_RX_16 (4 << 3)
+#define ST_UART011_DMAWM_RX_32 (5 << 3)
+#define ST_UART011_DMAWM_RX_48 (6 << 3)
+#define ST_UART011_DMAWM_TX_1  0
+#define ST_UART011_DMAWM_TX_2  1
+#define ST_UART011_DMAWM_TX_4  2
+#define ST_UART011_DMAWM_TX_8  3
+#define ST_UART011_DMAWM_TX_16 4
+#define ST_UART011_DMAWM_TX_32 5
+#define ST_UART011_DMAWM_TX_48 6
+
 #define UART010_IIR_RTIS       0x08
 #define UART010_IIR_TIS                0x04
 #define UART010_IIR_RIS                0x02