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 DECLARE_GLOBAL_DATA_PTR; 19 20 #define SR_TX_FIFO_FULL BIT(3) /* transmit FIFO full */ 21 #define SR_TX_FIFO_EMPTY BIT(2) /* transmit FIFO empty */ 22 #define SR_RX_FIFO_VALID_DATA BIT(0) /* data in receive FIFO */ 23 #define SR_RX_FIFO_FULL BIT(1) /* receive FIFO full */ 24 25 #define ULITE_CONTROL_RST_TX 0x01 26 #define ULITE_CONTROL_RST_RX 0x02 27 28 struct uartlite { 29 unsigned int rx_fifo; 30 unsigned int tx_fifo; 31 unsigned int status; 32 unsigned int control; 33 }; 34 35 struct uartlite_platdata { 36 struct uartlite *regs; 37 }; 38 39 static int uartlite_serial_putc(struct udevice *dev, const char ch) 40 { 41 struct uartlite_platdata *plat = dev_get_platdata(dev); 42 struct uartlite *regs = plat->regs; 43 44 if (in_be32(®s->status) & SR_TX_FIFO_FULL) 45 return -EAGAIN; 46 47 out_be32(®s->tx_fifo, ch & 0xff); 48 49 return 0; 50 } 51 52 static int uartlite_serial_getc(struct udevice *dev) 53 { 54 struct uartlite_platdata *plat = dev_get_platdata(dev); 55 struct uartlite *regs = plat->regs; 56 57 if (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA)) 58 return -EAGAIN; 59 60 return in_be32(®s->rx_fifo) & 0xff; 61 } 62 63 static int uartlite_serial_pending(struct udevice *dev, bool input) 64 { 65 struct uartlite_platdata *plat = dev_get_platdata(dev); 66 struct uartlite *regs = plat->regs; 67 68 if (input) 69 return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA; 70 71 return !(in_be32(®s->status) & SR_TX_FIFO_EMPTY); 72 } 73 74 static int uartlite_serial_probe(struct udevice *dev) 75 { 76 struct uartlite_platdata *plat = dev_get_platdata(dev); 77 struct uartlite *regs = plat->regs; 78 79 out_be32(®s->control, 0); 80 out_be32(®s->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX); 81 in_be32(®s->control); 82 83 return 0; 84 } 85 86 static int uartlite_serial_ofdata_to_platdata(struct udevice *dev) 87 { 88 struct uartlite_platdata *plat = dev_get_platdata(dev); 89 90 plat->regs = (struct uartlite *)devfdt_get_addr(dev); 91 92 return 0; 93 } 94 95 static const struct dm_serial_ops uartlite_serial_ops = { 96 .putc = uartlite_serial_putc, 97 .pending = uartlite_serial_pending, 98 .getc = uartlite_serial_getc, 99 }; 100 101 static const struct udevice_id uartlite_serial_ids[] = { 102 { .compatible = "xlnx,opb-uartlite-1.00.b", }, 103 { .compatible = "xlnx,xps-uartlite-1.00.a" }, 104 { } 105 }; 106 107 U_BOOT_DRIVER(serial_uartlite) = { 108 .name = "serial_uartlite", 109 .id = UCLASS_SERIAL, 110 .of_match = uartlite_serial_ids, 111 .ofdata_to_platdata = uartlite_serial_ofdata_to_platdata, 112 .platdata_auto_alloc_size = sizeof(struct uartlite_platdata), 113 .probe = uartlite_serial_probe, 114 .ops = &uartlite_serial_ops, 115 .flags = DM_FLAG_PRE_RELOC, 116 }; 117 118 #ifdef CONFIG_DEBUG_UART_UARTLITE 119 120 #include <debug_uart.h> 121 122 static inline void _debug_uart_init(void) 123 { 124 struct uartlite *regs = (struct uartlite *)CONFIG_DEBUG_UART_BASE; 125 126 out_be32(®s->control, 0); 127 out_be32(®s->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX); 128 in_be32(®s->control); 129 } 130 131 static inline void _debug_uart_putc(int ch) 132 { 133 struct uartlite *regs = (struct uartlite *)CONFIG_DEBUG_UART_BASE; 134 135 while (in_be32(®s->status) & SR_TX_FIFO_FULL) 136 ; 137 138 out_be32(®s->tx_fifo, ch & 0xff); 139 } 140 141 DEBUG_UART_FUNCS 142 #endif 143