]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
serial: sh-sci: Add support for RZ/V2H(P) SoC
authorLad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Tue, 4 Jun 2024 17:05:13 +0000 (18:05 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 24 Jun 2024 14:09:37 +0000 (16:09 +0200)
Add serial support for RZ/V2H(P) SoC with earlycon.

The SCIF interface in the Renesas RZ/V2H(P) is similar to that available
in the RZ/G2L (R9A07G044) SoC, with the following differences:

- RZ/V2H(P) SoC has three additional interrupts: one for Tx end/Rx ready
  and two for Rx and Tx buffer full, all of which are edge-triggered.
- RZ/V2H(P) supports asynchronous mode, whereas RZ/G2L supports both
  synchronous and asynchronous modes.
- There are differences in the configuration of certain registers such
  as SCSMR, SCFCR, and SCSPTR between the two SoCs.

To handle these differences on RZ/V2H(P) SoC SCIx_RZV2H_SCIF_REGTYPE
is added.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/20240604170513.522631-6-prabhakar.mahadev-lad.rj@bp.renesas.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/sh-sci.c
include/linux/serial_sci.h

index f738980a8b2cacf663590c9c284bdb755a90a5c8..b80e9a528e17ff8b07c39d1688316dd3de1a8c87 100644 (file)
@@ -317,6 +317,37 @@ static const struct sci_port_params sci_port_params[SCIx_NR_REGTYPES] = {
                .error_clear = SCIF_ERROR_CLEAR,
        },
 
+       /*
+        * The "SCIF" that is in RZ/V2H(P) SoC is similar to one found on RZ/G2L SoC
+        * with below differences,
+        * - Break out of interrupts are different: ERI, BRI, RXI, TXI, TEI, DRI,
+        *   TEI-DRI, RXI-EDGE and TXI-EDGE.
+        * - SCSMR register does not have CM bit (BIT(7)) ie it does not support synchronous mode.
+        * - SCFCR register does not have SCFCR_MCE bit.
+        * - SCSPTR register has only bits SCSPTR_SPB2DT and SCSPTR_SPB2IO.
+        */
+       [SCIx_RZV2H_SCIF_REGTYPE] = {
+               .regs = {
+                       [SCSMR]         = { 0x00, 16 },
+                       [SCBRR]         = { 0x02,  8 },
+                       [SCSCR]         = { 0x04, 16 },
+                       [SCxTDR]        = { 0x06,  8 },
+                       [SCxSR]         = { 0x08, 16 },
+                       [SCxRDR]        = { 0x0a,  8 },
+                       [SCFCR]         = { 0x0c, 16 },
+                       [SCFDR]         = { 0x0e, 16 },
+                       [SCSPTR]        = { 0x10, 16 },
+                       [SCLSR]         = { 0x12, 16 },
+                       [SEMR]          = { 0x14, 8 },
+               },
+               .fifosize = 16,
+               .overrun_reg = SCLSR,
+               .overrun_mask = SCLSR_ORER,
+               .sampling_rate_mask = SCI_SR(32),
+               .error_mask = SCIF_DEFAULT_ERROR_MASK,
+               .error_clear = SCIF_ERROR_CLEAR,
+       },
+
        /*
         * Common SH-3 SCIF definitions.
         */
@@ -757,7 +788,7 @@ static void sci_init_pins(struct uart_port *port, unsigned int cflag)
                }
                sci_serial_out(port, SCPDR, data);
                sci_serial_out(port, SCPCR, ctrl);
-       } else if (sci_getreg(port, SCSPTR)->size) {
+       } else if (sci_getreg(port, SCSPTR)->size && s->cfg->regtype != SCIx_RZV2H_SCIF_REGTYPE) {
                u16 status = sci_serial_in(port, SCSPTR);
 
                /* RTS# is always output; and active low, unless autorts */
@@ -2124,8 +2155,9 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
 
        if (!(mctrl & TIOCM_RTS)) {
                /* Disable Auto RTS */
-               sci_serial_out(port, SCFCR,
-                              sci_serial_in(port, SCFCR) & ~SCFCR_MCE);
+               if (s->cfg->regtype != SCIx_RZV2H_SCIF_REGTYPE)
+                       sci_serial_out(port, SCFCR,
+                                      sci_serial_in(port, SCFCR) & ~SCFCR_MCE);
 
                /* Clear RTS */
                sci_set_rts(port, 0);
@@ -2137,8 +2169,9 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
                }
 
                /* Enable Auto RTS */
-               sci_serial_out(port, SCFCR,
-                              sci_serial_in(port, SCFCR) | SCFCR_MCE);
+               if (s->cfg->regtype != SCIx_RZV2H_SCIF_REGTYPE)
+                       sci_serial_out(port, SCFCR,
+                                      sci_serial_in(port, SCFCR) | SCFCR_MCE);
        } else {
                /* Set RTS */
                sci_set_rts(port, 1);
@@ -3225,6 +3258,10 @@ static const struct of_device_id of_sci_match[] __maybe_unused = {
                .compatible = "renesas,scif-r9a07g044",
                .data = SCI_OF_DATA(PORT_SCIF, SCIx_RZ_SCIFA_REGTYPE),
        },
+       {
+               .compatible = "renesas,scif-r9a09g057",
+               .data = SCI_OF_DATA(PORT_SCIF, SCIx_RZV2H_SCIF_REGTYPE),
+       },
        /* Family-specific types */
        {
                .compatible = "renesas,rcar-gen1-scif",
@@ -3533,6 +3570,13 @@ static int __init rzscifa_early_console_setup(struct earlycon_device *device,
        return early_console_setup(device, PORT_SCIF);
 }
 
+static int __init rzv2hscif_early_console_setup(struct earlycon_device *device,
+                                               const char *opt)
+{
+       port_cfg.regtype = SCIx_RZV2H_SCIF_REGTYPE;
+       return early_console_setup(device, PORT_SCIF);
+}
+
 static int __init scifa_early_console_setup(struct earlycon_device *device,
                                          const char *opt)
 {
@@ -3553,6 +3597,7 @@ OF_EARLYCON_DECLARE(sci, "renesas,sci", sci_early_console_setup);
 OF_EARLYCON_DECLARE(scif, "renesas,scif", scif_early_console_setup);
 OF_EARLYCON_DECLARE(scif, "renesas,scif-r7s9210", rzscifa_early_console_setup);
 OF_EARLYCON_DECLARE(scif, "renesas,scif-r9a07g044", rzscifa_early_console_setup);
+OF_EARLYCON_DECLARE(scif, "renesas,scif-r9a09g057", rzv2hscif_early_console_setup);
 OF_EARLYCON_DECLARE(scifa, "renesas,scifa", scifa_early_console_setup);
 OF_EARLYCON_DECLARE(scifb, "renesas,scifb", scifb_early_console_setup);
 OF_EARLYCON_DECLARE(hscif, "renesas,hscif", hscif_early_console_setup);
index 1c89611e0e0634aec1f64c62d99637f4ee709bc0..0f2f50b8d28e27434366ce2301ecc2e8cc682803 100644 (file)
@@ -37,6 +37,7 @@ enum {
        SCIx_SH7705_SCIF_REGTYPE,
        SCIx_HSCIF_REGTYPE,
        SCIx_RZ_SCIFA_REGTYPE,
+       SCIx_RZV2H_SCIF_REGTYPE,
 
        SCIx_NR_REGTYPES,
 };