[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 1/6] xen/arm: platforms: Add earlyprintk and serial support for Tegra boards.



From: Chris Patterson <pattersonc@xxxxxxxxxxxx>

Tegra boards feature a NS16550-compatible serial mapped into the MMIO
space. Add support for its use both as a full-featured serial port and
as an earlyprintk driver.

This patch adds a quirk for platforms, such as the Tegra, which require
require the NS16550 Rx timeout interrupt to be enabled for receive to
function properly. The same quirk is applied in the eqvuialent Linux
driver [1].

This quirk is selectively enabled for the platform using a new "hw_quirks"
member with a corresponding set of bitmasks.  The existing quirk,
dw_usr_bsy was updated to match this approach as well.

[1] 
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=4539c24fe4f92c09ee668ef959d3e8180df619b9

Signed-off-by: Kyle Temkin <temkink@xxxxxxxxxxxx>
Signed-off-by: Chris Patterson <pattersonc@xxxxxxxxxxxx>
---

changes from rfc:
- use bitmask for quirks in ns1660, including dw_usr_bsy

---
 xen/arch/arm/Rules.mk       |  1 +
 xen/drivers/char/ns16550.c  | 28 ++++++++++++++++++++++++----
 xen/include/xen/8250-uart.h |  1 +
 3 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/xen/arch/arm/Rules.mk b/xen/arch/arm/Rules.mk
index 569a0ba..43b32d0 100644
--- a/xen/arch/arm/Rules.mk
+++ b/xen/arch/arm/Rules.mk
@@ -44,6 +44,7 @@ EARLY_PRINTK_vexpress       := pl011,0x1c090000
 EARLY_PRINTK_xgene-mcdivitt := 8250,0x1c021000,2
 EARLY_PRINTK_xgene-storm    := 8250,0x1c020000,2
 EARLY_PRINTK_zynqmp         := cadence,0xff000000
+EARLY_PRINTK_tegra          := 8250,0x70006000,2
 
 ifneq ($(EARLY_PRINTK_$(CONFIG_EARLY_PRINTK)),)
 EARLY_PRINTK_CFG := $(subst $(comma), ,$(EARLY_PRINTK_$(CONFIG_EARLY_PRINTK)))
diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
index e4de3b4..1b75e89 100644
--- a/xen/drivers/char/ns16550.c
+++ b/xen/drivers/char/ns16550.c
@@ -62,7 +62,7 @@ static struct ns16550 {
     struct timer resume_timer;
     unsigned int timeout_ms;
     bool_t intr_works;
-    bool_t dw_usr_bsy;
+    uint8_t hw_quirks;
 #ifdef CONFIG_HAS_PCI
     /* PCI card parameters. */
     bool_t pb_bdf_enable;   /* if =1, pb-bdf effective, port behind bridge */
@@ -414,6 +414,10 @@ static const struct ns16550_config __initconst 
uart_config[] =
 };
 #endif
 
+/* Various hardware quirks/features that may be need be enabled per device */
+#define HW_QUIRKS_DW_USR_BSY         (1<<0)
+#define HW_QUIRKS_USE_RTOIE          (1<<1)
+
 static void ns16550_delayed_resume(void *data);
 
 static u8 ns_read_reg(struct ns16550 *uart, unsigned int reg)
@@ -578,7 +582,7 @@ static void ns16550_setup_preirq(struct ns16550 *uart)
     /* No interrupts. */
     ns_write_reg(uart, UART_IER, 0);
 
-    if ( uart->dw_usr_bsy &&
+    if ( (uart->hw_quirks & HW_QUIRKS_DW_USR_BSY) &&
          (ns_read_reg(uart, UART_IIR) & UART_IIR_BSY) == UART_IIR_BSY )
     {
         /* DesignWare 8250 detects if LCR is written while the UART is
@@ -651,12 +655,23 @@ static void ns16550_setup_postirq(struct ns16550 *uart)
 {
     if ( uart->irq > 0 )
     {
+        u8 ier_value = 0;
+
         /* Master interrupt enable; also keep DTR/RTS asserted. */
         ns_write_reg(uart,
                      UART_MCR, UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS);
 
         /* Enable receive interrupts. */
-        ns_write_reg(uart, UART_IER, UART_IER_ERDAI);
+        ier_value = UART_IER_ERDAI;
+
+        /*
+         * If we're on a platform that needs Rx timeouts enabled, also
+         * set Rx TimeOut Interrupt Enable (RTOIE).
+         */
+        if ( uart->hw_quirks & HW_QUIRKS_USE_RTOIE )
+          ier_value |= UART_IER_RTOIE;
+
+        ns_write_reg(uart, UART_IER, ier_value);
     }
 
     if ( uart->irq >= 0 )
@@ -1271,7 +1286,11 @@ static int __init ns16550_uart_dt_init(struct 
dt_device_node *dev,
         return -EINVAL;
     uart->irq = res;
 
-    uart->dw_usr_bsy = dt_device_is_compatible(dev, "snps,dw-apb-uart");
+    if ( dt_device_is_compatible(dev, "snps,dw-apb-uart") )
+        uart->hw_quirks |= HW_QUIRKS_DW_USR_BSY;
+
+    if ( dt_device_is_compatible(dev, "nvidia,tegra20-uart") )
+        uart->hw_quirks |= HW_QUIRKS_USE_RTOIE;
 
     uart->vuart.base_addr = uart->io_base;
     uart->vuart.size = uart->io_size;
@@ -1292,6 +1311,7 @@ static const struct dt_device_match ns16550_dt_match[] 
__initconst =
     DT_MATCH_COMPATIBLE("ns16550"),
     DT_MATCH_COMPATIBLE("ns16550a"),
     DT_MATCH_COMPATIBLE("snps,dw-apb-uart"),
+    DT_MATCH_COMPATIBLE("nvidia,tegra20-uart"),
     { /* sentinel */ },
 };
 
diff --git a/xen/include/xen/8250-uart.h b/xen/include/xen/8250-uart.h
index c6b62c8..2ad0ee6 100644
--- a/xen/include/xen/8250-uart.h
+++ b/xen/include/xen/8250-uart.h
@@ -41,6 +41,7 @@
 #define UART_IER_ETHREI   0x02    /* tx reg. empty        */
 #define UART_IER_ELSI     0x04    /* rx line status       */
 #define UART_IER_EMSI     0x08    /* MODEM status         */
+#define UART_IER_RTOIE    0x10    /* rx timeout           */
 
 /* Interrupt Identificatiegister */
 #define UART_IIR_NOINT    0x01    /* no interrupt pending */
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.