1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * linux/arch/arm/mach-omap1/serial.c |
4 | * |
5 | * OMAP1 serial support. |
6 | */ |
7 | #include <linux/gpio/machine.h> |
8 | #include <linux/gpio/consumer.h> |
9 | #include <linux/module.h> |
10 | #include <linux/kernel.h> |
11 | #include <linux/init.h> |
12 | #include <linux/irq.h> |
13 | #include <linux/delay.h> |
14 | #include <linux/serial.h> |
15 | #include <linux/tty.h> |
16 | #include <linux/serial_8250.h> |
17 | #include <linux/serial_reg.h> |
18 | #include <linux/clk.h> |
19 | #include <linux/io.h> |
20 | |
21 | #include <asm/mach-types.h> |
22 | |
23 | #include "common.h" |
24 | #include "serial.h" |
25 | #include "mux.h" |
26 | #include "pm.h" |
27 | #include "soc.h" |
28 | |
29 | static struct clk * uart1_ck; |
30 | static struct clk * uart2_ck; |
31 | static struct clk * uart3_ck; |
32 | |
33 | static inline unsigned int omap_serial_in(struct plat_serial8250_port *up, |
34 | int offset) |
35 | { |
36 | offset <<= up->regshift; |
37 | return (unsigned int)__raw_readb(addr: up->membase + offset); |
38 | } |
39 | |
40 | static inline void omap_serial_outp(struct plat_serial8250_port *p, int offset, |
41 | int value) |
42 | { |
43 | offset <<= p->regshift; |
44 | __raw_writeb(val: value, addr: p->membase + offset); |
45 | } |
46 | |
47 | /* |
48 | * Internal UARTs need to be initialized for the 8250 autoconfig to work |
49 | * properly. Note that the TX watermark initialization may not be needed |
50 | * once the 8250.c watermark handling code is merged. |
51 | */ |
52 | static void __init omap_serial_reset(struct plat_serial8250_port *p) |
53 | { |
54 | omap_serial_outp(p, UART_OMAP_MDR1, |
55 | UART_OMAP_MDR1_DISABLE); /* disable UART */ |
56 | omap_serial_outp(p, UART_OMAP_SCR, value: 0x08); /* TX watermark */ |
57 | omap_serial_outp(p, UART_OMAP_MDR1, |
58 | UART_OMAP_MDR1_16X_MODE); /* enable UART */ |
59 | |
60 | if (!cpu_is_omap15xx()) { |
61 | omap_serial_outp(p, UART_OMAP_SYSC, value: 0x01); |
62 | while (!(omap_serial_in(up: p, UART_OMAP_SYSC) & 0x01)); |
63 | } |
64 | } |
65 | |
66 | static struct plat_serial8250_port serial_platform_data[] = { |
67 | { |
68 | .mapbase = OMAP1_UART1_BASE, |
69 | .irq = INT_UART1, |
70 | .flags = UPF_BOOT_AUTOCONF, |
71 | .iotype = UPIO_MEM, |
72 | .regshift = 2, |
73 | .uartclk = OMAP16XX_BASE_BAUD * 16, |
74 | }, |
75 | { |
76 | .mapbase = OMAP1_UART2_BASE, |
77 | .irq = INT_UART2, |
78 | .flags = UPF_BOOT_AUTOCONF, |
79 | .iotype = UPIO_MEM, |
80 | .regshift = 2, |
81 | .uartclk = OMAP16XX_BASE_BAUD * 16, |
82 | }, |
83 | { |
84 | .mapbase = OMAP1_UART3_BASE, |
85 | .irq = INT_UART3, |
86 | .flags = UPF_BOOT_AUTOCONF, |
87 | .iotype = UPIO_MEM, |
88 | .regshift = 2, |
89 | .uartclk = OMAP16XX_BASE_BAUD * 16, |
90 | }, |
91 | { }, |
92 | }; |
93 | |
94 | static struct platform_device serial_device = { |
95 | .name = "serial8250" , |
96 | .id = PLAT8250_DEV_PLATFORM, |
97 | .dev = { |
98 | .platform_data = serial_platform_data, |
99 | }, |
100 | }; |
101 | |
102 | /* |
103 | * Note that on Innovator-1510 UART2 pins conflict with USB2. |
104 | * By default UART2 does not work on Innovator-1510 if you have |
105 | * USB OHCI enabled. To use UART2, you must disable USB2 first. |
106 | */ |
107 | void __init omap_serial_init(void) |
108 | { |
109 | int i; |
110 | |
111 | if (cpu_is_omap15xx()) { |
112 | serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16; |
113 | serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16; |
114 | serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16; |
115 | } |
116 | |
117 | for (i = 0; i < ARRAY_SIZE(serial_platform_data) - 1; i++) { |
118 | /* Static mapping, never released */ |
119 | serial_platform_data[i].membase = |
120 | ioremap(offset: serial_platform_data[i].mapbase, SZ_2K); |
121 | if (!serial_platform_data[i].membase) { |
122 | printk(KERN_ERR "Could not ioremap uart%i\n" , i); |
123 | continue; |
124 | } |
125 | switch (i) { |
126 | case 0: |
127 | uart1_ck = clk_get(NULL, id: "uart1_ck" ); |
128 | if (IS_ERR(ptr: uart1_ck)) |
129 | printk("Could not get uart1_ck\n" ); |
130 | else { |
131 | clk_prepare_enable(clk: uart1_ck); |
132 | if (cpu_is_omap15xx()) |
133 | clk_set_rate(clk: uart1_ck, rate: 12000000); |
134 | } |
135 | break; |
136 | case 1: |
137 | uart2_ck = clk_get(NULL, id: "uart2_ck" ); |
138 | if (IS_ERR(ptr: uart2_ck)) |
139 | printk("Could not get uart2_ck\n" ); |
140 | else { |
141 | clk_prepare_enable(clk: uart2_ck); |
142 | if (cpu_is_omap15xx()) |
143 | clk_set_rate(clk: uart2_ck, rate: 12000000); |
144 | else |
145 | clk_set_rate(clk: uart2_ck, rate: 48000000); |
146 | } |
147 | break; |
148 | case 2: |
149 | uart3_ck = clk_get(NULL, id: "uart3_ck" ); |
150 | if (IS_ERR(ptr: uart3_ck)) |
151 | printk("Could not get uart3_ck\n" ); |
152 | else { |
153 | clk_prepare_enable(clk: uart3_ck); |
154 | if (cpu_is_omap15xx()) |
155 | clk_set_rate(clk: uart3_ck, rate: 12000000); |
156 | } |
157 | break; |
158 | } |
159 | omap_serial_reset(p: &serial_platform_data[i]); |
160 | } |
161 | } |
162 | |
163 | #ifdef CONFIG_OMAP_SERIAL_WAKE |
164 | |
165 | static irqreturn_t omap_serial_wake_interrupt(int irq, void *dev_id) |
166 | { |
167 | /* Need to do something with serial port right after wake-up? */ |
168 | return IRQ_HANDLED; |
169 | } |
170 | |
171 | /* |
172 | * Reroutes serial RX lines to GPIO lines for the duration of |
173 | * sleep to allow waking up the device from serial port even |
174 | * in deep sleep. |
175 | */ |
176 | void omap_serial_wake_trigger(int enable) |
177 | { |
178 | if (!cpu_is_omap16xx()) |
179 | return; |
180 | |
181 | if (uart1_ck != NULL) { |
182 | if (enable) |
183 | omap_cfg_reg(V14_16XX_GPIO37); |
184 | else |
185 | omap_cfg_reg(V14_16XX_UART1_RX); |
186 | } |
187 | if (uart2_ck != NULL) { |
188 | if (enable) |
189 | omap_cfg_reg(R9_16XX_GPIO18); |
190 | else |
191 | omap_cfg_reg(R9_16XX_UART2_RX); |
192 | } |
193 | if (uart3_ck != NULL) { |
194 | if (enable) |
195 | omap_cfg_reg(L14_16XX_GPIO49); |
196 | else |
197 | omap_cfg_reg(L14_16XX_UART3_RX); |
198 | } |
199 | } |
200 | |
201 | static void __init omap_serial_set_port_wakeup(int idx) |
202 | { |
203 | struct gpio_desc *d; |
204 | int ret; |
205 | |
206 | d = gpiod_get_index(NULL, "wakeup" , idx, GPIOD_IN); |
207 | if (IS_ERR(d)) { |
208 | pr_err("Unable to get UART wakeup GPIO descriptor\n" ); |
209 | return; |
210 | } |
211 | ret = request_irq(gpiod_to_irq(d), &omap_serial_wake_interrupt, |
212 | IRQF_TRIGGER_RISING, "serial wakeup" , NULL); |
213 | if (ret) { |
214 | gpiod_put(d); |
215 | pr_err("No interrupt for UART%d wake GPIO\n" , idx + 1); |
216 | return; |
217 | } |
218 | enable_irq_wake(gpiod_to_irq(d)); |
219 | } |
220 | |
221 | |
222 | int __init omap_serial_wakeup_init(void) |
223 | { |
224 | if (!cpu_is_omap16xx()) |
225 | return 0; |
226 | |
227 | if (uart1_ck != NULL) |
228 | omap_serial_set_port_wakeup(0); |
229 | if (uart2_ck != NULL) |
230 | omap_serial_set_port_wakeup(1); |
231 | if (uart3_ck != NULL) |
232 | omap_serial_set_port_wakeup(2); |
233 | |
234 | return 0; |
235 | } |
236 | |
237 | #endif /* CONFIG_OMAP_SERIAL_WAKE */ |
238 | |
239 | static int __init omap_init(void) |
240 | { |
241 | if (!cpu_class_is_omap1()) |
242 | return -ENODEV; |
243 | |
244 | return platform_device_register(&serial_device); |
245 | } |
246 | arch_initcall(omap_init); |
247 | |