![Robert Baldyga](/assets/img/avatar_default.png)
Add RX DMA transfers support for samsung serial driver. It's enabled when DMA controller for RX channel is specified in device-tree. DMA transactions are started when number of bytes in RX FIFO reaches trigger level, otherwise PIO mode is used. DMA transfer size is always PAGE_SIZE which can cause large latency when smaller data amount is transferred, so we always terminate DMA transaction on RX timeout interrupt. Timeout interval is set to 64 frame times. Based on previous work of Sylwester Nawrocki and Lukasz Czerwinski. Signed-off-by: Robert Baldyga <r.baldyga@samsung.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
126 lines
2.8 KiB
C
126 lines
2.8 KiB
C
#ifndef __SAMSUNG_H
|
|
#define __SAMSUNG_H
|
|
|
|
/*
|
|
* Driver for Samsung SoC onboard UARTs.
|
|
*
|
|
* Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
|
|
* http://armlinux.simtec.co.uk/
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
|
|
#include <linux/dmaengine.h>
|
|
|
|
struct s3c24xx_uart_info {
|
|
char *name;
|
|
unsigned int type;
|
|
unsigned int fifosize;
|
|
unsigned long rx_fifomask;
|
|
unsigned long rx_fifoshift;
|
|
unsigned long rx_fifofull;
|
|
unsigned long tx_fifomask;
|
|
unsigned long tx_fifoshift;
|
|
unsigned long tx_fifofull;
|
|
unsigned int def_clk_sel;
|
|
unsigned long num_clks;
|
|
unsigned long clksel_mask;
|
|
unsigned long clksel_shift;
|
|
|
|
/* uart port features */
|
|
|
|
unsigned int has_divslot:1;
|
|
|
|
/* uart controls */
|
|
int (*reset_port)(struct uart_port *, struct s3c2410_uartcfg *);
|
|
};
|
|
|
|
struct s3c24xx_serial_drv_data {
|
|
struct s3c24xx_uart_info *info;
|
|
struct s3c2410_uartcfg *def_cfg;
|
|
unsigned int fifosize[CONFIG_SERIAL_SAMSUNG_UARTS];
|
|
};
|
|
|
|
struct s3c24xx_uart_dma {
|
|
dma_filter_fn fn;
|
|
void *rx_param;
|
|
void *tx_param;
|
|
|
|
unsigned int rx_chan_id;
|
|
unsigned int tx_chan_id;
|
|
|
|
struct dma_slave_config rx_conf;
|
|
struct dma_slave_config tx_conf;
|
|
|
|
struct dma_chan *rx_chan;
|
|
struct dma_chan *tx_chan;
|
|
|
|
dma_addr_t rx_addr;
|
|
dma_addr_t tx_addr;
|
|
|
|
dma_cookie_t rx_cookie;
|
|
dma_cookie_t tx_cookie;
|
|
|
|
char *rx_buf;
|
|
|
|
dma_addr_t tx_transfer_addr;
|
|
|
|
size_t rx_size;
|
|
size_t tx_size;
|
|
|
|
struct dma_async_tx_descriptor *tx_desc;
|
|
struct dma_async_tx_descriptor *rx_desc;
|
|
|
|
int tx_bytes_requested;
|
|
int rx_bytes_requested;
|
|
};
|
|
|
|
struct s3c24xx_uart_port {
|
|
unsigned char rx_claimed;
|
|
unsigned char tx_claimed;
|
|
unsigned int pm_level;
|
|
unsigned long baudclk_rate;
|
|
|
|
unsigned int rx_irq;
|
|
unsigned int tx_irq;
|
|
|
|
unsigned int tx_in_progress;
|
|
unsigned int tx_mode;
|
|
unsigned int rx_mode;
|
|
|
|
struct s3c24xx_uart_info *info;
|
|
struct clk *clk;
|
|
struct clk *baudclk;
|
|
struct uart_port port;
|
|
struct s3c24xx_serial_drv_data *drv_data;
|
|
|
|
/* reference to platform data */
|
|
struct s3c2410_uartcfg *cfg;
|
|
|
|
struct s3c24xx_uart_dma *dma;
|
|
|
|
#ifdef CONFIG_CPU_FREQ
|
|
struct notifier_block freq_transition;
|
|
#endif
|
|
};
|
|
|
|
/* conversion functions */
|
|
|
|
#define s3c24xx_dev_to_port(__dev) dev_get_drvdata(__dev)
|
|
|
|
/* register access controls */
|
|
|
|
#define portaddr(port, reg) ((port)->membase + (reg))
|
|
#define portaddrl(port, reg) \
|
|
((unsigned long *)(unsigned long)((port)->membase + (reg)))
|
|
|
|
#define rd_regb(port, reg) (__raw_readb(portaddr(port, reg)))
|
|
#define rd_regl(port, reg) (__raw_readl(portaddr(port, reg)))
|
|
|
|
#define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg))
|
|
#define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg))
|
|
|
|
#endif
|