xref: /linux/drivers/soc/aspeed/aspeed-uart-routing.c (revision 6e7fd890f1d6ac83805409e9c346240de2705584)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2018 Google LLC
4  * Copyright (c) 2021 Aspeed Technology Inc.
5  */
6 #include <linux/device.h>
7 #include <linux/module.h>
8 #include <linux/of.h>
9 #include <linux/mfd/syscon.h>
10 #include <linux/regmap.h>
11 #include <linux/platform_device.h>
12 
13 /* register offsets */
14 #define HICR9	0x98
15 #define HICRA	0x9c
16 
17 /* attributes options */
18 #define UART_ROUTING_IO1	"io1"
19 #define UART_ROUTING_IO2	"io2"
20 #define UART_ROUTING_IO3	"io3"
21 #define UART_ROUTING_IO4	"io4"
22 #define UART_ROUTING_IO5	"io5"
23 #define UART_ROUTING_IO6	"io6"
24 #define UART_ROUTING_IO10	"io10"
25 #define UART_ROUTING_UART1	"uart1"
26 #define UART_ROUTING_UART2	"uart2"
27 #define UART_ROUTING_UART3	"uart3"
28 #define UART_ROUTING_UART4	"uart4"
29 #define UART_ROUTING_UART5	"uart5"
30 #define UART_ROUTING_UART6	"uart6"
31 #define UART_ROUTING_UART10	"uart10"
32 #define UART_ROUTING_RES	"reserved"
33 
34 struct aspeed_uart_routing {
35 	struct regmap *map;
36 	struct attribute_group const *attr_grp;
37 };
38 
39 struct aspeed_uart_routing_selector {
40 	struct device_attribute	dev_attr;
41 	uint8_t reg;
42 	uint8_t mask;
43 	uint8_t shift;
44 	const char *const options[];
45 };
46 
47 #define to_routing_selector(_dev_attr)					\
48 	container_of(_dev_attr, struct aspeed_uart_routing_selector, dev_attr)
49 
50 static ssize_t aspeed_uart_routing_show(struct device *dev,
51 					struct device_attribute *attr,
52 					char *buf);
53 
54 static ssize_t aspeed_uart_routing_store(struct device *dev,
55 					 struct device_attribute *attr,
56 					 const char *buf, size_t count);
57 
58 #define ROUTING_ATTR(_name) {					\
59 	.attr = {.name = _name,					\
60 		 .mode = VERIFY_OCTAL_PERMISSIONS(0644) },	\
61 	.show = aspeed_uart_routing_show,			\
62 	.store = aspeed_uart_routing_store,			\
63 }
64 
65 /* routing selector for AST25xx */
66 static struct aspeed_uart_routing_selector ast2500_io6_sel = {
67 	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO6),
68 	.reg = HICR9,
69 	.shift = 8,
70 	.mask = 0xf,
71 	.options = {
72 		    UART_ROUTING_UART1,
73 		    UART_ROUTING_UART2,
74 		    UART_ROUTING_UART3,
75 		    UART_ROUTING_UART4,
76 		    UART_ROUTING_UART5,
77 		    UART_ROUTING_IO1,
78 		    UART_ROUTING_IO2,
79 		    UART_ROUTING_IO3,
80 		    UART_ROUTING_IO4,
81 		    UART_ROUTING_IO5,
82 		    NULL,
83 		    },
84 };
85 
86 static struct aspeed_uart_routing_selector ast2500_uart5_sel = {
87 	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART5),
88 	.reg = HICRA,
89 	.shift = 28,
90 	.mask = 0xf,
91 	.options = {
92 		    UART_ROUTING_IO5,
93 		    UART_ROUTING_IO1,
94 		    UART_ROUTING_IO2,
95 		    UART_ROUTING_IO3,
96 		    UART_ROUTING_IO4,
97 		    UART_ROUTING_UART1,
98 		    UART_ROUTING_UART2,
99 		    UART_ROUTING_UART3,
100 		    UART_ROUTING_UART4,
101 		    UART_ROUTING_IO6,
102 		    NULL,
103 		    },
104 };
105 
106 static struct aspeed_uart_routing_selector ast2500_uart4_sel = {
107 	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART4),
108 	.reg = HICRA,
109 	.shift = 25,
110 	.mask = 0x7,
111 	.options = {
112 		    UART_ROUTING_IO4,
113 		    UART_ROUTING_IO1,
114 		    UART_ROUTING_IO2,
115 		    UART_ROUTING_IO3,
116 		    UART_ROUTING_UART1,
117 		    UART_ROUTING_UART2,
118 		    UART_ROUTING_UART3,
119 		    UART_ROUTING_IO6,
120 		    NULL,
121 	},
122 };
123 
124 static struct aspeed_uart_routing_selector ast2500_uart3_sel = {
125 	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART3),
126 	.reg = HICRA,
127 	.shift = 22,
128 	.mask = 0x7,
129 	.options = {
130 		    UART_ROUTING_IO3,
131 		    UART_ROUTING_IO4,
132 		    UART_ROUTING_IO1,
133 		    UART_ROUTING_IO2,
134 		    UART_ROUTING_UART4,
135 		    UART_ROUTING_UART1,
136 		    UART_ROUTING_UART2,
137 		    UART_ROUTING_IO6,
138 		    NULL,
139 		    },
140 };
141 
142 static struct aspeed_uart_routing_selector ast2500_uart2_sel = {
143 	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART2),
144 	.reg = HICRA,
145 	.shift = 19,
146 	.mask = 0x7,
147 	.options = {
148 		    UART_ROUTING_IO2,
149 		    UART_ROUTING_IO3,
150 		    UART_ROUTING_IO4,
151 		    UART_ROUTING_IO1,
152 		    UART_ROUTING_UART3,
153 		    UART_ROUTING_UART4,
154 		    UART_ROUTING_UART1,
155 		    UART_ROUTING_IO6,
156 		    NULL,
157 		    },
158 };
159 
160 static struct aspeed_uart_routing_selector ast2500_uart1_sel = {
161 	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART1),
162 	.reg = HICRA,
163 	.shift = 16,
164 	.mask = 0x7,
165 	.options = {
166 		    UART_ROUTING_IO1,
167 		    UART_ROUTING_IO2,
168 		    UART_ROUTING_IO3,
169 		    UART_ROUTING_IO4,
170 		    UART_ROUTING_UART2,
171 		    UART_ROUTING_UART3,
172 		    UART_ROUTING_UART4,
173 		    UART_ROUTING_IO6,
174 		    NULL,
175 		    },
176 };
177 
178 static struct aspeed_uart_routing_selector ast2500_io5_sel = {
179 	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO5),
180 	.reg = HICRA,
181 	.shift = 12,
182 	.mask = 0x7,
183 	.options = {
184 		    UART_ROUTING_UART5,
185 		    UART_ROUTING_UART1,
186 		    UART_ROUTING_UART2,
187 		    UART_ROUTING_UART3,
188 		    UART_ROUTING_UART4,
189 		    UART_ROUTING_IO1,
190 		    UART_ROUTING_IO3,
191 		    UART_ROUTING_IO6,
192 		    NULL,
193 		    },
194 };
195 
196 static struct aspeed_uart_routing_selector ast2500_io4_sel = {
197 	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO4),
198 	.reg = HICRA,
199 	.shift = 9,
200 	.mask = 0x7,
201 	.options = {
202 		    UART_ROUTING_UART4,
203 		    UART_ROUTING_UART5,
204 		    UART_ROUTING_UART1,
205 		    UART_ROUTING_UART2,
206 		    UART_ROUTING_UART3,
207 		    UART_ROUTING_IO1,
208 		    UART_ROUTING_IO2,
209 		    UART_ROUTING_IO6,
210 		    NULL,
211 		    },
212 };
213 
214 static struct aspeed_uart_routing_selector ast2500_io3_sel = {
215 	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO3),
216 	.reg = HICRA,
217 	.shift = 6,
218 	.mask = 0x7,
219 	.options = {
220 		    UART_ROUTING_UART3,
221 		    UART_ROUTING_UART4,
222 		    UART_ROUTING_UART5,
223 		    UART_ROUTING_UART1,
224 		    UART_ROUTING_UART2,
225 		    UART_ROUTING_IO1,
226 		    UART_ROUTING_IO2,
227 		    UART_ROUTING_IO6,
228 		    NULL,
229 		    },
230 };
231 
232 static struct aspeed_uart_routing_selector ast2500_io2_sel = {
233 	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO2),
234 	.reg = HICRA,
235 	.shift = 3,
236 	.mask = 0x7,
237 	.options = {
238 		    UART_ROUTING_UART2,
239 		    UART_ROUTING_UART3,
240 		    UART_ROUTING_UART4,
241 		    UART_ROUTING_UART5,
242 		    UART_ROUTING_UART1,
243 		    UART_ROUTING_IO3,
244 		    UART_ROUTING_IO4,
245 		    UART_ROUTING_IO6,
246 		    NULL,
247 		    },
248 };
249 
250 static struct aspeed_uart_routing_selector ast2500_io1_sel = {
251 	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO1),
252 	.reg = HICRA,
253 	.shift = 0,
254 	.mask = 0x7,
255 	.options = {
256 		    UART_ROUTING_UART1,
257 		    UART_ROUTING_UART2,
258 		    UART_ROUTING_UART3,
259 		    UART_ROUTING_UART4,
260 		    UART_ROUTING_UART5,
261 		    UART_ROUTING_IO3,
262 		    UART_ROUTING_IO4,
263 		    UART_ROUTING_IO6,
264 		    NULL,
265 		    },
266 };
267 
268 static struct attribute *ast2500_uart_routing_attrs[] = {
269 	&ast2500_io6_sel.dev_attr.attr,
270 	&ast2500_uart5_sel.dev_attr.attr,
271 	&ast2500_uart4_sel.dev_attr.attr,
272 	&ast2500_uart3_sel.dev_attr.attr,
273 	&ast2500_uart2_sel.dev_attr.attr,
274 	&ast2500_uart1_sel.dev_attr.attr,
275 	&ast2500_io5_sel.dev_attr.attr,
276 	&ast2500_io4_sel.dev_attr.attr,
277 	&ast2500_io3_sel.dev_attr.attr,
278 	&ast2500_io2_sel.dev_attr.attr,
279 	&ast2500_io1_sel.dev_attr.attr,
280 	NULL,
281 };
282 
283 static const struct attribute_group ast2500_uart_routing_attr_group = {
284 	.attrs = ast2500_uart_routing_attrs,
285 };
286 
287 /* routing selector for AST26xx */
288 static struct aspeed_uart_routing_selector ast2600_uart10_sel = {
289 	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART10),
290 	.reg = HICR9,
291 	.shift = 12,
292 	.mask = 0xf,
293 	.options = {
294 		    UART_ROUTING_IO10,
295 		    UART_ROUTING_IO1,
296 		    UART_ROUTING_IO2,
297 		    UART_ROUTING_IO3,
298 		    UART_ROUTING_IO4,
299 			UART_ROUTING_RES,
300 		    UART_ROUTING_UART1,
301 		    UART_ROUTING_UART2,
302 		    UART_ROUTING_UART3,
303 		    UART_ROUTING_UART4,
304 		    NULL,
305 		    },
306 };
307 
308 static struct aspeed_uart_routing_selector ast2600_io10_sel = {
309 	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO10),
310 	.reg = HICR9,
311 	.shift = 8,
312 	.mask = 0xf,
313 	.options = {
314 		    UART_ROUTING_UART1,
315 		    UART_ROUTING_UART2,
316 		    UART_ROUTING_UART3,
317 		    UART_ROUTING_UART4,
318 			UART_ROUTING_RES,
319 		    UART_ROUTING_IO1,
320 		    UART_ROUTING_IO2,
321 		    UART_ROUTING_IO3,
322 		    UART_ROUTING_IO4,
323 			UART_ROUTING_RES,
324 		    UART_ROUTING_UART10,
325 		    NULL,
326 		    },
327 };
328 
329 static struct aspeed_uart_routing_selector ast2600_uart4_sel = {
330 	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART4),
331 	.reg = HICRA,
332 	.shift = 25,
333 	.mask = 0x7,
334 	.options = {
335 		    UART_ROUTING_IO4,
336 		    UART_ROUTING_IO1,
337 		    UART_ROUTING_IO2,
338 		    UART_ROUTING_IO3,
339 		    UART_ROUTING_UART1,
340 		    UART_ROUTING_UART2,
341 		    UART_ROUTING_UART3,
342 		    UART_ROUTING_IO10,
343 		    NULL,
344 	},
345 };
346 
347 static struct aspeed_uart_routing_selector ast2600_uart3_sel = {
348 	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART3),
349 	.reg = HICRA,
350 	.shift = 22,
351 	.mask = 0x7,
352 	.options = {
353 		    UART_ROUTING_IO3,
354 		    UART_ROUTING_IO4,
355 		    UART_ROUTING_IO1,
356 		    UART_ROUTING_IO2,
357 		    UART_ROUTING_UART4,
358 		    UART_ROUTING_UART1,
359 		    UART_ROUTING_UART2,
360 		    UART_ROUTING_IO10,
361 		    NULL,
362 		    },
363 };
364 
365 static struct aspeed_uart_routing_selector ast2600_uart2_sel = {
366 	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART2),
367 	.reg = HICRA,
368 	.shift = 19,
369 	.mask = 0x7,
370 	.options = {
371 		    UART_ROUTING_IO2,
372 		    UART_ROUTING_IO3,
373 		    UART_ROUTING_IO4,
374 		    UART_ROUTING_IO1,
375 		    UART_ROUTING_UART3,
376 		    UART_ROUTING_UART4,
377 		    UART_ROUTING_UART1,
378 		    UART_ROUTING_IO10,
379 		    NULL,
380 		    },
381 };
382 
383 static struct aspeed_uart_routing_selector ast2600_uart1_sel = {
384 	.dev_attr = ROUTING_ATTR(UART_ROUTING_UART1),
385 	.reg = HICRA,
386 	.shift = 16,
387 	.mask = 0x7,
388 	.options = {
389 		    UART_ROUTING_IO1,
390 		    UART_ROUTING_IO2,
391 		    UART_ROUTING_IO3,
392 		    UART_ROUTING_IO4,
393 		    UART_ROUTING_UART2,
394 		    UART_ROUTING_UART3,
395 		    UART_ROUTING_UART4,
396 		    UART_ROUTING_IO10,
397 		    NULL,
398 		    },
399 };
400 
401 static struct aspeed_uart_routing_selector ast2600_io4_sel = {
402 	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO4),
403 	.reg = HICRA,
404 	.shift = 9,
405 	.mask = 0x7,
406 	.options = {
407 		    UART_ROUTING_UART4,
408 		    UART_ROUTING_UART10,
409 		    UART_ROUTING_UART1,
410 		    UART_ROUTING_UART2,
411 		    UART_ROUTING_UART3,
412 		    UART_ROUTING_IO1,
413 		    UART_ROUTING_IO2,
414 		    UART_ROUTING_IO10,
415 		    NULL,
416 		    },
417 };
418 
419 static struct aspeed_uart_routing_selector ast2600_io3_sel = {
420 	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO3),
421 	.reg = HICRA,
422 	.shift = 6,
423 	.mask = 0x7,
424 	.options = {
425 		    UART_ROUTING_UART3,
426 		    UART_ROUTING_UART4,
427 		    UART_ROUTING_UART10,
428 		    UART_ROUTING_UART1,
429 		    UART_ROUTING_UART2,
430 		    UART_ROUTING_IO1,
431 		    UART_ROUTING_IO2,
432 		    UART_ROUTING_IO10,
433 		    NULL,
434 		    },
435 };
436 
437 static struct aspeed_uart_routing_selector ast2600_io2_sel = {
438 	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO2),
439 	.reg = HICRA,
440 	.shift = 3,
441 	.mask = 0x7,
442 	.options = {
443 		    UART_ROUTING_UART2,
444 		    UART_ROUTING_UART3,
445 		    UART_ROUTING_UART4,
446 		    UART_ROUTING_UART10,
447 		    UART_ROUTING_UART1,
448 		    UART_ROUTING_IO3,
449 		    UART_ROUTING_IO4,
450 		    UART_ROUTING_IO10,
451 		    NULL,
452 		    },
453 };
454 
455 static struct aspeed_uart_routing_selector ast2600_io1_sel = {
456 	.dev_attr = ROUTING_ATTR(UART_ROUTING_IO1),
457 	.reg = HICRA,
458 	.shift = 0,
459 	.mask = 0x7,
460 	.options = {
461 		    UART_ROUTING_UART1,
462 		    UART_ROUTING_UART2,
463 		    UART_ROUTING_UART3,
464 		    UART_ROUTING_UART4,
465 		    UART_ROUTING_UART10,
466 		    UART_ROUTING_IO3,
467 		    UART_ROUTING_IO4,
468 		    UART_ROUTING_IO10,
469 		    NULL,
470 		    },
471 };
472 
473 static struct attribute *ast2600_uart_routing_attrs[] = {
474 	&ast2600_uart10_sel.dev_attr.attr,
475 	&ast2600_io10_sel.dev_attr.attr,
476 	&ast2600_uart4_sel.dev_attr.attr,
477 	&ast2600_uart3_sel.dev_attr.attr,
478 	&ast2600_uart2_sel.dev_attr.attr,
479 	&ast2600_uart1_sel.dev_attr.attr,
480 	&ast2600_io4_sel.dev_attr.attr,
481 	&ast2600_io3_sel.dev_attr.attr,
482 	&ast2600_io2_sel.dev_attr.attr,
483 	&ast2600_io1_sel.dev_attr.attr,
484 	NULL,
485 };
486 
487 static const struct attribute_group ast2600_uart_routing_attr_group = {
488 	.attrs = ast2600_uart_routing_attrs,
489 };
490 
491 static ssize_t aspeed_uart_routing_show(struct device *dev,
492 					struct device_attribute *attr,
493 					char *buf)
494 {
495 	struct aspeed_uart_routing *uart_routing = dev_get_drvdata(dev);
496 	struct aspeed_uart_routing_selector *sel = to_routing_selector(attr);
497 	int val, pos, len;
498 
499 	regmap_read(uart_routing->map, sel->reg, &val);
500 	val = (val >> sel->shift) & sel->mask;
501 
502 	len = 0;
503 	for (pos = 0; sel->options[pos] != NULL; ++pos) {
504 		if (pos == val)
505 			len += sysfs_emit_at(buf, len, "[%s] ", sel->options[pos]);
506 		else
507 			len += sysfs_emit_at(buf, len, "%s ", sel->options[pos]);
508 	}
509 
510 	if (val >= pos)
511 		len += sysfs_emit_at(buf, len, "[unknown(%d)]", val);
512 
513 	len += sysfs_emit_at(buf, len, "\n");
514 
515 	return len;
516 }
517 
518 static ssize_t aspeed_uart_routing_store(struct device *dev,
519 					 struct device_attribute *attr,
520 					 const char *buf, size_t count)
521 {
522 	struct aspeed_uart_routing *uart_routing = dev_get_drvdata(dev);
523 	struct aspeed_uart_routing_selector *sel = to_routing_selector(attr);
524 	int val;
525 
526 	val = __sysfs_match_string(sel->options, -1, buf);
527 	if (val < 0) {
528 		dev_err(dev, "invalid value \"%s\"\n", buf);
529 		return -EINVAL;
530 	}
531 
532 	regmap_update_bits(uart_routing->map, sel->reg,
533 			(sel->mask << sel->shift),
534 			(val & sel->mask) << sel->shift);
535 
536 	return count;
537 }
538 
539 static int aspeed_uart_routing_probe(struct platform_device *pdev)
540 {
541 	int rc;
542 	struct device *dev = &pdev->dev;
543 	struct aspeed_uart_routing *uart_routing;
544 
545 	uart_routing = devm_kzalloc(&pdev->dev, sizeof(*uart_routing), GFP_KERNEL);
546 	if (!uart_routing)
547 		return -ENOMEM;
548 
549 	uart_routing->map = syscon_node_to_regmap(dev->parent->of_node);
550 	if (IS_ERR(uart_routing->map)) {
551 		dev_err(dev, "cannot get regmap\n");
552 		return PTR_ERR(uart_routing->map);
553 	}
554 
555 	uart_routing->attr_grp = of_device_get_match_data(dev);
556 
557 	rc = sysfs_create_group(&dev->kobj, uart_routing->attr_grp);
558 	if (rc < 0)
559 		return rc;
560 
561 	dev_set_drvdata(dev, uart_routing);
562 
563 	dev_info(dev, "module loaded\n");
564 
565 	return 0;
566 }
567 
568 static void aspeed_uart_routing_remove(struct platform_device *pdev)
569 {
570 	struct device *dev = &pdev->dev;
571 	struct aspeed_uart_routing *uart_routing = platform_get_drvdata(pdev);
572 
573 	sysfs_remove_group(&dev->kobj, uart_routing->attr_grp);
574 }
575 
576 static const struct of_device_id aspeed_uart_routing_table[] = {
577 	{ .compatible = "aspeed,ast2400-uart-routing",
578 	  .data = &ast2500_uart_routing_attr_group },
579 	{ .compatible = "aspeed,ast2500-uart-routing",
580 	  .data = &ast2500_uart_routing_attr_group },
581 	{ .compatible = "aspeed,ast2600-uart-routing",
582 	  .data = &ast2600_uart_routing_attr_group },
583 	{ },
584 };
585 
586 static struct platform_driver aspeed_uart_routing_driver = {
587 	.driver = {
588 		.name = "aspeed-uart-routing",
589 		.of_match_table = aspeed_uart_routing_table,
590 	},
591 	.probe = aspeed_uart_routing_probe,
592 	.remove_new = aspeed_uart_routing_remove,
593 };
594 
595 module_platform_driver(aspeed_uart_routing_driver);
596 
597 MODULE_AUTHOR("Oskar Senft <osk@google.com>");
598 MODULE_AUTHOR("Chia-Wei Wang <chiawei_wang@aspeedtech.com>");
599 MODULE_LICENSE("GPL v2");
600 MODULE_DESCRIPTION("Driver to configure Aspeed UART routing");
601