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