Rong Wang | 161e773 | 2011-11-17 23:17:04 +0800 | [diff] [blame] | 1 | /* |
| 2 | * Drivers for CSR SiRFprimaII onboard UARTs. |
| 3 | * |
| 4 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. |
| 5 | * |
| 6 | * Licensed under GPLv2 or later. |
| 7 | */ |
| 8 | #include <linux/bitops.h> |
| 9 | |
| 10 | /* UART Register Offset Define */ |
| 11 | #define SIRFUART_LINE_CTRL 0x0040 |
| 12 | #define SIRFUART_TX_RX_EN 0x004c |
| 13 | #define SIRFUART_DIVISOR 0x0050 |
| 14 | #define SIRFUART_INT_EN 0x0054 |
| 15 | #define SIRFUART_INT_STATUS 0x0058 |
| 16 | #define SIRFUART_TX_DMA_IO_CTRL 0x0100 |
| 17 | #define SIRFUART_TX_DMA_IO_LEN 0x0104 |
| 18 | #define SIRFUART_TX_FIFO_CTRL 0x0108 |
| 19 | #define SIRFUART_TX_FIFO_LEVEL_CHK 0x010C |
| 20 | #define SIRFUART_TX_FIFO_OP 0x0110 |
| 21 | #define SIRFUART_TX_FIFO_STATUS 0x0114 |
| 22 | #define SIRFUART_TX_FIFO_DATA 0x0118 |
| 23 | #define SIRFUART_RX_DMA_IO_CTRL 0x0120 |
| 24 | #define SIRFUART_RX_DMA_IO_LEN 0x0124 |
| 25 | #define SIRFUART_RX_FIFO_CTRL 0x0128 |
| 26 | #define SIRFUART_RX_FIFO_LEVEL_CHK 0x012C |
| 27 | #define SIRFUART_RX_FIFO_OP 0x0130 |
| 28 | #define SIRFUART_RX_FIFO_STATUS 0x0134 |
| 29 | #define SIRFUART_RX_FIFO_DATA 0x0138 |
| 30 | #define SIRFUART_AFC_CTRL 0x0140 |
| 31 | #define SIRFUART_SWH_DMA_IO 0x0148 |
| 32 | |
| 33 | /* UART Line Control Register */ |
| 34 | #define SIRFUART_DATA_BIT_LEN_MASK 0x3 |
| 35 | #define SIRFUART_DATA_BIT_LEN_5 BIT(0) |
| 36 | #define SIRFUART_DATA_BIT_LEN_6 1 |
| 37 | #define SIRFUART_DATA_BIT_LEN_7 2 |
| 38 | #define SIRFUART_DATA_BIT_LEN_8 3 |
| 39 | #define SIRFUART_STOP_BIT_LEN_1 0 |
| 40 | #define SIRFUART_STOP_BIT_LEN_2 BIT(2) |
| 41 | #define SIRFUART_PARITY_EN BIT(3) |
| 42 | #define SIRFUART_EVEN_BIT BIT(4) |
| 43 | #define SIRFUART_STICK_BIT_MASK (7 << 3) |
| 44 | #define SIRFUART_STICK_BIT_NONE (0 << 3) |
| 45 | #define SIRFUART_STICK_BIT_EVEN BIT(3) |
| 46 | #define SIRFUART_STICK_BIT_ODD (3 << 3) |
| 47 | #define SIRFUART_STICK_BIT_MARK (5 << 3) |
| 48 | #define SIRFUART_STICK_BIT_SPACE (7 << 3) |
| 49 | #define SIRFUART_SET_BREAK BIT(6) |
| 50 | #define SIRFUART_LOOP_BACK BIT(7) |
| 51 | #define SIRFUART_PARITY_MASK (7 << 3) |
| 52 | #define SIRFUART_DUMMY_READ BIT(16) |
| 53 | |
| 54 | #define SIRFSOC_UART_RX_TIMEOUT(br, to) (((br) * (((to) + 999) / 1000)) / 1000) |
| 55 | #define SIRFUART_RECV_TIMEOUT_MASK (0xFFFF << 16) |
| 56 | #define SIRFUART_RECV_TIMEOUT(x) (((x) & 0xFFFF) << 16) |
| 57 | |
| 58 | /* UART Auto Flow Control */ |
| 59 | #define SIRFUART_AFC_RX_THD_MASK 0x000000FF |
| 60 | #define SIRFUART_AFC_RX_EN BIT(8) |
| 61 | #define SIRFUART_AFC_TX_EN BIT(9) |
| 62 | #define SIRFUART_CTS_CTRL BIT(10) |
| 63 | #define SIRFUART_RTS_CTRL BIT(11) |
| 64 | #define SIRFUART_CTS_IN_STATUS BIT(12) |
| 65 | #define SIRFUART_RTS_OUT_STATUS BIT(13) |
| 66 | |
| 67 | /* UART Interrupt Enable Register */ |
| 68 | #define SIRFUART_RX_DONE_INT BIT(0) |
| 69 | #define SIRFUART_TX_DONE_INT BIT(1) |
| 70 | #define SIRFUART_RX_OFLOW_INT BIT(2) |
| 71 | #define SIRFUART_TX_ALLOUT_INT BIT(3) |
| 72 | #define SIRFUART_RX_IO_DMA_INT BIT(4) |
| 73 | #define SIRFUART_TX_IO_DMA_INT BIT(5) |
| 74 | #define SIRFUART_RXFIFO_FULL_INT BIT(6) |
| 75 | #define SIRFUART_TXFIFO_EMPTY_INT BIT(7) |
| 76 | #define SIRFUART_RXFIFO_THD_INT BIT(8) |
| 77 | #define SIRFUART_TXFIFO_THD_INT BIT(9) |
| 78 | #define SIRFUART_FRM_ERR_INT BIT(10) |
| 79 | #define SIRFUART_RXD_BREAK_INT BIT(11) |
| 80 | #define SIRFUART_RX_TIMEOUT_INT BIT(12) |
| 81 | #define SIRFUART_PARITY_ERR_INT BIT(13) |
| 82 | #define SIRFUART_CTS_INT_EN BIT(14) |
| 83 | #define SIRFUART_RTS_INT_EN BIT(15) |
| 84 | |
| 85 | /* UART Interrupt Status Register */ |
| 86 | #define SIRFUART_RX_DONE BIT(0) |
| 87 | #define SIRFUART_TX_DONE BIT(1) |
| 88 | #define SIRFUART_RX_OFLOW BIT(2) |
| 89 | #define SIRFUART_TX_ALL_EMPTY BIT(3) |
| 90 | #define SIRFUART_DMA_IO_RX_DONE BIT(4) |
| 91 | #define SIRFUART_DMA_IO_TX_DONE BIT(5) |
| 92 | #define SIRFUART_RXFIFO_FULL BIT(6) |
| 93 | #define SIRFUART_TXFIFO_EMPTY BIT(7) |
| 94 | #define SIRFUART_RXFIFO_THD_REACH BIT(8) |
| 95 | #define SIRFUART_TXFIFO_THD_REACH BIT(9) |
| 96 | #define SIRFUART_FRM_ERR BIT(10) |
| 97 | #define SIRFUART_RXD_BREAK BIT(11) |
| 98 | #define SIRFUART_RX_TIMEOUT BIT(12) |
| 99 | #define SIRFUART_PARITY_ERR BIT(13) |
| 100 | #define SIRFUART_CTS_CHANGE BIT(14) |
| 101 | #define SIRFUART_RTS_CHANGE BIT(15) |
| 102 | #define SIRFUART_PLUG_IN BIT(16) |
| 103 | |
| 104 | #define SIRFUART_ERR_INT_STAT \ |
| 105 | (SIRFUART_RX_OFLOW | \ |
| 106 | SIRFUART_FRM_ERR | \ |
| 107 | SIRFUART_RXD_BREAK | \ |
| 108 | SIRFUART_PARITY_ERR) |
| 109 | #define SIRFUART_ERR_INT_EN \ |
| 110 | (SIRFUART_RX_OFLOW_INT | \ |
| 111 | SIRFUART_FRM_ERR_INT | \ |
| 112 | SIRFUART_RXD_BREAK_INT | \ |
| 113 | SIRFUART_PARITY_ERR_INT) |
| 114 | #define SIRFUART_TX_INT_EN SIRFUART_TXFIFO_EMPTY_INT |
| 115 | #define SIRFUART_RX_IO_INT_EN \ |
| 116 | (SIRFUART_RX_TIMEOUT_INT | \ |
| 117 | SIRFUART_RXFIFO_THD_INT | \ |
| 118 | SIRFUART_RXFIFO_FULL_INT | \ |
| 119 | SIRFUART_ERR_INT_EN) |
| 120 | |
| 121 | /* UART FIFO Register */ |
| 122 | #define SIRFUART_TX_FIFO_STOP 0x0 |
| 123 | #define SIRFUART_TX_FIFO_RESET 0x1 |
| 124 | #define SIRFUART_TX_FIFO_START 0x2 |
| 125 | #define SIRFUART_RX_FIFO_STOP 0x0 |
| 126 | #define SIRFUART_RX_FIFO_RESET 0x1 |
| 127 | #define SIRFUART_RX_FIFO_START 0x2 |
| 128 | #define SIRFUART_TX_MODE_DMA 0 |
| 129 | #define SIRFUART_TX_MODE_IO 1 |
| 130 | #define SIRFUART_RX_MODE_DMA 0 |
| 131 | #define SIRFUART_RX_MODE_IO 1 |
| 132 | |
| 133 | #define SIRFUART_RX_EN 0x1 |
| 134 | #define SIRFUART_TX_EN 0x2 |
| 135 | |
| 136 | /* Generic Definitions */ |
| 137 | #define SIRFSOC_UART_NAME "ttySiRF" |
| 138 | #define SIRFSOC_UART_MAJOR 0 |
| 139 | #define SIRFSOC_UART_MINOR 0 |
| 140 | #define SIRFUART_PORT_NAME "sirfsoc-uart" |
| 141 | #define SIRFUART_MAP_SIZE 0x200 |
| 142 | #define SIRFSOC_UART_NR 3 |
| 143 | #define SIRFSOC_PORT_TYPE 0xa5 |
| 144 | |
| 145 | /* Baud Rate Calculation */ |
| 146 | #define SIRF_MIN_SAMPLE_DIV 0xf |
| 147 | #define SIRF_MAX_SAMPLE_DIV 0x3f |
| 148 | #define SIRF_IOCLK_DIV_MAX 0xffff |
| 149 | #define SIRF_SAMPLE_DIV_SHIFT 16 |
| 150 | #define SIRF_IOCLK_DIV_MASK 0xffff |
| 151 | #define SIRF_SAMPLE_DIV_MASK 0x3f0000 |
| 152 | #define SIRF_BAUD_RATE_SUPPORT_NR 18 |
| 153 | |
| 154 | /* For Fast Baud Rate Calculation */ |
| 155 | struct sirfsoc_baudrate_to_regv { |
| 156 | unsigned int baud_rate; |
| 157 | unsigned int reg_val; |
| 158 | }; |
| 159 | |
| 160 | struct sirfsoc_uart_port { |
| 161 | unsigned char hw_flow_ctrl; |
| 162 | unsigned char ms_enabled; |
| 163 | |
| 164 | struct uart_port port; |
Linus Walleij | 5c9bdc3 | 2012-02-16 19:36:21 +0100 | [diff] [blame^] | 165 | struct pinctrl *p; |
Rong Wang | 161e773 | 2011-11-17 23:17:04 +0800 | [diff] [blame] | 166 | }; |
| 167 | |
| 168 | /* Hardware Flow Control */ |
| 169 | #define SIRFUART_AFC_CTRL_RX_THD 0x70 |
| 170 | |
| 171 | /* Register Access Control */ |
| 172 | #define portaddr(port, reg) ((port)->membase + (reg)) |
| 173 | #define rd_regb(port, reg) (__raw_readb(portaddr(port, reg))) |
| 174 | #define rd_regl(port, reg) (__raw_readl(portaddr(port, reg))) |
| 175 | #define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg)) |
| 176 | #define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg)) |
| 177 | |
| 178 | /* UART Port Mask */ |
| 179 | #define SIRFUART_FIFOLEVEL_MASK(port) ((port->line == 1) ? (0x1f) : (0x7f)) |
| 180 | #define SIRFUART_FIFOFULL_MASK(port) ((port->line == 1) ? (0x20) : (0x80)) |
| 181 | #define SIRFUART_FIFOEMPTY_MASK(port) ((port->line == 1) ? (0x40) : (0x100)) |
| 182 | |
| 183 | /* I/O Mode */ |
| 184 | #define SIRFSOC_UART_IO_RX_MAX_CNT 256 |
| 185 | #define SIRFSOC_UART_IO_TX_REASONABLE_CNT 6 |