[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251027154615.115759-17-biju.das.jz@bp.renesas.com>
Date: Mon, 27 Oct 2025 15:46:03 +0000
From: Biju Das <biju.das.jz@...renesas.com>
To: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Jiri Slaby <jirislaby@...nel.org>
Cc: Biju Das <biju.das.jz@...renesas.com>,
Geert Uytterhoeven <geert+renesas@...der.be>,
Lad Prabhakar <prabhakar.mahadev-lad.rj@...renesas.com>,
Wolfram Sang <wsa+renesas@...g-engineering.com>,
Claudiu Beznea <claudiu.beznea.uj@...renesas.com>,
Nam Cao <namcao@...utronix.de>,
linux-kernel@...r.kernel.org,
linux-serial@...r.kernel.org,
Biju Das <biju.das.au@...il.com>,
linux-renesas-soc@...r.kernel.org
Subject: [PATCH 16/19] serial: sh-sci: Add support for RZ/G3E RSCI SCI
Add support for RZ/G3E RSCI SCI(a.k.a non FIFO mode).
Signed-off-by: Biju Das <biju.das.jz@...renesas.com>
---
drivers/tty/serial/rsci.c | 137 ++++++++++++++++++++++++++----------
drivers/tty/serial/rsci.h | 1 +
drivers/tty/serial/sh-sci.c | 4 ++
3 files changed, 103 insertions(+), 39 deletions(-)
diff --git a/drivers/tty/serial/rsci.c b/drivers/tty/serial/rsci.c
index 4c74251dc171..5901f9e55101 100644
--- a/drivers/tty/serial/rsci.c
+++ b/drivers/tty/serial/rsci.c
@@ -161,8 +161,12 @@ static void rsci_serial_out(struct uart_port *p, int offset, int value)
static void rsci_clear_DRxC(struct uart_port *port)
{
+ struct sci_port *s = to_sci_port(port);
+
rsci_serial_out(port, CFCLR, CFCLR_RDRFC);
- rsci_serial_out(port, FFCLR, FFCLR_DRC);
+
+ if (s->type != RSCI_PORT_SCI)
+ rsci_serial_out(port, FFCLR, FFCLR_DRC);
}
static void rsci_clear_SCxSR(struct uart_port *port, unsigned int mask)
@@ -231,7 +235,6 @@ static void rsci_set_termios(struct uart_port *port, struct ktermios *termios,
unsigned long max_freq = 0;
unsigned int baud, i;
unsigned long flags;
- unsigned int ctrl;
int best_clk = -1;
if ((termios->c_cflag & CSIZE) == CS7) {
@@ -292,7 +295,10 @@ static void rsci_set_termios(struct uart_port *port, struct ktermios *termios,
rsci_serial_out(port, CCR0, ccr0_val);
- ccr3_val |= CCR3_FM;
+ if (s->type == RSCI_PORT_SCI)
+ ccr3_val |= CCR3_RXDESEL;
+ else
+ ccr3_val |= CCR3_FM;
rsci_serial_out(port, CCR3, ccr3_val);
@@ -303,13 +309,15 @@ static void rsci_set_termios(struct uart_port *port, struct ktermios *termios,
rsci_serial_out(port, CCR4, ccr4_val);
- ctrl = rsci_serial_in(port, FCR);
+ if (s->type != RSCI_PORT_SCI) {
+ unsigned int ctrl = rsci_serial_in(port, FCR);
- ctrl |= (FCR_RFRST | FCR_TFRST);
- rsci_serial_out(port, FCR, ctrl);
+ ctrl |= (FCR_RFRST | FCR_TFRST);
+ rsci_serial_out(port, FCR, ctrl);
- if (s->rx_trigger > 1)
- rsci_scif_set_rtrg(port, s->rx_trigger);
+ if (s->rx_trigger > 1)
+ rsci_scif_set_rtrg(port, s->rx_trigger);
+ }
port->status &= ~UPSTAT_AUTOCTS;
s->autorts = false;
@@ -322,7 +330,8 @@ static void rsci_set_termios(struct uart_port *port, struct ktermios *termios,
rsci_init_pins(port, termios->c_cflag);
rsci_serial_out(port, CFCLR, CFCLR_CLRFLAG);
- rsci_serial_out(port, FFCLR, FFCLR_DRC);
+ if (s->type != RSCI_PORT_SCI)
+ rsci_serial_out(port, FFCLR, FFCLR_DRC);
ccr0_val |= CCR0_RE;
rsci_serial_out(port, CCR0, ccr0_val);
@@ -339,12 +348,23 @@ static void rsci_set_termios(struct uart_port *port, struct ktermios *termios,
static int rsci_txfill(struct uart_port *port)
{
- return rsci_serial_in(port, FTSR);
+ struct sci_port *s = to_sci_port(port);
+
+ if (s->type == RSCI_PORT_SCI)
+ return !(rsci_serial_in(port, CSR) & CSR_TDRE);
+ else
+ return rsci_serial_in(port, FTSR);
}
static int rsci_rxfill(struct uart_port *port)
{
- u32 val = rsci_serial_in(port, FRSR);
+ struct sci_port *s = to_sci_port(port);
+ u32 val;
+
+ if (s->type == RSCI_PORT_SCI)
+ return (rsci_serial_in(port, CSR) & CSR_RDRF) != 0;
+
+ val = rsci_serial_in(port, FRSR);
return FIELD_GET(FRSR_R5_0, val);
}
@@ -359,7 +379,9 @@ static unsigned int rsci_tx_empty(struct uart_port *port)
static void rsci_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
- if (mctrl & TIOCM_LOOP) {
+ struct sci_port *s = to_sci_port(port);
+
+ if ((mctrl & TIOCM_LOOP) && s->type != RSCI_PORT_SCI) {
/* Standard loopback mode */
rsci_serial_out(port, CCR1, rsci_serial_in(port, CCR1) | CCR1_SPLP);
}
@@ -478,12 +500,13 @@ static void rsci_transmit_chars(struct uart_port *port)
static void rsci_receive_chars(struct uart_port *port)
{
struct tty_port *tport = &port->state->port;
+ struct sci_port *s = to_sci_port(port);
u32 rdat, status, frsr_status = 0;
int i, count, copied = 0;
unsigned char flag;
status = rsci_serial_in(port, CSR);
- frsr_status = rsci_serial_in(port, FRSR);
+ frsr_status = (s->type == RSCI_PORT_SCI) ? 0 : rsci_serial_in(port, FRSR);
if (!(status & CSR_RDRF) && !(frsr_status & FRSR_DR))
return;
@@ -496,33 +519,42 @@ static void rsci_receive_chars(struct uart_port *port)
if (count == 0)
break;
- for (i = 0; i < count; i++) {
- char c;
-
- rdat = rsci_serial_in(port, RDR);
- /* 9-bits data is not supported yet */
- c = rdat & RDR_RDAT_MSK;
-
- if (uart_handle_sysrq_char(port, c)) {
- count--;
- i--;
- continue;
- }
-
- /* Store data and status.
- * Non FIFO mode is not supported
- */
- if (rdat & RDR_FFER) {
- flag = TTY_FRAME;
- port->icount.frame++;
- } else if (rdat & RDR_FPER) {
- flag = TTY_PARITY;
- port->icount.parity++;
- } else {
- flag = TTY_NORMAL;
+ if (s->type == RSCI_PORT_SCI) {
+ char c = rsci_serial_in(port, RDR) & RDR_RDAT_MSK;
+
+ if (uart_handle_sysrq_char(port, c))
+ count = 0;
+ else
+ tty_insert_flip_char(tport, c, TTY_NORMAL);
+ } else {
+ for (i = 0; i < count; i++) {
+ char c;
+
+ rdat = rsci_serial_in(port, RDR);
+ /* 9-bits data is not supported yet */
+ c = rdat & RDR_RDAT_MSK;
+
+ if (uart_handle_sysrq_char(port, c)) {
+ count--;
+ i--;
+ continue;
+ }
+
+ /* Store data and status.
+ * Non FIFO mode is not supported
+ */
+ if (rdat & RDR_FFER) {
+ flag = TTY_FRAME;
+ port->icount.frame++;
+ } else if (rdat & RDR_FPER) {
+ flag = TTY_PARITY;
+ port->icount.parity++;
+ } else {
+ flag = TTY_NORMAL;
+ }
+
+ tty_insert_flip_char(tport, c, flag);
}
-
- tty_insert_flip_char(tport, c, flag);
}
rsci_serial_in(port, CSR); /* dummy read */
@@ -606,6 +638,8 @@ static const char *rsci_type(struct uart_port *port)
struct sci_port *s = to_sci_port(port);
switch (s->type) {
+ case RSCI_PORT_SCI:
+ return "sci";
case RSCI_PORT_SCIF:
return "scif";
}
@@ -649,6 +683,17 @@ static const struct sci_port_params rsci_port_params = {
.common_regs = &rsci_common_regs,
};
+static const struct sci_port_params rsci_rzg3e_sci_port_params = {
+ .fifosize = 1,
+ .overrun_reg = CSR,
+ .overrun_mask = CSR_ORER,
+ .sampling_rate_mask = SCI_SR(32),
+ .error_mask = RSCI_DEFAULT_ERROR_MASK,
+ .error_clear = RSCI_ERROR_CLEAR,
+ .param_bits = &rsci_port_param_bits,
+ .common_regs = &rsci_common_regs,
+};
+
static const struct sci_port_params rsci_rzg3e_scif_port_params = {
.fifosize = 32,
.overrun_reg = CSR,
@@ -700,6 +745,13 @@ struct sci_of_data of_sci_rsci_data = {
.params = &rsci_port_params,
};
+struct sci_of_data of_rsci_sci_data = {
+ .type = RSCI_PORT_SCI,
+ .ops = &rsci_port_ops,
+ .uart_ops = &rsci_uart_ops,
+ .params = &rsci_rzg3e_sci_port_params,
+};
+
struct sci_of_data of_rsci_scif_data = {
.type = RSCI_PORT_SCIF,
.ops = &rsci_port_ops,
@@ -715,12 +767,19 @@ static int __init rsci_early_console_setup(struct earlycon_device *device,
return scix_early_console_setup(device, &of_sci_rsci_data);
}
+static int __init rsci_rzg3e_sci_early_console_setup(struct earlycon_device *device,
+ const char *opt)
+{
+ return scix_early_console_setup(device, &of_rsci_sci_data);
+}
+
static int __init rsci_rzg3e_scif_early_console_setup(struct earlycon_device *device,
const char *opt)
{
return scix_early_console_setup(device, &of_rsci_scif_data);
}
+OF_EARLYCON_DECLARE(rsci, "renesas,r9a09g047-rsci", rsci_rzg3e_sci_early_console_setup);
OF_EARLYCON_DECLARE(rsci, "renesas,r9a09g047-rscif", rsci_rzg3e_scif_early_console_setup);
OF_EARLYCON_DECLARE(rsci, "renesas,r9a09g077-rsci", rsci_early_console_setup);
diff --git a/drivers/tty/serial/rsci.h b/drivers/tty/serial/rsci.h
index ba255f58c088..df7a7edad7d4 100644
--- a/drivers/tty/serial/rsci.h
+++ b/drivers/tty/serial/rsci.h
@@ -6,6 +6,7 @@
#include "sh-sci-common.h"
extern struct sci_of_data of_sci_rsci_data;
+extern struct sci_of_data of_rsci_sci_data;
extern struct sci_of_data of_rsci_scif_data;
#endif /* __RSCI_H__ */
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 379528c6725a..43c3e90f0a53 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -3498,6 +3498,10 @@ static const struct of_device_id of_sci_match[] __maybe_unused = {
.data = &of_sci_scif_rzv2h,
},
#ifdef CONFIG_SERIAL_RSCI
+ {
+ .compatible = "renesas,r9a09g047-rsci",
+ .data = &of_rsci_sci_data,
+ },
{
.compatible = "renesas,r9a09g047-rscif",
.data = &of_rsci_scif_data,
--
2.43.0
Powered by blists - more mailing lists