Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v5.3 446 lines 13 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Drivers for CSR SiRFprimaII onboard UARTs. 4 * 5 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. 6 */ 7#include <linux/bitops.h> 8#include <linux/log2.h> 9#include <linux/hrtimer.h> 10struct sirfsoc_uart_param { 11 const char *uart_name; 12 const char *port_name; 13}; 14 15struct sirfsoc_register { 16 /* hardware uart specific */ 17 u32 sirfsoc_line_ctrl; 18 u32 sirfsoc_divisor; 19 /* uart - usp common */ 20 u32 sirfsoc_tx_rx_en; 21 u32 sirfsoc_int_en_reg; 22 u32 sirfsoc_int_st_reg; 23 u32 sirfsoc_int_en_clr_reg; 24 u32 sirfsoc_tx_dma_io_ctrl; 25 u32 sirfsoc_tx_dma_io_len; 26 u32 sirfsoc_tx_fifo_ctrl; 27 u32 sirfsoc_tx_fifo_level_chk; 28 u32 sirfsoc_tx_fifo_op; 29 u32 sirfsoc_tx_fifo_status; 30 u32 sirfsoc_tx_fifo_data; 31 u32 sirfsoc_rx_dma_io_ctrl; 32 u32 sirfsoc_rx_dma_io_len; 33 u32 sirfsoc_rx_fifo_ctrl; 34 u32 sirfsoc_rx_fifo_level_chk; 35 u32 sirfsoc_rx_fifo_op; 36 u32 sirfsoc_rx_fifo_status; 37 u32 sirfsoc_rx_fifo_data; 38 u32 sirfsoc_afc_ctrl; 39 u32 sirfsoc_swh_dma_io; 40 /* hardware usp specific */ 41 u32 sirfsoc_mode1; 42 u32 sirfsoc_mode2; 43 u32 sirfsoc_tx_frame_ctrl; 44 u32 sirfsoc_rx_frame_ctrl; 45 u32 sirfsoc_async_param_reg; 46}; 47 48typedef u32 (*fifo_full_mask)(struct uart_port *port); 49typedef u32 (*fifo_empty_mask)(struct uart_port *port); 50 51struct sirfsoc_fifo_status { 52 fifo_full_mask ff_full; 53 fifo_empty_mask ff_empty; 54}; 55 56struct sirfsoc_int_en { 57 u32 sirfsoc_rx_done_en; 58 u32 sirfsoc_tx_done_en; 59 u32 sirfsoc_rx_oflow_en; 60 u32 sirfsoc_tx_allout_en; 61 u32 sirfsoc_rx_io_dma_en; 62 u32 sirfsoc_tx_io_dma_en; 63 u32 sirfsoc_rxfifo_full_en; 64 u32 sirfsoc_txfifo_empty_en; 65 u32 sirfsoc_rxfifo_thd_en; 66 u32 sirfsoc_txfifo_thd_en; 67 u32 sirfsoc_frm_err_en; 68 u32 sirfsoc_rxd_brk_en; 69 u32 sirfsoc_rx_timeout_en; 70 u32 sirfsoc_parity_err_en; 71 u32 sirfsoc_cts_en; 72 u32 sirfsoc_rts_en; 73}; 74 75struct sirfsoc_int_status { 76 u32 sirfsoc_rx_done; 77 u32 sirfsoc_tx_done; 78 u32 sirfsoc_rx_oflow; 79 u32 sirfsoc_tx_allout; 80 u32 sirfsoc_rx_io_dma; 81 u32 sirfsoc_tx_io_dma; 82 u32 sirfsoc_rxfifo_full; 83 u32 sirfsoc_txfifo_empty; 84 u32 sirfsoc_rxfifo_thd; 85 u32 sirfsoc_txfifo_thd; 86 u32 sirfsoc_frm_err; 87 u32 sirfsoc_rxd_brk; 88 u32 sirfsoc_rx_timeout; 89 u32 sirfsoc_parity_err; 90 u32 sirfsoc_cts; 91 u32 sirfsoc_rts; 92}; 93 94enum sirfsoc_uart_type { 95 SIRF_REAL_UART, 96 SIRF_USP_UART, 97}; 98 99struct sirfsoc_uart_register { 100 struct sirfsoc_register uart_reg; 101 struct sirfsoc_int_en uart_int_en; 102 struct sirfsoc_int_status uart_int_st; 103 struct sirfsoc_fifo_status fifo_status; 104 struct sirfsoc_uart_param uart_param; 105 enum sirfsoc_uart_type uart_type; 106}; 107 108static u32 uart_usp_ff_full_mask(struct uart_port *port) 109{ 110 u32 full_bit; 111 112 full_bit = ilog2(port->fifosize); 113 return (1 << full_bit); 114} 115 116static u32 uart_usp_ff_empty_mask(struct uart_port *port) 117{ 118 u32 empty_bit; 119 120 empty_bit = ilog2(port->fifosize) + 1; 121 return (1 << empty_bit); 122} 123struct sirfsoc_uart_register sirfsoc_usp = { 124 .uart_reg = { 125 .sirfsoc_mode1 = 0x0000, 126 .sirfsoc_mode2 = 0x0004, 127 .sirfsoc_tx_frame_ctrl = 0x0008, 128 .sirfsoc_rx_frame_ctrl = 0x000c, 129 .sirfsoc_tx_rx_en = 0x0010, 130 .sirfsoc_int_en_reg = 0x0014, 131 .sirfsoc_int_st_reg = 0x0018, 132 .sirfsoc_async_param_reg = 0x0024, 133 .sirfsoc_tx_dma_io_ctrl = 0x0100, 134 .sirfsoc_tx_dma_io_len = 0x0104, 135 .sirfsoc_tx_fifo_ctrl = 0x0108, 136 .sirfsoc_tx_fifo_level_chk = 0x010c, 137 .sirfsoc_tx_fifo_op = 0x0110, 138 .sirfsoc_tx_fifo_status = 0x0114, 139 .sirfsoc_tx_fifo_data = 0x0118, 140 .sirfsoc_rx_dma_io_ctrl = 0x0120, 141 .sirfsoc_rx_dma_io_len = 0x0124, 142 .sirfsoc_rx_fifo_ctrl = 0x0128, 143 .sirfsoc_rx_fifo_level_chk = 0x012c, 144 .sirfsoc_rx_fifo_op = 0x0130, 145 .sirfsoc_rx_fifo_status = 0x0134, 146 .sirfsoc_rx_fifo_data = 0x0138, 147 .sirfsoc_int_en_clr_reg = 0x140, 148 }, 149 .uart_int_en = { 150 .sirfsoc_rx_done_en = BIT(0), 151 .sirfsoc_tx_done_en = BIT(1), 152 .sirfsoc_rx_oflow_en = BIT(2), 153 .sirfsoc_tx_allout_en = BIT(3), 154 .sirfsoc_rx_io_dma_en = BIT(4), 155 .sirfsoc_tx_io_dma_en = BIT(5), 156 .sirfsoc_rxfifo_full_en = BIT(6), 157 .sirfsoc_txfifo_empty_en = BIT(7), 158 .sirfsoc_rxfifo_thd_en = BIT(8), 159 .sirfsoc_txfifo_thd_en = BIT(9), 160 .sirfsoc_frm_err_en = BIT(10), 161 .sirfsoc_rx_timeout_en = BIT(11), 162 .sirfsoc_rxd_brk_en = BIT(15), 163 }, 164 .uart_int_st = { 165 .sirfsoc_rx_done = BIT(0), 166 .sirfsoc_tx_done = BIT(1), 167 .sirfsoc_rx_oflow = BIT(2), 168 .sirfsoc_tx_allout = BIT(3), 169 .sirfsoc_rx_io_dma = BIT(4), 170 .sirfsoc_tx_io_dma = BIT(5), 171 .sirfsoc_rxfifo_full = BIT(6), 172 .sirfsoc_txfifo_empty = BIT(7), 173 .sirfsoc_rxfifo_thd = BIT(8), 174 .sirfsoc_txfifo_thd = BIT(9), 175 .sirfsoc_frm_err = BIT(10), 176 .sirfsoc_rx_timeout = BIT(11), 177 .sirfsoc_rxd_brk = BIT(15), 178 }, 179 .fifo_status = { 180 .ff_full = uart_usp_ff_full_mask, 181 .ff_empty = uart_usp_ff_empty_mask, 182 }, 183 .uart_param = { 184 .uart_name = "ttySiRF", 185 .port_name = "sirfsoc-uart", 186 }, 187}; 188 189struct sirfsoc_uart_register sirfsoc_uart = { 190 .uart_reg = { 191 .sirfsoc_line_ctrl = 0x0040, 192 .sirfsoc_tx_rx_en = 0x004c, 193 .sirfsoc_divisor = 0x0050, 194 .sirfsoc_int_en_reg = 0x0054, 195 .sirfsoc_int_st_reg = 0x0058, 196 .sirfsoc_int_en_clr_reg = 0x0060, 197 .sirfsoc_tx_dma_io_ctrl = 0x0100, 198 .sirfsoc_tx_dma_io_len = 0x0104, 199 .sirfsoc_tx_fifo_ctrl = 0x0108, 200 .sirfsoc_tx_fifo_level_chk = 0x010c, 201 .sirfsoc_tx_fifo_op = 0x0110, 202 .sirfsoc_tx_fifo_status = 0x0114, 203 .sirfsoc_tx_fifo_data = 0x0118, 204 .sirfsoc_rx_dma_io_ctrl = 0x0120, 205 .sirfsoc_rx_dma_io_len = 0x0124, 206 .sirfsoc_rx_fifo_ctrl = 0x0128, 207 .sirfsoc_rx_fifo_level_chk = 0x012c, 208 .sirfsoc_rx_fifo_op = 0x0130, 209 .sirfsoc_rx_fifo_status = 0x0134, 210 .sirfsoc_rx_fifo_data = 0x0138, 211 .sirfsoc_afc_ctrl = 0x0140, 212 .sirfsoc_swh_dma_io = 0x0148, 213 }, 214 .uart_int_en = { 215 .sirfsoc_rx_done_en = BIT(0), 216 .sirfsoc_tx_done_en = BIT(1), 217 .sirfsoc_rx_oflow_en = BIT(2), 218 .sirfsoc_tx_allout_en = BIT(3), 219 .sirfsoc_rx_io_dma_en = BIT(4), 220 .sirfsoc_tx_io_dma_en = BIT(5), 221 .sirfsoc_rxfifo_full_en = BIT(6), 222 .sirfsoc_txfifo_empty_en = BIT(7), 223 .sirfsoc_rxfifo_thd_en = BIT(8), 224 .sirfsoc_txfifo_thd_en = BIT(9), 225 .sirfsoc_frm_err_en = BIT(10), 226 .sirfsoc_rxd_brk_en = BIT(11), 227 .sirfsoc_rx_timeout_en = BIT(12), 228 .sirfsoc_parity_err_en = BIT(13), 229 .sirfsoc_cts_en = BIT(14), 230 .sirfsoc_rts_en = BIT(15), 231 }, 232 .uart_int_st = { 233 .sirfsoc_rx_done = BIT(0), 234 .sirfsoc_tx_done = BIT(1), 235 .sirfsoc_rx_oflow = BIT(2), 236 .sirfsoc_tx_allout = BIT(3), 237 .sirfsoc_rx_io_dma = BIT(4), 238 .sirfsoc_tx_io_dma = BIT(5), 239 .sirfsoc_rxfifo_full = BIT(6), 240 .sirfsoc_txfifo_empty = BIT(7), 241 .sirfsoc_rxfifo_thd = BIT(8), 242 .sirfsoc_txfifo_thd = BIT(9), 243 .sirfsoc_frm_err = BIT(10), 244 .sirfsoc_rxd_brk = BIT(11), 245 .sirfsoc_rx_timeout = BIT(12), 246 .sirfsoc_parity_err = BIT(13), 247 .sirfsoc_cts = BIT(14), 248 .sirfsoc_rts = BIT(15), 249 }, 250 .fifo_status = { 251 .ff_full = uart_usp_ff_full_mask, 252 .ff_empty = uart_usp_ff_empty_mask, 253 }, 254 .uart_param = { 255 .uart_name = "ttySiRF", 256 .port_name = "sirfsoc_uart", 257 }, 258}; 259/* uart io ctrl */ 260#define SIRFUART_DATA_BIT_LEN_MASK 0x3 261#define SIRFUART_DATA_BIT_LEN_5 BIT(0) 262#define SIRFUART_DATA_BIT_LEN_6 1 263#define SIRFUART_DATA_BIT_LEN_7 2 264#define SIRFUART_DATA_BIT_LEN_8 3 265#define SIRFUART_STOP_BIT_LEN_1 0 266#define SIRFUART_STOP_BIT_LEN_2 BIT(2) 267#define SIRFUART_PARITY_EN BIT(3) 268#define SIRFUART_EVEN_BIT BIT(4) 269#define SIRFUART_STICK_BIT_MASK (7 << 3) 270#define SIRFUART_STICK_BIT_NONE (0 << 3) 271#define SIRFUART_STICK_BIT_EVEN BIT(3) 272#define SIRFUART_STICK_BIT_ODD (3 << 3) 273#define SIRFUART_STICK_BIT_MARK (5 << 3) 274#define SIRFUART_STICK_BIT_SPACE (7 << 3) 275#define SIRFUART_SET_BREAK BIT(6) 276#define SIRFUART_LOOP_BACK BIT(7) 277#define SIRFUART_PARITY_MASK (7 << 3) 278#define SIRFUART_DUMMY_READ BIT(16) 279#define SIRFUART_AFC_CTRL_RX_THD 0x70 280#define SIRFUART_AFC_RX_EN BIT(8) 281#define SIRFUART_AFC_TX_EN BIT(9) 282#define SIRFUART_AFC_CTS_CTRL BIT(10) 283#define SIRFUART_AFC_RTS_CTRL BIT(11) 284#define SIRFUART_AFC_CTS_STATUS BIT(12) 285#define SIRFUART_AFC_RTS_STATUS BIT(13) 286/* UART FIFO Register */ 287#define SIRFUART_FIFO_STOP 0x0 288#define SIRFUART_FIFO_RESET BIT(0) 289#define SIRFUART_FIFO_START BIT(1) 290 291#define SIRFUART_RX_EN BIT(0) 292#define SIRFUART_TX_EN BIT(1) 293 294#define SIRFUART_IO_MODE BIT(0) 295#define SIRFUART_DMA_MODE 0x0 296#define SIRFUART_RX_DMA_FLUSH 0x4 297 298#define SIRFUART_CLEAR_RX_ADDR_EN 0x2 299/* Baud Rate Calculation */ 300#define SIRF_USP_MIN_SAMPLE_DIV 0x1 301#define SIRF_MIN_SAMPLE_DIV 0xf 302#define SIRF_MAX_SAMPLE_DIV 0x3f 303#define SIRF_IOCLK_DIV_MAX 0xffff 304#define SIRF_SAMPLE_DIV_SHIFT 16 305#define SIRF_IOCLK_DIV_MASK 0xffff 306#define SIRF_SAMPLE_DIV_MASK 0x3f0000 307#define SIRF_BAUD_RATE_SUPPORT_NR 18 308 309/* USP SPEC */ 310#define SIRFSOC_USP_ENDIAN_CTRL_LSBF BIT(4) 311#define SIRFSOC_USP_EN BIT(5) 312#define SIRFSOC_USP_MODE2_RXD_DELAY_OFFSET 0 313#define SIRFSOC_USP_MODE2_TXD_DELAY_OFFSET 8 314#define SIRFSOC_USP_MODE2_CLK_DIVISOR_MASK 0x3ff 315#define SIRFSOC_USP_MODE2_CLK_DIVISOR_OFFSET 21 316#define SIRFSOC_USP_TX_DATA_LEN_OFFSET 0 317#define SIRFSOC_USP_TX_SYNC_LEN_OFFSET 8 318#define SIRFSOC_USP_TX_FRAME_LEN_OFFSET 16 319#define SIRFSOC_USP_TX_SHIFTER_LEN_OFFSET 24 320#define SIRFSOC_USP_TX_CLK_DIVISOR_OFFSET 30 321#define SIRFSOC_USP_RX_DATA_LEN_OFFSET 0 322#define SIRFSOC_USP_RX_FRAME_LEN_OFFSET 8 323#define SIRFSOC_USP_RX_SHIFTER_LEN_OFFSET 16 324#define SIRFSOC_USP_RX_CLK_DIVISOR_OFFSET 24 325#define SIRFSOC_USP_ASYNC_DIV2_MASK 0x3f 326#define SIRFSOC_USP_ASYNC_DIV2_OFFSET 16 327#define SIRFSOC_USP_LOOP_BACK_CTRL BIT(2) 328#define SIRFSOC_USP_FRADDR_CLR_EN BIT(1) 329/* USP-UART Common */ 330#define SIRFSOC_UART_RX_TIMEOUT(br, to) (((br) * (((to) + 999) / 1000)) / 1000) 331#define SIRFUART_RECV_TIMEOUT_VALUE(x) \ 332 (((x) > 0xFFFF) ? 0xFFFF : ((x) & 0xFFFF)) 333#define SIRFUART_USP_RECV_TIMEOUT(x) (x & 0xFFFF) 334#define SIRFUART_UART_RECV_TIMEOUT(x) ((x & 0xFFFF) << 16) 335 336#define SIRFUART_FIFO_THD(port) (port->fifosize >> 1) 337#define SIRFUART_ERR_INT_STAT(unit_st, uart_type) \ 338 (uint_st->sirfsoc_rx_oflow | \ 339 uint_st->sirfsoc_frm_err | \ 340 uint_st->sirfsoc_rxd_brk | \ 341 ((uart_type != SIRF_REAL_UART) ? \ 342 0 : uint_st->sirfsoc_parity_err)) 343#define SIRFUART_RX_IO_INT_EN(uint_en, uart_type) \ 344 (uint_en->sirfsoc_rx_done_en |\ 345 uint_en->sirfsoc_rxfifo_thd_en |\ 346 uint_en->sirfsoc_rxfifo_full_en |\ 347 uint_en->sirfsoc_frm_err_en |\ 348 uint_en->sirfsoc_rx_oflow_en |\ 349 uint_en->sirfsoc_rxd_brk_en |\ 350 ((uart_type != SIRF_REAL_UART) ? \ 351 0 : uint_en->sirfsoc_parity_err_en)) 352#define SIRFUART_RX_IO_INT_ST(uint_st) \ 353 (uint_st->sirfsoc_rxfifo_thd |\ 354 uint_st->sirfsoc_rxfifo_full|\ 355 uint_st->sirfsoc_rx_done |\ 356 uint_st->sirfsoc_rx_timeout) 357#define SIRFUART_CTS_INT_ST(uint_st) (uint_st->sirfsoc_cts) 358#define SIRFUART_RX_DMA_INT_EN(uint_en, uart_type) \ 359 (uint_en->sirfsoc_frm_err_en |\ 360 uint_en->sirfsoc_rx_oflow_en |\ 361 uint_en->sirfsoc_rxd_brk_en |\ 362 ((uart_type != SIRF_REAL_UART) ? \ 363 0 : uint_en->sirfsoc_parity_err_en)) 364/* Generic Definitions */ 365#define SIRFSOC_UART_NAME "ttySiRF" 366#define SIRFSOC_UART_MAJOR 0 367#define SIRFSOC_UART_MINOR 0 368#define SIRFUART_PORT_NAME "sirfsoc-uart" 369#define SIRFUART_MAP_SIZE 0x200 370#define SIRFSOC_UART_NR 11 371#define SIRFSOC_PORT_TYPE 0xa5 372 373/* Uart Common Use Macro*/ 374#define SIRFSOC_RX_DMA_BUF_SIZE (1024 * 32) 375#define BYTES_TO_ALIGN(dma_addr) ((unsigned long)(dma_addr) & 0x3) 376/* Uart Fifo Level Chk */ 377#define SIRFUART_TX_FIFO_SC_OFFSET 0 378#define SIRFUART_TX_FIFO_LC_OFFSET 10 379#define SIRFUART_TX_FIFO_HC_OFFSET 20 380#define SIRFUART_TX_FIFO_CHK_SC(line, value) ((((line) == 1) ? (value & 0x3) :\ 381 (value & 0x1f)) << SIRFUART_TX_FIFO_SC_OFFSET) 382#define SIRFUART_TX_FIFO_CHK_LC(line, value) ((((line) == 1) ? (value & 0x3) :\ 383 (value & 0x1f)) << SIRFUART_TX_FIFO_LC_OFFSET) 384#define SIRFUART_TX_FIFO_CHK_HC(line, value) ((((line) == 1) ? (value & 0x3) :\ 385 (value & 0x1f)) << SIRFUART_TX_FIFO_HC_OFFSET) 386 387#define SIRFUART_RX_FIFO_CHK_SC SIRFUART_TX_FIFO_CHK_SC 388#define SIRFUART_RX_FIFO_CHK_LC SIRFUART_TX_FIFO_CHK_LC 389#define SIRFUART_RX_FIFO_CHK_HC SIRFUART_TX_FIFO_CHK_HC 390#define SIRFUART_RX_FIFO_MASK 0x7f 391/* Indicate how many buffers used */ 392 393/* For Fast Baud Rate Calculation */ 394struct sirfsoc_baudrate_to_regv { 395 unsigned int baud_rate; 396 unsigned int reg_val; 397}; 398 399enum sirfsoc_tx_state { 400 TX_DMA_IDLE, 401 TX_DMA_RUNNING, 402 TX_DMA_PAUSE, 403}; 404 405struct sirfsoc_rx_buffer { 406 struct circ_buf xmit; 407 dma_cookie_t cookie; 408 struct dma_async_tx_descriptor *desc; 409 dma_addr_t dma_addr; 410}; 411 412struct sirfsoc_uart_port { 413 bool hw_flow_ctrl; 414 bool ms_enabled; 415 416 struct uart_port port; 417 struct clk *clk; 418 /* for SiRFatlas7, there are SET/CLR for UART_INT_EN */ 419 bool is_atlas7; 420 struct sirfsoc_uart_register *uart_reg; 421 struct dma_chan *rx_dma_chan; 422 struct dma_chan *tx_dma_chan; 423 dma_addr_t tx_dma_addr; 424 struct dma_async_tx_descriptor *tx_dma_desc; 425 unsigned long transfer_size; 426 enum sirfsoc_tx_state tx_dma_state; 427 unsigned int cts_gpio; 428 unsigned int rts_gpio; 429 430 struct sirfsoc_rx_buffer rx_dma_items; 431 struct hrtimer hrt; 432 bool is_hrt_enabled; 433 unsigned long rx_period_time; 434 unsigned long rx_last_pos; 435 unsigned long pio_fetch_cnt; 436}; 437 438/* Register Access Control */ 439#define portaddr(port, reg) ((port)->membase + (reg)) 440#define rd_regl(port, reg) (__raw_readl(portaddr(port, reg))) 441#define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg)) 442 443/* UART Port Mask */ 444#define SIRFUART_FIFOLEVEL_MASK(port) ((port->fifosize - 1) & 0xFFF) 445#define SIRFUART_FIFOFULL_MASK(port) (port->fifosize & 0xFFF) 446#define SIRFUART_FIFOEMPTY_MASK(port) ((port->fifosize & 0xFFF) << 1)