GNU Linux-libre 5.10.215-gnu1
[releases.git] / drivers / tty / serial / 8250 / 8250_aspeed_vuart.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  Serial Port driver for Aspeed VUART device
4  *
5  *    Copyright (C) 2016 Jeremy Kerr <jk@ozlabs.org>, IBM Corp.
6  *    Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de>, IBM Corp.
7  */
8 #include <linux/device.h>
9 #include <linux/module.h>
10 #include <linux/of_address.h>
11 #include <linux/of_irq.h>
12 #include <linux/of_platform.h>
13 #include <linux/regmap.h>
14 #include <linux/mfd/syscon.h>
15 #include <linux/tty.h>
16 #include <linux/tty_flip.h>
17 #include <linux/clk.h>
18
19 #include "8250.h"
20
21 #define ASPEED_VUART_GCRA               0x20
22 #define ASPEED_VUART_GCRA_VUART_EN              BIT(0)
23 #define ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY    BIT(1)
24 #define ASPEED_VUART_GCRA_DISABLE_HOST_TX_DISCARD BIT(5)
25 #define ASPEED_VUART_GCRB               0x24
26 #define ASPEED_VUART_GCRB_HOST_SIRQ_MASK        GENMASK(7, 4)
27 #define ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT       4
28 #define ASPEED_VUART_ADDRL              0x28
29 #define ASPEED_VUART_ADDRH              0x2c
30
31 struct aspeed_vuart {
32         struct device           *dev;
33         void __iomem            *regs;
34         struct clk              *clk;
35         int                     line;
36         struct timer_list       unthrottle_timer;
37         struct uart_8250_port   *port;
38 };
39
40 /*
41  * If we fill the tty flip buffers, we throttle the data ready interrupt
42  * to prevent dropped characters. This timeout defines how long we wait
43  * to (conditionally, depending on buffer state) unthrottle.
44  */
45 static const int unthrottle_timeout = HZ/10;
46
47 /*
48  * The VUART is basically two UART 'front ends' connected by their FIFO
49  * (no actual serial line in between). One is on the BMC side (management
50  * controller) and one is on the host CPU side.
51  *
52  * It allows the BMC to provide to the host a "UART" that pipes into
53  * the BMC itself and can then be turned by the BMC into a network console
54  * of some sort for example.
55  *
56  * This driver is for the BMC side. The sysfs files allow the BMC
57  * userspace which owns the system configuration policy, to specify
58  * at what IO port and interrupt number the host side will appear
59  * to the host on the Host <-> BMC LPC bus. It could be different on a
60  * different system (though most of them use 3f8/4).
61  */
62
63 static ssize_t lpc_address_show(struct device *dev,
64                                 struct device_attribute *attr, char *buf)
65 {
66         struct aspeed_vuart *vuart = dev_get_drvdata(dev);
67         u16 addr;
68
69         addr = (readb(vuart->regs + ASPEED_VUART_ADDRH) << 8) |
70                 (readb(vuart->regs + ASPEED_VUART_ADDRL));
71
72         return snprintf(buf, PAGE_SIZE - 1, "0x%x\n", addr);
73 }
74
75 static ssize_t lpc_address_store(struct device *dev,
76                                  struct device_attribute *attr,
77                                  const char *buf, size_t count)
78 {
79         struct aspeed_vuart *vuart = dev_get_drvdata(dev);
80         unsigned long val;
81         int err;
82
83         err = kstrtoul(buf, 0, &val);
84         if (err)
85                 return err;
86
87         writeb(val >> 8, vuart->regs + ASPEED_VUART_ADDRH);
88         writeb(val >> 0, vuart->regs + ASPEED_VUART_ADDRL);
89
90         return count;
91 }
92
93 static DEVICE_ATTR_RW(lpc_address);
94
95 static ssize_t sirq_show(struct device *dev,
96                          struct device_attribute *attr, char *buf)
97 {
98         struct aspeed_vuart *vuart = dev_get_drvdata(dev);
99         u8 reg;
100
101         reg = readb(vuart->regs + ASPEED_VUART_GCRB);
102         reg &= ASPEED_VUART_GCRB_HOST_SIRQ_MASK;
103         reg >>= ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT;
104
105         return snprintf(buf, PAGE_SIZE - 1, "%u\n", reg);
106 }
107
108 static ssize_t sirq_store(struct device *dev, struct device_attribute *attr,
109                           const char *buf, size_t count)
110 {
111         struct aspeed_vuart *vuart = dev_get_drvdata(dev);
112         unsigned long val;
113         int err;
114         u8 reg;
115
116         err = kstrtoul(buf, 0, &val);
117         if (err)
118                 return err;
119
120         val <<= ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT;
121         val &= ASPEED_VUART_GCRB_HOST_SIRQ_MASK;
122
123         reg = readb(vuart->regs + ASPEED_VUART_GCRB);
124         reg &= ~ASPEED_VUART_GCRB_HOST_SIRQ_MASK;
125         reg |= val;
126         writeb(reg, vuart->regs + ASPEED_VUART_GCRB);
127
128         return count;
129 }
130
131 static DEVICE_ATTR_RW(sirq);
132
133 static ssize_t sirq_polarity_show(struct device *dev,
134                                   struct device_attribute *attr, char *buf)
135 {
136         struct aspeed_vuart *vuart = dev_get_drvdata(dev);
137         u8 reg;
138
139         reg = readb(vuart->regs + ASPEED_VUART_GCRA);
140         reg &= ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY;
141
142         return snprintf(buf, PAGE_SIZE - 1, "%u\n", reg ? 1 : 0);
143 }
144
145 static void aspeed_vuart_set_sirq_polarity(struct aspeed_vuart *vuart,
146                                            bool polarity)
147 {
148         u8 reg = readb(vuart->regs + ASPEED_VUART_GCRA);
149
150         if (polarity)
151                 reg |= ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY;
152         else
153                 reg &= ~ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY;
154
155         writeb(reg, vuart->regs + ASPEED_VUART_GCRA);
156 }
157
158 static ssize_t sirq_polarity_store(struct device *dev,
159                                    struct device_attribute *attr,
160                                    const char *buf, size_t count)
161 {
162         struct aspeed_vuart *vuart = dev_get_drvdata(dev);
163         unsigned long val;
164         int err;
165
166         err = kstrtoul(buf, 0, &val);
167         if (err)
168                 return err;
169
170         aspeed_vuart_set_sirq_polarity(vuart, val != 0);
171
172         return count;
173 }
174
175 static DEVICE_ATTR_RW(sirq_polarity);
176
177 static struct attribute *aspeed_vuart_attrs[] = {
178         &dev_attr_sirq.attr,
179         &dev_attr_sirq_polarity.attr,
180         &dev_attr_lpc_address.attr,
181         NULL,
182 };
183
184 static const struct attribute_group aspeed_vuart_attr_group = {
185         .attrs = aspeed_vuart_attrs,
186 };
187
188 static void aspeed_vuart_set_enabled(struct aspeed_vuart *vuart, bool enabled)
189 {
190         u8 reg = readb(vuart->regs + ASPEED_VUART_GCRA);
191
192         if (enabled)
193                 reg |= ASPEED_VUART_GCRA_VUART_EN;
194         else
195                 reg &= ~ASPEED_VUART_GCRA_VUART_EN;
196
197         writeb(reg, vuart->regs + ASPEED_VUART_GCRA);
198 }
199
200 static void aspeed_vuart_set_host_tx_discard(struct aspeed_vuart *vuart,
201                                              bool discard)
202 {
203         u8 reg;
204
205         reg = readb(vuart->regs + ASPEED_VUART_GCRA);
206
207         /* If the DISABLE_HOST_TX_DISCARD bit is set, discard is disabled */
208         if (!discard)
209                 reg |= ASPEED_VUART_GCRA_DISABLE_HOST_TX_DISCARD;
210         else
211                 reg &= ~ASPEED_VUART_GCRA_DISABLE_HOST_TX_DISCARD;
212
213         writeb(reg, vuart->regs + ASPEED_VUART_GCRA);
214 }
215
216 static int aspeed_vuart_startup(struct uart_port *uart_port)
217 {
218         struct uart_8250_port *uart_8250_port = up_to_u8250p(uart_port);
219         struct aspeed_vuart *vuart = uart_8250_port->port.private_data;
220         int rc;
221
222         rc = serial8250_do_startup(uart_port);
223         if (rc)
224                 return rc;
225
226         aspeed_vuart_set_host_tx_discard(vuart, false);
227
228         return 0;
229 }
230
231 static void aspeed_vuart_shutdown(struct uart_port *uart_port)
232 {
233         struct uart_8250_port *uart_8250_port = up_to_u8250p(uart_port);
234         struct aspeed_vuart *vuart = uart_8250_port->port.private_data;
235
236         aspeed_vuart_set_host_tx_discard(vuart, true);
237
238         serial8250_do_shutdown(uart_port);
239 }
240
241 static void __aspeed_vuart_set_throttle(struct uart_8250_port *up,
242                 bool throttle)
243 {
244         unsigned char irqs = UART_IER_RLSI | UART_IER_RDI;
245
246         up->ier &= ~irqs;
247         if (!throttle)
248                 up->ier |= irqs;
249         serial_out(up, UART_IER, up->ier);
250 }
251 static void aspeed_vuart_set_throttle(struct uart_port *port, bool throttle)
252 {
253         struct uart_8250_port *up = up_to_u8250p(port);
254         unsigned long flags;
255
256         spin_lock_irqsave(&port->lock, flags);
257         __aspeed_vuart_set_throttle(up, throttle);
258         spin_unlock_irqrestore(&port->lock, flags);
259 }
260
261 static void aspeed_vuart_throttle(struct uart_port *port)
262 {
263         aspeed_vuart_set_throttle(port, true);
264 }
265
266 static void aspeed_vuart_unthrottle(struct uart_port *port)
267 {
268         aspeed_vuart_set_throttle(port, false);
269 }
270
271 static void aspeed_vuart_unthrottle_exp(struct timer_list *timer)
272 {
273         struct aspeed_vuart *vuart = from_timer(vuart, timer, unthrottle_timer);
274         struct uart_8250_port *up = vuart->port;
275
276         if (!tty_buffer_space_avail(&up->port.state->port)) {
277                 mod_timer(&vuart->unthrottle_timer,
278                           jiffies + unthrottle_timeout);
279                 return;
280         }
281
282         aspeed_vuart_unthrottle(&up->port);
283 }
284
285 /*
286  * Custom interrupt handler to manage finer-grained flow control. Although we
287  * have throttle/unthrottle callbacks, we've seen that the VUART device can
288  * deliver characters faster than the ldisc has a chance to check buffer space
289  * against the throttle threshold. This results in dropped characters before
290  * the throttle.
291  *
292  * We do this by checking for flip buffer space before RX. If we have no space,
293  * throttle now and schedule an unthrottle for later, once the ldisc has had
294  * a chance to drain the buffers.
295  */
296 static int aspeed_vuart_handle_irq(struct uart_port *port)
297 {
298         struct uart_8250_port *up = up_to_u8250p(port);
299         unsigned int iir, lsr;
300         unsigned long flags;
301         int space, count;
302
303         iir = serial_port_in(port, UART_IIR);
304
305         if (iir & UART_IIR_NO_INT)
306                 return 0;
307
308         spin_lock_irqsave(&port->lock, flags);
309
310         lsr = serial_port_in(port, UART_LSR);
311
312         if (lsr & (UART_LSR_DR | UART_LSR_BI)) {
313                 space = tty_buffer_space_avail(&port->state->port);
314
315                 if (!space) {
316                         /* throttle and schedule an unthrottle later */
317                         struct aspeed_vuart *vuart = port->private_data;
318                         __aspeed_vuart_set_throttle(up, true);
319
320                         if (!timer_pending(&vuart->unthrottle_timer)) {
321                                 vuart->port = up;
322                                 mod_timer(&vuart->unthrottle_timer,
323                                           jiffies + unthrottle_timeout);
324                         }
325
326                 } else {
327                         count = min(space, 256);
328
329                         do {
330                                 serial8250_read_char(up, lsr);
331                                 lsr = serial_in(up, UART_LSR);
332                                 if (--count == 0)
333                                         break;
334                         } while (lsr & (UART_LSR_DR | UART_LSR_BI));
335
336                         tty_flip_buffer_push(&port->state->port);
337                 }
338         }
339
340         serial8250_modem_status(up);
341         if (lsr & UART_LSR_THRE)
342                 serial8250_tx_chars(up);
343
344         uart_unlock_and_check_sysrq(port, flags);
345
346         return 1;
347 }
348
349 static void aspeed_vuart_auto_configure_sirq_polarity(
350         struct aspeed_vuart *vuart, struct device_node *syscon_np,
351         u32 reg_offset, u32 reg_mask)
352 {
353         struct regmap *regmap;
354         u32 value;
355
356         regmap = syscon_node_to_regmap(syscon_np);
357         if (IS_ERR(regmap)) {
358                 dev_warn(vuart->dev,
359                          "could not get regmap for aspeed,sirq-polarity-sense\n");
360                 return;
361         }
362         if (regmap_read(regmap, reg_offset, &value)) {
363                 dev_warn(vuart->dev, "could not read hw strap table\n");
364                 return;
365         }
366
367         aspeed_vuart_set_sirq_polarity(vuart, (value & reg_mask) == 0);
368 }
369
370 static int aspeed_vuart_probe(struct platform_device *pdev)
371 {
372         struct of_phandle_args sirq_polarity_sense_args;
373         struct uart_8250_port port;
374         struct aspeed_vuart *vuart;
375         struct device_node *np;
376         struct resource *res;
377         u32 clk, prop;
378         int rc;
379
380         np = pdev->dev.of_node;
381
382         vuart = devm_kzalloc(&pdev->dev, sizeof(*vuart), GFP_KERNEL);
383         if (!vuart)
384                 return -ENOMEM;
385
386         vuart->dev = &pdev->dev;
387         timer_setup(&vuart->unthrottle_timer, aspeed_vuart_unthrottle_exp, 0);
388
389         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
390         vuart->regs = devm_ioremap_resource(&pdev->dev, res);
391         if (IS_ERR(vuart->regs))
392                 return PTR_ERR(vuart->regs);
393
394         memset(&port, 0, sizeof(port));
395         port.port.private_data = vuart;
396         port.port.membase = vuart->regs;
397         port.port.mapbase = res->start;
398         port.port.mapsize = resource_size(res);
399         port.port.startup = aspeed_vuart_startup;
400         port.port.shutdown = aspeed_vuart_shutdown;
401         port.port.throttle = aspeed_vuart_throttle;
402         port.port.unthrottle = aspeed_vuart_unthrottle;
403         port.port.status = UPSTAT_SYNC_FIFO;
404         port.port.dev = &pdev->dev;
405         port.port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_8250_CONSOLE);
406         port.bugs |= UART_BUG_TXRACE;
407
408         rc = sysfs_create_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);
409         if (rc < 0)
410                 return rc;
411
412         if (of_property_read_u32(np, "clock-frequency", &clk)) {
413                 vuart->clk = devm_clk_get(&pdev->dev, NULL);
414                 if (IS_ERR(vuart->clk)) {
415                         dev_warn(&pdev->dev,
416                                 "clk or clock-frequency not defined\n");
417                         rc = PTR_ERR(vuart->clk);
418                         goto err_sysfs_remove;
419                 }
420
421                 rc = clk_prepare_enable(vuart->clk);
422                 if (rc < 0)
423                         goto err_sysfs_remove;
424
425                 clk = clk_get_rate(vuart->clk);
426         }
427
428         /* If current-speed was set, then try not to change it. */
429         if (of_property_read_u32(np, "current-speed", &prop) == 0)
430                 port.port.custom_divisor = clk / (16 * prop);
431
432         /* Check for shifted address mapping */
433         if (of_property_read_u32(np, "reg-offset", &prop) == 0)
434                 port.port.mapbase += prop;
435
436         /* Check for registers offset within the devices address range */
437         if (of_property_read_u32(np, "reg-shift", &prop) == 0)
438                 port.port.regshift = prop;
439
440         /* Check for fifo size */
441         if (of_property_read_u32(np, "fifo-size", &prop) == 0)
442                 port.port.fifosize = prop;
443
444         /* Check for a fixed line number */
445         rc = of_alias_get_id(np, "serial");
446         if (rc >= 0)
447                 port.port.line = rc;
448
449         port.port.irq = irq_of_parse_and_map(np, 0);
450         port.port.handle_irq = aspeed_vuart_handle_irq;
451         port.port.iotype = UPIO_MEM;
452         port.port.type = PORT_16550A;
453         port.port.uartclk = clk;
454         port.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF
455                 | UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_NO_THRE_TEST;
456
457         if (of_property_read_bool(np, "no-loopback-test"))
458                 port.port.flags |= UPF_SKIP_TEST;
459
460         if (port.port.fifosize)
461                 port.capabilities = UART_CAP_FIFO;
462
463         if (of_property_read_bool(np, "auto-flow-control"))
464                 port.capabilities |= UART_CAP_AFE;
465
466         rc = serial8250_register_8250_port(&port);
467         if (rc < 0)
468                 goto err_clk_disable;
469
470         vuart->line = rc;
471
472         rc = of_parse_phandle_with_fixed_args(
473                 np, "aspeed,sirq-polarity-sense", 2, 0,
474                 &sirq_polarity_sense_args);
475         if (rc < 0) {
476                 dev_dbg(&pdev->dev,
477                         "aspeed,sirq-polarity-sense property not found\n");
478         } else {
479                 aspeed_vuart_auto_configure_sirq_polarity(
480                         vuart, sirq_polarity_sense_args.np,
481                         sirq_polarity_sense_args.args[0],
482                         BIT(sirq_polarity_sense_args.args[1]));
483                 of_node_put(sirq_polarity_sense_args.np);
484         }
485
486         aspeed_vuart_set_enabled(vuart, true);
487         aspeed_vuart_set_host_tx_discard(vuart, true);
488         platform_set_drvdata(pdev, vuart);
489
490         return 0;
491
492 err_clk_disable:
493         clk_disable_unprepare(vuart->clk);
494         irq_dispose_mapping(port.port.irq);
495 err_sysfs_remove:
496         sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);
497         return rc;
498 }
499
500 static int aspeed_vuart_remove(struct platform_device *pdev)
501 {
502         struct aspeed_vuart *vuart = platform_get_drvdata(pdev);
503
504         del_timer_sync(&vuart->unthrottle_timer);
505         aspeed_vuart_set_enabled(vuart, false);
506         serial8250_unregister_port(vuart->line);
507         sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);
508         clk_disable_unprepare(vuart->clk);
509
510         return 0;
511 }
512
513 static const struct of_device_id aspeed_vuart_table[] = {
514         { .compatible = "aspeed,ast2400-vuart" },
515         { .compatible = "aspeed,ast2500-vuart" },
516         { },
517 };
518
519 static struct platform_driver aspeed_vuart_driver = {
520         .driver = {
521                 .name = "aspeed-vuart",
522                 .of_match_table = aspeed_vuart_table,
523         },
524         .probe = aspeed_vuart_probe,
525         .remove = aspeed_vuart_remove,
526 };
527
528 module_platform_driver(aspeed_vuart_driver);
529
530 MODULE_AUTHOR("Jeremy Kerr <jk@ozlabs.org>");
531 MODULE_LICENSE("GPL");
532 MODULE_DESCRIPTION("Driver for Aspeed VUART device");