From bbe36e29ca2ce2b3fad0343383038a9ff07dd655 Mon Sep 17 00:00:00 2001 From: Hai Pham Date: Tue, 28 Feb 2023 22:29:19 +0100 Subject: [PATCH] serial: sh: Add HSCIF support for R-Car SoC Provide the basic HSCIF support for R-Car SoC. Reviewed-by: Marek Vasut Signed-off-by: Hai Pham Signed-off-by: Marek Vasut [Marek: Fill in HSSRR offset for Gen2 and SCBRR calculation for Gen2 and Gen3] Reviewed-by: Simon Glass --- doc/device-tree-bindings/serial/sh.txt | 2 +- drivers/serial/serial_sh.c | 6 ++++++ drivers/serial/serial_sh.h | 26 ++++++++++++++++++++++---- include/dm/platform_data/serial_sh.h | 1 + 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/doc/device-tree-bindings/serial/sh.txt b/doc/device-tree-bindings/serial/sh.txt index 99634a5e70..7707a9cbe3 100644 --- a/doc/device-tree-bindings/serial/sh.txt +++ b/doc/device-tree-bindings/serial/sh.txt @@ -1,6 +1,6 @@ * Renesas SCI serial interface Required properties: -- compatible: must be "renesas,scif", "renesas,scifa" or "renesas,sci" +- compatible: must be "renesas,scif", "renesas,hscif", "renesas,scifa" or "renesas,sci" - reg: exactly one register range with length - clock: input clock frequency for the SCI unit diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c index e08bdcadc9..20cda5dbe2 100644 --- a/drivers/serial/serial_sh.c +++ b/drivers/serial/serial_sh.c @@ -57,6 +57,9 @@ static void sh_serial_init_generic(struct uart_port *port) #if defined(CONFIG_RZA1) sci_out(port, SCSPTR, 0x0003); #endif + + if (port->type == PORT_HSCIF) + sci_out(port, HSSRR, HSSRR_SRE | HSSRR_SRCYC8); } static void @@ -205,6 +208,7 @@ static const struct udevice_id sh_serial_id[] ={ {.compatible = "renesas,sci", .data = PORT_SCI}, {.compatible = "renesas,scif", .data = PORT_SCIF}, {.compatible = "renesas,scifa", .data = PORT_SCIFA}, + {.compatible = "renesas,hscif", .data = PORT_HSCIF}, {} }; @@ -257,6 +261,8 @@ U_BOOT_DRIVER(serial_sh) = { #define SCIF_BASE_PORT PORT_SCIFA #elif defined(CFG_SCI) #define SCIF_BASE_PORT PORT_SCI +#elif defined(CFG_HSCIF) + #define SCIF_BASE_PORT PORT_HSCIF #else #define SCIF_BASE_PORT PORT_SCIF #endif diff --git a/drivers/serial/serial_sh.h b/drivers/serial/serial_sh.h index 128b0776da..149ec1fe73 100644 --- a/drivers/serial/serial_sh.h +++ b/drivers/serial/serial_sh.h @@ -213,6 +213,10 @@ struct uart_port { #define SCFCR_TCRST 0x4000 #define SCFCR_MCE 0x0008 +/* HSSRR */ +#define HSSRR_SRE BIT(15) +#define HSSRR_SRCYC8 0x0007 + #define SCI_MAJOR 204 #define SCI_MINOR_START 8 @@ -242,7 +246,8 @@ struct uart_port { #define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\ static inline unsigned int sci_##name##_in(struct uart_port *port) {\ - if (port->type == PORT_SCIF || port->type == PORT_SCIFB) {\ + if (port->type == PORT_SCIF || port->type == PORT_SCIFB ||\ + port->type == PORT_HSCIF) {\ SCI_IN(scif_size, scif_offset)\ } else { /* PORT_SCI or PORT_SCIFA */\ SCI_IN(sci_size, sci_offset);\ @@ -250,7 +255,8 @@ struct uart_port { }\ static inline void sci_##name##_out(struct uart_port *port,\ unsigned int value) {\ - if (port->type == PORT_SCIF || port->type == PORT_SCIFB) {\ + if (port->type == PORT_SCIF || port->type == PORT_SCIFB ||\ + port->type == PORT_HSCIF) {\ SCI_OUT(scif_size, scif_offset, value)\ } else { /* PORT_SCI or PORT_SCIFA */\ SCI_OUT(sci_size, sci_offset, value);\ @@ -375,6 +381,7 @@ SCIF_FNS(SCFDR, 0, 0, 0x1C, 16) SCIF_FNS(SCSPTR, 0, 0, 0x20, 16) SCIF_FNS(DL, 0, 0, 0x30, 16) SCIF_FNS(CKS, 0, 0, 0x34, 16) +SCIF_FNS(HSSRR, 0, 0, 0x40, 16) /* HSCIF only */ #if defined(CFG_SCIF_A) SCIF_FNS(SCLSR, 0, 0, 0x14, 16) #else @@ -414,7 +421,9 @@ SCIF_FNS(SCSPTR, 0, 0, 0x20, 16) #endif SCIF_FNS(SCLSR, 0, 0, 0x24, 16) #endif -SCIF_FNS(DL, 0, 0, 0x0, 0) /* dummy */ +SCIF_FNS(DL, 0, 0, 0x30, 16) +SCIF_FNS(CKS, 0, 0, 0x34, 16) +SCIF_FNS(HSSRR, 0, 0, 0x40, 16) /* HSCIF only */ #endif #define sci_in(port, reg) sci_##reg##_in(port) #define sci_out(port, reg, value) sci_##reg##_out(port, value) @@ -485,11 +494,20 @@ static inline int scbrr_calc(struct uart_port *port, int bps, int clk) #define SCBRR_VALUE(bps, clk) scbrr_calc(port, bps, clk) #elif defined(CONFIG_RCAR_GEN2) #define DL_VALUE(bps, clk) (clk / bps / 16) /* External Clock */ - #if defined(CFG_SCIF_A) + #if defined(CFG_SCIF_A) || defined(CFG_HSCIF) #define SCBRR_VALUE(bps, clk) (clk / bps / 16 - 1) /* Internal Clock */ #else #define SCBRR_VALUE(bps, clk) (clk / bps / 32 - 1) /* Internal Clock */ #endif +#elif defined(CONFIG_RCAR_64) +static inline int scbrr_calc(struct uart_port *port, int bps, int clk) +{ + if (port->type == PORT_SCIF) + return (clk + 16 * bps) / (32 * bps) - 1; + else /* PORT_HSCIF */ + return clk / bps / 8 / 2 - 1; /* Internal Clock, Sampling rate = 8 */ +} +#define SCBRR_VALUE(bps, clk) scbrr_calc(port, bps, clk) #else /* Generic SH */ #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1) #endif diff --git a/include/dm/platform_data/serial_sh.h b/include/dm/platform_data/serial_sh.h index 69cd012fc5..1a20285d92 100644 --- a/include/dm/platform_data/serial_sh.h +++ b/include/dm/platform_data/serial_sh.h @@ -17,6 +17,7 @@ enum sh_serial_type { PORT_SCIF, PORT_SCIFA, PORT_SCIFB, + PORT_HSCIF, }; /* -- 2.39.5