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
uartlite_serial_putc(struct udevice * dev,const char ch)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
uartlite_serial_getc(struct udevice * dev)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
uartlite_serial_pending(struct udevice * dev,bool input)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
uartlite_serial_probe(struct udevice * dev)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
uartlite_serial_ofdata_to_platdata(struct udevice * dev)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
90*a821c4afSSimon Glass plat->regs = (struct uartlite *)devfdt_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 };
1174166ba3bSMichal Simek
1184166ba3bSMichal Simek #ifdef CONFIG_DEBUG_UART_UARTLITE
1194166ba3bSMichal Simek
1204166ba3bSMichal Simek #include <debug_uart.h>
1214166ba3bSMichal Simek
_debug_uart_init(void)1224166ba3bSMichal Simek static inline void _debug_uart_init(void)
1234166ba3bSMichal Simek {
1244166ba3bSMichal Simek struct uartlite *regs = (struct uartlite *)CONFIG_DEBUG_UART_BASE;
1254166ba3bSMichal Simek
1264166ba3bSMichal Simek out_be32(®s->control, 0);
1274166ba3bSMichal Simek out_be32(®s->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX);
1284166ba3bSMichal Simek in_be32(®s->control);
1294166ba3bSMichal Simek }
1304166ba3bSMichal Simek
_debug_uart_putc(int ch)1314166ba3bSMichal Simek static inline void _debug_uart_putc(int ch)
1324166ba3bSMichal Simek {
1334166ba3bSMichal Simek struct uartlite *regs = (struct uartlite *)CONFIG_DEBUG_UART_BASE;
1344166ba3bSMichal Simek
1354166ba3bSMichal Simek while (in_be32(®s->status) & SR_TX_FIFO_FULL)
1364166ba3bSMichal Simek ;
1374166ba3bSMichal Simek
1384166ba3bSMichal Simek out_be32(®s->tx_fifo, ch & 0xff);
1394166ba3bSMichal Simek }
1404166ba3bSMichal Simek
1414166ba3bSMichal Simek DEBUG_UART_FUNCS
1424166ba3bSMichal Simek #endif
143