* [PATCH v2 0/6] tty: serial: msm: Add DMA support and fix bit definitions
@ 2015-09-30 12:08 Ivan T. Ivanov
2015-09-30 12:08 ` [PATCH v2 1/6] tty: serial: msm: Add mask value for UART_DM registers Ivan T. Ivanov
` (6 more replies)
0 siblings, 7 replies; 13+ messages in thread
From: Ivan T. Ivanov @ 2015-09-30 12:08 UTC (permalink / raw)
To: Andy Gross
Cc: David Brown, Srinivas Kandagatla, Greg Kroah-Hartman, Jiri Slaby,
Frank Rowand, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
devicetree, linux-kernel, linux-arm-msm, linux-soc, linux-serial
Hi,
This is second version of patches which DMA support for UARTDM type
of hardware found in Qualcomm chip sets.
Changes since v0 (https://lkml.org/lkml/2015/9/12/108):
* Fixed SysRq issue reported by Srini.
* Dropped [PATCH 3/7], which did not make any functional change.
Ivan T. Ivanov (4):
tty: serial: msm: Add msm prefix to all driver functions
tty: serial: msm: Add TX DMA support
tty: serial: msm: Add RX DMA support
tty: serial: msm: Remove 115.2 Kbps maximum baud rate limitation
Pramod Gurav (2):
tty: serial: msm: Add mask value for UART_DM registers
tty: serial: msm: replaces (1 << x) with BIT(x) macro
.../devicetree/bindings/serial/qcom,msm-uartdm.txt | 6 +
drivers/tty/serial/msm_serial.c | 620 +++++++++++++++++++--
drivers/tty/serial/msm_serial.h | 53 +-
3 files changed, 606 insertions(+), 73 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 1/6] tty: serial: msm: Add mask value for UART_DM registers
2015-09-30 12:08 [PATCH v2 0/6] tty: serial: msm: Add DMA support and fix bit definitions Ivan T. Ivanov
@ 2015-09-30 12:08 ` Ivan T. Ivanov
2015-09-30 12:08 ` [PATCH v2 2/6] tty: serial: msm: replaces (1 << x) with BIT(x) macro Ivan T. Ivanov
` (5 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Ivan T. Ivanov @ 2015-09-30 12:08 UTC (permalink / raw)
To: Andy Gross
Cc: Pramod Gurav, David Brown, Srinivas Kandagatla,
Greg Kroah-Hartman, Jiri Slaby, Frank Rowand, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, devicetree, linux-kernel,
linux-arm-msm, linux-soc, linux-serial
From: Pramod Gurav <gpramod@codeaurora.org>
The bit masks for RFR_LEVEL1 and STALE_TIMEOUT_MSB values in MR1 and
IPR registers respectively are different for UART and UART_DM hardware
cores. We have been using UART core mask values for these. Add the same
for UART_DM core.
There is no bit setting as UART_IPR_RXSTALE_LAST for UART_DM core so do
it only for UART core.
Signed-off-by: Pramod Gurav <gpramod@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ivan T. Ivanov <ivan.ivanov@linaro.org>
---
drivers/tty/serial/msm_serial.c | 26 ++++++++++++++++++++------
drivers/tty/serial/msm_serial.h | 2 ++
2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index b73889c8ed4b..d08cfd3e1c3a 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -421,7 +421,7 @@ msm_find_best_baud(struct uart_port *port, unsigned int baud)
static int msm_set_baud_rate(struct uart_port *port, unsigned int baud)
{
- unsigned int rxstale, watermark;
+ unsigned int rxstale, watermark, mask;
struct msm_port *msm_port = UART_TO_MSM(port);
const struct msm_baud_map *entry;
@@ -432,8 +432,15 @@ static int msm_set_baud_rate(struct uart_port *port, unsigned int baud)
/* RX stale watermark */
rxstale = entry->rxstale;
watermark = UART_IPR_STALE_LSB & rxstale;
- watermark |= UART_IPR_RXSTALE_LAST;
- watermark |= UART_IPR_STALE_TIMEOUT_MSB & (rxstale << 2);
+ if (msm_port->is_uartdm) {
+ mask = UART_DM_IPR_STALE_TIMEOUT_MSB;
+ } else {
+ watermark |= UART_IPR_RXSTALE_LAST;
+ mask = UART_IPR_STALE_TIMEOUT_MSB;
+ }
+
+ watermark |= mask & (rxstale << 2);
+
msm_write(port, watermark, UART_IPR);
/* set RX watermark */
@@ -476,7 +483,7 @@ static void msm_init_clock(struct uart_port *port)
static int msm_startup(struct uart_port *port)
{
struct msm_port *msm_port = UART_TO_MSM(port);
- unsigned int data, rfr_level;
+ unsigned int data, rfr_level, mask;
int ret;
snprintf(msm_port->name, sizeof(msm_port->name),
@@ -496,11 +503,18 @@ static int msm_startup(struct uart_port *port)
/* set automatic RFR level */
data = msm_read(port, UART_MR1);
- data &= ~UART_MR1_AUTO_RFR_LEVEL1;
+
+ if (msm_port->is_uartdm)
+ mask = UART_DM_MR1_AUTO_RFR_LEVEL1;
+ else
+ mask = UART_MR1_AUTO_RFR_LEVEL1;
+
+ data &= ~mask;
data &= ~UART_MR1_AUTO_RFR_LEVEL0;
- data |= UART_MR1_AUTO_RFR_LEVEL1 & (rfr_level << 2);
+ data |= mask & (rfr_level << 2);
data |= UART_MR1_AUTO_RFR_LEVEL0 & rfr_level;
msm_write(port, data, UART_MR1);
+
return 0;
}
diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h
index 737f69fe7113..5b7722c3938b 100644
--- a/drivers/tty/serial/msm_serial.h
+++ b/drivers/tty/serial/msm_serial.h
@@ -20,6 +20,7 @@
#define UART_MR1_AUTO_RFR_LEVEL0 0x3F
#define UART_MR1_AUTO_RFR_LEVEL1 0x3FF00
+#define UART_DM_MR1_AUTO_RFR_LEVEL1 0xFFFFFF00
#define UART_MR1_RX_RDY_CTL (1 << 7)
#define UART_MR1_CTS_CTL (1 << 6)
@@ -78,6 +79,7 @@
#define UART_IPR_RXSTALE_LAST 0x20
#define UART_IPR_STALE_LSB 0x1F
#define UART_IPR_STALE_TIMEOUT_MSB 0x3FF80
+#define UART_DM_IPR_STALE_TIMEOUT_MSB 0xFFFFFF80
#define UART_IPR 0x0018
#define UART_TFWR 0x001C
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 2/6] tty: serial: msm: replaces (1 << x) with BIT(x) macro
2015-09-30 12:08 [PATCH v2 0/6] tty: serial: msm: Add DMA support and fix bit definitions Ivan T. Ivanov
2015-09-30 12:08 ` [PATCH v2 1/6] tty: serial: msm: Add mask value for UART_DM registers Ivan T. Ivanov
@ 2015-09-30 12:08 ` Ivan T. Ivanov
2015-09-30 12:08 ` [PATCH v2 3/6] tty: serial: msm: Add msm prefix to all driver functions Ivan T. Ivanov
` (4 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Ivan T. Ivanov @ 2015-09-30 12:08 UTC (permalink / raw)
To: Andy Gross
Cc: Pramod Gurav, David Brown, Srinivas Kandagatla,
Greg Kroah-Hartman, Jiri Slaby, Frank Rowand, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, devicetree, linux-kernel,
linux-arm-msm, linux-soc, linux-serial
From: Pramod Gurav <gpramod@codeaurora.org>
Replaces (1 << x) with BIT(x) macro
Signed-off-by: Pramod Gurav <gpramod@codeaurora.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Ivan T. Ivanov <ivan.ivanov@linaro.org>
---
drivers/tty/serial/msm_serial.h | 44 ++++++++++++++++++++---------------------
1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h
index 5b7722c3938b..60917d30c6b5 100644
--- a/drivers/tty/serial/msm_serial.h
+++ b/drivers/tty/serial/msm_serial.h
@@ -21,11 +21,11 @@
#define UART_MR1_AUTO_RFR_LEVEL0 0x3F
#define UART_MR1_AUTO_RFR_LEVEL1 0x3FF00
#define UART_DM_MR1_AUTO_RFR_LEVEL1 0xFFFFFF00
-#define UART_MR1_RX_RDY_CTL (1 << 7)
-#define UART_MR1_CTS_CTL (1 << 6)
+#define UART_MR1_RX_RDY_CTL BIT(7)
+#define UART_MR1_CTS_CTL BIT(6)
#define UART_MR2 0x0004
-#define UART_MR2_ERROR_MODE (1 << 6)
+#define UART_MR2_ERROR_MODE BIT(6)
#define UART_MR2_BITS_PER_CHAR 0x30
#define UART_MR2_BITS_PER_CHAR_5 (0x0 << 4)
#define UART_MR2_BITS_PER_CHAR_6 (0x1 << 4)
@@ -62,19 +62,19 @@
#define UART_CR_CMD_STALE_EVENT_ENABLE (80 << 4)
#define UART_CR_CMD_FORCE_STALE (4 << 8)
#define UART_CR_CMD_RESET_TX_READY (3 << 8)
-#define UART_CR_TX_DISABLE (1 << 3)
-#define UART_CR_TX_ENABLE (1 << 2)
-#define UART_CR_RX_DISABLE (1 << 1)
-#define UART_CR_RX_ENABLE (1 << 0)
+#define UART_CR_TX_DISABLE BIT(3)
+#define UART_CR_TX_ENABLE BIT(2)
+#define UART_CR_RX_DISABLE BIT(1)
+#define UART_CR_RX_ENABLE BIT(0)
#define UART_CR_CMD_RESET_RXBREAK_START ((1 << 11) | (2 << 4))
#define UART_IMR 0x0014
-#define UART_IMR_TXLEV (1 << 0)
-#define UART_IMR_RXSTALE (1 << 3)
-#define UART_IMR_RXLEV (1 << 4)
-#define UART_IMR_DELTA_CTS (1 << 5)
-#define UART_IMR_CURRENT_CTS (1 << 6)
-#define UART_IMR_RXBREAK_START (1 << 10)
+#define UART_IMR_TXLEV BIT(0)
+#define UART_IMR_RXSTALE BIT(3)
+#define UART_IMR_RXLEV BIT(4)
+#define UART_IMR_DELTA_CTS BIT(5)
+#define UART_IMR_CURRENT_CTS BIT(6)
+#define UART_IMR_RXBREAK_START BIT(10)
#define UART_IPR_RXSTALE_LAST 0x20
#define UART_IPR_STALE_LSB 0x1F
@@ -98,20 +98,20 @@
#define UART_TEST_CTRL 0x0050
#define UART_SR 0x0008
-#define UART_SR_HUNT_CHAR (1 << 7)
-#define UART_SR_RX_BREAK (1 << 6)
-#define UART_SR_PAR_FRAME_ERR (1 << 5)
-#define UART_SR_OVERRUN (1 << 4)
-#define UART_SR_TX_EMPTY (1 << 3)
-#define UART_SR_TX_READY (1 << 2)
-#define UART_SR_RX_FULL (1 << 1)
-#define UART_SR_RX_READY (1 << 0)
+#define UART_SR_HUNT_CHAR BIT(7)
+#define UART_SR_RX_BREAK BIT(6)
+#define UART_SR_PAR_FRAME_ERR BIT(5)
+#define UART_SR_OVERRUN BIT(4)
+#define UART_SR_TX_EMPTY BIT(3)
+#define UART_SR_TX_READY BIT(2)
+#define UART_SR_RX_FULL BIT(1)
+#define UART_SR_RX_READY BIT(0)
#define UART_RF 0x000C
#define UARTDM_RF 0x0070
#define UART_MISR 0x0010
#define UART_ISR 0x0014
-#define UART_ISR_TX_READY (1 << 7)
+#define UART_ISR_TX_READY BIT(7)
#define UARTDM_RXFS 0x50
#define UARTDM_RXFS_BUF_SHIFT 0x7
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 3/6] tty: serial: msm: Add msm prefix to all driver functions
2015-09-30 12:08 [PATCH v2 0/6] tty: serial: msm: Add DMA support and fix bit definitions Ivan T. Ivanov
2015-09-30 12:08 ` [PATCH v2 1/6] tty: serial: msm: Add mask value for UART_DM registers Ivan T. Ivanov
2015-09-30 12:08 ` [PATCH v2 2/6] tty: serial: msm: replaces (1 << x) with BIT(x) macro Ivan T. Ivanov
@ 2015-09-30 12:08 ` Ivan T. Ivanov
2015-09-30 12:08 ` [PATCH v2 4/6] tty: serial: msm: Add TX DMA support Ivan T. Ivanov
` (3 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Ivan T. Ivanov @ 2015-09-30 12:08 UTC (permalink / raw)
To: Andy Gross
Cc: David Brown, Srinivas Kandagatla, Greg Kroah-Hartman, Jiri Slaby,
Frank Rowand, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
devicetree, linux-kernel, linux-arm-msm, linux-soc, linux-serial
Make function naming consistent across this driver.
Also rename msm_irq to msm_uart_irq. No functional changes.
Signed-off-by: Ivan T. Ivanov <ivan.ivanov@linaro.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
---
drivers/tty/serial/msm_serial.c | 40 ++++++++++++++++++++--------------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index d08cfd3e1c3a..e33966280606 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -57,7 +57,7 @@ struct msm_port {
bool break_detected;
};
-static inline void wait_for_xmitr(struct uart_port *port)
+static inline void msm_wait_for_xmitr(struct uart_port *port)
{
while (!(msm_read(port, UART_SR) & UART_SR_TX_EMPTY)) {
if (msm_read(port, UART_ISR) & UART_ISR_TX_READY)
@@ -99,7 +99,7 @@ static void msm_enable_ms(struct uart_port *port)
msm_write(port, msm_port->imr, UART_IMR);
}
-static void handle_rx_dm(struct uart_port *port, unsigned int misr)
+static void msm_handle_rx_dm(struct uart_port *port, unsigned int misr)
{
struct tty_port *tport = &port->state->port;
unsigned int sr;
@@ -171,7 +171,7 @@ static void handle_rx_dm(struct uart_port *port, unsigned int misr)
msm_write(port, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR);
}
-static void handle_rx(struct uart_port *port)
+static void msm_handle_rx(struct uart_port *port)
{
struct tty_port *tport = &port->state->port;
unsigned int sr;
@@ -224,14 +224,14 @@ static void handle_rx(struct uart_port *port)
spin_lock(&port->lock);
}
-static void reset_dm_count(struct uart_port *port, int count)
+static void msm_reset_dm_count(struct uart_port *port, int count)
{
- wait_for_xmitr(port);
+ msm_wait_for_xmitr(port);
msm_write(port, count, UARTDM_NCF_TX);
msm_read(port, UARTDM_NCF_TX);
}
-static void handle_tx(struct uart_port *port)
+static void msm_handle_tx(struct uart_port *port)
{
struct circ_buf *xmit = &port->state->xmit;
struct msm_port *msm_port = UART_TO_MSM(port);
@@ -250,13 +250,13 @@ static void handle_tx(struct uart_port *port)
if (port->x_char) {
if (msm_port->is_uartdm)
- reset_dm_count(port, tx_count + 1);
+ msm_reset_dm_count(port, tx_count + 1);
iowrite8_rep(tf, &port->x_char, 1);
port->icount.tx++;
port->x_char = 0;
} else if (tx_count && msm_port->is_uartdm) {
- reset_dm_count(port, tx_count);
+ msm_reset_dm_count(port, tx_count);
}
while (tf_pointer < tx_count) {
@@ -290,14 +290,14 @@ static void handle_tx(struct uart_port *port)
uart_write_wakeup(port);
}
-static void handle_delta_cts(struct uart_port *port)
+static void msm_handle_delta_cts(struct uart_port *port)
{
msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR);
port->icount.cts++;
wake_up_interruptible(&port->state->port.delta_msr_wait);
}
-static irqreturn_t msm_irq(int irq, void *dev_id)
+static irqreturn_t msm_uart_irq(int irq, void *dev_id)
{
struct uart_port *port = dev_id;
struct msm_port *msm_port = UART_TO_MSM(port);
@@ -314,14 +314,14 @@ static irqreturn_t msm_irq(int irq, void *dev_id)
if (misr & (UART_IMR_RXLEV | UART_IMR_RXSTALE)) {
if (msm_port->is_uartdm)
- handle_rx_dm(port, misr);
+ msm_handle_rx_dm(port, misr);
else
- handle_rx(port);
+ msm_handle_rx(port);
}
if (misr & UART_IMR_TXLEV)
- handle_tx(port);
+ msm_handle_tx(port);
if (misr & UART_IMR_DELTA_CTS)
- handle_delta_cts(port);
+ msm_handle_delta_cts(port);
msm_write(port, msm_port->imr, UART_IMR); /* restore interrupt */
spin_unlock(&port->lock);
@@ -779,7 +779,7 @@ static void msm_poll_put_char(struct uart_port *port, unsigned char c)
msm_write(port, 0, UART_IMR);
if (msm_port->is_uartdm)
- reset_dm_count(port, 1);
+ msm_reset_dm_count(port, 1);
/* Wait until FIFO is empty */
while (!(msm_read(port, UART_SR) & UART_SR_TX_READY))
@@ -853,7 +853,7 @@ static struct msm_port msm_uart_ports[] = {
#define UART_NR ARRAY_SIZE(msm_uart_ports)
-static inline struct uart_port *get_port_from_line(unsigned int line)
+static inline struct uart_port *msm_get_port_from_line(unsigned int line)
{
return &msm_uart_ports[line].uart;
}
@@ -880,7 +880,7 @@ static void __msm_console_write(struct uart_port *port, const char *s,
spin_lock(&port->lock);
if (is_uartdm)
- reset_dm_count(port, count);
+ msm_reset_dm_count(port, count);
i = 0;
while (i < count) {
@@ -925,7 +925,7 @@ static void msm_console_write(struct console *co, const char *s,
BUG_ON(co->index < 0 || co->index >= UART_NR);
- port = get_port_from_line(co->index);
+ port = msm_get_port_from_line(co->index);
msm_port = UART_TO_MSM(port);
__msm_console_write(port, s, count, msm_port->is_uartdm);
@@ -942,7 +942,7 @@ static int __init msm_console_setup(struct console *co, char *options)
if (unlikely(co->index >= UART_NR || co->index < 0))
return -ENXIO;
- port = get_port_from_line(co->index);
+ port = msm_get_port_from_line(co->index);
if (unlikely(!port->membase))
return -ENXIO;
@@ -1057,7 +1057,7 @@ static int msm_serial_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "msm_serial: detected port #%d\n", line);
- port = get_port_from_line(line);
+ port = msm_get_port_from_line(line);
port->dev = &pdev->dev;
msm_port = UART_TO_MSM(port);
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 4/6] tty: serial: msm: Add TX DMA support
2015-09-30 12:08 [PATCH v2 0/6] tty: serial: msm: Add DMA support and fix bit definitions Ivan T. Ivanov
` (2 preceding siblings ...)
2015-09-30 12:08 ` [PATCH v2 3/6] tty: serial: msm: Add msm prefix to all driver functions Ivan T. Ivanov
@ 2015-09-30 12:08 ` Ivan T. Ivanov
2015-09-30 13:29 ` Mark Rutland
2015-09-30 12:08 ` [PATCH v2 5/6] tty: serial: msm: Add RX " Ivan T. Ivanov
` (2 subsequent siblings)
6 siblings, 1 reply; 13+ messages in thread
From: Ivan T. Ivanov @ 2015-09-30 12:08 UTC (permalink / raw)
To: Andy Gross
Cc: David Brown, Srinivas Kandagatla, Greg Kroah-Hartman, Jiri Slaby,
Frank Rowand, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
devicetree, linux-kernel, linux-arm-msm, linux-soc, linux-serial
Add transmit DMA support for UARTDM type of controllers.
Tested on APQ8064, which have UARTDM v1.3 and ADM DMA engine
and APQ8016, which have UARTDM v1.4 and BAM DMA engine.
Signed-off-by: Ivan T. Ivanov <ivan.ivanov@linaro.org>
---
.../devicetree/bindings/serial/qcom,msm-uartdm.txt | 3 +
drivers/tty/serial/msm_serial.c | 312 +++++++++++++++++++--
drivers/tty/serial/msm_serial.h | 3 +
3 files changed, 294 insertions(+), 24 deletions(-)
diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
index a2114c217376..a600023d9ec1 100644
--- a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
+++ b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
@@ -26,6 +26,9 @@ Required properties:
Optional properties:
- dmas: Should contain dma specifiers for transmit and receive channels
- dma-names: Should contain "tx" for transmit and "rx" for receive channels
+- qcom,tx-crci: Identificator <u32> for Client Rate Control Interface to be
+ used with TX DMA channel. Required when using DMA for transmission
+ with UARTDM v1.3 and bellow.
Note: Aliases may be defined to ensure the correct ordering of the UARTs.
The alias serialN will result in the UART being assigned port N. If any
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index e33966280606..2f395f5d78d0 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -20,6 +20,8 @@
#endif
#include <linux/atomic.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
#include <linux/hrtimer.h>
#include <linux/module.h>
#include <linux/io.h>
@@ -39,6 +41,10 @@
#include "msm_serial.h"
+#define UARTDM_BURST_SIZE 16 /* in bytes */
+#define UARTDM_TX_AIGN(x) ((x) & ~0x3) /* valid for > 1p3 */
+#define UARTDM_TX_MAX 256 /* in bytes, valid for <= 1p3 */
+
enum {
UARTDM_1P1 = 1,
UARTDM_1P2,
@@ -46,6 +52,17 @@ enum {
UARTDM_1P4,
};
+struct msm_dma {
+ struct dma_chan *chan;
+ enum dma_data_direction dir;
+ dma_addr_t phys;
+ unsigned char *virt;
+ dma_cookie_t cookie;
+ u32 enable_bit;
+ unsigned int count;
+ struct dma_async_tx_descriptor *desc;
+};
+
struct msm_port {
struct uart_port uart;
char name[16];
@@ -55,8 +72,93 @@ struct msm_port {
int is_uartdm;
unsigned int old_snap_state;
bool break_detected;
+ struct msm_dma tx_dma;
};
+static void msm_handle_tx(struct uart_port *port);
+
+void msm_stop_dma(struct uart_port *port, struct msm_dma *dma)
+{
+ struct device *dev = port->dev;
+ unsigned int mapped;
+ u32 val;
+
+ mapped = dma->count;
+ dma->count = 0;
+
+ dmaengine_terminate_all(dma->chan);
+
+ /*
+ * DMA Stall happens if enqueue and flush command happens concurrently.
+ * For example before changing the baud rate/protocol configuration and
+ * sending flush command to ADM, disable the channel of UARTDM.
+ * Note: should not reset the receiver here immediately as it is not
+ * suggested to do disable/reset or reset/disable at the same time.
+ */
+ val = msm_read(port, UARTDM_DMEN);
+ val &= ~dma->enable_bit;
+ msm_write(port, val, UARTDM_DMEN);
+
+ if (mapped)
+ dma_unmap_single(dev, dma->phys, mapped, dma->dir);
+}
+
+static void msm_release_dma(struct msm_port *msm_port)
+{
+ struct msm_dma *dma;
+
+ dma = &msm_port->tx_dma;
+ if (dma->chan) {
+ msm_stop_dma(&msm_port->uart, dma);
+ dma_release_channel(dma->chan);
+ }
+
+ memset(dma, 0, sizeof(*dma));
+}
+
+static void msm_request_tx_dma(struct msm_port *msm_port, resource_size_t base)
+{
+ struct device *dev = msm_port->uart.dev;
+ struct dma_slave_config conf;
+ struct msm_dma *dma;
+ u32 crci = 0;
+ int ret;
+
+ dma = &msm_port->tx_dma;
+
+ /* allocate DMA resources, if available */
+ dma->chan = dma_request_slave_channel_reason(dev, "tx");
+ if (IS_ERR(dma->chan))
+ goto no_tx;
+
+ of_property_read_u32(dev->of_node, "qcom,tx-crci", &crci);
+
+ memset(&conf, 0, sizeof(conf));
+ conf.direction = DMA_MEM_TO_DEV;
+ conf.device_fc = true;
+ conf.dst_addr = base + UARTDM_TF;
+ conf.dst_maxburst = UARTDM_BURST_SIZE;
+ conf.slave_id = crci;
+
+ ret = dmaengine_slave_config(dma->chan, &conf);
+ if (ret)
+ goto rel_tx;
+
+ dma->dir = DMA_TO_DEVICE;
+
+ if (msm_port->is_uartdm < UARTDM_1P4)
+ dma->enable_bit = UARTDM_DMEN_TX_DM_ENABLE;
+ else
+ dma->enable_bit = UARTDM_DMEN_TX_BAM_ENABLE;
+
+ return;
+
+rel_tx:
+ dma_release_channel(dma->chan);
+no_tx:
+ memset(dma, 0, sizeof(*dma));
+}
+
static inline void msm_wait_for_xmitr(struct uart_port *port)
{
while (!(msm_read(port, UART_SR) & UART_SR_TX_EMPTY)) {
@@ -78,11 +180,132 @@ static void msm_stop_tx(struct uart_port *port)
static void msm_start_tx(struct uart_port *port)
{
struct msm_port *msm_port = UART_TO_MSM(port);
+ struct msm_dma *dma = &msm_port->tx_dma;
+
+ /* Already started in DMA mode */
+ if (dma->count)
+ return;
+
+ msm_port->imr |= UART_IMR_TXLEV;
+ msm_write(port, msm_port->imr, UART_IMR);
+}
+
+static void msm_reset_dm_count(struct uart_port *port, int count)
+{
+ msm_wait_for_xmitr(port);
+ msm_write(port, count, UARTDM_NCF_TX);
+ msm_read(port, UARTDM_NCF_TX);
+}
+
+static void msm_complete_tx_dma(void *args)
+{
+ struct msm_port *msm_port = args;
+ struct uart_port *port = &msm_port->uart;
+ struct circ_buf *xmit = &port->state->xmit;
+ struct msm_dma *dma = &msm_port->tx_dma;
+ struct dma_tx_state state;
+ enum dma_status status;
+ unsigned long flags;
+ unsigned int count;
+ u32 val;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ /* Already stopped */
+ if (!dma->count)
+ goto done;
+
+ status = dmaengine_tx_status(dma->chan, dma->cookie, &state);
+ dma_unmap_single(port->dev, dma->phys, dma->count, dma->dir);
+
+ val = msm_read(port, UARTDM_DMEN);
+ val &= ~dma->enable_bit;
+ msm_write(port, val, UARTDM_DMEN);
+
+ if (msm_port->is_uartdm > UARTDM_1P3) {
+ msm_write(port, UART_CR_CMD_RESET_TX, UART_CR);
+ msm_write(port, UART_CR_TX_ENABLE, UART_CR);
+ }
+
+ count = dma->count - state.residue;
+ port->icount.tx += count;
+ dma->count = 0;
+
+ xmit->tail += count;
+ xmit->tail &= UART_XMIT_SIZE - 1;
+
+ /* Restore "Tx FIFO below watermark" interrupt */
msm_port->imr |= UART_IMR_TXLEV;
msm_write(port, msm_port->imr, UART_IMR);
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(port);
+
+ msm_handle_tx(port);
+done:
+ spin_unlock_irqrestore(&port->lock, flags);
}
+static int msm_handle_tx_dma(struct msm_port *msm_port, unsigned int count)
+{
+ struct circ_buf *xmit = &msm_port->uart.state->xmit;
+ struct uart_port *port = &msm_port->uart;
+ struct msm_dma *dma = &msm_port->tx_dma;
+ void *cpu_addr;
+ int ret;
+ u32 val;
+
+ cpu_addr = &xmit->buf[xmit->tail];
+
+ dma->phys = dma_map_single(port->dev, cpu_addr, count, dma->dir);
+ ret = dma_mapping_error(port->dev, dma->phys);
+ if (ret)
+ return ret;
+
+ dma->desc = dmaengine_prep_slave_single(dma->chan, dma->phys,
+ count, DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT |
+ DMA_PREP_FENCE);
+ if (!dma->desc) {
+ ret = -EIO;
+ goto unmap;
+ }
+
+ dma->desc->callback = msm_complete_tx_dma;
+ dma->desc->callback_param = msm_port;
+
+ dma->cookie = dmaengine_submit(dma->desc);
+ ret = dma_submit_error(dma->cookie);
+ if (ret)
+ goto unmap;
+
+ /*
+ * Using DMA complete for Tx FIFO reload, no need for
+ * "Tx FIFO below watermark" one, disable it
+ */
+ msm_port->imr &= ~UART_IMR_TXLEV;
+ msm_write(port, msm_port->imr, UART_IMR);
+
+ dma->count = count;
+
+ val = msm_read(port, UARTDM_DMEN);
+ val |= dma->enable_bit;
+
+ if (msm_port->is_uartdm < UARTDM_1P4)
+ msm_write(port, val, UARTDM_DMEN);
+
+ msm_reset_dm_count(port, count);
+
+ if (msm_port->is_uartdm > UARTDM_1P3)
+ msm_write(port, val, UARTDM_DMEN);
+
+ dma_async_issue_pending(dma->chan);
+ return 0;
+unmap:
+ dma_unmap_single(port->dev, dma->phys, count, dma->dir);
+ return ret;
+}
static void msm_stop_rx(struct uart_port *port)
{
struct msm_port *msm_port = UART_TO_MSM(port);
@@ -224,18 +447,11 @@ static void msm_handle_rx(struct uart_port *port)
spin_lock(&port->lock);
}
-static void msm_reset_dm_count(struct uart_port *port, int count)
-{
- msm_wait_for_xmitr(port);
- msm_write(port, count, UARTDM_NCF_TX);
- msm_read(port, UARTDM_NCF_TX);
-}
-
-static void msm_handle_tx(struct uart_port *port)
+static void msm_handle_tx_pio(struct uart_port *port, unsigned int tx_count)
{
struct circ_buf *xmit = &port->state->xmit;
struct msm_port *msm_port = UART_TO_MSM(port);
- unsigned int tx_count, num_chars;
+ unsigned int num_chars;
unsigned int tf_pointer = 0;
void __iomem *tf;
@@ -244,20 +460,8 @@ static void msm_handle_tx(struct uart_port *port)
else
tf = port->membase + UART_TF;
- tx_count = uart_circ_chars_pending(xmit);
- tx_count = min3(tx_count, (unsigned int)UART_XMIT_SIZE - xmit->tail,
- port->fifosize);
-
- if (port->x_char) {
- if (msm_port->is_uartdm)
- msm_reset_dm_count(port, tx_count + 1);
-
- iowrite8_rep(tf, &port->x_char, 1);
- port->icount.tx++;
- port->x_char = 0;
- } else if (tx_count && msm_port->is_uartdm) {
+ if (tx_count && msm_port->is_uartdm)
msm_reset_dm_count(port, tx_count);
- }
while (tf_pointer < tx_count) {
int i;
@@ -290,6 +494,59 @@ static void msm_handle_tx(struct uart_port *port)
uart_write_wakeup(port);
}
+static void msm_handle_tx(struct uart_port *port)
+{
+ struct msm_port *msm_port = UART_TO_MSM(port);
+ struct circ_buf *xmit = &msm_port->uart.state->xmit;
+ struct msm_dma *dma = &msm_port->tx_dma;
+ unsigned int pio_count, dma_count, dma_min;
+ void __iomem *tf;
+ int err = 0;
+
+ if (port->x_char) {
+ if (msm_port->is_uartdm)
+ tf = port->membase + UARTDM_TF;
+ else
+ tf = port->membase + UART_TF;
+
+ if (msm_port->is_uartdm)
+ msm_reset_dm_count(port, 1);
+
+ iowrite8_rep(tf, &port->x_char, 1);
+ port->icount.tx++;
+ port->x_char = 0;
+ return;
+ }
+
+ if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
+ msm_stop_tx(port);
+ return;
+ }
+
+ pio_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE);
+ dma_count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
+
+ dma_min = 1; /* Always DMA */
+ if (msm_port->is_uartdm > UARTDM_1P3) {
+ dma_count = UARTDM_TX_AIGN(dma_count);
+ dma_min = UARTDM_BURST_SIZE;
+ } else {
+ if (dma_count > UARTDM_TX_MAX)
+ dma_count = UARTDM_TX_MAX;
+ }
+
+ if (pio_count > port->fifosize)
+ pio_count = port->fifosize;
+
+ if (!dma->chan || dma_count < dma_min)
+ msm_handle_tx_pio(port, pio_count);
+ else
+ err = msm_handle_tx_dma(msm_port, dma_count);
+
+ if (err) /* fall back to PIO mode */
+ msm_handle_tx_pio(port, pio_count);
+}
+
static void msm_handle_delta_cts(struct uart_port *port)
{
msm_write(port, UART_CR_CMD_RESET_CTS, UART_CR);
@@ -301,9 +558,10 @@ static irqreturn_t msm_uart_irq(int irq, void *dev_id)
{
struct uart_port *port = dev_id;
struct msm_port *msm_port = UART_TO_MSM(port);
+ unsigned long flags;
unsigned int misr;
- spin_lock(&port->lock);
+ spin_lock_irqsave(&port->lock, flags);
misr = msm_read(port, UART_MISR);
msm_write(port, 0, UART_IMR); /* disable interrupt */
@@ -324,7 +582,7 @@ static irqreturn_t msm_uart_irq(int irq, void *dev_id)
msm_handle_delta_cts(port);
msm_write(port, msm_port->imr, UART_IMR); /* restore interrupt */
- spin_unlock(&port->lock);
+ spin_unlock_irqrestore(&port->lock, flags);
return IRQ_HANDLED;
}
@@ -515,6 +773,9 @@ static int msm_startup(struct uart_port *port)
data |= UART_MR1_AUTO_RFR_LEVEL0 & rfr_level;
msm_write(port, data, UART_MR1);
+ if (msm_port->is_uartdm)
+ msm_request_tx_dma(msm_port, msm_port->uart.mapbase);
+
return 0;
}
@@ -525,6 +786,9 @@ static void msm_shutdown(struct uart_port *port)
msm_port->imr = 0;
msm_write(port, 0, UART_IMR); /* disable interrupts */
+ if (msm_port->is_uartdm)
+ msm_release_dma(msm_port);
+
clk_disable_unprepare(msm_port->clk);
free_irq(port->irq, port);
diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h
index 60917d30c6b5..103ae61b9d06 100644
--- a/drivers/tty/serial/msm_serial.h
+++ b/drivers/tty/serial/msm_serial.h
@@ -121,6 +121,9 @@
#define UARTDM_DMEN_RX_SC_ENABLE BIT(5)
#define UARTDM_DMEN_TX_SC_ENABLE BIT(4)
+#define UARTDM_DMEN_TX_BAM_ENABLE BIT(2) /* UARTDM_1P4 */
+#define UARTDM_DMEN_TX_DM_ENABLE BIT(0) /* < UARTDM_1P4 */
+
#define UARTDM_DMRX 0x34
#define UARTDM_NCF_TX 0x40
#define UARTDM_RX_TOTAL_SNAP 0x38
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 5/6] tty: serial: msm: Add RX DMA support
2015-09-30 12:08 [PATCH v2 0/6] tty: serial: msm: Add DMA support and fix bit definitions Ivan T. Ivanov
` (3 preceding siblings ...)
2015-09-30 12:08 ` [PATCH v2 4/6] tty: serial: msm: Add TX DMA support Ivan T. Ivanov
@ 2015-09-30 12:08 ` Ivan T. Ivanov
2015-09-30 13:30 ` Mark Rutland
2015-09-30 12:08 ` [PATCH v2 6/6] tty: serial: msm: Remove 115.2 Kbps maximum baud rate limitation Ivan T. Ivanov
[not found] ` <1443614906-2196-1-git-send-email-ivan.ivanov-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
6 siblings, 1 reply; 13+ messages in thread
From: Ivan T. Ivanov @ 2015-09-30 12:08 UTC (permalink / raw)
To: Andy Gross
Cc: David Brown, Srinivas Kandagatla, Greg Kroah-Hartman, Jiri Slaby,
Frank Rowand, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
devicetree, linux-kernel, linux-arm-msm, linux-soc, linux-serial
Add receive DMA support for UARTDM type of controllers.
Tested on APQ8064, which have UARTDM v1.3 and ADM DMA engine
and APQ8016, which have UARTDM v1.4 and BAM DMA engine.
Signed-off-by: Ivan T. Ivanov <ivan.ivanov@linaro.org>
---
.../devicetree/bindings/serial/qcom,msm-uartdm.txt | 3 +
drivers/tty/serial/msm_serial.c | 232 ++++++++++++++++++++-
drivers/tty/serial/msm_serial.h | 4 +
3 files changed, 236 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
index a600023d9ec1..182777fac9a2 100644
--- a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
+++ b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
@@ -29,6 +29,9 @@ Optional properties:
- qcom,tx-crci: Identificator <u32> for Client Rate Control Interface to be
used with TX DMA channel. Required when using DMA for transmission
with UARTDM v1.3 and bellow.
+- qcom,rx-crci: Identificator <u32> for Client Rate Control Interface to be
+ used with RX DMA channel. Required when using DMA for reception
+ with UARTDM v1.3 and bellow.
Note: Aliases may be defined to ensure the correct ordering of the UARTs.
The alias serialN will result in the UART being assigned port N. If any
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index 2f395f5d78d0..fc5f6b3b4bbb 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -33,6 +33,7 @@
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
+#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
@@ -44,6 +45,7 @@
#define UARTDM_BURST_SIZE 16 /* in bytes */
#define UARTDM_TX_AIGN(x) ((x) & ~0x3) /* valid for > 1p3 */
#define UARTDM_TX_MAX 256 /* in bytes, valid for <= 1p3 */
+#define UARTDM_RX_SIZE (UART_XMIT_SIZE / 4)
enum {
UARTDM_1P1 = 1,
@@ -73,9 +75,11 @@ struct msm_port {
unsigned int old_snap_state;
bool break_detected;
struct msm_dma tx_dma;
+ struct msm_dma rx_dma;
};
static void msm_handle_tx(struct uart_port *port);
+static void msm_start_rx_dma(struct msm_port *msm_port);
void msm_stop_dma(struct uart_port *port, struct msm_dma *dma)
{
@@ -114,6 +118,15 @@ static void msm_release_dma(struct msm_port *msm_port)
}
memset(dma, 0, sizeof(*dma));
+
+ dma = &msm_port->rx_dma;
+ if (dma->chan) {
+ msm_stop_dma(&msm_port->uart, dma);
+ dma_release_channel(dma->chan);
+ kfree(dma->virt);
+ }
+
+ memset(dma, 0, sizeof(*dma));
}
static void msm_request_tx_dma(struct msm_port *msm_port, resource_size_t base)
@@ -159,6 +172,54 @@ no_tx:
memset(dma, 0, sizeof(*dma));
}
+static void msm_request_rx_dma(struct msm_port *msm_port, resource_size_t base)
+{
+ struct device *dev = msm_port->uart.dev;
+ struct dma_slave_config conf;
+ struct msm_dma *dma;
+ u32 crci = 0;
+ int ret;
+
+ dma = &msm_port->rx_dma;
+
+ /* allocate DMA resources, if available */
+ dma->chan = dma_request_slave_channel_reason(dev, "rx");
+ if (IS_ERR(dma->chan))
+ goto no_rx;
+
+ of_property_read_u32(dev->of_node, "qcom,rx-crci", &crci);
+
+ dma->virt = kzalloc(UARTDM_RX_SIZE, GFP_KERNEL);
+ if (!dma->virt)
+ goto rel_rx;
+
+ memset(&conf, 0, sizeof(conf));
+ conf.direction = DMA_DEV_TO_MEM;
+ conf.device_fc = true;
+ conf.src_addr = base + UARTDM_RF;
+ conf.src_maxburst = UARTDM_BURST_SIZE;
+ conf.slave_id = crci;
+
+ ret = dmaengine_slave_config(dma->chan, &conf);
+ if (ret)
+ goto err;
+
+ dma->dir = DMA_FROM_DEVICE;
+
+ if (msm_port->is_uartdm < UARTDM_1P4)
+ dma->enable_bit = UARTDM_DMEN_RX_DM_ENABLE;
+ else
+ dma->enable_bit = UARTDM_DMEN_RX_BAM_ENABLE;
+
+ return;
+err:
+ kfree(dma->virt);
+rel_rx:
+ dma_release_channel(dma->chan);
+no_rx:
+ memset(dma, 0, sizeof(*dma));
+}
+
static inline void msm_wait_for_xmitr(struct uart_port *port)
{
while (!(msm_read(port, UART_SR) & UART_SR_TX_EMPTY)) {
@@ -306,12 +367,151 @@ unmap:
dma_unmap_single(port->dev, dma->phys, count, dma->dir);
return ret;
}
+
+static void msm_complete_rx_dma(void *args)
+{
+ struct msm_port *msm_port = args;
+ struct uart_port *port = &msm_port->uart;
+ struct tty_port *tport = &port->state->port;
+ struct msm_dma *dma = &msm_port->rx_dma;
+ int count = 0, i, sysrq;
+ unsigned long flags;
+ u32 val;
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ /* Already stopped */
+ if (!dma->count)
+ goto done;
+
+ val = msm_read(port, UARTDM_DMEN);
+ val &= ~dma->enable_bit;
+ msm_write(port, val, UARTDM_DMEN);
+
+ /* Restore interrupts */
+ msm_port->imr |= UART_IMR_RXLEV | UART_IMR_RXSTALE;
+ msm_write(port, msm_port->imr, UART_IMR);
+
+ if (msm_read(port, UART_SR) & UART_SR_OVERRUN) {
+ port->icount.overrun++;
+ tty_insert_flip_char(tport, 0, TTY_OVERRUN);
+ msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR);
+ }
+
+ count = msm_read(port, UARTDM_RX_TOTAL_SNAP);
+
+ port->icount.rx += count;
+
+ dma->count = 0;
+
+ dma_unmap_single(port->dev, dma->phys, UARTDM_RX_SIZE, dma->dir);
+
+ for (i = 0; i < count; i++) {
+ char flag = TTY_NORMAL;
+
+ if (msm_port->break_detected && dma->virt[i] == 0) {
+ port->icount.brk++;
+ flag = TTY_BREAK;
+ msm_port->break_detected = false;
+ if (uart_handle_break(port))
+ continue;
+ }
+
+ if (!(port->read_status_mask & UART_SR_RX_BREAK))
+ flag = TTY_NORMAL;
+
+ spin_unlock_irqrestore(&port->lock, flags);
+ sysrq = uart_handle_sysrq_char(port, dma->virt[i]);
+ spin_lock_irqsave(&port->lock, flags);
+ if (!sysrq)
+ tty_insert_flip_char(tport, dma->virt[i], flag);
+ }
+
+ msm_start_rx_dma(msm_port);
+done:
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ if (count)
+ tty_flip_buffer_push(tport);
+}
+
+static void msm_start_rx_dma(struct msm_port *msm_port)
+{
+ struct msm_dma *dma = &msm_port->rx_dma;
+ struct uart_port *uart = &msm_port->uart;
+ u32 val;
+ int ret;
+
+ if (!dma->chan)
+ return;
+
+ dma->phys = dma_map_single(uart->dev, dma->virt,
+ UARTDM_RX_SIZE, dma->dir);
+ ret = dma_mapping_error(uart->dev, dma->phys);
+ if (ret)
+ return;
+
+ dma->desc = dmaengine_prep_slave_single(dma->chan, dma->phys,
+ UARTDM_RX_SIZE, DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT);
+ if (!dma->desc)
+ goto unmap;
+
+ dma->desc->callback = msm_complete_rx_dma;
+ dma->desc->callback_param = msm_port;
+
+ dma->cookie = dmaengine_submit(dma->desc);
+ ret = dma_submit_error(dma->cookie);
+ if (ret)
+ goto unmap;
+ /*
+ * Using DMA for FIFO off-load, no need for "Rx FIFO over
+ * watermark" or "stale" interrupts, disable them
+ */
+ msm_port->imr &= ~(UART_IMR_RXLEV | UART_IMR_RXSTALE);
+
+ /*
+ * Well, when DMA is ADM3 engine(implied by <= UARTDM v1.3),
+ * we need RXSTALE to flush input DMA fifo to memory
+ */
+ if (msm_port->is_uartdm < UARTDM_1P4)
+ msm_port->imr |= UART_IMR_RXSTALE;
+
+ msm_write(uart, msm_port->imr, UART_IMR);
+
+ dma->count = UARTDM_RX_SIZE;
+
+ dma_async_issue_pending(dma->chan);
+
+ msm_write(uart, UART_CR_CMD_RESET_STALE_INT, UART_CR);
+ msm_write(uart, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR);
+
+ val = msm_read(uart, UARTDM_DMEN);
+ val |= dma->enable_bit;
+
+ if (msm_port->is_uartdm < UARTDM_1P4)
+ msm_write(uart, val, UARTDM_DMEN);
+
+ msm_write(uart, UARTDM_RX_SIZE, UARTDM_DMRX);
+
+ if (msm_port->is_uartdm > UARTDM_1P3)
+ msm_write(uart, val, UARTDM_DMEN);
+
+ return;
+unmap:
+ dma_unmap_single(uart->dev, dma->phys, UARTDM_RX_SIZE, dma->dir);
+}
+
static void msm_stop_rx(struct uart_port *port)
{
struct msm_port *msm_port = UART_TO_MSM(port);
+ struct msm_dma *dma = &msm_port->rx_dma;
msm_port->imr &= ~(UART_IMR_RXLEV | UART_IMR_RXSTALE);
msm_write(port, msm_port->imr, UART_IMR);
+
+ if (dma->chan)
+ msm_stop_dma(port, dma);
}
static void msm_enable_ms(struct uart_port *port)
@@ -392,6 +592,9 @@ static void msm_handle_rx_dm(struct uart_port *port, unsigned int misr)
msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR);
msm_write(port, 0xFFFFFF, UARTDM_DMRX);
msm_write(port, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR);
+
+ /* Try to use DMA */
+ msm_start_rx_dma(msm_port);
}
static void msm_handle_rx(struct uart_port *port)
@@ -558,8 +761,10 @@ static irqreturn_t msm_uart_irq(int irq, void *dev_id)
{
struct uart_port *port = dev_id;
struct msm_port *msm_port = UART_TO_MSM(port);
+ struct msm_dma *dma = &msm_port->rx_dma;
unsigned long flags;
unsigned int misr;
+ u32 val;
spin_lock_irqsave(&port->lock, flags);
misr = msm_read(port, UART_MISR);
@@ -571,10 +776,21 @@ static irqreturn_t msm_uart_irq(int irq, void *dev_id)
}
if (misr & (UART_IMR_RXLEV | UART_IMR_RXSTALE)) {
- if (msm_port->is_uartdm)
+ if (dma->count) {
+ val = UART_CR_CMD_STALE_EVENT_DISABLE;
+ msm_write(port, val, UART_CR);
+ val = UART_CR_CMD_RESET_STALE_INT;
+ msm_write(port, val, UART_CR);
+ /*
+ * Flush DMA input fifo to memory, this will also
+ * trigger DMA RX completion
+ */
+ dmaengine_terminate_all(dma->chan);
+ } else if (msm_port->is_uartdm) {
msm_handle_rx_dm(port, misr);
- else
+ } else {
msm_handle_rx(port);
+ }
}
if (misr & UART_IMR_TXLEV)
msm_handle_tx(port);
@@ -773,8 +989,10 @@ static int msm_startup(struct uart_port *port)
data |= UART_MR1_AUTO_RFR_LEVEL0 & rfr_level;
msm_write(port, data, UART_MR1);
- if (msm_port->is_uartdm)
+ if (msm_port->is_uartdm) {
msm_request_tx_dma(msm_port, msm_port->uart.mapbase);
+ msm_request_rx_dma(msm_port, msm_port->uart.mapbase);
+ }
return 0;
}
@@ -797,11 +1015,16 @@ static void msm_shutdown(struct uart_port *port)
static void msm_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
{
+ struct msm_port *msm_port = UART_TO_MSM(port);
+ struct msm_dma *dma = &msm_port->rx_dma;
unsigned long flags;
unsigned int baud, mr;
spin_lock_irqsave(&port->lock, flags);
+ if (dma->chan) /* Terminate if any */
+ msm_stop_dma(port, dma);
+
/* calculate and set baud rate */
baud = uart_get_baud_rate(port, termios, old, 300, 115200);
baud = msm_set_baud_rate(port, baud);
@@ -866,6 +1089,9 @@ static void msm_set_termios(struct uart_port *port, struct ktermios *termios,
uart_update_timeout(port, termios->c_cflag, baud);
+ /* Try to use DMA */
+ msm_start_rx_dma(msm_port);
+
spin_unlock_irqrestore(&port->lock, flags);
}
diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h
index 103ae61b9d06..178645826f16 100644
--- a/drivers/tty/serial/msm_serial.h
+++ b/drivers/tty/serial/msm_serial.h
@@ -59,6 +59,7 @@
#define UART_CR_CMD_SET_RFR (13 << 4)
#define UART_CR_CMD_RESET_RFR (14 << 4)
#define UART_CR_CMD_PROTECTION_EN (16 << 4)
+#define UART_CR_CMD_STALE_EVENT_DISABLE (6 << 8)
#define UART_CR_CMD_STALE_EVENT_ENABLE (80 << 4)
#define UART_CR_CMD_FORCE_STALE (4 << 8)
#define UART_CR_CMD_RESET_TX_READY (3 << 8)
@@ -124,6 +125,9 @@
#define UARTDM_DMEN_TX_BAM_ENABLE BIT(2) /* UARTDM_1P4 */
#define UARTDM_DMEN_TX_DM_ENABLE BIT(0) /* < UARTDM_1P4 */
+#define UARTDM_DMEN_RX_BAM_ENABLE BIT(3) /* UARTDM_1P4 */
+#define UARTDM_DMEN_RX_DM_ENABLE BIT(1) /* < UARTDM_1P4 */
+
#define UARTDM_DMRX 0x34
#define UARTDM_NCF_TX 0x40
#define UARTDM_RX_TOTAL_SNAP 0x38
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 6/6] tty: serial: msm: Remove 115.2 Kbps maximum baud rate limitation
2015-09-30 12:08 [PATCH v2 0/6] tty: serial: msm: Add DMA support and fix bit definitions Ivan T. Ivanov
` (4 preceding siblings ...)
2015-09-30 12:08 ` [PATCH v2 5/6] tty: serial: msm: Add RX " Ivan T. Ivanov
@ 2015-09-30 12:08 ` Ivan T. Ivanov
[not found] ` <1443614906-2196-1-git-send-email-ivan.ivanov-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
6 siblings, 0 replies; 13+ messages in thread
From: Ivan T. Ivanov @ 2015-09-30 12:08 UTC (permalink / raw)
To: Andy Gross
Cc: David Brown, Srinivas Kandagatla, Greg Kroah-Hartman, Jiri Slaby,
Frank Rowand, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
devicetree, linux-kernel, linux-arm-msm, linux-soc, linux-serial
UART controller is capable to perform transfers up to 4 Mbps.
Remove artificial 115.2 Kbps limitation.
Signed-off-by: Ivan T. Ivanov <ivan.ivanov@linaro.org>
---
drivers/tty/serial/msm_serial.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index fc5f6b3b4bbb..abeb35555d93 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -882,6 +882,7 @@ msm_find_best_baud(struct uart_port *port, unsigned int baud)
{ 3, 0xdd, 8 },
{ 2, 0xee, 16 },
{ 1, 0xff, 31 },
+ { 0, 0xff, 31 },
};
divisor = uart_get_divisor(port, baud);
@@ -893,16 +894,29 @@ msm_find_best_baud(struct uart_port *port, unsigned int baud)
return entry; /* Default to smallest divider */
}
-static int msm_set_baud_rate(struct uart_port *port, unsigned int baud)
+static int msm_set_baud_rate(struct uart_port *port, unsigned int baud,
+ unsigned long *saved_flags)
{
unsigned int rxstale, watermark, mask;
struct msm_port *msm_port = UART_TO_MSM(port);
const struct msm_baud_map *entry;
+ unsigned long flags;
entry = msm_find_best_baud(port, baud);
msm_write(port, entry->code, UART_CSR);
+ if (baud > 460800)
+ port->uartclk = baud * 16;
+
+ flags = *saved_flags;
+ spin_unlock_irqrestore(&port->lock, flags);
+
+ clk_set_rate(msm_port->clk, port->uartclk);
+
+ spin_lock_irqsave(&port->lock, flags);
+ *saved_flags = flags;
+
/* RX stale watermark */
rxstale = entry->rxstale;
watermark = UART_IPR_STALE_LSB & rxstale;
@@ -1026,8 +1040,8 @@ static void msm_set_termios(struct uart_port *port, struct ktermios *termios,
msm_stop_dma(port, dma);
/* calculate and set baud rate */
- baud = uart_get_baud_rate(port, termios, old, 300, 115200);
- baud = msm_set_baud_rate(port, baud);
+ baud = uart_get_baud_rate(port, termios, old, 300, 4000000);
+ baud = msm_set_baud_rate(port, baud, &flags);
if (tty_termios_baud_rate(termios))
tty_termios_encode_baud_rate(termios, baud, baud);
--
1.9.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 0/6] tty: serial: msm: Add DMA support and fix bit definitions
[not found] ` <1443614906-2196-1-git-send-email-ivan.ivanov-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2015-09-30 12:12 ` Ivan T. Ivanov
0 siblings, 0 replies; 13+ messages in thread
From: Ivan T. Ivanov @ 2015-09-30 12:12 UTC (permalink / raw)
To: Andy Gross
Cc: David Brown, Srinivas Kandagatla, Greg Kroah-Hartman, Jiri Slaby,
Frank Rowand, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
linux-soc-u79uwXL29TY76Z2rM5mHXA,
linux-serial-u79uwXL29TY76Z2rM5mHXA
On Wed, 2015-09-30 at 15:08 +0300, Ivan T. Ivanov wrote:
> Hi,
>
> This is second version of patches which DMA support for UARTDM type
> of hardware found in Qualcomm chip sets.
>
Please ignore this patch set. Wrong set of changes.
Sorry,
Ivan
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 4/6] tty: serial: msm: Add TX DMA support
2015-09-30 12:08 ` [PATCH v2 4/6] tty: serial: msm: Add TX DMA support Ivan T. Ivanov
@ 2015-09-30 13:29 ` Mark Rutland
2015-09-30 13:51 ` Ivan T. Ivanov
0 siblings, 1 reply; 13+ messages in thread
From: Mark Rutland @ 2015-09-30 13:29 UTC (permalink / raw)
To: Ivan T. Ivanov
Cc: Andy Gross, David Brown, Srinivas Kandagatla, Greg Kroah-Hartman,
Jiri Slaby, Frank Rowand, Rob Herring, Pawel Moll, Ian Campbell,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org,
linux-serial@vger.kernel.org
On Wed, Sep 30, 2015 at 01:08:24PM +0100, Ivan T. Ivanov wrote:
> Add transmit DMA support for UARTDM type of controllers.
>
> Tested on APQ8064, which have UARTDM v1.3 and ADM DMA engine
> and APQ8016, which have UARTDM v1.4 and BAM DMA engine.
>
> Signed-off-by: Ivan T. Ivanov <ivan.ivanov@linaro.org>
> ---
> .../devicetree/bindings/serial/qcom,msm-uartdm.txt | 3 +
> drivers/tty/serial/msm_serial.c | 312 +++++++++++++++++++--
> drivers/tty/serial/msm_serial.h | 3 +
> 3 files changed, 294 insertions(+), 24 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
> index a2114c217376..a600023d9ec1 100644
> --- a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
> +++ b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
> @@ -26,6 +26,9 @@ Required properties:
> Optional properties:
> - dmas: Should contain dma specifiers for transmit and receive channels
> - dma-names: Should contain "tx" for transmit and "rx" for receive channels
> +- qcom,tx-crci: Identificator <u32> for Client Rate Control Interface to be
> + used with TX DMA channel. Required when using DMA for transmission
> + with UARTDM v1.3 and bellow.
This sounds like it belongs in the dma-specifier, and dealt with by the
DMA controller driver.
Why does the UART driver need to know about this?
Mark.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 5/6] tty: serial: msm: Add RX DMA support
2015-09-30 12:08 ` [PATCH v2 5/6] tty: serial: msm: Add RX " Ivan T. Ivanov
@ 2015-09-30 13:30 ` Mark Rutland
0 siblings, 0 replies; 13+ messages in thread
From: Mark Rutland @ 2015-09-30 13:30 UTC (permalink / raw)
To: Ivan T. Ivanov
Cc: Andy Gross, David Brown, Srinivas Kandagatla, Greg Kroah-Hartman,
Jiri Slaby, Frank Rowand, Rob Herring, Pawel Moll, Ian Campbell,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org,
linux-serial@vger.kernel.org
On Wed, Sep 30, 2015 at 01:08:25PM +0100, Ivan T. Ivanov wrote:
> Add receive DMA support for UARTDM type of controllers.
>
> Tested on APQ8064, which have UARTDM v1.3 and ADM DMA engine
> and APQ8016, which have UARTDM v1.4 and BAM DMA engine.
>
> Signed-off-by: Ivan T. Ivanov <ivan.ivanov@linaro.org>
> ---
> .../devicetree/bindings/serial/qcom,msm-uartdm.txt | 3 +
> drivers/tty/serial/msm_serial.c | 232 ++++++++++++++++++++-
> drivers/tty/serial/msm_serial.h | 4 +
> 3 files changed, 236 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
> index a600023d9ec1..182777fac9a2 100644
> --- a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
> +++ b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
> @@ -29,6 +29,9 @@ Optional properties:
> - qcom,tx-crci: Identificator <u32> for Client Rate Control Interface to be
> used with TX DMA channel. Required when using DMA for transmission
> with UARTDM v1.3 and bellow.
> +- qcom,rx-crci: Identificator <u32> for Client Rate Control Interface to be
> + used with RX DMA channel. Required when using DMA for reception
> + with UARTDM v1.3 and bellow.
My comments on qcom,tx-crci apply to qcom,rx-crci too.
This does not deel like it belongs in the UART binding and/or driver.
Mark.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 4/6] tty: serial: msm: Add TX DMA support
2015-09-30 13:29 ` Mark Rutland
@ 2015-09-30 13:51 ` Ivan T. Ivanov
2015-09-30 17:32 ` Mark Rutland
0 siblings, 1 reply; 13+ messages in thread
From: Ivan T. Ivanov @ 2015-09-30 13:51 UTC (permalink / raw)
To: Mark Rutland
Cc: Andy Gross, David Brown, Srinivas Kandagatla, Greg Kroah-Hartman,
Jiri Slaby, Frank Rowand, Rob Herring, Pawel Moll, Ian Campbell,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org,
linux-serial@vger.kernel.org
On Wed, 2015-09-30 at 14:29 +0100, Mark Rutland wrote:
> On Wed, Sep 30, 2015 at 01:08:24PM +0100, Ivan T. Ivanov wrote:
> > Add transmit DMA support for UARTDM type of controllers.
> >
> > Tested on APQ8064, which have UARTDM v1.3 and ADM DMA engine
> > and APQ8016, which have UARTDM v1.4 and BAM DMA engine.
> >
> > Signed-off-by: Ivan T. Ivanov ivanov@linaro.org>
> > ---
> > .../devicetree/bindings/serial/qcom,msm-uartdm.txt | 3 +
> > drivers/tty/serial/msm_serial.c | 312 +++++++++++++++++++--
> > drivers/tty/serial/msm_serial.h | 3 +
> > 3 files changed, 294 insertions(+), 24 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
> > index a2114c217376..a600023d9ec1 100644
> > --- a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
> > +++ b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
> > @@ -26,6 +26,9 @@ Required properties:
> > Optional properties:
> > - dmas: Should contain dma specifiers for transmit and receive channels
> > - dma-names: Should contain "tx" for transmit and "rx" for receive channels
> > +- qcom,tx-crci: Identificator <u32> for Client Rate Control Interface to be
> > + used with TX DMA channel. Required when using DMA for transmission
> > + with UARTDM v1.3 and bellow.
>
> This sounds like it belongs in the dma-specifier, and dealt with by the
> DMA controller driver.
>
> Why does the UART driver need to know about this?
CRCI information was part of the first version of ADM DMA engine driver
bindings, but Andy remove it because some client devices are requiring
more that one CRCI number. See here[1] and here [2].
Regards,
Ivan
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/314190.html
[2] https://lkml.org/lkml/2015/8/19/19
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 4/6] tty: serial: msm: Add TX DMA support
2015-09-30 13:51 ` Ivan T. Ivanov
@ 2015-09-30 17:32 ` Mark Rutland
2015-09-30 20:24 ` Andy Gross
0 siblings, 1 reply; 13+ messages in thread
From: Mark Rutland @ 2015-09-30 17:32 UTC (permalink / raw)
To: Ivan T. Ivanov
Cc: Andy Gross, David Brown, Srinivas Kandagatla, Greg Kroah-Hartman,
Jiri Slaby, Frank Rowand, Rob Herring, Pawel Moll, Ian Campbell,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org,
linux-serial@vger.kernel.org
On Wed, Sep 30, 2015 at 02:51:26PM +0100, Ivan T. Ivanov wrote:
>
> On Wed, 2015-09-30 at 14:29 +0100, Mark Rutland wrote:
> > On Wed, Sep 30, 2015 at 01:08:24PM +0100, Ivan T. Ivanov wrote:
> > > Add transmit DMA support for UARTDM type of controllers.
> > >
> > > Tested on APQ8064, which have UARTDM v1.3 and ADM DMA engine
> > > and APQ8016, which have UARTDM v1.4 and BAM DMA engine.
> > >
> > > Signed-off-by: Ivan T. Ivanov ivanov@linaro.org>
> > > ---
> > > .../devicetree/bindings/serial/qcom,msm-uartdm.txt | 3 +
> > > drivers/tty/serial/msm_serial.c | 312 +++++++++++++++++++--
> > > drivers/tty/serial/msm_serial.h | 3 +
> > > 3 files changed, 294 insertions(+), 24 deletions(-)
> > >
> > > diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
> > > index a2114c217376..a600023d9ec1 100644
> > > --- a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
> > > +++ b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
> > > @@ -26,6 +26,9 @@ Required properties:
> > > Optional properties:
> > > - dmas: Should contain dma specifiers for transmit and receive channels
> > > - dma-names: Should contain "tx" for transmit and "rx" for receive channels
> > > +- qcom,tx-crci: Identificator <u32> for Client Rate Control Interface to be
> > > + used with TX DMA channel. Required when using DMA for transmission
> > > + with UARTDM v1.3 and bellow.
> >
> > This sounds like it belongs in the dma-specifier, and dealt with by the
> > DMA controller driver.
> >
> > Why does the UART driver need to know about this?
>
> CRCI information was part of the first version of ADM DMA engine driver
> bindings, but Andy remove it because some client devices are requiring
> more that one CRCI number. See here[1] and here [2].
>
> Regards,
> Ivan
>
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/314190.html
> [2] https://lkml.org/lkml/2015/8/19/19
This leaves me more confused. If different writes from the same agent
are being distinguished then it sounds like you actually have two
logical DMA channels.
Could you elaborate on the qcom,ebi2-nand binding? From a brief read I'd
expect you to have "txrx" and "cmd" dmas, rather than describing the
CRCI information on the side.
Mark.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 4/6] tty: serial: msm: Add TX DMA support
2015-09-30 17:32 ` Mark Rutland
@ 2015-09-30 20:24 ` Andy Gross
0 siblings, 0 replies; 13+ messages in thread
From: Andy Gross @ 2015-09-30 20:24 UTC (permalink / raw)
To: Mark Rutland
Cc: Ivan T. Ivanov, David Brown, Srinivas Kandagatla,
Greg Kroah-Hartman, Jiri Slaby, Frank Rowand, Rob Herring,
Pawel Moll, Ian Campbell, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
linux-soc@vger.kernel.org, linux-serial@vger.kernel.org
On Wed, Sep 30, 2015 at 06:32:01PM +0100, Mark Rutland wrote:
> On Wed, Sep 30, 2015 at 02:51:26PM +0100, Ivan T. Ivanov wrote:
> >
> > On Wed, 2015-09-30 at 14:29 +0100, Mark Rutland wrote:
> > > On Wed, Sep 30, 2015 at 01:08:24PM +0100, Ivan T. Ivanov wrote:
> > > > Add transmit DMA support for UARTDM type of controllers.
> > > >
> > > > Tested on APQ8064, which have UARTDM v1.3 and ADM DMA engine
> > > > and APQ8016, which have UARTDM v1.4 and BAM DMA engine.
> > > >
> > > > Signed-off-by: Ivan T. Ivanov ivanov@linaro.org>
> > > > ---
> > > > .../devicetree/bindings/serial/qcom,msm-uartdm.txt | 3 +
> > > > drivers/tty/serial/msm_serial.c | 312 +++++++++++++++++++--
> > > > drivers/tty/serial/msm_serial.h | 3 +
> > > > 3 files changed, 294 insertions(+), 24 deletions(-)
> > > >
> > > > diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
> > > > index a2114c217376..a600023d9ec1 100644
> > > > --- a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
> > > > +++ b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt
> > > > @@ -26,6 +26,9 @@ Required properties:
> > > > Optional properties:
> > > > - dmas: Should contain dma specifiers for transmit and receive channels
> > > > - dma-names: Should contain "tx" for transmit and "rx" for receive channels
> > > > +- qcom,tx-crci: Identificator <u32> for Client Rate Control Interface to be
> > > > + used with TX DMA channel. Required when using DMA for transmission
> > > > + with UARTDM v1.3 and bellow.
> > >
> > > This sounds like it belongs in the dma-specifier, and dealt with by the
> > > DMA controller driver.
> > >
> > > Why does the UART driver need to know about this?
> >
> > CRCI information was part of the first version of ADM DMA engine driver
> > bindings, but Andy remove it because some client devices are requiring
> > more that one CRCI number. See here[1] and here [2].
> >
> > Regards,
> > Ivan
> >
> > [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2015-January/314190.html
> > [2] https://lkml.org/lkml/2015/8/19/19
>
> This leaves me more confused. If different writes from the same agent
> are being distinguished then it sounds like you actually have two
> logical DMA channels.
>
> Could you elaborate on the qcom,ebi2-nand binding? From a brief read I'd
> expect you to have "txrx" and "cmd" dmas, rather than describing the
> CRCI information on the side.
The ADM does have physical channels, but when you utilize those channels you may
also need to describe the flow control used for specific transactions. And this
flow control has to be configured for that specific transaction, if you are
interleaving different flow control origination/end points.
In the case of nand, they actually use different flow controls on the same
physical channel. For UART/I2C/SPI, they use just one flow control identifier.
I see your point at specifying these as logical channels. That is certainly a
possibility. Then the ADM driver would just have to handle the logical channel
allocation. That would remove the need for the slave_config being sent.
--
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2015-09-30 20:24 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-30 12:08 [PATCH v2 0/6] tty: serial: msm: Add DMA support and fix bit definitions Ivan T. Ivanov
2015-09-30 12:08 ` [PATCH v2 1/6] tty: serial: msm: Add mask value for UART_DM registers Ivan T. Ivanov
2015-09-30 12:08 ` [PATCH v2 2/6] tty: serial: msm: replaces (1 << x) with BIT(x) macro Ivan T. Ivanov
2015-09-30 12:08 ` [PATCH v2 3/6] tty: serial: msm: Add msm prefix to all driver functions Ivan T. Ivanov
2015-09-30 12:08 ` [PATCH v2 4/6] tty: serial: msm: Add TX DMA support Ivan T. Ivanov
2015-09-30 13:29 ` Mark Rutland
2015-09-30 13:51 ` Ivan T. Ivanov
2015-09-30 17:32 ` Mark Rutland
2015-09-30 20:24 ` Andy Gross
2015-09-30 12:08 ` [PATCH v2 5/6] tty: serial: msm: Add RX " Ivan T. Ivanov
2015-09-30 13:30 ` Mark Rutland
2015-09-30 12:08 ` [PATCH v2 6/6] tty: serial: msm: Remove 115.2 Kbps maximum baud rate limitation Ivan T. Ivanov
[not found] ` <1443614906-2196-1-git-send-email-ivan.ivanov-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2015-09-30 12:12 ` [PATCH v2 0/6] tty: serial: msm: Add DMA support and fix bit definitions Ivan T. Ivanov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).