1 /* 2 * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <errno.h> 8 9 #include <common/debug.h> 10 #include <plat/arm/common/plat_arm.h> 11 #include <platform_def.h> 12 13 #define NI_CHILD_NODE_COUNT 4 14 #define NI_CHILD_POINTERS_START 8 15 16 #define NI_PMU_SECURE_CTRL 0x100 17 #define NI_PMU_SECURE_EVENT_OBSERVATION 0x108 18 #define NI_PMU_DEBUG_ENABLE 0x110 19 #define NI_COMP_NUM_SUBFEATURES 0x100 20 #define NI_COMP_SUBFEATURE_TYPE_START 0x108 21 #define NI_COMP_SUBFEATURE_SECURE_CTRL_START 0x308 22 23 #define SECURE_OVERRIDE_DEFAULT BIT(0) 24 #define SECURE_EVENT_ENABLE BIT(2) 25 #define NA_EVENT_ENABLE BIT(3) 26 #define PMU_ENABLE BIT(0) 27 28 #define NI_NODE_MASK 0x0000ffff 29 #define NI_NODE_TYPE(node_info) (node_info & NI_NODE_MASK) 30 #define NI_CHILD_POINTER(i) (NI_CHILD_POINTERS_START + (i * 4)) 31 #define NI_COMP_SUBFEATURE_TYPE(i) (NI_COMP_SUBFEATURE_TYPE_START + (i * 8)) 32 #define NI_COMP_SUBFEATURE_SECURE_CTRL(i) (NI_COMP_SUBFEATURE_SECURE_CTRL_START + (i * 8)) 33 34 #define NI_PERIPHERAL_ID0 0xfe0 35 #define NI_PIDR0_PART_MASK 0xff 36 #define NI_PERIPHERAL_ID1 0xfe4 37 #define NI_PIDR1_PART_MASK 0xf 38 #define NI_PIDR1_PART_SHIFT 8 39 40 enum ni_part { 41 NI_700 = 0x43b, 42 NI_710AE = 0x43d, 43 NI_TOWER = 0x43f, 44 }; 45 46 enum ni_node_type { 47 NI_INVALID_NODE = 0, 48 NI_VOLTAGE_DOMAIN = 1, 49 NI_POWER_DOMAIN = 2, 50 NI_CLOCK_DOMAIN = 3, 51 NI_ASNI = 4, 52 NI_AMNI = 5, 53 NI_PMU = 6, 54 NI_HSNI = 7, 55 NI_HMNI = 8, 56 NI_PMNI = 9, 57 NI_CMNI = 14, 58 NI_CFGNI = 15 59 }; 60 61 enum ni_subfeature_type { 62 NI_SUBFEATURE_APU = 0, 63 NI_SUBFEATURE_ADDR_MAP = 1, 64 NI_SUBFEATURE_FCU = 2, 65 NI_SUBFEATURE_IDM = 3 66 }; 67 68 static void ni_enable_pmu(uintptr_t pmu_addr) 69 { 70 mmio_setbits_32(pmu_addr + NI_PMU_DEBUG_ENABLE, PMU_ENABLE); 71 } 72 73 static void ni_enable_fcu_ns_access(uintptr_t comp_addr) 74 { 75 uint32_t subfeature_type; 76 uint32_t subfeature_count; 77 uint32_t subfeature_secure_ctrl; 78 79 subfeature_count = mmio_read_32(comp_addr + NI_COMP_NUM_SUBFEATURES); 80 for (uint32_t i = 0U; i < subfeature_count; i++) { 81 subfeature_type = 82 NI_NODE_TYPE(mmio_read_32(comp_addr + NI_COMP_SUBFEATURE_TYPE(i))); 83 if (subfeature_type == NI_SUBFEATURE_FCU) { 84 subfeature_secure_ctrl = comp_addr + NI_COMP_SUBFEATURE_SECURE_CTRL(i); 85 mmio_setbits_32(subfeature_secure_ctrl, SECURE_OVERRIDE_DEFAULT); 86 } 87 } 88 } 89 90 static void ni_enable_pmu_ns_access(uintptr_t comp_addr) 91 { 92 mmio_setbits_32(comp_addr + NI_PMU_SECURE_CTRL, SECURE_OVERRIDE_DEFAULT); 93 mmio_setbits_32(comp_addr + NI_PMU_SECURE_EVENT_OBSERVATION, 94 SECURE_EVENT_ENABLE | NA_EVENT_ENABLE); 95 } 96 97 static void ni_setup_component(uintptr_t comp_addr) 98 { 99 uint32_t node_info; 100 101 node_info = mmio_read_32(comp_addr); 102 103 switch (NI_NODE_TYPE(node_info)) { 104 case NI_ASNI: 105 case NI_AMNI: 106 case NI_HSNI: 107 case NI_HMNI: 108 case NI_PMNI: 109 ni_enable_fcu_ns_access(comp_addr); 110 break; 111 case NI_PMU: 112 ni_enable_pmu_ns_access(comp_addr); 113 ni_enable_pmu(comp_addr); 114 break; 115 default: 116 return; 117 } 118 } 119 120 int plat_arm_ni_setup(uintptr_t global_cfg) 121 { 122 uintptr_t vd_addr; 123 uintptr_t pd_addr; 124 uintptr_t cd_addr; 125 uintptr_t comp_addr; 126 uint32_t vd_count; 127 uint32_t pd_count; 128 uint32_t cd_count; 129 uint32_t comp_count; 130 uint32_t part; 131 uint32_t reg; 132 133 reg = mmio_read_32(global_cfg + NI_PERIPHERAL_ID0); 134 part = reg & NI_PIDR0_PART_MASK; 135 reg = mmio_read_32(global_cfg + NI_PERIPHERAL_ID1); 136 part |= ((reg & NI_PIDR1_PART_MASK) << NI_PIDR1_PART_SHIFT); 137 138 if (part != NI_TOWER) { 139 ERROR("0x%x is not supported\n", part); 140 return -EINVAL; 141 } 142 143 vd_count = mmio_read_32(global_cfg + NI_CHILD_NODE_COUNT); 144 145 for (uint32_t i = 0U; i < vd_count; i++) { 146 vd_addr = global_cfg + mmio_read_32(global_cfg + NI_CHILD_POINTER(i)); 147 148 VERBOSE("Voltage domain %u at 0x%lx node info: 0x%x\n", 149 i, vd_addr, mmio_read_32(vd_addr)); 150 151 pd_count = mmio_read_32(vd_addr + NI_CHILD_NODE_COUNT); 152 153 for (uint32_t j = 0U; j < pd_count; j++) { 154 pd_addr = global_cfg + mmio_read_32(vd_addr + NI_CHILD_POINTER(j)); 155 cd_count = mmio_read_32(pd_addr + NI_CHILD_NODE_COUNT); 156 157 VERBOSE("Power domain %u at 0x%lx node info: 0x%x\n", 158 j, pd_addr, mmio_read_32(pd_addr)); 159 160 for (uint32_t k = 0U; k < cd_count; k++) { 161 cd_addr = global_cfg + mmio_read_32(pd_addr + NI_CHILD_POINTER(k)); 162 comp_count = mmio_read_32(cd_addr + NI_CHILD_NODE_COUNT); 163 164 VERBOSE("Clock domain %u at 0x%lx node info: 0x%x\n", 165 k, cd_addr, mmio_read_32(cd_addr)); 166 167 for (uint32_t l = 0U; l < comp_count; l++) { 168 comp_addr = global_cfg + 169 mmio_read_32(cd_addr + NI_CHILD_POINTER(l)); 170 171 VERBOSE("Component %u at 0x%lx node info: 0x%x\n", 172 l, comp_addr, mmio_read_32(comp_addr)); 173 174 ni_setup_component(comp_addr); 175 } 176 } 177 } 178 } 179 180 return 0; 181 } 182