
Extend the existing driver to support the SCIF serial ports on the Renesas RZ/G2L (R9A07G044) SoC. This also requires us to ensure that the relevant reset signal is de-asserted before we try to talk to the SCIF module.
Signed-off-by: Paul Barker paul.barker.ct@bp.renesas.com Reviewed-by: Biju Das biju.das.jz@bp.renesas.com Reviewed-by: Lad Prabhakar prabhakar.mahadev-lad.rj@bp.renesas.com --- arch/arm/mach-rmobile/Kconfig | 1 + drivers/serial/serial_sh.c | 32 ++++++++++++++++++++++++++++++-- drivers/serial/serial_sh.h | 19 ++++++++++++++++++- 3 files changed, 49 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-rmobile/Kconfig b/arch/arm/mach-rmobile/Kconfig index 973e84fcf7ba..0ab22356aee5 100644 --- a/arch/arm/mach-rmobile/Kconfig +++ b/arch/arm/mach-rmobile/Kconfig @@ -77,6 +77,7 @@ config RZG2L imply RENESAS_SDHI imply CLK_RZG2L imply PINCTRL_RZG2L + imply SCIF_CONSOLE help Enable support for the Renesas RZ/G2L family of SoCs, including the the RZ/G2L itself (based on the R9A07G044 SoC). diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c index 5e543dbf3d58..a2e9a57137a6 100644 --- a/drivers/serial/serial_sh.c +++ b/drivers/serial/serial_sh.c @@ -17,6 +17,8 @@ #include <linux/compiler.h> #include <dm/platform_data/serial_sh.h> #include <linux/delay.h> +#include <dm/device_compat.h> +#include <reset.h> #include "serial_sh.h"
DECLARE_GLOBAL_DATA_PTR; @@ -79,8 +81,16 @@ sh_serial_setbrg_generic(struct uart_port *port, int clk, int baudrate)
static void handle_error(struct uart_port *port) { - sci_in(port, SCxSR); - sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); + /* The RZ/G2L datasheet says that error conditions are cleared by + * resetting the error bits in the FSR register to zero. + */ + if (IS_ENABLED(CONFIG_RZG2L)) { + unsigned short status = sci_in(port, SCxSR); + sci_out(port, SCxSR, status & ~SCIF_ERRORS); + } else { + sci_in(port, SCxSR); + sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port)); + } sci_in(port, SCLSR); sci_out(port, SCLSR, 0x00); } @@ -193,6 +203,23 @@ static int sh_serial_probe(struct udevice *dev) priv->type = plat->type; priv->clk_mode = plat->clk_mode;
+ if (IS_ENABLED(CONFIG_RZG2L)) { + struct reset_ctl rst; + int ret; + + ret = reset_get_by_index(dev, 0, &rst); + if (ret < 0) { + dev_err(dev, "failed to get reset line\n"); + return ret; + } + + ret = reset_deassert(&rst); + if (ret < 0) { + dev_err(dev, "failed to de-assert reset line\n"); + return ret; + } + } + sh_serial_init_generic(priv);
return 0; @@ -211,6 +238,7 @@ static const struct udevice_id sh_serial_id[] ={ {.compatible = "renesas,scif", .data = PORT_SCIF}, {.compatible = "renesas,scifa", .data = PORT_SCIFA}, {.compatible = "renesas,hscif", .data = PORT_HSCIF}, + {.compatible = "renesas,scif-r9a07g044", .data = PORT_SCIFA}, {} };
diff --git a/drivers/serial/serial_sh.h b/drivers/serial/serial_sh.h index 149ec1fe7397..58c2d22bc757 100644 --- a/drivers/serial/serial_sh.h +++ b/drivers/serial/serial_sh.h @@ -90,7 +90,7 @@ struct uart_port { # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ # define SCIF_ORER 0x0001 /* overrun error bit */ #elif defined(CONFIG_RCAR_GEN2) || defined(CONFIG_RCAR_64) || \ - defined(CONFIG_R7S72100) + defined(CONFIG_R7S72100) || defined(CONFIG_RZG2L) # if defined(CFG_SCIF_A) # define SCIF_ORER 0x0200 # else @@ -312,6 +312,9 @@ static inline void sci_##name##_out(struct uart_port *port,\ sh4_scif_offset, sh4_scif_size) #define SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) \ CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) +#elif defined(CONFIG_RZG2L) +#define SCIF_FNS(reg_name, reg_offset, reg_size) \ + CPU_SCIF_FNS(reg_name, reg_offset, reg_size) #else #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size,\ sh4_sci_offset, sh4_sci_size, \ @@ -387,6 +390,20 @@ SCIF_FNS(SCLSR, 0, 0, 0x14, 16) #else SCIF_FNS(SCLSR, 0, 0, 0x24, 16) #endif +#elif defined(CONFIG_RZG2L) +SCIF_FNS(SCSMR, 0x00, 16) +SCIF_FNS(SCBRR, 0x02, 8) +SCIF_FNS(SCSCR, 0x04, 16) +SCIF_FNS(SCxTDR, 0x06, 8) +SCIF_FNS(SCxSR, 0x08, 16) +SCIF_FNS(SCxRDR, 0x0A, 8) +SCIF_FNS(SCFCR, 0x0C, 16) +SCIF_FNS(SCFDR, 0x0E, 16) +SCIF_FNS(SCSPTR, 0x10, 16) +SCIF_FNS(SCLSR, 0x12, 16) +SCIF_FNS(SCSEMR, 0x14, 8) +SCIF_FNS(SCxTCR, 0x16, 16) +SCIF_FNS(DL, 0x00, 0) #else /* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 SCI/H8*/ /* name off sz off sz off sz off sz off sz*/