Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/arm/mach-omap1/serial.c
26292 views
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(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(value, 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, 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, 0x01);
62
while (!(omap_serial_in(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(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, "uart1_ck");
128
if (IS_ERR(uart1_ck))
129
printk("Could not get uart1_ck\n");
130
else {
131
clk_prepare_enable(uart1_ck);
132
if (cpu_is_omap15xx())
133
clk_set_rate(uart1_ck, 12000000);
134
}
135
break;
136
case 1:
137
uart2_ck = clk_get(NULL, "uart2_ck");
138
if (IS_ERR(uart2_ck))
139
printk("Could not get uart2_ck\n");
140
else {
141
clk_prepare_enable(uart2_ck);
142
if (cpu_is_omap15xx())
143
clk_set_rate(uart2_ck, 12000000);
144
else
145
clk_set_rate(uart2_ck, 48000000);
146
}
147
break;
148
case 2:
149
uart3_ck = clk_get(NULL, "uart3_ck");
150
if (IS_ERR(uart3_ck))
151
printk("Could not get uart3_ck\n");
152
else {
153
clk_prepare_enable(uart3_ck);
154
if (cpu_is_omap15xx())
155
clk_set_rate(uart3_ck, 12000000);
156
}
157
break;
158
}
159
omap_serial_reset(&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
248