1*7f368553SMasahiro Yamada /* 2*7f368553SMasahiro Yamada * Copyright (C) 2012-2014 Panasonic Corporation 3*7f368553SMasahiro Yamada * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> 4*7f368553SMasahiro Yamada * 5*7f368553SMasahiro Yamada * Based on serial_ns16550.c 6*7f368553SMasahiro Yamada * (C) Copyright 2000 7*7f368553SMasahiro Yamada * Rob Taylor, Flying Pig Systems. robt@flyingpig.com. 8*7f368553SMasahiro Yamada * 9*7f368553SMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+ 10*7f368553SMasahiro Yamada */ 11*7f368553SMasahiro Yamada 12*7f368553SMasahiro Yamada #include <common.h> 13*7f368553SMasahiro Yamada #include <serial.h> 14*7f368553SMasahiro Yamada 15*7f368553SMasahiro Yamada #define UART_REG(x) \ 16*7f368553SMasahiro Yamada u8 x; \ 17*7f368553SMasahiro Yamada u8 postpad_##x[3]; 18*7f368553SMasahiro Yamada 19*7f368553SMasahiro Yamada /* 20*7f368553SMasahiro Yamada * Note: Register map is slightly different from that of 16550. 21*7f368553SMasahiro Yamada */ 22*7f368553SMasahiro Yamada struct uniphier_serial { 23*7f368553SMasahiro Yamada UART_REG(rbr); /* 0x00 */ 24*7f368553SMasahiro Yamada UART_REG(ier); /* 0x04 */ 25*7f368553SMasahiro Yamada UART_REG(iir); /* 0x08 */ 26*7f368553SMasahiro Yamada UART_REG(fcr); /* 0x0c */ 27*7f368553SMasahiro Yamada u8 mcr; /* 0x10 */ 28*7f368553SMasahiro Yamada u8 lcr; 29*7f368553SMasahiro Yamada u16 __postpad; 30*7f368553SMasahiro Yamada UART_REG(lsr); /* 0x14 */ 31*7f368553SMasahiro Yamada UART_REG(msr); /* 0x18 */ 32*7f368553SMasahiro Yamada u32 __none1; 33*7f368553SMasahiro Yamada u32 __none2; 34*7f368553SMasahiro Yamada u16 dlr; 35*7f368553SMasahiro Yamada u16 __postpad2; 36*7f368553SMasahiro Yamada }; 37*7f368553SMasahiro Yamada 38*7f368553SMasahiro Yamada #define thr rbr 39*7f368553SMasahiro Yamada 40*7f368553SMasahiro Yamada /* 41*7f368553SMasahiro Yamada * These are the definitions for the Line Control Register 42*7f368553SMasahiro Yamada */ 43*7f368553SMasahiro Yamada #define UART_LCR_WLS_8 0x03 /* 8 bit character length */ 44*7f368553SMasahiro Yamada 45*7f368553SMasahiro Yamada /* 46*7f368553SMasahiro Yamada * These are the definitions for the Line Status Register 47*7f368553SMasahiro Yamada */ 48*7f368553SMasahiro Yamada #define UART_LSR_DR 0x01 /* Data ready */ 49*7f368553SMasahiro Yamada #define UART_LSR_THRE 0x20 /* Xmit holding register empty */ 50*7f368553SMasahiro Yamada 51*7f368553SMasahiro Yamada DECLARE_GLOBAL_DATA_PTR; 52*7f368553SMasahiro Yamada 53*7f368553SMasahiro Yamada static void uniphier_serial_init(struct uniphier_serial *port) 54*7f368553SMasahiro Yamada { 55*7f368553SMasahiro Yamada const unsigned int mode_x_div = 16; 56*7f368553SMasahiro Yamada unsigned int divisor; 57*7f368553SMasahiro Yamada 58*7f368553SMasahiro Yamada writeb(UART_LCR_WLS_8, &port->lcr); 59*7f368553SMasahiro Yamada 60*7f368553SMasahiro Yamada divisor = DIV_ROUND_CLOSEST(CONFIG_SYS_UNIPHIER_UART_CLK, 61*7f368553SMasahiro Yamada mode_x_div * gd->baudrate); 62*7f368553SMasahiro Yamada 63*7f368553SMasahiro Yamada writew(divisor, &port->dlr); 64*7f368553SMasahiro Yamada } 65*7f368553SMasahiro Yamada 66*7f368553SMasahiro Yamada static void uniphier_serial_setbrg(struct uniphier_serial *port) 67*7f368553SMasahiro Yamada { 68*7f368553SMasahiro Yamada uniphier_serial_init(port); 69*7f368553SMasahiro Yamada } 70*7f368553SMasahiro Yamada 71*7f368553SMasahiro Yamada static int uniphier_serial_tstc(struct uniphier_serial *port) 72*7f368553SMasahiro Yamada { 73*7f368553SMasahiro Yamada return (readb(&port->lsr) & UART_LSR_DR) != 0; 74*7f368553SMasahiro Yamada } 75*7f368553SMasahiro Yamada 76*7f368553SMasahiro Yamada static int uniphier_serial_getc(struct uniphier_serial *port) 77*7f368553SMasahiro Yamada { 78*7f368553SMasahiro Yamada while (!uniphier_serial_tstc(port)) 79*7f368553SMasahiro Yamada ; 80*7f368553SMasahiro Yamada 81*7f368553SMasahiro Yamada return readb(&port->rbr); 82*7f368553SMasahiro Yamada } 83*7f368553SMasahiro Yamada 84*7f368553SMasahiro Yamada static void uniphier_serial_putc(struct uniphier_serial *port, const char c) 85*7f368553SMasahiro Yamada { 86*7f368553SMasahiro Yamada if (c == '\n') 87*7f368553SMasahiro Yamada uniphier_serial_putc(port, '\r'); 88*7f368553SMasahiro Yamada 89*7f368553SMasahiro Yamada while (!(readb(&port->lsr) & UART_LSR_THRE)) 90*7f368553SMasahiro Yamada ; 91*7f368553SMasahiro Yamada 92*7f368553SMasahiro Yamada writeb(c, &port->thr); 93*7f368553SMasahiro Yamada } 94*7f368553SMasahiro Yamada 95*7f368553SMasahiro Yamada static struct uniphier_serial *serial_ports[4] = { 96*7f368553SMasahiro Yamada #ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE0 97*7f368553SMasahiro Yamada (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE0, 98*7f368553SMasahiro Yamada #else 99*7f368553SMasahiro Yamada NULL, 100*7f368553SMasahiro Yamada #endif 101*7f368553SMasahiro Yamada #ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE1 102*7f368553SMasahiro Yamada (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE1, 103*7f368553SMasahiro Yamada #else 104*7f368553SMasahiro Yamada NULL, 105*7f368553SMasahiro Yamada #endif 106*7f368553SMasahiro Yamada #ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE2 107*7f368553SMasahiro Yamada (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE2, 108*7f368553SMasahiro Yamada #else 109*7f368553SMasahiro Yamada NULL, 110*7f368553SMasahiro Yamada #endif 111*7f368553SMasahiro Yamada #ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE3 112*7f368553SMasahiro Yamada (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE3, 113*7f368553SMasahiro Yamada #else 114*7f368553SMasahiro Yamada NULL, 115*7f368553SMasahiro Yamada #endif 116*7f368553SMasahiro Yamada }; 117*7f368553SMasahiro Yamada 118*7f368553SMasahiro Yamada /* Multi serial device functions */ 119*7f368553SMasahiro Yamada #define DECLARE_ESERIAL_FUNCTIONS(port) \ 120*7f368553SMasahiro Yamada static int eserial##port##_init(void) \ 121*7f368553SMasahiro Yamada { \ 122*7f368553SMasahiro Yamada uniphier_serial_init(serial_ports[port]); \ 123*7f368553SMasahiro Yamada return 0 ; \ 124*7f368553SMasahiro Yamada } \ 125*7f368553SMasahiro Yamada static void eserial##port##_setbrg(void) \ 126*7f368553SMasahiro Yamada { \ 127*7f368553SMasahiro Yamada uniphier_serial_setbrg(serial_ports[port]); \ 128*7f368553SMasahiro Yamada } \ 129*7f368553SMasahiro Yamada static int eserial##port##_getc(void) \ 130*7f368553SMasahiro Yamada { \ 131*7f368553SMasahiro Yamada return uniphier_serial_getc(serial_ports[port]); \ 132*7f368553SMasahiro Yamada } \ 133*7f368553SMasahiro Yamada static int eserial##port##_tstc(void) \ 134*7f368553SMasahiro Yamada { \ 135*7f368553SMasahiro Yamada return uniphier_serial_tstc(serial_ports[port]); \ 136*7f368553SMasahiro Yamada } \ 137*7f368553SMasahiro Yamada static void eserial##port##_putc(const char c) \ 138*7f368553SMasahiro Yamada { \ 139*7f368553SMasahiro Yamada uniphier_serial_putc(serial_ports[port], c); \ 140*7f368553SMasahiro Yamada } 141*7f368553SMasahiro Yamada 142*7f368553SMasahiro Yamada /* Serial device descriptor */ 143*7f368553SMasahiro Yamada #define INIT_ESERIAL_STRUCTURE(port, __name) { \ 144*7f368553SMasahiro Yamada .name = __name, \ 145*7f368553SMasahiro Yamada .start = eserial##port##_init, \ 146*7f368553SMasahiro Yamada .stop = NULL, \ 147*7f368553SMasahiro Yamada .setbrg = eserial##port##_setbrg, \ 148*7f368553SMasahiro Yamada .getc = eserial##port##_getc, \ 149*7f368553SMasahiro Yamada .tstc = eserial##port##_tstc, \ 150*7f368553SMasahiro Yamada .putc = eserial##port##_putc, \ 151*7f368553SMasahiro Yamada .puts = default_serial_puts, \ 152*7f368553SMasahiro Yamada } 153*7f368553SMasahiro Yamada 154*7f368553SMasahiro Yamada #if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0) 155*7f368553SMasahiro Yamada DECLARE_ESERIAL_FUNCTIONS(0); 156*7f368553SMasahiro Yamada struct serial_device uniphier_serial0_device = 157*7f368553SMasahiro Yamada INIT_ESERIAL_STRUCTURE(0, "ttyS0"); 158*7f368553SMasahiro Yamada #endif 159*7f368553SMasahiro Yamada #if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1) 160*7f368553SMasahiro Yamada DECLARE_ESERIAL_FUNCTIONS(1); 161*7f368553SMasahiro Yamada struct serial_device uniphier_serial1_device = 162*7f368553SMasahiro Yamada INIT_ESERIAL_STRUCTURE(1, "ttyS1"); 163*7f368553SMasahiro Yamada #endif 164*7f368553SMasahiro Yamada #if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2) 165*7f368553SMasahiro Yamada DECLARE_ESERIAL_FUNCTIONS(2); 166*7f368553SMasahiro Yamada struct serial_device uniphier_serial2_device = 167*7f368553SMasahiro Yamada INIT_ESERIAL_STRUCTURE(2, "ttyS2"); 168*7f368553SMasahiro Yamada #endif 169*7f368553SMasahiro Yamada #if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3) 170*7f368553SMasahiro Yamada DECLARE_ESERIAL_FUNCTIONS(3); 171*7f368553SMasahiro Yamada struct serial_device uniphier_serial3_device = 172*7f368553SMasahiro Yamada INIT_ESERIAL_STRUCTURE(3, "ttyS3"); 173*7f368553SMasahiro Yamada #endif 174*7f368553SMasahiro Yamada 175*7f368553SMasahiro Yamada __weak struct serial_device *default_serial_console(void) 176*7f368553SMasahiro Yamada { 177*7f368553SMasahiro Yamada #if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0) 178*7f368553SMasahiro Yamada return &uniphier_serial0_device; 179*7f368553SMasahiro Yamada #elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1) 180*7f368553SMasahiro Yamada return &uniphier_serial1_device; 181*7f368553SMasahiro Yamada #elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2) 182*7f368553SMasahiro Yamada return &uniphier_serial2_device; 183*7f368553SMasahiro Yamada #elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3) 184*7f368553SMasahiro Yamada return &uniphier_serial3_device; 185*7f368553SMasahiro Yamada #else 186*7f368553SMasahiro Yamada #error "No uniphier serial ports configured." 187*7f368553SMasahiro Yamada #endif 188*7f368553SMasahiro Yamada } 189*7f368553SMasahiro Yamada 190*7f368553SMasahiro Yamada void uniphier_serial_initialize(void) 191*7f368553SMasahiro Yamada { 192*7f368553SMasahiro Yamada #if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0) 193*7f368553SMasahiro Yamada serial_register(&uniphier_serial0_device); 194*7f368553SMasahiro Yamada #endif 195*7f368553SMasahiro Yamada #if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1) 196*7f368553SMasahiro Yamada serial_register(&uniphier_serial1_device); 197*7f368553SMasahiro Yamada #endif 198*7f368553SMasahiro Yamada #if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2) 199*7f368553SMasahiro Yamada serial_register(&uniphier_serial2_device); 200*7f368553SMasahiro Yamada #endif 201*7f368553SMasahiro Yamada #if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3) 202*7f368553SMasahiro Yamada serial_register(&uniphier_serial3_device); 203*7f368553SMasahiro Yamada #endif 204*7f368553SMasahiro Yamada } 205