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