1 /* 2 * Copyright (c) 2014 The Chromium OS Authors. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <environment.h> 10 #include <errno.h> 11 #include <fdtdec.h> 12 #include <os.h> 13 #include <serial.h> 14 #include <stdio_dev.h> 15 #include <watchdog.h> 16 #include <dm/lists.h> 17 #include <dm/device-internal.h> 18 19 DECLARE_GLOBAL_DATA_PTR; 20 21 /* 22 * Table with supported baudrates (defined in config_xyz.h) 23 */ 24 static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE; 25 26 #ifndef CONFIG_SYS_MALLOC_F_LEN 27 #error "Serial is required before relocation - define CONFIG_SYS_MALLOC_F_LEN to make this work" 28 #endif 29 30 static void serial_find_console_or_panic(void) 31 { 32 struct udevice *dev; 33 int node; 34 35 if (OF_CONTROL) { 36 /* Check for a chosen console */ 37 node = fdtdec_get_chosen_node(gd->fdt_blob, "stdout-path"); 38 if (node < 0) 39 node = fdt_path_offset(gd->fdt_blob, "console"); 40 if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, 41 &dev)) { 42 gd->cur_serial_dev = dev; 43 return; 44 } 45 46 /* 47 * If the console is not marked to be bound before relocation, 48 * bind it anyway. 49 */ 50 if (node > 0 && 51 !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &dev)) { 52 if (!device_probe(dev)) { 53 gd->cur_serial_dev = dev; 54 return; 55 } 56 } 57 } else { 58 /* 59 * Try to use CONFIG_CONS_INDEX if available (it is numbered 60 * from 1!). 61 * 62 * Failing that, get the device with sequence number 0, or in 63 * extremis just the first serial device we can find. But we 64 * insist on having a console (even if it is silent). 65 */ 66 #ifdef CONFIG_CONS_INDEX 67 #define INDEX (CONFIG_CONS_INDEX - 1) 68 #else 69 #define INDEX 0 70 #endif 71 if (!uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) || 72 !uclass_get_device(UCLASS_SERIAL, INDEX, &dev) || 73 (!uclass_first_device(UCLASS_SERIAL, &dev) || dev)) { 74 gd->cur_serial_dev = dev; 75 return; 76 } 77 #undef INDEX 78 } 79 80 panic_str("No serial driver found"); 81 } 82 83 /* Called prior to relocation */ 84 int serial_init(void) 85 { 86 serial_find_console_or_panic(); 87 gd->flags |= GD_FLG_SERIAL_READY; 88 89 return 0; 90 } 91 92 /* Called after relocation */ 93 void serial_initialize(void) 94 { 95 serial_find_console_or_panic(); 96 } 97 98 static void _serial_putc(struct udevice *dev, char ch) 99 { 100 struct dm_serial_ops *ops = serial_get_ops(dev); 101 int err; 102 103 do { 104 err = ops->putc(dev, ch); 105 } while (err == -EAGAIN); 106 if (ch == '\n') 107 _serial_putc(dev, '\r'); 108 } 109 110 static void _serial_puts(struct udevice *dev, const char *str) 111 { 112 while (*str) 113 _serial_putc(dev, *str++); 114 } 115 116 static int _serial_getc(struct udevice *dev) 117 { 118 struct dm_serial_ops *ops = serial_get_ops(dev); 119 int err; 120 121 do { 122 err = ops->getc(dev); 123 if (err == -EAGAIN) 124 WATCHDOG_RESET(); 125 } while (err == -EAGAIN); 126 127 return err >= 0 ? err : 0; 128 } 129 130 static int _serial_tstc(struct udevice *dev) 131 { 132 struct dm_serial_ops *ops = serial_get_ops(dev); 133 134 if (ops->pending) 135 return ops->pending(dev, true); 136 137 return 1; 138 } 139 140 void serial_putc(char ch) 141 { 142 _serial_putc(gd->cur_serial_dev, ch); 143 } 144 145 void serial_puts(const char *str) 146 { 147 _serial_puts(gd->cur_serial_dev, str); 148 } 149 150 int serial_getc(void) 151 { 152 return _serial_getc(gd->cur_serial_dev); 153 } 154 155 int serial_tstc(void) 156 { 157 return _serial_tstc(gd->cur_serial_dev); 158 } 159 160 void serial_setbrg(void) 161 { 162 struct dm_serial_ops *ops = serial_get_ops(gd->cur_serial_dev); 163 164 if (ops->setbrg) 165 ops->setbrg(gd->cur_serial_dev, gd->baudrate); 166 } 167 168 void serial_stdio_init(void) 169 { 170 } 171 172 #ifdef CONFIG_DM_STDIO 173 static void serial_stub_putc(struct stdio_dev *sdev, const char ch) 174 { 175 _serial_putc(sdev->priv, ch); 176 } 177 #endif 178 179 void serial_stub_puts(struct stdio_dev *sdev, const char *str) 180 { 181 _serial_puts(sdev->priv, str); 182 } 183 184 int serial_stub_getc(struct stdio_dev *sdev) 185 { 186 return _serial_getc(sdev->priv); 187 } 188 189 int serial_stub_tstc(struct stdio_dev *sdev) 190 { 191 return _serial_tstc(sdev->priv); 192 } 193 194 /** 195 * on_baudrate() - Update the actual baudrate when the env var changes 196 * 197 * This will check for a valid baudrate and only apply it if valid. 198 */ 199 static int on_baudrate(const char *name, const char *value, enum env_op op, 200 int flags) 201 { 202 int i; 203 int baudrate; 204 205 switch (op) { 206 case env_op_create: 207 case env_op_overwrite: 208 /* 209 * Switch to new baudrate if new baudrate is supported 210 */ 211 baudrate = simple_strtoul(value, NULL, 10); 212 213 /* Not actually changing */ 214 if (gd->baudrate == baudrate) 215 return 0; 216 217 for (i = 0; i < ARRAY_SIZE(baudrate_table); ++i) { 218 if (baudrate == baudrate_table[i]) 219 break; 220 } 221 if (i == ARRAY_SIZE(baudrate_table)) { 222 if ((flags & H_FORCE) == 0) 223 printf("## Baudrate %d bps not supported\n", 224 baudrate); 225 return 1; 226 } 227 if ((flags & H_INTERACTIVE) != 0) { 228 printf("## Switch baudrate to %d bps and press ENTER ...\n", 229 baudrate); 230 udelay(50000); 231 } 232 233 gd->baudrate = baudrate; 234 235 serial_setbrg(); 236 237 udelay(50000); 238 239 if ((flags & H_INTERACTIVE) != 0) 240 while (1) { 241 if (getc() == '\r') 242 break; 243 } 244 245 return 0; 246 case env_op_delete: 247 printf("## Baudrate may not be deleted\n"); 248 return 1; 249 default: 250 return 0; 251 } 252 } 253 U_BOOT_ENV_CALLBACK(baudrate, on_baudrate); 254 255 static int serial_post_probe(struct udevice *dev) 256 { 257 struct dm_serial_ops *ops = serial_get_ops(dev); 258 #ifdef CONFIG_DM_STDIO 259 struct serial_dev_priv *upriv = dev_get_uclass_priv(dev); 260 struct stdio_dev sdev; 261 #endif 262 int ret; 263 264 #if defined(CONFIG_NEEDS_MANUAL_RELOC) 265 if (ops->setbrg) 266 ops->setbrg += gd->reloc_off; 267 if (ops->getc) 268 ops->getc += gd->reloc_off; 269 if (ops->putc) 270 ops->putc += gd->reloc_off; 271 if (ops->pending) 272 ops->pending += gd->reloc_off; 273 if (ops->clear) 274 ops->clear += gd->reloc_off; 275 #if CONFIG_POST & CONFIG_SYS_POST_UART 276 if (ops->loop) 277 ops->loop += gd->reloc_off 278 #endif 279 #endif 280 /* Set the baud rate */ 281 if (ops->setbrg) { 282 ret = ops->setbrg(dev, gd->baudrate); 283 if (ret) 284 return ret; 285 } 286 287 #ifdef CONFIG_DM_STDIO 288 if (!(gd->flags & GD_FLG_RELOC)) 289 return 0; 290 memset(&sdev, '\0', sizeof(sdev)); 291 292 strncpy(sdev.name, dev->name, sizeof(sdev.name)); 293 sdev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; 294 sdev.priv = dev; 295 sdev.putc = serial_stub_putc; 296 sdev.puts = serial_stub_puts; 297 sdev.getc = serial_stub_getc; 298 sdev.tstc = serial_stub_tstc; 299 stdio_register_dev(&sdev, &upriv->sdev); 300 #endif 301 return 0; 302 } 303 304 static int serial_pre_remove(struct udevice *dev) 305 { 306 #ifdef CONFIG_SYS_STDIO_DEREGISTER 307 struct serial_dev_priv *upriv = dev_get_uclass_priv(dev); 308 309 if (stdio_deregister_dev(upriv->sdev, 0)) 310 return -EPERM; 311 #endif 312 313 return 0; 314 } 315 316 UCLASS_DRIVER(serial) = { 317 .id = UCLASS_SERIAL, 318 .name = "serial", 319 .flags = DM_UC_FLAG_SEQ_ALIAS, 320 .post_probe = serial_post_probe, 321 .pre_remove = serial_pre_remove, 322 .per_device_auto_alloc_size = sizeof(struct serial_dev_priv), 323 }; 324