|  | /* | 
|  | * Drivers for CSR SiRFprimaII onboard UARTs. | 
|  | * | 
|  | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | 
|  | * | 
|  | * Licensed under GPLv2 or later. | 
|  | */ | 
|  | #include <linux/bitops.h> | 
|  |  | 
|  | /* UART Register Offset Define */ | 
|  | #define SIRFUART_LINE_CTRL			0x0040 | 
|  | #define SIRFUART_TX_RX_EN			0x004c | 
|  | #define SIRFUART_DIVISOR			0x0050 | 
|  | #define SIRFUART_INT_EN				0x0054 | 
|  | #define SIRFUART_INT_STATUS			0x0058 | 
|  | #define SIRFUART_TX_DMA_IO_CTRL			0x0100 | 
|  | #define SIRFUART_TX_DMA_IO_LEN			0x0104 | 
|  | #define SIRFUART_TX_FIFO_CTRL			0x0108 | 
|  | #define SIRFUART_TX_FIFO_LEVEL_CHK		0x010C | 
|  | #define SIRFUART_TX_FIFO_OP			0x0110 | 
|  | #define SIRFUART_TX_FIFO_STATUS			0x0114 | 
|  | #define SIRFUART_TX_FIFO_DATA			0x0118 | 
|  | #define SIRFUART_RX_DMA_IO_CTRL			0x0120 | 
|  | #define SIRFUART_RX_DMA_IO_LEN			0x0124 | 
|  | #define SIRFUART_RX_FIFO_CTRL			0x0128 | 
|  | #define SIRFUART_RX_FIFO_LEVEL_CHK		0x012C | 
|  | #define SIRFUART_RX_FIFO_OP			0x0130 | 
|  | #define SIRFUART_RX_FIFO_STATUS			0x0134 | 
|  | #define SIRFUART_RX_FIFO_DATA			0x0138 | 
|  | #define SIRFUART_AFC_CTRL			0x0140 | 
|  | #define SIRFUART_SWH_DMA_IO			0x0148 | 
|  |  | 
|  | /* UART Line Control Register */ | 
|  | #define SIRFUART_DATA_BIT_LEN_MASK		0x3 | 
|  | #define SIRFUART_DATA_BIT_LEN_5			BIT(0) | 
|  | #define SIRFUART_DATA_BIT_LEN_6			1 | 
|  | #define SIRFUART_DATA_BIT_LEN_7			2 | 
|  | #define SIRFUART_DATA_BIT_LEN_8			3 | 
|  | #define SIRFUART_STOP_BIT_LEN_1			0 | 
|  | #define SIRFUART_STOP_BIT_LEN_2			BIT(2) | 
|  | #define SIRFUART_PARITY_EN			BIT(3) | 
|  | #define SIRFUART_EVEN_BIT			BIT(4) | 
|  | #define SIRFUART_STICK_BIT_MASK			(7 << 3) | 
|  | #define SIRFUART_STICK_BIT_NONE			(0 << 3) | 
|  | #define SIRFUART_STICK_BIT_EVEN			BIT(3) | 
|  | #define SIRFUART_STICK_BIT_ODD			(3 << 3) | 
|  | #define SIRFUART_STICK_BIT_MARK			(5 << 3) | 
|  | #define SIRFUART_STICK_BIT_SPACE		(7 << 3) | 
|  | #define SIRFUART_SET_BREAK			BIT(6) | 
|  | #define SIRFUART_LOOP_BACK			BIT(7) | 
|  | #define SIRFUART_PARITY_MASK			(7 << 3) | 
|  | #define SIRFUART_DUMMY_READ			BIT(16) | 
|  |  | 
|  | #define SIRFSOC_UART_RX_TIMEOUT(br, to)	(((br) * (((to) + 999) / 1000)) / 1000) | 
|  | #define SIRFUART_RECV_TIMEOUT_MASK	(0xFFFF << 16) | 
|  | #define SIRFUART_RECV_TIMEOUT(x)	(((x) & 0xFFFF) << 16) | 
|  |  | 
|  | /* UART Auto Flow Control */ | 
|  | #define SIRFUART_AFC_RX_THD_MASK		0x000000FF | 
|  | #define SIRFUART_AFC_RX_EN			BIT(8) | 
|  | #define SIRFUART_AFC_TX_EN			BIT(9) | 
|  | #define SIRFUART_CTS_CTRL			BIT(10) | 
|  | #define SIRFUART_RTS_CTRL			BIT(11) | 
|  | #define SIRFUART_CTS_IN_STATUS			BIT(12) | 
|  | #define SIRFUART_RTS_OUT_STATUS			BIT(13) | 
|  |  | 
|  | /* UART Interrupt Enable Register */ | 
|  | #define SIRFUART_RX_DONE_INT			BIT(0) | 
|  | #define SIRFUART_TX_DONE_INT			BIT(1) | 
|  | #define SIRFUART_RX_OFLOW_INT			BIT(2) | 
|  | #define SIRFUART_TX_ALLOUT_INT			BIT(3) | 
|  | #define SIRFUART_RX_IO_DMA_INT			BIT(4) | 
|  | #define SIRFUART_TX_IO_DMA_INT			BIT(5) | 
|  | #define SIRFUART_RXFIFO_FULL_INT		BIT(6) | 
|  | #define SIRFUART_TXFIFO_EMPTY_INT		BIT(7) | 
|  | #define SIRFUART_RXFIFO_THD_INT			BIT(8) | 
|  | #define SIRFUART_TXFIFO_THD_INT			BIT(9) | 
|  | #define SIRFUART_FRM_ERR_INT			BIT(10) | 
|  | #define SIRFUART_RXD_BREAK_INT			BIT(11) | 
|  | #define SIRFUART_RX_TIMEOUT_INT			BIT(12) | 
|  | #define SIRFUART_PARITY_ERR_INT			BIT(13) | 
|  | #define SIRFUART_CTS_INT_EN			BIT(14) | 
|  | #define SIRFUART_RTS_INT_EN			BIT(15) | 
|  |  | 
|  | /* UART Interrupt Status Register */ | 
|  | #define SIRFUART_RX_DONE			BIT(0) | 
|  | #define SIRFUART_TX_DONE			BIT(1) | 
|  | #define SIRFUART_RX_OFLOW			BIT(2) | 
|  | #define SIRFUART_TX_ALL_EMPTY			BIT(3) | 
|  | #define SIRFUART_DMA_IO_RX_DONE			BIT(4) | 
|  | #define SIRFUART_DMA_IO_TX_DONE			BIT(5) | 
|  | #define SIRFUART_RXFIFO_FULL			BIT(6) | 
|  | #define SIRFUART_TXFIFO_EMPTY			BIT(7) | 
|  | #define SIRFUART_RXFIFO_THD_REACH		BIT(8) | 
|  | #define SIRFUART_TXFIFO_THD_REACH		BIT(9) | 
|  | #define SIRFUART_FRM_ERR			BIT(10) | 
|  | #define SIRFUART_RXD_BREAK			BIT(11) | 
|  | #define SIRFUART_RX_TIMEOUT			BIT(12) | 
|  | #define SIRFUART_PARITY_ERR			BIT(13) | 
|  | #define SIRFUART_CTS_CHANGE			BIT(14) | 
|  | #define SIRFUART_RTS_CHANGE			BIT(15) | 
|  | #define SIRFUART_PLUG_IN			BIT(16) | 
|  |  | 
|  | #define SIRFUART_ERR_INT_STAT					\ | 
|  | (SIRFUART_RX_OFLOW |		\ | 
|  | SIRFUART_FRM_ERR |		\ | 
|  | SIRFUART_RXD_BREAK |		\ | 
|  | SIRFUART_PARITY_ERR) | 
|  | #define SIRFUART_ERR_INT_EN					\ | 
|  | (SIRFUART_RX_OFLOW_INT |	\ | 
|  | SIRFUART_FRM_ERR_INT |		\ | 
|  | SIRFUART_RXD_BREAK_INT |	\ | 
|  | SIRFUART_PARITY_ERR_INT) | 
|  | #define SIRFUART_TX_INT_EN	SIRFUART_TXFIFO_EMPTY_INT | 
|  | #define SIRFUART_RX_IO_INT_EN					\ | 
|  | (SIRFUART_RX_TIMEOUT_INT |	\ | 
|  | SIRFUART_RXFIFO_THD_INT |	\ | 
|  | SIRFUART_RXFIFO_FULL_INT |	\ | 
|  | SIRFUART_ERR_INT_EN) | 
|  |  | 
|  | /* UART FIFO Register */ | 
|  | #define SIRFUART_TX_FIFO_STOP			0x0 | 
|  | #define SIRFUART_TX_FIFO_RESET			0x1 | 
|  | #define SIRFUART_TX_FIFO_START			0x2 | 
|  | #define SIRFUART_RX_FIFO_STOP			0x0 | 
|  | #define SIRFUART_RX_FIFO_RESET			0x1 | 
|  | #define SIRFUART_RX_FIFO_START			0x2 | 
|  | #define SIRFUART_TX_MODE_DMA			0 | 
|  | #define SIRFUART_TX_MODE_IO			1 | 
|  | #define SIRFUART_RX_MODE_DMA			0 | 
|  | #define SIRFUART_RX_MODE_IO			1 | 
|  |  | 
|  | #define SIRFUART_RX_EN				0x1 | 
|  | #define SIRFUART_TX_EN				0x2 | 
|  |  | 
|  | /* Generic Definitions */ | 
|  | #define SIRFSOC_UART_NAME			"ttySiRF" | 
|  | #define SIRFSOC_UART_MAJOR			0 | 
|  | #define SIRFSOC_UART_MINOR			0 | 
|  | #define SIRFUART_PORT_NAME			"sirfsoc-uart" | 
|  | #define SIRFUART_MAP_SIZE			0x200 | 
|  | #define SIRFSOC_UART_NR				3 | 
|  | #define SIRFSOC_PORT_TYPE			0xa5 | 
|  |  | 
|  | /* Baud Rate Calculation */ | 
|  | #define SIRF_MIN_SAMPLE_DIV			0xf | 
|  | #define SIRF_MAX_SAMPLE_DIV			0x3f | 
|  | #define SIRF_IOCLK_DIV_MAX			0xffff | 
|  | #define SIRF_SAMPLE_DIV_SHIFT			16 | 
|  | #define SIRF_IOCLK_DIV_MASK			0xffff | 
|  | #define SIRF_SAMPLE_DIV_MASK			0x3f0000 | 
|  | #define SIRF_BAUD_RATE_SUPPORT_NR		18 | 
|  |  | 
|  | /* For Fast Baud Rate Calculation */ | 
|  | struct sirfsoc_baudrate_to_regv { | 
|  | unsigned int baud_rate; | 
|  | unsigned int reg_val; | 
|  | }; | 
|  |  | 
|  | struct sirfsoc_uart_port { | 
|  | unsigned char			hw_flow_ctrl; | 
|  | unsigned char			ms_enabled; | 
|  |  | 
|  | struct uart_port		port; | 
|  | struct pinmux			*pmx; | 
|  | }; | 
|  |  | 
|  | /* Hardware Flow Control */ | 
|  | #define SIRFUART_AFC_CTRL_RX_THD	0x70 | 
|  |  | 
|  | /* Register Access Control */ | 
|  | #define portaddr(port, reg)		((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)) | 
|  |  | 
|  | /* UART Port Mask */ | 
|  | #define SIRFUART_FIFOLEVEL_MASK(port)	((port->line == 1) ? (0x1f) : (0x7f)) | 
|  | #define SIRFUART_FIFOFULL_MASK(port)	((port->line == 1) ? (0x20) : (0x80)) | 
|  | #define SIRFUART_FIFOEMPTY_MASK(port)	((port->line == 1) ? (0x40) : (0x100)) | 
|  |  | 
|  | /* I/O Mode */ | 
|  | #define SIRFSOC_UART_IO_RX_MAX_CNT		256 | 
|  | #define SIRFSOC_UART_IO_TX_REASONABLE_CNT	6 |