aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/serial/qcom,msm-uartdm.txt3
-rw-r--r--drivers/tty/serial/msm_serial.c232
-rw-r--r--drivers/tty/serial/msm_serial.h4
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:
29- qcom,tx-crci: Identificator <u32> for Client Rate Control Interface to be 29- qcom,tx-crci: Identificator <u32> for Client Rate Control Interface to be
30 used with TX DMA channel. Required when using DMA for transmission 30 used with TX DMA channel. Required when using DMA for transmission
31 with UARTDM v1.3 and bellow. 31 with UARTDM v1.3 and bellow.
32- qcom,rx-crci: Identificator <u32> for Client Rate Control Interface to be
33 used with RX DMA channel. Required when using DMA for reception
34 with UARTDM v1.3 and bellow.
32 35
33Note: Aliases may be defined to ensure the correct ordering of the UARTs. 36Note: Aliases may be defined to ensure the correct ordering of the UARTs.
34The alias serialN will result in the UART being assigned port N. If any 37The 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 7006d979d9d2..3efb80f511db 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -33,6 +33,7 @@
33#include <linux/tty_flip.h> 33#include <linux/tty_flip.h>
34#include <linux/serial_core.h> 34#include <linux/serial_core.h>
35#include <linux/serial.h> 35#include <linux/serial.h>
36#include <linux/slab.h>
36#include <linux/clk.h> 37#include <linux/clk.h>
37#include <linux/platform_device.h> 38#include <linux/platform_device.h>
38#include <linux/delay.h> 39#include <linux/delay.h>
@@ -44,6 +45,7 @@
44#define UARTDM_BURST_SIZE 16 /* in bytes */ 45#define UARTDM_BURST_SIZE 16 /* in bytes */
45#define UARTDM_TX_AIGN(x) ((x) & ~0x3) /* valid for > 1p3 */ 46#define UARTDM_TX_AIGN(x) ((x) & ~0x3) /* valid for > 1p3 */
46#define UARTDM_TX_MAX 256 /* in bytes, valid for <= 1p3 */ 47#define UARTDM_TX_MAX 256 /* in bytes, valid for <= 1p3 */
48#define UARTDM_RX_SIZE (UART_XMIT_SIZE / 4)
47 49
48enum { 50enum {
49 UARTDM_1P1 = 1, 51 UARTDM_1P1 = 1,
@@ -73,9 +75,11 @@ struct msm_port {
73 unsigned int old_snap_state; 75 unsigned int old_snap_state;
74 bool break_detected; 76 bool break_detected;
75 struct msm_dma tx_dma; 77 struct msm_dma tx_dma;
78 struct msm_dma rx_dma;
76}; 79};
77 80
78static void msm_handle_tx(struct uart_port *port); 81static void msm_handle_tx(struct uart_port *port);
82static void msm_start_rx_dma(struct msm_port *msm_port);
79 83
80void msm_stop_dma(struct uart_port *port, struct msm_dma *dma) 84void msm_stop_dma(struct uart_port *port, struct msm_dma *dma)
81{ 85{
@@ -114,6 +118,15 @@ static void msm_release_dma(struct msm_port *msm_port)
114 } 118 }
115 119
116 memset(dma, 0, sizeof(*dma)); 120 memset(dma, 0, sizeof(*dma));
121
122 dma = &msm_port->rx_dma;
123 if (dma->chan) {
124 msm_stop_dma(&msm_port->uart, dma);
125 dma_release_channel(dma->chan);
126 kfree(dma->virt);
127 }
128
129 memset(dma, 0, sizeof(*dma));
117} 130}
118 131
119static void msm_request_tx_dma(struct msm_port *msm_port, resource_size_t base) 132static void msm_request_tx_dma(struct msm_port *msm_port, resource_size_t base)
@@ -159,6 +172,54 @@ no_tx:
159 memset(dma, 0, sizeof(*dma)); 172 memset(dma, 0, sizeof(*dma));
160} 173}
161 174
175static void msm_request_rx_dma(struct msm_port *msm_port, resource_size_t base)
176{
177 struct device *dev = msm_port->uart.dev;
178 struct dma_slave_config conf;
179 struct msm_dma *dma;
180 u32 crci = 0;
181 int ret;
182
183 dma = &msm_port->rx_dma;
184
185 /* allocate DMA resources, if available */
186 dma->chan = dma_request_slave_channel_reason(dev, "rx");
187 if (IS_ERR(dma->chan))
188 goto no_rx;
189
190 of_property_read_u32(dev->of_node, "qcom,rx-crci", &crci);
191
192 dma->virt = kzalloc(UARTDM_RX_SIZE, GFP_KERNEL);
193 if (!dma->virt)
194 goto rel_rx;
195
196 memset(&conf, 0, sizeof(conf));
197 conf.direction = DMA_DEV_TO_MEM;
198 conf.device_fc = true;
199 conf.src_addr = base + UARTDM_RF;
200 conf.src_maxburst = UARTDM_BURST_SIZE;
201 conf.slave_id = crci;
202
203 ret = dmaengine_slave_config(dma->chan, &conf);
204 if (ret)
205 goto err;
206
207 dma->dir = DMA_FROM_DEVICE;
208
209 if (msm_port->is_uartdm < UARTDM_1P4)
210 dma->enable_bit = UARTDM_DMEN_RX_DM_ENABLE;
211 else
212 dma->enable_bit = UARTDM_DMEN_RX_BAM_ENABLE;
213
214 return;
215err:
216 kfree(dma->virt);
217rel_rx:
218 dma_release_channel(dma->chan);
219no_rx:
220 memset(dma, 0, sizeof(*dma));
221}
222
162static inline void msm_wait_for_xmitr(struct uart_port *port) 223static inline void msm_wait_for_xmitr(struct uart_port *port)
163{ 224{
164 while (!(msm_read(port, UART_SR) & UART_SR_TX_EMPTY)) { 225 while (!(msm_read(port, UART_SR) & UART_SR_TX_EMPTY)) {
@@ -306,12 +367,151 @@ unmap:
306 dma_unmap_single(port->dev, dma->phys, count, dma->dir); 367 dma_unmap_single(port->dev, dma->phys, count, dma->dir);
307 return ret; 368 return ret;
308} 369}
370
371static void msm_complete_rx_dma(void *args)
372{
373 struct msm_port *msm_port = args;
374 struct uart_port *port = &msm_port->uart;
375 struct tty_port *tport = &port->state->port;
376 struct msm_dma *dma = &msm_port->rx_dma;
377 int count = 0, i, sysrq;
378 unsigned long flags;
379 u32 val;
380
381 spin_lock_irqsave(&port->lock, flags);
382
383 /* Already stopped */
384 if (!dma->count)
385 goto done;
386
387 val = msm_read(port, UARTDM_DMEN);
388 val &= ~dma->enable_bit;
389 msm_write(port, val, UARTDM_DMEN);
390
391 /* Restore interrupts */
392 msm_port->imr |= UART_IMR_RXLEV | UART_IMR_RXSTALE;
393 msm_write(port, msm_port->imr, UART_IMR);
394
395 if (msm_read(port, UART_SR) & UART_SR_OVERRUN) {
396 port->icount.overrun++;
397 tty_insert_flip_char(tport, 0, TTY_OVERRUN);
398 msm_write(port, UART_CR_CMD_RESET_ERR, UART_CR);
399 }
400
401 count = msm_read(port, UARTDM_RX_TOTAL_SNAP);
402
403 port->icount.rx += count;
404
405 dma->count = 0;
406
407 dma_unmap_single(port->dev, dma->phys, UARTDM_RX_SIZE, dma->dir);
408
409 for (i = 0; i < count; i++) {
410 char flag = TTY_NORMAL;
411
412 if (msm_port->break_detected && dma->virt[i] == 0) {
413 port->icount.brk++;
414 flag = TTY_BREAK;
415 msm_port->break_detected = false;
416 if (uart_handle_break(port))
417 continue;
418 }
419
420 if (!(port->read_status_mask & UART_SR_RX_BREAK))
421 flag = TTY_NORMAL;
422
423 spin_unlock_irqrestore(&port->lock, flags);
424 sysrq = uart_handle_sysrq_char(port, dma->virt[i]);
425 spin_lock_irqsave(&port->lock, flags);
426 if (!sysrq)
427 tty_insert_flip_char(tport, dma->virt[i], flag);
428 }
429
430 msm_start_rx_dma(msm_port);
431done:
432 spin_unlock_irqrestore(&port->lock, flags);
433
434 if (count)
435 tty_flip_buffer_push(tport);
436}
437
438static void msm_start_rx_dma(struct msm_port *msm_port)
439{
440 struct msm_dma *dma = &msm_port->rx_dma;
441 struct uart_port *uart = &msm_port->uart;
442 u32 val;
443 int ret;
444
445 if (!dma->chan)
446 return;
447
448 dma->phys = dma_map_single(uart->dev, dma->virt,
449 UARTDM_RX_SIZE, dma->dir);
450 ret = dma_mapping_error(uart->dev, dma->phys);
451 if (ret)
452 return;
453
454 dma->desc = dmaengine_prep_slave_single(dma->chan, dma->phys,
455 UARTDM_RX_SIZE, DMA_DEV_TO_MEM,
456 DMA_PREP_INTERRUPT);
457 if (!dma->desc)
458 goto unmap;
459
460 dma->desc->callback = msm_complete_rx_dma;
461 dma->desc->callback_param = msm_port;
462
463 dma->cookie = dmaengine_submit(dma->desc);
464 ret = dma_submit_error(dma->cookie);
465 if (ret)
466 goto unmap;
467 /*
468 * Using DMA for FIFO off-load, no need for "Rx FIFO over
469 * watermark" or "stale" interrupts, disable them
470 */
471 msm_port->imr &= ~(UART_IMR_RXLEV | UART_IMR_RXSTALE);
472
473 /*
474 * Well, when DMA is ADM3 engine(implied by <= UARTDM v1.3),
475 * we need RXSTALE to flush input DMA fifo to memory
476 */
477 if (msm_port->is_uartdm < UARTDM_1P4)
478 msm_port->imr |= UART_IMR_RXSTALE;
479
480 msm_write(uart, msm_port->imr, UART_IMR);
481
482 dma->count = UARTDM_RX_SIZE;
483
484 dma_async_issue_pending(dma->chan);
485
486 msm_write(uart, UART_CR_CMD_RESET_STALE_INT, UART_CR);
487 msm_write(uart, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR);
488
489 val = msm_read(uart, UARTDM_DMEN);
490 val |= dma->enable_bit;
491
492 if (msm_port->is_uartdm < UARTDM_1P4)
493 msm_write(uart, val, UARTDM_DMEN);
494
495 msm_write(uart, UARTDM_RX_SIZE, UARTDM_DMRX);
496
497 if (msm_port->is_uartdm > UARTDM_1P3)
498 msm_write(uart, val, UARTDM_DMEN);
499
500 return;
501unmap:
502 dma_unmap_single(uart->dev, dma->phys, UARTDM_RX_SIZE, dma->dir);
503}
504
309static void msm_stop_rx(struct uart_port *port) 505static void msm_stop_rx(struct uart_port *port)
310{ 506{
311 struct msm_port *msm_port = UART_TO_MSM(port); 507 struct msm_port *msm_port = UART_TO_MSM(port);
508 struct msm_dma *dma = &msm_port->rx_dma;
312 509
313 msm_port->imr &= ~(UART_IMR_RXLEV | UART_IMR_RXSTALE); 510 msm_port->imr &= ~(UART_IMR_RXLEV | UART_IMR_RXSTALE);
314 msm_write(port, msm_port->imr, UART_IMR); 511 msm_write(port, msm_port->imr, UART_IMR);
512
513 if (dma->chan)
514 msm_stop_dma(port, dma);
315} 515}
316 516
317static void msm_enable_ms(struct uart_port *port) 517static 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)
392 msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR); 592 msm_write(port, UART_CR_CMD_RESET_STALE_INT, UART_CR);
393 msm_write(port, 0xFFFFFF, UARTDM_DMRX); 593 msm_write(port, 0xFFFFFF, UARTDM_DMRX);
394 msm_write(port, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR); 594 msm_write(port, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR);
595
596 /* Try to use DMA */
597 msm_start_rx_dma(msm_port);
395} 598}
396 599
397static void msm_handle_rx(struct uart_port *port) 600static void msm_handle_rx(struct uart_port *port)
@@ -558,8 +761,10 @@ static irqreturn_t msm_uart_irq(int irq, void *dev_id)
558{ 761{
559 struct uart_port *port = dev_id; 762 struct uart_port *port = dev_id;
560 struct msm_port *msm_port = UART_TO_MSM(port); 763 struct msm_port *msm_port = UART_TO_MSM(port);
764 struct msm_dma *dma = &msm_port->rx_dma;
561 unsigned long flags; 765 unsigned long flags;
562 unsigned int misr; 766 unsigned int misr;
767 u32 val;
563 768
564 spin_lock_irqsave(&port->lock, flags); 769 spin_lock_irqsave(&port->lock, flags);
565 misr = msm_read(port, UART_MISR); 770 misr = msm_read(port, UART_MISR);
@@ -571,10 +776,21 @@ static irqreturn_t msm_uart_irq(int irq, void *dev_id)
571 } 776 }
572 777
573 if (misr & (UART_IMR_RXLEV | UART_IMR_RXSTALE)) { 778 if (misr & (UART_IMR_RXLEV | UART_IMR_RXSTALE)) {
574 if (msm_port->is_uartdm) 779 if (dma->count) {
780 val = UART_CR_CMD_STALE_EVENT_DISABLE;
781 msm_write(port, val, UART_CR);
782 val = UART_CR_CMD_RESET_STALE_INT;
783 msm_write(port, val, UART_CR);
784 /*
785 * Flush DMA input fifo to memory, this will also
786 * trigger DMA RX completion
787 */
788 dmaengine_terminate_all(dma->chan);
789 } else if (msm_port->is_uartdm) {
575 msm_handle_rx_dm(port, misr); 790 msm_handle_rx_dm(port, misr);
576 else 791 } else {
577 msm_handle_rx(port); 792 msm_handle_rx(port);
793 }
578 } 794 }
579 if (misr & UART_IMR_TXLEV) 795 if (misr & UART_IMR_TXLEV)
580 msm_handle_tx(port); 796 msm_handle_tx(port);
@@ -773,8 +989,10 @@ static int msm_startup(struct uart_port *port)
773 data |= UART_MR1_AUTO_RFR_LEVEL0 & rfr_level; 989 data |= UART_MR1_AUTO_RFR_LEVEL0 & rfr_level;
774 msm_write(port, data, UART_MR1); 990 msm_write(port, data, UART_MR1);
775 991
776 if (msm_port->is_uartdm) 992 if (msm_port->is_uartdm) {
777 msm_request_tx_dma(msm_port, msm_port->uart.mapbase); 993 msm_request_tx_dma(msm_port, msm_port->uart.mapbase);
994 msm_request_rx_dma(msm_port, msm_port->uart.mapbase);
995 }
778 996
779 return 0; 997 return 0;
780} 998}
@@ -797,11 +1015,16 @@ static void msm_shutdown(struct uart_port *port)
797static void msm_set_termios(struct uart_port *port, struct ktermios *termios, 1015static void msm_set_termios(struct uart_port *port, struct ktermios *termios,
798 struct ktermios *old) 1016 struct ktermios *old)
799{ 1017{
1018 struct msm_port *msm_port = UART_TO_MSM(port);
1019 struct msm_dma *dma = &msm_port->rx_dma;
800 unsigned long flags; 1020 unsigned long flags;
801 unsigned int baud, mr; 1021 unsigned int baud, mr;
802 1022
803 spin_lock_irqsave(&port->lock, flags); 1023 spin_lock_irqsave(&port->lock, flags);
804 1024
1025 if (dma->chan) /* Terminate if any */
1026 msm_stop_dma(port, dma);
1027
805 /* calculate and set baud rate */ 1028 /* calculate and set baud rate */
806 baud = uart_get_baud_rate(port, termios, old, 300, 115200); 1029 baud = uart_get_baud_rate(port, termios, old, 300, 115200);
807 baud = msm_set_baud_rate(port, baud); 1030 baud = msm_set_baud_rate(port, baud);
@@ -866,6 +1089,9 @@ static void msm_set_termios(struct uart_port *port, struct ktermios *termios,
866 1089
867 uart_update_timeout(port, termios->c_cflag, baud); 1090 uart_update_timeout(port, termios->c_cflag, baud);
868 1091
1092 /* Try to use DMA */
1093 msm_start_rx_dma(msm_port);
1094
869 spin_unlock_irqrestore(&port->lock, flags); 1095 spin_unlock_irqrestore(&port->lock, flags);
870} 1096}
871 1097
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 @@
59#define UART_CR_CMD_SET_RFR (13 << 4) 59#define UART_CR_CMD_SET_RFR (13 << 4)
60#define UART_CR_CMD_RESET_RFR (14 << 4) 60#define UART_CR_CMD_RESET_RFR (14 << 4)
61#define UART_CR_CMD_PROTECTION_EN (16 << 4) 61#define UART_CR_CMD_PROTECTION_EN (16 << 4)
62#define UART_CR_CMD_STALE_EVENT_DISABLE (6 << 8)
62#define UART_CR_CMD_STALE_EVENT_ENABLE (80 << 4) 63#define UART_CR_CMD_STALE_EVENT_ENABLE (80 << 4)
63#define UART_CR_CMD_FORCE_STALE (4 << 8) 64#define UART_CR_CMD_FORCE_STALE (4 << 8)
64#define UART_CR_CMD_RESET_TX_READY (3 << 8) 65#define UART_CR_CMD_RESET_TX_READY (3 << 8)
@@ -124,6 +125,9 @@
124#define UARTDM_DMEN_TX_BAM_ENABLE BIT(2) /* UARTDM_1P4 */ 125#define UARTDM_DMEN_TX_BAM_ENABLE BIT(2) /* UARTDM_1P4 */
125#define UARTDM_DMEN_TX_DM_ENABLE BIT(0) /* < UARTDM_1P4 */ 126#define UARTDM_DMEN_TX_DM_ENABLE BIT(0) /* < UARTDM_1P4 */
126 127
128#define UARTDM_DMEN_RX_BAM_ENABLE BIT(3) /* UARTDM_1P4 */
129#define UARTDM_DMEN_RX_DM_ENABLE BIT(1) /* < UARTDM_1P4 */
130
127#define UARTDM_DMRX 0x34 131#define UARTDM_DMRX 0x34
128#define UARTDM_NCF_TX 0x40 132#define UARTDM_NCF_TX 0x40
129#define UARTDM_RX_TOTAL_SNAP 0x38 133#define UARTDM_RX_TOTAL_SNAP 0x38