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
This commit is contained in:
Manish V Badarkhe 2024-08-05 17:43:33 +02:00 committed by TrustedFirmware Code Review
commit 18faaa2424
8 changed files with 297 additions and 52 deletions

View file

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

View file

@ -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>;
};
};

View file

@ -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";
};

View file

@ -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";

View file

@ -362,6 +362,7 @@ void plat_arm_interconnect_enter_coherency(void);
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);

View file

@ -121,7 +121,8 @@ TC_CPU_SOURCES += lib/cpus/aarch64/cortex_a520.S \
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

View file

@ -110,6 +110,7 @@ void bl31_platform_setup(void)
#if TARGET_PLATFORM == 3
enable_ns_mcn_pmu();
set_mcn_slc_alloc_mode();
plat_arm_ni_setup(NCI_BASE_ADDR);
#endif
}

167
plat/arm/common/arm_ni.c Normal file
View file

@ -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;
}