summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/serial/Kconfig26
-rw-r--r--drivers/serial/altera_jtag_uart.c171
2 files changed, 137 insertions, 60 deletions
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 <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