diff options
author | Qipan Li <Qipan.Li@csr.com> | 2013-08-18 23:47:53 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-19 20:13:22 -0400 |
commit | 8316d04c42b94e94c8e54027d7c77ebe098ab5fa (patch) | |
tree | 365541927dac54b6d2f151366e59d999f5aa8fe7 /drivers/tty/serial/sirfsoc_uart.h | |
parent | 15cdcb12cbcbd6abf16d6b6a52e04d452b464e3b (diff) |
serial: sirf: add DMA support using dmaengine APIs
if we get the valid dma channels from dts, move to use dmaengine to do
rx/tx. because the dma hardware requires dma address and length to be
4bytes aligned, in this driver, we will still use PIO for non-aligned
bytes, and use dma for aligned bytes.
for rx, to keep the dmaengine always active, we use double-buffer, so
we issue two dma_desc at first, and maintain the status of both
1. dma transfer done: update in rx dma finish callback
2. dma buffer is inserted into tty: update in rx dma finish tasklet and
rx timeout tasklet
so we re-issue the dma_desc only if both 1&2 are finished.
for tx, as we know the actual length for every transfer, we don't need
the above double buffering.
Signed-off-by: Qipan Li <Qipan.Li@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/sirfsoc_uart.h')
-rw-r--r-- | drivers/tty/serial/sirfsoc_uart.h | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h index e87035a9bbcb..173e00f84c67 100644 --- a/drivers/tty/serial/sirfsoc_uart.h +++ b/drivers/tty/serial/sirfsoc_uart.h | |||
@@ -338,6 +338,12 @@ struct sirfsoc_uart_register sirfsoc_uart = { | |||
338 | uint_st->sirfsoc_rxfifo_thd |\ | 338 | uint_st->sirfsoc_rxfifo_thd |\ |
339 | uint_st->sirfsoc_rxfifo_full) | 339 | uint_st->sirfsoc_rxfifo_full) |
340 | #define SIRFUART_CTS_INT_ST(uint_st) (uint_st->sirfsoc_cts) | 340 | #define SIRFUART_CTS_INT_ST(uint_st) (uint_st->sirfsoc_cts) |
341 | #define SIRFUART_RX_DMA_INT_EN(port, uint_en) \ | ||
342 | (uint_en->sirfsoc_rx_timeout_en |\ | ||
343 | uint_en->sirfsoc_frm_err_en |\ | ||
344 | uint_en->sirfsoc_rx_oflow_en |\ | ||
345 | uint_en->sirfsoc_rxd_brk_en |\ | ||
346 | ((port->line > 2) ? 0 : uint_en->sirfsoc_parity_err_en)) | ||
341 | /* Generic Definitions */ | 347 | /* Generic Definitions */ |
342 | #define SIRFSOC_UART_NAME "ttySiRF" | 348 | #define SIRFSOC_UART_NAME "ttySiRF" |
343 | #define SIRFSOC_UART_MAJOR 0 | 349 | #define SIRFSOC_UART_MAJOR 0 |
@@ -356,12 +362,52 @@ struct sirfsoc_uart_register sirfsoc_uart = { | |||
356 | #define SIRF_SAMPLE_DIV_MASK 0x3f0000 | 362 | #define SIRF_SAMPLE_DIV_MASK 0x3f0000 |
357 | #define SIRF_BAUD_RATE_SUPPORT_NR 18 | 363 | #define SIRF_BAUD_RATE_SUPPORT_NR 18 |
358 | 364 | ||
365 | /* Uart Common Use Macro*/ | ||
366 | #define SIRFSOC_RX_DMA_BUF_SIZE 256 | ||
367 | #define BYTES_TO_ALIGN(dma_addr) ((unsigned long)(dma_addr) & 0x3) | ||
368 | #define LOOP_DMA_BUFA_FILL 1 | ||
369 | #define LOOP_DMA_BUFB_FILL 2 | ||
370 | #define TX_TRAN_PIO 1 | ||
371 | #define TX_TRAN_DMA 2 | ||
372 | /* Uart Fifo Level Chk */ | ||
373 | #define SIRFUART_TX_FIFO_SC_OFFSET 0 | ||
374 | #define SIRFUART_TX_FIFO_LC_OFFSET 10 | ||
375 | #define SIRFUART_TX_FIFO_HC_OFFSET 20 | ||
376 | #define SIRFUART_TX_FIFO_CHK_SC(line, value) ((((line) == 1) ? (value & 0x3) :\ | ||
377 | (value & 0x1f)) << SIRFUART_TX_FIFO_SC_OFFSET) | ||
378 | #define SIRFUART_TX_FIFO_CHK_LC(line, value) ((((line) == 1) ? (value & 0x3) :\ | ||
379 | (value & 0x1f)) << SIRFUART_TX_FIFO_LC_OFFSET) | ||
380 | #define SIRFUART_TX_FIFO_CHK_HC(line, value) ((((line) == 1) ? (value & 0x3) :\ | ||
381 | (value & 0x1f)) << SIRFUART_TX_FIFO_HC_OFFSET) | ||
382 | |||
383 | #define SIRFUART_RX_FIFO_CHK_SC SIRFUART_TX_FIFO_CHK_SC | ||
384 | #define SIRFUART_RX_FIFO_CHK_LC SIRFUART_TX_FIFO_CHK_LC | ||
385 | #define SIRFUART_RX_FIFO_CHK_HC SIRFUART_TX_FIFO_CHK_HC | ||
386 | /* Indicate how many buffers used */ | ||
387 | #define SIRFSOC_RX_LOOP_BUF_CNT 2 | ||
388 | |||
389 | /* Indicate if DMA channel valid */ | ||
390 | #define IS_DMA_CHAN_VALID(x) ((x) != -1) | ||
391 | #define UNVALID_DMA_CHAN -1 | ||
359 | /* For Fast Baud Rate Calculation */ | 392 | /* For Fast Baud Rate Calculation */ |
360 | struct sirfsoc_baudrate_to_regv { | 393 | struct sirfsoc_baudrate_to_regv { |
361 | unsigned int baud_rate; | 394 | unsigned int baud_rate; |
362 | unsigned int reg_val; | 395 | unsigned int reg_val; |
363 | }; | 396 | }; |
364 | 397 | ||
398 | enum sirfsoc_tx_state { | ||
399 | TX_DMA_IDLE, | ||
400 | TX_DMA_RUNNING, | ||
401 | TX_DMA_PAUSE, | ||
402 | }; | ||
403 | |||
404 | struct sirfsoc_loop_buffer { | ||
405 | struct circ_buf xmit; | ||
406 | dma_cookie_t cookie; | ||
407 | struct dma_async_tx_descriptor *desc; | ||
408 | dma_addr_t dma_addr; | ||
409 | }; | ||
410 | |||
365 | struct sirfsoc_uart_port { | 411 | struct sirfsoc_uart_port { |
366 | bool hw_flow_ctrl; | 412 | bool hw_flow_ctrl; |
367 | bool ms_enabled; | 413 | bool ms_enabled; |
@@ -371,8 +417,25 @@ struct sirfsoc_uart_port { | |||
371 | /* for SiRFmarco, there are SET/CLR for UART_INT_EN */ | 417 | /* for SiRFmarco, there are SET/CLR for UART_INT_EN */ |
372 | bool is_marco; | 418 | bool is_marco; |
373 | struct sirfsoc_uart_register *uart_reg; | 419 | struct sirfsoc_uart_register *uart_reg; |
420 | int rx_dma_no; | ||
421 | int tx_dma_no; | ||
422 | struct dma_chan *rx_dma_chan; | ||
423 | struct dma_chan *tx_dma_chan; | ||
424 | dma_addr_t tx_dma_addr; | ||
425 | struct dma_async_tx_descriptor *tx_dma_desc; | ||
426 | spinlock_t rx_lock; | ||
427 | spinlock_t tx_lock; | ||
428 | struct tasklet_struct rx_dma_complete_tasklet; | ||
429 | struct tasklet_struct rx_tmo_process_tasklet; | ||
430 | unsigned int rx_io_count; | ||
431 | unsigned long transfer_size; | ||
432 | enum sirfsoc_tx_state tx_dma_state; | ||
374 | unsigned int cts_gpio; | 433 | unsigned int cts_gpio; |
375 | unsigned int rts_gpio; | 434 | unsigned int rts_gpio; |
435 | |||
436 | struct sirfsoc_loop_buffer rx_dma_items[SIRFSOC_RX_LOOP_BUF_CNT]; | ||
437 | int rx_completed; | ||
438 | int rx_issued; | ||
376 | }; | 439 | }; |
377 | 440 | ||
378 | /* Hardware Flow Control */ | 441 | /* Hardware Flow Control */ |