xref: /rk3399_rockchip-uboot/drivers/serial/serial_xuartlite.c (revision 4166ba3b2351aa72c372f66a54e9fb92cffbd230)
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(&regs->status) & SR_TX_FIFO_FULL)
4593768393SMichal Simek 		return -EAGAIN;
4649a23e4aSMichal Simek 
4793768393SMichal Simek 	out_be32(&regs->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(&regs->status) & SR_RX_FIFO_VALID_DATA))
5893768393SMichal Simek 		return -EAGAIN;
5993768393SMichal Simek 
6093768393SMichal Simek 	return in_be32(&regs->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(&regs->status) & SR_RX_FIFO_VALID_DATA;
7093768393SMichal Simek 
7193768393SMichal Simek 	return !(in_be32(&regs->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(&regs->control, 0);
8093768393SMichal Simek 	out_be32(&regs->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX);
8193768393SMichal Simek 	in_be32(&regs->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(&regs->control, 0);
127*4166ba3bSMichal Simek 	out_be32(&regs->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX);
128*4166ba3bSMichal Simek 	in_be32(&regs->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(&regs->status) & SR_TX_FIFO_FULL)
136*4166ba3bSMichal Simek 		;
137*4166ba3bSMichal Simek 
138*4166ba3bSMichal Simek 	out_be32(&regs->tx_fifo, ch & 0xff);
139*4166ba3bSMichal Simek }
140*4166ba3bSMichal Simek 
141*4166ba3bSMichal Simek DEBUG_UART_FUNCS
142*4166ba3bSMichal Simek #endif
143