2014-12-24 07:12:21

by Vineet Gupta

[permalink] [raw]
Subject: [PATCH 0/3] Early 8250 fixlets

Hi,

This series addresses some of the issues seen on early 8250 uart when
working with ARC SDP platform.

Thx,
-Vineet

Vineet Gupta (3):
serial: 8250_early: optimize early 8250 uart
serial: 8250_early: prepare for dynamic BASE_BAUD
ARC: runtime determine BASE_BAUD per machine

arch/arc/include/asm/serial.h | 24 ++++--------------------
arch/arc/kernel/devtree.c | 24 ++++++++++++++++++++++++
drivers/tty/serial/8250/8250_early.c | 7 +++++--
drivers/tty/serial/earlycon.c | 13 +++++++++++--
4 files changed, 44 insertions(+), 24 deletions(-)

--
1.8.3.2


2014-12-24 07:12:30

by Vineet Gupta

[permalink] [raw]
Subject: [PATCH 1/3] serial: 8250_early: optimize early 8250 uart

In early 8250, IER is already zero so no point in writing this - twice
per char.

This helped improve the SystemC model based ARC OSCI platform

Signed-off-by: Vineet Gupta <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Jiri Slaby <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: Rob Herring <[email protected]>
---
drivers/tty/serial/8250/8250_early.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_early.c b/drivers/tty/serial/8250/8250_early.c
index 4858b8a99d3b..ce2a8abd1f54 100644
--- a/drivers/tty/serial/8250/8250_early.c
+++ b/drivers/tty/serial/8250/8250_early.c
@@ -95,13 +95,16 @@ static void __init early_serial8250_write(struct console *console,

/* Save the IER and disable interrupts */
ier = serial8250_early_in(port, UART_IER);
- serial8250_early_out(port, UART_IER, 0);
+ if (ier)
+ serial8250_early_out(port, UART_IER, 0);

uart_console_write(port, s, count, serial_putc);

/* Wait for transmitter to become empty and restore the IER */
wait_for_xmitr(port);
- serial8250_early_out(port, UART_IER, ier);
+
+ if (ier)
+ serial8250_early_out(port, UART_IER, ier);
}

static unsigned int __init probe_baud(struct uart_port *port)
--
1.8.3.2

2014-12-24 07:12:35

by Vineet Gupta

[permalink] [raw]
Subject: [PATCH 2/3] serial: 8250_early: prepare for dynamic BASE_BAUD

BASE_BAUD is pain in neck for multi-platform support as it hard codes at
build time the clk value for early uart.

Mitigate this by allowing arches/platforms to provide their own version
which can do dynamic setup based on DT values etc (see next patch for
usage)

This was needed for ARC SDP platforms based on 2 different FPGA flows, each
with a different UART clk value.

Signed-off-by: Vineet Gupta <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Jiri Slaby <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: Rob Herring <[email protected]>
Cc: Arnd Bergmann <[email protected]>
---
drivers/tty/serial/earlycon.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c
index 64fe25a4285c..bfd3537739e0 100644
--- a/drivers/tty/serial/earlycon.c
+++ b/drivers/tty/serial/earlycon.c
@@ -54,6 +54,15 @@ static void __iomem * __init earlycon_map(unsigned long paddr, size_t size)
return base;
}

+unsigned int __weak __init earlycon_base_baud(char *options)
+{
+#ifdef BASE_BAUD
+ return BASE_BAUD;
+#else
+ return 1843200/16; /* x86 early console */
+#endif
+}
+
static int __init parse_options(struct earlycon_device *device,
char *options)
{
@@ -87,7 +96,7 @@ static int __init parse_options(struct earlycon_device *device,
return -EINVAL;
}

- port->uartclk = BASE_BAUD * 16;
+ port->uartclk = earlycon_base_baud(options) * 16;

options = strchr(options, ',');
if (options) {
@@ -156,7 +165,7 @@ int __init of_setup_earlycon(unsigned long addr,

port->iotype = UPIO_MEM;
port->mapbase = addr;
- port->uartclk = BASE_BAUD * 16;
+ port->uartclk = earlycon_base_baud(NULL) * 16;
port->membase = earlycon_map(addr, SZ_4K);

early_console_dev.con->data = &early_console_dev;
--
1.8.3.2

2014-12-24 07:12:53

by Vineet Gupta

[permalink] [raw]
Subject: [PATCH 3/3] ARC: runtime determine BASE_BAUD per machine

Signed-off-by: Vineet Gupta <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Jiri Slaby <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: Rob Herring <[email protected]>
Cc: Arnd Bergmann <[email protected]>
---
arch/arc/include/asm/serial.h | 24 ++++--------------------
arch/arc/kernel/devtree.c | 24 ++++++++++++++++++++++++
2 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/arch/arc/include/asm/serial.h b/arch/arc/include/asm/serial.h
index 602b0970a764..a8c0b8743709 100644
--- a/arch/arc/include/asm/serial.h
+++ b/arch/arc/include/asm/serial.h
@@ -10,26 +10,10 @@
#define _ASM_ARC_SERIAL_H

/*
- * early-8250 requires BASE_BAUD to be defined and includes this header.
- * We put in a typical value:
- * (core clk / 16) - i.e. UART samples 16 times per sec.
- * Athough in multi-platform-image this might not work, specially if the
- * clk driving the UART is different.
- * We can't use DeviceTree as this is typically for early serial.
+ * 8250_early (now earlycon) include this hdr and expect BASE_BAUD definition
+ * for setting up uartclk.
+ * Now that is done via arch provided earlycon_base_baud() which can use FDT
+ * provided info as well to provide uartclk based on DT in use.
*/

-#include <asm/clk.h>
-
-#define BASE_BAUD (arc_get_core_freq() / 16)
-
-/*
- * This is definitely going to break early 8250 consoles on multi-platform
- * images but hey, it won't add any code complexity for a debug feature of
- * one broken driver.
- */
-#ifdef CONFIG_ARC_PLAT_TB10X
-#undef BASE_BAUD
-#define BASE_BAUD (arc_get_core_freq() / 16 / 3)
-#endif
-
#endif /* _ASM_ARC_SERIAL_H */
diff --git a/arch/arc/kernel/devtree.c b/arch/arc/kernel/devtree.c
index fffdb5e41b20..8adc5958982f 100644
--- a/arch/arc/kernel/devtree.c
+++ b/arch/arc/kernel/devtree.c
@@ -17,6 +17,28 @@
#include <asm/clk.h>
#include <asm/mach_desc.h>

+#ifdef CONFIG_SERIAL_8250_CONSOLE
+
+static unsigned int arc_base_baud;
+
+unsigned int __init serial8250_early_base_baud(char *options)
+{
+ return arc_base_baud/16;
+}
+
+static void __init arc_set_early_base_baud(unsigned long dt_root)
+{
+ unsigned int core_clk = arc_get_core_freq();
+
+ if (of_flat_dt_is_compatible(dt_root, "abilis,arc-tb10x"))
+ arc_base_baud = core_clk/3;
+ else
+ arc_base_baud = core_clk;
+}
+#else
+#define arc_set_early_base_baud(dt_root)
+#endif
+
static const void * __init arch_get_next_mach(const char *const **match)
{
static const struct machine_desc *mdesc = __arch_info_begin;
@@ -56,5 +78,7 @@ const struct machine_desc * __init setup_machine_fdt(void *dt)
if (clk)
arc_set_core_freq(of_read_ulong(clk, len/4));

+ arc_set_early_base_baud(dt_root);
+
return mdesc;
}
--
1.8.3.2