nios2: convert altera_jtag_uart to driver model
authorThomas Chou <thomas@wytron.com.tw>
Thu, 22 Oct 2015 23:36:37 +0000 (07:36 +0800)
committerThomas Chou <thomas@wytron.com.tw>
Thu, 22 Oct 2015 23:36:37 +0000 (07:36 +0800)
Convert altera_jtag_uart to driver model.

Signed-off-by: Thomas Chou <thomas@wytron.com.tw>
Acked-by: Marek Vasut <marex@denx.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
arch/nios2/dts/3c120_devboard.dts
configs/nios2-generic_defconfig
doc/device-tree-bindings/serial/altera_jtaguart.txt [new file with mode: 0644]
drivers/serial/Kconfig
drivers/serial/altera_jtag_uart.c
include/configs/nios2-generic.h

index 02524ab..3d76ec4 100644 (file)
 
        chosen {
                bootargs = "debug console=ttyJ0,115200";
+               stdout-path = &jtag_uart;
        };
 };
index 9c1bec5..9dc6a72 100644 (file)
@@ -1,4 +1,5 @@
 CONFIG_NIOS2=y
+CONFIG_DM_SERIAL=y
 CONFIG_TARGET_NIOS2_GENERIC=y
 CONFIG_DEFAULT_DEVICE_TREE="3c120_devboard"
 CONFIG_HUSH_PARSER=y
@@ -14,3 +15,5 @@ CONFIG_CMD_PING=y
 CONFIG_OF_CONTROL=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
+CONFIG_ALTERA_JTAG_UART=y
+CONFIG_ALTERA_JTAG_UART_BYPASS=y
diff --git a/doc/device-tree-bindings/serial/altera_jtaguart.txt b/doc/device-tree-bindings/serial/altera_jtaguart.txt
new file mode 100644 (file)
index 0000000..97c7062
--- /dev/null
@@ -0,0 +1,4 @@
+Altera JTAG UART
+
+Required properties:
+- compatible : should be "altr,juart-1.0"
index ac5920a..85e6764 100644 (file)
@@ -54,6 +54,13 @@ choice
        prompt "Select which UART will provide the debug UART"
        depends on DEBUG_UART
 
+config DEBUG_UART_ALTERA_JTAGUART
+       bool "Altera JTAG UART"
+       help
+         Select this to enable a debug UART using the altera_jtag_uart driver.
+         You will need to provide parameters to make this work. The driver will
+         be available until the real driver model serial is running.
+
 config DEBUG_UART_NS16550
        bool "ns16550"
        help
@@ -130,6 +137,25 @@ config DEBUG_UART_ANNOUNCE
          debug_uart_init()). This can be useful just as a check that
          everything is working.
 
+config ALTERA_JTAG_UART
+       bool "Altera JTAG UART support"
+       depends on DM_SERIAL
+       help
+         Select this to enable an JTAG UART for Altera devices.The JTAG UART
+         core implements a method to communicate serial character streams
+         between a host PC and a Qsys system on an Altera FPGA. Please find
+         details on the "Embedded Peripherals IP User Guide" of Altera.
+
+config ALTERA_JTAG_UART_BYPASS
+       bool "Bypass output when no connection"
+       depends on ALTERA_JTAG_UART
+       help
+         Bypass console output and keep going even if there is no JTAG
+         terminal connection with the host. The console output will resume
+         once the JTAG terminal is connected. Without the bypass, the console
+         output will wait forever until a JTAG terminal is connected. If you
+         not are sure, say Y.
+
 config ROCKCHIP_SERIAL
        bool "Rockchip on-chip UART support"
        depends on ARCH_ROCKCHIP && DM_SERIAL
index 9a81402..39d4a4e 100644 (file)
  */
 
 #include <common.h>
-#include <watchdog.h>
+#include <dm.h>
+#include <errno.h>
 #include <asm/io.h>
 #include <linux/compiler.h>
 #include <serial.h>
 
-typedef volatile struct {
-       unsigned        data;                   /* Data register */
-       unsigned        control;                /* Control register */
-} nios_jtag_t;
+struct altera_jtaguart_regs {
+       u32     data;                   /* Data register */
+       u32     control;                /* Control register */
+};
+
+struct altera_jtaguart_platdata {
+       struct altera_jtaguart_regs *regs;
+};
 
 /* data register */
