arm-trusted-firmware/lib/fconf/fconf_mpmm_getter.c
Chris Kay 68120783d6 feat(mpmm): add support for MPMM
MPMM - the Maximum Power Mitigation Mechanism - is an optional
microarchitectural feature present on some Armv9-A cores, introduced
with the Cortex-X2, Cortex-A710 and Cortex-A510 cores.

MPMM allows the SoC firmware to detect and limit high activity events
to assist in SoC processor power domain dynamic power budgeting and
limit the triggering of whole-rail (i.e. clock chopping) responses to
overcurrent conditions.

This feature is enabled via the `ENABLE_MPMM` build option.
Configuration can be done via FCONF by enabling `ENABLE_MPMM_FCONF`, or
by via the plaform-implemented `plat_mpmm_topology` function.

Change-Id: I77da82808ad4744ece8263f0bf215c5a091c3167
Signed-off-by: Chris Kay <chris.kay@arm.com>
2021-10-26 12:15:42 +01:00

80 lines
1.8 KiB
C

/*
* Copyright (c) 2021, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stddef.h>
#include <stdint.h>
#include <common/debug.h>
#include <common/fdt_wrappers.h>
#include <lib/fconf/fconf.h>
#include <lib/fconf/fconf_mpmm_getter.h>
#include <libfdt.h>
#include <plat/common/platform.h>
struct fconf_mpmm_config fconf_mpmm_config;
static struct mpmm_topology fconf_mpmm_topology;
/*
* Within a `cpu` node, determine support for MPMM via the `supports-mpmm`
* property.
*
* Returns `0` on success, or a negative integer representing an error code.
*/
static int fconf_populate_mpmm_cpu(const void *fdt, int off, uintptr_t mpidr)
{
int ret, len;
int core_pos;
struct mpmm_core *core;
core_pos = plat_core_pos_by_mpidr(mpidr);
if (core_pos < 0) {
return -FDT_ERR_BADVALUE;
}
core = &fconf_mpmm_topology.cores[core_pos];
fdt_getprop(fdt, off, "supports-mpmm", &len);
if (len >= 0) {
core->supported = true;
ret = 0;
} else {
core->supported = false;
ret = len;
}
return ret;
}
/*
* Populates the global `fconf_mpmm_config` structure based on what's described
* by the hardware configuration device tree blob.
*
* The device tree is expected to provide a `supports-mpmm` property for each
* `cpu` node, like so:
*
* cpu@0 {
* supports-mpmm;
* };
*
* This property indicates whether the core implements MPMM, as we cannot detect
* support for it dynamically.
*/
static int fconf_populate_mpmm(uintptr_t config)
{
int ret = fdtw_for_each_cpu(
(const void *)config, fconf_populate_mpmm_cpu);
if (ret == 0) {
fconf_mpmm_config.topology = &fconf_mpmm_topology;
} else {
ERROR("FCONF: failed to configure MPMM: %d\n", ret);
}
return ret;
}
FCONF_REGISTER_POPULATOR(HW_CONFIG, mpmm, fconf_populate_mpmm);