1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2021 Mark Kettenis <kettenis@openbsd.org>
4  */
5 
6 #include <common.h>
7 #include <cpu_func.h>
8 #include <dm.h>
9 #include <asm/io.h>
10 
11 #define DART_PARAMS2		0x0004
12 #define  DART_PARAMS2_BYPASS_SUPPORT	BIT(0)
13 #define DART_TLB_OP		0x0020
14 #define  DART_TLB_OP_OPMASK	(0xfff << 20)
15 #define  DART_TLB_OP_FLUSH	(0x001 << 20)
16 #define  DART_TLB_OP_BUSY	BIT(2)
17 #define DART_TLB_OP_SIDMASK	0x0034
18 #define DART_ERROR_STATUS	0x0040
19 #define DART_TCR(sid)		(0x0100 + 4 * (sid))
20 #define  DART_TCR_TRANSLATE_ENABLE	BIT(7)
21 #define  DART_TCR_BYPASS_DART		BIT(8)
22 #define  DART_TCR_BYPASS_DAPF		BIT(12)
23 #define DART_TTBR(sid, idx)	(0x0200 + 16 * (sid) + 4 * (idx))
24 #define  DART_TTBR_VALID	BIT(31)
25 #define  DART_TTBR_SHIFT	12
26 
apple_dart_probe(struct udevice * dev)27 static int apple_dart_probe(struct udevice *dev)
28 {
29 	void *base;
30 	int sid, i;
31 
32 	base = dev_read_addr_ptr(dev);
33 	if (!base)
34 		return -EINVAL;
35 
36 	u32 params2 = readl(base + DART_PARAMS2);
37 	if (params2 & DART_PARAMS2_BYPASS_SUPPORT) {
38 		for (sid = 0; sid < 16; sid++) {
39 			writel(DART_TCR_BYPASS_DART | DART_TCR_BYPASS_DAPF,
40 			       base + DART_TCR(sid));
41 			for (i = 0; i < 4; i++)
42 				writel(0, base + DART_TTBR(sid, i));
43 		}
44 	}
45 
46 	return 0;
47 }
48 
49 static const struct udevice_id apple_dart_ids[] = {
50 	{ .compatible = "apple,t8103-dart" },
51 	{ /* sentinel */ }
52 };
53 
54 U_BOOT_DRIVER(apple_dart) = {
55 	.name = "apple_dart",
56 	.id = UCLASS_IOMMU,
57 	.of_match = apple_dart_ids,
58 	.probe = apple_dart_probe
59 };
60