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