1*9e160ee8SPaul Thacker /* 2*9e160ee8SPaul Thacker * (c) 2015 Paul Thacker <paul.thacker@microchip.com> 3*9e160ee8SPaul Thacker * 4*9e160ee8SPaul Thacker * SPDX-License-Identifier: GPL-2.0+ 5*9e160ee8SPaul Thacker * 6*9e160ee8SPaul Thacker */ 7*9e160ee8SPaul Thacker #include <common.h> 8*9e160ee8SPaul Thacker #include <clk.h> 9*9e160ee8SPaul Thacker #include <dm.h> 10*9e160ee8SPaul Thacker #include <serial.h> 11*9e160ee8SPaul Thacker #include <wait_bit.h> 12*9e160ee8SPaul Thacker #include <mach/pic32.h> 13*9e160ee8SPaul Thacker #include <dt-bindings/clock/microchip,clock.h> 14*9e160ee8SPaul Thacker 15*9e160ee8SPaul Thacker DECLARE_GLOBAL_DATA_PTR; 16*9e160ee8SPaul Thacker 17*9e160ee8SPaul Thacker /* UART Control Registers */ 18*9e160ee8SPaul Thacker #define U_MOD 0x00 19*9e160ee8SPaul Thacker #define U_MODCLR (U_MOD + _CLR_OFFSET) 20*9e160ee8SPaul Thacker #define U_MODSET (U_MOD + _SET_OFFSET) 21*9e160ee8SPaul Thacker #define U_STA 0x10 22*9e160ee8SPaul Thacker #define U_STACLR (U_STA + _CLR_OFFSET) 23*9e160ee8SPaul Thacker #define U_STASET (U_STA + _SET_OFFSET) 24*9e160ee8SPaul Thacker #define U_TXR 0x20 25*9e160ee8SPaul Thacker #define U_RXR 0x30 26*9e160ee8SPaul Thacker #define U_BRG 0x40 27*9e160ee8SPaul Thacker 28*9e160ee8SPaul Thacker /* U_MOD bits */ 29*9e160ee8SPaul Thacker #define UART_ENABLE BIT(15) 30*9e160ee8SPaul Thacker 31*9e160ee8SPaul Thacker /* U_STA bits */ 32*9e160ee8SPaul Thacker #define UART_RX_ENABLE BIT(12) 33*9e160ee8SPaul Thacker #define UART_TX_BRK BIT(11) 34*9e160ee8SPaul Thacker #define UART_TX_ENABLE BIT(10) 35*9e160ee8SPaul Thacker #define UART_TX_FULL BIT(9) 36*9e160ee8SPaul Thacker #define UART_TX_EMPTY BIT(8) 37*9e160ee8SPaul Thacker #define UART_RX_OVER BIT(1) 38*9e160ee8SPaul Thacker #define UART_RX_DATA_AVAIL BIT(0) 39*9e160ee8SPaul Thacker 40*9e160ee8SPaul Thacker struct pic32_uart_priv { 41*9e160ee8SPaul Thacker void __iomem *base; 42*9e160ee8SPaul Thacker ulong uartclk; 43*9e160ee8SPaul Thacker }; 44*9e160ee8SPaul Thacker 45*9e160ee8SPaul Thacker /* 46*9e160ee8SPaul Thacker * Initialize the serial port with the given baudrate. 47*9e160ee8SPaul Thacker * The settings are always 8 data bits, no parity, 1 stop bit, no start bits. 48*9e160ee8SPaul Thacker */ 49*9e160ee8SPaul Thacker static int pic32_serial_init(void __iomem *base, ulong clk, u32 baudrate) 50*9e160ee8SPaul Thacker { 51*9e160ee8SPaul Thacker u32 div = DIV_ROUND_CLOSEST(clk, baudrate * 16); 52*9e160ee8SPaul Thacker 53*9e160ee8SPaul Thacker /* wait for TX FIFO to empty */ 54*9e160ee8SPaul Thacker wait_for_bit(__func__, base + U_STA, UART_TX_EMPTY, 55*9e160ee8SPaul Thacker true, CONFIG_SYS_HZ, false); 56*9e160ee8SPaul Thacker 57*9e160ee8SPaul Thacker /* send break */ 58*9e160ee8SPaul Thacker writel(UART_TX_BRK, base + U_STASET); 59*9e160ee8SPaul Thacker 60*9e160ee8SPaul Thacker /* disable and clear mode */ 61*9e160ee8SPaul Thacker writel(0, base + U_MOD); 62*9e160ee8SPaul Thacker writel(0, base + U_STA); 63*9e160ee8SPaul Thacker 64*9e160ee8SPaul Thacker /* set baud rate generator */ 65*9e160ee8SPaul Thacker writel(div - 1, base + U_BRG); 66*9e160ee8SPaul Thacker 67*9e160ee8SPaul Thacker /* enable the UART for TX and RX */ 68*9e160ee8SPaul Thacker writel(UART_TX_ENABLE | UART_RX_ENABLE, base + U_STASET); 69*9e160ee8SPaul Thacker 70*9e160ee8SPaul Thacker /* enable the UART */ 71*9e160ee8SPaul Thacker writel(UART_ENABLE, base + U_MODSET); 72*9e160ee8SPaul Thacker return 0; 73*9e160ee8SPaul Thacker } 74*9e160ee8SPaul Thacker 75*9e160ee8SPaul Thacker /* Check whether any char pending in RX fifo */ 76*9e160ee8SPaul Thacker static int pic32_uart_pending_input(void __iomem *base) 77*9e160ee8SPaul Thacker { 78*9e160ee8SPaul Thacker /* check if rx buffer overrun error has occurred */ 79*9e160ee8SPaul Thacker if (readl(base + U_STA) & UART_RX_OVER) { 80*9e160ee8SPaul Thacker readl(base + U_RXR); 81*9e160ee8SPaul Thacker 82*9e160ee8SPaul Thacker /* clear overrun error to keep receiving */ 83*9e160ee8SPaul Thacker writel(UART_RX_OVER, base + U_STACLR); 84*9e160ee8SPaul Thacker } 85*9e160ee8SPaul Thacker 86*9e160ee8SPaul Thacker /* In PIC32 there is no way to know number of outstanding 87*9e160ee8SPaul Thacker * chars in rx-fifo. Only it can be known whether there is any. 88*9e160ee8SPaul Thacker */ 89*9e160ee8SPaul Thacker return readl(base + U_STA) & UART_RX_DATA_AVAIL; 90*9e160ee8SPaul Thacker } 91*9e160ee8SPaul Thacker 92*9e160ee8SPaul Thacker static int pic32_uart_pending(struct udevice *dev, bool input) 93*9e160ee8SPaul Thacker { 94*9e160ee8SPaul Thacker struct pic32_uart_priv *priv = dev_get_priv(dev); 95*9e160ee8SPaul Thacker 96*9e160ee8SPaul Thacker if (input) 97*9e160ee8SPaul Thacker return pic32_uart_pending_input(priv->base); 98*9e160ee8SPaul Thacker 99*9e160ee8SPaul Thacker return !(readl(priv->base + U_STA) & UART_TX_EMPTY); 100*9e160ee8SPaul Thacker } 101*9e160ee8SPaul Thacker 102*9e160ee8SPaul Thacker static int pic32_uart_setbrg(struct udevice *dev, int baudrate) 103*9e160ee8SPaul Thacker { 104*9e160ee8SPaul Thacker struct pic32_uart_priv *priv = dev_get_priv(dev); 105*9e160ee8SPaul Thacker 106*9e160ee8SPaul Thacker return pic32_serial_init(priv->base, priv->uartclk, baudrate); 107*9e160ee8SPaul Thacker } 108*9e160ee8SPaul Thacker 109*9e160ee8SPaul Thacker static int pic32_uart_putc(struct udevice *dev, const char ch) 110*9e160ee8SPaul Thacker { 111*9e160ee8SPaul Thacker struct pic32_uart_priv *priv = dev_get_priv(dev); 112*9e160ee8SPaul Thacker 113*9e160ee8SPaul Thacker /* Check if Tx FIFO is full */ 114*9e160ee8SPaul Thacker if (readl(priv->base + U_STA) & UART_TX_FULL) 115*9e160ee8SPaul Thacker return -EAGAIN; 116*9e160ee8SPaul Thacker 117*9e160ee8SPaul Thacker /* pump the char to tx buffer */ 118*9e160ee8SPaul Thacker writel(ch, priv->base + U_TXR); 119*9e160ee8SPaul Thacker 120*9e160ee8SPaul Thacker return 0; 121*9e160ee8SPaul Thacker } 122*9e160ee8SPaul Thacker 123*9e160ee8SPaul Thacker static int pic32_uart_getc(struct udevice *dev) 124*9e160ee8SPaul Thacker { 125*9e160ee8SPaul Thacker struct pic32_uart_priv *priv = dev_get_priv(dev); 126*9e160ee8SPaul Thacker 127*9e160ee8SPaul Thacker /* return error if RX fifo is empty */ 128*9e160ee8SPaul Thacker if (!pic32_uart_pending_input(priv->base)) 129*9e160ee8SPaul Thacker return -EAGAIN; 130*9e160ee8SPaul Thacker 131*9e160ee8SPaul Thacker /* read the character from rx buffer */ 132*9e160ee8SPaul Thacker return readl(priv->base + U_RXR) & 0xff; 133*9e160ee8SPaul Thacker } 134*9e160ee8SPaul Thacker 135*9e160ee8SPaul Thacker static int pic32_uart_probe(struct udevice *dev) 136*9e160ee8SPaul Thacker { 137*9e160ee8SPaul Thacker struct pic32_uart_priv *priv = dev_get_priv(dev); 138*9e160ee8SPaul Thacker struct udevice *clkdev; 139*9e160ee8SPaul Thacker fdt_addr_t addr; 140*9e160ee8SPaul Thacker fdt_size_t size; 141*9e160ee8SPaul Thacker int ret; 142*9e160ee8SPaul Thacker 143*9e160ee8SPaul Thacker /* get address */ 144*9e160ee8SPaul Thacker addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size); 145*9e160ee8SPaul Thacker if (addr == FDT_ADDR_T_NONE) 146*9e160ee8SPaul Thacker return -EINVAL; 147*9e160ee8SPaul Thacker 148*9e160ee8SPaul Thacker priv->base = ioremap(addr, size); 149*9e160ee8SPaul Thacker 150*9e160ee8SPaul Thacker /* get clock rate */ 151*9e160ee8SPaul Thacker ret = clk_get_by_index(dev, 0, &clkdev); 152*9e160ee8SPaul Thacker if (ret < 0) 153*9e160ee8SPaul Thacker return ret; 154*9e160ee8SPaul Thacker priv->uartclk = clk_get_periph_rate(clkdev, ret); 155*9e160ee8SPaul Thacker 156*9e160ee8SPaul Thacker /* initialize serial */ 157*9e160ee8SPaul Thacker return pic32_serial_init(priv->base, priv->uartclk, CONFIG_BAUDRATE); 158*9e160ee8SPaul Thacker } 159*9e160ee8SPaul Thacker 160*9e160ee8SPaul Thacker static const struct dm_serial_ops pic32_uart_ops = { 161*9e160ee8SPaul Thacker .putc = pic32_uart_putc, 162*9e160ee8SPaul Thacker .pending = pic32_uart_pending, 163*9e160ee8SPaul Thacker .getc = pic32_uart_getc, 164*9e160ee8SPaul Thacker .setbrg = pic32_uart_setbrg, 165*9e160ee8SPaul Thacker }; 166*9e160ee8SPaul Thacker 167*9e160ee8SPaul Thacker static const struct udevice_id pic32_uart_ids[] = { 168*9e160ee8SPaul Thacker { .compatible = "microchip,pic32mzda-uart" }, 169*9e160ee8SPaul Thacker {} 170*9e160ee8SPaul Thacker }; 171*9e160ee8SPaul Thacker 172*9e160ee8SPaul Thacker U_BOOT_DRIVER(pic32_serial) = { 173*9e160ee8SPaul Thacker .name = "pic32-uart", 174*9e160ee8SPaul Thacker .id = UCLASS_SERIAL, 175*9e160ee8SPaul Thacker .of_match = pic32_uart_ids, 176*9e160ee8SPaul Thacker .probe = pic32_uart_probe, 177*9e160ee8SPaul Thacker .ops = &pic32_uart_ops, 178*9e160ee8SPaul Thacker .flags = DM_FLAG_PRE_RELOC, 179*9e160ee8SPaul Thacker .priv_auto_alloc_size = sizeof(struct pic32_uart_priv), 180*9e160ee8SPaul Thacker }; 181*9e160ee8SPaul Thacker 182*9e160ee8SPaul Thacker #ifdef CONFIG_DEBUG_UART_PIC32 183*9e160ee8SPaul Thacker #include <debug_uart.h> 184*9e160ee8SPaul Thacker 185*9e160ee8SPaul Thacker static inline void _debug_uart_init(void) 186*9e160ee8SPaul Thacker { 187*9e160ee8SPaul Thacker void __iomem *base = (void __iomem *)CONFIG_DEBUG_UART_BASE; 188*9e160ee8SPaul Thacker 189*9e160ee8SPaul Thacker pic32_serial_init(base, CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE); 190*9e160ee8SPaul Thacker } 191*9e160ee8SPaul Thacker 192*9e160ee8SPaul Thacker static inline void _debug_uart_putc(int ch) 193*9e160ee8SPaul Thacker { 194*9e160ee8SPaul Thacker writel(ch, CONFIG_DEBUG_UART_BASE + U_TXR); 195*9e160ee8SPaul Thacker } 196*9e160ee8SPaul Thacker 197*9e160ee8SPaul Thacker DEBUG_UART_FUNCS 198*9e160ee8SPaul Thacker #endif 199