mediatek: mt8183: add DEVAPC driver to control protection
[project/bcm63xx/atf.git] / plat / mediatek / mt8183 / drivers / devapc / devapc.c
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
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
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
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
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
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
119 static void set_default_master_transaction(void)
120 {
121 set_master_transaction(MASTER_SSPM, SECURE_TRANSACTION);
122 }
123
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
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
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
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