]> Git Repo - J-u-boot.git/blobdiff - drivers/serial/serial_sh.c
pinctrl: renesas: Minimize R8A77970 V3M PFC tables
[J-u-boot.git] / drivers / serial / serial_sh.c
index e08bdcadc9c72edd7bd47a0b0ae49773b586200a..e4cc4ee426039c7d3ad6cf7be31ddee9f84c771c 100644 (file)
@@ -6,17 +6,18 @@
  * Copyright (C) 2002 - 2008  Paul Mundt
  */
 
-#include <common.h>
-#include <errno.h>
-#include <clk.h>
-#include <dm.h>
 #include <asm/global_data.h>
 #include <asm/io.h>
 #include <asm/processor.h>
-#include <serial.h>
-#include <linux/compiler.h>
+#include <clk.h>
+#include <dm.h>
+#include <dm/device_compat.h>
 #include <dm/platform_data/serial_sh.h>
+#include <errno.h>
+#include <linux/compiler.h>
 #include <linux/delay.h>
+#include <reset.h>
+#include <serial.h>
 #include "serial_sh.h"
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -57,6 +58,11 @@ static void sh_serial_init_generic(struct uart_port *port)
 #if defined(CONFIG_RZA1)
        sci_out(port, SCSPTR, 0x0003);
 #endif
+
+#if IS_ENABLED(CONFIG_RCAR_GEN2) || IS_ENABLED(CONFIG_RCAR_GEN3) || IS_ENABLED(CONFIG_RCAR_GEN4)
+       if (port->type == PORT_HSCIF)
+               sci_out(port, HSSRR, HSSRR_SRE | HSSRR_SRCYC8);
+#endif
 }
 
 static void
@@ -74,10 +80,22 @@ 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));
+       /*
+        * Most errors are cleared by resetting the relevant error bits to zero
+        * in the FSR & LSR registers. For each register, a read followed by a
+        * write is needed according to the relevant datasheets.
+        */
+       unsigned short status = sci_in(port, SCxSR);
+       sci_out(port, SCxSR, status & ~SCxSR_ERRORS(port));
        sci_in(port, SCLSR);
        sci_out(port, SCLSR, 0x00);
+
+       /*
+        * To clear framing errors, we also need to read and discard a
+        * character.
+        */
+       if ((port->type != PORT_SCI) && (status & SCIF_FER))
+               sci_in(port, SCxRDR);
 }
 
 static int serial_raw_putc(struct uart_port *port, const char c)
@@ -182,12 +200,24 @@ static int sh_serial_probe(struct udevice *dev)
 {
        struct sh_serial_plat *plat = dev_get_plat(dev);
        struct uart_port *priv = dev_get_priv(dev);
+       struct reset_ctl rst;
+       int ret;
 
        priv->membase   = (unsigned char *)plat->base;
        priv->mapbase   = plat->base;
        priv->type      = plat->type;
        priv->clk_mode  = plat->clk_mode;
 
+       /* De-assert the module reset if it is defined. */
+       ret = reset_get_by_index(dev, 0, &rst);
+       if (!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;
@@ -204,7 +234,9 @@ static const struct dm_serial_ops sh_serial_ops = {
 static const struct udevice_id sh_serial_id[] ={
        {.compatible = "renesas,sci", .data = PORT_SCI},
        {.compatible = "renesas,scif", .data = PORT_SCIF},
+       {.compatible = "renesas,scif-r9a07g044", .data = PORT_SCIFA},
        {.compatible = "renesas,scifa", .data = PORT_SCIFA},
+       {.compatible = "renesas,hscif", .data = PORT_HSCIF},
        {}
 };
 
@@ -257,6 +289,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
This page took 0.027397 seconds and 4 git commands to generate.