1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park * Copyright (c) 2021, Arm Limited. All rights reserved.
3*54fd6939SJiyong Park *
4*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park */
6*54fd6939SJiyong Park
7*54fd6939SJiyong Park #include <stddef.h>
8*54fd6939SJiyong Park #include <stdint.h>
9*54fd6939SJiyong Park
10*54fd6939SJiyong Park #include <common/debug.h>
11*54fd6939SJiyong Park #include <common/fdt_wrappers.h>
12*54fd6939SJiyong Park #include <lib/fconf/fconf.h>
13*54fd6939SJiyong Park #include <lib/fconf/fconf_mpmm_getter.h>
14*54fd6939SJiyong Park #include <libfdt.h>
15*54fd6939SJiyong Park
16*54fd6939SJiyong Park #include <plat/common/platform.h>
17*54fd6939SJiyong Park
18*54fd6939SJiyong Park struct fconf_mpmm_config fconf_mpmm_config;
19*54fd6939SJiyong Park static struct mpmm_topology fconf_mpmm_topology;
20*54fd6939SJiyong Park
21*54fd6939SJiyong Park /*
22*54fd6939SJiyong Park * Within a `cpu` node, determine support for MPMM via the `supports-mpmm`
23*54fd6939SJiyong Park * property.
24*54fd6939SJiyong Park *
25*54fd6939SJiyong Park * Returns `0` on success, or a negative integer representing an error code.
26*54fd6939SJiyong Park */
fconf_populate_mpmm_cpu(const void * fdt,int off,uintptr_t mpidr)27*54fd6939SJiyong Park static int fconf_populate_mpmm_cpu(const void *fdt, int off, uintptr_t mpidr)
28*54fd6939SJiyong Park {
29*54fd6939SJiyong Park int ret, len;
30*54fd6939SJiyong Park
31*54fd6939SJiyong Park int core_pos;
32*54fd6939SJiyong Park struct mpmm_core *core;
33*54fd6939SJiyong Park
34*54fd6939SJiyong Park core_pos = plat_core_pos_by_mpidr(mpidr);
35*54fd6939SJiyong Park if (core_pos < 0) {
36*54fd6939SJiyong Park return -FDT_ERR_BADVALUE;
37*54fd6939SJiyong Park }
38*54fd6939SJiyong Park
39*54fd6939SJiyong Park core = &fconf_mpmm_topology.cores[core_pos];
40*54fd6939SJiyong Park
41*54fd6939SJiyong Park fdt_getprop(fdt, off, "supports-mpmm", &len);
42*54fd6939SJiyong Park if (len >= 0) {
43*54fd6939SJiyong Park core->supported = true;
44*54fd6939SJiyong Park ret = 0;
45*54fd6939SJiyong Park } else {
46*54fd6939SJiyong Park core->supported = false;
47*54fd6939SJiyong Park ret = len;
48*54fd6939SJiyong Park }
49*54fd6939SJiyong Park
50*54fd6939SJiyong Park return ret;
51*54fd6939SJiyong Park }
52*54fd6939SJiyong Park
53*54fd6939SJiyong Park /*
54*54fd6939SJiyong Park * Populates the global `fconf_mpmm_config` structure based on what's described
55*54fd6939SJiyong Park * by the hardware configuration device tree blob.
56*54fd6939SJiyong Park *
57*54fd6939SJiyong Park * The device tree is expected to provide a `supports-mpmm` property for each
58*54fd6939SJiyong Park * `cpu` node, like so:
59*54fd6939SJiyong Park *
60*54fd6939SJiyong Park * cpu@0 {
61*54fd6939SJiyong Park * supports-mpmm;
62*54fd6939SJiyong Park * };
63*54fd6939SJiyong Park *
64*54fd6939SJiyong Park * This property indicates whether the core implements MPMM, as we cannot detect
65*54fd6939SJiyong Park * support for it dynamically.
66*54fd6939SJiyong Park */
fconf_populate_mpmm(uintptr_t config)67*54fd6939SJiyong Park static int fconf_populate_mpmm(uintptr_t config)
68*54fd6939SJiyong Park {
69*54fd6939SJiyong Park int ret = fdtw_for_each_cpu(
70*54fd6939SJiyong Park (const void *)config, fconf_populate_mpmm_cpu);
71*54fd6939SJiyong Park if (ret == 0) {
72*54fd6939SJiyong Park fconf_mpmm_config.topology = &fconf_mpmm_topology;
73*54fd6939SJiyong Park } else {
74*54fd6939SJiyong Park ERROR("FCONF: failed to configure MPMM: %d\n", ret);
75*54fd6939SJiyong Park }
76*54fd6939SJiyong Park
77*54fd6939SJiyong Park return ret;
78*54fd6939SJiyong Park }
79*54fd6939SJiyong Park
80*54fd6939SJiyong Park FCONF_REGISTER_POPULATOR(HW_CONFIG, mpmm, fconf_populate_mpmm);
81