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