1// SPDX-License-Identifier: GPL-2.0
2#include <linux/device.h>
3#include <linux/kernel.h>
4#include <linux/module.h>
5#include <linux/io.h>
6#include <linux/mcb.h>
7#include <linux/serial.h>
8#include <linux/serial_core.h>
9#include <linux/serial_8250.h>
10
11#define MEN_UART_ID_Z025 0x19
12#define MEN_UART_ID_Z057 0x39
13#define MEN_UART_ID_Z125 0x7d
14
15/*
16 * IP Cores Z025 and Z057 can have up to 4 UART
17 * The UARTs available are stored in a global
18 * register saved in physical address + 0x40
19 * Is saved as follows:
20 *
21 * 7                                                              0
22 * +------+-------+-------+-------+-------+-------+-------+-------+
23 * |UART4 | UART3 | UART2 | UART1 | U4irq | U3irq | U2irq | U1irq |
24 * +------+-------+-------+-------+-------+-------+-------+-------+
25 */
26#define MEN_UART1_MASK	0x01
27#define MEN_UART2_MASK	0x02
28#define MEN_UART3_MASK	0x04
29#define MEN_UART4_MASK	0x08
30
31#define MEN_Z125_UARTS_AVAILABLE	0x01
32
33#define MEN_Z025_MAX_UARTS		4
34#define MEN_UART_MEM_SIZE		0x10
35#define MEM_UART_REGISTER_SIZE		0x01
36#define MEN_Z025_REGISTER_OFFSET	0x40
37
38#define MEN_UART1_OFFSET	0
39#define MEN_UART2_OFFSET	(MEN_UART1_OFFSET + MEN_UART_MEM_SIZE)
40#define MEN_UART3_OFFSET	(MEN_UART2_OFFSET + MEN_UART_MEM_SIZE)
41#define MEN_UART4_OFFSET	(MEN_UART3_OFFSET + MEN_UART_MEM_SIZE)
42
43#define MEN_READ_REGISTER(addr)	readb(addr)
44
45#define MAX_PORTS	4
46
47struct serial_8250_men_mcb_data {
48	int num_ports;
49	int line[MAX_PORTS];
50	unsigned int offset[MAX_PORTS];
51};
52
53/*
54 * The Z125 16550-compatible UART has no fixed base clock assigned
55 * So, depending on the board we're on, we need to adjust the
56 * parameter in order to really set the correct baudrate, and
57 * do so if possible without user interaction
58 */
59static u32 men_lookup_uartclk(struct mcb_device *mdev)
60{
61	/* use default value if board is not available below */
62	u32 clkval = 1041666;
63
64	dev_info(&mdev->dev, "%s on board %s\n",
65		dev_name(&mdev->dev),
66		mdev->bus->name);
67	if  (strncmp(mdev->bus->name, "F075", 4) == 0)
68		clkval = 1041666;
69	else if (strncmp(mdev->bus->name, "F216", 4) == 0)
70		clkval = 1843200;
71	else if (strncmp(mdev->bus->name, "F210", 4) == 0)
72		clkval = 115200;
73	else if (strstr(mdev->bus->name, "215"))
74		clkval = 1843200;
75	else
76		dev_info(&mdev->dev,
77			 "board not detected, using default uartclk\n");
78
79	clkval = clkval  << 4;
80
81	return clkval;
82}
83
84static int read_uarts_available_from_register(struct resource *mem_res,
85					      u8 *uarts_available)
86{
87	void __iomem *mem;
88	int reg_value;
89
90	if (!request_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET,
91				MEM_UART_REGISTER_SIZE,  KBUILD_MODNAME)) {
92		return -EBUSY;
93	}
94
95	mem = ioremap(mem_res->start + MEN_Z025_REGISTER_OFFSET,
96		      MEM_UART_REGISTER_SIZE);
97	if (!mem) {
98		release_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET,
99				   MEM_UART_REGISTER_SIZE);
100		return -ENOMEM;
101	}
102
103	reg_value = MEN_READ_REGISTER(mem);
104
105	iounmap(mem);
106
107	release_mem_region(mem_res->start + MEN_Z025_REGISTER_OFFSET,
108			   MEM_UART_REGISTER_SIZE);
109
110	*uarts_available = reg_value >> 4;
111
112	return 0;
113}
114
115static int read_serial_data(struct mcb_device *mdev,
116			    struct resource *mem_res,
117			    struct serial_8250_men_mcb_data *serial_data)
118{
119	u8 uarts_available;
120	int count = 0;
121	int mask;
122	int res;
123	int i;
124
125	res = read_uarts_available_from_register(mem_res, &uarts_available);
126	if (res < 0)
127		return res;
128
129	for (i = 0; i < MAX_PORTS; i++) {
130		mask = 0x1 << i;
131		switch (uarts_available & mask) {
132		case MEN_UART1_MASK:
133			serial_data->offset[count] = MEN_UART1_OFFSET;
134			count++;
135			break;
136		case MEN_UART2_MASK:
137			serial_data->offset[count] = MEN_UART2_OFFSET;
138			count++;
139			break;
140		case MEN_UART3_MASK:
141			serial_data->offset[count] = MEN_UART3_OFFSET;
142			count++;
143			break;
144		case MEN_UART4_MASK:
145			serial_data->offset[count] = MEN_UART4_OFFSET;
146			count++;
147			break;
148		default:
149			return -EINVAL;
150		}
151	}
152
153	if (count <= 0 || count > MAX_PORTS) {
154		dev_err(&mdev->dev, "unexpected number of ports: %u\n",
155			count);
156		return -ENODEV;
157	}
158
159	serial_data->num_ports = count;
160
161	return 0;
162}
163
164static int init_serial_data(struct mcb_device *mdev,
165			    struct resource *mem_res,
166			    struct serial_8250_men_mcb_data *serial_data)
167{
168	switch (mdev->id) {
169	case MEN_UART_ID_Z125:
170		serial_data->num_ports = 1;
171		serial_data->offset[0] = 0;
172		return 0;
173	case MEN_UART_ID_Z025:
174	case MEN_UART_ID_Z057:
175		return read_serial_data(mdev, mem_res, serial_data);
176	default:
177		dev_err(&mdev->dev, "no supported device!\n");
178		return -ENODEV;
179	}
180}
181
182static int serial_8250_men_mcb_probe(struct mcb_device *mdev,
183				     const struct mcb_device_id *id)
184{
185	struct uart_8250_port uart;
186	struct serial_8250_men_mcb_data *data;
187	struct resource *mem;
188	int i;
189	int res;
190
191	mem = mcb_get_resource(mdev, IORESOURCE_MEM);
192	if (mem == NULL)
193		return -ENXIO;
194
195	data = devm_kzalloc(&mdev->dev,
196			    sizeof(struct serial_8250_men_mcb_data),
197			    GFP_KERNEL);
198	if (!data)
199		return -ENOMEM;
200
201	res = init_serial_data(mdev, mem, data);
202	if (res < 0)
203		return res;
204
205	dev_dbg(&mdev->dev, "found a 16z%03u with %u ports\n",
206		mdev->id, data->num_ports);
207
208	mcb_set_drvdata(mdev, data);
209
210	for (i = 0; i < data->num_ports; i++) {
211		memset(&uart, 0, sizeof(struct uart_8250_port));
212		spin_lock_init(&uart.port.lock);
213
214		uart.port.flags = UPF_SKIP_TEST |
215				  UPF_SHARE_IRQ |
216				  UPF_BOOT_AUTOCONF |
217				  UPF_IOREMAP;
218		uart.port.iotype = UPIO_MEM;
219		uart.port.uartclk = men_lookup_uartclk(mdev);
220		uart.port.irq = mcb_get_irq(mdev);
221		uart.port.mapbase = (unsigned long) mem->start
222					    + data->offset[i];
223
224		/* ok, register the port */
225		res = serial8250_register_8250_port(&uart);
226		if (res < 0) {
227			dev_err(&mdev->dev, "unable to register UART port\n");
228			return res;
229		}
230
231		data->line[i] = res;
232		dev_info(&mdev->dev, "found MCB UART: ttyS%d\n", data->line[i]);
233	}
234
235	return 0;
236}
237
238static void serial_8250_men_mcb_remove(struct mcb_device *mdev)
239{
240	int i;
241	struct serial_8250_men_mcb_data *data = mcb_get_drvdata(mdev);
242
243	if (!data)
244		return;
245
246	for (i = 0; i < data->num_ports; i++)
247		serial8250_unregister_port(data->line[i]);
248}
249
250static const struct mcb_device_id serial_8250_men_mcb_ids[] = {
251	{ .device = MEN_UART_ID_Z025 },
252	{ .device = MEN_UART_ID_Z057 },
253	{ .device = MEN_UART_ID_Z125 },
254	{ }
255};
256MODULE_DEVICE_TABLE(mcb, serial_8250_men_mcb_ids);
257
258static struct mcb_driver mcb_driver = {
259	.driver = {
260		.name = "8250_men_mcb",
261	},
262	.probe = serial_8250_men_mcb_probe,
263	.remove = serial_8250_men_mcb_remove,
264	.id_table = serial_8250_men_mcb_ids,
265};
266module_mcb_driver(mcb_driver);
267
268MODULE_LICENSE("GPL v2");
269MODULE_DESCRIPTION("MEN 8250 UART driver");
270MODULE_AUTHOR("Michael Moese <michael.moese@men.de");
271MODULE_ALIAS("mcb:16z125");
272MODULE_ALIAS("mcb:16z025");
273MODULE_ALIAS("mcb:16z057");
274MODULE_IMPORT_NS(MCB);
275