X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fserial%2Faltera_jtag_uart.c;h=4a6e60f87efe81c3d474aa1b88c0bbdb1e1cce2a;hb=791c174d58f6fbea2b055b5851ab33d8f73b2c93;hp=2980e4d07c18105a9c27827102f9be97edc18dee;hpb=9d62f20d0861ef87460d073dc189c851715b46ae;p=u-boot diff --git a/drivers/serial/altera_jtag_uart.c b/drivers/serial/altera_jtag_uart.c index 2980e4d07c..4a6e60f87e 100644 --- a/drivers/serial/altera_jtag_uart.c +++ b/drivers/serial/altera_jtag_uart.c @@ -2,77 +2,153 @@ * (C) Copyright 2004, Psyent Corporation * Scott McNutt * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ */ #include -#include +#include +#include +#include #include -#include DECLARE_GLOBAL_DATA_PTR; -/*------------------------------------------------------------------ - * JTAG acts as the serial port - *-----------------------------------------------------------------*/ -static nios_jtag_t *jtag = (nios_jtag_t *)CONFIG_SYS_NIOS_CONSOLE; +/* data register */ +#define ALTERA_JTAG_RVALID BIT(15) /* Read valid */ -void serial_setbrg( void ){ return; } -int serial_init( void ) { return(0);} +/* control register */ +#define ALTERA_JTAG_AC BIT(10) /* activity indicator */ +#define ALTERA_JTAG_RRDY BIT(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 -void serial_putc (char c) +struct altera_jtaguart_regs { + u32 data; /* Data register */ + u32 control; /* Control register */ +}; + +struct altera_jtaguart_platdata { + struct altera_jtaguart_regs *regs; +}; + +static int altera_jtaguart_setbrg(struct udevice *dev, int baudrate) { - while (1) { - unsigned st = readl(&jtag->control); - if (NIOS_JTAG_WSPACE(st)) - break; + return 0; +} + +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 & NIOS_JTAG_AC)) /* no connection */ - return; + if (!(st & ALTERA_JTAG_AC)) /* no connection yet */ + return -ENETUNREACH; #endif - WATCHDOG_RESET(); - } - writel ((unsigned char)c, &jtag->data); + + if (ALTERA_JTAG_WSPACE(st) == 0) + return -EAGAIN; + + writel(ch, ®s->data); + + return 0; } -void serial_puts (const char *s) +static int altera_jtaguart_pending(struct udevice *dev, bool input) { - while (*s != 0) - serial_putc (*s++); + 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); } -int 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; } -int 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; + + 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 = map_physmem(devfdt_get_addr(dev), + sizeof(struct altera_jtaguart_regs), + MAP_NOCACHE); + + return 0; +} + +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, +}; + +#ifdef CONFIG_DEBUG_UART_ALTERA_JTAGUART + +#include + +static inline void _debug_uart_init(void) +{ +} + +static inline void _debug_uart_putc(int ch) +{ + struct altera_jtaguart_regs *regs = (void *)CONFIG_DEBUG_UART_BASE; while (1) { - WATCHDOG_RESET (); - val = readl (&jtag->data); - if (val & NIOS_JTAG_RVALID) + u32 st = readl(®s->control); + + if (ALTERA_JTAG_WSPACE(st)) break; } - c = val & 0x0ff; - return (c); + + writel(ch, ®s->data); } + +DEBUG_UART_FUNCS + +#endif