1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2008 - 2015 Michal Simek <monstr@monstr.eu> 4 * Clean driver and add xilinx constant from header file 5 * 6 * (C) Copyright 2004 Atmark Techno, Inc. 7 * Yasushi SHOJI <yashi@atmark-techno.com> 8 */ 9 10 #include <config.h> 11 #include <common.h> 12 #include <dm.h> 13 #include <asm/io.h> 14 #include <linux/compiler.h> 15 #include <serial.h> 16 17 #define SR_TX_FIFO_FULL BIT(3) /* transmit FIFO full */ 18 #define SR_TX_FIFO_EMPTY BIT(2) /* transmit FIFO empty */ 19 #define SR_RX_FIFO_VALID_DATA BIT(0) /* data in receive FIFO */ 20 #define SR_RX_FIFO_FULL BIT(1) /* receive FIFO full */ 21 22 #define ULITE_CONTROL_RST_TX 0x01 23 #define ULITE_CONTROL_RST_RX 0x02 24 25 struct uartlite { 26 unsigned int rx_fifo; 27 unsigned int tx_fifo; 28 unsigned int status; 29 unsigned int control; 30 }; 31 32 struct uartlite_platdata { 33 struct uartlite *regs; 34 }; 35 36 static int uartlite_serial_putc(struct udevice *dev, const char ch) 37 { 38 struct uartlite_platdata *plat = dev_get_platdata(dev); 39 struct uartlite *regs = plat->regs; 40 41 if (in_be32(®s->status) & SR_TX_FIFO_FULL) 42 return -EAGAIN; 43 44 out_be32(®s->tx_fifo, ch & 0xff); 45 46 return 0; 47 } 48 49 static int uartlite_serial_getc(struct udevice *dev) 50 { 51 struct uartlite_platdata *plat = dev_get_platdata(dev); 52 struct uartlite *regs = plat->regs; 53 54 if (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA)) 55 return -EAGAIN; 56 57 return in_be32(®s->rx_fifo) & 0xff; 58 } 59 60 static int uartlite_serial_pending(struct udevice *dev, bool input) 61 { 62 struct uartlite_platdata *plat = dev_get_platdata(dev); 63 struct uartlite *regs = plat->regs; 64 65 if (input) 66 return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA; 67 68 return !(in_be32(®s->status) & SR_TX_FIFO_EMPTY); 69 } 70 71 static int uartlite_serial_probe(struct udevice *dev) 72 { 73 struct uartlite_platdata *plat = dev_get_platdata(dev); 74 struct uartlite *regs = plat->regs; 75 76 out_be32(®s->control, 0); 77 out_be32(®s->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX); 78 in_be32(®s->control); 79 80 return 0; 81 } 82 83 static int uartlite_serial_ofdata_to_platdata(struct udevice *dev) 84 { 85 struct uartlite_platdata *plat = dev_get_platdata(dev); 86 87 plat->regs = (struct uartlite *)devfdt_get_addr(dev); 88 89 return 0; 90 } 91 92 static const struct dm_serial_ops uartlite_serial_ops = { 93 .putc = uartlite_serial_putc, 94 .pending = uartlite_serial_pending, 95 .getc = uartlite_serial_getc, 96 }; 97 98 static const struct udevice_id uartlite_serial_ids[] = { 99 { .compatible = "xlnx,opb-uartlite-1.00.b", }, 100 { .compatible = "xlnx,xps-uartlite-1.00.a" }, 101 { } 102 }; 103 104 U_BOOT_DRIVER(serial_uartlite) = { 105 .name = "serial_uartlite", 106 .id = UCLASS_SERIAL, 107 .of_match = uartlite_serial_ids, 108 .ofdata_to_platdata = uartlite_serial_ofdata_to_platdata, 109 .platdata_auto_alloc_size = sizeof(struct uartlite_platdata), 110 .probe = uartlite_serial_probe, 111 .ops = &uartlite_serial_ops, 112 .flags = DM_FLAG_PRE_RELOC, 113 }; 114 115 #ifdef CONFIG_DEBUG_UART_UARTLITE 116 117 #include <debug_uart.h> 118 119 static inline void _debug_uart_init(void) 120 { 121 struct uartlite *regs = (struct uartlite *)CONFIG_DEBUG_UART_BASE; 122 123 out_be32(®s->control, 0); 124 out_be32(®s->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX); 125 in_be32(®s->control); 126 } 127 128 static inline void _debug_uart_putc(int ch) 129 { 130 struct uartlite *regs = (struct uartlite *)CONFIG_DEBUG_UART_BASE; 131 132 while (in_be32(®s->status) & SR_TX_FIFO_FULL) 133 ; 134 135 out_be32(®s->tx_fifo, ch & 0xff); 136 } 137 138 DEBUG_UART_FUNCS 139 #endif 140