-#define NIOS_JTAG_RVALID       (1<<15)         /* Read valid */
-#define NIOS_JTAG_DATA(d)      ((d)&0x0ff)     /* Read data */
-#define NIOS_JTAG_RAVAIL(d)    ((d)>>16)       /* Read space avail */
+#define ALTERA_JTAG_RVALID     (1<<15)         /* Read valid */
 
 /* control register */
-#define NIOS_JTAG_RE           (1 << 0)        /* read intr enable */
-#define NIOS_JTAG_WE           (1 << 1)        /* write intr enable */
-#define NIOS_JTAG_RI           (1 << 8)        /* read intr pending */
-#define NIOS_JTAG_WI           (1 << 9)        /* write intr pending*/
-#define NIOS_JTAG_AC           (1 << 10)       /* activity indicator */
-#define NIOS_JTAG_RRDY         (1 << 12)       /* read available */
-#define NIOS_JTAG_WSPACE(d)    ((d)>>16)       /* Write space avail */
+#define ALTERA_JTAG_AC         (1 << 10)       /* activity indicator */
+#define ALTERA_JTAG_RRDY       (1 << 12)       /* read available */
+#define ALTERA_JTAG_WSPACE(d)  ((d)>>16)       /* Write space avail */
+/* Write fifo size. FIXME: this should be extracted with sopc2dts */
+#define ALTERA_JTAG_WRITE_DEPTH        64
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/*------------------------------------------------------------------
- * JTAG acts as the serial port
- *-----------------------------------------------------------------*/
-static nios_jtag_t *jtag = (nios_jtag_t *)CONFIG_SYS_NIOS_CONSOLE;
-
-static void altera_jtag_serial_setbrg(void)
+static int altera_jtaguart_setbrg(struct udevice *dev, int baudrate)
 {
+       return 0;
 }
 
-static int altera_jtag_serial_init(void)
+static int altera_jtaguart_putc(struct udevice *dev, const char ch)
 {
+       struct altera_jtaguart_platdata *plat = dev->platdata;
+       struct altera_jtaguart_regs *const regs = plat->regs;
+       u32 st = readl(&regs->control);
+
+#ifdef CONFIG_ALTERA_JTAG_UART_BYPASS
+       if (!(st & ALTERA_JTAG_AC)) /* no connection yet */
+               return -ENETUNREACH;
+#endif
+
+       if (ALTERA_JTAG_WSPACE(st) == 0)
+               return -EAGAIN;
+
+       writel(ch, &regs->data);
+
        return 0;
 }
 
-static void altera_jtag_serial_putc(char c)
+static int altera_jtaguart_pending(struct udevice *dev, bool input)
 {
-       while (1) {
-               unsigned st = readl(&jtag->control);
-               if (NIOS_JTAG_WSPACE(st))
-                       break;
-#ifdef CONFIG_ALTERA_JTAG_UART_BYPASS
-               if (!(st & NIOS_JTAG_AC)) /* no connection */
-                       return;
-#endif
-               WATCHDOG_RESET();
-       }
-       writel ((unsigned char)c, &jtag->data);
+       struct altera_jtaguart_platdata *plat = dev->platdata;
+       struct altera_jtaguart_regs *const regs = plat->regs;
+       u32 st = readl(&regs->control);
+
+       if (input)
+               return st & ALTERA_JTAG_RRDY ? 1 : 0;
+       else
+               return !(ALTERA_JTAG_WSPACE(st) == ALTERA_JTAG_WRITE_DEPTH);
 }
 
-static int altera_jtag_serial_tstc(void)
+static int altera_jtaguart_getc(struct udevice *dev)
 {
-       return ( readl (&jtag->control) & NIOS_JTAG_RRDY);
+       struct altera_jtaguart_platdata *plat = dev->platdata;
+       struct altera_jtaguart_regs *const regs = plat->regs;
+       u32 val;
+
+       val = readl(&regs->data);
+
+       if (!(val & ALTERA_JTAG_RVALID))
+               return -EAGAIN;
+
+       return val & 0xff;
 }
 
