1/* 2 * (C) Copyright 2004 3 * DAVE Srl 4 * http://www.dave-tech.it 5 * http://www.wawnet.biz 6 * mailto:info@wawnet.biz 7 * 8 * (C) Copyright 2002-2004 9 * Wolfgang Denk, DENX Software Engineering, <wd@denx.de> 10 * 11 * (C) Copyright 2002 12 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> 13 * Marius Groeger <mgroeger@sysgo.de> 14 * 15 * (C) Copyright 2002 16 * Sysgo Real-Time Solutions, GmbH <www.elinos.com> 17 * Alex Zuepke <azu@sysgo.de> 18 * 19 * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) 20 * 21 * This program is free software; you can redistribute it and/or modify 22 * it under the terms of the GNU General Public License as published by 23 * the Free Software Foundation; either version 2 of the License, or 24 * (at your option) any later version. 25 * 26 * This program is distributed in the hope that it will be useful, 27 * but WITHOUT ANY WARRANTY; without even the implied warranty of 28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29 * GNU General Public License for more details. 30 * 31 * You should have received a copy of the GNU General Public License 32 * along with this program; if not, write to the Free Software 33 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 34 * 35 */ 36 37#include <common.h> 38#include <asm/hardware.h> 39 40DECLARE_GLOBAL_DATA_PTR; 41 42/* flush serial input queue. returns 0 on success or negative error 43 * number otherwise 44 */ 45static int serial_flush_input(void) 46{ 47 volatile u32 tmp; 48 49 /* keep on reading as long as the receiver is not empty */ 50 while(UTRSTAT0&0x01) { 51 tmp = REGB(URXH0); 52 } 53 54 return 0; 55} 56 57 58/* flush output queue. returns 0 on success or negative error number 59 * otherwise 60 */ 61static int serial_flush_output(void) 62{ 63 /* wait until the transmitter is no longer busy */ 64 while(!(UTRSTAT0 & 0x02)) { 65 } 66 67 return 0; 68} 69 70 71void serial_setbrg (void) 72{ 73 u32 divisor = 0; 74 75 /* get correct divisor */ 76 switch(gd->baudrate) { 77 78 case 1200: 79#if CONFIG_S3C44B0_CLOCK_SPEED==66 80 divisor = 3124; 81#elif CONFIG_S3C44B0_CLOCK_SPEED==75 82 divisor = 3905; 83#else 84# error CONFIG_S3C44B0_CLOCK_SPEED undefined 85#endif 86 break; 87 88 case 9600: 89#if CONFIG_S3C44B0_CLOCK_SPEED==66 90 divisor = 390; 91#elif CONFIG_S3C44B0_CLOCK_SPEED==75 92 divisor = 487; 93#else 94# error CONFIG_S3C44B0_CLOCK_SPEED undefined 95#endif 96 break; 97 98 case 19200: 99#if CONFIG_S3C44B0_CLOCK_SPEED==66 100 divisor = 194; 101#elif CONFIG_S3C44B0_CLOCK_SPEED==75 102 divisor = 243; 103#else 104# error CONFIG_S3C44B0_CLOCK_SPEED undefined 105#endif 106 break; 107 108 case 38400: 109#if CONFIG_S3C44B0_CLOCK_SPEED==66 110 divisor = 97; 111#elif CONFIG_S3C44B0_CLOCK_SPEED==75 112 divisor = 121; 113#else 114# error CONFIG_S3C44B0_CLOCK_SPEED undefined 115#endif /* break; */ 116 117 case 57600: 118#if CONFIG_S3C44B0_CLOCK_SPEED==66 119 divisor = 64; 120#elif CONFIG_S3C44B0_CLOCK_SPEED==75 121 divisor = 80; 122#else 123# error CONFIG_S3C44B0_CLOCK_SPEED undefined 124#endif /* break; */ 125 126 case 115200: 127#if CONFIG_S3C44B0_CLOCK_SPEED==66 128 divisor = 32; 129#elif CONFIG_S3C44B0_CLOCK_SPEED==75 130 divisor = 40; 131#else 132# error CONFIG_S3C44B0_CLOCK_SPEED undefined 133#endif /* break; */ 134 } 135 136 serial_flush_output(); 137 serial_flush_input(); 138 UFCON0 = 0x0; 139 ULCON0 = 0x03; 140 UCON0 = 0x05; 141 UBRDIV0 = divisor; 142 143 UFCON1 = 0x0; 144 ULCON1 = 0x03; 145 UCON1 = 0x05; 146 UBRDIV1 = divisor; 147 148 for(divisor=0; divisor<100; divisor++) { 149 /* NOP */ 150 } 151} 152 153 154/* 155 * Initialise the serial port with the given baudrate. The settings 156 * are always 8 data bits, no parity, 1 stop bit, no start bits. 157 * 158 */ 159int serial_init (void) 160{ 161 serial_setbrg (); 162 163 return (0); 164} 165 166 167/* 168 * Output a single byte to the serial port. 169 */ 170void serial_putc (const char c) 171{ 172 /* wait for room in the transmit FIFO */ 173 while(!(UTRSTAT0 & 0x02)); 174 175 UTXH0 = (unsigned char)c; 176 177 /* 178 to be polite with serial console add a line feed 179 to the carriage return character 180 */ 181 if (c=='\n') 182 serial_putc('\r'); 183} 184 185/* 186 * Read a single byte from the serial port. Returns 1 on success, 0 187 * otherwise. When the function is succesfull, the character read is 188 * written into its argument c. 189 */ 190int serial_tstc (void) 191{ 192 return (UTRSTAT0 & 0x01); 193} 194 195/* 196 * Read a single byte from the serial port. Returns 1 on success, 0 197 * otherwise. When the function is succesfull, the character read is 198 * written into its argument c. 199 */ 200int serial_getc (void) 201{ 202 int rv; 203 204 for(;;) { 205 rv = serial_tstc(); 206 207 if(rv > 0) 208 return URXH0; 209 } 210} 211 212void 213serial_puts (const char *s) 214{ 215 while (*s) { 216 serial_putc (*s++); 217 } 218} 219