FILE
rsci.c
File preview with syntax highlighting.
linux-6.19.14/drivers/tty/serial/rsci.c
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2025 Renesas Electronics Corp. 4 */ 5 6#include <linux/bitfield.h> 7#include <linux/bitops.h> 8#include <linux/io.h> 9#include <linux/iopoll.h> 10#include <linux/module.h> 11#include <linux/serial_core.h> 12#include <linux/serial_sci.h> 13#include <linux/tty_flip.h> 14#include "rsci.h" 15 16MODULE_IMPORT_NS("SH_SCI"); 17 18/* RSCI registers */ 19#define RDR 0x00 20#define TDR 0x04 21#define CCR0 0x08 22#define CCR1 0x0C 23#define CCR2 0x10 24#define CCR3 0x14 25#define CCR4 0x18 26#define FCR 0x24 27#define DCR 0x30 28#define CSR 0x48 29#define FRSR 0x50 30#define FTSR 0x54 31#define CFCLR 0x68 32#define FFCLR 0x70 33 34/* RDR (Receive Data Register) */ 35#define RDR_FFER BIT(12) /* FIFO Framing Error */ 36#define RDR_FPER BIT(11) /* FIFO Parity Error */ 37#define RDR_RDAT_MSK GENMASK(8, 0) 38 39/* TDR (Transmit Data Register) */ 40#define TDR_MPBT BIT(9) /* Multiprocessor Transfer */ 41#define TDR_TDAT_9BIT_LSHIFT 0 42#define TDR_TDAT_9BIT_VAL 0x1FF 43#define TDR_TDAT_9BIT_MSK (TDR_TDAT_9BIT_VAL << TDR_TDAT_9BIT_LSHIFT) 44 45/* CCR0 (Common Control Register 0) */ 46#define CCR0_SSE BIT(24) /* SSn# Pin Function Enable */ 47#define CCR0_TEIE BIT(21) /* Transmit End Interrupt Enable */ 48#define CCR0_TIE BIT(20) /* Transmit Interrupt Enable */ 49#define CCR0_RIE BIT(16) /* Receive Interrupt Enable */ 50#define CCR0_IDSEL BIT(10) /* ID Frame Select */ 51#define CCR0_DCME BIT(9) /* Data Compare Match Enable */ 52#define CCR0_MPIE BIT(8) /* Multiprocessor Interrupt Enable */ 53#define CCR0_TE BIT(4) /* Transmit Enable */ 54#define CCR0_RE BIT(0) /* Receive Enable */ 55 56/* CCR1 (Common Control Register 1) */ 57#define CCR1_NFEN BIT(28) /* Digital Noise Filter Function */ 58#define CCR1_SHARPS BIT(20) /* Half -duplex Communication Select */ 59#define CCR1_SPLP BIT(16) /* Loopback Control */ 60#define CCR1_RINV BIT(13) /* RxD invert */ 61#define CCR1_TINV BIT(12) /* TxD invert */ 62#define CCR1_PM BIT(9) /* Parity Mode */ 63#define CCR1_PE BIT(8) /* Parity Enable */ 64#define CCR1_SPB2IO BIT(5) /* Serial Port Break I/O */ 65#define CCR1_SPB2DT BIT(4) /* Serial Port Break Data Select */ 66#define CCR1_CTSPEN BIT(1) /* CTS External Pin Enable */ 67#define CCR1_CTSE BIT(0) /* CTS Enable */ 68 69/* FCR (FIFO Control Register) */ 70#define FCR_RFRST BIT(23) /* Receive FIFO Data Register Reset */ 71#define FCR_TFRST BIT(15) /* Transmit FIFO Data Register Reset */ 72#define FCR_DRES BIT(0) /* Incoming Data Ready Error Select */ 73#define FCR_RTRG4_0 GENMASK(20, 16) 74#define FCR_TTRG GENMASK(12, 8) 75 76/* CSR (Common Status Register) */ 77#define CSR_RDRF BIT(31) /* Receive Data Full */ 78#define CSR_TEND BIT(30) /* Transmit End Flag */ 79#define CSR_TDRE BIT(29) /* Transmit Data Empty */ 80#define CSR_FER BIT(28) /* Framing Error */ 81#define CSR_PER BIT(27) /* Parity Error */ 82#define CSR_MFF BIT(26) /* Mode Fault Error */ 83#define CSR_ORER BIT(24) /* Overrun Error */ 84#define CSR_DFER BIT(18) /* Data Compare Match Framing Error */ 85#define CSR_DPER BIT(17) /* Data Compare Match Parity Error */ 86#define CSR_DCMF BIT(16) /* Data Compare Match */ 87#define CSR_RXDMON BIT(15) /* Serial Input Data Monitor */ 88#define CSR_ERS BIT(4) /* Error Signal Status */ 89 90#define SCxSR_ERRORS(port) (to_sci_port(port)->params->error_mask) 91#define SCxSR_ERROR_CLEAR(port) (to_sci_port(port)->params->error_clear) 92 93#define RSCI_DEFAULT_ERROR_MASK (CSR_PER | CSR_FER) 94 95#define RSCI_RDxF_CLEAR (CFCLR_RDRFC) 96#define RSCI_ERROR_CLEAR (CFCLR_PERC | CFCLR_FERC) 97#define RSCI_TDxE_CLEAR (CFCLR_TDREC) 98#define RSCI_BREAK_CLEAR (CFCLR_PERC | CFCLR_FERC | CFCLR_ORERC) 99 100/* FRSR (FIFO Receive Status Register) */ 101#define FRSR_R5_0 GENMASK(13, 8) /* Receive FIFO Data Count */ 102#define FRSR_DR BIT(0) /* Receive Data Ready */ 103 104/* CFCLR (Common Flag CLear Register) */ 105#define CFCLR_RDRFC BIT(31) /* RDRF Clear */ 106#define CFCLR_TDREC BIT(29) /* TDRE Clear */ 107#define CFCLR_FERC BIT(28) /* FER Clear */ 108#define CFCLR_PERC BIT(27) /* PER Clear */ 109#define CFCLR_MFFC BIT(26) /* MFF Clear */ 110#define CFCLR_ORERC BIT(24) /* ORER Clear */ 111#define CFCLR_DFERC BIT(18) /* DFER Clear */ 112#define CFCLR_DPERC BIT(17) /* DPER Clear */ 113#define CFCLR_DCMFC BIT(16) /* DCMF Clear */ 114#define CFCLR_ERSC BIT(4) /* ERS Clear */ 115#define CFCLR_CLRFLAG (CFCLR_RDRFC | CFCLR_FERC | CFCLR_PERC | \ 116 CFCLR_MFFC | CFCLR_ORERC | CFCLR_DFERC | \ 117 CFCLR_DPERC | CFCLR_DCMFC | CFCLR_ERSC) 118 119/* FFCLR (FIFO Flag CLear Register) */ 120#define FFCLR_DRC BIT(0) /* DR Clear */ 121 122#define DCR_DEPOL BIT(0) 123 124static u32 rsci_serial_in(struct uart_port *p, int offset) 125{ 126 return readl(p->membase + offset); 127} 128 129static void rsci_serial_out(struct uart_port *p, int offset, int value) 130{ 131 writel(value, p->membase + offset); 132} 133 134static void rsci_clear_DRxC(struct uart_port *port) 135{ 136 rsci_serial_out(port, CFCLR, CFCLR_RDRFC); 137 rsci_serial_out(port, FFCLR, FFCLR_DRC); 138} 139 140static void rsci_clear_SCxSR(struct uart_port *port, unsigned int mask) 141{ 142 rsci_serial_out(port, CFCLR, mask); 143} 144 145static void rsci_start_rx(struct uart_port *port) 146{ 147 unsigned int ctrl; 148 149 ctrl = rsci_serial_in(port, CCR0); 150 ctrl |= CCR0_RIE; 151 rsci_serial_out(port, CCR0, ctrl); 152} 153 154static int rsci_scif_set_rtrg(struct uart_port *port, int rx_trig) 155{ 156 u32 fcr = rsci_serial_in(port, FCR); 157 158 if (rx_trig >= port->fifosize) 159 rx_trig = port->fifosize - 1; 160 else if (rx_trig < 1) 161 rx_trig = 0; 162 163 fcr &= ~FCR_RTRG4_0; 164 fcr |= field_prep(FCR_RTRG4_0, rx_trig); 165 rsci_serial_out(port, FCR, fcr); 166 167 return rx_trig; 168} 169 170static void rsci_set_termios(struct uart_port *port, struct ktermios *termios, 171 const struct ktermios *old) 172{ 173 struct sci_port *s = to_sci_port(port); 174 unsigned long flags; 175 176 sci_port_enable(s); 177 uart_port_lock_irqsave(port, &flags); 178 179 /* For now, only RX enabling is supported */ 180 if (termios->c_cflag & CREAD) 181 rsci_start_rx(port); 182 183 uart_port_unlock_irqrestore(port, flags); 184 sci_port_disable(s); 185} 186 187static int rsci_txfill(struct uart_port *port) 188{ 189 return rsci_serial_in(port, FTSR); 190} 191 192static int rsci_rxfill(struct uart_port *port) 193{ 194 u32 val = rsci_serial_in(port, FRSR); 195 196 return FIELD_GET(FRSR_R5_0, val); 197} 198 199static unsigned int rsci_tx_empty(struct uart_port *port) 200{ 201 unsigned int status = rsci_serial_in(port, CSR); 202 unsigned int in_tx_fifo = rsci_txfill(port); 203 204 return (status & CSR_TEND) && !in_tx_fifo ? TIOCSER_TEMT : 0; 205} 206 207static void rsci_set_mctrl(struct uart_port *port, unsigned int mctrl) 208{ 209 /* Not supported yet */ 210} 211 212static unsigned int rsci_get_mctrl(struct uart_port *port) 213{ 214 /* Not supported yet */ 215 return 0; 216} 217 218static void rsci_clear_CFC(struct uart_port *port, unsigned int mask) 219{ 220 rsci_serial_out(port, CFCLR, mask); 221} 222 223static void rsci_start_tx(struct uart_port *port) 224{ 225 struct sci_port *sp = to_sci_port(port); 226 u32 ctrl; 227 228 if (sp->chan_tx) 229 return; 230 231 /* 232 * TE (Transmit Enable) must be set after setting TIE 233 * (Transmit Interrupt Enable) or in the same instruction 234 * to start the transmit process. 235 */ 236 ctrl = rsci_serial_in(port, CCR0); 237 ctrl |= CCR0_TIE | CCR0_TE; 238 rsci_serial_out(port, CCR0, ctrl); 239} 240 241static void rsci_stop_tx(struct uart_port *port) 242{ 243 u32 ctrl; 244 245 ctrl = rsci_serial_in(port, CCR0); 246 ctrl &= ~CCR0_TIE; 247 rsci_serial_out(port, CCR0, ctrl); 248} 249 250static void rsci_stop_rx(struct uart_port *port) 251{ 252 u32 ctrl; 253 254 ctrl = rsci_serial_in(port, CCR0); 255 ctrl &= ~CCR0_RIE; 256 rsci_serial_out(port, CCR0, ctrl); 257} 258 259static int rsci_txroom(struct uart_port *port) 260{ 261 return port->fifosize - rsci_txfill(port); 262} 263 264static void rsci_transmit_chars(struct uart_port *port) 265{ 266 unsigned int stopped = uart_tx_stopped(port); 267 struct tty_port *tport = &port->state->port; 268 u32 status, ctrl; 269 int count; 270 271 status = rsci_serial_in(port, CSR); 272 if (!(status & CSR_TDRE)) { 273 ctrl = rsci_serial_in(port, CCR0); 274 if (kfifo_is_empty(&tport->xmit_fifo)) 275 ctrl &= ~CCR0_TIE; 276 else 277 ctrl |= CCR0_TIE; 278 rsci_serial_out(port, CCR0, ctrl); 279 return; 280 } 281 282 count = rsci_txroom(port); 283 284 do { 285 unsigned char c; 286 287 if (port->x_char) { 288 c = port->x_char; 289 port->x_char = 0; 290 } else if (stopped || !kfifo_get(&tport->xmit_fifo, &c)) { 291 break; 292 } 293 294 rsci_clear_CFC(port, CFCLR_TDREC); 295 rsci_serial_out(port, TDR, c); 296 297 port->icount.tx++; 298 } while (--count > 0); 299 300 if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS) 301 uart_write_wakeup(port); 302 303 if (kfifo_is_empty(&tport->xmit_fifo)) { 304 ctrl = rsci_serial_in(port, CCR0); 305 ctrl &= ~CCR0_TIE; 306 ctrl |= CCR0_TEIE; 307 rsci_serial_out(port, CCR0, ctrl); 308 } 309} 310 311static void rsci_receive_chars(struct uart_port *port) 312{ 313 struct tty_port *tport = &port->state->port; 314 u32 rdat, status, frsr_status = 0; 315 int i, count, copied = 0; 316 unsigned char flag; 317 318 status = rsci_serial_in(port, CSR); 319 frsr_status = rsci_serial_in(port, FRSR); 320 321 if (!(status & CSR_RDRF) && !(frsr_status & FRSR_DR)) 322 return; 323 324 while (1) { 325 /* Don't copy more bytes than there is room for in the buffer */ 326 count = tty_buffer_request_room(tport, rsci_rxfill(port)); 327 328 /* If for any reason we can't copy more data, we're done! */ 329 if (count == 0) 330 break; 331 332 for (i = 0; i < count; i++) { 333 char c; 334 335 rdat = rsci_serial_in(port, RDR); 336 /* 9-bits data is not supported yet */ 337 c = rdat & RDR_RDAT_MSK; 338 339 if (uart_handle_sysrq_char(port, c)) { 340 count--; 341 i--; 342 continue; 343 } 344 345 /* Store data and status. 346 * Non FIFO mode is not supported 347 */ 348 if (rdat & RDR_FFER) { 349 flag = TTY_FRAME; 350 port->icount.frame++; 351 } else if (rdat & RDR_FPER) { 352 flag = TTY_PARITY; 353 port->icount.parity++; 354 } else { 355 flag = TTY_NORMAL; 356 } 357 358 tty_insert_flip_char(tport, c, flag); 359 } 360 361 rsci_serial_in(port, CSR); /* dummy read */ 362 rsci_clear_DRxC(port); 363 364 copied += count; 365 port->icount.rx += count; 366 } 367 368 if (copied) { 369 /* Tell the rest of the system the news. New characters! */ 370 tty_flip_buffer_push(tport); 371 } else { 372 /* TTY buffers full; read from RX reg to prevent lockup */ 373 rsci_serial_in(port, RDR); 374 rsci_serial_in(port, CSR); /* dummy read */ 375 rsci_clear_DRxC(port); 376 } 377} 378 379static void rsci_poll_put_char(struct uart_port *port, unsigned char c) 380{ 381 u32 status; 382 int ret; 383 384 ret = readl_relaxed_poll_timeout_atomic(port->membase + CSR, status, 385 (status & CSR_TDRE), 100, 386 USEC_PER_SEC); 387 if (ret != 0) { 388 dev_err(port->dev, 389 "Error while sending data in UART TX : %d\n", ret); 390 goto done; 391 } 392 rsci_serial_out(port, TDR, c); 393done: 394 rsci_clear_SCxSR(port, CFCLR_TDREC); 395} 396 397static void rsci_prepare_console_write(struct uart_port *port, u32 ctrl) 398{ 399 struct sci_port *s = to_sci_port(port); 400 u32 ctrl_temp = 401 s->params->param_bits->rxtx_enable | CCR0_TIE | 402 s->hscif_tot; 403 rsci_serial_out(port, CCR0, ctrl_temp); 404} 405 406static const char *rsci_type(struct uart_port *port) 407{ 408 return "rsci"; 409} 410 411static size_t rsci_suspend_regs_size(void) 412{ 413 return 0; 414} 415 416static void rsci_shutdown_complete(struct uart_port *port) 417{ 418 /* 419 * Stop RX and TX, disable related interrupts, keep clock source 420 */ 421 rsci_serial_out(port, CCR0, 0); 422} 423 424static const struct sci_common_regs rsci_common_regs = { 425 .status = CSR, 426 .control = CCR0, 427}; 428 429static const struct sci_port_params_bits rsci_port_param_bits = { 430 .rxtx_enable = CCR0_RE | CCR0_TE, 431 .te_clear = CCR0_TE | CCR0_TEIE, 432 .poll_sent_bits = CSR_TDRE | CSR_TEND, 433}; 434 435static const struct sci_port_params rsci_port_params = { 436 .fifosize = 16, 437 .overrun_reg = CSR, 438 .overrun_mask = CSR_ORER, 439 .sampling_rate_mask = SCI_SR(32), 440 .error_mask = RSCI_DEFAULT_ERROR_MASK, 441 .error_clear = RSCI_ERROR_CLEAR, 442 .param_bits = &rsci_port_param_bits, 443 .common_regs = &rsci_common_regs, 444}; 445 446static const struct uart_ops rsci_uart_ops = { 447 .tx_empty = rsci_tx_empty, 448 .set_mctrl = rsci_set_mctrl, 449 .get_mctrl = rsci_get_mctrl, 450 .start_tx = rsci_start_tx, 451 .stop_tx = rsci_stop_tx, 452 .stop_rx = rsci_stop_rx, 453 .startup = sci_startup, 454 .shutdown = sci_shutdown, 455 .set_termios = rsci_set_termios, 456 .pm = sci_pm, 457 .type = rsci_type, 458 .release_port = sci_release_port, 459 .request_port = sci_request_port, 460 .config_port = sci_config_port, 461 .verify_port = sci_verify_port, 462}; 463 464static const struct sci_port_ops rsci_port_ops = { 465 .read_reg = rsci_serial_in, 466 .write_reg = rsci_serial_out, 467 .clear_SCxSR = rsci_clear_SCxSR, 468 .transmit_chars = rsci_transmit_chars, 469 .receive_chars = rsci_receive_chars, 470 .poll_put_char = rsci_poll_put_char, 471 .prepare_console_write = rsci_prepare_console_write, 472 .suspend_regs_size = rsci_suspend_regs_size, 473 .set_rtrg = rsci_scif_set_rtrg, 474 .shutdown_complete = rsci_shutdown_complete, 475}; 476 477struct sci_of_data of_sci_rsci_data = { 478 .type = SCI_PORT_RSCI, 479 .ops = &rsci_port_ops, 480 .uart_ops = &rsci_uart_ops, 481 .params = &rsci_port_params, 482}; 483 484#ifdef CONFIG_SERIAL_SH_SCI_EARLYCON 485 486static int __init rsci_early_console_setup(struct earlycon_device *device, 487 const char *opt) 488{ 489 return scix_early_console_setup(device, &of_sci_rsci_data); 490} 491 492OF_EARLYCON_DECLARE(rsci, "renesas,r9a09g077-rsci", rsci_early_console_setup); 493 494#endif /* CONFIG_SERIAL_SH_SCI_EARLYCON */ 495 496MODULE_LICENSE("GPL"); 497MODULE_DESCRIPTION("RSCI serial driver");
~/
Read-only file preview.