-static int altera_jtag_serial_getc(void)
+static int altera_jtaguart_probe(struct udevice *dev)
 {
-       int c;
-       unsigned val;
+#ifdef CONFIG_ALTERA_JTAG_UART_BYPASS
+       struct altera_jtaguart_platdata *plat = dev->platdata;
+       struct altera_jtaguart_regs *const regs = plat->regs;
 
-       while (1) {
-               WATCHDOG_RESET ();
-               val = readl (&jtag->data);
-               if (val & NIOS_JTAG_RVALID)
-                       break;
-       }
-       c = val & 0x0ff;
-       return (c);
+       writel(ALTERA_JTAG_AC, &regs->control); /* clear AC flag */
+#endif
+       return 0;
+}
+
+static int altera_jtaguart_ofdata_to_platdata(struct udevice *dev)
+{
+       struct altera_jtaguart_platdata *plat = dev_get_platdata(dev);
+
+       plat->regs = ioremap(dev_get_addr(dev),
+               sizeof(struct altera_jtaguart_regs));
+
+       return 0;
 }
 
-static struct serial_device altera_jtag_serial_drv = {
-       .name   = "altera_jtag_uart",
-       .start  = altera_jtag_serial_init,
-       .stop   = NULL,
-       .setbrg = altera_jtag_serial_setbrg,
-       .putc   = altera_jtag_serial_putc,
-       .puts   = default_serial_puts,
-       .getc   = altera_jtag_serial_getc,
-       .tstc   = altera_jtag_serial_tstc,
+static const struct dm_serial_ops altera_jtaguart_ops = {
+       .putc = altera_jtaguart_putc,
+       .pending = altera_jtaguart_pending,
+       .getc = altera_jtaguart_getc,
+       .setbrg = altera_jtaguart_setbrg,
+};
+
+static const struct udevice_id altera_jtaguart_ids[] = {
+       { .compatible = "altr,juart-1.0", },
+       { }
+};
+
+U_BOOT_DRIVER(altera_jtaguart) = {
+       .name   = "altera_jtaguart",
+       .id     = UCLASS_SERIAL,
+       .of_match = altera_jtaguart_ids,
+       .ofdata_to_platdata = altera_jtaguart_ofdata_to_platdata,
+       .platdata_auto_alloc_size = sizeof(struct altera_jtaguart_platdata),
+       .probe = altera_jtaguart_probe,
+       .ops    = &altera_jtaguart_ops,
+       .flags = DM_FLAG_PRE_RELOC,
 };
 
-void altera_jtag_serial_initialize(void)
+#ifdef CONFIG_DEBUG_UART_ALTERA_JTAGUART
+
+#include <debug_uart.h>
+
+void debug_uart_init(void)
 {
-       serial_register(&altera_jtag_serial_drv);
 }
 
-__weak struct serial_device *default_serial_console(void)
+static inline void _debug_uart_putc(int ch)
 {
-       return &altera_jtag_serial_drv;
+       struct altera_jtaguart_regs *regs = (void *)CONFIG_DEBUG_UART_BASE;
+
+       while (1) {
+               u32 st = readl(&regs->control);
+
+               if (ALTERA_JTAG_WSPACE(st))
+                       break;
+       }
+
+       writel(ch, &regs->data);
 }
+
+DEBUG_UART_FUNCS
+
+#endif
index 3d29a1f..e0ee047 100644 (file)
 /*
  * SERIAL
  */
-#define CONFIG_ALTERA_JTAG_UART
 #if defined(CONFIG_ALTERA_JTAG_UART)
-# define CONFIG_SYS_NIOS_CONSOLE       CONFIG_SYS_JTAG_UART_BASE
 #else
 # define CONFIG_SYS_NIOS_CONSOLE       CONFIG_SYS_UART_BASE
 #endif
 
-#define CONFIG_ALTERA_JTAG_UART_BYPASS
 #define CONFIG_SYS_NIOS_FIXEDBAUD
 #define CONFIG_BAUDRATE                CONFIG_SYS_UART_BAUD
 #define CONFIG_SYS_BAUDRATE_TABLE      {CONFIG_BAUDRATE}