1 /* 2 * Copyright 2013 Freescale Semiconductor, Inc. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <watchdog.h> 9 #include <asm/io.h> 10 #include <serial.h> 11 #include <linux/compiler.h> 12 #include <asm/arch/imx-regs.h> 13 #include <asm/arch/clock.h> 14 15 #define US1_TDRE (1 << 7) 16 #define US1_RDRF (1 << 5) 17 #define US1_OR (1 << 3) 18 #define UC2_TE (1 << 3) 19 #define UC2_RE (1 << 2) 20 #define CFIFO_TXFLUSH (1 << 7) 21 #define CFIFO_RXFLUSH (1 << 6) 22 #define SFIFO_RXOF (1 << 2) 23 #define SFIFO_RXUF (1 << 0) 24 25 DECLARE_GLOBAL_DATA_PTR; 26 27 struct lpuart_fsl *base = (struct lpuart_fsl *)LPUART_BASE; 28 29 static void lpuart_serial_setbrg(void) 30 { 31 u32 clk = mxc_get_clock(MXC_UART_CLK); 32 u16 sbr; 33 34 if (!gd->baudrate) 35 gd->baudrate = CONFIG_BAUDRATE; 36 37 sbr = (u16)(clk / (16 * gd->baudrate)); 38 /* place adjustment later - n/32 BRFA */ 39 40 __raw_writeb(sbr >> 8, &base->ubdh); 41 __raw_writeb(sbr & 0xff, &base->ubdl); 42 } 43 44 static int lpuart_serial_getc(void) 45 { 46 while (!(__raw_readb(&base->us1) & (US1_RDRF | US1_OR))) 47 WATCHDOG_RESET(); 48 49 barrier(); 50 51 return __raw_readb(&base->ud); 52 } 53 54 static void lpuart_serial_putc(const char c) 55 { 56 if (c == '\n') 57 serial_putc('\r'); 58 59 while (!(__raw_readb(&base->us1) & US1_TDRE)) 60 WATCHDOG_RESET(); 61 62 __raw_writeb(c, &base->ud); 63 } 64 65 /* 66 * Test whether a character is in the RX buffer 67 */ 68 static int lpuart_serial_tstc(void) 69 { 70 if (__raw_readb(&base->urcfifo) == 0) 71 return 0; 72 73 return 1; 74 } 75 76 /* 77 * Initialise the serial port with the given baudrate. The settings 78 * are always 8 data bits, no parity, 1 stop bit, no start bits. 79 */ 80 static int lpuart_serial_init(void) 81 { 82 u8 ctrl; 83 84 ctrl = __raw_readb(&base->uc2); 85 ctrl &= ~UC2_RE; 86 ctrl &= ~UC2_TE; 87 __raw_writeb(ctrl, &base->uc2); 88 89 __raw_writeb(0, &base->umodem); 90 __raw_writeb(0, &base->uc1); 91 92 /* Disable FIFO and flush buffer */ 93 __raw_writeb(0x0, &base->upfifo); 94 __raw_writeb(0x0, &base->utwfifo); 95 __raw_writeb(0x1, &base->urwfifo); 96 __raw_writeb(CFIFO_TXFLUSH | CFIFO_RXFLUSH, &base->ucfifo); 97 98 /* provide data bits, parity, stop bit, etc */ 99 100 serial_setbrg(); 101 102 __raw_writeb(UC2_RE | UC2_TE, &base->uc2); 103 104 return 0; 105 } 106 107 static struct serial_device lpuart_serial_drv = { 108 .name = "lpuart_serial", 109 .start = lpuart_serial_init, 110 .stop = NULL, 111 .setbrg = lpuart_serial_setbrg, 112 .putc = lpuart_serial_putc, 113 .puts = default_serial_puts, 114 .getc = lpuart_serial_getc, 115 .tstc = lpuart_serial_tstc, 116 }; 117 118 void lpuart_serial_initialize(void) 119 { 120 serial_register(&lpuart_serial_drv); 121 } 122 123 __weak struct serial_device *default_serial_console(void) 124 { 125 return &lpuart_serial_drv; 126 } 127