1 /*
2  * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <common/debug.h>
8 #include <devapc.h>
9 #include <drivers/console.h>
10 #include <lib/mmio.h>
11 
set_master_transaction(uint32_t master_index,enum TRANSACTION transaction_type)12 static void set_master_transaction(uint32_t master_index,
13 				   enum TRANSACTION transaction_type)
14 {
15 	uintptr_t base;
16 	uint32_t master_register_index;
17 	uint32_t master_set_index;
18 	uint32_t set_bit;
19 
20 	master_register_index = master_index / (MOD_NO_IN_1_DEVAPC * 2);
21 	master_set_index = master_index % (MOD_NO_IN_1_DEVAPC * 2);
22 
23 	base = DEVAPC_INFRA_MAS_SEC_0 + master_register_index * 4;
24 
25 	set_bit = 0x1 << master_set_index;
26 	if (transaction_type == SECURE_TRANSACTION)
27 		mmio_setbits_32(base, set_bit);
28 	else
29 		mmio_clrbits_32(base, set_bit);
30 }
31 
set_master_domain(uint32_t master_index,enum MASK_DOM domain)32 static void set_master_domain(uint32_t master_index, enum MASK_DOM domain)
33 {
34 	uintptr_t base;
35 	uint32_t domain_reg;
36 	uint32_t domain_index;
37 	uint32_t clr_bit;
38 	uint32_t set_bit;
39 
40 	domain_reg = master_index / MASTER_MOD_NO_IN_1_DEVAPC;
41 	domain_index = master_index % MASTER_MOD_NO_IN_1_DEVAPC;
42 	clr_bit = 0xF << (4 * domain_index);
43 	set_bit = domain << (4 * domain_index);
44 
45 	base = DEVAPC_INFRA_MAS_DOM_0 + domain_reg * 4;
46 	mmio_clrsetbits_32(base, clr_bit, set_bit);
47 }
48 
set_master_domain_remap_infra(enum MASK_DOM domain_emi_view,enum MASK_DOM domain_infra_view)49 static void set_master_domain_remap_infra(enum MASK_DOM domain_emi_view,
50 					enum MASK_DOM domain_infra_view)
51 {
52 	uintptr_t base;
53 	uint32_t clr_bit;
54 	uint32_t set_bit;
55 
56 	if (domain_emi_view < DOMAIN_10) {
57 		base = DEVAPC_INFRA_DOM_RMP_0;
58 		clr_bit = 0x7 << (domain_emi_view * 3);
59 		set_bit = domain_infra_view << (domain_emi_view * 3);
60 		mmio_clrsetbits_32(base, clr_bit, set_bit);
61 	} else if (domain_emi_view > DOMAIN_10) {
62 		base = DEVAPC_INFRA_DOM_RMP_1;
63 		domain_emi_view = domain_emi_view - DOMAIN_11;
64 		clr_bit = 0x7 << (domain_emi_view * 3 + 1);
65 		set_bit = domain_infra_view << (domain_emi_view * 3 + 1);
66 		mmio_clrsetbits_32(base, clr_bit, set_bit);
67 	} else {
68 		base = DEVAPC_INFRA_DOM_RMP_0;
69 		clr_bit = 0x3 << (domain_emi_view * 3);
70 		set_bit = domain_infra_view << (domain_emi_view * 3);
71 		mmio_clrsetbits_32(base, clr_bit, set_bit);
72 
73 		base = DEVAPC_INFRA_DOM_RMP_1;
74 		set_bit = (domain_infra_view & 0x4) >> 2;
75 		mmio_clrsetbits_32(base, 0x1, set_bit);
76 	}
77 }
78 
set_master_domain_remap_mm(enum MASK_DOM domain_emi_view,enum MASK_DOM domain_mm_view)79 static void set_master_domain_remap_mm(enum MASK_DOM domain_emi_view,
80 					enum MASK_DOM domain_mm_view)
81 {
82 	uintptr_t base;
83 	uint32_t clr_bit;
84 	uint32_t set_bit;
85 
86 	base = DEVAPC_MM_DOM_RMP_0;
87 	clr_bit = 0x3 << (domain_emi_view * 2);
88 	set_bit = domain_mm_view << (domain_emi_view * 2);
89 
90 	mmio_clrsetbits_32(base, clr_bit, set_bit);
91 }
92 
set_module_apc(enum DAPC_SLAVE_TYPE slave_type,uint32_t module,enum MASK_DOM domain_num,enum APC_ATTR permission_control)93 static void set_module_apc(enum DAPC_SLAVE_TYPE slave_type, uint32_t module,
94 			   enum MASK_DOM domain_num,
95 			   enum APC_ATTR permission_control)
96 {
97 	uintptr_t base;
98 	uint32_t apc_index;
99 	uint32_t apc_set_index;
100 	uint32_t clr_bit;
101 	uint32_t set_bit;
102 
103 	apc_index = module / MOD_NO_IN_1_DEVAPC;
104 	apc_set_index = module % MOD_NO_IN_1_DEVAPC;
105 	clr_bit = 0x3 << (apc_set_index * 2);
106 	set_bit = permission_control << (apc_set_index * 2);
107 
108 	if (slave_type == DAPC_INFRA_SLAVE && module <= SLAVE_INFRA_MAX_INDEX)
109 		base = DEVAPC_INFRA_D0_APC_0 + domain_num * 0x100 +
110 					       apc_index * 4;
111 	else if (slave_type == DAPC_MM_SLAVE && module <= SLAVE_MM_MAX_INDEX)
112 		base = DEVAPC_MM_D0_APC_0 + domain_num * 0x100 + apc_index * 4;
113 	else
114 		return;
115 
116 	mmio_clrsetbits_32(base, clr_bit, set_bit);
117 }
118 
set_default_master_transaction(void)119 static void set_default_master_transaction(void)
120 {
121 	set_master_transaction(MASTER_SSPM, SECURE_TRANSACTION);
122 }
123 
set_default_master_domain(void)124 static void set_default_master_domain(void)
125 {
126 	set_master_domain(MASTER_SCP, DOMAIN_1);
127 	set_master_domain_remap_infra(DOMAIN_1, DOMAIN_1);
128 	set_master_domain_remap_mm(DOMAIN_1, DOMAIN_1);
129 
130 	set_master_domain(MASTER_SPM, DOMAIN_2);
131 	set_master_domain_remap_infra(DOMAIN_2, DOMAIN_2);
132 	set_master_domain_remap_mm(DOMAIN_2, DOMAIN_2);
133 
134 	set_master_domain(MASTER_SSPM, DOMAIN_2);
135 	set_master_domain_remap_infra(DOMAIN_2, DOMAIN_2);
136 	set_master_domain_remap_mm(DOMAIN_2, DOMAIN_2);
137 }
138 
set_default_slave_permission(void)139 static void set_default_slave_permission(void)
140 {
141 	uint32_t module_index;
142 	uint32_t infra_size;
143 	uint32_t mm_size;
144 
145 	infra_size = sizeof(D_APC_INFRA_Devices) / sizeof(struct DEVICE_INFO);
146 	mm_size = sizeof(D_APC_MM_Devices) / sizeof(struct DEVICE_INFO);
147 
148 	for (module_index = 0; module_index < infra_size; module_index++) {
149 		if (D_APC_INFRA_Devices[module_index].d0_permission > 0) {
150 			set_module_apc(DAPC_INFRA_SLAVE, module_index, DOMAIN_0,
151 			       D_APC_INFRA_Devices[module_index].d0_permission);
152 		}
153 		if (D_APC_INFRA_Devices[module_index].d1_permission > 0) {
154 			set_module_apc(DAPC_INFRA_SLAVE, module_index, DOMAIN_1,
155 			       D_APC_INFRA_Devices[module_index].d1_permission);
156 		}
157 		if (D_APC_INFRA_Devices[module_index].d2_permission > 0) {
158 			set_module_apc(DAPC_INFRA_SLAVE, module_index, DOMAIN_2,
159 			       D_APC_INFRA_Devices[module_index].d2_permission);
160 		}
161 	}
162 
163 	for (module_index = 0; module_index < mm_size; module_index++) {
164 		if (D_APC_MM_Devices[module_index].d0_permission > 0) {
165 			set_module_apc(DAPC_MM_SLAVE, module_index, DOMAIN_0,
166 				D_APC_MM_Devices[module_index].d0_permission);
167 		}
168 		if (D_APC_MM_Devices[module_index].d1_permission > 0) {
169 			set_module_apc(DAPC_MM_SLAVE, module_index, DOMAIN_1,
170 				D_APC_MM_Devices[module_index].d1_permission);
171 		}
172 		if (D_APC_MM_Devices[module_index].d2_permission > 0) {
173 			set_module_apc(DAPC_MM_SLAVE, module_index, DOMAIN_2,
174 				D_APC_MM_Devices[module_index].d2_permission);
175 		}
176 	}
177 }
178 
dump_devapc(void)179 static void dump_devapc(void)
180 {
181 	int i;
182 
183 	INFO("[DEVAPC] dump DEVAPC registers:\n");
184 
185 	for (i = 0; i < 13; i++) {
186 		INFO("[DEVAPC] (INFRA)D0_APC_%d = 0x%x, "
187 			       "(INFRA)D1_APC_%d = 0x%x, "
188 			       "(INFRA)D2_APC_%d = 0x%x\n",
189 		i, mmio_read_32(DEVAPC_INFRA_D0_APC_0 + i * 4),
190 		i, mmio_read_32(DEVAPC_INFRA_D0_APC_0 + 0x100 + i * 4),
191 		i, mmio_read_32(DEVAPC_INFRA_D0_APC_0 + 0x200 + i * 4));
192 	}
193 
194 	for (i = 0; i < 9; i++) {
195 		INFO("[DEVAPC] (MM)D0_APC_%d = 0x%x, "
196 			       "(MM)D1_APC_%d = 0x%x, "
197 			       "(MM)D2_APC_%d = 0x%x\n",
198 		i, mmio_read_32(DEVAPC_MM_D0_APC_0 + i * 4),
199 		i, mmio_read_32(DEVAPC_MM_D0_APC_0 + 0x100 + i * 4),
200 		i, mmio_read_32(DEVAPC_MM_D0_APC_0 + 0x200 + i * 4));
201 	}
202 
203 	for (i = 0; i < 4; i++) {
204 		INFO("[DEVAPC] MAS_DOM_%d = 0x%x\n", i,
205 			mmio_read_32(DEVAPC_INFRA_MAS_DOM_0 + i * 4));
206 	}
207 
208 	INFO("[DEVAPC] MAS_SEC_0 = 0x%x\n",
209 			mmio_read_32(DEVAPC_INFRA_MAS_SEC_0));
210 
211 	INFO("[DEVAPC]  (INFRA)MAS_DOMAIN_REMAP_0 = 0x%x, "
212 			"(INFRA)MAS_DOMAIN_REMAP_1 = 0x%x\n",
213 			mmio_read_32(DEVAPC_INFRA_DOM_RMP_0),
214 			mmio_read_32(DEVAPC_INFRA_DOM_RMP_1));
215 
216 	INFO("[DEVAPC]  (MM)MAS_DOMAIN_REMAP_0 = 0x%x\n",
217 			mmio_read_32(DEVAPC_MM_DOM_RMP_0));
218 }
219 
devapc_init(void)220 void devapc_init(void)
221 {
222 	mmio_write_32(DEVAPC_INFRA_APC_CON, 0x80000001);
223 	mmio_write_32(DEVAPC_MM_APC_CON, 0x80000001);
224 	mmio_write_32(DEVAPC_MD_APC_CON, 0x80000001);
225 
226 	set_default_master_transaction();
227 	set_default_master_domain();
228 	set_default_slave_permission();
229 	dump_devapc();
230 }
231 
232