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 UC2_TE (1 << 3) 18 #define UC2_RE (1 << 2) 19 20 DECLARE_GLOBAL_DATA_PTR; 21 22 struct lpuart_fsl *base = (struct lpuart_fsl *)LPUART_BASE; 23 24 static void lpuart_serial_setbrg(void) 25 { 26 u32 clk = mxc_get_clock(MXC_UART_CLK); 27 u16 sbr; 28 29 if (!gd->baudrate) 30 gd->baudrate = CONFIG_BAUDRATE; 31 32 sbr = (u16)(clk / (16 * gd->baudrate)); 33 /* place adjustment later - n/32 BRFA */ 34 35 __raw_writeb(sbr >> 8, &base->ubdh); 36 __raw_writeb(sbr & 0xff, &base->ubdl); 37 } 38 39 static int lpuart_serial_getc(void) 40 { 41 u8 status; 42 43 while (!(__raw_readb(&base->us1) & US1_RDRF)) 44 WATCHDOG_RESET(); 45 46 status = __raw_readb(&base->us1); 47 status |= US1_RDRF; 48 __raw_writeb(status, &base->us1); 49 50 return __raw_readb(&base->ud); 51 } 52 53 static void lpuart_serial_putc(const char c) 54 { 55 if (c == '\n') 56 serial_putc('\r'); 57 58 while (!(__raw_readb(&base->us1) & US1_TDRE)) 59 WATCHDOG_RESET(); 60 61 __raw_writeb(c, &base->ud); 62 } 63 64 /* 65 * Test whether a character is in the RX buffer 66 */ 67 static int lpuart_serial_tstc(void) 68 { 69 if (__raw_readb(&base->urcfifo) == 0) 70 return 0; 71 72 return 1; 73 } 74 75 /* 76 * Initialise the serial port with the given baudrate. The settings 77 * are always 8 data bits, no parity, 1 stop bit, no start bits. 78 */ 79 static int lpuart_serial_init(void) 80 { 81 u8 ctrl; 82 83 ctrl = __raw_readb(&base->uc2); 84 ctrl &= ~UC2_RE; 85 ctrl &= ~UC2_TE; 86 __raw_writeb(ctrl, &base->uc2); 87 88 __raw_writeb(0, &base->umodem); 89 __raw_writeb(0, &base->uc1); 90 91 /* provide data bits, parity, stop bit, etc */ 92 93 serial_setbrg(); 94 95 __raw_writeb(UC2_RE | UC2_TE, &base->uc2); 96 97 return 0; 98 } 99 100 static struct serial_device lpuart_serial_drv = { 101 .name = "lpuart_serial", 102 .start = lpuart_serial_init, 103 .stop = NULL, 104 .setbrg = lpuart_serial_setbrg, 105 .putc = lpuart_serial_putc, 106 .puts = default_serial_puts, 107 .getc = lpuart_serial_getc, 108 .tstc = lpuart_serial_tstc, 109 }; 110 111 void lpuart_serial_initialize(void) 112 { 113 serial_register(&lpuart_serial_drv); 114 } 115 116 __weak struct serial_device *default_serial_console(void) 117 { 118 return &lpuart_serial_drv; 119 } 120