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 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 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 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 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 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 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 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 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 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 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