1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
4 */
5
6 #include <linux/clk.h>
7 #include <linux/console.h>
8 #include <linux/io.h>
9 #include <linux/module.h>
10 #include <linux/of.h>
11 #include <linux/platform_device.h>
12
13 #include "8250.h"
14
15 /* Most (but not all) of UniPhier UART devices have 64-depth FIFO. */
16 #define UNIPHIER_UART_DEFAULT_FIFO_SIZE 64
17
18 /*
19 * This hardware is similar to 8250, but its register map is a bit different:
20 * - MMIO32 (regshift = 2)
21 * - FCR is not at 2, but 3
22 * - LCR and MCR are not at 3 and 4, they share 4
23 * - No SCR (Instead, CHAR can be used as a scratch register)
24 * - Divisor latch at 9, no divisor latch access bit
25 */
26
27 #define UNIPHIER_UART_REGSHIFT 2
28
29 /* bit[15:8] = CHAR, bit[7:0] = FCR */
30 #define UNIPHIER_UART_CHAR_FCR (3 << (UNIPHIER_UART_REGSHIFT))
31 /* bit[15:8] = LCR, bit[7:0] = MCR */
32 #define UNIPHIER_UART_LCR_MCR (4 << (UNIPHIER_UART_REGSHIFT))
33 /* Divisor Latch Register */
34 #define UNIPHIER_UART_DLR (9 << (UNIPHIER_UART_REGSHIFT))
35
36 struct uniphier8250_priv {
37 int line;
38 struct clk *clk;
39 spinlock_t atomic_write_lock;
40 };
41
42 #ifdef CONFIG_SERIAL_8250_CONSOLE
uniphier_early_console_setup(struct earlycon_device * device,const char * options)43 static int __init uniphier_early_console_setup(struct earlycon_device *device,
44 const char *options)
45 {
46 if (!device->port.membase)
47 return -ENODEV;
48
49 /* This hardware always expects MMIO32 register interface. */
50 device->port.iotype = UPIO_MEM32;
51 device->port.regshift = UNIPHIER_UART_REGSHIFT;
52
53 /*
54 * Do not touch the divisor register in early_serial8250_setup();
55 * we assume it has been initialized by a boot loader.
56 */
57 device->baud = 0;
58
59 return early_serial8250_setup(device, options);
60 }
61 OF_EARLYCON_DECLARE(uniphier, "socionext,uniphier-uart",
62 uniphier_early_console_setup);
63 #endif
64
65 /*
66 * The register map is slightly different from that of 8250.
67 * IO callbacks must be overridden for correct access to FCR, LCR, MCR and SCR.
68 */
uniphier_serial_in(struct uart_port * p,int offset)69 static unsigned int uniphier_serial_in(struct uart_port *p, int offset)
70 {
71 unsigned int valshift = 0;
72
73 switch (offset) {
74 case UART_SCR:
75 /* No SCR for this hardware. Use CHAR as a scratch register */
76 valshift = 8;
77 offset = UNIPHIER_UART_CHAR_FCR;
78 break;
79 case UART_LCR:
80 valshift = 8;
81 /* fall through */
82 case UART_MCR:
83 offset = UNIPHIER_UART_LCR_MCR;
84 break;
85 default:
86 offset <<= UNIPHIER_UART_REGSHIFT;
87 break;
88 }
89
90 /*
91 * The return value must be masked with 0xff because some registers
92 * share the same offset that must be accessed by 32-bit write/read.
93 * 8 or 16 bit access to this hardware result in unexpected behavior.
94 */
95 return (readl(p->membase + offset) >> valshift) & 0xff;
96 }
97
uniphier_serial_out(struct uart_port * p,int offset,int value)98 static void uniphier_serial_out(struct uart_port *p, int offset, int value)
99 {
100 unsigned int valshift = 0;
101 bool normal = false;
102
103 switch (offset) {
104 case UART_SCR:
105 /* No SCR for this hardware. Use CHAR as a scratch register */
106 valshift = 8;
107 /* fall through */
108 case UART_FCR:
109 offset = UNIPHIER_UART_CHAR_FCR;
110 break;
111 case UART_LCR:
112 valshift = 8;
113 /* Divisor latch access bit does not exist. */
114 value &= ~UART_LCR_DLAB;
115 /* fall through */
116 case UART_MCR:
117 offset = UNIPHIER_UART_LCR_MCR;
118 break;
119 default:
120 offset <<= UNIPHIER_UART_REGSHIFT;
121 normal = true;
122 break;
123 }
124
125 if (normal) {
126 writel(value, p->membase + offset);
127 } else {
128 /*
129 * Special case: two registers share the same address that
130 * must be 32-bit accessed. As this is not longer atomic safe,
131 * take a lock just in case.
132 */
133 struct uniphier8250_priv *priv = p->private_data;
134 unsigned long flags;
135 u32 tmp;
136
137 spin_lock_irqsave(&priv->atomic_write_lock, flags);
138 tmp = readl(p->membase + offset);
139 tmp &= ~(0xff << valshift);
140 tmp |= value << valshift;
141 writel(tmp, p->membase + offset);
142 spin_unlock_irqrestore(&priv->atomic_write_lock, flags);
143 }
144 }
145
146 /*
147 * This hardware does not have the divisor latch access bit.
148 * The divisor latch register exists at different address.
149 * Override dl_read/write callbacks.
150 */
uniphier_serial_dl_read(struct uart_8250_port * up)151 static int uniphier_serial_dl_read(struct uart_8250_port *up)
152 {
153 return readl(up->port.membase + UNIPHIER_UART_DLR);
154 }
155
uniphier_serial_dl_write(struct uart_8250_port * up,int value)156 static void uniphier_serial_dl_write(struct uart_8250_port *up, int value)
157 {
158 writel(value, up->port.membase + UNIPHIER_UART_DLR);
159 }
160
uniphier_of_serial_setup(struct device * dev,struct uart_port * port,struct uniphier8250_priv * priv)161 static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port,
162 struct uniphier8250_priv *priv)
163 {
164 int ret;
165 u32 prop;
166 struct device_node *np = dev->of_node;
167
168 ret = of_alias_get_id(np, "serial");
169 if (ret < 0) {
170 dev_err(dev, "failed to get alias id\n");
171 return ret;
172 }
173 port->line = ret;
174
175 /* Get clk rate through clk driver */
176 priv->clk = devm_clk_get(dev, NULL);
177 if (IS_ERR(priv->clk)) {
178 dev_err(dev, "failed to get clock\n");
179 return PTR_ERR(priv->clk);
180 }
181
182 ret = clk_prepare_enable(priv->clk);
183 if (ret < 0)
184 return ret;
185
186 port->uartclk = clk_get_rate(priv->clk);
187
188 /* Check for fifo size */
189 if (of_property_read_u32(np, "fifo-size", &prop) == 0)
190 port->fifosize = prop;
191 else
192 port->fifosize = UNIPHIER_UART_DEFAULT_FIFO_SIZE;
193
194 return 0;
195 }
196
uniphier_uart_probe(struct platform_device * pdev)197 static int uniphier_uart_probe(struct platform_device *pdev)
198 {
199 struct device *dev = &pdev->dev;
200 struct uart_8250_port up;
201 struct uniphier8250_priv *priv;
202 struct resource *regs;
203 void __iomem *membase;
204 int irq;
205 int ret;
206
207 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
208 if (!regs) {
209 dev_err(dev, "failed to get memory resource\n");
210 return -EINVAL;
211 }
212
213 membase = devm_ioremap(dev, regs->start, resource_size(regs));
214 if (!membase)
215 return -ENOMEM;
216
217 irq = platform_get_irq(pdev, 0);
218 if (irq < 0) {
219 dev_err(dev, "failed to get IRQ number\n");
220 return irq;
221 }
222
223 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
224 if (!priv)
225 return -ENOMEM;
226
227 memset(&up, 0, sizeof(up));
228
229 ret = uniphier_of_serial_setup(dev, &up.port, priv);
230 if (ret < 0)
231 return ret;
232
233 spin_lock_init(&priv->atomic_write_lock);
234
235 up.port.dev = dev;
236 up.port.private_data = priv;
237 up.port.mapbase = regs->start;
238 up.port.mapsize = resource_size(regs);
239 up.port.membase = membase;
240 up.port.irq = irq;
241
242 up.port.type = PORT_16550A;
243 up.port.iotype = UPIO_MEM32;
244 up.port.regshift = UNIPHIER_UART_REGSHIFT;
245 up.port.flags = UPF_FIXED_PORT | UPF_FIXED_TYPE;
246 up.capabilities = UART_CAP_FIFO;
247
248 up.port.serial_in = uniphier_serial_in;
249 up.port.serial_out = uniphier_serial_out;
250 up.dl_read = uniphier_serial_dl_read;
251 up.dl_write = uniphier_serial_dl_write;
252
253 ret = serial8250_register_8250_port(&up);
254 if (ret < 0) {
255 dev_err(dev, "failed to register 8250 port\n");
256 clk_disable_unprepare(priv->clk);
257 return ret;
258 }
259 priv->line = ret;
260
261 platform_set_drvdata(pdev, priv);
262
263 return 0;
264 }
265
uniphier_uart_remove(struct platform_device * pdev)266 static int uniphier_uart_remove(struct platform_device *pdev)
267 {
268 struct uniphier8250_priv *priv = platform_get_drvdata(pdev);
269
270 serial8250_unregister_port(priv->line);
271 clk_disable_unprepare(priv->clk);
272
273 return 0;
274 }
275
uniphier_uart_suspend(struct device * dev)276 static int __maybe_unused uniphier_uart_suspend(struct device *dev)
277 {
278 struct uniphier8250_priv *priv = dev_get_drvdata(dev);
279 struct uart_8250_port *up = serial8250_get_port(priv->line);
280
281 serial8250_suspend_port(priv->line);
282
283 if (!uart_console(&up->port) || console_suspend_enabled)
284 clk_disable_unprepare(priv->clk);
285
286 return 0;
287 }
288
uniphier_uart_resume(struct device * dev)289 static int __maybe_unused uniphier_uart_resume(struct device *dev)
290 {
291 struct uniphier8250_priv *priv = dev_get_drvdata(dev);
292 struct uart_8250_port *up = serial8250_get_port(priv->line);
293 int ret;
294
295 if (!uart_console(&up->port) || console_suspend_enabled) {
296 ret = clk_prepare_enable(priv->clk);
297 if (ret)
298 return ret;
299 }
300
301 serial8250_resume_port(priv->line);
302
303 return 0;
304 }
305
306 static const struct dev_pm_ops uniphier_uart_pm_ops = {
307 SET_SYSTEM_SLEEP_PM_OPS(uniphier_uart_suspend, uniphier_uart_resume)
308 };
309
310 static const struct of_device_id uniphier_uart_match[] = {
311 { .compatible = "socionext,uniphier-uart" },
312 { /* sentinel */ }
313 };
314 MODULE_DEVICE_TABLE(of, uniphier_uart_match);
315
316 static struct platform_driver uniphier_uart_platform_driver = {
317 .probe = uniphier_uart_probe,
318 .remove = uniphier_uart_remove,
319 .driver = {
320 .name = "uniphier-uart",
321 .of_match_table = uniphier_uart_match,
322 .pm = &uniphier_uart_pm_ops,
323 },
324 };
325 module_platform_driver(uniphier_uart_platform_driver);
326
327 MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>");
328 MODULE_DESCRIPTION("UniPhier UART driver");
329 MODULE_LICENSE("GPL");
330