74a29c505e60af81f90d8800bc7303676e58fdc9
[openwrt/staging/mkresin.git] / target / linux / rtl838x / files-5.4 / arch / mips / rtl838x / serial.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * 8250 serial console setup for the Realtek RTL838X SoC
4 *
5 * based on the original BSP by
6 * Copyright (C) 2006-2012 Tony Wu (tonywu@realtek.com)
7 *
8 * Copyright (C) 2020 B. Koblitz
9 *
10 */
11
12 #include <linux/types.h>
13 #include <linux/ctype.h>
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/version.h>
17 #include <linux/serial.h>
18 #include <linux/serial_core.h>
19 #include <linux/serial_8250.h>
20 #include <linux/serial_reg.h>
21 #include <linux/tty.h>
22 #include <linux/clk.h>
23
24 #include <asm/mach-rtl838x/mach-rtl838x.h>
25
26 extern char arcs_cmdline[];
27 extern struct rtl838x_soc_info soc_info;
28
29 int __init rtl838x_serial_init(void)
30 {
31 #ifdef CONFIG_SERIAL_8250
32 int ret;
33 struct uart_port p;
34 unsigned long baud = 0;
35 int err;
36 char parity = '\0', bits = '\0', flow = '\0';
37 char *s;
38 struct device_node *dn;
39
40 dn = of_find_compatible_node(NULL, NULL, "ns16550a");
41 if (dn) {
42 pr_info("Found NS16550a: %s (%s)\n", dn->name, dn->full_name);
43 dn = of_find_compatible_node(dn, NULL, "ns16550a");
44 if (dn && of_device_is_available(dn) && soc_info.family == RTL8380_FAMILY_ID) {
45 /* Enable UART1 on RTL838x */
46 pr_info("Enabling uart1\n");
47 sw_w32(0x10, RTL838X_GMII_INTF_SEL);
48 }
49 } else {
50 pr_err("No NS16550a UART found!");
51 return -ENODEV;
52 }
53
54 s = strstr(arcs_cmdline, "console=ttyS0,");
55 if (s) {
56 s += 14;
57 err = kstrtoul(s, 10, &baud);
58 if (err)
59 baud = 0;
60 while (isdigit(*s))
61 s++;
62 if (*s == ',')
63 s++;
64 if (*s)
65 parity = *s++;
66 if (*s == ',')
67 s++;
68 if (*s)
69 bits = *s++;
70 if (*s == ',')
71 s++;
72 if (*s == 'h')
73 flow = 'r';
74 }
75
76 if (baud == 0) {
77 baud = 38400;
78 pr_warn("Using default baud rate: %lu\n", baud);
79 }
80 if (parity != 'n' && parity != 'o' && parity != 'e')
81 parity = 'n';
82 if (bits != '7' && bits != '8')
83 bits = '8';
84
85 memset(&p, 0, sizeof(p));
86
87 p.type = PORT_16550A;
88 p.membase = (unsigned char *) RTL838X_UART0_BASE;
89 p.irq = RTL838X_UART0_IRQ;
90 p.uartclk = SYSTEM_FREQ - (24 * baud);
91 p.flags = UPF_SKIP_TEST | UPF_LOW_LATENCY | UPF_FIXED_TYPE;
92 p.iotype = UPIO_MEM;
93 p.regshift = 2;
94 p.fifosize = 1;
95
96 /* Call early_serial_setup() here, to set up 8250 console driver */
97 if (early_serial_setup(&p) != 0)
98 ret = 1;
99 #endif
100 return 0;
101 }