summaryrefslogtreecommitdiff
path: root/recipes-bsp/u-boot-mainline/files/0009-MLK-16560-1-imx8-Configure-sids-based-on-iommu-prope.patch
blob: 94a54ccbb176fa7f5849a693213e27943a6374f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
From dd44f99dc42905f17bc72832b9b2de391441e78b Mon Sep 17 00:00:00 2001
From: Ye Li <ye.li@nxp.com>
Date: Mon, 16 Apr 2018 00:27:31 -0700
Subject: [PATCH 09/15] MLK-16560-1: imx8: Configure sids based on iommu
 properties in dtb

Use streamids specified in dtb because they need to match anyway. This
removes the need to rebuild uboot for stream id assignments.

Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
Acked-by: Peng Fan <peng.fan@nxp.com>
(cherry picked from downstream commit 3caa05e6dc973b8710642f27f834bf022fbb65b4)
---
 arch/arm/mach-imx/imx8/cpu.c | 85 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c
index 7f2dd2166b..4eb15de93e 100644
--- a/arch/arm/mach-imx/imx8/cpu.c
+++ b/arch/arm/mach-imx/imx8/cpu.c
@@ -299,10 +299,95 @@ static void update_fdt_with_owned_resources(void *blob)
 		}
 	}
 }
+#endif
+
+#ifdef CONFIG_IMX_SMMU
+static int get_srsc_from_fdt_node_power_domain(void *blob, int device_offset)
+{
+	const fdt32_t *prop;
+	int pdnode_offset;
+
+	prop = fdt_getprop(blob, device_offset, "power-domains", NULL);
+	if (!prop) {
+		debug("node %s has no power-domains\n",
+				fdt_get_name(blob, device_offset, NULL));
+		return -ENOENT;
+	}
+
+	pdnode_offset = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*prop));
+	if (pdnode_offset < 0) {
+		pr_err("failed to fetch node %s power-domain",
+				fdt_get_name(blob, device_offset, NULL));
+		return pdnode_offset;
+	}
+
+	return fdtdec_get_uint(blob, pdnode_offset, "reg", -ENOENT);
+}
+
+static int config_smmu_resource_sid(int rsrc, int sid)
+{
+	sc_err_t err;
+
+	err = sc_rm_set_master_sid(-1, rsrc, sid);
+	debug("set_master_sid rsrc=%d sid=0x%x err=%d\n", rsrc, sid, err);
+	if (err != SC_ERR_NONE) {
+		pr_err("fail set_master_sid rsrc=%d sid=0x%x err=%d", rsrc, sid, err);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int config_smmu_fdt_device_sid(void *blob, int device_offset, int sid)
+{
+	int rsrc;
+	const char *name = fdt_get_name(blob, device_offset, NULL);
 
+	rsrc = get_srsc_from_fdt_node_power_domain(blob, device_offset);
+	debug("configure node %s sid 0x%x rsrc=%d\n", name, sid, rsrc);
+	if (rsrc < 0) {
+		debug("failed to determine SC_R_* for node %s\n", name);
+		return rsrc;
+	}
+
+	return config_smmu_resource_sid(rsrc, sid);
+}
+
+/* assign master sid based on iommu properties in fdt */
+static int config_smmu_fdt(void *blob)
+{
+	int offset, proplen;
+	const fdt32_t *prop;
+	const char *name;
+
+	offset = 0;
+	while ((offset = fdt_next_node(blob, offset, NULL)) > 0)
+	{
+		name = fdt_get_name(blob, offset, NULL);
+		prop = fdt_getprop(blob, offset, "iommus", &proplen);
+		if (!prop)
+			continue;
+		debug("node %s iommus proplen %d\n", name, proplen);
+
+		if (proplen == 12) {
+			int sid = fdt32_to_cpu(prop[1]);
+			config_smmu_fdt_device_sid(blob, offset, sid);
+		} else if (proplen != 4) {
+			debug("node %s ignore unexpected iommus proplen=%d\n", name, proplen);
+		}
+	}
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_OF_SYSTEM_SETUP
 int ft_system_setup(void *blob, bd_t *bd)
 {
 	update_fdt_with_owned_resources(blob);
+#ifdef CONFIG_IMX_SMMU
+	config_smmu_fdt(blob);
+#endif
 
 	return 0;
 }
-- 
2.13.6