#define SUPPORT_SYSRQ\r
#endif\r
\r
-//#define DEBUG\r
#include <linux/module.h>\r
#include <linux/ioport.h>\r
#include <linux/init.h>\r
#include <linux/serial_reg.h>\r
#include <linux/serial_core.h>\r
#include <linux/serial.h>\r
-#include <linux/serial_8250.h>\r
#include <linux/nmi.h>\r
#include <linux/mutex.h>\r
#include <linux/slab.h>\r
#include <asm/io.h>\r
#include <asm/irq.h>\r
\r
+/*\r
+* Driver Version Note\r
+*\r
+*v0.0 : this driver is 2.6.32 kernel driver;\r
+*v0.1 : this driver is 3.0.8 kernel driver;\r
+*v1.0 : 1.modify dma dirver;\r
+* 2.enable Programmable THRE Interrupt Mode, so we can just judge ((up->iir & 0x0f) == 0x02) when transmit\r
+* 3.reset uart and set it to loopback state to ensure setting baud rate sucessfully \r
+*/\r
+#define VERSION_AND_TIME "rk_serial.c v1.0 2012-08-09"\r
\r
#define PORT_RK 90\r
#define UART_USR 0x1F /* UART Status Register */\r
#define UART_LSR_RFE 0x80 /* receive fifo error */\r
#define UART_SRR 0x22 /* software reset register */\r
#define UART_RESET 0x01\r
-#define RX_TIMEOUT (3000*10) //uint ms\r
\r
#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)\r
\r
#define UART_NR 4 //uart port number\r
-#define POWER_MANEGEMENT 1\r
\r
-/* configurate whether the port transmit-receive by DMA */\r
+/* configurate whether the port transmit-receive by DMA in menuconfig*/\r
#define OPEN_DMA 1\r
#define CLOSE_DMA 0\r
\r
-#ifdef CONFIG_UART0_DMA_RK29\r
-#define UART0_USE_DMA OPEN_DMA\r
+#define TX_DMA (1)\r
+#define RX_DMA (2)\r
+\r
+#ifdef CONFIG_UART0_DMA_RK29 \r
+#define UART0_USE_DMA CONFIG_UART0_DMA_RK29\r
#else\r
#define UART0_USE_DMA CLOSE_DMA\r
#endif\r
-\r
+#ifdef CONFIG_UART1_DMA_RK29\r
+#define UART1_USE_DMA CONFIG_UART1_DMA_RK29\r
+#else\r
+#define UART1_USE_DMA CLOSE_DMA\r
+#endif\r
#ifdef CONFIG_UART2_DMA_RK29\r
-#define UART2_USE_DMA OPEN_DMA\r
+#define UART2_USE_DMA CONFIG_UART2_DMA_RK29\r
#else\r
#define UART2_USE_DMA CLOSE_DMA\r
#endif\r
-\r
#ifdef CONFIG_UART3_DMA_RK29\r
-#define UART3_USE_DMA OPEN_DMA\r
+#define UART3_USE_DMA CONFIG_UART3_DMA_RK29\r
#else\r
#define UART3_USE_DMA CLOSE_DMA\r
#endif\r
\r
-#define UART1_USE_DMA CLOSE_DMA\r
+#define USE_TIMER 1 // use timer for dma transport\r
+#define POWER_MANEGEMENT 1\r
+#define RX_TIMEOUT (3000*3) //uint ms\r
+#define DMA_TX_TRRIGE_LEVEL 128\r
+#define SERIAL_CIRC_CNT_TO_END(xmit) CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE)\r
+\r
\r
#define USE_DMA (UART0_USE_DMA | UART1_USE_DMA | UART2_USE_DMA | UART3_USE_DMA)\r
#if USE_DMA\r
#endif\r
#endif\r
\r
-#define DMA_TX_TRRIGE_LEVEL 30\r
\r
-#define USE_TIMER 1 // use timer for dma transport\r
-#define THRE_MODE 0X00 //0yhh\r
\r
static struct uart_driver serial_rk_reg;\r
\r
/*\r
* Debugging.\r
*/\r
+#ifdef CONFIG_ARCH_RK29\r
#define DBG_PORT 1 //DBG_PORT which uart is used to print log message\r
-\r
+#else\r
+#define DBG_PORT -1 //DBG_PORT which uart is used to print log message\r
+#endif\r
#ifdef CONFIG_SERIAL_CORE_CONSOLE\r
#define uart_console(port) ((port)->cons && (port)->cons->index == (port)->line)\r
#else\r
#define uart_console(port) (0)\r
#endif\r
\r
-#define DEBUG 0\r
\r
extern void printascii(const char *);\r
static void dbg(const char *fmt, ...)\r
printascii(buff);\r
}\r
\r
+//enable log output\r
+#define DEBUG 1\r
+static int log_port = -1;\r
+module_param(log_port, int, S_IRUGO|S_IWUSR);\r
+\r
#if DEBUG\r
-#define DEBUG_INTR(fmt...) if (!uart_console(&up->port)) dbg(fmt)\r
+#define DEBUG_INTR(fmt...) if (up->port.line == log_port && !uart_console(&up->port)) dbg(fmt)\r
#else\r
#define DEBUG_INTR(fmt...) do { } while (0)\r
#endif\r
#if USE_DMA\r
/* added by hhb@rock-chips.com for uart dma transfer */\r
\r
-struct rk29_uart_dma_t {\r
+struct rk_uart_dma {\r
u32 use_dma; //1:used\r
- u32 rx_dma_start;\r
enum dma_ch rx_dmach;\r
enum dma_ch tx_dmach;\r
- u32 tx_dma_inited;\r
- u32 rx_dma_inited;\r
- spinlock_t tx_lock;\r
- spinlock_t rx_lock;\r
- char * rx_buffer;\r
+\r
+ //receive and transfer buffer\r
+ char * rx_buffer; //visual memory\r
char * tx_buffer;\r
- dma_addr_t rx_phy_addr;\r
+ dma_addr_t rx_phy_addr; //physical memory\r
dma_addr_t tx_phy_addr;\r
- u32 rx_buffer_size;\r
- u32 tx_buffer_size;\r
+ u32 rb_size; //buffer size\r
+ u32 tb_size;\r
\r
- u32 rb_cur_pos;\r
- u32 rb_pre_pos;\r
+ //regard the rx buffer as a circular buffer\r
+ u32 rb_head;\r
+ u32 rb_tail;\r
u32 rx_size;\r
- char use_timer;\r
- char tx_dma_used;\r
- /* timer to poll activity on rx dma */\r
- struct timer_list rx_timer;\r
- int rx_timeout;\r
\r
+ spinlock_t tx_lock;\r
+ spinlock_t rx_lock;\r
+\r
+ char tx_dma_inited; //1:dma tx channel has been init\r
+ char rx_dma_inited; //1:dma rx channel has been init\r
+ char tx_dma_used; //1:dma tx is working\r
+ char rx_dma_used; //1:dma rx is working\r
+\r
+ /* timer to poll activity on rx dma */\r
+ char use_timer;\r
+ int rx_timeout;\r
+ struct timer_list rx_timer;\r
};\r
#endif\r
\r
#endif\r
\r
char name[12];\r
- char fifo[32];\r
+ char fifo[64];\r
char fifo_size;\r
unsigned long port_activity;\r
struct work_struct uart_work;\r
struct work_struct uart_work_rx;\r
struct workqueue_struct *uart_wq;\r
#if USE_DMA\r
- struct rk29_uart_dma_t *prk29_uart_dma_t;\r
+ struct rk_uart_dma *dma;\r
#endif\r
};\r
\r
#if USE_DMA\r
static void serial_rk_release_dma_tx(struct uart_port *port);\r
static int serial_rk_start_tx_dma(struct uart_port *port);\r
-static void serial_rk_rx_timeout(unsigned long uart);\r
+//static void serial_rk_rx_timeout(unsigned long uart);\r
static void serial_rk_release_dma_rx(struct uart_port *port);\r
static int serial_rk_start_rx_dma(struct uart_port *port);\r
#else\r
static inline int serial_rk_start_tx_dma(struct uart_port *port) { return 0; }\r
#endif\r
static int serial_rk_startup(struct uart_port *port);\r
+\r
static inline unsigned int serial_in(struct uart_rk_port *up, int offset)\r
{\r
offset = offset << 2;\r
static int serial_dl_write(struct uart_rk_port *up, unsigned int value)\r
{\r
unsigned int tmout = 100;\r
- if(up->port.line != DBG_PORT)\r
- {\r
- while(!(serial_in(up, UART_LCR) & UART_LCR_DLAB)){\r
- if (--tmout == 0){\r
+\r
+ while(!(serial_in(up, UART_LCR) & UART_LCR_DLAB)){\r
+ if (--tmout == 0){\r
+ if(up->port.line != DBG_PORT)\r
dbg("set serial.%d baudrate fail with DLAB not set\n", up->port.line);\r
- return -1;\r
- }\r
+ return -1;\r
}\r
+ }\r
\r
- tmout = 15000;\r
- while(serial_in(up, UART_USR) & UART_USR_BUSY){\r
- if (--tmout == 0){\r
+ tmout = 15000;\r
+ while(serial_in(up, UART_USR) & UART_USR_BUSY){\r
+ if (--tmout == 0){\r
+ if(up->port.line != DBG_PORT)\r
dbg("set serial.%d baudrate timeout\n", up->port.line);\r
- return -1;\r
- }\r
+ return -1;\r
}\r
+ udelay(1);\r
}\r
\r
serial_out(up, UART_DLL, value & 0xff);\r
{\r
unsigned int tmout = 15000;\r
\r
- if(up->port.line != DBG_PORT)\r
- {\r
- while(serial_in(up, UART_USR) & UART_USR_BUSY){\r
-\r
- if (--tmout == 0){\r
+ while(serial_in(up, UART_USR) & UART_USR_BUSY){\r
+ if (--tmout == 0){\r
+ if(up->port.line != DBG_PORT)\r
dbg("set serial.%d lc r = 0x%02x timeout\n", up->port.line, value);\r
- return -1;\r
- }\r
- udelay(1);\r
+ return -1;\r
}\r
+ udelay(1);\r
}\r
\r
serial_out(up, UART_LCR, value);\r
serial_out(up, UART_IER, up->ier);\r
}\r
}\r
-#if 0\r
+\r
static int rk29_uart_dump_register(struct uart_rk_port *up){\r
\r
unsigned int reg_value = 0;\r
return 0;\r
\r
}\r
-#endif\r
\r
/*\r
* FIFO support.\r
struct uart_rk_port *up =\r
container_of(port, struct uart_rk_port, port);\r
#if USE_DMA\r
- struct rk29_uart_dma_t *prk29_uart_dma_t = up->prk29_uart_dma_t;\r
-\r
- if(OPEN_DMA == prk29_uart_dma_t->use_dma){\r
+ struct rk_uart_dma *uart_dma = up->dma;\r
+ if(uart_dma->use_dma & TX_DMA){\r
serial_rk_release_dma_tx(port);\r
}\r
#endif\r
__stop_tx(up);\r
+\r
}\r
\r
\r
struct uart_rk_port *up =\r
container_of(port, struct uart_rk_port, port);\r
\r
-\r
- if(0 == serial_rk_start_tx_dma(port)){\r
+#if USE_DMA\r
+ if(up->dma->use_dma & TX_DMA) {\r
+ if(!up->dma->tx_dma_used)\r
+ serial_rk_enable_ier_thri(up);\r
+ }else {\r
serial_rk_enable_ier_thri(up);\r
}\r
-\r
+#else\r
+ serial_rk_enable_ier_thri(up);\r
+#endif\r
}\r
\r
\r
struct uart_rk_port *up =\r
container_of(port, struct uart_rk_port, port);\r
#if USE_DMA\r
- struct rk29_uart_dma_t *prk29_uart_dma_t = up->prk29_uart_dma_t;\r
-\r
- if(OPEN_DMA == prk29_uart_dma_t->use_dma){\r
+ struct rk_uart_dma *uart_dma = up->dma;\r
+ if(uart_dma->use_dma & RX_DMA){\r
serial_rk_release_dma_rx(port);\r
}\r
#endif\r
#define DMA_SERIAL_BUFFER_SIZE UART_XMIT_SIZE\r
\r
/* added by hhb@rock-chips.com for uart dma transfer*/\r
-static struct rk29_uart_dma_t rk29_uart_ports_dma_t[] = {\r
- {UART0_USE_DMA, 0, DMACH_UART0_RX, DMACH_UART0_TX},\r
- {UART1_USE_DMA, 0, DMACH_UART1_RX, DMACH_UART1_TX},\r
- {UART2_USE_DMA, 0, DMACH_UART2_RX, DMACH_UART2_TX},\r
- {UART3_USE_DMA, 0, DMACH_UART3_RX, DMACH_UART3_TX},\r
+static struct rk_uart_dma rk29_uart_ports_dma[] = {\r
+ {UART0_USE_DMA, DMACH_UART0_RX, DMACH_UART0_TX},\r
+ {UART1_USE_DMA, DMACH_UART1_RX, DMACH_UART1_TX},\r
+ {UART2_USE_DMA, DMACH_UART2_RX, DMACH_UART2_TX},\r
+ {UART3_USE_DMA, DMACH_UART3_RX, DMACH_UART3_TX},\r
};\r
\r
\r
/* DMAC PL330 add by hhb@rock-chips.com */\r
static struct rk29_dma_client rk29_uart_dma_client = {\r
- .name = "rk29xx-uart-dma",\r
+ .name = "rk-uart-dma",\r
};\r
\r
/*TX*/\r
{\r
struct uart_rk_port *up =\r
container_of(port, struct uart_rk_port, port);\r
- struct rk29_uart_dma_t *prk29_uart_dma_t = up->prk29_uart_dma_t;\r
+ struct rk_uart_dma *uart_dma = up->dma;\r
if(!port){\r
return;\r
}\r
- if(prk29_uart_dma_t && prk29_uart_dma_t->tx_dma_inited) {\r
- rk29_dma_free(prk29_uart_dma_t->tx_dmach, &rk29_uart_dma_client);\r
- prk29_uart_dma_t->tx_dma_inited = 0;\r
+ if(uart_dma && uart_dma->tx_dma_inited) {\r
+ rk29_dma_free(uart_dma->tx_dmach, &rk29_uart_dma_client);\r
+ uart_dma->tx_dma_inited = 0;\r
+ uart_dma->tx_dma_used = 0;\r
}\r
}\r
\r
struct circ_buf *xmit = &port->state->xmit;\r
\r
if(result != RK29_RES_OK){\r
+ printk(">>>>%s:%d result:%d\n", __func__, __LINE__, result);\r
+ up->dma->tx_dma_used = 0;\r
return;\r
}\r
\r
- port->icount.tx += size;\r
+ //spin_lock(&(up->dma->rx_lock));\r
xmit->tail = (xmit->tail + size) & (UART_XMIT_SIZE - 1);\r
-\r
+ port->icount.tx += size;\r
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)\r
uart_write_wakeup(&up->port);\r
- spin_lock(&(up->prk29_uart_dma_t->tx_lock));\r
- up->prk29_uart_dma_t->tx_dma_used = 0;\r
- spin_unlock(&(up->prk29_uart_dma_t->tx_lock));\r
- if (!uart_circ_empty(xmit)) {\r
- serial_rk_start_tx_dma(port);\r
- }\r
\r
+ //spin_lock(&(up->dma->tx_lock));\r
+ up->dma->tx_dma_used = 0;\r
+ //spin_unlock(&(up->dma->tx_lock));\r
+ serial_rk_enable_ier_thri(up);\r
up->port_activity = jiffies;\r
// dev_info(up->port.dev, "s:%d\n", size);\r
}\r
\r
struct uart_rk_port *up =\r
container_of(port, struct uart_rk_port, port);\r
- struct rk29_uart_dma_t *prk29_uart_dma_t = up->prk29_uart_dma_t;\r
- if(!port || !prk29_uart_dma_t){\r
+ struct rk_uart_dma *uart_dma = up->dma;\r
+\r
+ if(!port || !uart_dma){\r
dev_info(up->port.dev, "serial_rk_init_dma_tx fail\n");\r
return -1;\r
}\r
\r
- if(prk29_uart_dma_t->tx_dma_inited) {\r
+ if(uart_dma->tx_dma_inited) {\r
return 0;\r
}\r
\r
- if (rk29_dma_request(prk29_uart_dma_t->tx_dmach, &rk29_uart_dma_client, NULL) == -EBUSY) {\r
+ if (rk29_dma_request(uart_dma->tx_dmach, &rk29_uart_dma_client, NULL) == -EBUSY) {\r
dev_info(up->port.dev, "rk29_dma_request tx fail\n");\r
return -1;\r
}\r
\r
- if (rk29_dma_set_buffdone_fn(prk29_uart_dma_t->tx_dmach, serial_rk_dma_txcb)) {\r
+ if (rk29_dma_set_buffdone_fn(uart_dma->tx_dmach, serial_rk_dma_txcb)) {\r
dev_info(up->port.dev, "rk29_dma_set_buffdone_fn tx fail\n");\r
return -1;\r
}\r
- if (rk29_dma_devconfig(prk29_uart_dma_t->tx_dmach, RK29_DMASRC_MEM, (unsigned long)(port->iobase + UART_TX))) {\r
+ \r
+ if (rk29_dma_devconfig(uart_dma->tx_dmach, RK29_DMASRC_MEM, (unsigned long)(port->iobase + UART_TX))) {\r
dev_info(up->port.dev, "rk29_dma_devconfig tx fail\n");\r
return -1;\r
}\r
- if (rk29_dma_config(prk29_uart_dma_t->tx_dmach, 1, 1)) {\r
+ \r
+ if (rk29_dma_config(uart_dma->tx_dmach, 1, 16)) {\r
dev_info(up->port.dev, "rk29_dma_config tx fail\n");\r
return -1;\r
}\r
\r
- prk29_uart_dma_t->tx_dma_inited = 1;\r
+ uart_dma->tx_dma_inited = 1;\r
dev_info(up->port.dev, "serial_rk_init_dma_tx sucess\n");\r
return 0;\r
\r
\r
static int serial_rk_start_tx_dma(struct uart_port *port)\r
{\r
-\r
+ int count = 0;\r
struct circ_buf *xmit = &port->state->xmit;\r
struct uart_rk_port *up = container_of(port, struct uart_rk_port, port);\r
- struct rk29_uart_dma_t *prk29_uart_dma_t = up->prk29_uart_dma_t;\r
+ struct rk_uart_dma *uart_dma = up->dma;\r
\r
- if(0 == prk29_uart_dma_t->use_dma){\r
- return CLOSE_DMA;\r
- }\r
+ if(!uart_dma->use_dma)\r
+ goto err_out;\r
\r
- if(-1 == serial_rk_init_dma_tx(port)){\r
+ if(-1 == serial_rk_init_dma_tx(port))\r
goto err_out;\r
- }\r
\r
- if (1 == prk29_uart_dma_t->tx_dma_used){\r
+ if (1 == uart_dma->tx_dma_used)\r
return 1;\r
- }\r
- if(!uart_circ_empty(xmit)){\r
- if (rk29_dma_enqueue(prk29_uart_dma_t->tx_dmach, port,\r
- prk29_uart_dma_t->tx_phy_addr + xmit->tail,\r
- CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE))) {\r
+\r
+// spin_lock(&(uart_dma->tx_lock));\r
+ __stop_tx(up);\r
+\r
+ count = SERIAL_CIRC_CNT_TO_END(xmit);\r
+ count -= count%16;\r
+ if(count >= DMA_TX_TRRIGE_LEVEL) {\r
+ if (rk29_dma_enqueue(uart_dma->tx_dmach, port, uart_dma->tx_phy_addr + xmit->tail , count)) {\r
goto err_out;\r
}\r
+ rk29_dma_ctrl(uart_dma->tx_dmach, RK29_DMAOP_START);\r
+ up->dma->tx_dma_used = 1;\r
}\r
- rk29_dma_ctrl(prk29_uart_dma_t->tx_dmach, RK29_DMAOP_START);\r
- spin_lock(&(prk29_uart_dma_t->tx_lock));\r
- up->prk29_uart_dma_t->tx_dma_used = 1;\r
- spin_unlock(&(prk29_uart_dma_t->tx_lock));\r
-\r
+// spin_unlock(&(uart_dma->tx_lock));\r
return 1;\r
err_out:\r
dev_info(up->port.dev, "-serial_rk_start_tx_dma-error-\n");\r
return -1;\r
-\r
}\r
\r
\r
/*RX*/\r
static void serial_rk_dma_rxcb(void *buf, int size, enum rk29_dma_buffresult result) {\r
\r
-\r
+ //printk(">>%s:%d\n", __func__, result);\r
}\r
\r
static void serial_rk_release_dma_rx(struct uart_port *port)\r
{\r
struct uart_rk_port *up =\r
container_of(port, struct uart_rk_port, port);\r
- struct rk29_uart_dma_t *prk29_uart_dma_t = up->prk29_uart_dma_t;\r
+ struct rk_uart_dma *uart_dma = up->dma;\r
+ \r
if(!port){\r
return;\r
}\r
- if(prk29_uart_dma_t && prk29_uart_dma_t->rx_dma_inited) {\r
- del_timer(&prk29_uart_dma_t->rx_timer);\r
- rk29_dma_free(prk29_uart_dma_t->rx_dmach, &rk29_uart_dma_client);\r
- prk29_uart_dma_t->rb_pre_pos = 0;\r
- prk29_uart_dma_t->rx_dma_inited = 0;\r
- prk29_uart_dma_t->rx_dma_start = 0;\r
+ \r
+ if(uart_dma && uart_dma->rx_dma_inited) {\r
+ del_timer(&uart_dma->rx_timer);\r
+ rk29_dma_free(uart_dma->rx_dmach, &rk29_uart_dma_client);\r
+ uart_dma->rb_tail = 0;\r
+ uart_dma->rx_dma_inited = 0;\r
+ uart_dma->rx_dma_used = 0;\r
}\r
}\r
\r
\r
struct uart_rk_port *up =\r
container_of(port, struct uart_rk_port, port);\r
- struct rk29_uart_dma_t *prk29_uart_dma_t = up->prk29_uart_dma_t;\r
- if(!port || !prk29_uart_dma_t){\r
+ struct rk_uart_dma *uart_dma = up->dma;\r
+\r
+ if(!port || !uart_dma){\r
dev_info(up->port.dev, "serial_rk_init_dma_rx: port fail\n");\r
return -1;\r
}\r
- if(prk29_uart_dma_t->rx_dma_inited) {\r
+\r
+ if(uart_dma->rx_dma_inited) {\r
return 0;\r
}\r
\r
- if (rk29_dma_request(prk29_uart_dma_t->rx_dmach, &rk29_uart_dma_client, NULL) == -EBUSY) {\r
+ if (rk29_dma_request(uart_dma->rx_dmach, &rk29_uart_dma_client, NULL) == -EBUSY) {\r
dev_info(up->port.dev, "rk29_dma_request fail rx \n");\r
return -1;\r
}\r
\r
- if (rk29_dma_set_buffdone_fn(prk29_uart_dma_t->rx_dmach, serial_rk_dma_rxcb)) {\r
+ if (rk29_dma_set_buffdone_fn(uart_dma->rx_dmach, serial_rk_dma_rxcb)) {\r
dev_info(up->port.dev, "rk29_dma_set_buffdone_fn rx fail\n");\r
return -1;\r
}\r
- if (rk29_dma_devconfig(prk29_uart_dma_t->rx_dmach, RK29_DMASRC_HW, (unsigned long)(port->iobase + UART_RX))) {\r
+\r
+ if (rk29_dma_devconfig(uart_dma->rx_dmach, RK29_DMASRC_HW, (unsigned long)(port->iobase + UART_RX))) {\r
dev_info(up->port.dev, "rk29_dma_devconfig rx fail\n");\r
return -1;\r
}\r
\r
- if (rk29_dma_config(prk29_uart_dma_t->rx_dmach, 1, 1)) {\r
- dev_info(up->port.dev, "rk29_dma_config rx fail\n");\r
+ if (rk29_dma_config(uart_dma->rx_dmach, 1, 1)) {\r
+ dev_info(up->port.dev, "rk29_dma_config rx fail 1 1 \n");\r
return -1;\r
}\r
\r
- rk29_dma_setflags(prk29_uart_dma_t->rx_dmach, RK29_DMAF_CIRCULAR);\r
+ rk29_dma_setflags(uart_dma->rx_dmach, RK29_DMAF_CIRCULAR);\r
\r
- prk29_uart_dma_t->rx_dma_inited = 1;\r
+ uart_dma->rx_dma_inited = 1;\r
dev_info(up->port.dev, "serial_rk_init_dma_rx sucess\n");\r
return 0;\r
\r
{\r
struct uart_rk_port *up =\r
container_of(port, struct uart_rk_port, port);\r
- struct rk29_uart_dma_t *prk29_uart_dma_t = up->prk29_uart_dma_t;\r
- if(0 == prk29_uart_dma_t->use_dma){\r
+ struct rk_uart_dma *uart_dma = up->dma;\r
+ if(!uart_dma->use_dma)\r
return 0;\r
- }\r
\r
- if(prk29_uart_dma_t->rx_dma_start == 1){\r
+ if(uart_dma->rx_dma_used == 1)\r
return 0;\r
- }\r
\r
if(-1 == serial_rk_init_dma_rx(port)){\r
dev_info(up->port.dev, "*******serial_rk_init_dma_rx*******error*******\n");\r
return -1;\r
}\r
\r
- if (rk29_dma_enqueue(prk29_uart_dma_t->rx_dmach, (void *)up, prk29_uart_dma_t->rx_phy_addr,\r
- prk29_uart_dma_t->rx_buffer_size/2)) {\r
+ if (rk29_dma_enqueue(uart_dma->rx_dmach, (void *)up, uart_dma->rx_phy_addr,\r
+ uart_dma->rb_size/2)) {\r
dev_info(up->port.dev, "*******rk29_dma_enqueue fail*****\n");\r
return -1;\r
}\r
\r
- if (rk29_dma_enqueue(prk29_uart_dma_t->rx_dmach, (void *)up,\r
- prk29_uart_dma_t->rx_phy_addr+prk29_uart_dma_t->rx_buffer_size/2,\r
- prk29_uart_dma_t->rx_buffer_size/2)) {\r
+ if (rk29_dma_enqueue(uart_dma->rx_dmach, (void *)up,\r
+ uart_dma->rx_phy_addr+uart_dma->rb_size/2, uart_dma->rb_size/2)) {\r
dev_info(up->port.dev, "*******rk29_dma_enqueue fail*****\n");\r
return -1;\r
}\r
\r
- rk29_dma_ctrl(prk29_uart_dma_t->rx_dmach, RK29_DMAOP_START);\r
- prk29_uart_dma_t->rx_dma_start = 1;\r
- if(prk29_uart_dma_t->use_timer == 1){\r
- mod_timer(&prk29_uart_dma_t->rx_timer, jiffies +\r
- msecs_to_jiffies(prk29_uart_dma_t->rx_timeout));\r
+ rk29_dma_ctrl(uart_dma->rx_dmach, RK29_DMAOP_START);\r
+ uart_dma->rx_dma_used = 1;\r
+ if(uart_dma->use_timer == 1){\r
+ mod_timer(&uart_dma->rx_timer, jiffies + msecs_to_jiffies(uart_dma->rx_timeout));\r
}\r
up->port_activity = jiffies;\r
return 1;\r
static void serial_rk_update_rb_addr(struct uart_rk_port *up){\r
dma_addr_t current_pos = 0;\r
dma_addr_t rx_current_pos = 0;\r
- struct rk29_uart_dma_t *prk29_uart_dma_t = up->prk29_uart_dma_t;\r
- spin_lock(&(up->prk29_uart_dma_t->rx_lock));\r
- rk29_dma_getposition(prk29_uart_dma_t->rx_dmach, ¤t_pos, &rx_current_pos);\r
-\r
- prk29_uart_dma_t->rb_cur_pos = (rx_current_pos - prk29_uart_dma_t->rx_phy_addr);\r
- prk29_uart_dma_t->rx_size = CIRC_CNT(prk29_uart_dma_t->rb_cur_pos,\r
- prk29_uart_dma_t->rb_pre_pos, prk29_uart_dma_t->rx_buffer_size);\r
-\r
- spin_unlock(&(up->prk29_uart_dma_t->rx_lock));\r
+ struct rk_uart_dma *uart_dma = up->dma;\r
+ //spin_lock(&(up->dma->rx_lock));\r
+ uart_dma->rx_size = 0;\r
+ if(uart_dma->rx_dma_used == 1){\r
+ rk29_dma_getposition(uart_dma->rx_dmach, ¤t_pos, &rx_current_pos);\r
+ uart_dma->rb_head = (rx_current_pos - uart_dma->rx_phy_addr);\r
+ uart_dma->rx_size = CIRC_CNT(uart_dma->rb_head, uart_dma->rb_tail, uart_dma->rb_size);\r
+ }\r
+ //spin_unlock(&(up->dma->rx_lock));\r
}\r
\r
static void serial_rk_report_dma_rx(unsigned long uart)\r
{\r
+ int count, flip = 0;\r
struct uart_rk_port *up = (struct uart_rk_port *)uart;\r
- struct rk29_uart_dma_t *prk29_uart_dma_t = up->prk29_uart_dma_t;\r
- if(prk29_uart_dma_t->use_timer == 1){\r
- serial_rk_update_rb_addr(up);\r
- }\r
- if(prk29_uart_dma_t->rx_size > 0) {\r
- spin_lock(&(up->prk29_uart_dma_t->rx_lock));\r
+ struct rk_uart_dma *uart_dma = up->dma;\r
\r
- if(prk29_uart_dma_t->rb_cur_pos > prk29_uart_dma_t->rb_pre_pos){\r
- tty_insert_flip_string(up->port.state->port.tty, prk29_uart_dma_t->rx_buffer\r
- + prk29_uart_dma_t->rb_pre_pos, prk29_uart_dma_t->rx_size);\r
- tty_flip_buffer_push(up->port.state->port.tty);\r
- }\r
- else if(prk29_uart_dma_t->rb_cur_pos < prk29_uart_dma_t->rb_pre_pos){\r
-\r
- tty_insert_flip_string(up->port.state->port.tty, prk29_uart_dma_t->rx_buffer\r
- + prk29_uart_dma_t->rb_pre_pos, CIRC_CNT_TO_END(prk29_uart_dma_t->rb_cur_pos,\r
- prk29_uart_dma_t->rb_pre_pos, prk29_uart_dma_t->rx_buffer_size));\r
- tty_flip_buffer_push(up->port.state->port.tty);\r
+ if(!uart_dma->rx_dma_used || !up->port.state->port.tty)\r
+ return;\r
\r
- if(prk29_uart_dma_t->rb_cur_pos != 0){\r
- tty_insert_flip_string(up->port.state->port.tty, prk29_uart_dma_t->rx_buffer,\r
- prk29_uart_dma_t->rb_cur_pos);\r
- tty_flip_buffer_push(up->port.state->port.tty);\r
- }\r
- }\r
+ serial_rk_update_rb_addr(up);\r
\r
- prk29_uart_dma_t->rb_pre_pos = (prk29_uart_dma_t->rb_pre_pos + prk29_uart_dma_t->rx_size)\r
- & (prk29_uart_dma_t->rx_buffer_size - 1);\r
- up->port.icount.rx += prk29_uart_dma_t->rx_size;\r
- spin_unlock(&(up->prk29_uart_dma_t->rx_lock));\r
- prk29_uart_dma_t->rx_timeout = 7;\r
+ while(1) {\r
+ count = CIRC_CNT_TO_END(uart_dma->rb_head, uart_dma->rb_tail, uart_dma->rb_size);\r
+ if(count <= 0)\r
+ break;\r
+ up->port.icount.rx += count;\r
+ flip = tty_insert_flip_string(up->port.state->port.tty, uart_dma->rx_buffer\r
+ + uart_dma->rb_tail, count);\r
+ tty_flip_buffer_push(up->port.state->port.tty);\r
+ uart_dma->rb_tail = (uart_dma->rb_tail + count) & (uart_dma->rb_size - 1);\r
up->port_activity = jiffies;\r
}\r
\r
+ //if (uart_dma->rx_size > 0)\r
+ // printk("rx_size:%d ADDR:%x\n", uart_dma->rx_size, uart_dma->rb_head);\r
\r
-#if 1\r
- if (jiffies_to_msecs(jiffies - up->port_activity) < RX_TIMEOUT) {\r
- if(prk29_uart_dma_t->use_timer == 1){\r
- mod_timer(&prk29_uart_dma_t->rx_timer, jiffies + msecs_to_jiffies(prk29_uart_dma_t->rx_timeout));\r
- }\r
- } else {\r
-\r
-#if 1\r
-\r
-\r
- prk29_uart_dma_t->rx_timeout = 20;\r
- mod_timer(&prk29_uart_dma_t->rx_timer, jiffies + msecs_to_jiffies(prk29_uart_dma_t->rx_timeout));\r
-#else\r
-// serial_out(up, 0x2a, 0x01);\r
- serial_rk_release_dma_rx(&up->port);\r
- serial_out(up, 0x2a, 0x01);\r
- up->ier |= (UART_IER_RDI | UART_IER_RLSI);\r
- serial_out(up, UART_IER, up->ier);\r
-// serial_out(up, 0x22, 0x01);\r
- dev_info(up->port.dev, "*****enable recv int*****\n");\r
-\r
- //serial_rk_start_rx_dma(&up->port);\r
-#endif\r
- }\r
-\r
-\r
-#else\r
- if(prk29_uart_dma_t->use_timer == 1){\r
- mod_timer(&prk29_uart_dma_t->rx_timer, jiffies + msecs_to_jiffies(prk29_uart_dma_t->rx_timeout));\r
+ if(uart_dma->use_timer == 1){\r
+ mod_timer(&uart_dma->rx_timer, jiffies + msecs_to_jiffies(uart_dma->rx_timeout));\r
}\r
-#endif\r
\r
}\r
-\r
+#if 0\r
static void serial_rk_rx_timeout(unsigned long uart)\r
{\r
struct uart_rk_port *up = (struct uart_rk_port *)uart;\r
\r
- //serial_rk_report_dma_rx(up);\r
- queue_work(up->uart_wq, &up->uart_work);\r
+ serial_rk_report_dma_rx(up);\r
+ //queue_work(up->uart_wq, &up->uart_work);\r
}\r
\r
static void serial_rk_report_revdata_workfunc(struct work_struct *work)\r
{\r
struct uart_rk_port *up =\r
container_of(work, struct uart_rk_port, uart_work);\r
+\r
serial_rk_report_dma_rx((unsigned long)up);\r
- spin_lock(&(up->prk29_uart_dma_t->rx_lock));\r
\r
- if(up->prk29_uart_dma_t->use_timer == 1){\r
+ //spin_lock(&(up->dma->rx_lock));\r
+\r
+ if(up->port.state->port.tty && up->dma->use_timer != 1 && up->fifo_size > 0){\r
\r
- }else{\r
tty_insert_flip_string(up->port.state->port.tty, up->fifo, up->fifo_size);\r
tty_flip_buffer_push(up->port.state->port.tty);\r
up->port.icount.rx += up->fifo_size;\r
+ up->ier |= UART_IER_RDI;\r
+ serial_out(up, UART_IER, up->ier);\r
}\r
\r
- spin_unlock(&(up->prk29_uart_dma_t->rx_lock));\r
+ //spin_unlock(&(up->dma->rx_lock));\r
\r
}\r
\r
{\r
struct uart_rk_port *up =\r
container_of(work, struct uart_rk_port, uart_work_rx);\r
- serial_rk_start_rx_dma(&up->port);\r
+\r
+ //mod_timer(&up->dma->rx_timer, jiffies + msecs_to_jiffies(up->dma->rx_timeout));\r
+ //rk29_dma_ctrl(up->dma->rx_dmach, RK29_DMAOP_START);\r
+ //serial_rk_start_rx_dma(&up->port);\r
+\r
}\r
-#endif /* USE_DMA */\r
+#endif\r
\r
+#endif /* USE_DMA */\r
\r
\r
static void\r
__stop_tx(up);\r
return;\r
}\r
-\r
- count = up->tx_loadsz;\r
+#if USE_DMA\r
+ //hhb\r
+ if(up->dma->use_dma & TX_DMA){\r
+ if(SERIAL_CIRC_CNT_TO_END(xmit) >= DMA_TX_TRRIGE_LEVEL){\r
+ serial_rk_start_tx_dma(&up->port);\r
+ return;\r
+ }\r
+ }\r
+#endif\r
+ count = up->port.fifosize - serial_in(up , 0x20);\r
do {\r
serial_out(up, UART_TX, xmit->buf[xmit->tail]);\r
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);\r
uart_write_wakeup(&up->port);\r
\r
DEBUG_INTR("THRE...");\r
-\r
+#if USE_DMA\r
+ up->port_activity = jiffies;\r
+#endif\r
if (uart_circ_empty(xmit))\r
__stop_tx(up);\r
}\r
/* reading UART_LSR can automatically clears PE FE OE bits, except receive fifo error bit*/\r
status = serial_in(up, UART_LSR);\r
\r
- DEBUG_INTR("status = %x...", status);\r
+ DEBUG_INTR("status = %x...\n", status);\r
#if USE_DMA\r
/* DMA mode enable */\r
- if(up->prk29_uart_dma_t->use_dma == 1) {\r
-\r
- if(up->iir & UART_IIR_RLSI){\r
- if (status & (UART_LSR_DR | UART_LSR_BI)) {\r
- up->port_activity = jiffies;\r
- up->ier &= ~UART_IER_RLSI;\r
- up->ier &= ~UART_IER_RDI;\r
- serial_out(up, UART_IER, up->ier);\r
- //receive_chars(up, &status);\r
- //mod_timer(&up->prk29_uart_dma_t->rx_timer, jiffies +\r
- //msecs_to_jiffies(up->prk29_uart_dma_t->rx_timeout));\r
- if(serial_rk_start_rx_dma(&up->port) == -1){\r
- receive_chars(up, &status);\r
- }\r
+ if(up->dma->use_dma) {\r
+\r
+ if (status & UART_LSR_RFE) {\r
+ if(up->port.line != DBG_PORT){\r
+ dev_info(up->port.dev, "error:lsr=0x%x\n", status);\r
+ status = serial_in(up, UART_LSR);\r
+ DEBUG_INTR("error:lsr=0x%x\n", status);\r
}\r
}\r
\r
- } else\r
+ if (status & 0x02) {\r
+ if(up->port.line != DBG_PORT){\r
+ dev_info(up->port.dev, "error:lsr=0x%x\n", status);\r
+ status = serial_in(up, UART_LSR);\r
+ DEBUG_INTR("error:lsr=0x%x\n", status);\r
+ }\r
+ }\r
+\r
+ if ((up->iir & 0x0f) == 0x02) {\r
+ transmit_chars(up);\r
+ }\r
+ } else \r
#endif\r
- { //dma mode disable\r
+ { //dma mode disable\r
\r
/*\r
* when uart receive a serial of data which doesn't have stop bit and so on, that causes frame error,and\r
*/\r
\r
if (status & UART_LSR_RFE) {\r
- \r
if(up->port.line != DBG_PORT){\r
- status = serial_in(up, UART_LSR);\r
dev_info(up->port.dev, "error:lsr=0x%x\n", status);\r
+ status = serial_in(up, UART_LSR);\r
+ DEBUG_INTR("error:lsr=0x%x\n", status);\r
+ rk29_uart_dump_register(up);\r
}\r
- \r
- \r
- // rk29_uart_dump_register(up);\r
}\r
\r
if (status & (UART_LSR_DR | UART_LSR_BI)) {\r
receive_chars(up, &status);\r
}\r
check_modem_status(up);\r
- if (status & UART_LSR_THRE) {\r
+ //hhb@rock-chips.com when FIFO and THRE mode both are enabled,and FIFO TX empty trigger is set to larger than 1,\r
+ //,we need to add ((up->iir & 0x0f) == 0x02) to transmit_chars,because when entering interrupt,the FIFO and THR\r
+ //might not be 1.\r
+ if ((up->iir & 0x0f) == 0x02) {\r
transmit_chars(up);\r
}\r
}\r
-\r
spin_unlock_irqrestore(&up->port.lock, flags);\r
}\r
\r
iir = serial_in(up, UART_IIR);\r
\r
DEBUG_INTR("%s(%d) iir = 0x%02x\n", __func__, irq, iir);\r
-\r
up->iir = iir;\r
\r
if (!(iir & UART_IIR_NO_INT)) {\r
struct uart_rk_port *up =\r
container_of(port, struct uart_rk_port, port);\r
unsigned long flags;\r
- int retval;\r
-\r
+ int retval, fifosize = 0;\r
+ \r
\r
dev_dbg(port->dev, "%s\n", __func__);\r
\r
*/\r
serial_rk_clear_fifos(up);\r
\r
+ //read uart fifo size hhb@rock-chips.com\r
+ fifosize = __raw_readl(up->port.membase + 0xf4);\r
+ up->port.fifosize = ((fifosize >> 16) & 0xff) << 4;\r
+ if(up->port.fifosize <= 0)\r
+ up->port.fifosize = 32;\r
+ //printk("fifo size:%d :%08x\n", up->port.fifosize, fifosize);\r
+\r
/*\r
* Clear the interrupt registers.\r
*/\r
#if 0\r
up->msr_saved_flags = 0;\r
#endif\r
-\r
#if USE_DMA\r
- if (1 == up->prk29_uart_dma_t->use_dma) {\r
-\r
- if(up->port.state->xmit.buf != up->prk29_uart_dma_t->tx_buffer){\r
+ if (up->dma->use_dma & TX_DMA) {\r
+ if(up->port.state->xmit.buf != up->dma->tx_buffer){\r
free_page((unsigned long)up->port.state->xmit.buf);\r
- up->port.state->xmit.buf = up->prk29_uart_dma_t->tx_buffer;\r
+ up->port.state->xmit.buf = up->dma->tx_buffer;\r
}\r
-\r
-#if 1\r
- serial_rk_start_rx_dma(&up->port);\r
-#else\r
- up->ier |= UART_IER_RDI;\r
- up->ier |= UART_IER_RLSI;\r
- serial_out(up, UART_IER, up->ier);\r
+ } else \r
#endif\r
- up->port_activity = jiffies;\r
-\r
- } else\r
-#endif /* USE_DMA */\r
{\r
up->ier = 0;\r
serial_out(up, UART_IER, up->ier);\r
* Read data port to reset things, and then free the irq\r
*/\r
(void) serial_in(up, UART_RX);\r
-\r
+#if USE_DMA\r
+ //if (up->dma->use_dma & TX_DMA)\r
+ // up->port.state->xmit.buf = NULL;\r
+#endif\r
free_irq(up->port.irq, up);\r
clk_disable(up->clk);\r
clk_disable(up->pclk);\r
{\r
struct uart_rk_port *up =\r
container_of(port, struct uart_rk_port, port);\r
- unsigned char cval, fcr = 0;\r
+ unsigned char cval = 0, fcr = 0, mcr = 0;\r
unsigned long flags;\r
unsigned int baud, quot;\r
- int timeout = 1000000;\r
dev_dbg(port->dev, "+%s\n", __func__);\r
\r
switch (termios->c_cflag & CSIZE) {\r
port->uartclk / 16);\r
\r
quot = uart_get_divisor(port, baud);\r
-\r
- dev_info(up->port.dev, "baud:%d\n", baud);\r
-// dev_info(up->port.dev, "quot:%d\n", quot);\r
-\r
- /*\r
- * To wait long enough to avoid writting lcr when the uart is busy\r
- * because of data communication, so that we can set lcr and baud rate\r
- * successfully. added by hhb@rock-chips.com\r
- */\r
-\r
- while(serial_in(up, UART_USR) & UART_USR_BUSY){\r
- if(--timeout == 0){\r
- if(port->line != DBG_PORT){\r
- serial_out(up, UART_SRR, UART_RESET);\r
- }\r
- dbg("rk_serial_set_termios uart.%d timeout,irq=%d,ret=0x%x AND uart is reseted\n",\r
- port->line, port->irq, serial_in(up, UART_USR));\r
- break;\r
- }\r
- cpu_relax();\r
- }\r
-\r
-\r
- printk("serial.%d timeout:%d\n", up->port.line,timeout);\r
-\r
+ //dev_info(up->port.dev, "uartclk:%d\n", port->uartclk/16);\r
+ //dev_info(up->port.dev, "baud:%d\n", baud);\r
+ //dev_info(up->port.dev, "quot:%d\n", quot);\r
\r
if (baud < 2400){\r
fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;\r
}\r
else{\r
+ fcr = UART_FCR_ENABLE_FIFO;\r
#if USE_DMA\r
//added by hhb@rock-chips.com\r
- if(up->prk29_uart_dma_t->use_timer == 1){\r
- fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_01;\r
+ if(up->dma->use_dma & TX_DMA){\r
+ fcr |= UART_FCR_T_TRIG_01;\r
} else\r
#endif\r
{\r
- fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | UART_FCR_T_TRIG_01;\r
+ fcr |= UART_FCR_T_TRIG_01;\r
+ }\r
+\r
+#if USE_DMA\r
+ //added by hhb@rock-chips.com\r
+ if(up->dma->use_dma & RX_DMA){ \r
+ fcr |= UART_FCR_R_TRIG_00;\r
+ } else\r
+#endif\r
+ {\r
+ if (termios->c_cflag & CRTSCTS)\r
+ fcr |= UART_FCR_R_TRIG_11;\r
+ else\r
+ fcr |= UART_FCR_R_TRIG_00;\r
}\r
}\r
\r
up->ier |= UART_IER_MSI;\r
#endif\r
\r
+ //to avoid uart busy when set baud rate hhb@rock-chips.com\r
+ serial_out(up, UART_SRR, UART_RESET);\r
+ mcr = serial_in(up, UART_MCR);\r
+ serial_out(up, UART_MCR, mcr | 0x10); //loopback mode\r
+ \r
up->lcr = cval; /* Save LCR */\r
/* set DLAB */\r
- if(serial_lcr_write(up, cval | UART_LCR_DLAB)){\r
- dbg("serial.%d set DLAB fail\n", up->port.line);\r
+ if(serial_lcr_write(up, cval | UART_LCR_DLAB)) {\r
+ if(up->port.line != DBG_PORT)\r
+ dbg("serial.%d set DLAB fail\n", up->port.line);\r
serial_out(up, UART_SRR, UART_RESET);\r
goto fail;\r
}\r
\r
/* set uart baud rate */\r
- if(serial_dl_write(up, quot)){\r
- dbg("serial.%d set dll fail\n", up->port.line);\r
+ if(serial_dl_write(up, quot)) {\r
+ if(up->port.line != DBG_PORT)\r
+ dbg("serial.%d set dll fail\n", up->port.line);\r
serial_out(up, UART_SRR, UART_RESET);\r
goto fail;\r
}\r
\r
/* reset DLAB */\r
- if(serial_lcr_write(up, cval)){\r
- dbg("serial.%d reset DLAB fail\n", up->port.line);\r
+ if(serial_lcr_write(up, cval)) {\r
+ if(up->port.line != DBG_PORT)\r
+ dbg("serial.%d reset DLAB fail\n", up->port.line);\r
serial_out(up, UART_SRR, UART_RESET);\r
goto fail;\r
}\r
- else{\r
+ else {\r
serial_rk_set_mctrl(&up->port, up->port.mctrl);\r
- serial_out(up, UART_FCR, fcr); /* set fcr */\r
up->fcr = fcr;\r
- /* enable the uart interrupt last */\r
- up->ier |= UART_IER_RDI;\r
- up->ier |= UART_IER_RLSI;\r
+ serial_out(up, UART_FCR, up->fcr); /* set fcr */\r
+ up->ier = 0;\r
+ //start serial receive data\r
+#if USE_DMA\r
+ if (up->dma->use_dma) {\r
+ up->ier |= UART_IER_RLSI;\r
+ up->ier |= UART_IER_PTIME; //Programmable THRE Interrupt Mode Enable\r
+ serial_rk_start_rx_dma(&up->port);\r
+ } else\r
+#endif\r
+ {\r
+ // not use dma receive\r
+ up->ier |= UART_IER_RDI;\r
+ up->ier |= UART_IER_RLSI;\r
+ if(up->port.line != DBG_PORT)\r
+ up->ier |= UART_IER_PTIME; //Programmable THRE Interrupt Mode Enable\r
+\r
+ }\r
serial_out(up, UART_IER, up->ier);\r
}\r
-\r
+ \r
spin_unlock_irqrestore(&up->port.lock, flags);\r
\r
/* Don't rewrite B0 */\r
if (tty_termios_baud_rate(termios))\r
tty_termios_encode_baud_rate(termios, baud, baud);\r
dev_dbg(port->dev, "-%s baud %d\n", __func__, baud);\r
-\r
return;\r
\r
fail:\r
struct resource *mem;\r
int irq;\r
int ret = -ENOSPC;\r
+ \r
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);\r
if (!mem) {\r
dev_err(&pdev->dev, "no mem resource?\n");\r
}\r
up->tx_loadsz = 30;\r
#if USE_DMA\r
- up->prk29_uart_dma_t = &rk29_uart_ports_dma_t[pdev->id];\r
+ up->dma = &rk29_uart_ports_dma[pdev->id];\r
#endif\r
up->port.dev = &pdev->dev;\r
up->port.type = PORT_RK;\r
up->port.iotype = UPIO_DWAPB;\r
\r
up->port.regshift = 2;\r
+ //fifo size default is 32, but it will be updated later when start_up\r
up->port.fifosize = 32;\r
up->port.ops = &serial_rk_pops;\r
up->port.line = pdev->id;\r
\r
#if USE_DMA\r
/* set dma config */\r
- if(1 == up->prk29_uart_dma_t->use_dma) {\r
+ if(up->dma->use_dma & RX_DMA) {\r
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);\r
-\r
//timer\r
- up->prk29_uart_dma_t->use_timer = USE_TIMER;\r
- up->prk29_uart_dma_t->rx_timer.function = serial_rk_rx_timeout;\r
- up->prk29_uart_dma_t->rx_timer.data = (unsigned long)up;\r
- up->prk29_uart_dma_t->rx_timeout = 7;\r
- up->prk29_uart_dma_t->rx_timer.expires = jiffies + msecs_to_jiffies(up->prk29_uart_dma_t->rx_timeout);\r
- init_timer(&up->prk29_uart_dma_t->rx_timer);\r
- //tx buffer\r
- up->prk29_uart_dma_t->tx_buffer_size = UART_XMIT_SIZE;\r
- up->prk29_uart_dma_t->tx_buffer = dmam_alloc_coherent(up->port.dev, up->prk29_uart_dma_t->tx_buffer_size,\r
- &up->prk29_uart_dma_t->tx_phy_addr, DMA_MEMORY_MAP);\r
- if(!up->prk29_uart_dma_t->tx_buffer){\r
- dev_info(up->port.dev, "dmam_alloc_coherent dma_tx_buffer fail\n");\r
- }\r
- else{\r
- dev_info(up->port.dev, "dma_tx_buffer 0x%08x\n", (unsigned) up->prk29_uart_dma_t->tx_buffer);\r
- dev_info(up->port.dev, "dma_tx_phy 0x%08x\n", (unsigned) up->prk29_uart_dma_t->tx_phy_addr);\r
- }\r
+ up->dma->use_timer = USE_TIMER;\r
+ up->dma->rx_timer.function = serial_rk_report_dma_rx;\r
+ up->dma->rx_timer.data = (unsigned long)up;\r
+ up->dma->rx_timeout = 10;\r
+ up->dma->rx_timer.expires = jiffies + msecs_to_jiffies(up->dma->rx_timeout);\r
+ init_timer(&up->dma->rx_timer);\r
+\r
//rx buffer\r
- up->prk29_uart_dma_t->rx_buffer_size = UART_XMIT_SIZE*32;\r
- up->prk29_uart_dma_t->rx_buffer = dmam_alloc_coherent(up->port.dev, up->prk29_uart_dma_t->rx_buffer_size,\r
- &up->prk29_uart_dma_t->rx_phy_addr, DMA_MEMORY_MAP);\r
- up->prk29_uart_dma_t->rb_pre_pos = 0;\r
- if(!up->prk29_uart_dma_t->rx_buffer){\r
+ up->dma->rb_size = UART_XMIT_SIZE*8;\r
+ up->dma->rx_buffer = dmam_alloc_coherent(up->port.dev, up->dma->rb_size,\r
+ &up->dma->rx_phy_addr, DMA_MEMORY_MAP);\r
+ up->dma->rb_tail = 0;\r
+\r
+ if(!up->dma->rx_buffer){\r
dev_info(up->port.dev, "dmam_alloc_coherent dma_rx_buffer fail\n");\r
}\r
else {\r
- dev_info(up->port.dev, "dma_rx_buffer 0x%08x\n", (unsigned) up->prk29_uart_dma_t->rx_buffer);\r
- dev_info(up->port.dev, "up 0x%08x\n", (unsigned)up->prk29_uart_dma_t);\r
+ dev_info(up->port.dev, "dma_rx_buffer 0x%08x\n", (unsigned) up->dma->rx_buffer);\r
+ dev_info(up->port.dev, "up 0x%08x\n", (unsigned)up->dma);\r
}\r
\r
// work queue\r
- INIT_WORK(&up->uart_work, serial_rk_report_revdata_workfunc);\r
- INIT_WORK(&up->uart_work_rx, serial_rk_start_dma_rx);\r
- up->uart_wq = create_singlethread_workqueue("uart_workqueue");\r
- up->prk29_uart_dma_t->rx_dma_start = 0;\r
- spin_lock_init(&(up->prk29_uart_dma_t->tx_lock));\r
- spin_lock_init(&(up->prk29_uart_dma_t->rx_lock));\r
+ //INIT_WORK(&up->uart_work, serial_rk_report_revdata_workfunc);\r
+ //INIT_WORK(&up->uart_work_rx, serial_rk_start_dma_rx);\r
+ //up->uart_wq = create_singlethread_workqueue("uart_workqueue");\r
+ up->dma->rx_dma_used = 0;\r
+ spin_lock_init(&(up->dma->rx_lock));\r
serial_rk_init_dma_rx(&up->port);\r
+ }\r
+\r
+ if(up->dma->use_dma & TX_DMA){\r
+ //tx buffer\r
+ up->dma->tb_size = UART_XMIT_SIZE;\r
+ up->dma->tx_buffer = dmam_alloc_coherent(up->port.dev, up->dma->tb_size,\r
+ &up->dma->tx_phy_addr, DMA_MEMORY_MAP);\r
+ if(!up->dma->tx_buffer){\r
+ dev_info(up->port.dev, "dmam_alloc_coherent dma_tx_buffer fail\n");\r
+ }\r
+ else{\r
+ dev_info(up->port.dev, "dma_tx_buffer 0x%08x\n", (unsigned) up->dma->tx_buffer);\r
+ dev_info(up->port.dev, "dma_tx_phy 0x%08x\n", (unsigned) up->dma->tx_phy_addr);\r
+ }\r
+ spin_lock_init(&(up->dma->tx_lock));\r
serial_rk_init_dma_tx(&up->port);\r
- up->ier |= THRE_MODE; // enable THRE interrupt mode\r
- serial_out(up, UART_IER, up->ier);\r
}\r
-#endif\r
\r
+#endif\r
serial_rk_add_console_port(up);\r
ret = uart_add_one_port(&serial_rk_reg, &up->port);\r
if (ret != 0)\r
static int __init serial_rk_init(void)\r
{\r
int ret;\r
+ //hhb@rock-chips.com\r
+ printk("%s\n", VERSION_AND_TIME);\r
\r
ret = uart_register_driver(&serial_rk_reg);\r
if (ret)\r