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