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