File Index
Files and directories
Sign in
FILE

rsci.c

File preview with syntax highlighting.

linux-6.19.14/drivers/tty/serial/rsci.c 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.