1 // SPDX-License-Identifier: GPL-2.0+
3 * Serial Port driver for Aspeed VUART device
5 * Copyright (C) 2016 Jeremy Kerr <jk@ozlabs.org>, IBM Corp.
6 * Copyright (C) 2006 Arnd Bergmann <arnd@arndb.de>, IBM Corp.
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>
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
36 struct timer_list unthrottle_timer
;
37 struct uart_8250_port
*port
;
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.
45 static const int unthrottle_timeout
= HZ
/10;
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.
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.
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).
63 static ssize_t
lpc_address_show(struct device
*dev
,
64 struct device_attribute
*attr
, char *buf
)
66 struct aspeed_vuart
*vuart
= dev_get_drvdata(dev
);
69 addr
= (readb(vuart
->regs
+ ASPEED_VUART_ADDRH
) << 8) |
70 (readb(vuart
->regs
+ ASPEED_VUART_ADDRL
));
72 return snprintf(buf
, PAGE_SIZE
- 1, "0x%x\n", addr
);
75 static ssize_t
lpc_address_store(struct device
*dev
,
76 struct device_attribute
*attr
,
77 const char *buf
, size_t count
)
79 struct aspeed_vuart
*vuart
= dev_get_drvdata(dev
);
83 err
= kstrtoul(buf
, 0, &val
);
87 writeb(val
>> 8, vuart
->regs
+ ASPEED_VUART_ADDRH
);
88 writeb(val
>> 0, vuart
->regs
+ ASPEED_VUART_ADDRL
);
93 static DEVICE_ATTR_RW(lpc_address
);
95 static ssize_t
sirq_show(struct device
*dev
,
96 struct device_attribute
*attr
, char *buf
)
98 struct aspeed_vuart
*vuart
= dev_get_drvdata(dev
);
101 reg
= readb(vuart
->regs
+ ASPEED_VUART_GCRB
);
102 reg
&= ASPEED_VUART_GCRB_HOST_SIRQ_MASK
;
103 reg
>>= ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT
;
105 return snprintf(buf
, PAGE_SIZE
- 1, "%u\n", reg
);
108 static ssize_t
sirq_store(struct device
*dev
, struct device_attribute
*attr
,
109 const char *buf
, size_t count
)
111 struct aspeed_vuart
*vuart
= dev_get_drvdata(dev
);
116 err
= kstrtoul(buf
, 0, &val
);
120 val
<<= ASPEED_VUART_GCRB_HOST_SIRQ_SHIFT
;
121 val
&= ASPEED_VUART_GCRB_HOST_SIRQ_MASK
;
123 reg
= readb(vuart
->regs
+ ASPEED_VUART_GCRB
);
124 reg
&= ~ASPEED_VUART_GCRB_HOST_SIRQ_MASK
;
126 writeb(reg
, vuart
->regs
+ ASPEED_VUART_GCRB
);
131 static DEVICE_ATTR_RW(sirq
);
133 static ssize_t
sirq_polarity_show(struct device
*dev
,
134 struct device_attribute
*attr
, char *buf
)
136 struct aspeed_vuart
*vuart
= dev_get_drvdata(dev
);
139 reg
= readb(vuart
->regs
+ ASPEED_VUART_GCRA
);
140 reg
&= ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY
;
142 return snprintf(buf
, PAGE_SIZE
- 1, "%u\n", reg
? 1 : 0);
145 static void aspeed_vuart_set_sirq_polarity(struct aspeed_vuart
*vuart
,
148 u8 reg
= readb(vuart
->regs
+ ASPEED_VUART_GCRA
);
151 reg
|= ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY
;
153 reg
&= ~ASPEED_VUART_GCRA_HOST_SIRQ_POLARITY
;
155 writeb(reg
, vuart
->regs
+ ASPEED_VUART_GCRA
);
158 static ssize_t
sirq_polarity_store(struct device
*dev
,
159 struct device_attribute
*attr
,
160 const char *buf
, size_t count
)
162 struct aspeed_vuart
*vuart
= dev_get_drvdata(dev
);
166 err
= kstrtoul(buf
, 0, &val
);
170 aspeed_vuart_set_sirq_polarity(vuart
, val
!= 0);
175 static DEVICE_ATTR_RW(sirq_polarity
);
177 static struct attribute
*aspeed_vuart_attrs
[] = {
179 &dev_attr_sirq_polarity
.attr
,
180 &dev_attr_lpc_address
.attr
,
184 static const struct attribute_group aspeed_vuart_attr_group
= {
185 .attrs
= aspeed_vuart_attrs
,
188 static void aspeed_vuart_set_enabled(struct aspeed_vuart
*vuart
, bool enabled
)
190 u8 reg
= readb(vuart
->regs
+ ASPEED_VUART_GCRA
);
193 reg
|= ASPEED_VUART_GCRA_VUART_EN
;
195 reg
&= ~ASPEED_VUART_GCRA_VUART_EN
;
197 writeb(reg
, vuart
->regs
+ ASPEED_VUART_GCRA
);
200 static void aspeed_vuart_set_host_tx_discard(struct aspeed_vuart
*vuart
,
205 reg
= readb(vuart
->regs
+ ASPEED_VUART_GCRA
);
207 /* If the DISABLE_HOST_TX_DISCARD bit is set, discard is disabled */
209 reg
|= ASPEED_VUART_GCRA_DISABLE_HOST_TX_DISCARD
;
211 reg
&= ~ASPEED_VUART_GCRA_DISABLE_HOST_TX_DISCARD
;
213 writeb(reg
, vuart
->regs
+ ASPEED_VUART_GCRA
);
216 static int aspeed_vuart_startup(struct uart_port
*uart_port
)
218 struct uart_8250_port
*uart_8250_port
= up_to_u8250p(uart_port
);
219 struct aspeed_vuart
*vuart
= uart_8250_port
->port
.private_data
;
222 rc
= serial8250_do_startup(uart_port
);
226 aspeed_vuart_set_host_tx_discard(vuart
, false);
231 static void aspeed_vuart_shutdown(struct uart_port
*uart_port
)
233 struct uart_8250_port
*uart_8250_port
= up_to_u8250p(uart_port
);
234 struct aspeed_vuart
*vuart
= uart_8250_port
->port
.private_data
;
236 aspeed_vuart_set_host_tx_discard(vuart
, true);
238 serial8250_do_shutdown(uart_port
);
241 static void __aspeed_vuart_set_throttle(struct uart_8250_port
*up
,
244 unsigned char irqs
= UART_IER_RLSI
| UART_IER_RDI
;
249 serial_out(up
, UART_IER
, up
->ier
);
251 static void aspeed_vuart_set_throttle(struct uart_port
*port
, bool throttle
)
253 struct uart_8250_port
*up
= up_to_u8250p(port
);
256 spin_lock_irqsave(&port
->lock
, flags
);
257 __aspeed_vuart_set_throttle(up
, throttle
);
258 spin_unlock_irqrestore(&port
->lock
, flags
);
261 static void aspeed_vuart_throttle(struct uart_port
*port
)
263 aspeed_vuart_set_throttle(port
, true);
266 static void aspeed_vuart_unthrottle(struct uart_port
*port
)
268 aspeed_vuart_set_throttle(port
, false);
271 static void aspeed_vuart_unthrottle_exp(struct timer_list
*timer
)
273 struct aspeed_vuart
*vuart
= from_timer(vuart
, timer
, unthrottle_timer
);
274 struct uart_8250_port
*up
= vuart
->port
;
276 if (!tty_buffer_space_avail(&up
->port
.state
->port
)) {
277 mod_timer(&vuart
->unthrottle_timer
,
278 jiffies
+ unthrottle_timeout
);
282 aspeed_vuart_unthrottle(&up
->port
);
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
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.
296 static int aspeed_vuart_handle_irq(struct uart_port
*port
)
298 struct uart_8250_port
*up
= up_to_u8250p(port
);
299 unsigned int iir
, lsr
;
303 iir
= serial_port_in(port
, UART_IIR
);
305 if (iir
& UART_IIR_NO_INT
)
308 spin_lock_irqsave(&port
->lock
, flags
);
310 lsr
= serial_port_in(port
, UART_LSR
);
312 if (lsr
& (UART_LSR_DR
| UART_LSR_BI
)) {
313 space
= tty_buffer_space_avail(&port
->state
->port
);
316 /* throttle and schedule an unthrottle later */
317 struct aspeed_vuart
*vuart
= port
->private_data
;
318 __aspeed_vuart_set_throttle(up
, true);
320 if (!timer_pending(&vuart
->unthrottle_timer
)) {
322 mod_timer(&vuart
->unthrottle_timer
,
323 jiffies
+ unthrottle_timeout
);
327 count
= min(space
, 256);
330 serial8250_read_char(up
, lsr
);
331 lsr
= serial_in(up
, UART_LSR
);
334 } while (lsr
& (UART_LSR_DR
| UART_LSR_BI
));
336 tty_flip_buffer_push(&port
->state
->port
);
340 serial8250_modem_status(up
);
341 if (lsr
& UART_LSR_THRE
)
342 serial8250_tx_chars(up
);
344 uart_unlock_and_check_sysrq(port
, flags
);
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
)
353 struct regmap
*regmap
;
356 regmap
= syscon_node_to_regmap(syscon_np
);
357 if (IS_ERR(regmap
)) {
359 "could not get regmap for aspeed,sirq-polarity-sense\n");
362 if (regmap_read(regmap
, reg_offset
, &value
)) {
363 dev_warn(vuart
->dev
, "could not read hw strap table\n");
367 aspeed_vuart_set_sirq_polarity(vuart
, (value
& reg_mask
) == 0);
370 static int aspeed_vuart_probe(struct platform_device
*pdev
)
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
;
380 np
= pdev
->dev
.of_node
;
382 vuart
= devm_kzalloc(&pdev
->dev
, sizeof(*vuart
), GFP_KERNEL
);
386 vuart
->dev
= &pdev
->dev
;
387 timer_setup(&vuart
->unthrottle_timer
, aspeed_vuart_unthrottle_exp
, 0);
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
);
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
);
407 rc
= sysfs_create_group(&vuart
->dev
->kobj
, &aspeed_vuart_attr_group
);
411 if (of_property_read_u32(np
, "clock-frequency", &clk
)) {
412 vuart
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
413 if (IS_ERR(vuart
->clk
)) {
415 "clk or clock-frequency not defined\n");
416 rc
= PTR_ERR(vuart
->clk
);
417 goto err_sysfs_remove
;
420 rc
= clk_prepare_enable(vuart
->clk
);
422 goto err_sysfs_remove
;
424 clk
= clk_get_rate(vuart
->clk
);
427 /* If current-speed was set, then try not to change it. */
428 if (of_property_read_u32(np
, "current-speed", &prop
) == 0)
429 port
.port
.custom_divisor
= clk
/ (16 * prop
);
431 /* Check for shifted address mapping */
432 if (of_property_read_u32(np
, "reg-offset", &prop
) == 0)
433 port
.port
.mapbase
+= prop
;
435 /* Check for registers offset within the devices address range */
436 if (of_property_read_u32(np
, "reg-shift", &prop
) == 0)
437 port
.port
.regshift
= prop
;
439 /* Check for fifo size */
440 if (of_property_read_u32(np
, "fifo-size", &prop
) == 0)
441 port
.port
.fifosize
= prop
;
443 /* Check for a fixed line number */
444 rc
= of_alias_get_id(np
, "serial");
448 port
.port
.irq
= irq_of_parse_and_map(np
, 0);
449 port
.port
.handle_irq
= aspeed_vuart_handle_irq
;
450 port
.port
.iotype
= UPIO_MEM
;
451 port
.port
.type
= PORT_16550A
;
452 port
.port
.uartclk
= clk
;
453 port
.port
.flags
= UPF_SHARE_IRQ
| UPF_BOOT_AUTOCONF
454 | UPF_FIXED_PORT
| UPF_FIXED_TYPE
| UPF_NO_THRE_TEST
;
456 if (of_property_read_bool(np
, "no-loopback-test"))
457 port
.port
.flags
|= UPF_SKIP_TEST
;
459 if (port
.port
.fifosize
)
460 port
.capabilities
= UART_CAP_FIFO
;
462 if (of_property_read_bool(np
, "auto-flow-control"))
463 port
.capabilities
|= UART_CAP_AFE
;
465 rc
= serial8250_register_8250_port(&port
);
467 goto err_clk_disable
;
471 rc
= of_parse_phandle_with_fixed_args(
472 np
, "aspeed,sirq-polarity-sense", 2, 0,
473 &sirq_polarity_sense_args
);
476 "aspeed,sirq-polarity-sense property not found\n");
478 aspeed_vuart_auto_configure_sirq_polarity(
479 vuart
, sirq_polarity_sense_args
.np
,
480 sirq_polarity_sense_args
.args
[0],
481 BIT(sirq_polarity_sense_args
.args
[1]));
482 of_node_put(sirq_polarity_sense_args
.np
);
485 aspeed_vuart_set_enabled(vuart
, true);
486 aspeed_vuart_set_host_tx_discard(vuart
, true);
487 platform_set_drvdata(pdev
, vuart
);
492 clk_disable_unprepare(vuart
->clk
);
493 irq_dispose_mapping(port
.port
.irq
);
495 sysfs_remove_group(&vuart
->dev
->kobj
, &aspeed_vuart_attr_group
);
499 static int aspeed_vuart_remove(struct platform_device
*pdev
)
501 struct aspeed_vuart
*vuart
= platform_get_drvdata(pdev
);
503 del_timer_sync(&vuart
->unthrottle_timer
);
504 aspeed_vuart_set_enabled(vuart
, false);
505 serial8250_unregister_port(vuart
->line
);
506 sysfs_remove_group(&vuart
->dev
->kobj
, &aspeed_vuart_attr_group
);
507 clk_disable_unprepare(vuart
->clk
);
512 static const struct of_device_id aspeed_vuart_table
[] = {
513 { .compatible
= "aspeed,ast2400-vuart" },
514 { .compatible
= "aspeed,ast2500-vuart" },
518 static struct platform_driver aspeed_vuart_driver
= {
520 .name
= "aspeed-vuart",
521 .of_match_table
= aspeed_vuart_table
,
523 .probe
= aspeed_vuart_probe
,
524 .remove
= aspeed_vuart_remove
,
527 module_platform_driver(aspeed_vuart_driver
);
529 MODULE_AUTHOR("Jeremy Kerr <jk@ozlabs.org>");
530 MODULE_LICENSE("GPL");
531 MODULE_DESCRIPTION("Driver for Aspeed VUART device");