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