From 220e8021af96741bd7149ca9895e1f0c8a38d0bb Mon Sep 17 00:00:00 2001 From: Thomas Chou Date: Fri, 23 Oct 2015 07:36:37 +0800 Subject: nios2: convert altera_jtag_uart to driver model Convert altera_jtag_uart to driver model. Signed-off-by: Thomas Chou Acked-by: Marek Vasut Reviewed-by: Simon Glass --- arch/nios2/dts/3c120_devboard.dts | 1 + configs/nios2-generic_defconfig | 3 + .../serial/altera_jtaguart.txt | 4 + drivers/serial/Kconfig | 26 ++++ drivers/serial/altera_jtag_uart.c | 171 +++++++++++++-------- include/configs/nios2-generic.h | 3 - 6 files changed, 145 insertions(+), 63 deletions(-) create mode 100644 doc/device-tree-bindings/serial/altera_jtaguart.txt diff --git a/arch/nios2/dts/3c120_devboard.dts b/arch/nios2/dts/3c120_devboard.dts index 02524abf1d..3d76ec4b9e 100644 --- a/arch/nios2/dts/3c120_devboard.dts +++ b/arch/nios2/dts/3c120_devboard.dts @@ -149,5 +149,6 @@ chosen { bootargs = "debug console=ttyJ0,115200"; + stdout-path = &jtag_uart; }; }; diff --git a/configs/nios2-generic_defconfig b/configs/nios2-generic_defconfig index 9c1bec58e6..9dc6a7292b 100644 --- a/configs/nios2-generic_defconfig +++ b/configs/nios2-generic_defconfig @@ -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 index 0000000000..97c7062c5f --- /dev/null +++ b/doc/device-tree-bindings/serial/altera_jtaguart.txt @@ -0,0 +1,4 @@ +Altera JTAG UART + +Required properties: +- compatible : should be "altr,juart-1.0" diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index ac5920ad5a..85e6764433 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -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 diff --git a/drivers/serial/altera_jtag_uart.c b/drivers/serial/altera_jtag_uart.c index 9a81402ffb..39d4a4e933 100644 --- a/drivers/serial/altera_jtag_uart.c +++ b/drivers/serial/altera_jtag_uart.c @@ -6,98 +6,149 @@ */ #include -#include +#include +#include #include #include #include -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(®s->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, ®s->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(®s->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(®s->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, ®s->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 + +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(®s->control); + + if (ALTERA_JTAG_WSPACE(st)) + break; + } + + writel(ch, ®s->data); } + +DEBUG_UART_FUNCS + +#endif diff --git a/include/configs/nios2-generic.h b/include/configs/nios2-generic.h index 3d29a1f7af..e0ee04784e 100644 --- a/include/configs/nios2-generic.h +++ b/include/configs/nios2-generic.h @@ -23,14 +23,11 @@ /* * 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} -- cgit v1.2.1