17742aa65SMarek Vasut /* 27742aa65SMarek Vasut * (C) Copyright 2004 37742aa65SMarek Vasut * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 47742aa65SMarek Vasut * 57742aa65SMarek Vasut * See file CREDITS for list of people who contributed to this 67742aa65SMarek Vasut * project. 77742aa65SMarek Vasut * 87742aa65SMarek Vasut * This program is free software; you can redistribute it and/or 97742aa65SMarek Vasut * modify it under the terms of the GNU General Public License as 107742aa65SMarek Vasut * published by the Free Software Foundation; either version 2 of 117742aa65SMarek Vasut * the License, or (at your option) any later version. 127742aa65SMarek Vasut * 137742aa65SMarek Vasut * This program is distributed in the hope that it will be useful, 147742aa65SMarek Vasut * but WITHOUT ANY WARRANTY; without even the implied warranty of 157742aa65SMarek Vasut * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 167742aa65SMarek Vasut * GNU General Public License for more details. 177742aa65SMarek Vasut * 187742aa65SMarek Vasut * You should have received a copy of the GNU General Public License 197742aa65SMarek Vasut * along with this program; if not, write to the Free Software 207742aa65SMarek Vasut * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 217742aa65SMarek Vasut * MA 02111-1307 USA 227742aa65SMarek Vasut */ 237742aa65SMarek Vasut 247742aa65SMarek Vasut #include <common.h> 257742aa65SMarek Vasut #include <serial.h> 267742aa65SMarek Vasut #include <stdio_dev.h> 277742aa65SMarek Vasut #include <post.h> 287742aa65SMarek Vasut #include <linux/compiler.h> 296d93e258SMarek Vasut #include <errno.h> 307742aa65SMarek Vasut 317742aa65SMarek Vasut DECLARE_GLOBAL_DATA_PTR; 327742aa65SMarek Vasut 337742aa65SMarek Vasut static struct serial_device *serial_devices; 347742aa65SMarek Vasut static struct serial_device *serial_current; 357742aa65SMarek Vasut 36*9cd2b9e4SMarek Vasut /** 37*9cd2b9e4SMarek Vasut * serial_null() - Void registration routine of a serial driver 38*9cd2b9e4SMarek Vasut * 39*9cd2b9e4SMarek Vasut * This routine implements a void registration routine of a serial 40*9cd2b9e4SMarek Vasut * driver. The registration routine of a particular driver is aliased 41*9cd2b9e4SMarek Vasut * to this empty function in case the driver is not compiled into 42*9cd2b9e4SMarek Vasut * U-Boot. 43*9cd2b9e4SMarek Vasut */ 447742aa65SMarek Vasut static void serial_null(void) 457742aa65SMarek Vasut { 467742aa65SMarek Vasut } 477742aa65SMarek Vasut 48*9cd2b9e4SMarek Vasut /** 49*9cd2b9e4SMarek Vasut * serial_initfunc() - Forward declare of driver registration routine 50*9cd2b9e4SMarek Vasut * @name: Name of the real driver registration routine. 51*9cd2b9e4SMarek Vasut * 52*9cd2b9e4SMarek Vasut * This macro expands onto forward declaration of a driver registration 53*9cd2b9e4SMarek Vasut * routine, which is then used below in serial_initialize() function. 54*9cd2b9e4SMarek Vasut * The declaration is made weak and aliases to serial_null() so in case 55*9cd2b9e4SMarek Vasut * the driver is not compiled in, the function is still declared and can 56*9cd2b9e4SMarek Vasut * be used, but aliases to serial_null() and thus is optimized away. 57*9cd2b9e4SMarek Vasut */ 587742aa65SMarek Vasut #define serial_initfunc(name) \ 597742aa65SMarek Vasut void name(void) \ 607742aa65SMarek Vasut __attribute__((weak, alias("serial_null"))); 617742aa65SMarek Vasut 627742aa65SMarek Vasut serial_initfunc(mpc8xx_serial_initialize); 637742aa65SMarek Vasut serial_initfunc(ns16550_serial_initialize); 647742aa65SMarek Vasut serial_initfunc(pxa_serial_initialize); 657742aa65SMarek Vasut serial_initfunc(s3c24xx_serial_initialize); 667742aa65SMarek Vasut serial_initfunc(s5p_serial_initialize); 677742aa65SMarek Vasut serial_initfunc(zynq_serial_initalize); 687742aa65SMarek Vasut serial_initfunc(bfin_serial_initialize); 697742aa65SMarek Vasut serial_initfunc(bfin_jtag_initialize); 707742aa65SMarek Vasut serial_initfunc(mpc512x_serial_initialize); 717742aa65SMarek Vasut serial_initfunc(uartlite_serial_initialize); 727742aa65SMarek Vasut serial_initfunc(au1x00_serial_initialize); 737742aa65SMarek Vasut serial_initfunc(asc_serial_initialize); 747742aa65SMarek Vasut serial_initfunc(jz_serial_initialize); 757742aa65SMarek Vasut serial_initfunc(mpc5xx_serial_initialize); 767742aa65SMarek Vasut serial_initfunc(mpc8220_serial_initialize); 777742aa65SMarek Vasut serial_initfunc(mpc8260_scc_serial_initialize); 787742aa65SMarek Vasut serial_initfunc(mpc8260_smc_serial_initialize); 797742aa65SMarek Vasut serial_initfunc(mpc85xx_serial_initialize); 807742aa65SMarek Vasut serial_initfunc(iop480_serial_initialize); 817742aa65SMarek Vasut serial_initfunc(leon2_serial_initialize); 827742aa65SMarek Vasut serial_initfunc(leon3_serial_initialize); 837742aa65SMarek Vasut serial_initfunc(marvell_serial_initialize); 847742aa65SMarek Vasut serial_initfunc(amirix_serial_initialize); 857742aa65SMarek Vasut serial_initfunc(bmw_serial_initialize); 867742aa65SMarek Vasut serial_initfunc(cogent_serial_initialize); 877742aa65SMarek Vasut serial_initfunc(cpci750_serial_initialize); 887742aa65SMarek Vasut serial_initfunc(evb64260_serial_initialize); 897742aa65SMarek Vasut serial_initfunc(ml2_serial_initialize); 907742aa65SMarek Vasut serial_initfunc(sconsole_serial_initialize); 917742aa65SMarek Vasut serial_initfunc(p3mx_serial_initialize); 927742aa65SMarek Vasut serial_initfunc(altera_jtag_serial_initialize); 937742aa65SMarek Vasut serial_initfunc(altera_serial_initialize); 947742aa65SMarek Vasut serial_initfunc(atmel_serial_initialize); 957742aa65SMarek Vasut serial_initfunc(lpc32xx_serial_initialize); 967742aa65SMarek Vasut serial_initfunc(mcf_serial_initialize); 977742aa65SMarek Vasut serial_initfunc(ns9750_serial_initialize); 987742aa65SMarek Vasut serial_initfunc(oc_serial_initialize); 997742aa65SMarek Vasut serial_initfunc(s3c4510b_serial_initialize); 1007742aa65SMarek Vasut serial_initfunc(s3c64xx_serial_initialize); 1017742aa65SMarek Vasut serial_initfunc(sandbox_serial_initialize); 1027742aa65SMarek Vasut serial_initfunc(clps7111_serial_initialize); 1037742aa65SMarek Vasut serial_initfunc(imx_serial_initialize); 1047742aa65SMarek Vasut serial_initfunc(ixp_serial_initialize); 1057742aa65SMarek Vasut serial_initfunc(ks8695_serial_initialize); 1067742aa65SMarek Vasut serial_initfunc(lh7a40x_serial_initialize); 1077742aa65SMarek Vasut serial_initfunc(lpc2292_serial_initialize); 1087742aa65SMarek Vasut serial_initfunc(max3100_serial_initialize); 1097742aa65SMarek Vasut serial_initfunc(mxc_serial_initialize); 1107742aa65SMarek Vasut serial_initfunc(netarm_serial_initialize); 1117742aa65SMarek Vasut serial_initfunc(pl01x_serial_initialize); 1127742aa65SMarek Vasut serial_initfunc(s3c44b0_serial_initialize); 1137742aa65SMarek Vasut serial_initfunc(sa1100_serial_initialize); 1147742aa65SMarek Vasut serial_initfunc(sh_serial_initialize); 1157742aa65SMarek Vasut 116*9cd2b9e4SMarek Vasut /** 117*9cd2b9e4SMarek Vasut * serial_register() - Register serial driver with serial driver core 118*9cd2b9e4SMarek Vasut * @dev: Pointer to the serial driver structure 119*9cd2b9e4SMarek Vasut * 120*9cd2b9e4SMarek Vasut * This function registers the serial driver supplied via @dev with 121*9cd2b9e4SMarek Vasut * serial driver core, thus making U-Boot aware of it and making it 122*9cd2b9e4SMarek Vasut * available for U-Boot to use. On platforms that still require manual 123*9cd2b9e4SMarek Vasut * relocation of constant variables, relocation of the supplied structure 124*9cd2b9e4SMarek Vasut * is performed. 125*9cd2b9e4SMarek Vasut */ 1267742aa65SMarek Vasut void serial_register(struct serial_device *dev) 1277742aa65SMarek Vasut { 1287742aa65SMarek Vasut #ifdef CONFIG_NEEDS_MANUAL_RELOC 129f2760c4aSMarek Vasut if (dev->start) 1307742aa65SMarek Vasut dev->start += gd->reloc_off; 131f2760c4aSMarek Vasut if (dev->stop) 132f2760c4aSMarek Vasut dev->stop += gd->reloc_off; 133f2760c4aSMarek Vasut if (dev->setbrg) 1347742aa65SMarek Vasut dev->setbrg += gd->reloc_off; 135f2760c4aSMarek Vasut if (dev->getc) 1367742aa65SMarek Vasut dev->getc += gd->reloc_off; 137f2760c4aSMarek Vasut if (dev->tstc) 1387742aa65SMarek Vasut dev->tstc += gd->reloc_off; 139f2760c4aSMarek Vasut if (dev->putc) 1407742aa65SMarek Vasut dev->putc += gd->reloc_off; 141f2760c4aSMarek Vasut if (dev->puts) 1427742aa65SMarek Vasut dev->puts += gd->reloc_off; 1437742aa65SMarek Vasut #endif 1447742aa65SMarek Vasut 1457742aa65SMarek Vasut dev->next = serial_devices; 1467742aa65SMarek Vasut serial_devices = dev; 1477742aa65SMarek Vasut } 1487742aa65SMarek Vasut 149*9cd2b9e4SMarek Vasut /** 150*9cd2b9e4SMarek Vasut * serial_initialize() - Register all compiled-in serial port drivers 151*9cd2b9e4SMarek Vasut * 152*9cd2b9e4SMarek Vasut * This function registers all serial port drivers that are compiled 153*9cd2b9e4SMarek Vasut * into the U-Boot binary with the serial core, thus making them 154*9cd2b9e4SMarek Vasut * available to U-Boot to use. Lastly, this function assigns a default 155*9cd2b9e4SMarek Vasut * serial port to the serial core. That serial port is then used as a 156*9cd2b9e4SMarek Vasut * default output. 157*9cd2b9e4SMarek Vasut */ 1587742aa65SMarek Vasut void serial_initialize(void) 1597742aa65SMarek Vasut { 1607742aa65SMarek Vasut mpc8xx_serial_initialize(); 1617742aa65SMarek Vasut ns16550_serial_initialize(); 1627742aa65SMarek Vasut pxa_serial_initialize(); 1637742aa65SMarek Vasut s3c24xx_serial_initialize(); 1647742aa65SMarek Vasut s5p_serial_initialize(); 1657742aa65SMarek Vasut mpc512x_serial_initialize(); 1667742aa65SMarek Vasut bfin_serial_initialize(); 1677742aa65SMarek Vasut bfin_jtag_initialize(); 1687742aa65SMarek Vasut uartlite_serial_initialize(); 1697742aa65SMarek Vasut zynq_serial_initalize(); 1707742aa65SMarek Vasut au1x00_serial_initialize(); 1717742aa65SMarek Vasut asc_serial_initialize(); 1727742aa65SMarek Vasut jz_serial_initialize(); 1737742aa65SMarek Vasut mpc5xx_serial_initialize(); 1747742aa65SMarek Vasut mpc8220_serial_initialize(); 1757742aa65SMarek Vasut mpc8260_scc_serial_initialize(); 1767742aa65SMarek Vasut mpc8260_smc_serial_initialize(); 1777742aa65SMarek Vasut mpc85xx_serial_initialize(); 1787742aa65SMarek Vasut iop480_serial_initialize(); 1797742aa65SMarek Vasut leon2_serial_initialize(); 1807742aa65SMarek Vasut leon3_serial_initialize(); 1817742aa65SMarek Vasut marvell_serial_initialize(); 1827742aa65SMarek Vasut amirix_serial_initialize(); 1837742aa65SMarek Vasut bmw_serial_initialize(); 1847742aa65SMarek Vasut cogent_serial_initialize(); 1857742aa65SMarek Vasut cpci750_serial_initialize(); 1867742aa65SMarek Vasut evb64260_serial_initialize(); 1877742aa65SMarek Vasut ml2_serial_initialize(); 1887742aa65SMarek Vasut sconsole_serial_initialize(); 1897742aa65SMarek Vasut p3mx_serial_initialize(); 1907742aa65SMarek Vasut altera_jtag_serial_initialize(); 1917742aa65SMarek Vasut altera_serial_initialize(); 1927742aa65SMarek Vasut atmel_serial_initialize(); 1937742aa65SMarek Vasut lpc32xx_serial_initialize(); 1947742aa65SMarek Vasut mcf_serial_initialize(); 1957742aa65SMarek Vasut ns9750_serial_initialize(); 1967742aa65SMarek Vasut oc_serial_initialize(); 1977742aa65SMarek Vasut s3c4510b_serial_initialize(); 1987742aa65SMarek Vasut s3c64xx_serial_initialize(); 1997742aa65SMarek Vasut sandbox_serial_initialize(); 2007742aa65SMarek Vasut clps7111_serial_initialize(); 2017742aa65SMarek Vasut imx_serial_initialize(); 2027742aa65SMarek Vasut ixp_serial_initialize(); 2037742aa65SMarek Vasut ks8695_serial_initialize(); 2047742aa65SMarek Vasut lh7a40x_serial_initialize(); 2057742aa65SMarek Vasut lpc2292_serial_initialize(); 2067742aa65SMarek Vasut max3100_serial_initialize(); 2077742aa65SMarek Vasut mxc_serial_initialize(); 2087742aa65SMarek Vasut netarm_serial_initialize(); 2097742aa65SMarek Vasut pl01x_serial_initialize(); 2107742aa65SMarek Vasut s3c44b0_serial_initialize(); 2117742aa65SMarek Vasut sa1100_serial_initialize(); 2127742aa65SMarek Vasut sh_serial_initialize(); 2137742aa65SMarek Vasut 2147742aa65SMarek Vasut serial_assign(default_serial_console()->name); 2157742aa65SMarek Vasut } 2167742aa65SMarek Vasut 217*9cd2b9e4SMarek Vasut /** 218*9cd2b9e4SMarek Vasut * serial_stdio_init() - Register serial ports with STDIO core 219*9cd2b9e4SMarek Vasut * 220*9cd2b9e4SMarek Vasut * This function generates a proxy driver for each serial port driver. 221*9cd2b9e4SMarek Vasut * These proxy drivers then register with the STDIO core, making the 222*9cd2b9e4SMarek Vasut * serial drivers available as STDIO devices. 223*9cd2b9e4SMarek Vasut */ 2247742aa65SMarek Vasut void serial_stdio_init(void) 2257742aa65SMarek Vasut { 2267742aa65SMarek Vasut struct stdio_dev dev; 2277742aa65SMarek Vasut struct serial_device *s = serial_devices; 2287742aa65SMarek Vasut 2297742aa65SMarek Vasut while (s) { 2307742aa65SMarek Vasut memset(&dev, 0, sizeof(dev)); 2317742aa65SMarek Vasut 2327742aa65SMarek Vasut strcpy(dev.name, s->name); 2337742aa65SMarek Vasut dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; 2347742aa65SMarek Vasut 2357742aa65SMarek Vasut dev.start = s->start; 2367742aa65SMarek Vasut dev.stop = s->stop; 2377742aa65SMarek Vasut dev.putc = s->putc; 2387742aa65SMarek Vasut dev.puts = s->puts; 2397742aa65SMarek Vasut dev.getc = s->getc; 2407742aa65SMarek Vasut dev.tstc = s->tstc; 2417742aa65SMarek Vasut 2427742aa65SMarek Vasut stdio_register(&dev); 2437742aa65SMarek Vasut 2447742aa65SMarek Vasut s = s->next; 2457742aa65SMarek Vasut } 2467742aa65SMarek Vasut } 2477742aa65SMarek Vasut 248*9cd2b9e4SMarek Vasut /** 249*9cd2b9e4SMarek Vasut * serial_assign() - Select the serial output device by name 250*9cd2b9e4SMarek Vasut * @name: Name of the serial driver to be used as default output 251*9cd2b9e4SMarek Vasut * 252*9cd2b9e4SMarek Vasut * This function configures the serial output multiplexing by 253*9cd2b9e4SMarek Vasut * selecting which serial device will be used as default. In case 254*9cd2b9e4SMarek Vasut * the STDIO "serial" device is selected as stdin/stdout/stderr, 255*9cd2b9e4SMarek Vasut * the serial device previously configured by this function will be 256*9cd2b9e4SMarek Vasut * used for the particular operation. 257*9cd2b9e4SMarek Vasut * 258*9cd2b9e4SMarek Vasut * Returns 0 on success, negative on error. 259*9cd2b9e4SMarek Vasut */ 2607742aa65SMarek Vasut int serial_assign(const char *name) 2617742aa65SMarek Vasut { 2627742aa65SMarek Vasut struct serial_device *s; 2637742aa65SMarek Vasut 2647742aa65SMarek Vasut for (s = serial_devices; s; s = s->next) { 2656d93e258SMarek Vasut if (strcmp(s->name, name)) 2666d93e258SMarek Vasut continue; 2677742aa65SMarek Vasut serial_current = s; 2687742aa65SMarek Vasut return 0; 2697742aa65SMarek Vasut } 2707742aa65SMarek Vasut 2716d93e258SMarek Vasut return -EINVAL; 2727742aa65SMarek Vasut } 2737742aa65SMarek Vasut 274*9cd2b9e4SMarek Vasut /** 275*9cd2b9e4SMarek Vasut * serial_reinit_all() - Reinitialize all compiled-in serial ports 276*9cd2b9e4SMarek Vasut * 277*9cd2b9e4SMarek Vasut * This function reinitializes all serial ports that are compiled 278*9cd2b9e4SMarek Vasut * into U-Boot by calling their serial_start() functions. 279*9cd2b9e4SMarek Vasut */ 2807742aa65SMarek Vasut void serial_reinit_all(void) 2817742aa65SMarek Vasut { 2827742aa65SMarek Vasut struct serial_device *s; 2837742aa65SMarek Vasut 2847742aa65SMarek Vasut for (s = serial_devices; s; s = s->next) 2857742aa65SMarek Vasut s->start(); 2867742aa65SMarek Vasut } 2877742aa65SMarek Vasut 288*9cd2b9e4SMarek Vasut /** 289*9cd2b9e4SMarek Vasut * get_current() - Return pointer to currently selected serial port 290*9cd2b9e4SMarek Vasut * 291*9cd2b9e4SMarek Vasut * This function returns a pointer to currently selected serial port. 292*9cd2b9e4SMarek Vasut * The currently selected serial port is altered by serial_assign() 293*9cd2b9e4SMarek Vasut * function. 294*9cd2b9e4SMarek Vasut * 295*9cd2b9e4SMarek Vasut * In case this function is called before relocation or before any serial 296*9cd2b9e4SMarek Vasut * port is configured, this function calls default_serial_console() to 297*9cd2b9e4SMarek Vasut * determine the serial port. Otherwise, the configured serial port is 298*9cd2b9e4SMarek Vasut * returned. 299*9cd2b9e4SMarek Vasut * 300*9cd2b9e4SMarek Vasut * Returns pointer to the currently selected serial port on success, 301*9cd2b9e4SMarek Vasut * NULL on error. 302*9cd2b9e4SMarek Vasut */ 3037742aa65SMarek Vasut static struct serial_device *get_current(void) 3047742aa65SMarek Vasut { 3057742aa65SMarek Vasut struct serial_device *dev; 3067742aa65SMarek Vasut 307dee19416SMarek Vasut if (!(gd->flags & GD_FLG_RELOC)) 3087742aa65SMarek Vasut dev = default_serial_console(); 309dee19416SMarek Vasut else if (!serial_current) 310dee19416SMarek Vasut dev = default_serial_console(); 311dee19416SMarek Vasut else 312dee19416SMarek Vasut dev = serial_current; 3137742aa65SMarek Vasut 3147742aa65SMarek Vasut /* We must have a console device */ 3157742aa65SMarek Vasut if (!dev) { 3167742aa65SMarek Vasut #ifdef CONFIG_SPL_BUILD 3177742aa65SMarek Vasut puts("Cannot find console\n"); 3187742aa65SMarek Vasut hang(); 3197742aa65SMarek Vasut #else 3207742aa65SMarek Vasut panic("Cannot find console\n"); 3217742aa65SMarek Vasut #endif 3227742aa65SMarek Vasut } 323dee19416SMarek Vasut 3247742aa65SMarek Vasut return dev; 3257742aa65SMarek Vasut } 3267742aa65SMarek Vasut 327*9cd2b9e4SMarek Vasut /** 328*9cd2b9e4SMarek Vasut * serial_init() - Initialize currently selected serial port 329*9cd2b9e4SMarek Vasut * 330*9cd2b9e4SMarek Vasut * This function initializes the currently selected serial port. This 331*9cd2b9e4SMarek Vasut * usually involves setting up the registers of that particular port, 332*9cd2b9e4SMarek Vasut * enabling clock and such. This function uses the get_current() call 333*9cd2b9e4SMarek Vasut * to determine which port is selected. 334*9cd2b9e4SMarek Vasut * 335*9cd2b9e4SMarek Vasut * Returns 0 on success, negative on error. 336*9cd2b9e4SMarek Vasut */ 3377742aa65SMarek Vasut int serial_init(void) 3387742aa65SMarek Vasut { 3397742aa65SMarek Vasut return get_current()->start(); 3407742aa65SMarek Vasut } 3417742aa65SMarek Vasut 342*9cd2b9e4SMarek Vasut /** 343*9cd2b9e4SMarek Vasut * serial_setbrg() - Configure baud-rate of currently selected serial port 344*9cd2b9e4SMarek Vasut * 345*9cd2b9e4SMarek Vasut * This function configures the baud-rate of the currently selected 346*9cd2b9e4SMarek Vasut * serial port. The baud-rate is retrieved from global data within 347*9cd2b9e4SMarek Vasut * the serial port driver. This function uses the get_current() call 348*9cd2b9e4SMarek Vasut * to determine which port is selected. 349*9cd2b9e4SMarek Vasut * 350*9cd2b9e4SMarek Vasut * Returns 0 on success, negative on error. 351*9cd2b9e4SMarek Vasut */ 3527742aa65SMarek Vasut void serial_setbrg(void) 3537742aa65SMarek Vasut { 3547742aa65SMarek Vasut get_current()->setbrg(); 3557742aa65SMarek Vasut } 3567742aa65SMarek Vasut 357*9cd2b9e4SMarek Vasut /** 358*9cd2b9e4SMarek Vasut * serial_getc() - Read character from currently selected serial port 359*9cd2b9e4SMarek Vasut * 360*9cd2b9e4SMarek Vasut * This function retrieves a character from currently selected serial 361*9cd2b9e4SMarek Vasut * port. In case there is no character waiting on the serial port, 362*9cd2b9e4SMarek Vasut * this function will block and wait for the character to appear. This 363*9cd2b9e4SMarek Vasut * function uses the get_current() call to determine which port is 364*9cd2b9e4SMarek Vasut * selected. 365*9cd2b9e4SMarek Vasut * 366*9cd2b9e4SMarek Vasut * Returns the character on success, negative on error. 367*9cd2b9e4SMarek Vasut */ 3687742aa65SMarek Vasut int serial_getc(void) 3697742aa65SMarek Vasut { 3707742aa65SMarek Vasut return get_current()->getc(); 3717742aa65SMarek Vasut } 3727742aa65SMarek Vasut 373*9cd2b9e4SMarek Vasut /** 374*9cd2b9e4SMarek Vasut * serial_tstc() - Test if data is available on currently selected serial port 375*9cd2b9e4SMarek Vasut * 376*9cd2b9e4SMarek Vasut * This function tests if one or more characters are available on 377*9cd2b9e4SMarek Vasut * currently selected serial port. This function never blocks. This 378*9cd2b9e4SMarek Vasut * function uses the get_current() call to determine which port is 379*9cd2b9e4SMarek Vasut * selected. 380*9cd2b9e4SMarek Vasut * 381*9cd2b9e4SMarek Vasut * Returns positive if character is available, zero otherwise. 382*9cd2b9e4SMarek Vasut */ 3837742aa65SMarek Vasut int serial_tstc(void) 3847742aa65SMarek Vasut { 3857742aa65SMarek Vasut return get_current()->tstc(); 3867742aa65SMarek Vasut } 3877742aa65SMarek Vasut 388*9cd2b9e4SMarek Vasut /** 389*9cd2b9e4SMarek Vasut * serial_putc() - Output character via currently selected serial port 390*9cd2b9e4SMarek Vasut * @c: Single character to be output from the serial port. 391*9cd2b9e4SMarek Vasut * 392*9cd2b9e4SMarek Vasut * This function outputs a character via currently selected serial 393*9cd2b9e4SMarek Vasut * port. This character is passed to the serial port driver responsible 394*9cd2b9e4SMarek Vasut * for controlling the hardware. The hardware may still be in process 395*9cd2b9e4SMarek Vasut * of transmitting another character, therefore this function may block 396*9cd2b9e4SMarek Vasut * for a short amount of time. This function uses the get_current() 397*9cd2b9e4SMarek Vasut * call to determine which port is selected. 398*9cd2b9e4SMarek Vasut */ 3997742aa65SMarek Vasut void serial_putc(const char c) 4007742aa65SMarek Vasut { 4017742aa65SMarek Vasut get_current()->putc(c); 4027742aa65SMarek Vasut } 4037742aa65SMarek Vasut 404*9cd2b9e4SMarek Vasut /** 405*9cd2b9e4SMarek Vasut * serial_puts() - Output string via currently selected serial port 406*9cd2b9e4SMarek Vasut * @s: Zero-terminated string to be output from the serial port. 407*9cd2b9e4SMarek Vasut * 408*9cd2b9e4SMarek Vasut * This function outputs a zero-terminated string via currently 409*9cd2b9e4SMarek Vasut * selected serial port. This function behaves as an accelerator 410*9cd2b9e4SMarek Vasut * in case the hardware can queue multiple characters for transfer. 411*9cd2b9e4SMarek Vasut * The whole string that is to be output is available to the function 412*9cd2b9e4SMarek Vasut * implementing the hardware manipulation. Transmitting the whole 413*9cd2b9e4SMarek Vasut * string may take some time, thus this function may block for some 414*9cd2b9e4SMarek Vasut * amount of time. This function uses the get_current() call to 415*9cd2b9e4SMarek Vasut * determine which port is selected. 416*9cd2b9e4SMarek Vasut */ 4177742aa65SMarek Vasut void serial_puts(const char *s) 4187742aa65SMarek Vasut { 4197742aa65SMarek Vasut get_current()->puts(s); 4207742aa65SMarek Vasut } 4217742aa65SMarek Vasut 422*9cd2b9e4SMarek Vasut /** 423*9cd2b9e4SMarek Vasut * default_serial_puts() - Output string by calling serial_putc() in loop 424*9cd2b9e4SMarek Vasut * @s: Zero-terminated string to be output from the serial port. 425*9cd2b9e4SMarek Vasut * 426*9cd2b9e4SMarek Vasut * This function outputs a zero-terminated string by calling serial_putc() 427*9cd2b9e4SMarek Vasut * in a loop. Most drivers do not support queueing more than one byte for 428*9cd2b9e4SMarek Vasut * transfer, thus this function precisely implements their serial_puts(). 429*9cd2b9e4SMarek Vasut * 430*9cd2b9e4SMarek Vasut * To optimize the number of get_current() calls, this function only 431*9cd2b9e4SMarek Vasut * calls get_current() once and then directly accesses the putc() call 432*9cd2b9e4SMarek Vasut * of the &struct serial_device . 433*9cd2b9e4SMarek Vasut */ 434bfb7d7a3SMarek Vasut void default_serial_puts(const char *s) 435bfb7d7a3SMarek Vasut { 436bfb7d7a3SMarek Vasut struct serial_device *dev = get_current(); 437bfb7d7a3SMarek Vasut while (*s) 438bfb7d7a3SMarek Vasut dev->putc(*s++); 439bfb7d7a3SMarek Vasut } 440bfb7d7a3SMarek Vasut 4417742aa65SMarek Vasut #if CONFIG_POST & CONFIG_SYS_POST_UART 4427742aa65SMarek Vasut static const int bauds[] = CONFIG_SYS_BAUDRATE_TABLE; 4437742aa65SMarek Vasut 444*9cd2b9e4SMarek Vasut /** 445*9cd2b9e4SMarek Vasut * uart_post_test() - Test the currently selected serial port using POST 446*9cd2b9e4SMarek Vasut * @flags: POST framework flags 447*9cd2b9e4SMarek Vasut * 448*9cd2b9e4SMarek Vasut * Do a loopback test of the currently selected serial port. This 449*9cd2b9e4SMarek Vasut * function is only useful in the context of the POST testing framwork. 450*9cd2b9e4SMarek Vasut * The serial port is firstly configured into loopback mode and then 451*9cd2b9e4SMarek Vasut * characters are sent through it. 452*9cd2b9e4SMarek Vasut * 453*9cd2b9e4SMarek Vasut * Returns 0 on success, value otherwise. 454*9cd2b9e4SMarek Vasut */ 4557742aa65SMarek Vasut /* Mark weak until post/cpu/.../uart.c migrate over */ 4567742aa65SMarek Vasut __weak 4577742aa65SMarek Vasut int uart_post_test(int flags) 4587742aa65SMarek Vasut { 4597742aa65SMarek Vasut unsigned char c; 4607742aa65SMarek Vasut int ret, saved_baud, b; 4617742aa65SMarek Vasut struct serial_device *saved_dev, *s; 4627742aa65SMarek Vasut bd_t *bd = gd->bd; 4637742aa65SMarek Vasut 4647742aa65SMarek Vasut /* Save current serial state */ 4657742aa65SMarek Vasut ret = 0; 4667742aa65SMarek Vasut saved_dev = serial_current; 4677742aa65SMarek Vasut saved_baud = bd->bi_baudrate; 4687742aa65SMarek Vasut 4697742aa65SMarek Vasut for (s = serial_devices; s; s = s->next) { 4707742aa65SMarek Vasut /* If this driver doesn't support loop back, skip it */ 4717742aa65SMarek Vasut if (!s->loop) 4727742aa65SMarek Vasut continue; 4737742aa65SMarek Vasut 4747742aa65SMarek Vasut /* Test the next device */ 4757742aa65SMarek Vasut serial_current = s; 4767742aa65SMarek Vasut 4777742aa65SMarek Vasut ret = serial_init(); 4787742aa65SMarek Vasut if (ret) 4797742aa65SMarek Vasut goto done; 4807742aa65SMarek Vasut 4817742aa65SMarek Vasut /* Consume anything that happens to be queued */ 4827742aa65SMarek Vasut while (serial_tstc()) 4837742aa65SMarek Vasut serial_getc(); 4847742aa65SMarek Vasut 4857742aa65SMarek Vasut /* Enable loop back */ 4867742aa65SMarek Vasut s->loop(1); 4877742aa65SMarek Vasut 4887742aa65SMarek Vasut /* Test every available baud rate */ 4897742aa65SMarek Vasut for (b = 0; b < ARRAY_SIZE(bauds); ++b) { 4907742aa65SMarek Vasut bd->bi_baudrate = bauds[b]; 4917742aa65SMarek Vasut serial_setbrg(); 4927742aa65SMarek Vasut 4937742aa65SMarek Vasut /* 4947742aa65SMarek Vasut * Stick to printable chars to avoid issues: 4957742aa65SMarek Vasut * - terminal corruption 4967742aa65SMarek Vasut * - serial program reacting to sequences and sending 4977742aa65SMarek Vasut * back random extra data 4987742aa65SMarek Vasut * - most serial drivers add in extra chars (like \r\n) 4997742aa65SMarek Vasut */ 5007742aa65SMarek Vasut for (c = 0x20; c < 0x7f; ++c) { 5017742aa65SMarek Vasut /* Send it out */ 5027742aa65SMarek Vasut serial_putc(c); 5037742aa65SMarek Vasut 5047742aa65SMarek Vasut /* Make sure it's the same one */ 5057742aa65SMarek Vasut ret = (c != serial_getc()); 5067742aa65SMarek Vasut if (ret) { 5077742aa65SMarek Vasut s->loop(0); 5087742aa65SMarek Vasut goto done; 5097742aa65SMarek Vasut } 5107742aa65SMarek Vasut 5117742aa65SMarek Vasut /* Clean up the output in case it was sent */ 5127742aa65SMarek Vasut serial_putc('\b'); 5137742aa65SMarek Vasut ret = ('\b' != serial_getc()); 5147742aa65SMarek Vasut if (ret) { 5157742aa65SMarek Vasut s->loop(0); 5167742aa65SMarek Vasut goto done; 5177742aa65SMarek Vasut } 5187742aa65SMarek Vasut } 5197742aa65SMarek Vasut } 5207742aa65SMarek Vasut 5217742aa65SMarek Vasut /* Disable loop back */ 5227742aa65SMarek Vasut s->loop(0); 5237742aa65SMarek Vasut 5247742aa65SMarek Vasut /* XXX: There is no serial_stop() !? */ 5257742aa65SMarek Vasut if (s->stop) 5267742aa65SMarek Vasut s->stop(); 5277742aa65SMarek Vasut } 5287742aa65SMarek Vasut 5297742aa65SMarek Vasut done: 5307742aa65SMarek Vasut /* Restore previous serial state */ 5317742aa65SMarek Vasut serial_current = saved_dev; 5327742aa65SMarek Vasut bd->bi_baudrate = saved_baud; 5337742aa65SMarek Vasut serial_reinit_all(); 5347742aa65SMarek Vasut serial_setbrg(); 5357742aa65SMarek Vasut 5367742aa65SMarek Vasut return ret; 5377742aa65SMarek Vasut } 5387742aa65SMarek Vasut #endif 539