Merge changes from topic "us_pmu" into integration
* changes:
fix(tc): correct CPU PMU binding
feat(tc): add device tree binding for SPE
feat(tc): add PPI partitions in DT binding
feat(tc): change GIC DT property 'interrupt-cells' to 4
feat(tc): add NI-Tower PMU node for TC3
feat(tc): setup ni-tower non-secure access for TC3
diff --git a/fdts/tc-base.dtsi b/fdts/tc-base.dtsi
index 2e03be2..fc6fe78 100644
--- a/fdts/tc-base.dtsi
+++ b/fdts/tc-base.dtsi
@@ -265,9 +265,22 @@
method = "smc";
};
- cpu-pmu {
- compatible = "arm,armv8-pmuv3";
- interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ cpu-pmu-little {
+ compatible = LIT_CPU_PMU_COMPATIBLE;
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition_little>;
+ status = "okay";
+ };
+
+ cpu-pmu-mid {
+ compatible = MID_CPU_PMU_COMPATIBLE;
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition_mid>;
+ status = "okay";
+ };
+
+ cpu-pmu-big {
+ compatible = BIG_CPU_PMU_COMPATIBLE;
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_partition_big>;
+ status = "okay";
};
sram: sram@6000000 {
@@ -290,7 +303,7 @@
clocks = <&soc_refclk>;
clock-names = "apb_pclk";
#mbox-cells = <MHU_MBOX_CELLS>;
- interrupts = <GIC_SPI MHU_RX_INT_NUM IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI MHU_RX_INT_NUM IRQ_TYPE_LEVEL_HIGH 0>;
interrupt-names = MHU_RX_INT_NAME;
};
@@ -332,21 +345,33 @@
gic: interrupt-controller@GIC_CTRL_ADDR {
compatible = "arm,gic-v3";
#address-cells = <2>;
- #interrupt-cells = <3>;
+ #interrupt-cells = <4>;
#size-cells = <2>;
ranges;
interrupt-controller;
reg = <0x0 0x30000000 0 0x10000>, /* GICD */
<0x0 0x30080000 0 GIC_GICR_OFFSET>; /* GICR */
- interrupts = <GIC_PPI 0x9 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_PPI 0x9 IRQ_TYPE_LEVEL_LOW 0>;
};
timer {
compatible = "arm,armv8-timer";
- interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
- <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW 0>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW 0>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW 0>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW 0>;
+ };
+
+ spe-pmu-mid {
+ compatible = "arm,statistical-profiling-extension-v1";
+ interrupts = <GIC_PPI 1 IRQ_TYPE_LEVEL_HIGH &ppi_partition_mid>;
+ status = "disabled";
+ };
+
+ spe-pmu-big {
+ compatible = "arm,statistical-profiling-extension-v1";
+ interrupts = <GIC_PPI 1 IRQ_TYPE_LEVEL_HIGH &ppi_partition_big>;
+ status = "disabled";
};
soc_refclk: refclk {
@@ -374,7 +399,7 @@
os_uart: serial@2a400000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x0 0x2A400000 0x0 UART_OFFSET>;
- interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&soc_uartclk>, <&soc_refclk>;
clock-names = "uartclk", "apb_pclk";
status = "okay";
@@ -414,7 +439,7 @@
ethernet: ethernet@18000000 {
reg = <0x0 0x18000000 0x0 0x10000>;
- interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH 0>;
reg-io-width = <2>;
smsc,irq-push-pull;
@@ -446,8 +471,8 @@
mmci: mmci@1c050000 {
compatible = "arm,pl180", "arm,primecell";
reg = <0x0 0x001c050000 0x0 0x1000>;
- interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
wp-gpios = <&sysreg 1 0>;
bus-width = <4>;
max-frequency = <25000000>;
@@ -471,9 +496,9 @@
gpu: gpu@2d000000 {
compatible = "arm,mali-midgard";
reg = <0x0 0x2d000000 0x0 0x200000>;
- interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH 0>,
+ <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH 0>;
interrupt-names = "JOB", "MMU", "GPU";
clocks = <&gpu_core_clk>;
clock-names = "shadercores";
@@ -507,10 +532,10 @@
smmu_600: smmu@2ce00000 {
compatible = "arm,smmu-v3";
reg = <0 0x2ce00000 0 0x20000>;
- interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>,
- <GIC_SPI 74 IRQ_TYPE_EDGE_RISING>,
- <GIC_SPI 76 IRQ_TYPE_EDGE_RISING>,
- <GIC_SPI 77 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING 0>,
+ <GIC_SPI 74 IRQ_TYPE_EDGE_RISING 0>,
+ <GIC_SPI 76 IRQ_TYPE_EDGE_RISING 0>,
+ <GIC_SPI 77 IRQ_TYPE_EDGE_RISING 0>;
interrupt-names = "eventq", "priq", "cmdq-sync", "gerror";
#iommu-cells = <1>;
status = "disabled";
@@ -520,9 +545,9 @@
#iommu-cells = <1>;
compatible = "arm,smmu-v3";
reg = <0x0 0x3f000000 0x0 0x5000000>;
- interrupts = <GIC_SPI 228 IRQ_TYPE_EDGE_RISING>,
- <GIC_SPI 229 IRQ_TYPE_EDGE_RISING>,
- <GIC_SPI 230 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <GIC_SPI 228 IRQ_TYPE_EDGE_RISING 0>,
+ <GIC_SPI 229 IRQ_TYPE_EDGE_RISING 0>,
+ <GIC_SPI 230 IRQ_TYPE_EDGE_RISING 0>;
interrupt-names = "eventq", "cmdq-sync", "gerror";
dma-coherent;
status = "disabled";
@@ -532,9 +557,9 @@
#iommu-cells = <1>;
compatible = "arm,smmu-v3";
reg = <HI(0x4002a00000) LO(0x4002a00000) 0x0 0x5000000>;
- interrupts = <GIC_SPI 481 IRQ_TYPE_EDGE_RISING>,
- <GIC_SPI 482 IRQ_TYPE_EDGE_RISING>,
- <GIC_SPI 483 IRQ_TYPE_EDGE_RISING>;
+ interrupts = <GIC_SPI 481 IRQ_TYPE_EDGE_RISING 0>,
+ <GIC_SPI 482 IRQ_TYPE_EDGE_RISING 0>,
+ <GIC_SPI 483 IRQ_TYPE_EDGE_RISING 0>;
interrupt-names = "eventq", "cmdq-sync", "gerror";
dma-coherent;
status = "disabled";
@@ -545,7 +570,7 @@
#size-cells = <0>;
compatible = "arm,mali-d71";
reg = <HI(ADDRESSIFY(DPU_ADDR)) LO(ADDRESSIFY(DPU_ADDR)) 0 0x20000>;
- interrupts = <GIC_SPI DPU_IRQ IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI DPU_IRQ IRQ_TYPE_LEVEL_HIGH 0>;
interrupt-names = "DPU";
DPU_CLK_ATTR1;
@@ -630,7 +655,7 @@
trbe {
compatible = "arm,trace-buffer-extension";
- interrupts = <GIC_PPI 2 IRQ_TYPE_LEVEL_LOW>;
+ interrupts = <GIC_PPI 2 IRQ_TYPE_LEVEL_LOW 0>;
};
trusty {
diff --git a/fdts/tc-fvp.dtsi b/fdts/tc-fvp.dtsi
index 9f3a9ac..1e14f0b 100644
--- a/fdts/tc-fvp.dtsi
+++ b/fdts/tc-fvp.dtsi
@@ -54,7 +54,7 @@
rtc@1c170000 {
compatible = "arm,pl031", "arm,primecell";
reg = <0x0 0x1C170000 0x0 0x1000>;
- interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&soc_refclk>;
clock-names = "apb_pclk";
};
@@ -62,7 +62,7 @@
kmi@1c060000 {
compatible = "arm,pl050", "arm,primecell";
reg = <0x0 0x001c060000 0x0 0x1000>;
- interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
clock-names = "KMIREFCLK", "apb_pclk";
};
@@ -70,7 +70,7 @@
kmi@1c070000 {
compatible = "arm,pl050", "arm,primecell";
reg = <0x0 0x001c070000 0x0 0x1000>;
- interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&bp_clock24mhz>, <&bp_clock24mhz>;
clock-names = "KMIREFCLK", "apb_pclk";
};
@@ -79,6 +79,6 @@
compatible = "virtio,mmio";
reg = <0x0 0x1c130000 0x0 0x200>;
/* spec lists this wrong */
- interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH 0>;
};
};
diff --git a/fdts/tc2.dts b/fdts/tc2.dts
index 4946aca..ae37ce3 100644
--- a/fdts/tc2.dts
+++ b/fdts/tc2.dts
@@ -31,6 +31,10 @@
#define MHU_RX_INT_NUM 317
#define MHU_RX_INT_NAME "mhu_rx"
+#define LIT_CPU_PMU_COMPATIBLE "arm,cortex-a520-pmu"
+#define MID_CPU_PMU_COMPATIBLE "arm,cortex-a720-pmu"
+#define BIG_CPU_PMU_COMPATIBLE "arm,cortex-x4-pmu"
+
#define MPAM_ADDR 0x1 0x00010000 /* 0x1_0001_0000 */
#define UARTCLK_FREQ 5000000
@@ -193,22 +197,10 @@
};
#endif /* TARGET_FLAVOUR_FPGA */
- cpu-pmu {
-#if TARGET_FLAVOUR_FPGA
- interrupt-affinity = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>,
- <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>,
- <&CPU8>, <&CPU9>, <&CPU10>, <&CPU11>,
- <&CPU12>, <&CPU13>;
-#else
- interrupt-affinity = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>,
- <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>;
-#endif
- };
-
cmn-pmu {
compatible = "arm,ci-700";
reg = <0x0 0x50000000 0x0 0x10000000>;
- interrupts = <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH 0>;
};
mbox_db_rx: mhu@MHU_RX_ADDR {
@@ -237,6 +229,36 @@
};
};
+ gic: interrupt-controller@GIC_CTRL_ADDR {
+ ppi-partitions {
+ ppi_partition_little: interrupt-partition-0 {
+ affinity = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>;
+ };
+
+#if TARGET_FLAVOUR_FVP
+ ppi_partition_mid: interrupt-partition-1 {
+ affinity = <&CPU4>, <&CPU5>, <&CPU6>;
+ };
+
+ ppi_partition_big: interrupt-partition-2 {
+ affinity = <&CPU7>;
+ };
+#elif TARGET_FLAVOUR_FPGA
+ ppi_partition_mid: interrupt-partition-1 {
+ affinity = <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>, <&CPU8>;
+ };
+
+ ppi_partition_big: interrupt-partition-2 {
+ affinity = <&CPU9>, <&CPU10>, <&CPU11>, <&CPU12>, <&CPU13>;
+ };
+#endif
+ };
+ };
+
+ spe-pmu-big {
+ status = "okay";
+ };
+
smmu_700: iommu@3f000000 {
status = "okay";
};
diff --git a/fdts/tc3.dts b/fdts/tc3.dts
index 71b3cb1..58c8edc 100644
--- a/fdts/tc3.dts
+++ b/fdts/tc3.dts
@@ -25,6 +25,10 @@
#define MHU_RX_INT_NUM 300
#define MHU_RX_INT_NAME "combined-mbx"
+#define LIT_CPU_PMU_COMPATIBLE "arm,cortex-a520-pmu"
+#define MID_CPU_PMU_COMPATIBLE "arm,cortex-a725-pmu"
+#define BIG_CPU_PMU_COMPATIBLE "arm,cortex-x925-pmu"
+
#define MPAM_ADDR 0x0 0x5f010000 /* 0x5f01_0000 */
#define UARTCLK_FREQ 3750000
@@ -67,11 +71,6 @@
};
};
- cpu-pmu {
- interrupt-affinity = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>,
- <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>;
- };
-
cs-pmu@0 {
compatible = "arm,coresight-pmu";
reg = <0x0 MCN_PMU_ADDR(0) 0x0 0xffc>;
@@ -92,11 +91,24 @@
reg = <0x0 MCN_PMU_ADDR(3) 0x0 0xffc>;
};
+ spe-pmu-mid {
+ status = "okay";
+ };
+
+ spe-pmu-big {
+ status = "okay";
+ };
+
dsu-pmu {
compatible = "arm,dsu-pmu";
cpus = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>, <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>;
};
+ ni-pmu {
+ compatible = "arm,ni-tower";
+ reg = <0x0 0x4f000000 0x0 0x4000000>;
+ };
+
sram: sram@6000000 {
cpu_scp_scmi_p2a: scp-shmem@80 {
compatible = "arm,scmi-shmem";
@@ -111,6 +123,22 @@
};
};
+ gic: interrupt-controller@GIC_CTRL_ADDR {
+ ppi-partitions {
+ ppi_partition_little: interrupt-partition-0 {
+ affinity = <&CPU0>, <&CPU1>;
+ };
+
+ ppi_partition_mid: interrupt-partition-1 {
+ affinity = <&CPU2>, <&CPU3>, <&CPU4>, <&CPU5>;
+ };
+
+ ppi_partition_big: interrupt-partition-2 {
+ affinity = <&CPU6>, <&CPU7>;
+ };
+ };
+ };
+
#if TARGET_FLAVOUR_FVP
smmu_700: iommu@3f000000 {
status = "okay";
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 3ea29eb..83a5cd2 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -362,6 +362,7 @@
void plat_arm_interconnect_exit_coherency(void);
void plat_arm_program_trusted_mailbox(uintptr_t address);
bool plat_arm_bl1_fwu_needed(void);
+int plat_arm_ni_setup(uintptr_t global_cfg);
__dead2 void plat_arm_error_handler(int err);
__dead2 void plat_arm_system_reset(void);
diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk
index 78b6945..fb70500 100644
--- a/plat/arm/board/tc/platform.mk
+++ b/plat/arm/board/tc/platform.mk
@@ -121,7 +121,8 @@
lib/cpus/aarch64/cortex_x925.S
endif
-INTERCONNECT_SOURCES := ${TC_BASE}/tc_interconnect.c
+INTERCONNECT_SOURCES := ${TC_BASE}/tc_interconnect.c \
+ plat/arm/common/arm_ni.c
PLAT_BL_COMMON_SOURCES += ${TC_BASE}/tc_plat.c \
${TC_BASE}/include/tc_helpers.S
diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c
index 7d1bc9c..53404df 100644
--- a/plat/arm/board/tc/tc_bl31_setup.c
+++ b/plat/arm/board/tc/tc_bl31_setup.c
@@ -110,6 +110,7 @@
#if TARGET_PLATFORM == 3
enable_ns_mcn_pmu();
set_mcn_slc_alloc_mode();
+ plat_arm_ni_setup(NCI_BASE_ADDR);
#endif
}
diff --git a/plat/arm/common/arm_ni.c b/plat/arm/common/arm_ni.c
new file mode 100644
index 0000000..b3ad8b3
--- /dev/null
+++ b/plat/arm/common/arm_ni.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+#include <plat/arm/common/plat_arm.h>
+#include <platform_def.h>
+
+#define NI_CHILD_NODE_COUNT 4
+#define NI_CHILD_POINTERS_START 8
+
+#define NI_PMU_SECURE_CTRL 0x100
+#define NI_PMU_SECURE_EVENT_OBSERVATION 0x108
+#define NI_PMU_DEBUG_ENABLE 0x110
+#define NI_COMP_NUM_SUBFEATURES 0x100
+#define NI_COMP_SUBFEATURE_TYPE_START 0x108
+#define NI_COMP_SUBFEATURE_SECURE_CTRL_START 0x308
+
+#define SECURE_OVERRIDE_DEFAULT BIT(0)
+#define SECURE_EVENT_ENABLE BIT(2)
+#define NA_EVENT_ENABLE BIT(3)
+#define PMU_ENABLE BIT(0)
+
+#define NI_NODE_MASK 0x0000ffff
+#define NI_NODE_TYPE(node_info) (node_info & NI_NODE_MASK)
+#define NI_CHILD_POINTER(i) (NI_CHILD_POINTERS_START + (i * 4))
+#define NI_COMP_SUBFEATURE_TYPE(i) (NI_COMP_SUBFEATURE_TYPE_START + (i * 8))
+#define NI_COMP_SUBFEATURE_SECURE_CTRL(i) (NI_COMP_SUBFEATURE_SECURE_CTRL_START + (i * 8))
+
+#define NI_PERIPHERAL_ID0 0xfe0
+#define NI_PIDR0_PART_MASK 0xff
+#define NI_PERIPHERAL_ID1 0xfe4
+#define NI_PIDR1_PART_MASK 0xf
+#define NI_PIDR1_PART_SHIFT 8
+
+enum ni_part {
+ NI_700 = 0x43b,
+ NI_710AE = 0x43d,
+ NI_TOWER = 0x43f,
+};
+
+enum ni_node_type {
+ NI_INVALID_NODE = 0,
+ NI_VOLTAGE_DOMAIN = 1,
+ NI_POWER_DOMAIN = 2,
+ NI_CLOCK_DOMAIN = 3,
+ NI_ASNI = 4,
+ NI_AMNI = 5,
+ NI_PMU = 6,
+ NI_HSNI = 7,
+ NI_HMNI = 8,
+ NI_PMNI = 9,
+ NI_CMNI = 14,
+ NI_CFGNI = 15
+};
+
+enum ni_subfeature_type {
+ NI_SUBFEATURE_APU = 0,
+ NI_SUBFEATURE_ADDR_MAP = 1,
+ NI_SUBFEATURE_FCU = 2,
+ NI_SUBFEATURE_IDM = 3
+};
+
+static void ni_enable_pmu(uintptr_t pmu_addr)
+{
+ mmio_setbits_32(pmu_addr + NI_PMU_DEBUG_ENABLE, PMU_ENABLE);
+}
+
+static void ni_enable_fcu_ns_access(uintptr_t comp_addr)
+{
+ uint32_t subfeature_type;
+ uint32_t subfeature_count;
+ uint32_t subfeature_secure_ctrl;
+
+ subfeature_count = mmio_read_32(comp_addr + NI_COMP_NUM_SUBFEATURES);
+ for (uint32_t i = 0U; i < subfeature_count; i++) {
+ subfeature_type =
+ NI_NODE_TYPE(mmio_read_32(comp_addr + NI_COMP_SUBFEATURE_TYPE(i)));
+ if (subfeature_type == NI_SUBFEATURE_FCU) {
+ subfeature_secure_ctrl = comp_addr + NI_COMP_SUBFEATURE_SECURE_CTRL(i);
+ mmio_setbits_32(subfeature_secure_ctrl, SECURE_OVERRIDE_DEFAULT);
+ }
+ }
+}
+
+static void ni_enable_pmu_ns_access(uintptr_t comp_addr)
+{
+ mmio_setbits_32(comp_addr + NI_PMU_SECURE_CTRL, SECURE_OVERRIDE_DEFAULT);
+ mmio_setbits_32(comp_addr + NI_PMU_SECURE_EVENT_OBSERVATION,
+ SECURE_EVENT_ENABLE | NA_EVENT_ENABLE);
+}
+
+static void ni_setup_component(uintptr_t comp_addr)
+{
+ uint32_t node_info;
+
+ node_info = mmio_read_32(comp_addr);
+
+ switch (NI_NODE_TYPE(node_info)) {
+ case NI_ASNI:
+ case NI_AMNI:
+ case NI_HSNI:
+ case NI_HMNI:
+ case NI_PMNI:
+ ni_enable_fcu_ns_access(comp_addr);
+ break;
+ case NI_PMU:
+ ni_enable_pmu_ns_access(comp_addr);
+ ni_enable_pmu(comp_addr);
+ break;
+ default:
+ return;
+ }
+}
+
+int plat_arm_ni_setup(uintptr_t global_cfg)
+{
+ uintptr_t vd_addr;
+ uintptr_t pd_addr;
+ uintptr_t cd_addr;
+ uintptr_t comp_addr;
+ uint32_t vd_count;
+ uint32_t pd_count;
+ uint32_t cd_count;
+ uint32_t comp_count;
+ uint32_t part;
+ uint32_t reg;
+
+ reg = mmio_read_32(global_cfg + NI_PERIPHERAL_ID0);
+ part = reg & NI_PIDR0_PART_MASK;
+ reg = mmio_read_32(global_cfg + NI_PERIPHERAL_ID1);
+ part |= ((reg & NI_PIDR1_PART_MASK) << NI_PIDR1_PART_SHIFT);
+
+ if (part != NI_TOWER) {
+ ERROR("0x%x is not supported\n", part);
+ return -EINVAL;
+ }
+
+ vd_count = mmio_read_32(global_cfg + NI_CHILD_NODE_COUNT);
+
+ for (uint32_t i = 0U; i < vd_count; i++) {
+ vd_addr = global_cfg + mmio_read_32(global_cfg + NI_CHILD_POINTER(i));
+ pd_count = mmio_read_32(vd_addr + NI_CHILD_NODE_COUNT);
+
+ for (uint32_t j = 0U; j < pd_count; j++) {
+ pd_addr = global_cfg + mmio_read_32(vd_addr + NI_CHILD_POINTER(j));
+ cd_count = mmio_read_32(pd_addr + NI_CHILD_NODE_COUNT);
+
+ for (uint32_t k = 0U; k < cd_count; k++) {
+ cd_addr = global_cfg + mmio_read_32(pd_addr + NI_CHILD_POINTER(k));
+ comp_count = mmio_read_32(cd_addr + NI_CHILD_NODE_COUNT);
+
+ for (uint32_t l = 0U; l < comp_count; l++) {
+ comp_addr = global_cfg +
+ mmio_read_32(cd_addr + NI_CHILD_POINTER(l));
+ ni_setup_component(comp_addr);
+ }
+ }
+ }
+ }
+
+ return 0;
+}