11378df79SJean-Christophe PLAGNIOL-VILLARD /* 293768393SMichal Simek * (C) Copyright 2008 - 2015 Michal Simek <monstr@monstr.eu> 353ea981cSMichal Simek * Clean driver and add xilinx constant from header file 41378df79SJean-Christophe PLAGNIOL-VILLARD * 553ea981cSMichal Simek * (C) Copyright 2004 Atmark Techno, Inc. 61378df79SJean-Christophe PLAGNIOL-VILLARD * Yasushi SHOJI <yashi@atmark-techno.com> 71378df79SJean-Christophe PLAGNIOL-VILLARD * 81a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 91378df79SJean-Christophe PLAGNIOL-VILLARD */ 101378df79SJean-Christophe PLAGNIOL-VILLARD 111378df79SJean-Christophe PLAGNIOL-VILLARD #include <config.h> 1249a23e4aSMichal Simek #include <common.h> 1393768393SMichal Simek #include <dm.h> 1453ea981cSMichal Simek #include <asm/io.h> 1549a23e4aSMichal Simek #include <linux/compiler.h> 1649a23e4aSMichal Simek #include <serial.h> 171378df79SJean-Christophe PLAGNIOL-VILLARD 1893768393SMichal Simek DECLARE_GLOBAL_DATA_PTR; 1993768393SMichal Simek 2093768393SMichal Simek #define SR_TX_FIFO_FULL BIT(3) /* transmit FIFO full */ 2193768393SMichal Simek #define SR_TX_FIFO_EMPTY BIT(2) /* transmit FIFO empty */ 2293768393SMichal Simek #define SR_RX_FIFO_VALID_DATA BIT(0) /* data in receive FIFO */ 2393768393SMichal Simek #define SR_RX_FIFO_FULL BIT(1) /* receive FIFO full */ 241378df79SJean-Christophe PLAGNIOL-VILLARD 258c3bd6b5SMichal Simek #define ULITE_CONTROL_RST_TX 0x01 268c3bd6b5SMichal Simek #define ULITE_CONTROL_RST_RX 0x02 278c3bd6b5SMichal Simek 2849a23e4aSMichal Simek struct uartlite { 2949a23e4aSMichal Simek unsigned int rx_fifo; 3049a23e4aSMichal Simek unsigned int tx_fifo; 3149a23e4aSMichal Simek unsigned int status; 328c3bd6b5SMichal Simek unsigned int control; 3349a23e4aSMichal Simek }; 341378df79SJean-Christophe PLAGNIOL-VILLARD 3593768393SMichal Simek struct uartlite_platdata { 3693768393SMichal Simek struct uartlite *regs; 3749a23e4aSMichal Simek }; 3849a23e4aSMichal Simek 3993768393SMichal Simek static int uartlite_serial_putc(struct udevice *dev, const char ch) 4049a23e4aSMichal Simek { 4193768393SMichal Simek struct uartlite_platdata *plat = dev_get_platdata(dev); 4293768393SMichal Simek struct uartlite *regs = plat->regs; 4349a23e4aSMichal Simek 4493768393SMichal Simek if (in_be32(®s->status) & SR_TX_FIFO_FULL) 4593768393SMichal Simek return -EAGAIN; 4649a23e4aSMichal Simek 4793768393SMichal Simek out_be32(®s->tx_fifo, ch & 0xff); 4849a23e4aSMichal Simek 4925239e12SMichal Simek return 0; 508c3bd6b5SMichal Simek } 518c3bd6b5SMichal Simek 5293768393SMichal Simek static int uartlite_serial_getc(struct udevice *dev) 5349a23e4aSMichal Simek { 5493768393SMichal Simek struct uartlite_platdata *plat = dev_get_platdata(dev); 5593768393SMichal Simek struct uartlite *regs = plat->regs; 5625239e12SMichal Simek 5793768393SMichal Simek if (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA)) 5893768393SMichal Simek return -EAGAIN; 5993768393SMichal Simek 6093768393SMichal Simek return in_be32(®s->rx_fifo) & 0xff; 6149a23e4aSMichal Simek } 6287d69229SMarek Vasut 6393768393SMichal Simek static int uartlite_serial_pending(struct udevice *dev, bool input) 6487d69229SMarek Vasut { 6593768393SMichal Simek struct uartlite_platdata *plat = dev_get_platdata(dev); 6693768393SMichal Simek struct uartlite *regs = plat->regs; 6793768393SMichal Simek 6893768393SMichal Simek if (input) 6993768393SMichal Simek return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA; 7093768393SMichal Simek 7193768393SMichal Simek return !(in_be32(®s->status) & SR_TX_FIFO_EMPTY); 7287d69229SMarek Vasut } 7393768393SMichal Simek 7493768393SMichal Simek static int uartlite_serial_probe(struct udevice *dev) 7593768393SMichal Simek { 7693768393SMichal Simek struct uartlite_platdata *plat = dev_get_platdata(dev); 7793768393SMichal Simek struct uartlite *regs = plat->regs; 7893768393SMichal Simek 7993768393SMichal Simek out_be32(®s->control, 0); 8093768393SMichal Simek out_be32(®s->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX); 8193768393SMichal Simek in_be32(®s->control); 8293768393SMichal Simek 8393768393SMichal Simek return 0; 8493768393SMichal Simek } 8593768393SMichal Simek 8693768393SMichal Simek static int uartlite_serial_ofdata_to_platdata(struct udevice *dev) 8793768393SMichal Simek { 8893768393SMichal Simek struct uartlite_platdata *plat = dev_get_platdata(dev); 8993768393SMichal Simek 9093768393SMichal Simek plat->regs = (struct uartlite *)dev_get_addr(dev); 9193768393SMichal Simek 9293768393SMichal Simek return 0; 9393768393SMichal Simek } 9493768393SMichal Simek 9593768393SMichal Simek static const struct dm_serial_ops uartlite_serial_ops = { 9693768393SMichal Simek .putc = uartlite_serial_putc, 9793768393SMichal Simek .pending = uartlite_serial_pending, 9893768393SMichal Simek .getc = uartlite_serial_getc, 9993768393SMichal Simek }; 10093768393SMichal Simek 10193768393SMichal Simek static const struct udevice_id uartlite_serial_ids[] = { 10293768393SMichal Simek { .compatible = "xlnx,opb-uartlite-1.00.b", }, 10393768393SMichal Simek { .compatible = "xlnx,xps-uartlite-1.00.a" }, 10493768393SMichal Simek { } 10593768393SMichal Simek }; 10693768393SMichal Simek 10793768393SMichal Simek U_BOOT_DRIVER(serial_uartlite) = { 10893768393SMichal Simek .name = "serial_uartlite", 10993768393SMichal Simek .id = UCLASS_SERIAL, 11093768393SMichal Simek .of_match = uartlite_serial_ids, 11193768393SMichal Simek .ofdata_to_platdata = uartlite_serial_ofdata_to_platdata, 11293768393SMichal Simek .platdata_auto_alloc_size = sizeof(struct uartlite_platdata), 11393768393SMichal Simek .probe = uartlite_serial_probe, 11493768393SMichal Simek .ops = &uartlite_serial_ops, 11593768393SMichal Simek .flags = DM_FLAG_PRE_RELOC, 11693768393SMichal Simek }; 117*4166ba3bSMichal Simek 118*4166ba3bSMichal Simek #ifdef CONFIG_DEBUG_UART_UARTLITE 119*4166ba3bSMichal Simek 120*4166ba3bSMichal Simek #include <debug_uart.h> 121*4166ba3bSMichal Simek 122*4166ba3bSMichal Simek static inline void _debug_uart_init(void) 123*4166ba3bSMichal Simek { 124*4166ba3bSMichal Simek struct uartlite *regs = (struct uartlite *)CONFIG_DEBUG_UART_BASE; 125*4166ba3bSMichal Simek 126*4166ba3bSMichal Simek out_be32(®s->control, 0); 127*4166ba3bSMichal Simek out_be32(®s->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX); 128*4166ba3bSMichal Simek in_be32(®s->control); 129*4166ba3bSMichal Simek } 130*4166ba3bSMichal Simek 131*4166ba3bSMichal Simek static inline void _debug_uart_putc(int ch) 132*4166ba3bSMichal Simek { 133*4166ba3bSMichal Simek struct uartlite *regs = (struct uartlite *)CONFIG_DEBUG_UART_BASE; 134*4166ba3bSMichal Simek 135*4166ba3bSMichal Simek while (in_be32(®s->status) & SR_TX_FIFO_FULL) 136*4166ba3bSMichal Simek ; 137*4166ba3bSMichal Simek 138*4166ba3bSMichal Simek out_be32(®s->tx_fifo, ch & 0xff); 139*4166ba3bSMichal Simek } 140*4166ba3bSMichal Simek 141*4166ba3bSMichal Simek DEBUG_UART_FUNCS 142*4166ba3bSMichal Simek #endif 143