1 /* 2 * SuperH SCIF device driver. 3 * Copyright (C) 2013 Renesas Electronics Corporation 4 * Copyright (C) 2007,2008,2010 Nobuhiro Iwamatsu 5 * Copyright (C) 2002 - 2008 Paul Mundt 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10 #include <common.h> 11 #include <asm/io.h> 12 #include <asm/processor.h> 13 #include "serial_sh.h" 14 #include <serial.h> 15 #include <linux/compiler.h> 16 17 #if defined(CONFIG_CONS_SCIF0) 18 # define SCIF_BASE SCIF0_BASE 19 #elif defined(CONFIG_CONS_SCIF1) 20 # define SCIF_BASE SCIF1_BASE 21 #elif defined(CONFIG_CONS_SCIF2) 22 # define SCIF_BASE SCIF2_BASE 23 #elif defined(CONFIG_CONS_SCIF3) 24 # define SCIF_BASE SCIF3_BASE 25 #elif defined(CONFIG_CONS_SCIF4) 26 # define SCIF_BASE SCIF4_BASE 27 #elif defined(CONFIG_CONS_SCIF5) 28 # define SCIF_BASE SCIF5_BASE 29 #elif defined(CONFIG_CONS_SCIF6) 30 # define SCIF_BASE SCIF6_BASE 31 #elif defined(CONFIG_CONS_SCIF7) 32 # define SCIF_BASE SCIF7_BASE 33 #else 34 # error "Default SCIF doesn't set....." 35 #endif 36 37 #if defined(CONFIG_SCIF_A) 38 #define SCIF_BASE_PORT PORT_SCIFA 39 #else 40 #define SCIF_BASE_PORT PORT_SCIF 41 #endif 42 43 static struct uart_port sh_sci = { 44 .membase = (unsigned char*)SCIF_BASE, 45 .mapbase = SCIF_BASE, 46 .type = SCIF_BASE_PORT, 47 }; 48 49 static void sh_serial_setbrg(void) 50 { 51 DECLARE_GLOBAL_DATA_PTR; 52 53 sci_out(&sh_sci, SCBRR, 54 SCBRR_VALUE(gd->baudrate, CONFIG_SH_SCIF_CLK_FREQ)); 55 } 56 57 static int sh_serial_init(void) 58 { 59 sci_out(&sh_sci, SCSCR , SCSCR_INIT(&sh_sci)); 60 sci_out(&sh_sci, SCSCR , SCSCR_INIT(&sh_sci)); 61 sci_out(&sh_sci, SCSMR, 0); 62 sci_out(&sh_sci, SCSMR, 0); 63 sci_out(&sh_sci, SCFCR, SCFCR_RFRST|SCFCR_TFRST); 64 sci_in(&sh_sci, SCFCR); 65 sci_out(&sh_sci, SCFCR, 0); 66 67 serial_setbrg(); 68 return 0; 69 } 70 71 #if defined(CONFIG_CPU_SH7760) || \ 72 defined(CONFIG_CPU_SH7780) || \ 73 defined(CONFIG_CPU_SH7785) || \ 74 defined(CONFIG_CPU_SH7786) 75 static int scif_rxfill(struct uart_port *port) 76 { 77 return sci_in(port, SCRFDR) & 0xff; 78 } 79 #elif defined(CONFIG_CPU_SH7763) 80 static int scif_rxfill(struct uart_port *port) 81 { 82 if ((port->mapbase == 0xffe00000) || 83 (port->mapbase == 0xffe08000)) { 84 /* SCIF0/1*/ 85 return sci_in(port, SCRFDR) & 0xff; 86 } else { 87 /* SCIF2 */ 88 return sci_in(port, SCFDR) & SCIF2_RFDC_MASK; 89 } 90 } 91 #elif defined(CONFIG_ARCH_SH7372) 92 static int scif_rxfill(struct uart_port *port) 93 { 94 if (port->type == PORT_SCIFA) 95 return sci_in(port, SCFDR) & SCIF_RFDC_MASK; 96 else 97 return sci_in(port, SCRFDR); 98 } 99 #else 100 static int scif_rxfill(struct uart_port *port) 101 { 102 return sci_in(port, SCFDR) & SCIF_RFDC_MASK; 103 } 104 #endif 105 106 static int serial_rx_fifo_level(void) 107 { 108 return scif_rxfill(&sh_sci); 109 } 110 111 static void handle_error(void) 112 { 113 sci_in(&sh_sci, SCxSR); 114 sci_out(&sh_sci, SCxSR, SCxSR_ERROR_CLEAR(&sh_sci)); 115 sci_in(&sh_sci, SCLSR); 116 sci_out(&sh_sci, SCLSR, 0x00); 117 } 118 119 void serial_raw_putc(const char c) 120 { 121 while (1) { 122 /* Tx fifo is empty */ 123 if (sci_in(&sh_sci, SCxSR) & SCxSR_TEND(&sh_sci)) 124 break; 125 } 126 127 sci_out(&sh_sci, SCxTDR, c); 128 sci_out(&sh_sci, SCxSR, sci_in(&sh_sci, SCxSR) & ~SCxSR_TEND(&sh_sci)); 129 } 130 131 static void sh_serial_putc(const char c) 132 { 133 if (c == '\n') 134 serial_raw_putc('\r'); 135 serial_raw_putc(c); 136 } 137 138 static int sh_serial_tstc(void) 139 { 140 if (sci_in(&sh_sci, SCxSR) & SCIF_ERRORS) { 141 handle_error(); 142 return 0; 143 } 144 145 return serial_rx_fifo_level() ? 1 : 0; 146 } 147 148 149 int serial_getc_check(void) 150 { 151 unsigned short status; 152 153 status = sci_in(&sh_sci, SCxSR); 154 155 if (status & SCIF_ERRORS) 156 handle_error(); 157 if (sci_in(&sh_sci, SCLSR) & SCxSR_ORER(&sh_sci)) 158 handle_error(); 159 return status & (SCIF_DR | SCxSR_RDxF(&sh_sci)); 160 } 161 162 static int sh_serial_getc(void) 163 { 164 unsigned short status; 165 char ch; 166 167 while (!serial_getc_check()) 168 ; 169 170 ch = sci_in(&sh_sci, SCxRDR); 171 status = sci_in(&sh_sci, SCxSR); 172 173 sci_out(&sh_sci, SCxSR, SCxSR_RDxF_CLEAR(&sh_sci)); 174 175 if (status & SCIF_ERRORS) 176 handle_error(); 177 178 if (sci_in(&sh_sci, SCLSR) & SCxSR_ORER(&sh_sci)) 179 handle_error(); 180 return ch; 181 } 182 183 static struct serial_device sh_serial_drv = { 184 .name = "sh_serial", 185 .start = sh_serial_init, 186 .stop = NULL, 187 .setbrg = sh_serial_setbrg, 188 .putc = sh_serial_putc, 189 .puts = default_serial_puts, 190 .getc = sh_serial_getc, 191 .tstc = sh_serial_tstc, 192 }; 193 194 void sh_serial_initialize(void) 195 { 196 serial_register(&sh_serial_drv); 197 } 198 199 __weak struct serial_device *default_serial_console(void) 200 { 201 return &sh_serial_drv; 202 } 203