* [PATCH 0/3] arm64: dts: imx95: Update for smmu
From: Peng Fan (OSS) @ 2026-04-09 12:00 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan
Update smmu reg size
Add SMMU PMU nodes
Enable SMMU by default and add iommus property for sdhc/edma.
Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
Peng Fan (3):
arm64: dts: imx95: Correct SMMU reg
arm64: dts: imx95: Add SMMU PMU nodes
arm64: dts: imx95: Add iommus property and enable SMMU
arch/arm64/boot/dts/freescale/imx95.dtsi | 91 +++++++++++++++++++++++++++++++-
1 file changed, 89 insertions(+), 2 deletions(-)
---
base-commit: db7efce4ae23ad5e42f5f55428f529ff62b86fab
change-id: 20260409-imx95-s-dts-e8f12dc94c29
Best regards,
--
Peng Fan <peng.fan@nxp.com>
^ permalink raw reply
* Re: [PATCH v2 5/7] soc: samsung: exynos-pmu: add Exynos850 CPU hotplug support
From: Henrik Grimler @ 2026-04-09 11:57 UTC (permalink / raw)
To: Alexey Klimov
Cc: Sam Protsenko, linux-samsung-soc, Krzysztof Kozlowski,
Peter Griffin, André Draszik, Conor Dooley, Alim Akhtar,
Tudor Ambarus, Rob Herring, Krzysztof Kozlowski, linux-arm-kernel,
devicetree, linux-kernel
In-Reply-To: <20260401-exynos850-cpuhotplug-v2-5-c5a760a3e259@linaro.org>
Hi Alexey,
This patch breaks compilation for arm(32) exynos devices. Compiling
with exynos_defconfig I get:
[ ... ]
CC drivers/soc/samsung/exynos850-pmu.o
CC [M] fs/squashfs/page_actor.o
../drivers/soc/samsung/exynos850-pmu.c:17:21: error: call to undeclared function 'MPIDR_AFFINITY_LEVEL'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
17 | u32 this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 2);
| ^
../drivers/soc/samsung/exynos850-pmu.c:17:42: error: call to undeclared function 'read_cpuid_mpidr'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
17 | u32 this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 2);
| ^
../drivers/soc/samsung/exynos850-pmu.c:48:21: error: call to undeclared function 'MPIDR_AFFINITY_LEVEL'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
48 | u32 this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 2);
| ^
../drivers/soc/samsung/exynos850-pmu.c:48:42: error: call to undeclared function 'read_cpuid_mpidr'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
48 | u32 this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 2);
| ^
4 errors generated.
make[6]: *** [../scripts/Makefile.build:289: drivers/soc/samsung/exynos850-pmu.o] Error 1
make[5]: *** [../scripts/Makefile.build:548: drivers/soc/samsung] Error 2
make[4]: *** [../scripts/Makefile.build:548: drivers/soc] Error 2
make[3]: *** [../scripts/Makefile.build:548: drivers] Error 2
make[3]: *** Waiting for unfinished jobs....
[ ... ]
Best regards,
Henrik Grimler
On Wed, Apr 01, 2026 at 05:51:58AM +0100, Alexey Klimov wrote:
> Add cpuhotplug support for Exynos850 platforms. This SoC requires
> its own specific set of writes/updates to PMU and PMU interrupts
> generation block in order to put a CPU or a group of CPUs into
> a different sleep states or prepare these entities for a CPU_OFF
> or wake-up out of idle state or after CPU online.
> Without these writes/updates the CPU(s) wake-up or online fails.
> While at this, also add description of Exynos850 PMU registers.
>
> Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
> ---
> drivers/soc/samsung/Makefile | 2 +-
> drivers/soc/samsung/exynos-pmu.c | 1 +
> drivers/soc/samsung/exynos-pmu.h | 1 +
> drivers/soc/samsung/exynos850-pmu.c | 78 +++++++++++++++++++++++++++++
> include/linux/soc/samsung/exynos-regs-pmu.h | 5 ++
> 5 files changed, 86 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile
> index 636a762608c9..7f544e3c1fcc 100644
> --- a/drivers/soc/samsung/Makefile
> +++ b/drivers/soc/samsung/Makefile
> @@ -7,7 +7,7 @@ exynos_chipid-y += exynos-chipid.o exynos-asv.o
> obj-$(CONFIG_EXYNOS_USI) += exynos-usi.o
>
> obj-$(CONFIG_EXYNOS_PMU) += exynos_pmu.o
> -exynos_pmu-y += exynos-pmu.o gs101-pmu.o
> +exynos_pmu-y += exynos-pmu.o gs101-pmu.o exynos850-pmu.o
>
> obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS) += exynos3250-pmu.o exynos4-pmu.o \
> exynos5250-pmu.o exynos5420-pmu.o
> diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c
> index 4e5fcc01e5e0..daa870ba88f5 100644
> --- a/drivers/soc/samsung/exynos-pmu.c
> +++ b/drivers/soc/samsung/exynos-pmu.c
> @@ -133,6 +133,7 @@ static const struct of_device_id exynos_pmu_of_device_ids[] = {
> .compatible = "samsung,exynos7-pmu",
> }, {
> .compatible = "samsung,exynos850-pmu",
> + .data = &exynos850_pmu_data,
> },
> { /*sentinel*/ },
> };
> diff --git a/drivers/soc/samsung/exynos-pmu.h b/drivers/soc/samsung/exynos-pmu.h
> index 186299a049a8..4202d3cd94c9 100644
> --- a/drivers/soc/samsung/exynos-pmu.h
> +++ b/drivers/soc/samsung/exynos-pmu.h
> @@ -102,6 +102,7 @@ extern const struct exynos_pmu_data exynos5250_pmu_data;
> extern const struct exynos_pmu_data exynos5420_pmu_data;
> #endif
> extern const struct exynos_pmu_data gs101_pmu_data;
> +extern const struct exynos_pmu_data exynos850_pmu_data;
>
> extern void pmu_raw_writel(u32 val, u32 offset);
> extern u32 pmu_raw_readl(u32 offset);
> diff --git a/drivers/soc/samsung/exynos850-pmu.c b/drivers/soc/samsung/exynos850-pmu.c
> new file mode 100644
> index 000000000000..b3841547577a
> --- /dev/null
> +++ b/drivers/soc/samsung/exynos850-pmu.c
> @@ -0,0 +1,78 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2026 Linaro Ltd.
> + *
> + * Exynos850 PMU support
> + */
> +
> +#include <linux/soc/samsung/exynos-pmu.h>
> +#include <linux/soc/samsung/exynos-regs-pmu.h>
> +#include <linux/regmap.h>
> +
> +#include "exynos-pmu.h"
> +
> +static int exynos850_cpu_pmu_offline(struct exynos_pmu_context *pmu_context, unsigned int cpu)
> + __must_hold(&pmu_context->cpupm_lock)
> +{
> + u32 this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 2);
> + u32 cluster_cpu = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1);
> + unsigned int cpuhint = smp_processor_id();
> + u32 reg, mask;
> +
> + /* set cpu inform hint */
> + regmap_write(pmu_context->pmureg, EXYNOS850_CPU_INFORM(cpuhint),
> + CPU_INFORM_C2);
> +
> + mask = BIT(cpu);
> + regmap_update_bits(pmu_context->pmuintrgen, EXYNOS_GRP2_INTR_BID_ENABLE,
> + mask, BIT(cpu));
> +
> + regmap_read(pmu_context->pmuintrgen, EXYNOS_GRP1_INTR_BID_UPEND, ®);
> + regmap_write(pmu_context->pmuintrgen, EXYNOS_GRP1_INTR_BID_CLEAR,
> + reg & mask);
> +
> + mask = (BIT(cpu + 8));
> + regmap_read(pmu_context->pmuintrgen, EXYNOS_GRP1_INTR_BID_UPEND, ®);
> + regmap_write(pmu_context->pmuintrgen, EXYNOS_GRP1_INTR_BID_CLEAR,
> + reg & mask);
> +
> + regmap_update_bits(pmu_context->pmureg,
> + EXYNOS850_CLUSTER_CPU_INT_EN(this_cluster, cluster_cpu),
> + 1 << 3, 1 << 3);
> + return 0;
> +}
> +
> +static int exynos850_cpu_pmu_online(struct exynos_pmu_context *pmu_context, unsigned int cpu)
> + __must_hold(&pmu_context->cpupm_lock)
> +{
> + u32 this_cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 2);
> + u32 cluster_cpu = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1);
> + unsigned int cpuhint = smp_processor_id();
> + u32 reg, mask;
> +
> + /* clear cpu inform hint */
> + regmap_write(pmu_context->pmureg, EXYNOS850_CPU_INFORM(cpuhint),
> + CPU_INFORM_CLEAR);
> +
> + mask = BIT(cpu);
> +
> + regmap_update_bits(pmu_context->pmuintrgen, EXYNOS_GRP2_INTR_BID_ENABLE,
> + mask, (0 << cpu));
> +
> + regmap_read(pmu_context->pmuintrgen, EXYNOS_GRP2_INTR_BID_UPEND, ®);
> +
> + regmap_write(pmu_context->pmuintrgen, EXYNOS_GRP2_INTR_BID_CLEAR,
> + reg & mask);
> +
> + regmap_update_bits(pmu_context->pmureg,
> + EXYNOS850_CLUSTER_CPU_INT_EN(this_cluster, cluster_cpu),
> + 1 << 3, 0 << 3);
> + return 0;
> +}
> +
> +const struct exynos_pmu_data exynos850_pmu_data = {
> + .pmu_cpuhp = true,
> + .cpu_pmu_offline = exynos850_cpu_pmu_offline,
> + .cpu_pmu_online = exynos850_cpu_pmu_online,
> +};
> +
> diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h
> index 9c4d3da41dbf..93c4d724c8ea 100644
> --- a/include/linux/soc/samsung/exynos-regs-pmu.h
> +++ b/include/linux/soc/samsung/exynos-regs-pmu.h
> @@ -1015,6 +1015,11 @@
> #define EXYNOS_GRP2_INTR_BID_UPEND (0x0208)
> #define EXYNOS_GRP2_INTR_BID_CLEAR (0x020c)
>
> +/* Exynos850 PMU Alive */
> +#define EXYNOS850_CPU_INFORM(cpu) (0x0860 + ((cpu) & 7) * 4)
> +#define EXYNOS850_CLUSTER_CPU_OFFSET(cl, cpu) (0x1000 + ((cl * 0x400) + ((cpu) * 0x80)))
> +#define EXYNOS850_CLUSTER_CPU_INT_EN(cl, cpu) (EXYNOS850_CLUSTER_CPU_OFFSET(cl, cpu) + 0x44)
> +
> /* exynosautov920 */
> #define EXYNOSAUTOV920_PHY_CTRL_USB20 (0x0710)
> #define EXYNOSAUTOV920_PHY_CTRL_USB31 (0x0714)
>
> --
> 2.51.0
>
>
^ permalink raw reply
* [PATCH v2 10/10] Introduce v18 dtb version
From: Herve Codina @ 2026-04-09 11:54 UTC (permalink / raw)
To: David Gibson, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Ayush Singh, Geert Uytterhoeven, devicetree-compiler, devicetree,
linux-kernel, devicetree-spec, Hui Pu, Ian Ray, Luca Ceresoli,
Thomas Petazzoni, Herve Codina
In-Reply-To: <20260409115426.352214-1-herve.codina@bootlin.com>
This v18 version will add support for
- Structured tags.
Those tags value definition will allow "old" libfdt, dtc and other
tools to skip unknown tags if encountered in future dtb version.
libfdt, dtc and other tools implementing version v18 will be able to
skip unknown tags available in dtbd generated with later version of
dtc.
- dt_flags header field.
For now this flag field is set to 0. It is a placeholder for future
dtb version and could be used to store some dtb related information
such as the kind of dtb. For instance, the future addons format will
use this field to clearly identify that the dtb is an addon dtb.
- last_comp_version_w header field.
This field is similar to last_comp_version but for writing.
It contains the lowest version of the devicetree data structure with
which the version used can safely perform modifications (taking into
account following rules related to unknown tags).
If this lowest version is greater than the last known supported
version, modification are simply forbidden and lead to a
FDT_ERR_BADVERSION error.
For modification, when an unknown tag that can be skipped is involved
and last_comp_version_w allows modifications, the following rules
apply:
- When a property is modified, tags related to this property are
removed and the dtb version is downgraded.
- When a property is removed, tags related to this property are
obviously removed. The dtb version is kept unchanged.
- When a property or a node is added, obviously no unknown tags are
added and the dtb version is kept unchanged.
- When a node is removed, tags related to this node are obviously
removed. The dtb version is kept unchanged.
- Adding, removing or modifying a property is not considered as a node
modification and so, those operations have no impacts on unknown
tags related to the node. Those node related tags are kept
unchanged.
- The only modification considered as a node modification is setting
its name. We consider that this operation has no impact on tags
related to the node. Here also, those node related tags and the dtb
version are kept unchanged.
- Global (dtb related) unknown tags are kept unchanged regardless the
modification done.
In all cases, if unknown tags are not involved in a modification, the
dtb version is not downgraded when the modification is made.
It is worth noting that with this v18 version, the dtb version is not
downgraded for any modification but only when unknown tags are removed
due to a property modification. In v17 or older version any modification
led to a dtb version downgrade.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
dtc.h | 2 +-
fdtdump.c | 8 +++-
flattree.c | 37 +++++++++++++++----
libfdt/fdt.h | 5 +++
libfdt/fdt_rw.c | 20 +++++++---
libfdt/fdt_sw.c | 3 ++
libfdt/libfdt.h | 7 +++-
pylibfdt/libfdt.i | 18 +++++++++
tests/dumptrees.c | 3 +-
tests/pylibfdt_tests.py | 10 +++--
tests/run_tests.sh | 26 +++++++++----
tests/testdata.h | 1 +
tests/testutils.c | 2 +-
tests/trees.S | 29 +++++++++++++--
...own_tags_can_skip.fdtput.test.dtb.0.expect | 1 +
...own_tags_can_skip.fdtput.test.dtb.1.expect | 3 +-
...own_tags_can_skip.fdtput.test.dtb.2.expect | 3 +-
...own_tags_can_skip.fdtput.test.dtb.3.expect | 3 +-
...own_tags_can_skip.fdtput.test.dtb.4.expect | 3 +-
...own_tags_can_skip.fdtput.test.dtb.5.expect | 3 +-
...own_tags_can_skip.fdtput.test.dtb.6.expect | 3 +-
21 files changed, 152 insertions(+), 38 deletions(-)
diff --git a/dtc.h b/dtc.h
index 473552e..f0c2cde 100644
--- a/dtc.h
+++ b/dtc.h
@@ -29,7 +29,7 @@
#define debug(...)
#endif
-#define DEFAULT_FDT_VERSION 17
+#define DEFAULT_FDT_VERSION 18
/*
* Command line options
diff --git a/fdtdump.c b/fdtdump.c
index 7a8b278..5994e1d 100644
--- a/fdtdump.c
+++ b/fdtdump.c
@@ -18,7 +18,7 @@
#include "util.h"
#define FDT_MAGIC_SIZE 4
-#define MAX_VERSION 17U
+#define MAX_VERSION 18U
#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
#define PALIGN(p, a) ((void *)(ALIGN((uintptr_t)(p), (a))))
@@ -86,6 +86,12 @@ static void dump_blob(void *blob, bool debug, int dump_unknown)
if (version >= 17)
printf("// size_dt_struct:\t0x%"PRIx32"\n",
fdt32_to_cpu(bph->size_dt_struct));
+ if (version >= 18) {
+ printf("// dt_flags:\t\t0x%"PRIx32"\n",
+ fdt32_to_cpu(bph->dt_flags));
+ printf("// last_comp_version_w:\t%"PRIu32"\n",
+ fdt32_to_cpu(bph->last_comp_version_w));
+ }
printf("\n");
for (i = 0; ; i++) {
diff --git a/flattree.c b/flattree.c
index 88dbfa7..ff57fc5 100644
--- a/flattree.c
+++ b/flattree.c
@@ -13,23 +13,29 @@
#define FTF_STRTABSIZE 0x10
#define FTF_STRUCTSIZE 0x20
#define FTF_NOPS 0x40
+#define FTF_DTFLAGS 0x80
+#define FTF_LCVERSW 0x100
static struct version_info {
int version;
int last_comp_version;
+ int last_comp_version_w;
int hdr_size;
int flags;
} version_table[] = {
- {1, 1, FDT_V1_SIZE,
+ {1, 1, 0, FDT_V1_SIZE,
FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS},
- {2, 1, FDT_V2_SIZE,
+ {2, 1, 0, FDT_V2_SIZE,
FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID},
- {3, 1, FDT_V3_SIZE,
+ {3, 1, 0, FDT_V3_SIZE,
FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID|FTF_STRTABSIZE},
- {16, 16, FDT_V3_SIZE,
+ {16, 16, 0, FDT_V3_SIZE,
FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_NOPS},
- {17, 16, FDT_V17_SIZE,
+ {17, 16, 0, FDT_V17_SIZE,
FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS},
+ {18, 16, 17, FDT_V18_SIZE,
+ FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS|FTF_DTFLAGS|
+ FTF_LCVERSW},
};
struct emitter {
@@ -314,7 +320,7 @@ static struct data flatten_reserve_list(struct reserve_info *reservelist,
static void make_fdt_header(struct fdt_header *fdt,
struct version_info *vi,
int reservesize, int dtsize, int strsize,
- int boot_cpuid_phys)
+ int boot_cpuid_phys, uint32_t dt_flags)
{
int reserve_off;
@@ -341,6 +347,10 @@ static void make_fdt_header(struct fdt_header *fdt,
fdt->size_dt_strings = cpu_to_fdt32(strsize);
if (vi->flags & FTF_STRUCTSIZE)
fdt->size_dt_struct = cpu_to_fdt32(dtsize);
+ if (vi->flags & FTF_DTFLAGS)
+ fdt->dt_flags = cpu_to_fdt32(dt_flags);
+ if (vi->flags & FTF_LCVERSW)
+ fdt->last_comp_version_w = cpu_to_fdt32(vi->last_comp_version_w);
}
void dt_to_blob(FILE *f, struct dt_info *dti, int version)
@@ -368,7 +378,7 @@ void dt_to_blob(FILE *f, struct dt_info *dti, int version)
/* Make header */
make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len,
- dti->boot_cpuid_phys);
+ dti->boot_cpuid_phys, 0);
/*
* If the user asked for more space than is used, adjust the totalsize.
@@ -499,6 +509,16 @@ void dt_to_asm(FILE *f, struct dt_info *dti, int version)
symprefix, symprefix);
}
+ if (vi->flags & FTF_DTFLAGS) {
+ fprintf(f, "\t/* dt_flags */\n");
+ asm_emit_cell(f, 0);
+ }
+
+ if (vi->flags & FTF_LCVERSW) {
+ fprintf(f, "\t/* last_comp_version_w */\n");
+ asm_emit_cell(f, vi->last_comp_version_w);
+ }
+
/*
* Reserve map entries.
* Align the reserve map to a doubleword boundary.
@@ -955,6 +975,9 @@ struct dt_info *dt_from_blob(const char *fname)
flags |= FTF_NOPS;
}
+ if (version >= 18)
+ flags |= FTF_DTFLAGS | FTF_LCVERSW;
+
inbuf_init(&memresvbuf,
blob + off_mem_rsvmap, blob + totalsize);
inbuf_init(&dtbuf, blob + off_dt, blob + totalsize);
diff --git a/libfdt/fdt.h b/libfdt/fdt.h
index e6f75e7..12d358d 100644
--- a/libfdt/fdt.h
+++ b/libfdt/fdt.h
@@ -26,6 +26,10 @@ struct fdt_header {
/* version 17 fields below */
fdt32_t size_dt_struct; /* size of the structure block */
+
+ /* version 18 fields below */
+ fdt32_t dt_flags; /* Ored value of FDT_FLAG_XXXX */
+ fdt32_t last_comp_version_w; /* last compatible version for writing */
};
struct fdt_reserve_entry {
@@ -85,5 +89,6 @@ struct fdt_property {
#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t))
#define FDT_V16_SIZE FDT_V3_SIZE
#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t))
+#define FDT_V18_SIZE (FDT_V17_SIZE + 2 * sizeof(fdt32_t))
#endif /* FDT_H */
diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c
index a8f53b4..0a4a03f 100644
--- a/libfdt/fdt_rw.c
+++ b/libfdt/fdt_rw.c
@@ -34,13 +34,17 @@ static int fdt_rw_probe_(void *fdt)
return 0;
FDT_RO_PROBE(fdt);
- if (!can_assume(LATEST) && fdt_version(fdt) < 17)
- return -FDT_ERR_BADVERSION;
+ if (!can_assume(LATEST)) {
+ if (fdt_version(fdt) < 17)
+ return -FDT_ERR_BADVERSION;
+ else if (fdt_version(fdt) >= 18 &&
+ fdt_last_comp_version_w(fdt) > FDT_LAST_SUPPORTED_VERSION)
+ return -FDT_ERR_BADVERSION;
+ }
if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry),
fdt_size_dt_struct(fdt)))
return -FDT_ERR_BADLAYOUT;
- fdt_downgrade_version(fdt);
return 0;
}
@@ -582,7 +586,11 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
err = fdt_move(fdt, buf, bufsize);
if (err)
return err;
- fdt_set_version(buf, 17);
+ if (can_assume(LATEST) || fdt_version(fdt) < 18) {
+ fdt_set_version(buf, 18);
+ fdt_set_dt_flags(buf, 0);
+ fdt_set_last_comp_version_w(buf, 17);
+ }
fdt_set_size_dt_struct(buf, struct_size);
fdt_set_totalsize(buf, bufsize);
return 0;
@@ -611,8 +619,10 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
fdt_set_magic(buf, FDT_MAGIC);
fdt_set_totalsize(buf, bufsize);
- fdt_set_version(buf, 17);
+ fdt_set_version(buf, 18);
fdt_set_last_comp_version(buf, 16);
+ fdt_set_dt_flags(buf, 0);
+ fdt_set_last_comp_version_w(buf, 17);
fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
return 0;
diff --git a/libfdt/fdt_sw.c b/libfdt/fdt_sw.c
index 4c569ee..10da0d6 100644
--- a/libfdt/fdt_sw.c
+++ b/libfdt/fdt_sw.c
@@ -137,6 +137,9 @@ int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags)
fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
fdt_set_off_dt_strings(fdt, 0);
+ fdt_set_dt_flags(fdt, 0);
+ fdt_set_last_comp_version_w(fdt, FDT_LAST_COMPATIBLE_VERSION_W);
+
return 0;
}
diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h
index 7a10f66..71c7de5 100644
--- a/libfdt/libfdt.h
+++ b/libfdt/libfdt.h
@@ -15,7 +15,8 @@ extern "C" {
#define FDT_FIRST_SUPPORTED_VERSION 0x02
#define FDT_LAST_COMPATIBLE_VERSION 0x10
-#define FDT_LAST_SUPPORTED_VERSION 0x11
+#define FDT_LAST_COMPATIBLE_VERSION_W 0x11
+#define FDT_LAST_SUPPORTED_VERSION 0x12
/* Error codes: informative error codes */
#define FDT_ERR_NOTFOUND 1
@@ -284,6 +285,8 @@ int fdt_next_subnode(const void *fdt, int offset);
#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys))
#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))
#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct))
+#define fdt_dt_flags(fdt) (fdt_get_header(fdt, dt_flags))
+#define fdt_last_comp_version_w(fdt) (fdt_get_header(fdt, last_comp_version_w))
#define fdt_set_hdr_(name) \
static inline void fdt_set_##name(void *fdt, uint32_t val) \
@@ -301,6 +304,8 @@ fdt_set_hdr_(last_comp_version)
fdt_set_hdr_(boot_cpuid_phys)
fdt_set_hdr_(size_dt_strings)
fdt_set_hdr_(size_dt_struct)
+fdt_set_hdr_(dt_flags)
+fdt_set_hdr_(last_comp_version_w)
#undef fdt_set_hdr_
/**
diff --git a/pylibfdt/libfdt.i b/pylibfdt/libfdt.i
index 1f9c047..90966bd 100644
--- a/pylibfdt/libfdt.i
+++ b/pylibfdt/libfdt.i
@@ -281,6 +281,22 @@ class FdtRo(object):
"""
return fdt_size_dt_struct(self._fdt)
+ def dt_flags(self):
+ """Return flags from the header
+
+ Returns:
+ flags value from the header
+ """
+ return fdt_dt_flags(self._fdt)
+
+ def last_comp_version_w(self):
+ """Return the last compatible version for writing of the device tree
+
+ Returns:
+ Last compatible version number for writing of the device tree
+ """
+ return fdt_last_comp_version_w(self._fdt)
+
def num_mem_rsv(self, quiet=()):
"""Return the number of memory reserve-map records
@@ -1215,6 +1231,8 @@ uint32_t fdt_last_comp_version(const void *fdt);
uint32_t fdt_boot_cpuid_phys(const void *fdt);
uint32_t fdt_size_dt_strings(const void *fdt);
uint32_t fdt_size_dt_struct(const void *fdt);
+uint32_t fdt_dt_flags(const void *fdt);
+uint32_t fdt_last_comp_version_w(const void *fdt);
int fdt_property_string(void *fdt, const char *name, const char *val);
int fdt_property_cell(void *fdt, const char *name, uint32_t val);
diff --git a/tests/dumptrees.c b/tests/dumptrees.c
index 4732fff..c05d216 100644
--- a/tests/dumptrees.c
+++ b/tests/dumptrees.c
@@ -27,7 +27,8 @@ static struct {
TREE(two_roots),
TREE(named_root),
TREE(unknown_tags_can_skip),
- TREE(unknown_tags_no_skip)
+ TREE(unknown_tags_no_skip),
+ TREE(last_comp_version_w_future)
};
#define NUM_TREES (sizeof(trees) / sizeof(trees[0]))
diff --git a/tests/pylibfdt_tests.py b/tests/pylibfdt_tests.py
index a4f73ed..72c98c5 100644
--- a/tests/pylibfdt_tests.py
+++ b/tests/pylibfdt_tests.py
@@ -285,14 +285,16 @@ class PyLibfdtBasicTests(unittest.TestCase):
"""Test that we can access the header values"""
self.assertEqual(self.fdt.magic(), 0xd00dfeed)
self.assertEqual(self.fdt.totalsize(), len(self.fdt._fdt))
- self.assertEqual(self.fdt.off_dt_struct(), 88)
- self.assertEqual(self.fdt.off_dt_strings(), 652)
- self.assertEqual(self.fdt.off_mem_rsvmap(), 40)
- self.assertEqual(self.fdt.version(), 17)
+ self.assertEqual(self.fdt.off_dt_struct(), 96)
+ self.assertEqual(self.fdt.off_dt_strings(), 660)
+ self.assertEqual(self.fdt.off_mem_rsvmap(), 48)
+ self.assertEqual(self.fdt.version(), 18)
self.assertEqual(self.fdt.last_comp_version(), 16)
self.assertEqual(self.fdt.boot_cpuid_phys(), 0)
self.assertEqual(self.fdt.size_dt_strings(), 105)
self.assertEqual(self.fdt.size_dt_struct(), 564)
+ self.assertEqual(self.fdt.dt_flags(), 0)
+ self.assertEqual(self.fdt.last_comp_version_w(), 17)
def testPack(self):
"""Test that we can pack the tree after deleting something"""
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 1ba937d..90ba558 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -576,7 +576,8 @@ libfdt_tests () {
run_test dtbs_equal_ordered cell-overflow.test.dtb cell-overflow-results.test.dtb
# check full tests
- for good in test_tree1.dtb unknown_tags_can_skip.dtb; do
+ for good in test_tree1.dtb unknown_tags_can_skip.dtb \
+ last_comp_version_w_future.dtb; do
run_test check_full $good
done
for bad in truncated_property.dtb truncated_string.dtb \
@@ -1044,32 +1045,41 @@ fdtput_tests () {
# TODO: Add tests for verbose mode?
+ # Not allowed to modify a dtb due to last_comp_version_w
+ # FDT_ERR_BADVERSION error code is returned
+ dtb=last_comp_version_w_future.fdtput.test.dtb
+ cp last_comp_version_w_future.dtb $dtb
+ run_wrap_error_test $DTPUT $dtb /subnode prop-int -tu 123
+ run_wrap_error_test $DTPUT $dtb -d /subnode prop-int
+ run_wrap_error_test $DTPUT $dtb -c /new-node
+ run_wrap_error_test $DTPUT $dtb -r /subnode
+
# Modify a dtb containing some "unknown" tags that can be skipped
dtb=unknown_tags_can_skip.fdtput.test.dtb
cp unknown_tags_can_skip.dtb $dtb
base_run_test wrap_fdtdump $dtb $dtb.0.out
# Remove unneeded header fields (keep those related to versions)
- sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.0.out
+ sed -i '/^\/.*\(magic\|off\|size\|cpu\|flags\)/d' $dtb.0.out
base_run_test check_diff $dtb.0.out "$SRCDIR/$dtb.0.expect"
run_fdtput_test "vwxyz" $dtb / prop-str -ts "vwxyz"
base_run_test wrap_fdtdump $dtb $dtb.1.out
# Remove unneeded header fields (keep those related to versions)
- sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.1.out
+ sed -i '/^\/.*\(magic\|off\|size\|cpu\|flags\)/d' $dtb.1.out
base_run_test check_diff $dtb.1.out "$SRCDIR/$dtb.1.expect"
cp unknown_tags_can_skip.dtb $dtb
run_wrap_test $DTPUT $dtb -c /tst-fdtput
base_run_test wrap_fdtdump $dtb $dtb.2.out
# Remove unneeded header fields (keep those related to versions)
- sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.2.out
+ sed -i '/^\/.*\(magic\|off\|size\|cpu\|flags\)/d' $dtb.2.out
base_run_test check_diff $dtb.2.out "$SRCDIR/$dtb.2.expect"
run_wrap_test $DTPUT $dtb -c /tst-fdtput/n1 /tst-fdtput/n2 /tst-fdtput/n3
run_wrap_test $DTPUT $dtb -r /tst-fdtput/n1 /tst-fdtput/n3
run_fdtget_test "n2" $dtb -l /tst-fdtput
base_run_test wrap_fdtdump $dtb $dtb.3.out
# Remove unneeded header fields (keep those related to versions)
- sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.3.out
+ sed -i '/^\/.*\(magic\|off\|size\|cpu\|flags\)/d' $dtb.3.out
base_run_test check_diff $dtb.3.out "$SRCDIR/$dtb.3.expect"
cp unknown_tags_can_skip.dtb $dtb
@@ -1077,21 +1087,21 @@ fdtput_tests () {
run_fdtget_test "prop-int" $dtb -p /
base_run_test wrap_fdtdump $dtb $dtb.4.out
# Remove unneeded header fields (keep those related to versions)
- sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.4.out
+ sed -i '/^\/.*\(magic\|off\|size\|cpu\|flags\)/d' $dtb.4.out
base_run_test check_diff $dtb.4.out "$SRCDIR/$dtb.4.expect"
cp unknown_tags_can_skip.dtb $dtb
run_wrap_test $DTPUT $dtb /subnode2 prop-tst-fdtput -ts "Test fdtput"
base_run_test wrap_fdtdump $dtb $dtb.5.out
# Remove unneeded header fields (keep those related to versions)
- sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.5.out
+ sed -i '/^\/.*\(magic\|off\|size\|cpu\|flags\)/d' $dtb.5.out
base_run_test check_diff $dtb.5.out "$SRCDIR/$dtb.5.expect"
cp unknown_tags_can_skip.dtb $dtb
run_wrap_test $DTPUT $dtb -r /subnode2/subsubnode
base_run_test wrap_fdtdump $dtb $dtb.6.out
# Remove unneeded header fields (keep those related to versions)
- sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.6.out
+ sed -i '/^\/.*\(magic\|off\|size\|cpu\|flags\)/d' $dtb.6.out
base_run_test check_diff $dtb.6.out "$SRCDIR/$dtb.6.expect"
}
diff --git a/tests/testdata.h b/tests/testdata.h
index aef04ab..26c7c18 100644
--- a/tests/testdata.h
+++ b/tests/testdata.h
@@ -59,4 +59,5 @@ extern struct fdt_header two_roots;
extern struct fdt_header named_root;
extern struct fdt_header unknown_tags_can_skip;
extern struct fdt_header unknown_tags_no_skip;
+extern struct fdt_header last_comp_version_w_future;
#endif /* ! __ASSEMBLER__ */
diff --git a/tests/testutils.c b/tests/testutils.c
index 54da2e4..728d89c 100644
--- a/tests/testutils.c
+++ b/tests/testutils.c
@@ -344,7 +344,7 @@ void *open_blob_rw(const void *blob)
{
int err;
void *buf;
- int newsize = fdt_totalsize(blob) + 8;
+ int newsize = fdt_totalsize(blob) + 8 + 2 * 4;
buf = xmalloc(newsize);
err = fdt_open_into(blob, buf, newsize);
diff --git a/tests/trees.S b/tests/trees.S
index ef9a175..9215f3e 100644
--- a/tests/trees.S
+++ b/tests/trees.S
@@ -8,7 +8,7 @@
.byte (\val) & 0xff
.endm
- .macro treehdr_vers tree vers last_comp_vers
+ .macro treehdr_vers tree vers last_comp_vers last_comp_vers_w
.balign 8
.globl \tree
\tree :
@@ -22,10 +22,12 @@
fdtlong 0
fdtlong (\tree\()_strings_end - \tree\()_strings)
fdtlong (\tree\()_struct_end - \tree\()_struct)
+ fdtlong 0
+ fdtlong \last_comp_vers_w
.endm
.macro treehdr tree
- treehdr_vers \tree 0x11 0x10
+ treehdr_vers \tree 0x12 0x10 0x11
.endm
.macro rsvmape addrh, addrl, lenh, lenl
@@ -334,7 +336,7 @@ named_root_end:
* Use a really future dtb version to check version downgrade on
* modification.
*/
- treehdr_vers unknown_tags_can_skip 0xffffffff 0x10
+ treehdr_vers unknown_tags_can_skip 0xffffffff 0x10 0x11
empty_rsvmap unknown_tags_can_skip
unknown_tags_can_skip_struct:
@@ -444,3 +446,24 @@ unknown_tags_no_skip_strings:
unknown_tags_no_skip_strings_end:
unknown_tags_no_skip_end:
+
+
+ /* Tree with last_comp_version_w set to avoid any modifications */
+ treehdr_vers last_comp_version_w_future 0xffffffff 0x10 0xffffffff
+ empty_rsvmap last_comp_version_w_future
+
+last_comp_version_w_future_struct:
+ beginn ""
+ propu64 last_comp_version_w_future, prop_int, 1, 2
+ beginn "subnode"
+ propu64 last_comp_version_w_future, prop_int, 1, 2
+ endn
+ endn
+ fdtlong FDT_END
+last_comp_version_w_future_struct_end:
+
+last_comp_version_w_future_strings:
+ string last_comp_version_w_future, prop_int, "prop-int"
+last_comp_version_w_future_strings_end:
+
+last_comp_version_w_future_end:
diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.0.expect b/tests/unknown_tags_can_skip.fdtput.test.dtb.0.expect
index 3cdf448..0d72e1f 100644
--- a/tests/unknown_tags_can_skip.fdtput.test.dtb.0.expect
+++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.0.expect
@@ -1,6 +1,7 @@
/dts-v1/;
// version: 4294967295
// last_comp_version: 16
+// last_comp_version_w: 17
// Unknown tag ignored: 0xd0000000, data len 4 00000001
/ {
diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect b/tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect
index 71f2d1c..d355d5a 100644
--- a/tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect
+++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect
@@ -1,6 +1,7 @@
/dts-v1/;
-// version: 17
+// version: 18
// last_comp_version: 16
+// last_comp_version_w: 17
// Unknown tag ignored: 0xd0000000, data len 4 00000001
/ {
diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.2.expect b/tests/unknown_tags_can_skip.fdtput.test.dtb.2.expect
index bd3a13b..69b4465 100644
--- a/tests/unknown_tags_can_skip.fdtput.test.dtb.2.expect
+++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.2.expect
@@ -1,6 +1,7 @@
/dts-v1/;
-// version: 17
+// version: 4294967295
// last_comp_version: 16
+// last_comp_version_w: 17
// Unknown tag ignored: 0xd0000000, data len 4 00000001
/ {
diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.3.expect b/tests/unknown_tags_can_skip.fdtput.test.dtb.3.expect
index 237eb95..bbdd1c6 100644
--- a/tests/unknown_tags_can_skip.fdtput.test.dtb.3.expect
+++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.3.expect
@@ -1,6 +1,7 @@
/dts-v1/;
-// version: 17
+// version: 4294967295
// last_comp_version: 16
+// last_comp_version_w: 17
// Unknown tag ignored: 0xd0000000, data len 4 00000001
/ {
diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.4.expect b/tests/unknown_tags_can_skip.fdtput.test.dtb.4.expect
index 8473040..98b0252 100644
--- a/tests/unknown_tags_can_skip.fdtput.test.dtb.4.expect
+++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.4.expect
@@ -1,6 +1,7 @@
/dts-v1/;
-// version: 17
+// version: 4294967295
// last_comp_version: 16
+// last_comp_version_w: 17
// Unknown tag ignored: 0xd0000000, data len 4 00000001
/ {
diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.5.expect b/tests/unknown_tags_can_skip.fdtput.test.dtb.5.expect
index f7806f4..9738793 100644
--- a/tests/unknown_tags_can_skip.fdtput.test.dtb.5.expect
+++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.5.expect
@@ -1,6 +1,7 @@
/dts-v1/;
-// version: 17
+// version: 4294967295
// last_comp_version: 16
+// last_comp_version_w: 17
// Unknown tag ignored: 0xd0000000, data len 4 00000001
/ {
diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.6.expect b/tests/unknown_tags_can_skip.fdtput.test.dtb.6.expect
index 029f3b4..22449ae 100644
--- a/tests/unknown_tags_can_skip.fdtput.test.dtb.6.expect
+++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.6.expect
@@ -1,6 +1,7 @@
/dts-v1/;
-// version: 17
+// version: 4294967295
// last_comp_version: 16
+// last_comp_version_w: 17
// Unknown tag ignored: 0xd0000000, data len 4 00000001
/ {
--
2.53.0
^ permalink raw reply related
* [PATCH v2 09/10] libfdt: Handle unknown tags on dtb modifications
From: Herve Codina @ 2026-04-09 11:54 UTC (permalink / raw)
To: David Gibson, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Ayush Singh, Geert Uytterhoeven, devicetree-compiler, devicetree,
linux-kernel, devicetree-spec, Hui Pu, Ian Ray, Luca Ceresoli,
Thomas Petazzoni, Herve Codina
In-Reply-To: <20260409115426.352214-1-herve.codina@bootlin.com>
The structured tag value definition introduced recently gives the
ability to ignore unknown tags without any error.
When the dtb is modified those unknown tags have to be taken into
account.
First, depending on the unknown tag location, the item associated with
the tag is identified:
- An unknown tag located just after a FDT_BEGIN_NODE is related to the
node.
- An unknown tag located just after a FDT_PROP is related to the
property.
- An unknown tag out of any node (i.e located before the first
FDT_BEGIN_NODE or after the last FDT_END_NODE) is a global tag
related to the dtb itself.
Then, if we are allowed to write a dtb containing unknown tags, the
following rules are used:
- When a property is modified, tags related to this property are
removed and the dtb version is downgraded.
- When a property is removed, tags related to this property are
obviously removed. The dtb version is kept unchanged.
- When a property or a node is added, obviously no unknown tags are
added and the dtb version is kept unchanged.
- When a node is removed, tags related to this node are obviously
removed. The dtb version is kept unchanged.
- Adding, removing or modifying a property is not considered as a node
modification and so, those operations have no impacts on unknown
tags related to the node. Those node related tags are kept unchanged.
- The only modification considered as a node modification is setting
its name. We consider that this operation has no impact on tags
related to the node. Here also, those node related tags and the
dtb version are kept unchanged.
- Global (dtb related) unknown tags are kept unchanged regardless the
modification done.
Implement those rules when a dtb is modified.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
libfdt/fdt_rw.c | 118 +++++++++++++++++-
tests/run_tests.sh | 50 ++++++++
...own_tags_can_skip.fdtput.test.dtb.0.expect | 31 +++++
...own_tags_can_skip.fdtput.test.dtb.1.expect | 35 ++++++
...own_tags_can_skip.fdtput.test.dtb.2.expect | 33 +++++
...own_tags_can_skip.fdtput.test.dtb.3.expect | 35 ++++++
...own_tags_can_skip.fdtput.test.dtb.4.expect | 34 +++++
...own_tags_can_skip.fdtput.test.dtb.5.expect | 32 +++++
...own_tags_can_skip.fdtput.test.dtb.6.expect | 27 ++++
9 files changed, 394 insertions(+), 1 deletion(-)
create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.0.expect
create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect
create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.2.expect
create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.3.expect
create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.4.expect
create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.5.expect
create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.6.expect
diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c
index f5c28fc..a8f53b4 100644
--- a/libfdt/fdt_rw.c
+++ b/libfdt/fdt_rw.c
@@ -188,6 +188,60 @@ int fdt_del_mem_rsv(void *fdt, int n)
return fdt_splice_mem_rsv_(fdt, re, 1, 0);
}
+static void fdt_nopify_area(void *fdt, int start_offset, int next_offset)
+{
+ int count = (next_offset - start_offset) / sizeof(fdt32_t);
+ fdt32_t fdt32_nop = cpu_to_fdt32(FDT_NOP);
+ fdt32_t *ptr;
+
+ ptr = fdt_offset_ptr_w_(fdt, start_offset);
+ while (count--)
+ *(ptr++) = fdt32_nop;
+};
+
+static int fdt_property_remove_unknown_tags(void *fdt,
+ const struct fdt_property *prop,
+ bool downgrade_version)
+{
+ int nextoffset, offset;
+ bool is_unknown;
+ uint32_t tag;
+
+ tag = fdt_next_tag(fdt, fdt_ptr_offset_(fdt, prop), &nextoffset);
+ if (tag == FDT_END)
+ return nextoffset;
+
+ /*
+ * Look at all tags related to the current property. I.e. tags after the
+ * current property and before either the next property, a sub-node or
+ * the end of current node
+ */
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag_(fdt, offset, &nextoffset, &is_unknown);
+ if (tag == FDT_END)
+ return nextoffset;
+
+ /*
+ * Unknown tags are returned as NOP. Force FDT_NOP to be really
+ * present in the area to remove the unknown tag and its related
+ * data. Also, as a tag is removed, downgrade the dtb version
+ * if asked for.
+ */
+ if (tag == FDT_NOP) {
+ if (is_unknown) {
+ if (downgrade_version)
+ fdt_downgrade_version(fdt);
+ fdt_nopify_area(fdt, offset, nextoffset);
+ }
+ }
+
+ } while ((tag != FDT_PROP) && (tag != FDT_BEGIN_NODE) &&
+ (tag != FDT_END_NODE));
+
+ return 0;
+}
+
static int fdt_resize_property_(void *fdt, int nodeoffset,
const char *name, int namelen,
int len, struct fdt_property **prop)
@@ -200,6 +254,14 @@ static int fdt_resize_property_(void *fdt, int nodeoffset,
if (!*prop)
return oldlen;
+ /*
+ * The property is resized. Remove possible unknown tags related to the
+ * property downgrading the dtb version.
+ */
+ err = fdt_property_remove_unknown_tags(fdt, *prop, true);
+ if (err)
+ return err;
+
if ((err = fdt_splice_struct_(fdt, (*prop)->data, FDT_TAGALIGN(oldlen),
FDT_TAGALIGN(len))))
return err;
@@ -208,6 +270,29 @@ static int fdt_resize_property_(void *fdt, int nodeoffset,
return 0;
}
+static int fdt_node_skip_unknown_tags(void *fdt, int next)
+{
+ int nextoffset = next;
+ int offset;
+ uint32_t tag;
+
+ /*
+ * Skip all tags related to the current node. I.e. tags after the
+ * current node and before either the next property, a sub-node or the
+ * end of current node.
+ */
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+ if (tag == FDT_END)
+ return nextoffset;
+
+ } while ((tag != FDT_PROP) && (tag != FDT_BEGIN_NODE) &&
+ (tag != FDT_END_NODE));
+
+ return offset;
+}
+
static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
int namelen, int len, struct fdt_property **prop)
{
@@ -220,6 +305,15 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,
if ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0)
return nextoffset;
+ /*
+ * nextoffset it at the first tag after the node.
+ * Skip possible unknown tags related to the node in order to add the
+ * property after those tags.
+ */
+ nextoffset = fdt_node_skip_unknown_tags(fdt, nextoffset);
+ if (nextoffset < 0)
+ return nextoffset;
+
namestroff = fdt_find_add_string_(fdt, name, namelen, &allocated);
if (namestroff < 0)
return namestroff;
@@ -309,6 +403,14 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name,
prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
if (prop) {
+ /*
+ * The property is going to be modified. Remove possible unknown
+ * tags related to this property downgrading the dtb version.
+ */
+ err = fdt_property_remove_unknown_tags(fdt, prop, true);
+ if (err)
+ return err;
+
newlen = len + oldlen;
err = fdt_splice_struct_(fdt, prop->data,
FDT_TAGALIGN(oldlen),
@@ -331,6 +433,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name)
{
struct fdt_property *prop;
int len, proplen;
+ int err;
FDT_RW_PROBE(fdt);
@@ -338,6 +441,14 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name)
if (!prop)
return len;
+ /*
+ * The property is going to be removed. Remove also possible unknown
+ * tags related to this property. Keep the dtb version unchanged.
+ */
+ err = fdt_property_remove_unknown_tags(fdt, prop, false);
+ if (err)
+ return err;
+
proplen = sizeof(*prop) + FDT_TAGALIGN(len);
return fdt_splice_struct_(fdt, prop, proplen, 0);
}
@@ -366,7 +477,12 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
else if (offset != -FDT_ERR_NOTFOUND)
return offset;
- /* Try to place the new node after the parent's properties */
+ /*
+ * Try to place the new node after the parent's properties and unknown
+ * tags related to those properties.
+ * Unknown tags are reported as FDT_NOP tags by fdt_next_tag.
+ * Skipping FDT_NOP tags will correctly skip unknown tags.
+ */
tag = fdt_next_tag(fdt, parentoffset, &nextoffset);
/* the fdt_subnode_offset_namelen() should ensure this never hits */
if (!can_assume(LIBFDT_FLAWLESS) && (tag != FDT_BEGIN_NODE))
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 48ac6fa..1ba937d 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -1043,6 +1043,56 @@ fdtput_tests () {
run_wrap_error_test $DTPUT $dtb -d /chosen non-existent-prop
# TODO: Add tests for verbose mode?
+
+ # Modify a dtb containing some "unknown" tags that can be skipped
+ dtb=unknown_tags_can_skip.fdtput.test.dtb
+ cp unknown_tags_can_skip.dtb $dtb
+ base_run_test wrap_fdtdump $dtb $dtb.0.out
+ # Remove unneeded header fields (keep those related to versions)
+ sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.0.out
+ base_run_test check_diff $dtb.0.out "$SRCDIR/$dtb.0.expect"
+
+ run_fdtput_test "vwxyz" $dtb / prop-str -ts "vwxyz"
+ base_run_test wrap_fdtdump $dtb $dtb.1.out
+ # Remove unneeded header fields (keep those related to versions)
+ sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.1.out
+ base_run_test check_diff $dtb.1.out "$SRCDIR/$dtb.1.expect"
+
+ cp unknown_tags_can_skip.dtb $dtb
+ run_wrap_test $DTPUT $dtb -c /tst-fdtput
+ base_run_test wrap_fdtdump $dtb $dtb.2.out
+ # Remove unneeded header fields (keep those related to versions)
+ sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.2.out
+ base_run_test check_diff $dtb.2.out "$SRCDIR/$dtb.2.expect"
+ run_wrap_test $DTPUT $dtb -c /tst-fdtput/n1 /tst-fdtput/n2 /tst-fdtput/n3
+ run_wrap_test $DTPUT $dtb -r /tst-fdtput/n1 /tst-fdtput/n3
+ run_fdtget_test "n2" $dtb -l /tst-fdtput
+ base_run_test wrap_fdtdump $dtb $dtb.3.out
+ # Remove unneeded header fields (keep those related to versions)
+ sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.3.out
+ base_run_test check_diff $dtb.3.out "$SRCDIR/$dtb.3.expect"
+
+ cp unknown_tags_can_skip.dtb $dtb
+ run_wrap_test $DTPUT $dtb -d / prop-str
+ run_fdtget_test "prop-int" $dtb -p /
+ base_run_test wrap_fdtdump $dtb $dtb.4.out
+ # Remove unneeded header fields (keep those related to versions)
+ sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.4.out
+ base_run_test check_diff $dtb.4.out "$SRCDIR/$dtb.4.expect"
+
+ cp unknown_tags_can_skip.dtb $dtb
+ run_wrap_test $DTPUT $dtb /subnode2 prop-tst-fdtput -ts "Test fdtput"
+ base_run_test wrap_fdtdump $dtb $dtb.5.out
+ # Remove unneeded header fields (keep those related to versions)
+ sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.5.out
+ base_run_test check_diff $dtb.5.out "$SRCDIR/$dtb.5.expect"
+
+ cp unknown_tags_can_skip.dtb $dtb
+ run_wrap_test $DTPUT $dtb -r /subnode2/subsubnode
+ base_run_test wrap_fdtdump $dtb $dtb.6.out
+ # Remove unneeded header fields (keep those related to versions)
+ sed -i '/^\/.*\(magic\|off\|size\|cpu\)/d' $dtb.6.out
+ base_run_test check_diff $dtb.6.out "$SRCDIR/$dtb.6.expect"
}
utilfdt_tests () {
diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.0.expect b/tests/unknown_tags_can_skip.fdtput.test.dtb.0.expect
new file mode 100644
index 0000000..3cdf448
--- /dev/null
+++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.0.expect
@@ -0,0 +1,31 @@
+/dts-v1/;
+// version: 4294967295
+// last_comp_version: 16
+
+// Unknown tag ignored: 0xd0000000, data len 4 00000001
+/ {
+ // Unknown tag ignored: 0xc0000000, data len 0
+ prop-int = <0x00003201>;
+ // Unknown tag ignored: 0xd0000000, data len 4 00000110
+ prop-str = "abcd";
+ // Unknown tag ignored: 0xe0000000, data len 8 0000012000000121
+ // Unknown tag ignored: 0xf0000000, data len 3 101112
+ subnode1 {
+ prop-int = <0x00006401 0x00006402>;
+ // Unknown tag ignored: 0xc0000000, data len 0
+ };
+ subnode2 {
+ // Unknown tag ignored: 0xd0000000, data len 4 00000121
+ prop-int1 = <0x00064020 0x00064021>;
+ // Unknown tag ignored: 0xe0000000, data len 8 0000122000001221
+ prop-int2 = <0x00032022>;
+ subsubnode {
+ // Unknown tag ignored: 0xe0000000, data len 8 0000123000001231
+ prop-int = <0x00064023 0x00064024>;
+ };
+ // Unknown tag ignored: 0xf0000000, data len 3 212223
+ };
+ // Unknown tag ignored: 0xf0000000, data len 5 3132333435
+};
+// Unknown tag ignored: 0xd0000000, data len 4 00000002
+// Unknown tag ignored: 0xf0000000, data len 2 4041
diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect b/tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect
new file mode 100644
index 0000000..71f2d1c
--- /dev/null
+++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect
@@ -0,0 +1,35 @@
+/dts-v1/;
+// version: 17
+// last_comp_version: 16
+
+// Unknown tag ignored: 0xd0000000, data len 4 00000001
+/ {
+ // Unknown tag ignored: 0xc0000000, data len 0
+ prop-int = <0x00003201>;
+ // Unknown tag ignored: 0xd0000000, data len 4 00000110
+ prop-str = "vwxyz";
+ // [NOP]
+ // [NOP]
+ // [NOP]
+ // [NOP]
+ // [NOP]
+ // [NOP]
+ subnode1 {
+ prop-int = <0x00006401 0x00006402>;
+ // Unknown tag ignored: 0xc0000000, data len 0
+ };
+ subnode2 {
+ // Unknown tag ignored: 0xd0000000, data len 4 00000121
+ prop-int1 = <0x00064020 0x00064021>;
+ // Unknown tag ignored: 0xe0000000, data len 8 0000122000001221
+ prop-int2 = <0x00032022>;
+ subsubnode {
+ // Unknown tag ignored: 0xe0000000, data len 8 0000123000001231
+ prop-int = <0x00064023 0x00064024>;
+ };
+ // Unknown tag ignored: 0xf0000000, data len 3 212223
+ };
+ // Unknown tag ignored: 0xf0000000, data len 5 3132333435
+};
+// Unknown tag ignored: 0xd0000000, data len 4 00000002
+// Unknown tag ignored: 0xf0000000, data len 2 4041
diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.2.expect b/tests/unknown_tags_can_skip.fdtput.test.dtb.2.expect
new file mode 100644
index 0000000..bd3a13b
--- /dev/null
+++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.2.expect
@@ -0,0 +1,33 @@
+/dts-v1/;
+// version: 17
+// last_comp_version: 16
+
+// Unknown tag ignored: 0xd0000000, data len 4 00000001
+/ {
+ // Unknown tag ignored: 0xc0000000, data len 0
+ prop-int = <0x00003201>;
+ // Unknown tag ignored: 0xd0000000, data len 4 00000110
+ prop-str = "abcd";
+ // Unknown tag ignored: 0xe0000000, data len 8 0000012000000121
+ // Unknown tag ignored: 0xf0000000, data len 3 101112
+ tst-fdtput {
+ };
+ subnode1 {
+ prop-int = <0x00006401 0x00006402>;
+ // Unknown tag ignored: 0xc0000000, data len 0
+ };
+ subnode2 {
+ // Unknown tag ignored: 0xd0000000, data len 4 00000121
+ prop-int1 = <0x00064020 0x00064021>;
+ // Unknown tag ignored: 0xe0000000, data len 8 0000122000001221
+ prop-int2 = <0x00032022>;
+ subsubnode {
+ // Unknown tag ignored: 0xe0000000, data len 8 0000123000001231
+ prop-int = <0x00064023 0x00064024>;
+ };
+ // Unknown tag ignored: 0xf0000000, data len 3 212223
+ };
+ // Unknown tag ignored: 0xf0000000, data len 5 3132333435
+};
+// Unknown tag ignored: 0xd0000000, data len 4 00000002
+// Unknown tag ignored: 0xf0000000, data len 2 4041
diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.3.expect b/tests/unknown_tags_can_skip.fdtput.test.dtb.3.expect
new file mode 100644
index 0000000..237eb95
--- /dev/null
+++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.3.expect
@@ -0,0 +1,35 @@
+/dts-v1/;
+// version: 17
+// last_comp_version: 16
+
+// Unknown tag ignored: 0xd0000000, data len 4 00000001
+/ {
+ // Unknown tag ignored: 0xc0000000, data len 0
+ prop-int = <0x00003201>;
+ // Unknown tag ignored: 0xd0000000, data len 4 00000110
+ prop-str = "abcd";
+ // Unknown tag ignored: 0xe0000000, data len 8 0000012000000121
+ // Unknown tag ignored: 0xf0000000, data len 3 101112
+ tst-fdtput {
+ n2 {
+ };
+ };
+ subnode1 {
+ prop-int = <0x00006401 0x00006402>;
+ // Unknown tag ignored: 0xc0000000, data len 0
+ };
+ subnode2 {
+ // Unknown tag ignored: 0xd0000000, data len 4 00000121
+ prop-int1 = <0x00064020 0x00064021>;
+ // Unknown tag ignored: 0xe0000000, data len 8 0000122000001221
+ prop-int2 = <0x00032022>;
+ subsubnode {
+ // Unknown tag ignored: 0xe0000000, data len 8 0000123000001231
+ prop-int = <0x00064023 0x00064024>;
+ };
+ // Unknown tag ignored: 0xf0000000, data len 3 212223
+ };
+ // Unknown tag ignored: 0xf0000000, data len 5 3132333435
+};
+// Unknown tag ignored: 0xd0000000, data len 4 00000002
+// Unknown tag ignored: 0xf0000000, data len 2 4041
diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.4.expect b/tests/unknown_tags_can_skip.fdtput.test.dtb.4.expect
new file mode 100644
index 0000000..8473040
--- /dev/null
+++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.4.expect
@@ -0,0 +1,34 @@
+/dts-v1/;
+// version: 17
+// last_comp_version: 16
+
+// Unknown tag ignored: 0xd0000000, data len 4 00000001
+/ {
+ // Unknown tag ignored: 0xc0000000, data len 0
+ prop-int = <0x00003201>;
+ // Unknown tag ignored: 0xd0000000, data len 4 00000110
+ // [NOP]
+ // [NOP]
+ // [NOP]
+ // [NOP]
+ // [NOP]
+ // [NOP]
+ subnode1 {
+ prop-int = <0x00006401 0x00006402>;
+ // Unknown tag ignored: 0xc0000000, data len 0
+ };
+ subnode2 {
+ // Unknown tag ignored: 0xd0000000, data len 4 00000121
+ prop-int1 = <0x00064020 0x00064021>;
+ // Unknown tag ignored: 0xe0000000, data len 8 0000122000001221
+ prop-int2 = <0x00032022>;
+ subsubnode {
+ // Unknown tag ignored: 0xe0000000, data len 8 0000123000001231
+ prop-int = <0x00064023 0x00064024>;
+ };
+ // Unknown tag ignored: 0xf0000000, data len 3 212223
+ };
+ // Unknown tag ignored: 0xf0000000, data len 5 3132333435
+};
+// Unknown tag ignored: 0xd0000000, data len 4 00000002
+// Unknown tag ignored: 0xf0000000, data len 2 4041
diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.5.expect b/tests/unknown_tags_can_skip.fdtput.test.dtb.5.expect
new file mode 100644
index 0000000..f7806f4
--- /dev/null
+++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.5.expect
@@ -0,0 +1,32 @@
+/dts-v1/;
+// version: 17
+// last_comp_version: 16
+
+// Unknown tag ignored: 0xd0000000, data len 4 00000001
+/ {
+ // Unknown tag ignored: 0xc0000000, data len 0
+ prop-int = <0x00003201>;
+ // Unknown tag ignored: 0xd0000000, data len 4 00000110
+ prop-str = "abcd";
+ // Unknown tag ignored: 0xe0000000, data len 8 0000012000000121
+ // Unknown tag ignored: 0xf0000000, data len 3 101112
+ subnode1 {
+ prop-int = <0x00006401 0x00006402>;
+ // Unknown tag ignored: 0xc0000000, data len 0
+ };
+ subnode2 {
+ // Unknown tag ignored: 0xd0000000, data len 4 00000121
+ prop-tst-fdtput = "Test fdtput";
+ prop-int1 = <0x00064020 0x00064021>;
+ // Unknown tag ignored: 0xe0000000, data len 8 0000122000001221
+ prop-int2 = <0x00032022>;
+ subsubnode {
+ // Unknown tag ignored: 0xe0000000, data len 8 0000123000001231
+ prop-int = <0x00064023 0x00064024>;
+ };
+ // Unknown tag ignored: 0xf0000000, data len 3 212223
+ };
+ // Unknown tag ignored: 0xf0000000, data len 5 3132333435
+};
+// Unknown tag ignored: 0xd0000000, data len 4 00000002
+// Unknown tag ignored: 0xf0000000, data len 2 4041
diff --git a/tests/unknown_tags_can_skip.fdtput.test.dtb.6.expect b/tests/unknown_tags_can_skip.fdtput.test.dtb.6.expect
new file mode 100644
index 0000000..029f3b4
--- /dev/null
+++ b/tests/unknown_tags_can_skip.fdtput.test.dtb.6.expect
@@ -0,0 +1,27 @@
+/dts-v1/;
+// version: 17
+// last_comp_version: 16
+
+// Unknown tag ignored: 0xd0000000, data len 4 00000001
+/ {
+ // Unknown tag ignored: 0xc0000000, data len 0
+ prop-int = <0x00003201>;
+ // Unknown tag ignored: 0xd0000000, data len 4 00000110
+ prop-str = "abcd";
+ // Unknown tag ignored: 0xe0000000, data len 8 0000012000000121
+ // Unknown tag ignored: 0xf0000000, data len 3 101112
+ subnode1 {
+ prop-int = <0x00006401 0x00006402>;
+ // Unknown tag ignored: 0xc0000000, data len 0
+ };
+ subnode2 {
+ // Unknown tag ignored: 0xd0000000, data len 4 00000121
+ prop-int1 = <0x00064020 0x00064021>;
+ // Unknown tag ignored: 0xe0000000, data len 8 0000122000001221
+ prop-int2 = <0x00032022>;
+ // Unknown tag ignored: 0xf0000000, data len 3 212223
+ };
+ // Unknown tag ignored: 0xf0000000, data len 5 3132333435
+};
+// Unknown tag ignored: 0xd0000000, data len 4 00000002
+// Unknown tag ignored: 0xf0000000, data len 2 4041
--
2.53.0
^ permalink raw reply related
* [PATCH v2 08/10] libfdt: Introduce fdt_ptr_offset_
From: Herve Codina @ 2026-04-09 11:54 UTC (permalink / raw)
To: David Gibson, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Ayush Singh, Geert Uytterhoeven, devicetree-compiler, devicetree,
linux-kernel, devicetree-spec, Hui Pu, Ian Ray, Luca Ceresoli,
Thomas Petazzoni, Herve Codina
In-Reply-To: <20260409115426.352214-1-herve.codina@bootlin.com>
libfdt provides internal helpers to convert an offset to a pointer but
nothing to do the reverse operation.
Introduce the fdt_ptr_offset_() internal helper to convert a pointer to
an offset.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
libfdt/libfdt_internal.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h
index c1ae306..9fd0012 100644
--- a/libfdt/libfdt_internal.h
+++ b/libfdt/libfdt_internal.h
@@ -47,6 +47,11 @@ static inline void *fdt_offset_ptr_w_(void *fdt, int offset)
return (void *)(uintptr_t)fdt_offset_ptr_(fdt, offset);
}
+static inline int fdt_ptr_offset_(const void *fdt, const void *ptr)
+{
+ return (const char *)ptr - (const char *)fdt_offset_ptr_(fdt, 0);
+}
+
static inline const struct fdt_reserve_entry *fdt_mem_rsv_(const void *fdt, int n)
{
const struct fdt_reserve_entry *rsv_table =
--
2.53.0
^ permalink raw reply related
* [PATCH v2 07/10] libfdt: Handle unknown tags in fdt_next_tag()
From: Herve Codina @ 2026-04-09 11:54 UTC (permalink / raw)
To: David Gibson, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Ayush Singh, Geert Uytterhoeven, devicetree-compiler, devicetree,
linux-kernel, devicetree-spec, Hui Pu, Ian Ray, Luca Ceresoli,
Thomas Petazzoni, Herve Codina
In-Reply-To: <20260409115426.352214-1-herve.codina@bootlin.com>
The structured tag value definition introduced recently gives the
ability to ignore unknown tags without any error when they are read.
libfdt uses fdt_next_tag() to get a tag.
Filtering out tags that should be ignored in fdt_next_tag() allows to
have the filtering done globally and allows, in future releases, to have
a central place to add new known tags that should not be filtered out.
An already known tag exists with the meaning of "just ignore". This tag
is FDT_NOP. fdt_next_tag() callers already handle the FDT_NOP tag.
Avoid unneeded modification at callers side and use a fake FDT_NOP tag
when an unknown tag that should be ignored is encountered.
Add also fdt_next_tag_() internal function for callers who need to know
if the FDT_NOP tag returned is a real FDT_NOP or a fake FDT_NOP due to
an unknown tag.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
libfdt/fdt.c | 75 ++++++++++++++++++++++++++++++++++++++--
libfdt/libfdt_internal.h | 3 ++
tests/run_tests.sh | 9 +++--
3 files changed, 83 insertions(+), 4 deletions(-)
diff --git a/libfdt/fdt.c b/libfdt/fdt.c
index fb4faba..cce1373 100644
--- a/libfdt/fdt.c
+++ b/libfdt/fdt.c
@@ -167,7 +167,7 @@ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
return fdt_offset_ptr_(fdt, offset);
}
-uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
+static uint32_t fdt_next_tag_all(const void *fdt, int startoffset, int *nextoffset)
{
const fdt32_t *tagp, *lenp;
uint32_t tag, len, sum;
@@ -218,7 +218,37 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
break;
default:
- return FDT_END;
+ if (!(tag & FDT_TAG_STRUCTURED) || !(tag & FDT_TAG_SKIP_SAFE))
+ return FDT_END;
+
+ switch (tag & FDT_TAG_DATA_MASK) {
+ case FDT_TAG_DATA_NONE:
+ break;
+ case FDT_TAG_DATA_1CELL:
+ offset += FDT_CELLSIZE;
+ break;
+ case FDT_TAG_DATA_2CELLS:
+ offset += 2 * FDT_CELLSIZE;
+ break;
+ case FDT_TAG_DATA_VARLEN:
+ /* Get the length */
+ lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
+ if (!can_assume(VALID_DTB) && !lenp)
+ return FDT_END; /* premature end */
+ len = fdt32_to_cpu(*lenp);
+ /*
+ * Skip the cell encoding the length and the
+ * following length bytes
+ */
+ len += sizeof(*lenp);
+ sum = len + offset;
+ if (!can_assume(VALID_DTB) &&
+ (sum >= INT_MAX || sum < (uint32_t) offset))
+ return FDT_END; /* premature end */
+
+ offset += len;
+ break;
+ }
}
if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
@@ -228,6 +258,47 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
return tag;
}
+static bool fdt_is_unknown_tag(uint32_t tag)
+{
+ switch (tag) {
+ case FDT_BEGIN_NODE:
+ case FDT_END_NODE:
+ case FDT_PROP:
+ case FDT_NOP:
+ case FDT_END:
+ return false;
+ default:
+ break;
+ }
+ return true;
+}
+
+uint32_t fdt_next_tag_(const void *fdt, int startoffset, int *nextoffset, bool *is_unknown)
+{
+ uint32_t tag;
+ bool unknown = false;
+
+ /* Retrieve next tag */
+ tag = fdt_next_tag_all(fdt, startoffset, nextoffset);
+ if (tag == FDT_END)
+ goto end;
+
+ if (fdt_is_unknown_tag(tag)) {
+ unknown = true;
+ /* Use a known tag that should be skipped by the caller */
+ tag = FDT_NOP;
+ }
+end:
+ if (is_unknown)
+ *is_unknown = unknown;
+ return tag;
+}
+
+uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
+{
+ return fdt_next_tag_(fdt, startoffset, nextoffset, NULL);
+}
+
int fdt_check_node_offset_(const void *fdt, int offset)
{
if (!can_assume(VALID_INPUT)
diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h
index 4c15264..c1ae306 100644
--- a/libfdt/libfdt_internal.h
+++ b/libfdt/libfdt_internal.h
@@ -20,6 +20,9 @@ int32_t fdt_ro_probe_(const void *fdt);
} \
}
+uint32_t fdt_next_tag_(const void *fdt, int startoffset, int *nextoffset,
+ bool *is_unknown);
+
int fdt_check_node_offset_(const void *fdt, int offset);
int fdt_check_prop_offset_(const void *fdt, int offset);
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index d147011..48ac6fa 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -576,11 +576,12 @@ libfdt_tests () {
run_test dtbs_equal_ordered cell-overflow.test.dtb cell-overflow-results.test.dtb
# check full tests
- for good in test_tree1.dtb; do
+ for good in test_tree1.dtb unknown_tags_can_skip.dtb; do
run_test check_full $good
done
for bad in truncated_property.dtb truncated_string.dtb \
- truncated_memrsv.dtb two_roots.dtb named_root.dtb; do
+ truncated_memrsv.dtb two_roots.dtb named_root.dtb \
+ unknown_tags_no_skip.dtb; do
run_test check_full -n $bad
done
}
@@ -961,6 +962,10 @@ fdtget_tests () {
run_fdtget_test "<the dead silence>" -tx \
-d "<the dead silence>" $dtb /randomnode doctor-who
run_fdtget_test "<blink>" -tx -d "<blink>" $dtb /memory doctor-who
+
+ # test with unknown tags involved
+ run_fdtget_test "25601 25602" unknown_tags_can_skip.dtb /subnode1 prop-int
+ run_wrap_error_test $DTGET unknown_tags_no_skip.dtb /subnode1 prop-int
}
fdtput_tests () {
--
2.53.0
^ permalink raw reply related
* [PATCH v2 06/10] flattree: Handle unknown tags
From: Herve Codina @ 2026-04-09 11:54 UTC (permalink / raw)
To: David Gibson, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Ayush Singh, Geert Uytterhoeven, devicetree-compiler, devicetree,
linux-kernel, devicetree-spec, Hui Pu, Ian Ray, Luca Ceresoli,
Thomas Petazzoni, Herve Codina
In-Reply-To: <20260409115426.352214-1-herve.codina@bootlin.com>
The structured tag value definition introduced recently gives the
ability to ignore unknown tags without any error when they are read.
Handle those structured tag.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
flattree.c | 65 ++++++++++++++++++++--
tests/run_tests.sh | 5 ++
tests/unknown_tags_can_skip.dtb.dts.expect | 19 +++++++
3 files changed, 84 insertions(+), 5 deletions(-)
create mode 100644 tests/unknown_tags_can_skip.dtb.dts.expect
diff --git a/flattree.c b/flattree.c
index f3b698c..88dbfa7 100644
--- a/flattree.c
+++ b/flattree.c
@@ -579,7 +579,8 @@ static void flat_read_chunk(struct inbuf *inb, void *p, int len)
if ((inb->ptr + len) > inb->limit)
die("Premature end of data parsing flat device tree\n");
- memcpy(p, inb->ptr, len);
+ if (p)
+ memcpy(p, inb->ptr, len);
inb->ptr += len;
}
@@ -604,6 +605,61 @@ static void flat_realign(struct inbuf *inb, int align)
die("Premature end of data parsing flat device tree\n");
}
+static bool flat_skip_unknown_tag(struct inbuf *inb, uint32_t tag)
+{
+ uint32_t lng;
+
+ if (!(tag & FDT_TAG_STRUCTURED) || !(tag & FDT_TAG_SKIP_SAFE))
+ return false;
+
+ switch (tag & FDT_TAG_DATA_MASK) {
+ case FDT_TAG_DATA_NONE:
+ break;
+
+ case FDT_TAG_DATA_1CELL:
+ flat_read_word(inb);
+ break;
+
+ case FDT_TAG_DATA_2CELLS:
+ flat_read_word(inb);
+ flat_read_word(inb);
+ break;
+
+ case FDT_TAG_DATA_VARLEN:
+ /* Get the length */
+ lng = flat_read_word(inb);
+
+ /* Skip the following length bytes */
+ flat_read_chunk(inb, NULL, lng);
+
+ flat_realign(inb, sizeof(uint32_t));
+ break;
+ }
+
+ return true;
+}
+
+static uint32_t flat_read_tag(struct inbuf *inb)
+{
+ uint32_t tag;
+
+ do {
+ tag = flat_read_word(inb);
+ switch (tag) {
+ case FDT_BEGIN_NODE:
+ case FDT_END_NODE:
+ case FDT_PROP:
+ case FDT_NOP:
+ case FDT_END:
+ return tag;
+ default:
+ break;
+ }
+ } while (flat_skip_unknown_tag(inb, tag));
+
+ die("Cannot skip unknown tag 0x%08x\n", tag);
+}
+
static const char *flat_read_string(struct inbuf *inb)
{
int len = 0;
@@ -750,7 +806,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
struct property *prop;
struct node *child;
- val = flat_read_word(dtbuf);
+ val = flat_read_tag(dtbuf);
switch (val) {
case FDT_PROP:
if (node->children)
@@ -905,14 +961,13 @@ struct dt_info *dt_from_blob(const char *fname)
reservelist = flat_read_mem_reserve(&memresvbuf);
- val = flat_read_word(&dtbuf);
-
+ val = flat_read_tag(&dtbuf);
if (val != FDT_BEGIN_NODE)
die("Device tree blob doesn't begin with FDT_BEGIN_NODE (begins with 0x%08x)\n", val);
tree = unflatten_tree(&dtbuf, &strbuf, "", flags);
- val = flat_read_word(&dtbuf);
+ val = flat_read_tag(&dtbuf);
if (val != FDT_END)
die("Device tree blob doesn't end with FDT_END\n");
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index f2855dd..d147011 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -881,6 +881,11 @@ dtc_tests () {
# Tests for overlay/plugin generation
dtc_overlay_tests
+
+ # Tests with "unknown tags"
+ run_dtc_test -I dtb -O dts -o unknown_tags_can_skip.dtb.dts unknown_tags_can_skip.dtb
+ base_run_test check_diff unknown_tags_can_skip.dtb.dts "$SRCDIR/unknown_tags_can_skip.dtb.dts.expect"
+ run_wrap_error_test $DTC -I dtb -O dts -o unknown_tags_no_skip.dtb.dts unknown_tags_no_skip.dtb
}
cmp_tests () {
diff --git a/tests/unknown_tags_can_skip.dtb.dts.expect b/tests/unknown_tags_can_skip.dtb.dts.expect
new file mode 100644
index 0000000..a11ee57
--- /dev/null
+++ b/tests/unknown_tags_can_skip.dtb.dts.expect
@@ -0,0 +1,19 @@
+/dts-v1/;
+
+/ {
+ prop-int = <0x3201>;
+ prop-str = "abcd";
+
+ subnode1 {
+ prop-int = <0x6401 0x6402>;
+ };
+
+ subnode2 {
+ prop-int1 = <0x64020 0x64021>;
+ prop-int2 = <0x32022>;
+
+ subsubnode {
+ prop-int = <0x64023 0x64024>;
+ };
+ };
+};
--
2.53.0
^ permalink raw reply related
* [PATCH v2 05/10] fdtdump: Handle unknown tags
From: Herve Codina @ 2026-04-09 11:54 UTC (permalink / raw)
To: David Gibson, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Ayush Singh, Geert Uytterhoeven, devicetree-compiler, devicetree,
linux-kernel, devicetree-spec, Hui Pu, Ian Ray, Luca Ceresoli,
Thomas Petazzoni, Herve Codina
In-Reply-To: <20260409115426.352214-1-herve.codina@bootlin.com>
The structured tag value definition introduced recently gives the
ability to ignore unknown tags without any error when they are read.
Add support for those structured tags in fdtdump and introduce a command
line option to dump unknown tags that should be ignored.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
fdtdump.c | 45 +++++++++-
tests/dumptrees.c | 4 +-
tests/run_tests.sh | 41 +++++++++
tests/testdata.h | 2 +
tests/trees.S | 116 +++++++++++++++++++++++++
tests/unknown_tags_can_skip.dtb.expect | 29 +++++++
6 files changed, 233 insertions(+), 4 deletions(-)
create mode 100644 tests/unknown_tags_can_skip.dtb.expect
diff --git a/fdtdump.c b/fdtdump.c
index 0e7a265..7a8b278 100644
--- a/fdtdump.c
+++ b/fdtdump.c
@@ -44,7 +44,7 @@ static const char *tagname(uint32_t tag)
#define dumpf(fmt, args...) \
do { if (debug) printf("// " fmt, ## args); } while (0)
-static void dump_blob(void *blob, bool debug)
+static void dump_blob(void *blob, bool debug, int dump_unknown)
{
uintptr_t blob_off = (uintptr_t)blob;
struct fdt_header *bph = blob;
@@ -146,20 +146,55 @@ static void dump_blob(void *blob, bool debug)
continue;
}
+ if ((tag & FDT_TAG_STRUCTURED) && (tag & FDT_TAG_SKIP_SAFE)) {
+ sz = 0;
+ switch (tag & FDT_TAG_DATA_MASK) {
+ case FDT_TAG_DATA_NONE:
+ break;
+ case FDT_TAG_DATA_1CELL:
+ sz = FDT_CELLSIZE;
+ break;
+ case FDT_TAG_DATA_2CELLS:
+ sz = 2 * FDT_CELLSIZE;
+ break;
+ case FDT_TAG_DATA_VARLEN:
+ /* Get the length */
+ sz = fdt32_to_cpu(GET_CELL(p));
+ break;
+ }
+
+ if (dump_unknown) {
+ printf("%*s// Unknown tag ignored: 0x%08"PRIx32", data len %d",
+ depth * shift, "", tag, sz);
+ if (dump_unknown > 1 && sz != 0) {
+ printf(" ");
+ for (i = 0; i < sz; i++)
+ printf("%02hhx", *(p + i));
+ }
+ printf("\n");
+ }
+
+ /* Skip the data bytes */
+ p = PALIGN(p + sz, 4);
+ continue;
+ }
+
die("** Unknown tag 0x%08"PRIx32"\n", tag);
}
}
/* Usage related data. */
static const char usage_synopsis[] = "fdtdump [options] <file>";
-static const char usage_short_opts[] = "ds" USAGE_COMMON_SHORT_OPTS;
+static const char usage_short_opts[] = "dus" USAGE_COMMON_SHORT_OPTS;
static struct option const usage_long_opts[] = {
{"debug", no_argument, NULL, 'd'},
+ {"unknown", no_argument, NULL, 'u'},
{"scan", no_argument, NULL, 's'},
USAGE_COMMON_LONG_OPTS
};
static const char * const usage_opts_help[] = {
"Dump debug information while decoding the file",
+ "Dump unknown tags information while decoding the file (-uu to dump data)",
"Scan for an embedded fdt in file",
USAGE_COMMON_OPTS_HELP
};
@@ -183,6 +218,7 @@ int main(int argc, char *argv[])
const char *file;
char *buf;
bool debug = false;
+ int dump_unknown = 0;
bool scan = false;
size_t len;
@@ -198,6 +234,9 @@ int main(int argc, char *argv[])
case 'd':
debug = true;
break;
+ case 'u':
+ dump_unknown++;
+ break;
case 's':
scan = true;
break;
@@ -242,7 +281,7 @@ int main(int argc, char *argv[])
} else if (!valid_header(buf, len))
die("%s: header is not valid\n", file);
- dump_blob(buf, debug);
+ dump_blob(buf, debug, dump_unknown);
return 0;
}
diff --git a/tests/dumptrees.c b/tests/dumptrees.c
index 08967b3..4732fff 100644
--- a/tests/dumptrees.c
+++ b/tests/dumptrees.c
@@ -25,7 +25,9 @@ static struct {
TREE(truncated_property), TREE(truncated_string),
TREE(truncated_memrsv),
TREE(two_roots),
- TREE(named_root)
+ TREE(named_root),
+ TREE(unknown_tags_can_skip),
+ TREE(unknown_tags_no_skip)
};
#define NUM_TREES (sizeof(trees) / sizeof(trees[0]))
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index f07092b..f2855dd 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -196,6 +196,40 @@ check_align () {
)
}
+# $1: f1 file
+# $2: f2 file
+check_diff () {
+ printf "diff $1 $2: "
+ local f1="$1"
+ local f2="$2"
+ (
+ if diff $f1 $f2 >/dev/null; then
+ PASS
+ else
+ if [ -z "$QUIET_TEST" ]; then
+ echo "DIFF :-:"
+ diff -u $f1 $f2
+ fi
+ FAIL "Results differ from expected"
+ fi
+ )
+}
+
+# $1: dtb file
+# $2: out file
+wrap_fdtdump () {
+ printf "wrap_fdtdump -uu $1: "
+ local dtb="$1"
+ local out="$2"
+ (
+ if $FDTDUMP -uu ${dtb} 2>/dev/null >${out}; then
+ PASS
+ else
+ FAIL
+ fi
+ )
+}
+
run_dtc_test () {
printf "dtc $*: "
base_run_test wrap_test $VALGRIND $DTC "$@"
@@ -1007,6 +1041,13 @@ utilfdt_tests () {
fdtdump_tests () {
run_fdtdump_test "$SRCDIR/fdtdump.dts"
+
+ base_run_test wrap_fdtdump unknown_tags_can_skip.dtb unknown_tags_can_skip.dtb.out
+ # Remove unneeded comments
+ sed -i '/^\/\/ [^U]/d' unknown_tags_can_skip.dtb.out
+ base_run_test check_diff unknown_tags_can_skip.dtb.out "$SRCDIR/unknown_tags_can_skip.dtb.expect"
+
+ run_wrap_error_test $FDTDUMP unknown_tags_no_skip.dtb
}
fdtoverlay_tests() {
diff --git a/tests/testdata.h b/tests/testdata.h
index fcebc2c..aef04ab 100644
--- a/tests/testdata.h
+++ b/tests/testdata.h
@@ -57,4 +57,6 @@ extern struct fdt_header truncated_string;
extern struct fdt_header truncated_memrsv;
extern struct fdt_header two_roots;
extern struct fdt_header named_root;
+extern struct fdt_header unknown_tags_can_skip;
+extern struct fdt_header unknown_tags_no_skip;
#endif /* ! __ASSEMBLER__ */
diff --git a/tests/trees.S b/tests/trees.S
index 4db2b9b..ef9a175 100644
--- a/tests/trees.S
+++ b/tests/trees.S
@@ -328,3 +328,119 @@ named_root_strings:
named_root_strings_end:
named_root_end:
+
+
+ /* Tree with "unknown" tags that can be skipped
+ * Use a really future dtb version to check version downgrade on
+ * modification.
+ */
+ treehdr_vers unknown_tags_can_skip 0xffffffff 0x10
+ empty_rsvmap unknown_tags_can_skip
+
+unknown_tags_can_skip_struct:
+ fdtlong FDT_TEST_1CELL_CAN_SKIP
+ fdtlong 0x1
+
+ beginn ""
+ fdtlong FDT_TEST_NONE_CAN_SKIP
+
+ propu32 unknown_tags_can_skip, prop_int, 0x3201
+
+ fdtlong FDT_TEST_1CELL_CAN_SKIP
+ fdtlong 0x110
+
+ propstr unknown_tags_can_skip, prop_str, "abcd"
+
+ fdtlong FDT_TEST_2CELLS_CAN_SKIP
+ fdtlong 0x120
+ fdtlong 0x121
+
+ fdtlong FDT_TEST_VARLEN_CAN_SKIP
+ fdtlong 3
+ .byte 0x10
+ .byte 0x11
+ .byte 0x12
+ .byte 0 /* padding */
+
+ beginn "subnode1"
+ propu64 unknown_tags_can_skip, prop_int, 0x6401, 0x6402
+ fdtlong FDT_TEST_NONE_CAN_SKIP
+ endn
+
+ beginn "subnode2"
+ fdtlong FDT_TEST_1CELL_CAN_SKIP
+ fdtlong 0x121
+ propu64 unknown_tags_can_skip, prop_int1, 0x64020, 0x64021
+ fdtlong FDT_TEST_2CELLS_CAN_SKIP
+ fdtlong 0x1220
+ fdtlong 0x1221
+ propu32 unknown_tags_can_skip, prop_int2, 0x32022
+ beginn "subsubnode"
+ fdtlong FDT_TEST_2CELLS_CAN_SKIP
+ fdtlong 0x1230
+ fdtlong 0x1231
+ propu64 unknown_tags_can_skip, prop_int, 0x64023, 0x64024
+ endn
+ fdtlong FDT_TEST_VARLEN_CAN_SKIP
+ fdtlong 3
+ .byte 0x21
+ .byte 0x22
+ .byte 0x23
+ .byte 0x0
+ endn
+
+ fdtlong FDT_TEST_VARLEN_CAN_SKIP
+ fdtlong 5
+ .byte 0x31
+ .byte 0x32
+ .byte 0x33
+ .byte 0x34
+ .byte 0x35
+ .byte 0 /* padding */
+ .byte 0 /* padding */
+ .byte 0 /* padding */
+ endn
+
+ fdtlong FDT_TEST_1CELL_CAN_SKIP
+ fdtlong 0x2
+
+ fdtlong FDT_TEST_VARLEN_CAN_SKIP
+ fdtlong 2
+ .byte 0x40
+ .byte 0x41
+ .byte 0 /* padding */
+ .byte 0 /* padding */
+
+ fdtlong FDT_END
+
+unknown_tags_can_skip_struct_end:
+
+unknown_tags_can_skip_strings:
+ string unknown_tags_can_skip, prop_int, "prop-int"
+ string unknown_tags_can_skip, prop_int1, "prop-int1"
+ string unknown_tags_can_skip, prop_int2, "prop-int2"
+ string unknown_tags_can_skip, prop_str, "prop-str"
+unknown_tags_can_skip_strings_end:
+
+unknown_tags_can_skip_end:
+
+
+ /* Tree with "unknown" tags that cannot be skipped */
+ treehdr unknown_tags_no_skip
+ empty_rsvmap unknown_tags_no_skip
+
+unknown_tags_no_skip_struct:
+ beginn ""
+ fdtlong FDT_TEST_NONE_NO_SKIP
+ beginn "subnode1"
+ propu64 unknown_tags_no_skip, prop_int, 1, 2
+ endn
+ endn
+ fdtlong FDT_END
+unknown_tags_no_skip_struct_end:
+
+unknown_tags_no_skip_strings:
+ string unknown_tags_no_skip, prop_int, "prop-int"
+unknown_tags_no_skip_strings_end:
+
+unknown_tags_no_skip_end:
diff --git a/tests/unknown_tags_can_skip.dtb.expect b/tests/unknown_tags_can_skip.dtb.expect
new file mode 100644
index 0000000..bf52e05
--- /dev/null
+++ b/tests/unknown_tags_can_skip.dtb.expect
@@ -0,0 +1,29 @@
+/dts-v1/;
+
+// Unknown tag ignored: 0xd0000000, data len 4 00000001
+/ {
+ // Unknown tag ignored: 0xc0000000, data len 0
+ prop-int = <0x00003201>;
+ // Unknown tag ignored: 0xd0000000, data len 4 00000110
+ prop-str = "abcd";
+ // Unknown tag ignored: 0xe0000000, data len 8 0000012000000121
+ // Unknown tag ignored: 0xf0000000, data len 3 101112
+ subnode1 {
+ prop-int = <0x00006401 0x00006402>;
+ // Unknown tag ignored: 0xc0000000, data len 0
+ };
+ subnode2 {
+ // Unknown tag ignored: 0xd0000000, data len 4 00000121
+ prop-int1 = <0x00064020 0x00064021>;
+ // Unknown tag ignored: 0xe0000000, data len 8 0000122000001221
+ prop-int2 = <0x00032022>;
+ subsubnode {
+ // Unknown tag ignored: 0xe0000000, data len 8 0000123000001231
+ prop-int = <0x00064023 0x00064024>;
+ };
+ // Unknown tag ignored: 0xf0000000, data len 3 212223
+ };
+ // Unknown tag ignored: 0xf0000000, data len 5 3132333435
+};
+// Unknown tag ignored: 0xd0000000, data len 4 00000002
+// Unknown tag ignored: 0xf0000000, data len 2 4041
--
2.53.0
^ permalink raw reply related
* [PATCH v2 04/10] Introduce structured tag value definition
From: Herve Codina @ 2026-04-09 11:54 UTC (permalink / raw)
To: David Gibson, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Ayush Singh, Geert Uytterhoeven, devicetree-compiler, devicetree,
linux-kernel, devicetree-spec, Hui Pu, Ian Ray, Luca Ceresoli,
Thomas Petazzoni, Herve Codina
In-Reply-To: <20260409115426.352214-1-herve.codina@bootlin.com>
The goal of structured tag values is to ease the introduction of new
tags in future releases with the capability for an already existing
release to ignore those structured tags. In order to do that data length
related to the unknown tag needs to be identified.
Also add a flag to tell an old release if this tag can be simply skipped
or must lead to an error.
Structured tag value is defined on 32bit and is defined as follow:
Bits | 31 | 30 | 29 28 | 27 0|
------+----+-----------+-------------------+--------+
Fields| 1 | SKIP_SAFE | DATA_LEN_ENCODING | TAG_ID |
------+----+-----------+-------------------+--------+
Bit 31 is always set to 1 to identify a structured tag value.
Bit 30 (SKIP_SAFE) is set to 1 if the tag can be safely ignored when its
TAG_ID value is not a known value (unknown tag). If the SKIP_SAFE bit is
set to 0 this tag must not be ignored and an error should be reported
when its TAG_ID value is not a known value (unknown tag).
Bits 29..28 (DATA_LEN_ENCODING) indicates the length of the data related
to the tag. Following values are possible:
- 0b00: No data.
The tag is followed by the next tag value.
- 0b01: 1 cell data
The tag is followed by a 1 cell (u32) data. The next tag is
available after this cell.
- 0b10: 2 cells data
The tag is followed by a 2 cells (2 * u32) data. The next tag
is available after those two cells.
- 0b11: Data length encoding
The tag is followed by a cell (u32) indicating the size of the
data. This size is given in bytes. Data are available right
after this cell.
The next tag is available after the data. Padding is present
after the data in order to have the next tag aligned on 32bits.
This padding is not included in the size of the data.
Bits 27..0 (TAG_ID) is the tag identifier defining a specific tag.
Introduce the structured tag values definition and some specific tags
reserved for tests based on this structure definition.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
libfdt/fdt.h | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/libfdt/fdt.h b/libfdt/fdt.h
index a07abfc..e6f75e7 100644
--- a/libfdt/fdt.h
+++ b/libfdt/fdt.h
@@ -49,6 +49,7 @@ struct fdt_property {
#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */
#define FDT_TAGSIZE sizeof(fdt32_t)
+#define FDT_CELLSIZE sizeof(fdt32_t)
#define FDT_BEGIN_NODE 0x1 /* Start node: full name */
#define FDT_END_NODE 0x2 /* End node */
@@ -57,6 +58,28 @@ struct fdt_property {
#define FDT_NOP 0x4 /* nop */
#define FDT_END 0x9
+/* Tag values flags */
+#define FDT_TAG_STRUCTURED (1<<31)
+#define FDT_TAG_SKIP_SAFE (1<<30)
+#define FDT_TAG_DATA_MASK (3<<28)
+#define FDT_TAG_DATA_NONE (0<<28)
+#define FDT_TAG_DATA_1CELL (1<<28)
+#define FDT_TAG_DATA_2CELLS (2<<28)
+#define FDT_TAG_DATA_VARLEN (3<<28)
+
+#define FDT_TAG_NO_SKIP(tag_data, tag_id) \
+ (FDT_TAG_STRUCTURED | tag_data | tag_id)
+
+#define FDT_TAG_CAN_SKIP(tag_data, tag_id) \
+ (FDT_TAG_STRUCTURED | FDT_TAG_SKIP_SAFE | tag_data | tag_id)
+
+/* Tests reserved tags */
+#define FDT_TEST_NONE_CAN_SKIP FDT_TAG_CAN_SKIP(FDT_TAG_DATA_NONE, 0)
+#define FDT_TEST_1CELL_CAN_SKIP FDT_TAG_CAN_SKIP(FDT_TAG_DATA_1CELL, 0)
+#define FDT_TEST_2CELLS_CAN_SKIP FDT_TAG_CAN_SKIP(FDT_TAG_DATA_2CELLS, 0)
+#define FDT_TEST_VARLEN_CAN_SKIP FDT_TAG_CAN_SKIP(FDT_TAG_DATA_VARLEN, 0)
+#define FDT_TEST_NONE_NO_SKIP FDT_TAG_NO_SKIP(FDT_TAG_DATA_NONE, 0)
+
#define FDT_V1_SIZE (7*sizeof(fdt32_t))
#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t))
#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t))
--
2.53.0
^ permalink raw reply related
* [PATCH v2 03/10] tests: asm: Introduce treehdr_vers macro
From: Herve Codina @ 2026-04-09 11:54 UTC (permalink / raw)
To: David Gibson, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Ayush Singh, Geert Uytterhoeven, devicetree-compiler, devicetree,
linux-kernel, devicetree-spec, Hui Pu, Ian Ray, Luca Ceresoli,
Thomas Petazzoni, Herve Codina
In-Reply-To: <20260409115426.352214-1-herve.codina@bootlin.com>
tree.S is used to generate custom dtbs. It uses the treehdr macro to
build the header part.
The current definition of this macro doesn't allow to set custom
settings related to version fields.
In order to easily generate some dtb with custom version values without
duplicating the full header computation, introduce the treehdr_vers
macro.
The modification doesn't introduce any functional changes.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
tests/trees.S | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/tests/trees.S b/tests/trees.S
index d69f7f1..4db2b9b 100644
--- a/tests/trees.S
+++ b/tests/trees.S
@@ -8,7 +8,7 @@
.byte (\val) & 0xff
.endm
- .macro treehdr tree
+ .macro treehdr_vers tree vers last_comp_vers
.balign 8
.globl \tree
\tree :
@@ -17,13 +17,17 @@
fdtlong (\tree\()_struct - \tree)
fdtlong (\tree\()_strings - \tree)
fdtlong (\tree\()_rsvmap - \tree)
- fdtlong 0x11
- fdtlong 0x10
+ fdtlong \vers
+ fdtlong \last_comp_vers
fdtlong 0
fdtlong (\tree\()_strings_end - \tree\()_strings)
fdtlong (\tree\()_struct_end - \tree\()_struct)
.endm
+ .macro treehdr tree
+ treehdr_vers \tree 0x11 0x10
+ .endm
+
.macro rsvmape addrh, addrl, lenh, lenl
fdtlong \addrh
fdtlong \addrl
--
2.53.0
^ permalink raw reply related
* [PATCH v2 02/10] libfdt: Don't assume that a FDT_BEGIN_NODE tag is available at offset 0
From: Herve Codina @ 2026-04-09 11:54 UTC (permalink / raw)
To: David Gibson, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Ayush Singh, Geert Uytterhoeven, devicetree-compiler, devicetree,
linux-kernel, devicetree-spec, Hui Pu, Ian Ray, Luca Ceresoli,
Thomas Petazzoni, Herve Codina
In-Reply-To: <20260409115426.352214-1-herve.codina@bootlin.com>
In several places, libfdt assumes that a FDT_BEGIN_NODE tag is present
at the offset 0 of the structure block.
This assumption is not correct. Indeed, a FDT_NOP can be present at the
offset 0 and this is a legit case.
fdt_first_node() has been introduced recently to get the offset of the
first node (first FDT_BEGIN_NODE) in a fdt blob.
Use this function to get the first node offset instead of looking for
this node at offset 0.
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
libfdt/fdt.c | 14 ++++++++++++--
libfdt/fdt_ro.c | 16 +++++++++++++---
libfdt/fdt_rw.c | 6 ++++++
3 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/libfdt/fdt.c b/libfdt/fdt.c
index 676c7d7..fb4faba 100644
--- a/libfdt/fdt.c
+++ b/libfdt/fdt.c
@@ -279,11 +279,21 @@ int fdt_first_node(const void *fdt)
int fdt_next_node(const void *fdt, int offset, int *depth)
{
- int nextoffset = 0;
+ int nextoffset = offset;
uint32_t tag;
+ /*
+ * Get the first node if asked for next node from the first node
+ * (offset == 0) or if the given offset is not valid (negative).
+ */
+ if (offset <= 0) {
+ nextoffset = fdt_first_node(fdt);
+ if (nextoffset < 0)
+ return nextoffset;
+ }
+
if (offset >= 0)
- if ((nextoffset = fdt_check_node_offset_(fdt, offset)) < 0)
+ if ((nextoffset = fdt_check_node_offset_(fdt, nextoffset)) < 0)
return nextoffset;
do {
diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c
index 63494fb..8e1db7d 100644
--- a/libfdt/fdt_ro.c
+++ b/libfdt/fdt_ro.c
@@ -229,6 +229,12 @@ int fdt_subnode_offset_namelen(const void *fdt, int offset,
FDT_RO_PROBE(fdt);
+ if (!offset) {
+ offset = fdt_first_node(fdt);
+ if (offset < 0)
+ return offset;
+ }
+
for (depth = 0;
(offset >= 0) && (depth >= 0);
offset = fdt_next_node(fdt, offset, &depth))
@@ -251,13 +257,17 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen)
{
const char *end = path + namelen;
const char *p = path;
- int offset = 0;
+ int offset;
FDT_RO_PROBE(fdt);
if (!can_assume(VALID_INPUT) && namelen <= 0)
return -FDT_ERR_BADPATH;
+ offset = fdt_first_node(fdt);
+ if (offset < 0)
+ return offset;
+
/* see if we have an alias */
if (*path != '/') {
const char *q = memchr(path, '/', end - p);
@@ -579,7 +589,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
if (buflen < 2)
return -FDT_ERR_NOSPACE;
- for (offset = 0, depth = 0;
+ for (offset = fdt_first_node(fdt), depth = 0;
(offset >= 0) && (offset <= nodeoffset);
offset = fdt_next_node(fdt, offset, &depth)) {
while (pdepth > depth) {
@@ -617,7 +627,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
else if (offset == -FDT_ERR_BADOFFSET)
return -FDT_ERR_BADSTRUCTURE;
- return offset; /* error from fdt_next_node() */
+ return offset; /* error from fdt_next_node() or fdt_first_node() */
}
int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c
index 90ea14e..f5c28fc 100644
--- a/libfdt/fdt_rw.c
+++ b/libfdt/fdt_rw.c
@@ -354,6 +354,12 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset,
FDT_RW_PROBE(fdt);
+ if (!parentoffset) {
+ parentoffset = fdt_first_node(fdt);
+ if (parentoffset < 0)
+ return parentoffset;
+ }
+
offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
if (offset >= 0)
return -FDT_ERR_EXISTS;
--
2.53.0
^ permalink raw reply related
* [PATCH v2 01/10] libfdt: Introduce fdt_first_node()
From: Herve Codina @ 2026-04-09 11:54 UTC (permalink / raw)
To: David Gibson, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Ayush Singh, Geert Uytterhoeven, devicetree-compiler, devicetree,
linux-kernel, devicetree-spec, Hui Pu, Ian Ray, Luca Ceresoli,
Thomas Petazzoni, Herve Codina
In-Reply-To: <20260409115426.352214-1-herve.codina@bootlin.com>
In several places, libfdt assumes that a FDT_BEGIN_NODE tag is present
at the offset 0 of the structure block.
This assumption is not correct. Indeed, a FDT_NOP can be present at the
offset 0 and this is a legit case.
Indeed, the device-tree specification [0] defines the FDT_NOP tag as
follow:
The FDT_NOP token will be ignored by any program parsing the device
tree. This token has no extra data; so it is followed immediately by
the next token, which can be any valid token. A property or node
definition in the tree can be overwritten with FDT_NOP tokens to
remove it from the tree without needing to move other sections of
the tree’s representation in the devicetree blob.
Nothing refers to any location for this tag and it has to be simply
ignored. Having this tag at offset 0 doesn't make an exception, the tag
has to be ignored.
Introduce fdt_first_node() in order to get the offset of the first node
(first FDT_BEGIN_NODE tag) available in a fdt blob taking care of
FDT_NOP tags.
[0] https://github.com/devicetree-org/devicetree-specification/blob/main/source/chapter5-flattened-format.rst?plain=1#L317
Signed-off-by: Herve Codina <herve.codina@bootlin.com>
---
libfdt/fdt.c | 25 +++++++++++++++++++++++++
libfdt/libfdt_internal.h | 1 +
2 files changed, 26 insertions(+)
diff --git a/libfdt/fdt.c b/libfdt/fdt.c
index 56d4dcb..676c7d7 100644
--- a/libfdt/fdt.c
+++ b/libfdt/fdt.c
@@ -252,6 +252,31 @@ int fdt_check_prop_offset_(const void *fdt, int offset)
return offset;
}
+int fdt_first_node(const void *fdt)
+{
+ int nextoffset = 0;
+ int offset;
+ uint32_t tag;
+
+ do {
+ offset = nextoffset;
+ tag = fdt_next_tag(fdt, offset, &nextoffset);
+ switch (tag) {
+ case FDT_END_NODE:
+ case FDT_PROP:
+ return -FDT_ERR_BADSTRUCTURE;
+
+ case FDT_BEGIN_NODE:
+ return offset;
+
+ default:
+ break;
+ }
+ } while (tag != FDT_END);
+
+ return (nextoffset < 0) ? nextoffset : -FDT_ERR_NOTFOUND;
+}
+
int fdt_next_node(const void *fdt, int offset, int *depth)
{
int nextoffset = 0;
diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h
index 0e103ca..4c15264 100644
--- a/libfdt/libfdt_internal.h
+++ b/libfdt/libfdt_internal.h
@@ -32,6 +32,7 @@ static inline const char *fdt_find_string_(const char *strtab, int tabsize,
}
int fdt_node_end_offset_(void *fdt, int nodeoffset);
+int fdt_first_node(const void *fdt);
static inline const void *fdt_offset_ptr_(const void *fdt, int offset)
{
--
2.53.0
^ permalink raw reply related
* [PATCH v2 00/10] Add support for structured tags and v18 dtb version
From: Herve Codina @ 2026-04-09 11:54 UTC (permalink / raw)
To: David Gibson, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Ayush Singh, Geert Uytterhoeven, devicetree-compiler, devicetree,
linux-kernel, devicetree-spec, Hui Pu, Ian Ray, Luca Ceresoli,
Thomas Petazzoni, Herve Codina
Recently, I sent a RFC series related to support for metadata and addon
device-trees [1].
During the discussion the concept of structured tags and "unknown" tags
emerged as well as the need to have them handled as a prerequisite of
support for metadata and addon.
The conclusion was the need for a new dtb version (v18) with support
for:
- Structured tags and based on them, "unknown" tags.
Those structured tags allow to have an standardized definition of
tags with the capability of skipping a tag and its related data
when a "unknown" tag is incountered by a given version of libfdt,
dtc and tools. Those "unknown" tags are tags defined in future
versions. Even if they exact meaning is unknown for an 'old'
version, they structure is understood and the 'old' version can skip
them without any errors if allowed.
- Flags in the dtb header (dt_flags).
The goal of this field is to have a placeholder to specify the
type of dtb we are dealing with. For instance, addons dtb will set a
flag in this placeholder
- A last compatible version for writing purpose.
The goal of the new dtb header field (last_comp_version_w) is to
disable globally any modification. It works similarly to
last_comp_version but for modification. It can be used to avoid any
modification that could be done by an 'old' version and could lead
to inconsistencies between the modification itself and some
"unknown" tags.
This current series implements those features and leads to the v18 dtb
version.
First patches (patches from 1 to 3) are patches fixing issues or
preparation patches. IMHO, those patches could be taken even if other
patches in the series lead to discussions.
Patch 4 introduces the structured tags. The patch gives definitions
needed to handle those tags.
Patches 5, 6 and 7 handles "unknown" tags in fdtdump, dtc and libfdt.
This is the reading part implementation related to "unknown" tags in
tools and lib.
Patch 8 is a preparation commit for patch 9 and patch 9 itself is
handling modifications (writing part) when unknown tags are involved.
The last patch (patch 10) bumps the dtb version including changes that
cannot be moved out of the version bump without having a v18 without all
expected features.
Also, several tests are added as soon as the related feature is
supported. Those tests are part of the last commit adding the feature.
As already said, this current series is a prerequisite to the support
for metadata and addons. The RFC series related to metadata and addons
[1] will be rebased on top of this prerequisite. Please, keep that in
mind for the review of this current prerequisite series.
[1] https://lore.kernel.org/all/20260112142009.1006236-1-herve.codina@bootlin.com/
This v2 iteration is the continuation of the first (RFC) iteration. It
mainly removes patches already applied and takes into account feedback
received from Luca during the first iteration.
Best regards,
Hervé
Changes:
v1 -> v2
v1: https://lore.kernel.org/devicetree-compiler/20260316171640.6fb0d952@bootlin.com/T/#t
Rebase on top of the last master branch of the dtc repository.
Remove the RFC tag.
- Patches 1, 2, 3, 4 and 7 in v1: Removed
Already applied.
- Patch 1 (5 in v1)
Update the commit log.
- Patch 2 (6 in v1)
Fix a typo in the commit log.
Add a comment related to 'offset <= 0' in fdt_next_node().
- Patch 3 (8 in v1)
No change
- Patch 4 (9 in v1)
Fix typos in commit log.
Replace DATA_LNG_ENCODING by DATA_LEN_ENCODING in commit log.
Use SKIP_SAFE instead of CAN_SKIP in commit log.
Rename FDT_TAG_DATA_LNG to FDT_TAG_DATA_VARLEN in tags definition.
Rename FDT_TEST_LNG_CAN_SKIP to FDT_TEST_VARLEN_CAN_SKIP.
- Patch 5 (10 in v1)
Use FDT_TAG_DATA_VARLEN instead of FDT_TAG_DATA_LNG.
Use FDT_TEST_VARLEN_CAN_SKIP instead of FDT_TEST_LNG_CAN_SKIP.
Update values used in the unknown_tags_can_skip dtb test file.
Use 'len' instead of 'lng'
Update the '-uu' option help message.
Update the fdtdump test to be stricter (avoid removing some specific
comments related to unknown tags in sed command used in the test).
- Patch 6 (11 in v1)
Use FDT_TAG_DATA_VARLEN instead of FDT_TAG_DATA_LNG.
Update the dtc test due to unknown_tags_can_skip dtb changes.
Add 'Reviewed-by: Luca Ceresoli'
- Patch 7 (12 in v1)
Replace fdt_get_next() by fdt_next_tag() in commit title and log.
Fix a typo in commit log.
Use FDT_TAG_DATA_VARLEN instead of FDT_TAG_DATA_LNG.
Update the fdtget test due to unknown_tags_can_skip dtb changes.
Add 'Reviewed-by: Luca Ceresoli'
- Patch 8 (13 in v1)
Fix commit log.
Add 'Reviewed-by: Luca Ceresoli'
- Patch 9 (14 in v1)
Update the fdtput test due to unknown_tags_can_skip dtb and
fdtdump changes.
Add a missing ')' in commit log
Add 'Reviewed-by: Luca Ceresoli'
- Patch 10 (15 in v1)
Fix typos and clarify several parts of the commit log.
Herve Codina (10):
libfdt: Introduce fdt_first_node()
libfdt: Don't assume that a FDT_BEGIN_NODE tag is available at offset
0
tests: asm: Introduce treehdr_vers macro
Introduce structured tag value definition
fdtdump: Handle unknown tags
flattree: Handle unknown tags
libfdt: Handle unknown tags in fdt_next_tag()
libfdt: Introduce fdt_ptr_offset_
libfdt: Handle unknown tags on dtb modifications
Introduce v18 dtb version
dtc.h | 2 +-
fdtdump.c | 53 ++++++-
flattree.c | 102 ++++++++++--
libfdt/fdt.c | 114 +++++++++++++-
libfdt/fdt.h | 28 ++++
libfdt/fdt_ro.c | 16 +-
libfdt/fdt_rw.c | 144 ++++++++++++++++-
libfdt/fdt_sw.c | 3 +
libfdt/libfdt.h | 7 +-
libfdt/libfdt_internal.h | 9 ++
pylibfdt/libfdt.i | 18 +++
tests/dumptrees.c | 5 +-
tests/pylibfdt_tests.py | 10 +-
tests/run_tests.sh | 115 +++++++++++++-
tests/testdata.h | 3 +
tests/testutils.c | 2 +-
tests/trees.S | 149 +++++++++++++++++-
tests/unknown_tags_can_skip.dtb.dts.expect | 19 +++
tests/unknown_tags_can_skip.dtb.expect | 29 ++++
...own_tags_can_skip.fdtput.test.dtb.0.expect | 32 ++++
...own_tags_can_skip.fdtput.test.dtb.1.expect | 36 +++++
...own_tags_can_skip.fdtput.test.dtb.2.expect | 34 ++++
...own_tags_can_skip.fdtput.test.dtb.3.expect | 36 +++++
...own_tags_can_skip.fdtput.test.dtb.4.expect | 35 ++++
...own_tags_can_skip.fdtput.test.dtb.5.expect | 33 ++++
...own_tags_can_skip.fdtput.test.dtb.6.expect | 28 ++++
26 files changed, 1020 insertions(+), 42 deletions(-)
create mode 100644 tests/unknown_tags_can_skip.dtb.dts.expect
create mode 100644 tests/unknown_tags_can_skip.dtb.expect
create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.0.expect
create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.1.expect
create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.2.expect
create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.3.expect
create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.4.expect
create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.5.expect
create mode 100644 tests/unknown_tags_can_skip.fdtput.test.dtb.6.expect
--
2.53.0
^ permalink raw reply
* Re: [PATCH 5/5] arm64: dts: qcom: qcs8550: add QCS8550 RB5Gen2 board support
From: Joe Sandom @ 2026-04-09 11:46 UTC (permalink / raw)
To: Manivannan Sadhasivam
Cc: Dmitry Baryshkov, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-arm-msm, devicetree,
linux-kernel
In-Reply-To: <lusy4sd2q22tvtvzgbb3pbpxauy5ym46ojjtpjq43wyzn72yxy@uxcggqladbnl>
On Thu, Apr 09, 2026 at 04:56:06PM +0530, Manivannan Sadhasivam wrote:
> On Thu, Apr 09, 2026 at 11:04:55AM +0100, Joe Sandom wrote:
> > On Tue, Apr 07, 2026 at 09:44:34PM +0530, Manivannan Sadhasivam wrote:
> > > On Tue, Apr 07, 2026 at 12:39:25PM +0100, Joe Sandom wrote:
> > >
> > > [...]
> > >
> > > > > > +&pcie0 {
> > > > > > + wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
> > > > > > + perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
> > > > > > +
> > > > > > + pinctrl-0 = <&pcie0_default_state>;
> > > > > > + pinctrl-names = "default";
> > > > > > +
> > > > > > + iommu-map = <0x0 &apps_smmu 0x1400 0x1>,
> > > > > > + <0x100 &apps_smmu 0x1401 0x1>,
> > > > > > + <0x208 &apps_smmu 0x1402 0x1>,
> > > > > > + <0x210 &apps_smmu 0x1403 0x1>,
> > > > > > + <0x218 &apps_smmu 0x1404 0x1>,
> > > > > > + <0x300 &apps_smmu 0x1407 0x1>,
> > > > > > + <0x400 &apps_smmu 0x1408 0x1>,
> > > > > > + <0x500 &apps_smmu 0x140c 0x1>,
> > > > > > + <0x501 &apps_smmu 0x140e 0x1>;
> > > > > > +
> > > > > > + /delete-property/ msi-map;
> > > > >
> > > > > Why?
> > > > I tried extending the msi-map to cover the RIDs from the QPS615
> > > > PCIe switch (matching the iommu-map entries), but this caused
> > > > ITS MAPD command timeouts.
> > >
> > > I'm not aware of any specific issue with ITS on this chipset. At what time did
> > > you see the timeout? During probe?
> > So when I set msi-map to match the iommu-map entries, I got this;
> > [ 0.000000] ITS [mem 0x17140000-0x1717ffff]
> > [ 11.085152] ath12k_wifi7_pci 0001:04:00.0: BAR 0 assigned
> > [ 11.115762] ath12k_wifi7_pci 0001:04:00.0: Wi-Fi 7 Hardware name: wcn7850 hw2.0
> > [ 11.153632] ath12k_wifi7_pci 0001:04:00.0: MSI vectors: 16
> > [ 11.252398] mhi mhi0: Requested to power ON
> > .........
> > [ 101.596274] mhi mhi0: Wait for device to enter SBL or Mission mode
> > [ 101.603098] ath12k_wifi7_pci 0001:04:00.0: failed to set mhi state: POWER_ON(2)
> > [ 101.610632] ath12k_wifi7_pci 0001:04:00.0: failed to start mhi: -110
> > [ 101.617171] ath12k_wifi7_pci 0001:04:00.0: failed to power up :-110
> > [ 101.794431] ath12k_wifi7_pci 0001:04:00.0: probe failed with error -110
> > [ 103.158872] ITS queue timeout (12640 12609)
> > [ 103.163183] ITS cmd its_build_mapd_cmd failed
> >
> > With msi-map removed, I got this;
> > [ 11.469642] ath12k_wifi7_pci 0001:04:00.0: BAR 0 assigned
> > [ 11.490059] ath12k_wifi7_pci 0001:04:00.0: Wi-Fi 7 Hardware name: wcn7850 hw2.0
> > [ 11.497787] ath12k_wifi7_pci 0001:04:00.0: MSI vectors: 16
> > [ 11.559958] mhi mhi0: Requested to power ON
> > [ 11.567375] mhi mhi0: Power on setup success
> > [ 11.693069] mhi mhi0: Wait for device to enter SBL or Mission mode
> > [ 12.185946] ath12k_wifi7_pci 0001:04:00.0: chip_id 0x2 ... soc_id 0x40170200
> > [ 12.482168] ath12k_wifi7_pci 0001:04:00.0 wlP1p4s0: renamed from wlan0
>
> Thanks for the logs. I also checked internally and learned that the timeout is
> due to Gunyah limiting the devices per-port. On SM8550, it currently only
> allows 2 devices per RC instance to save the memory footprint. So when you
> connect a PCIe switch which exposes more than two devices (1 USP + (1+) DSPs),
> you'll run out of ITS mapping in Gunyah, leading to these timeouts.
>
> So either you need to modify Gunyah to allow more devices per-port or switch to
> iMSI-RX which you are already doing.
>
Makes sense! Thanks for checking Mani, good to get to the bottom of that.
I'll leave it as is for now and will look into modifying Gunyah
separately.
In v3 I'll update the commit message to reflect your findings
> - Mani
>
> --
> மணிவண்ணன் சதாசிவம்
Thanks,
Joe
^ permalink raw reply
* [PATCH v8 5/5] arm64: dts: qcom: monaco: Add OPP-table for ICE UFS and ICE eMMC nodes
From: Abhinaba Rakshit @ 2026-04-09 11:44 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Manivannan Sadhasivam,
James E.J. Bottomley, Martin K. Petersen, Adrian Hunter,
Ulf Hansson, Neeraj Soni, Harshal Dev, Kuldeep Singh, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, linux-kernel, linux-scsi, linux-mmc, devicetree,
Abhinaba Rakshit
In-Reply-To: <20260409-enable-ice-clock-scaling-v8-0-ca1129798606@oss.qualcomm.com>
Qualcomm Inline Crypto Engine (ICE) platform driver now, supports
an optional OPP-table.
Add OPP-table for ICE UFS and ICE eMMC device nodes for Monaco
platform.
Signed-off-by: Abhinaba Rakshit <abhinaba.rakshit@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/monaco.dtsi | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi
index 487bb682ae8620b819f022162edd11023ed07be8..cb0e554e94d237b0adccb55fa9ed967bae9eea05 100644
--- a/arch/arm64/boot/dts/qcom/monaco.dtsi
+++ b/arch/arm64/boot/dts/qcom/monaco.dtsi
@@ -2730,6 +2730,22 @@ ice: crypto@1d88000 {
clock-names = "core",
"iface";
power-domains = <&gcc GCC_UFS_PHY_GDSC>;
+
+ operating-points-v2 = <&ice_opp_table>;
+
+ ice_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-201600000 {
+ opp-hz = /bits/ 64 <201600000>;
+ required-opps = <&rpmhpd_opp_svs_l1>;
+ };
+
+ opp-403200000 {
+ opp-hz = /bits/ 64 <403200000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ };
+ };
};
crypto: crypto@1dfa000 {
@@ -4797,6 +4813,22 @@ sdhc_ice: crypto@87c8000 {
clock-names = "core",
"iface";
power-domains = <&rpmhpd RPMHPD_CX>;
+
+ operating-points-v2 = <&ice_mmc_opp_table>;
+
+ ice_mmc_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-150000000 {
+ opp-hz = /bits/ 64 <150000000>;
+ required-opps = <&rpmhpd_opp_svs_l1>;
+ };
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ };
+ };
};
usb_1_hsphy: phy@8904000 {
--
2.34.1
^ permalink raw reply related
* [PATCH v8 4/5] arm64: dts: qcom: kodiak: Add OPP-table for ICE UFS and ICE eMMC nodes
From: Abhinaba Rakshit @ 2026-04-09 11:44 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Manivannan Sadhasivam,
James E.J. Bottomley, Martin K. Petersen, Adrian Hunter,
Ulf Hansson, Neeraj Soni, Harshal Dev, Kuldeep Singh, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, linux-kernel, linux-scsi, linux-mmc, devicetree,
Abhinaba Rakshit
In-Reply-To: <20260409-enable-ice-clock-scaling-v8-0-ca1129798606@oss.qualcomm.com>
Qualcomm Inline Crypto Engine (ICE) platform driver now, supports
an optional OPP-table.
Add OPP-table for ICE UFS and ICE eMMC device nodes for Kodiak
platform.
Signed-off-by: Abhinaba Rakshit <abhinaba.rakshit@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/kodiak.dtsi | 42 ++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi
index c899a17026fd2a10ebc528a816629c88ee3bde5d..b0aa1970d42a3bb0b9d371e0e6cd09b8cd164dbe 100644
--- a/arch/arm64/boot/dts/qcom/kodiak.dtsi
+++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi
@@ -1087,6 +1087,27 @@ sdhc_ice: crypto@7c8000 {
clock-names = "core",
"iface";
power-domains = <&rpmhpd SC7280_CX>;
+
+ operating-points-v2 = <&ice_mmc_opp_table>;
+
+ ice_mmc_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-150000000 {
+ opp-hz = /bits/ 64 <150000000>;
+ required-opps = <&rpmhpd_opp_svs>;
+ };
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ };
+ };
};
gpi_dma0: dma-controller@900000 {
@@ -2597,6 +2618,27 @@ ice: crypto@1d88000 {
clock-names = "core",
"iface";
power-domains = <&gcc GCC_UFS_PHY_GDSC>;
+
+ operating-points-v2 = <&ice_opp_table>;
+
+ ice_opp_table: opp-table {
+ compatible = "operating-points-v2";
+
+ opp-75000000 {
+ opp-hz = /bits/ 64 <75000000>;
+ required-opps = <&rpmhpd_opp_low_svs>;
+ };
+
+ opp-150000000 {
+ opp-hz = /bits/ 64 <150000000>;
+ required-opps = <&rpmhpd_opp_svs>;
+ };
+
+ opp-300000000 {
+ opp-hz = /bits/ 64 <300000000>;
+ required-opps = <&rpmhpd_opp_nom>;
+ };
+ };
};
cryptobam: dma-controller@1dc4000 {
--
2.34.1
^ permalink raw reply related
* [PATCH v8 3/5] mmc: sdhci-msm: Set ICE clk to TURBO at sdhci ICE init
From: Abhinaba Rakshit @ 2026-04-09 11:44 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Manivannan Sadhasivam,
James E.J. Bottomley, Martin K. Petersen, Adrian Hunter,
Ulf Hansson, Neeraj Soni, Harshal Dev, Kuldeep Singh, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, linux-kernel, linux-scsi, linux-mmc, devicetree,
Abhinaba Rakshit, Konrad Dybcio
In-Reply-To: <20260409-enable-ice-clock-scaling-v8-0-ca1129798606@oss.qualcomm.com>
MMC controller lacks a clock scaling mechanism, unlike the UFS
controller. By default, the MMC controller is set to TURBO mode
during probe, but the ICE clock remains at XO frequency,
leading to read/write performance degradation on eMMC.
To address this, set the ICE clock to TURBO during sdhci_msm_ice_init
to align it with the controller clock. This ensures consistent
performance and avoids mismatches between the controller
and ICE clock frequencies.
For platforms where ICE is represented as a separate device,
use the OPP framework to vote for TURBO mode, maintaining
proper voltage and power domain constraints.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Abhinaba Rakshit <abhinaba.rakshit@oss.qualcomm.com>
---
drivers/mmc/host/sdhci-msm.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index da356627d9de6a11ed5779bf057fa8eb23c38bc0..32e3f37fe425f66c00290a373e06e8ab6257824e 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -1901,6 +1901,8 @@ static void sdhci_msm_set_clock(struct sdhci_host *host, unsigned int clock)
#ifdef CONFIG_MMC_CRYPTO
static const struct blk_crypto_ll_ops sdhci_msm_crypto_ops; /* forward decl */
+static int sdhci_msm_ice_scale_clk(struct sdhci_msm_host *msm_host, unsigned long target_freq,
+ bool round_ceil); /* forward decl */
static int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host,
struct cqhci_host *cq_host)
@@ -1964,6 +1966,11 @@ static int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host,
}
mmc->caps2 |= MMC_CAP2_CRYPTO;
+
+ err = sdhci_msm_ice_scale_clk(msm_host, INT_MAX, false);
+ if (err && err != -EOPNOTSUPP)
+ dev_warn(dev, "Unable to boost ICE clock to TURBO\n");
+
return 0;
}
@@ -1989,6 +1996,16 @@ static int sdhci_msm_ice_suspend(struct sdhci_msm_host *msm_host)
return 0;
}
+static int sdhci_msm_ice_scale_clk(struct sdhci_msm_host *msm_host,
+ unsigned long target_freq,
+ bool round_ceil)
+{
+ if (msm_host->mmc->caps2 & MMC_CAP2_CRYPTO)
+ return qcom_ice_scale_clk(msm_host->ice, target_freq, round_ceil);
+
+ return 0;
+}
+
static inline struct sdhci_msm_host *
sdhci_msm_host_from_crypto_profile(struct blk_crypto_profile *profile)
{
@@ -2114,6 +2131,13 @@ sdhci_msm_ice_suspend(struct sdhci_msm_host *msm_host)
{
return 0;
}
+
+static inline int
+sdhci_msm_ice_scale_clk(struct sdhci_msm_host *msm_host, unsigned long target_freq,
+ bool round_ceil)
+{
+ return 0;
+}
#endif /* !CONFIG_MMC_CRYPTO */
/*****************************************************************************\
--
2.34.1
^ permalink raw reply related
* [PATCH v8 2/5] ufs: host: Add ICE clock scaling during UFS clock changes
From: Abhinaba Rakshit @ 2026-04-09 11:44 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Manivannan Sadhasivam,
James E.J. Bottomley, Martin K. Petersen, Adrian Hunter,
Ulf Hansson, Neeraj Soni, Harshal Dev, Kuldeep Singh, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, linux-kernel, linux-scsi, linux-mmc, devicetree,
Abhinaba Rakshit
In-Reply-To: <20260409-enable-ice-clock-scaling-v8-0-ca1129798606@oss.qualcomm.com>
Implement ICE (Inline Crypto Engine) clock scaling in sync with
UFS controller clock scaling. This ensures that the ICE operates at
an appropriate frequency when the UFS clocks are scaled up or down,
improving performance and maintaining stability for crypto operations.
For scale_up operation ensure to pass ~round_ceil (round_floor)
and vice-versa for scale_down operations.
Incase of OPP scaling is not supported by ICE, ensure to not prevent
devfreq for UFS, as ICE OPP-table is optional.
Acked-by: Manivannan Sadhasivam <mani@kernel.org>
Signed-off-by: Abhinaba Rakshit <abhinaba.rakshit@oss.qualcomm.com>
---
drivers/ufs/host/ufs-qcom.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
index 375fd24ba458a7ef65d075ba98e5f99f4aa977c1..aceb2c42969b5d2dcddcddf0167f8824733998ec 100644
--- a/drivers/ufs/host/ufs-qcom.c
+++ b/drivers/ufs/host/ufs-qcom.c
@@ -306,6 +306,15 @@ static int ufs_qcom_ice_prepare_key(struct blk_crypto_profile *profile,
return qcom_ice_prepare_key(host->ice, lt_key, lt_key_size, eph_key);
}
+static int ufs_qcom_ice_scale_clk(struct ufs_qcom_host *host, unsigned long target_freq,
+ bool round_ceil)
+{
+ if (host->hba->caps & UFSHCD_CAP_CRYPTO)
+ return qcom_ice_scale_clk(host->ice, target_freq, round_ceil);
+
+ return 0;
+}
+
static const struct blk_crypto_ll_ops ufs_qcom_crypto_ops = {
.keyslot_program = ufs_qcom_ice_keyslot_program,
.keyslot_evict = ufs_qcom_ice_keyslot_evict,
@@ -340,6 +349,12 @@ static void ufs_qcom_config_ice_allocator(struct ufs_qcom_host *host)
{
}
+static int ufs_qcom_ice_scale_clk(struct ufs_qcom_host *host, unsigned long target_freq,
+ bool round_ceil)
+{
+ return 0;
+}
+
#endif
static void ufs_qcom_disable_lane_clks(struct ufs_qcom_host *host)
@@ -1743,12 +1758,17 @@ static int ufs_qcom_clk_scale_notify(struct ufs_hba *hba, bool scale_up,
else
err = ufs_qcom_clk_scale_down_post_change(hba, target_freq);
-
if (err) {
ufshcd_uic_hibern8_exit(hba);
return err;
}
+ err = ufs_qcom_ice_scale_clk(host, target_freq, !scale_up);
+ if (err && err != -EOPNOTSUPP) {
+ ufshcd_uic_hibern8_exit(hba);
+ return err;
+ }
+
ufs_qcom_icc_update_bw(host);
ufshcd_uic_hibern8_exit(hba);
}
--
2.34.1
^ permalink raw reply related
* [PATCH v8 1/5] soc: qcom: ice: Add OPP-based clock scaling support for ICE
From: Abhinaba Rakshit @ 2026-04-09 11:44 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Manivannan Sadhasivam,
James E.J. Bottomley, Martin K. Petersen, Adrian Hunter,
Ulf Hansson, Neeraj Soni, Harshal Dev, Kuldeep Singh, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, linux-kernel, linux-scsi, linux-mmc, devicetree,
Abhinaba Rakshit
In-Reply-To: <20260409-enable-ice-clock-scaling-v8-0-ca1129798606@oss.qualcomm.com>
Register optional operation-points-v2 table for ICE device
during device probe. Attach the OPP-table with only the ICE
core clock. Since, dtbinding is on a trasition phase to include
iface clock and clock-names, attaching the opp-table to core clock
remains options such that it does not cause probe failures.
Introduce clock scaling API qcom_ice_scale_clk which scale ICE
core clock based on the target frequency provided and if a valid
OPP-table is registered. Use round_ceil passed to decide on the
rounding of the clock freq against OPP-table. Clock scaling is
disabled when a valid OPP-table is not registered.
This ensures when an ICE-device specific OPP table is available,
use the PM OPP framework to manage frequency scaling and maintain
proper power-domain constraints.
Also, ensure to drop the votes in suspend to prevent power/thermal
retention. Subsequently restore the frequency in resume from
core_clk_freq which stores the last ICE core clock operating frequency.
Signed-off-by: Abhinaba Rakshit <abhinaba.rakshit@oss.qualcomm.com>
---
drivers/soc/qcom/ice.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/soc/qcom/ice.h | 2 ++
2 files changed, 94 insertions(+)
diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c
index bf4ab2d9e5c0360d8fe6135cc35f93b6b09e7a0e..9e869e6abc6300c7608b4d9a18e7f3e80c93f5e7 100644
--- a/drivers/soc/qcom/ice.c
+++ b/drivers/soc/qcom/ice.c
@@ -16,6 +16,7 @@
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
#include <linux/firmware/qcom/qcom_scm.h>
@@ -112,6 +113,8 @@ struct qcom_ice {
bool use_hwkm;
bool hwkm_init_complete;
u8 hwkm_version;
+ unsigned long core_clk_freq;
+ bool has_opp;
};
static bool qcom_ice_check_supported(struct qcom_ice *ice)
@@ -311,6 +314,10 @@ int qcom_ice_resume(struct qcom_ice *ice)
struct device *dev = ice->dev;
int err;
+ /* Restore the ICE core clk freq */
+ if (ice->has_opp && ice->core_clk_freq)
+ dev_pm_opp_set_rate(ice->dev, ice->core_clk_freq);
+
err = clk_prepare_enable(ice->core_clk);
if (err) {
dev_err(dev, "Failed to enable core clock: %d\n", err);
@@ -331,6 +338,11 @@ int qcom_ice_suspend(struct qcom_ice *ice)
{
clk_disable_unprepare(ice->iface_clk);
clk_disable_unprepare(ice->core_clk);
+
+ /* Drop the clock votes while suspend */
+ if (ice->has_opp)
+ dev_pm_opp_set_rate(ice->dev, 0);
+
ice->hwkm_init_complete = false;
return 0;
@@ -556,6 +568,51 @@ int qcom_ice_import_key(struct qcom_ice *ice,
}
EXPORT_SYMBOL_GPL(qcom_ice_import_key);
+/**
+ * qcom_ice_scale_clk() - Scale ICE clock for DVFS-aware operations
+ * @ice: ICE driver data
+ * @target_freq: requested frequency in Hz
+ * @round_ceil: when true, selects nearest freq >= @target_freq;
+ * otherwise, selects nearest freq <= @target_freq
+ *
+ * Selects an OPP frequency based on @target_freq and the rounding direction
+ * specified by @round_ceil, then programs it using dev_pm_opp_set_rate(),
+ * including any voltage or power-domain transitions handled by the OPP
+ * framework. Updates ice->core_clk_freq on success.
+ *
+ * Return: 0 on success; -EOPNOTSUPP if no OPP table; or error from
+ * dev_pm_opp_set_rate()/OPP lookup.
+ */
+int qcom_ice_scale_clk(struct qcom_ice *ice, unsigned long target_freq,
+ bool round_ceil)
+{
+ unsigned long ice_freq = target_freq;
+ struct dev_pm_opp *opp;
+ int ret;
+
+ if (!ice->has_opp)
+ return -EOPNOTSUPP;
+
+ if (round_ceil)
+ opp = dev_pm_opp_find_freq_ceil(ice->dev, &ice_freq);
+ else
+ opp = dev_pm_opp_find_freq_floor(ice->dev, &ice_freq);
+
+ if (IS_ERR(opp))
+ return PTR_ERR(opp);
+ dev_pm_opp_put(opp);
+
+ ret = dev_pm_opp_set_rate(ice->dev, ice_freq);
+ if (ret) {
+ dev_err(ice->dev, "Unable to scale ICE clock rate\n");
+ return ret;
+ }
+ ice->core_clk_freq = ice_freq;
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_ice_scale_clk);
+
static struct qcom_ice *qcom_ice_create(struct device *dev,
void __iomem *base)
{
@@ -731,6 +788,7 @@ static int qcom_ice_probe(struct platform_device *pdev)
{
struct qcom_ice *engine;
void __iomem *base;
+ int err;
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base)) {
@@ -742,6 +800,40 @@ static int qcom_ice_probe(struct platform_device *pdev)
if (IS_ERR(engine))
return PTR_ERR(engine);
+ /* qcom_ice_create() may return NULL if scm calls are not available */
+ if (!engine)
+ return -EOPNOTSUPP;
+
+ err = devm_pm_opp_set_clkname(&pdev->dev, "core");
+ if (err && err != -ENOENT) {
+ dev_err(&pdev->dev, "Unable to set core clkname to OPP-table\n");
+ return err;
+ }
+
+ /* OPP table is optional */
+ err = devm_pm_opp_of_add_table(&pdev->dev);
+ if (err && err != -ENODEV) {
+ dev_err(&pdev->dev, "Invalid OPP table in Device tree\n");
+ return err;
+ }
+
+ /*
+ * The OPP table is optional. devm_pm_opp_of_add_table() returns
+ * -ENODEV when no OPP table is present in DT, which is not treated
+ * as an error. Therefore, track successful OPP registration only
+ * when the return value is 0.
+ */
+ engine->has_opp = (err == 0);
+ if (!engine->has_opp)
+ dev_info(&pdev->dev, "ICE OPP table is not registered, please update your DT\n");
+
+ /*
+ * Store the core clock rate for suspend resume cycles,
+ * against OPP aware DVFS operations. core_clk_freq will
+ * have a valid value only for non-legacy bindings.
+ */
+ engine->core_clk_freq = clk_get_rate(engine->core_clk);
+
platform_set_drvdata(pdev, engine);
return 0;
diff --git a/include/soc/qcom/ice.h b/include/soc/qcom/ice.h
index 4bee553f0a59d86ec6ce20f7c7b4bce28a706415..4eb58a264d416e71228ed4b13e7f53c549261fdc 100644
--- a/include/soc/qcom/ice.h
+++ b/include/soc/qcom/ice.h
@@ -30,5 +30,7 @@ int qcom_ice_import_key(struct qcom_ice *ice,
const u8 *raw_key, size_t raw_key_size,
u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]);
struct qcom_ice *devm_of_qcom_ice_get(struct device *dev);
+int qcom_ice_scale_clk(struct qcom_ice *ice, unsigned long target_freq,
+ bool round_ceil);
#endif /* __QCOM_ICE_H__ */
--
2.34.1
^ permalink raw reply related
* [PATCH v8 0/5] Enable ICE clock scaling
From: Abhinaba Rakshit @ 2026-04-09 11:44 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Manivannan Sadhasivam,
James E.J. Bottomley, Martin K. Petersen, Adrian Hunter,
Ulf Hansson, Neeraj Soni, Harshal Dev, Kuldeep Singh, Rob Herring,
Krzysztof Kozlowski, Conor Dooley
Cc: linux-arm-msm, linux-kernel, linux-scsi, linux-mmc, devicetree,
Abhinaba Rakshit, Konrad Dybcio
Introduce support for dynamic clock scaling of the ICE (Inline Crypto Engine)
using the OPP framework. During ICE device probe, the driver now attempts to
parse an optional OPP table from the ICE-specific device tree node for
DVFS-aware operations. API qcom_ice_scale_clk is exposed by ICE driver
and is invoked by UFS host controller driver in response to clock scaling
requests, ensuring coordination between ICE and host controller.
For MMC controllers that do not support clock scaling, the ICE clock frequency
is kept aligned with the MMC controller’s clock rate (TURBO) to ensure
consistent operation.
Dynamic clock scaling based on OPP tables enables better power-performance
trade-offs. By adjusting ICE clock frequencies according to workload and power
constraints, the system can achieve higher throughput when needed and
reduce power consumption during idle or low-load conditions.
The OPP table remains optional, absence of the table will not cause
probe failure. However, in the absence of an OPP table, ICE clocks will
remain at their default rates, which may limit performance under
high-load scenarios or prevent performance optimizations during idle periods.
Testing:
* dtbs_check
* Validated on Rb3Gen2 and qcs8300-ride-sx
Merge Order and Dependencies
============================
Patch 2 is dependent on patch 1 for the qcom_ice_scale_clk API to be available.
Patch 3 is dependent on patch 1 for the qcom_ice_scale_clk API to be available.
Due to dependency, all patches should go through Qcom SoC tree.
This patchset supersedes earlier ICE clock scaling series (v1–v7) with updated dependencies.
Hence, this patchset also *Depends-On* the following patchseries:
[1] Add explicit clock vote and enable power-domain for QCOM-ICE
https://lore.kernel.org/linux-arm-msm/20260323-qcom_ice_power_and_clk_vote-v4-0-e36044bbdfe9@oss.qualcomm.com
[2] Enable Inline crypto engine for kodiak and monaco
https://lore.kernel.org/lkml/20260310113557.348502-1-neeraj.soni@oss.qualcomm.com/
[3] Enable iface clock and power domain for kodiak and monaco ice sdhc
https://lore.kernel.org/linux-arm-msm/20260409-ice_emmc_clock_addition-v2-0-90bbcc057361@oss.qualcomm.com/
Signed-off-by: Abhinaba Rakshit <abhinaba.rakshit@oss.qualcomm.com>
---
Changes in v8:
- Instead of scaling to TURBO in ICE probe, sdhci_msm_ice_init calls qcom_ice_scale_clk for setting freq to max.
- Fix error handling in qcom_ice_scale_clk.
- Fix error handling in ufs_qcom_clk_scale_notify for the call to qcom_ice_scale_clk.
- Move the registering of OPP-table to qcom_ice_probe and remove passing legacy_bindings argument to qcom_ice_create.
- Add OPP-table for kodiak and monaco ICE eMMC and UFS device nodes.
- Link to v7: https://lore.kernel.org/r/20260302-enable-ufs-ice-clock-scaling-v7-0-669b96ecadd8@oss.qualcomm.com
Changes in v7:
- Replace the custom rounding flags with 'bool round_ceil' as suggested.
- Update the dev_info log-line.
- Dropped dt-bindings patch (already applied by in previous patchseries).
- Add merge order and dependencies as suggested.
- Link to v6: https://lore.kernel.org/r/20260219-enable-ufs-ice-clock-scaling-v6-0-0c5245117d45@oss.qualcomm.com
Changes in v6:
- Remove scale_up parameter from qcom_ice_scale_clk API.
- Remove having max_freq and min_freq as the checks for overclocking and underclocking is no-longer needed.
- UFS driver passes rounding flags depending on scale_up value.
- Ensure UFS driver does not fail devfreq requests if ICE OPP is not supported.
- Link to v5: https://lore.kernel.org/all/20260211-enable-ufs-ice-clock-scaling-v5-0-221c520a1f2e@oss.qualcomm.com/
Changes in v5:
- Update operating-points-v2 property in dtbindings as suggested.
- Fix comment styles.
- Add argument in qcom_ice_create to distinguish between legacy bindings and newer bindings.
- Ensure to drop votes in suspend and enable the last vote in resume.
- Link to v4: https://lore.kernel.org/r/20260128-enable-ufs-ice-clock-scaling-v4-0-260141e8fce6@oss.qualcomm.com
Changes in v4:
- Enable multiple frequency scaling based OPP-entries as suggested in v3 patchset.
- Include bindings change: https://lore.kernel.org/all/20260123-add-operating-points-v2-property-for-qcom-ice-bindings-v1-1-2155f7aacc28@oss.qualcomm.com/.
- Link to v3: https://lore.kernel.org/r/20260123-enable-ufs-ice-clock-scaling-v3-0-d0d8532abd98@oss.qualcomm.com
Changes in v3:
- Avoid clock scaling in case of legacy bindings as suggested.
- Use of_device_is_compatible to distinguish between legacy and non-legacy bindings.
- Link to v2: https://lore.kernel.org/r/20251121-enable-ufs-ice-clock-scaling-v2-0-66cb72998041@oss.qualcomm.com
Changes in v2:
- Use OPP-table instead of freq-table-hz for clock scaling.
- Enable clock scaling for legacy targets as well, by fetching frequencies from storage opp-table.
- Introduce has_opp variable in qcom_ice structure to keep track, if ICE instance has dedicated OPP-table registered.
- Combined the changes for patch-series <20251001-set-ice-clock-to-turbo-v1-1-7b802cf61dda@oss.qualcomm.com> as suggested.
- Link to v1: https://lore.kernel.org/r/20251001-enable-ufs-ice-clock-scaling-v1-0-ec956160b696@oss.qualcomm.com
---
Abhinaba Rakshit (5):
soc: qcom: ice: Add OPP-based clock scaling support for ICE
ufs: host: Add ICE clock scaling during UFS clock changes
mmc: sdhci-msm: Set ICE clk to TURBO at sdhci ICE init
arm64: dts: qcom: kodiak: Add OPP-table for ICE UFS and ICE eMMC nodes
arm64: dts: qcom: monaco: Add OPP-table for ICE UFS and ICE eMMC nodes
arch/arm64/boot/dts/qcom/kodiak.dtsi | 42 ++++++++++++++++
arch/arm64/boot/dts/qcom/monaco.dtsi | 32 +++++++++++++
drivers/mmc/host/sdhci-msm.c | 24 ++++++++++
drivers/soc/qcom/ice.c | 92 ++++++++++++++++++++++++++++++++++++
drivers/ufs/host/ufs-qcom.c | 22 ++++++++-
include/soc/qcom/ice.h | 2 +
6 files changed, 213 insertions(+), 1 deletion(-)
---
base-commit: 95c541ddfb0815a0ea8477af778bb13bb075079a
change-id: 20260408-enable-ice-clock-scaling-5ca54ed63179
prerequisite-message-id: <20260323-qcom_ice_power_and_clk_vote-v4-0-e36044bbdfe9@oss.qualcomm.com>
prerequisite-patch-id: 1750aded4cac0105fbf943c5bfd9f844acf4f227
prerequisite-patch-id: 8cf945709b92296c73859515bb67820360d785a2
prerequisite-patch-id: bc8821cbbe222f208c5d86d96f3640c169b972d6
prerequisite-patch-id: a1baf04d3cce803fcb47b1a80591bf7759de8a76
prerequisite-patch-id: b7de0f216e54e264e054f6333b3067abce8d05c5
prerequisite-patch-id: 57f21e8a9505564caebbf89cafa9bd80be1dfe9f
prerequisite-patch-id: 5128586130e3f5847e0417de47ef755b2e2fba93
prerequisite-patch-id: fa46b7d6710907c5eb5ad01e84d28f09a0b26e5a
prerequisite-patch-id: e375d6e54a55c055f5d8673c65d35073df396646
prerequisite-patch-id: ec670d98300863c4b68155a3b0feeace56a4a55a
prerequisite-patch-id: c5ee690afd7f7105963e991dff760de62a403d9b
prerequisite-message-id: <20260310113557.348502-1-neeraj.soni@oss.qualcomm.com>
prerequisite-patch-id: ab9cc8bd28b2e1e27df6e44907e8d758dfeee3df
prerequisite-patch-id: 40f239f7f06573ed45452249f444e54e3565ada7
prerequisite-patch-id: 59129ed0aeba84f6b50f42261d51fe323806a240
prerequisite-message-id: <20260409-ice_emmc_clock_addition-v2-0-90bbcc057361@oss.qualcomm.com>
prerequisite-patch-id: 5b6a436bd949a93e44f912d2565103f6bf0ef55a
prerequisite-patch-id: 7f9ff2b708418a77578e154102f72f0da243eb71
Best regards,
--
Abhinaba Rakshit <abhinaba.rakshit@oss.qualcomm.com>
^ permalink raw reply
* Re: [PATCH v2 1/5] arm64: dts: qcom: sm8550: add PCIe MHI register regions
From: Joe Sandom @ 2026-04-09 11:41 UTC (permalink / raw)
To: Neil Armstrong
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <8ed5aeb8-98fb-4b87-a6a9-983e4fa91db5@linaro.org>
On Tue, Apr 07, 2026 at 07:38:54PM +0200, Neil Armstrong wrote:
> On 4/7/26 17:46, Joe Sandom wrote:
> > Add the MHI register regions to the pcie0 and pcie1 controller nodes
> > so that the MHI bus layer can access controller registers directly.
>
> Can you elaborate more on that ? Looking at the current implementation,
> the pcie host driver only uses the mhi memory zone to show the transition
> count in debugfs.
>
hmm yeah, you're right. As you said, it's only used for transition count
currently. I'll make sure the commit message is clearer in v3.
> Neil
>
> >
> > Signed-off-by: Joe Sandom <jsandom@axon.com>
> > ---
> > arch/arm64/boot/dts/qcom/sm8550.dtsi | 20 ++++++++++++++++----
> > 1 file changed, 16 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
> > index 912525e9bca6f5e1cbb8887ee0bf9e39650dc4ff..055ca931c04859f3a312eb9921aeb7a8cc676822 100644
> > --- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
> > +++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
> > @@ -1964,8 +1964,14 @@ pcie0: pcie@1c00000 {
> > <0 0x60000000 0 0xf1d>,
> > <0 0x60000f20 0 0xa8>,
> > <0 0x60001000 0 0x1000>,
> > - <0 0x60100000 0 0x100000>;
> > - reg-names = "parf", "dbi", "elbi", "atu", "config";
> > + <0 0x60100000 0 0x100000>,
> > + <0 0x01c03000 0 0x1000>;
> > + reg-names = "parf",
> > + "dbi",
> > + "elbi",
> > + "atu",
> > + "config",
> > + "mhi";
> > #address-cells = <3>;
> > #size-cells = <2>;
> > ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>,
> > @@ -2138,8 +2144,14 @@ pcie1: pcie@1c08000 {
> > <0x0 0x40000000 0x0 0xf1d>,
> > <0x0 0x40000f20 0x0 0xa8>,
> > <0x0 0x40001000 0x0 0x1000>,
> > - <0x0 0x40100000 0x0 0x100000>;
> > - reg-names = "parf", "dbi", "elbi", "atu", "config";
> > + <0x0 0x40100000 0x0 0x100000>,
> > + <0x0 0x01c0b000 0x0 0x1000>;
> > + reg-names = "parf",
> > + "dbi",
> > + "elbi",
> > + "atu",
> > + "config",
> > + "mhi";
> > #address-cells = <3>;
> > #size-cells = <2>;
> > ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
> >
>
^ permalink raw reply
* [PATCH v2 3/3] ARM: dts: aspeed: anacapa: add EVT2 devicetree and update wrapper
From: Colin Huang @ 2026-04-09 11:40 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
Andrew Jeffery
Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel,
colin.huang2, Colin Huang
In-Reply-To: <20260409-anacapa-devlop-phase-devicetree-v2-0-68f328671653@gmail.com>
Add a development-phase devicetree for the Facebook Anacapa BMC EVT2
hardware revision and update the Anacapa wrapper DTS to reference
it.
Signed-off-by: Colin Huang <u8813345@gmail.com>
---
.../aspeed/aspeed-bmc-facebook-anacapa-evt2.dts | 1123 ++++++++++++++++++++
.../dts/aspeed/aspeed-bmc-facebook-anacapa.dts | 2 +-
2 files changed, 1124 insertions(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa-evt2.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa-evt2.dts
new file mode 100644
index 000000000000..6e1e51e6c3f2
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa-evt2.dts
@@ -0,0 +1,1123 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/dts-v1/;
+#include "aspeed-g6.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/i2c/i2c.h>
+
+/ {
+ model = "Facebook Anacapa BMC";
+ compatible = "facebook,anacapa-bmc-evt2", "aspeed,ast2600";
+
+ aliases {
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ i2c16 = &i2c0mux0ch0;
+ i2c17 = &i2c0mux0ch1;
+ i2c18 = &i2c0mux0ch2;
+ i2c19 = &i2c0mux0ch3;
+ i2c20 = &i2c1mux0ch0;
+ i2c21 = &i2c1mux0ch1;
+ i2c22 = &i2c1mux0ch2;
+ i2c23 = &i2c1mux0ch3;
+ i2c24 = &i2c4mux0ch0;
+ i2c25 = &i2c4mux0ch1;
+ i2c26 = &i2c4mux0ch2;
+ i2c27 = &i2c4mux0ch3;
+ i2c28 = &i2c4mux0ch4;
+ i2c29 = &i2c4mux0ch5;
+ i2c30 = &i2c4mux0ch6;
+ i2c31 = &i2c4mux0ch7;
+ i2c32 = &i2c8mux0ch0;
+ i2c33 = &i2c8mux0ch1;
+ i2c34 = &i2c8mux0ch2;
+ i2c35 = &i2c8mux0ch3;
+ i2c36 = &i2c10mux0ch0;
+ i2c37 = &i2c10mux0ch1;
+ i2c38 = &i2c10mux0ch2;
+ i2c39 = &i2c10mux0ch3;
+ i2c40 = &i2c10mux0ch4;
+ i2c41 = &i2c10mux0ch5;
+ i2c42 = &i2c10mux0ch6;
+ i2c43 = &i2c10mux0ch7;
+ i2c44 = &i2c11mux0ch0;
+ i2c45 = &i2c11mux0ch1;
+ i2c46 = &i2c11mux0ch2;
+ i2c47 = &i2c11mux0ch3;
+ i2c48 = &i2c11mux0ch4;
+ i2c49 = &i2c11mux0ch5;
+ i2c50 = &i2c11mux0ch6;
+ i2c51 = &i2c11mux0ch7;
+ i2c52 = &i2c13mux0ch0;
+ i2c53 = &i2c13mux0ch1;
+ i2c54 = &i2c13mux0ch2;
+ i2c55 = &i2c13mux0ch3;
+ i2c56 = &i2c13mux0ch4;
+ i2c57 = &i2c13mux0ch5;
+ i2c58 = &i2c13mux0ch6;
+ i2c59 = &i2c13mux0ch7;
+ };
+
+ chosen {
+ stdout-path = "serial4:57600n8";
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>,
+ <&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>,
+ <&adc1 2>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ label = "bmc_heartbeat_amber";
+ gpios = <&gpio0 ASPEED_GPIO(P, 7) GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ led-1 {
+ label = "fp_id_amber";
+ default-state = "off";
+ gpios = <&gpio0 ASPEED_GPIO(B, 5) GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x80000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ video_engine_memory: video {
+ size = <0x02c00000>;
+ alignment = <0x00100000>;
+ compatible = "shared-dma-pool";
+ reusable;
+ };
+
+ gfx_memory: framebuffer {
+ size = <0x01000000>;
+ alignment = <0x01000000>;
+ compatible = "shared-dma-pool";
+ reusable;
+ };
+ };
+
+ p3v3_bmc_aux: regulator-p3v3-bmc-aux {
+ compatible = "regulator-fixed";
+ regulator-name = "p3v3_bmc_aux";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ spi_gpio: spi {
+ compatible = "spi-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sck-gpios = <&gpio0 ASPEED_GPIO(Z, 3) GPIO_ACTIVE_HIGH>;
+ mosi-gpios = <&gpio0 ASPEED_GPIO(Z, 4) GPIO_ACTIVE_HIGH>;
+ miso-gpios = <&gpio0 ASPEED_GPIO(Z, 5) GPIO_ACTIVE_HIGH>;
+ num-chipselects = <1>;
+ cs-gpios = <&gpio0 ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>;
+ status = "okay";
+
+ tpm@0 {
+ compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
+ spi-max-frequency = <33000000>;
+ reg = <0>;
+ };
+ };
+};
+
+&adc0 {
+ aspeed,int-vref-microvolt = <2500000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0_default &pinctrl_adc1_default
+ &pinctrl_adc2_default &pinctrl_adc3_default
+ &pinctrl_adc4_default &pinctrl_adc5_default
+ &pinctrl_adc6_default &pinctrl_adc7_default>;
+ status = "okay";
+};
+
+&adc1 {
+ aspeed,int-vref-microvolt = <2500000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc10_default>;
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&fmc {
+ status = "okay";
+
+ flash@0 {
+ status = "okay";
+ m25p,fast-read;
+ label = "bmc";
+ spi-max-frequency = <50000000>;
+#include "openbmc-flash-layout-128.dtsi"
+ };
+
+ flash@1 {
+ status = "okay";
+ m25p,fast-read;
+ label = "alt-bmc";
+ spi-max-frequency = <50000000>;
+ };
+};
+
+&gfx {
+ status = "okay";
+ memory-region = <&gfx_memory>;
+};
+
+&gpio0 {
+ gpio-line-names =
+
+ /*A0-A7*/
+ "","","","","","","","",
+
+ /*B0-B7*/
+ "BATTERY_DETECT", "",
+ "BMC_I2C1_FPGA_ALERT", "BMC_READY",
+ "IOEXP_INT_3V3", "FM_ID_LED",
+ "", "",
+
+ /*C0-C7*/
+ "","","","",
+ "PMBUS_REQ_N", "PSU_FW_UPDATE_REQ_N",
+ "", "",
+
+ /*D0-D7*/
+ "","","","","","","","",
+
+ /*E0-E7*/
+ "","","","","","","","",
+
+ /*F0-F7*/
+ "","","","","","","","",
+
+ /*G0-G7*/
+ "FM_MUX1_SEL", "",
+ "", "", "", "",
+ "FM_DEBUG_PORT_PRSNT_N", "FM_BMC_DBP_PRESENT_N",
+
+ /*H0-H7*/
+ "","","","","","","","",
+
+ /*I0-I7*/
+ "","","","",
+ "", "FLASH_WP_STATUS",
+ "BMC_JTAG_MUX_SEL", "",
+
+ /*J0-J7*/
+ "","","","","","","","",
+
+ /*K0-K7*/
+ "","","","","","","","",
+
+ /*L0-L7*/
+ "","","","","","","","",
+
+ /*M0-M7*/
+ "PCIE_EP_RST_EN", "BMC_FRU_WP",
+ "SCM_HPM_STBY_RST_N", "SCM_HPM_STBY_EN",
+ "STBY_POWER_PG_3V3", "TH500_SHDN_OK",
+ "", "",
+
+ /*N0-N7*/
+ "LED_POSTCODE_0", "LED_POSTCODE_1",
+ "LED_POSTCODE_2", "LED_POSTCODE_3",
+ "LED_POSTCODE_4", "LED_POSTCODE_5",
+ "LED_POSTCODE_6", "LED_POSTCODE_7",
+
+ /*O0-O7*/
+ "RUN_POWER_PG", "PWR_BRAKE",
+ "CHASSIS_AC_LOSS", "BSM_PRSNT_N",
+ "PSU_SMB_ALERT", "FM_TPM_PRSNT_0_N",
+ "PSU_FW_UPDATING_N", "",
+
+ /*P0-P7*/
+ "PWR_BTN_BMC_BUF_N", "IPEX_CABLE_PRSNT",
+ "ID_RST_BTN_BMC_N", "RST_BMC_RSTBTN_OUT_N",
+ "PWR_LED", "RUN_POWER_EN",
+ "SHDN_FORCE", "BMC_HEARTBEAT_N",
+
+ /*Q0-Q7*/
+ "IRQ_PCH_TPM_SPI_LV3_N", "USB_OC0_REAR_N",
+ "UART_MUX_SEL", "I2C_MUX_RESET",
+ "RSVD_NV_PLT_DETECT", "SPI_TPM_INT",
+ "CPU_JTAG_MUX_SELECT", "THERM_BB_OVERT",
+
+ /*R0-R7*/
+ "THERM_BB_WARN", "SPI_BMC_FPGA_INT",
+ "CPU_BOOT_DONE", "PMBUS_GNT",
+ "CHASSIS_PWR_BRK", "PCIE_WAKE",
+ "PDB_THERM_OVERT", "SHDN_REQ",
+
+ /*S0-S7*/
+ "", "",
+ "SYS_BMC_PWRBTN_N", "FM_TPM_PRSNT_1_N",
+ "FM_BMC_DEBUG_SW_N", "UID_LED_N",
+ "SYS_FAULT_LED_N", "RUN_POWER_FAULT",
+
+ /*T0-T7*/
+ "","","","","","","","",
+
+ /*U0-U7*/
+ "","","","","","","","",
+
+ /*V0-V7*/
+ "L2_RST_REQ_OUT", "L0L1_RST_REQ_OUT",
+ "BMC_ID_BEEP_SEL", "BMC_I2C0_FPGA_ALERT",
+ "SMB_BMC_TMP_ALERT", "PWR_LED_N",
+ "SYS_RST_OUT", "IRQ_TPM_SPI_N",
+
+ /*W0-W7*/
+ "","","","","","","","",
+
+ /*X0-X7*/
+ "","","","","","","","",
+
+ /*Y0-Y7*/
+ "RST_WDTRST_PLD_N", "RST_BMC_SELF_HW",
+ "FM_FLASH_LATCH_N", "BMC_EMMC_RST_N",
+ "","","","",
+
+ /*Z0-Z7*/
+ "","","","","","","","";
+};
+
+&gpio1 {
+ gpio-line-names =
+ /*18A0-18A7*/
+ "","","","","","","","",
+
+ /*18B0-18B7*/
+ "","","","",
+ "FM_BOARD_BMC_REV_ID0", "FM_BOARD_BMC_REV_ID1",
+ "FM_BOARD_BMC_REV_ID2", "",
+
+ /*18C0-18C7*/
+ "", "", "SPI_BMC_BIOS_ROM_IRQ0_N", "",
+ "", "", "", "",
+
+ /*18D0-18D7*/
+ "","","","","","","","",
+
+ /*18E0-18E3*/
+ "FM_BMC_PROT_LS_EN", "AC_PWR_BMC_BTN_N", "", "";
+};
+
+// L Bridge Board
+&i2c0 {
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "atmel,24c2048";
+ reg = <0x50>;
+ pagesize = <128>;
+ };
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9546";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c0mux0ch0: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c0mux0ch1: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c0mux0ch2: i2c@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c0mux0ch3: i2c@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+// R Bridge Board
+&i2c1 {
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "atmel,24c2048";
+ reg = <0x50>;
+ pagesize = <128>;
+ };
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9546";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c1mux0ch0: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c1mux0ch1: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c1mux0ch2: i2c@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c1mux0ch3: i2c@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+// MB - E1.S
+&i2c4 {
+ status = "okay";
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9548";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c4mux0ch0: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c4mux0ch1: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c4mux0ch2: i2c@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c4mux0ch3: i2c@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c4mux0ch4: i2c@4 {
+ reg = <4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c4mux0ch5: i2c@5 {
+ reg = <5>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c4mux0ch6: i2c@6 {
+ reg = <6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c4mux0ch7: i2c@7 {
+ reg = <7>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+// AMC
+&i2c5 {
+ status = "okay";
+};
+
+// MB
+&i2c6 {
+ status = "okay";
+
+ // HPM FRU
+ eeprom@50 {
+ compatible = "atmel,24c256";
+ reg = <0x50>;
+ };
+};
+
+// SCM
+&i2c7 {
+ status = "okay";
+
+
+};
+
+// MB - PDB
+&i2c8 {
+ status = "okay";
+
+ i2c-mux@72 {
+ compatible = "nxp,pca9546";
+ reg = <0x72>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c8mux0ch0: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ adc@1f {
+ compatible = "ti,adc128d818";
+ reg = <0x1f>;
+ ti,mode = /bits/ 8 <1>;
+ };
+
+ gpio@22 {
+ compatible = "nxp,pca9555";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "RPDB_FAN_FULL_SPEED_R_N", "RPDB_I2C_TEMP75_U8_ALERT_R_N",
+ "RPDB_I2C_TMP432_U29_ALERT_R_N", "RPDB_GLOBAL_WP",
+ "RPDB_FAN_CT_FAN_FAIL_R_N", "",
+ "", "",
+ "RPDB_ALERT_P50V_HSC2_R_N", "RPDB_ALERT_P50V_HSC3_R_N",
+ "RPDB_ALERT_P50V_HSC4_R_N", "RPDB_ALERT_P50V_STBY_R_N",
+ "RPDB_I2C_P12V_MB_VRM_ALERT_R_N",
+ "RPDB_I2C_P12V_STBY_VRM_ALERT_R_N",
+ "RPDB_PGD_P3V3_STBY_PWRGD_R",
+ "RPDB_P12V_STBY_VRM_PWRGD_BUF_R";
+ };
+
+ gpio@24 {
+ compatible = "nxp,pca9555";
+ reg = <0x24>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "RPDB_EAM2_PRSNT_MOS_N_R", "RPDB_EAM3_PRSNT_MOS_N_R",
+ "RPDB_PWRGD_P50V_HSC4_SYS_R",
+ "RPDB_PWRGD_P50V_STBY_SYS_BUF_R",
+ "RPDB_P50V_FAN1_R2_PG", "RPDB_P50V_FAN2_R2_PG",
+ "RPDB_P50V_FAN3_R2_PG", "RPDB_P50V_FAN4_R2_PG",
+ "", "RPDB_FAN1_PRSNT_N_R",
+ "", "RPDB_FAN2_PRSNT_N_R",
+ "RPDB_FAN3_PRSNT_N_R", "RPDB_FAN4_PRSNT_N_R",
+ "", "";
+ };
+
+ // R-PDB FRU
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+ };
+ i2c8mux0ch1: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio@22 {
+ compatible = "nxp,pca9555";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "LPDB_FAN_FULL_SPEED_R_N","LPDB_I2C_TEMP75_U8_ALERT_R_N",
+ "LPDB_I2C_TMP432_U29_ALERT_R_N","LPDB_GLOBAL_WP",
+ "LPDB_FAN_CT_FAN_FAIL_R_N","",
+ "","",
+ "LPDB_ALERT_P50V_HSC0_R_N","LPDB_ALERT_P50V_HSC1_R_N",
+ "LPDB_ALERT_P50V_HSC5_R_N","LPDB_I2C_P12V_SW_VRM_ALERT_R_N",
+ "LPDB_EAM0_PRSNT_MOS_N_R","LPDB_EAM1_PRSNT_MOS_N_R",
+ "LPDB_PWRGD_P50V_HSC5_SYS_R","";
+ };
+
+ gpio@24 {
+ compatible = "nxp,pca9555";
+ reg = <0x24>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "LPDB_P50V_FAN1_R2_PG","LPDB_P50V_FAN2_R2_PG",
+ "LPDB_P50V_FAN3_R2_PG","LPDB_P50V_FAN4_R2_PG",
+ "LPDB_P50V_FAN5_R2_PG","LPDB_FAN1_PRSNT_N_R",
+ "LPDB_FAN2_PRSNT_N_R","LPDB_FAN3_PRSNT_N_R",
+ "LPDB_FAN4_PRSNT_N_R","LPDB_FAN5_PRSNT_N_R",
+ "","",
+ "","",
+ "","";
+ };
+
+ // L-PDB FRU
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+ };
+ i2c8mux0ch2: i2c@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c8mux0ch3: i2c@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+// SCM
+&i2c9 {
+ status = "okay";
+
+ // SCM FRU
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+
+ eeprom@51 {
+ compatible = "atmel,24c128";
+ reg = <0x51>;
+ };
+
+ // BSM FRU
+ eeprom@56 {
+ compatible = "atmel,24c64";
+ reg = <0x56>;
+ };
+};
+
+// R Bridge Board
+&i2c10 {
+ status = "okay";
+
+ i2c-mux@71 {
+ compatible = "nxp,pca9548";
+ reg = <0x71>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c10mux0ch0: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c10mux0ch1: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c10mux0ch2: i2c@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c10mux0ch3: i2c@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c10mux0ch4: i2c@4 {
+ reg = <4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c10mux0ch5: i2c@5 {
+ reg = <5>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio@22 {
+ compatible = "nxp,pca9555";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "","",
+ "","RBB_CPLD_REFRESH_IN_PRGRS_R_L",
+ "RBB_EAM0_NIC_CBL_PRSNT_R_L","RBB_EAM1_NIC_CBL_PRSNT_R_L",
+ "RBB_AINIC_JTAG_MUX_R2_SEL","RBB_SPI_MUX0_R2_SEL",
+ "RBB_AINIC_PRSNT_R_L","RBB_AINIC_OE_R_N",
+ "RBB_AINIC_BOARD_R2_ID","RBB_RST_USB2_HUB_R_N",
+ "RBB_RST_FT4222_R_N","RBB_RST_MCP2210_R_N",
+ "","";
+ };
+
+ // R Bridge Board FRU
+ eeprom@52 {
+ compatible = "atmel,24c256";
+ reg = <0x52>;
+ };
+ };
+ i2c10mux0ch6: i2c@6 {
+ reg = <6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c10mux0ch7: i2c@7 {
+ reg = <7>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+// L Bridge Board
+&i2c11 {
+ status = "okay";
+
+ i2c-mux@71 {
+ compatible = "nxp,pca9548";
+ reg = <0x71>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c11mux0ch0: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c11mux0ch1: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c11mux0ch2: i2c@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c11mux0ch3: i2c@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c11mux0ch4: i2c@4 {
+ reg = <4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c11mux0ch5: i2c@5 {
+ reg = <5>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio@22 {
+ compatible = "nxp,pca9555";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "","",
+ "","LBB_CPLD_REFRESH_IN_PRGRS_R_L",
+ "LBB_EAM0_NIC_CBL_PRSNT_R_L","LBB_EAM1_NIC_CBL_PRSNT_R_L",
+ "LBB_AINIC_JTAG_MUX_R2_SEL","LBB_SPI_MUX0_R2_SEL",
+ "LBB_AINIC_PRSNT_R_L","LBB_AINIC_OE_R_N",
+ "LBB_AINIC_BOARD_R2_ID","LBB_RST_USB2_HUB_R_N",
+ "LBB_RST_FT4222_R_N","LBB_RST_MCP2210_R_N",
+ "","";
+ };
+
+ // L Bridge Board FRU
+ eeprom@52 {
+ compatible = "atmel,24c256";
+ reg = <0x52>;
+ };
+ };
+ i2c11mux0ch6: i2c@6 {
+ reg = <6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c11mux0ch7: i2c@7 {
+ reg = <7>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+// Debug Card
+&i2c12 {
+ status = "okay";
+};
+
+// MB
+&i2c13 {
+ status = "okay";
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9548";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c13mux0ch0: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c13mux0ch1: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c13mux0ch2: i2c@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c13mux0ch3: i2c@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ adc@1f {
+ compatible = "ti,adc128d818";
+ reg = <0x1f>;
+ ti,mode = /bits/ 8 <1>;
+ };
+ };
+ i2c13mux0ch4: i2c@4 {
+ reg = <4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ // HPM BRD ID FRU
+ eeprom@51 {
+ compatible = "atmel,24c256";
+ reg = <0x51>;
+ };
+ };
+ i2c13mux0ch5: i2c@5 {
+ reg = <5>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c13mux0ch6: i2c@6 {
+ reg = <6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c13mux0ch7: i2c@7 {
+ reg = <7>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ nfc@28 {
+ compatible = "nxp,nxp-nci-i2c";
+ reg = <0x28>;
+
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <156 IRQ_TYPE_LEVEL_HIGH>;
+
+ enable-gpios = <&sgpiom0 241 GPIO_ACTIVE_HIGH>;
+ };
+ };
+ };
+};
+
+// SCM
+&i2c14 {
+ status = "okay";
+};
+
+&i2c15 {
+ status = "okay";
+};
+
+&kcs2 {
+ aspeed,lpc-io-reg = <0xca8>;
+ status = "okay";
+};
+
+&kcs3 {
+ aspeed,lpc-io-reg = <0xca2>;
+ status = "okay";
+};
+
+&lpc_ctrl {
+ status = "okay";
+};
+
+&mac2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ncsi3_default>;
+ use-ncsi;
+};
+
+&sgpiom0 {
+ ngpios = <128>;
+ bus-frequency = <2000000>;
+ gpio-line-names =
+ /*in - out */
+ /* A0-A7 line 0-15 */
+ "L_FNIC_FLT", "FM_CPU0_SYS_RESET_N",
+ "L_BNIC0_FLT", "CPU0_KBRST_N",
+ "L_BNIC1_FLT", "FM_CPU0_PROCHOT_trigger_N",
+ "L_BNIC2_FLT", "FM_CLR_CMOS_R_P0",
+ "L_BNIC3_FLT", "Force_I3C_SEL",
+ "L_RTM_SW_FLT", "SYSTEM_Force_Run_AC_Cycle",
+ "", "",
+ "", "",
+
+ /* B0-B7 line 16-31 */
+ "Channel0_leakage_EAM3", "FM_CPU_FPGA_JTAG_MUX_SEL",
+ "Channel1_leakage_EAM0", "FM_SCM_JTAG_MUX_SEL",
+ "Channel2_leakage_Manifold1", "FM_BRIDGE_JTAG_MUX_SEL",
+ "Channel3_leakage", "FM_CPU0_NMI_SYNC_FLOOD_N",
+ "Channel4_leakage_Manifold2", "BMC_AINIC0_WP_R2_L",
+ "Channel5_leakage_EAM1", "BMC_AINIC1_WP_R2_L",
+ "Channel6_leakage_CPU_DIMM", "CPLD_BUF_R_AGPIO330",
+ "Channel7_leakage_EAM2", "CPLD_BUF_R_AGPIO331",
+
+ /* C0-C7 line 32-47 */
+ "RSVD_RMC_GPIO3", "RTM_MUX_L",
+ "LEAK_DETECT_RMC_N", "RTM_MUX_R",
+ "HDR_P0_NMI_BTN_BUF_R_N", "FPGA_JTAG_SCM_DBREQ_N",
+ "No_Leak_Sensor_flag", "whdt_sel",
+ "", "",
+ "", "",
+ "", "",
+ "", "",
+
+ /* D0-D7 line 48-63 */
+ "PWRGD_CHAD_CPU0_FPGA", "",
+ "PWRGD_CHEH_CPU0_FPGA", "",
+ "PWRGD_CHIL_CPU0_FPGA", "",
+ "PWRGD_CHMP_CPU0_FPGA", "",
+ "AMC_BRD_PRSNT_CPLD_L", "",
+ "", "",
+ "", "",
+ "", "",
+
+ /* E0-E7 line 64-79 */
+ "L_PRSNT_B_FENIC_R2_N", "",
+ "L_PRSNT_B_BENIC0_R2_N", "",
+ "L_PRSNT_B_BENIC1_R2_N", "",
+ "L_PRSNT_B_BENIC2_R2_N", "",
+ "L_PRSNT_B_BENIC3_R2_N", "",
+ "", "",
+ "", "",
+ "", "",
+
+ /* F0-F7 line 80-95 */
+ "R_PRSNT_B_FENIC_R2_N", "SGPIO_READY",
+ "R_PRSNT_B_BENIC0_R2_N", "",
+ "R_PRSNT_B_BENIC1_R2_N", "",
+ "R_PRSNT_B_BENIC2_R2_N", "",
+ "R_PRSNT_B_BENIC3_R2_N", "",
+ "", "",
+ "", "",
+ "", "",
+
+ /* G0-G7 line 96-111 */
+ "L_PRSNT_EDSFF2_N", "",
+ "L_PRSNT_EDSFF3_N", "",
+ "R_PRSNT_EDSFF2_N", "",
+ "R_PRSNT_EDSFF3_N", "",
+ "", "",
+ "", "",
+ "", "",
+ "PRSNT_NFC_BOARD_R", "",
+
+ /* H0-H7 line 112-127 */
+ "R_FNIC_FLT", "",
+ "R_BNIC0_FLT", "",
+ "R_BNIC1_FLT", "",
+ "R_BNIC2_FLT", "",
+ "R_BNIC3_FLT", "",
+ "R_RTM_SW_FLT", "",
+ "", "",
+ "", "",
+
+ /* I0-I7 line 128-143 */
+ "EAM0_BRD_PRSNT_R_L", "",
+ "EAM1_BRD_PRSNT_R_L", "",
+ "EAM2_BRD_PRSNT_R_L", "",
+ "EAM3_BRD_PRSNT_R_L", "",
+ "FM_TPM_PRSNT_R_N", "",
+ "PDB_PRSNT_R_N", "",
+ "PRSNT_EDSFF0_N", "",
+ "PRSNT_CPU0_N", "",
+
+ /* J0-J7 line 144-159 */
+ "PRSNT_L_BRIDGE_R", "",
+ "PRSNT_R_BRIDGE_R", "",
+ "BRIDGE_L_MAIN_PG_R", "",
+ "BRIDGE_R_MAIN_PG_R", "",
+ "BRIDGE_L_STBY_PG_R", "",
+ "BRIDGE_R_STBY_PG_R", "",
+ "IRQ_NFC_BOARD_R", "",
+ "RSMRST_N", "",
+
+ /* K0-K7 line 160-175 */
+ "ADC_I2C_ALERT_N", "",
+ "TEMP_I2C_ALERT_R_L", "",
+ "CPU0_VR_SMB_ALERT_CPLD_N", "",
+ "COVER_INTRUDER_R_N", "",
+ "HANDLE_INTRUDER_CPLD_N", "",
+ "IRQ_MCIO_CPLD_WAKE_R_N", "",
+ "APML_CPU0_ALERT_R_N", "",
+ "PDB_ALERT_R_N", "",
+
+ /* L0-L7 line 176-191 */
+ "CPU0_SP7R1", "",
+ "CPU0_SP7R2", "",
+ "CPU0_SP7R3", "",
+ "CPU0_SP7R4", "",
+ "CPU0_CORETYPE0", "",
+ "CPU0_CORETYPE1", "",
+ "CPU0_CORETYPE2", "",
+ "FM_BIOS_POST_CMPLT_R_N", "",
+
+ /* M0-M7 line 192-207 */
+ "EAM0_SMERR_CPLD_R_L", "",
+ "EAM1_SMERR_CPLD_R_L", "",
+ "EAM2_SMERR_CPLD_R_L", "",
+ "EAM3_SMERR_CPLD_R_L", "",
+ "CPU0_SMERR_N_R", "",
+ "CPU0_NV_SAVE_N_R", "",
+ "PDB_PWR_LOSS_CPLD_N", "",
+ "IRQ_BMC_SMI_ACTIVE_R_N", "",
+
+ /* N0-N7 line 208-223 */
+ "AMCROT_BMC_S5_RDY_R", "",
+ "AMC_RDY_R", "",
+ "AMC_STBY_PGOOD_R", "",
+ "CPU_AMC_SLP_S5_R_L", "",
+ "AMC_CPU_EAMPG_R", "",
+ "DIMM_PMIC_PG_TIMEOUT", "",
+ "EAM_MOD_PWR_GD_TIMEOUT", "",
+ "CPLD_AMC_STBY_PWR_EN", "",
+
+ /* O0-O7 line 224-239 */
+ "HPM_PWR_FAIL", "Port80_b0",
+ "FM_DIMM_IP_FAIL", "Port80_b1",
+ "FM_DIMM_AH_FAIL", "Port80_b2",
+ "HPM_AMC_THERMTRIP_R_L", "Port80_b3",
+ "cpu_thermtrip_detect", "Port80_b4",
+ "PVDDCR_SOC_P0_OCP_L", "Port80_b5",
+ "CPLD_SGPIO_RDY", "Port80_b6",
+ "FM_MAIN_PWREN_RMC_EN_ISO", "Port80_b7",
+
+ /* P0-P7 line 240-255 */
+ "CPU0_SLP_S5_N_R", "NFC_VEN",
+ "CPU0_SLP_S3_N_R", "",
+ "FM_CPU0_PWRGD", "",
+ "PWRGD_RMC", "",
+ "FM_RST_CPU0_RESET_N", "RBB_CPLD_RISCV_RST",
+ "FM_PWRGD_CPU0_PWROK", "LBB_CPLD_RISCV_RST",
+ "AMC_FAIL", "HPM_CPLD_RISCV_RST",
+ "wS0_ON_N", "";
+ status = "okay";
+};
+
+// BIOS Flash
+&spi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi2_default>;
+ status = "okay";
+ reg = <0x1e631000 0xc4>, <0x50000000 0x8000000>;
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ label = "pnor";
+ spi-max-frequency = <12000000>;
+ spi-tx-bus-width = <2>;
+ spi-rx-bus-width = <2>;
+ status = "okay";
+ };
+};
+
+// HOST BIOS Debug
+&uart1 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&uart4 {
+ status = "okay";
+};
+
+// BMC Debug Console
+&uart5 {
+ status = "okay";
+};
+
+&uart_routing {
+ status = "okay";
+};
+
+&uhci {
+ status = "okay";
+};
+
+&vhub {
+ status = "okay";
+ pinctrl-names = "default";
+};
+
+&video {
+ status = "okay";
+ memory-region = <&video_engine_memory>;
+};
+
+&wdt1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdtrst1_default>;
+ aspeed,reset-type = "soc";
+ aspeed,external-signal;
+ aspeed,ext-push-pull;
+ aspeed,ext-active-high;
+ aspeed,ext-pulse-duration = <256>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa.dts
index 980628af80b0..18b6a7525178 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa.dts
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/dts-v1/;
-#include "aspeed-bmc-facebook-anacapa-evt1.dts"
+#include "aspeed-bmc-facebook-anacapa-evt2.dts"
--
2.34.1
^ permalink raw reply related
* [PATCH v2 2/3] ARM: dts: aspeed: anacapa: add EVT1 devicetree and point wrapper to it
From: Colin Huang @ 2026-04-09 11:40 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
Andrew Jeffery
Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel,
colin.huang2, Colin Huang
In-Reply-To: <20260409-anacapa-devlop-phase-devicetree-v2-0-68f328671653@gmail.com>
This change introduces a development-phase devicetree for the
Facebook Anacapa BMC EVT1 hardware revision and updates the Anacapa
wrapper DTS to reference it.
A dedicated EVT1 DTS is added for revision-specific hardware while
keeping a single, Anacapa entrypoint used by the build and deployment
flow. The top-level aspeed-bmc-facebook-anacapa.dts
Signed-off-by: Colin Huang <u8813345@gmail.com>
---
.../aspeed/aspeed-bmc-facebook-anacapa-evt1.dts | 1067 ++++++++++++++++++++
.../dts/aspeed/aspeed-bmc-facebook-anacapa.dts | 1064 +------------------
2 files changed, 1068 insertions(+), 1063 deletions(-)
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa-evt1.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa-evt1.dts
new file mode 100644
index 000000000000..81ad065e114c
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa-evt1.dts
@@ -0,0 +1,1067 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/dts-v1/;
+#include "aspeed-g6.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/i2c/i2c.h>
+
+/ {
+ model = "Facebook Anacapa BMC";
+ compatible = "facebook,anacapa-bmc-evt1", "aspeed,ast2600";
+
+ aliases {
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ i2c16 = &i2c0mux0ch0;
+ i2c17 = &i2c0mux0ch1;
+ i2c18 = &i2c0mux0ch2;
+ i2c19 = &i2c0mux0ch3;
+ i2c20 = &i2c1mux0ch0;
+ i2c21 = &i2c1mux0ch1;
+ i2c22 = &i2c1mux0ch2;
+ i2c23 = &i2c1mux0ch3;
+ i2c24 = &i2c4mux0ch0;
+ i2c25 = &i2c4mux0ch1;
+ i2c26 = &i2c4mux0ch2;
+ i2c27 = &i2c4mux0ch3;
+ i2c28 = &i2c4mux0ch4;
+ i2c29 = &i2c4mux0ch5;
+ i2c30 = &i2c4mux0ch6;
+ i2c31 = &i2c4mux0ch7;
+ i2c32 = &i2c8mux0ch0;
+ i2c33 = &i2c8mux0ch1;
+ i2c34 = &i2c8mux0ch2;
+ i2c35 = &i2c8mux0ch3;
+ i2c36 = &i2c10mux0ch0;
+ i2c37 = &i2c10mux0ch1;
+ i2c38 = &i2c10mux0ch2;
+ i2c39 = &i2c10mux0ch3;
+ i2c40 = &i2c10mux0ch4;
+ i2c41 = &i2c10mux0ch5;
+ i2c42 = &i2c10mux0ch6;
+ i2c43 = &i2c10mux0ch7;
+ i2c44 = &i2c11mux0ch0;
+ i2c45 = &i2c11mux0ch1;
+ i2c46 = &i2c11mux0ch2;
+ i2c47 = &i2c11mux0ch3;
+ i2c48 = &i2c11mux0ch4;
+ i2c49 = &i2c11mux0ch5;
+ i2c50 = &i2c11mux0ch6;
+ i2c51 = &i2c11mux0ch7;
+ i2c52 = &i2c13mux0ch0;
+ i2c53 = &i2c13mux0ch1;
+ i2c54 = &i2c13mux0ch2;
+ i2c55 = &i2c13mux0ch3;
+ i2c56 = &i2c13mux0ch4;
+ i2c57 = &i2c13mux0ch5;
+ i2c58 = &i2c13mux0ch6;
+ i2c59 = &i2c13mux0ch7;
+ };
+
+ chosen {
+ stdout-path = "serial4:57600n8";
+ };
+
+ iio-hwmon {
+ compatible = "iio-hwmon";
+ io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>,
+ <&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>,
+ <&adc1 2>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ label = "bmc_heartbeat_amber";
+ gpios = <&gpio0 ASPEED_GPIO(P, 7) GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ led-1 {
+ label = "fp_id_amber";
+ default-state = "off";
+ gpios = <&gpio0 ASPEED_GPIO(B, 5) GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x80000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ video_engine_memory: video {
+ size = <0x02c00000>;
+ alignment = <0x00100000>;
+ compatible = "shared-dma-pool";
+ reusable;
+ };
+
+ gfx_memory: framebuffer {
+ size = <0x01000000>;
+ alignment = <0x01000000>;
+ compatible = "shared-dma-pool";
+ reusable;
+ };
+ };
+
+ p3v3_bmc_aux: regulator-p3v3-bmc-aux {
+ compatible = "regulator-fixed";
+ regulator-name = "p3v3_bmc_aux";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ spi_gpio: spi {
+ compatible = "spi-gpio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sck-gpios = <&gpio0 ASPEED_GPIO(Z, 3) GPIO_ACTIVE_HIGH>;
+ mosi-gpios = <&gpio0 ASPEED_GPIO(Z, 4) GPIO_ACTIVE_HIGH>;
+ miso-gpios = <&gpio0 ASPEED_GPIO(Z, 5) GPIO_ACTIVE_HIGH>;
+ cs-gpios = <&gpio0 ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>;
+ num-chipselects = <1>;
+ status = "okay";
+
+ tpm@0 {
+ compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
+ spi-max-frequency = <33000000>;
+ reg = <0>;
+ };
+ };
+};
+
+&adc0 {
+ aspeed,int-vref-microvolt = <2500000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0_default &pinctrl_adc1_default
+ &pinctrl_adc2_default &pinctrl_adc3_default
+ &pinctrl_adc4_default &pinctrl_adc5_default
+ &pinctrl_adc6_default &pinctrl_adc7_default>;
+ status = "okay";
+};
+
+&adc1 {
+ aspeed,int-vref-microvolt = <2500000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc10_default>;
+ status = "okay";
+};
+
+&ehci1 {
+ status = "okay";
+};
+
+&fmc {
+ status = "okay";
+
+ flash@0 {
+ status = "okay";
+ m25p,fast-read;
+ label = "bmc";
+ spi-max-frequency = <50000000>;
+#include "openbmc-flash-layout-128.dtsi"
+ };
+
+ flash@1 {
+ status = "okay";
+ m25p,fast-read;
+ label = "alt-bmc";
+ spi-max-frequency = <50000000>;
+ };
+};
+
+&gfx {
+ status = "okay";
+ memory-region = <&gfx_memory>;
+};
+
+&gpio0 {
+ gpio-line-names =
+
+ /*A0-A7*/
+ "","","","","","","","",
+
+ /*B0-B7*/
+ "BATTERY_DETECT", "", "", "BMC_READY",
+ "", "FM_ID_LED", "", "",
+
+ /*C0-C7*/
+ "","","","","","","","",
+
+ /*D0-D7*/
+ "","","","","","","","",
+
+ /*E0-E7*/
+ "","","","","","","","",
+
+ /*F0-F7*/
+ "","","","","","","","",
+
+ /*G0-G7*/
+ "FM_MUX1_SEL", "", "", "",
+ "", "", "FM_DEBUG_PORT_PRSNT_N", "FM_BMC_DBP_PRESENT_N",
+
+ /*H0-H7*/
+ "","","","","","","","",
+
+ /*I0-I7*/
+ "", "", "", "",
+ "", "FLASH_WP_STATUS", "BMC_JTAG_MUX_SEL", "",
+
+ /*J0-J7*/
+ "","","","","","","","",
+
+ /*K0-K7*/
+ "","","","","","","","",
+
+ /*L0-L7*/
+ "","","","","","","","",
+
+ /*M0-M7*/
+ "", "BMC_FRU_WP", "", "",
+ "", "", "", "",
+
+ /*N0-N7*/
+ "LED_POSTCODE_0", "LED_POSTCODE_1", "LED_POSTCODE_2", "LED_POSTCODE_3",
+ "LED_POSTCODE_4", "LED_POSTCODE_5", "LED_POSTCODE_6", "LED_POSTCODE_7",
+
+ /*O0-O7*/
+ "","","","","","","","",
+
+ /*P0-P7*/
+ "PWR_BTN_BMC_BUF_N", "", "ID_RST_BTN_BMC_N", "",
+ "PWR_LED", "", "", "BMC_HEARTBEAT_N",
+
+ /*Q0-Q7*/
+ "","","","","","","","",
+
+ /*R0-R7*/
+ "","","","","","","","",
+
+ /*S0-S7*/
+ "", "", "SYS_BMC_PWRBTN_N", "",
+ "", "", "", "RUN_POWER_FAULT",
+
+ /*T0-T7*/
+ "","","","","","","","",
+
+ /*U0-U7*/
+ "","","","","","","","",
+
+ /*V0-V7*/
+ "","","","","","","","",
+
+ /*W0-W7*/
+ "","","","","","","","",
+
+ /*X0-X7*/
+ "","","","","","","","",
+
+ /*Y0-Y7*/
+ "","","","","","","","",
+
+ /*Z0-Z7*/
+ "SPI_BMC_TPM_CS2_N", "", "", "SPI_BMC_TPM_CLK",
+ "SPI_BMC_TPM_MOSI", "SPI_BMC_TPM_MISO", "", "";
+};
+
+&gpio1 {
+ gpio-line-names =
+ /*18A0-18A7*/
+ "","","","","","","","",
+
+ /*18B0-18B7*/
+ "","","","",
+ "FM_BOARD_BMC_REV_ID0", "FM_BOARD_BMC_REV_ID1",
+ "FM_BOARD_BMC_REV_ID2", "",
+
+ /*18C0-18C7*/
+ "","","","","","","","",
+
+ /*18D0-18D7*/
+ "","","","","","","","",
+
+ /*18E0-18E3*/
+ "FM_BMC_PROT_LS_EN", "AC_PWR_BMC_BTN_N", "", "";
+};
+
+// L Bridge Board
+&i2c0 {
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "atmel,24c2048";
+ reg = <0x50>;
+ pagesize = <128>;
+ };
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9546";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c0mux0ch0: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c0mux0ch1: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c0mux0ch2: i2c@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c0mux0ch3: i2c@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+// R Bridge Board
+&i2c1 {
+ status = "okay";
+
+ eeprom@50 {
+ compatible = "atmel,24c2048";
+ reg = <0x50>;
+ pagesize = <128>;
+ };
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9546";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c1mux0ch0: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c1mux0ch1: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c1mux0ch2: i2c@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c1mux0ch3: i2c@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+// MB - E1.S
+&i2c4 {
+ status = "okay";
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9548";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c4mux0ch0: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c4mux0ch1: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c4mux0ch2: i2c@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c4mux0ch3: i2c@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c4mux0ch4: i2c@4 {
+ reg = <4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c4mux0ch5: i2c@5 {
+ reg = <5>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c4mux0ch6: i2c@6 {
+ reg = <6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c4mux0ch7: i2c@7 {
+ reg = <7>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+// AMC
+&i2c5 {
+ status = "okay";
+};
+
+// MB
+&i2c6 {
+ status = "okay";
+
+ // HPM FRU
+ eeprom@50 {
+ compatible = "atmel,24c256";
+ reg = <0x50>;
+ };
+};
+
+// SCM
+&i2c7 {
+ status = "okay";
+
+
+};
+
+// MB - PDB
+&i2c8 {
+ status = "okay";
+
+ i2c-mux@72 {
+ compatible = "nxp,pca9546";
+ reg = <0x72>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c8mux0ch0: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ adc@1f {
+ compatible = "ti,adc128d818";
+ reg = <0x1f>;
+ ti,mode = /bits/ 8 <1>;
+ };
+
+ gpio@22 {
+ compatible = "nxp,pca9555";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "RPDB_FAN_FULL_SPEED_R_N", "RPDB_I2C_TEMP75_U8_ALERT_R_N",
+ "RPDB_I2C_TMP432_U29_ALERT_R_N", "RPDB_GLOBAL_WP",
+ "RPDB_FAN_CT_FAN_FAIL_R_N", "",
+ "", "",
+ "RPDB_ALERT_P50V_HSC2_R_N", "RPDB_ALERT_P50V_HSC3_R_N",
+ "RPDB_ALERT_P50V_HSC4_R_N", "RPDB_ALERT_P50V_STBY_R_N",
+ "RPDB_I2C_P12V_MB_VRM_ALERT_R_N",
+ "RPDB_I2C_P12V_STBY_VRM_ALERT_R_N",
+ "RPDB_PGD_P3V3_STBY_PWRGD_R",
+ "RPDB_P12V_STBY_VRM_PWRGD_BUF_R";
+ };
+
+ gpio@24 {
+ compatible = "nxp,pca9555";
+ reg = <0x24>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "RPDB_EAM2_PRSNT_MOS_N_R", "RPDB_EAM3_PRSNT_MOS_N_R",
+ "RPDB_PWRGD_P50V_HSC4_SYS_R",
+ "RPDB_PWRGD_P50V_STBY_SYS_BUF_R",
+ "RPDB_P50V_FAN1_R2_PG", "RPDB_P50V_FAN2_R2_PG",
+ "RPDB_P50V_FAN3_R2_PG", "RPDB_P50V_FAN4_R2_PG",
+ "", "RPDB_FAN1_PRSNT_N_R",
+ "", "RPDB_FAN2_PRSNT_N_R",
+ "RPDB_FAN3_PRSNT_N_R", "RPDB_FAN4_PRSNT_N_R",
+ "", "";
+ };
+
+ // R-PDB FRU
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+ };
+ i2c8mux0ch1: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio@22 {
+ compatible = "nxp,pca9555";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "LPDB_FAN_FULL_SPEED_R_N","LPDB_I2C_TEMP75_U8_ALERT_R_N",
+ "LPDB_I2C_TMP432_U29_ALERT_R_N","LPDB_GLOBAL_WP",
+ "LPDB_FAN_CT_FAN_FAIL_R_N","",
+ "","",
+ "LPDB_ALERT_P50V_HSC0_R_N","LPDB_ALERT_P50V_HSC1_R_N",
+ "LPDB_ALERT_P50V_HSC5_R_N","LPDB_I2C_P12V_SW_VRM_ALERT_R_N",
+ "LPDB_EAM0_PRSNT_MOS_N_R","LPDB_EAM1_PRSNT_MOS_N_R",
+ "LPDB_PWRGD_P50V_HSC5_SYS_R","";
+ };
+
+ gpio@24 {
+ compatible = "nxp,pca9555";
+ reg = <0x24>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "LPDB_P50V_FAN1_R2_PG","LPDB_P50V_FAN2_R2_PG",
+ "LPDB_P50V_FAN3_R2_PG","LPDB_P50V_FAN4_R2_PG",
+ "LPDB_P50V_FAN5_R2_PG","LPDB_FAN1_PRSNT_N_R",
+ "LPDB_FAN2_PRSNT_N_R","LPDB_FAN3_PRSNT_N_R",
+ "LPDB_FAN4_PRSNT_N_R","LPDB_FAN5_PRSNT_N_R",
+ "","",
+ "","",
+ "","";
+ };
+
+ // L-PDB FRU
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+ };
+ i2c8mux0ch2: i2c@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c8mux0ch3: i2c@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+// SCM
+&i2c9 {
+ status = "okay";
+
+ // SCM FRU
+ eeprom@50 {
+ compatible = "atmel,24c128";
+ reg = <0x50>;
+ };
+
+ // BSM FRU
+ eeprom@56 {
+ compatible = "atmel,24c64";
+ reg = <0x56>;
+ };
+};
+
+// R Bridge Board
+&i2c10 {
+ status = "okay";
+
+ i2c-mux@71 {
+ compatible = "nxp,pca9548";
+ reg = <0x71>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c10mux0ch0: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c10mux0ch1: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c10mux0ch2: i2c@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c10mux0ch3: i2c@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c10mux0ch4: i2c@4 {
+ reg = <4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c10mux0ch5: i2c@5 {
+ reg = <5>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio@22 {
+ compatible = "nxp,pca9555";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "","",
+ "","RBB_CPLD_REFRESH_IN_PRGRS_R_L",
+ "RBB_EAM0_NIC_CBL_PRSNT_R_L","RBB_EAM1_NIC_CBL_PRSNT_R_L",
+ "RBB_AINIC_JTAG_MUX_R2_SEL","RBB_SPI_MUX0_R2_SEL",
+ "RBB_AINIC_PRSNT_R_L","RBB_AINIC_OE_R_N",
+ "RBB_AINIC_BOARD_R2_ID","RBB_RST_USB2_HUB_R_N",
+ "RBB_RST_FT4222_R_N","RBB_RST_MCP2210_R_N",
+ "","";
+ };
+
+ // R Bridge Board FRU
+ eeprom@52 {
+ compatible = "atmel,24c256";
+ reg = <0x52>;
+ };
+ };
+ i2c10mux0ch6: i2c@6 {
+ reg = <6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c10mux0ch7: i2c@7 {
+ reg = <7>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+// L Bridge Board
+&i2c11 {
+ status = "okay";
+
+ i2c-mux@71 {
+ compatible = "nxp,pca9548";
+ reg = <0x71>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c11mux0ch0: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c11mux0ch1: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c11mux0ch2: i2c@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c11mux0ch3: i2c@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c11mux0ch4: i2c@4 {
+ reg = <4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c11mux0ch5: i2c@5 {
+ reg = <5>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpio@22 {
+ compatible = "nxp,pca9555";
+ reg = <0x22>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ gpio-line-names =
+ "","",
+ "","LBB_CPLD_REFRESH_IN_PRGRS_R_L",
+ "LBB_EAM0_NIC_CBL_PRSNT_R_L","LBB_EAM1_NIC_CBL_PRSNT_R_L",
+ "LBB_AINIC_JTAG_MUX_R2_SEL","LBB_SPI_MUX0_R2_SEL",
+ "LBB_AINIC_PRSNT_R_L","LBB_AINIC_OE_R_N",
+ "LBB_AINIC_BOARD_R2_ID","LBB_RST_USB2_HUB_R_N",
+ "LBB_RST_FT4222_R_N","LBB_RST_MCP2210_R_N",
+ "","";
+ };
+
+ // L Bridge Board FRU
+ eeprom@52 {
+ compatible = "atmel,24c256";
+ reg = <0x52>;
+ };
+ };
+ i2c11mux0ch6: i2c@6 {
+ reg = <6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c11mux0ch7: i2c@7 {
+ reg = <7>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+};
+
+// Debug Card
+&i2c12 {
+ status = "okay";
+};
+
+// MB
+&i2c13 {
+ status = "okay";
+
+ i2c-mux@70 {
+ compatible = "nxp,pca9548";
+ reg = <0x70>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ i2c-mux-idle-disconnect;
+
+ i2c13mux0ch0: i2c@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c13mux0ch1: i2c@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c13mux0ch2: i2c@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c13mux0ch3: i2c@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ adc@1f {
+ compatible = "ti,adc128d818";
+ reg = <0x1f>;
+ ti,mode = /bits/ 8 <1>;
+ };
+ };
+ i2c13mux0ch4: i2c@4 {
+ reg = <4>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ // HPM BRD ID FRU
+ eeprom@51 {
+ compatible = "atmel,24c256";
+ reg = <0x51>;
+ };
+ };
+ i2c13mux0ch5: i2c@5 {
+ reg = <5>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c13mux0ch6: i2c@6 {
+ reg = <6>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ i2c13mux0ch7: i2c@7 {
+ reg = <7>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ nfc@28 {
+ compatible = "nxp,nxp-nci-i2c";
+ reg = <0x28>;
+
+ interrupt-parent = <&sgpiom0>;
+ interrupts = <156 IRQ_TYPE_LEVEL_HIGH>;
+
+ enable-gpios = <&sgpiom0 241 GPIO_ACTIVE_HIGH>;
+ };
+ };
+ };
+};
+
+// SCM
+&i2c14 {
+ status = "okay";
+};
+
+&i2c15 {
+ status = "okay";
+};
+
+&kcs2 {
+ aspeed,lpc-io-reg = <0xca8>;
+ status = "okay";
+};
+
+&kcs3 {
+ aspeed,lpc-io-reg = <0xca2>;
+ status = "okay";
+};
+
+&lpc_ctrl {
+ status = "okay";
+};
+
+&mac2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ncsi3_default>;
+ use-ncsi;
+};
+
+&sgpiom0 {
+ ngpios = <128>;
+ bus-frequency = <2000000>;
+ gpio-line-names =
+ /*in - out - in - out */
+ /* A0-A7 line 0-15 */
+ "", "FM_CPU0_SYS_RESET_N", "", "CPU0_KBRST_N",
+ "", "FM_CPU0_PROCHOT_trigger_N", "", "FM_CLR_CMOS_R_P0",
+ "", "Force_I3C_SEL", "", "SYSTEM_Force_Run_AC_Cycle",
+ "", "", "", "",
+
+ /* B0-B7 line 16-31 */
+ "Channel0_leakage_EAM3", "FM_CPU_FPGA_JTAG_MUX_SEL",
+ "Channel1_leakage_EAM0", "FM_SCM_JTAG_MUX_SEL",
+ "Channel2_leakage_Manifold1", "FM_BRIDGE_JTAG_MUX_SEL",
+ "Channel3_leakage", "FM_CPU0_NMI_SYNC_FLOOD_N",
+ "Channel4_leakage_Manifold2", "",
+ "Channel5_leakage_EAM1", "",
+ "Channel6_leakage_CPU_DIMM", "",
+ "Channel7_leakage_EAM2", "",
+
+ /* C0-C7 line 32-47 */
+ "RSVD_RMC_GPIO3", "", "", "",
+ "", "", "", "",
+ "LEAK_DETECT_RMC_N", "", "", "",
+ "", "", "", "",
+
+ /* D0-D7 line 48-63 */
+ "PWRGD_PDB_EAMHSC0_CPLD_PG_R", "",
+ "PWRGD_PDB_EAMHSC1_CPLD_PG_R", "",
+ "PWRGD_PDB_EAMHSC2_CPLD_PG_R", "",
+ "PWRGD_PDB_EAMHSC3_CPLD_PG_R", "",
+ "AMC_BRD_PRSNT_CPLD_L", "", "", "",
+ "", "", "", "",
+
+ /* E0-E7 line 64-79 */
+ "AMC_PDB_EAMHSC0_CPLD_EN_R", "",
+ "AMC_PDB_EAMHSC1_CPLD_EN_R", "",
+ "AMC_PDB_EAMHSC2_CPLD_EN_R", "",
+ "AMC_PDB_EAMHSC3_CPLD_EN_R", "",
+ "", "", "", "",
+ "", "", "", "",
+
+ /* F0-F7 line 80-95 */
+ "PWRGD_PVDDCR_CPU1_P0", "SGPIO_READY",
+ "PWRGD_PVDDCR_CPU0_P0", "",
+ "", "", "", "",
+ "", "", "", "",
+
+ /* G0-G7 line 96-111 */
+ "PWRGD_PVDDCR_SOC_P0", "",
+ "PWRGD_PVDDIO_P0", "",
+ "PWRGD_PVDDIO_MEM_S3_P0", "",
+ "PWRGD_CHMP_CPU0_FPGA", "",
+ "PWRGD_CHIL_CPU0_FPGA", "",
+ "PWRGD_CHEH_CPU0_FPGA", "",
+ "PWRGD_CHAD_CPU0_FPGA", "FM_BMC_READY_PLD",
+ "", "",
+
+ /* H0-H7 line 112-127 */
+ "PWRGD_P3V3", "",
+ "P12V_DDR_IP_PWRGD_R", "",
+ "P12V_DDR_AH_PWRGD_R", "",
+ "PWRGD_P12V_VRM1_CPLD_PG_R", "",
+ "PWRGD_P12V_VRM0_CPLD_PG_R", "",
+ "PWRGD_PDB_HSC4_CPLD_PG_R", "",
+ "PWRGD_PVDD18_S5_P0_PG", "",
+ "PWRGD_PVDD33_S5_P0_PG", "",
+
+ /* I0-I7 line 128-143 */
+ "EAM0_BRD_PRSNT_R_L", "",
+ "EAM1_BRD_PRSNT_R_L", "",
+ "EAM2_BRD_PRSNT_R_L", "",
+ "EAM3_BRD_PRSNT_R_L", "",
+ "EAM0_CPU_MOD_PWR_GD_R", "",
+ "EAM1_CPU_MOD_PWR_GD_R", "",
+ "EAM2_CPU_MOD_PWR_GD_R", "",
+ "EAM3_CPU_MOD_PWR_GD_R", "",
+
+ /* J0-J7 line 144-159 */
+ "PRSNT_L_BIRDGE_R", "",
+ "PRSNT_R_BIRDGE_R", "",
+ "BRIDGE_L_MAIN_PG_R", "",
+ "BRIDGE_R_MAIN_PG_R", "",
+ "BRIDGE_L_STBY_PG_R", "",
+ "BRIDGE_R_STBY_PG_R", "",
+ "", "", "", "",
+
+ /* K0-K7 line 160-175 */
+ "ADC_I2C_ALERT_N", "",
+ "TEMP_I2C_ALERT_R_L", "",
+ "CPU0_VR_SMB_ALERT_CPLD_N", "",
+ "COVER_INTRUDER_R_N", "",
+ "HANDLE_INTRUDER_CPLD_N", "",
+ "IRQ_MCIO_CPLD_WAKE_R_N", "",
+ "APML_CPU0_ALERT_R_N", "",
+ "PDB_ALERT_R_N", "",
+
+ /* L0-L7 line 176-191 */
+ "CPU0_SP7R1", "", "CPU0_SP7R2", "",
+ "CPU0_SP7R3", "", "CPU0_SP7R4", "",
+ "CPU0_CORETYPE0", "", "CPU0_CORETYPE1", "",
+ "CPU0_CORETYPE2", "", "FM_BIOS_POST_CMPLT_R_N", "",
+
+ /* M0-M7 line 192-207 */
+ "EAM0_SMERR_CPLD_R_L", "",
+ "EAM1_SMERR_CPLD_R_L", "",
+ "EAM2_SMERR_CPLD_R_L", "",
+ "EAM3_SMERR_CPLD_R_L", "",
+ "CPU0_SMERR_N_R", "",
+ "CPU0_NV_SAVE_N_R", "",
+ "PDB_PWR_LOSS_CPLD_N", "",
+ "IRQ_BMC_SMI_ACTIVE_R_N", "",
+
+ /* N0-N7 line 208-223 */
+ "AMCROT_BMC_S5_RDY_R", "",
+ "AMC_RDY_R", "",
+ "AMC_STBY_PGOOD_R", "",
+ "CPU_AMC_SLP_S5_R_L", "",
+ "AMC_CPU_EAMPG_R", "",
+ "", "", "", "",
+
+ /* O0-O7 line 224-239 */
+ "HPM_PWR_FAIL", "Port80_b0",
+ "FM_DIMM_IP_FAIL", "Port80_b1",
+ "FM_DIMM_AH_FAIL", "Port80_b2",
+ "HPM_AMC_THERMTRIP_R_L", "Port80_b3",
+ "FM_CPU0_THERMTRIP_N", "Port80_b4",
+ "PVDDCR_SOC_P0_OCP_L", "Port80_b5",
+ "CPLD_SGPIO_RDY", "Port80_b6",
+ "", "Port80_b7",
+
+ /* P0-P7 line 240-255 */
+ "CPU0_SLP_S5_N_R", "NFC_VEN",
+ "CPU0_SLP_S3_N_R", "",
+ "FM_CPU0_PWRGD", "",
+ "PWRGD_RMC", "",
+ "FM_RST_CPU0_RESET_N", "",
+ "FM_PWRGD_CPU0_PWROK", "",
+ "wS5_PWR_Ready", "",
+ "wS0_ON_N", "PWRGD_P1V0_AUX";
+ status = "okay";
+};
+
+// BIOS Flash
+&spi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_spi2_default>;
+ status = "okay";
+ reg = <0x1e631000 0xc4>, <0x50000000 0x8000000>;
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ label = "pnor";
+ spi-max-frequency = <12000000>;
+ spi-tx-bus-width = <2>;
+ spi-rx-bus-width = <2>;
+ status = "okay";
+ };
+};
+
+// HOST BIOS Debug
+&uart1 {
+ status = "okay";
+};
+
+&uart3 {
+ status = "okay";
+};
+
+&uart4 {
+ status = "okay";
+};
+
+// BMC Debug Console
+&uart5 {
+ status = "okay";
+};
+
+&uart_routing {
+ status = "okay";
+};
+
+&uhci {
+ status = "okay";
+};
+
+&vhub {
+ status = "okay";
+ pinctrl-names = "default";
+};
+
+&video {
+ status = "okay";
+ memory-region = <&video_engine_memory>;
+};
+
+&wdt1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_wdtrst1_default>;
+ aspeed,reset-type = "soc";
+ aspeed,external-signal;
+ aspeed,ext-push-pull;
+ aspeed,ext-active-high;
+ aspeed,ext-pulse-duration = <256>;
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa.dts
index 2cb7bd128d24..980628af80b0 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa.dts
+++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-anacapa.dts
@@ -1,1067 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/dts-v1/;
-#include "aspeed-g6.dtsi"
-#include <dt-bindings/gpio/aspeed-gpio.h>
-#include <dt-bindings/i2c/i2c.h>
+#include "aspeed-bmc-facebook-anacapa-evt1.dts"
-/ {
- model = "Facebook Anacapa BMC";
- compatible = "facebook,anacapa-bmc", "aspeed,ast2600";
-
- aliases {
- serial0 = &uart1;
- serial1 = &uart2;
- serial2 = &uart3;
- serial3 = &uart4;
- serial4 = &uart5;
- i2c16 = &i2c0mux0ch0;
- i2c17 = &i2c0mux0ch1;
- i2c18 = &i2c0mux0ch2;
- i2c19 = &i2c0mux0ch3;
- i2c20 = &i2c1mux0ch0;
- i2c21 = &i2c1mux0ch1;
- i2c22 = &i2c1mux0ch2;
- i2c23 = &i2c1mux0ch3;
- i2c24 = &i2c4mux0ch0;
- i2c25 = &i2c4mux0ch1;
- i2c26 = &i2c4mux0ch2;
- i2c27 = &i2c4mux0ch3;
- i2c28 = &i2c4mux0ch4;
- i2c29 = &i2c4mux0ch5;
- i2c30 = &i2c4mux0ch6;
- i2c31 = &i2c4mux0ch7;
- i2c32 = &i2c8mux0ch0;
- i2c33 = &i2c8mux0ch1;
- i2c34 = &i2c8mux0ch2;
- i2c35 = &i2c8mux0ch3;
- i2c36 = &i2c10mux0ch0;
- i2c37 = &i2c10mux0ch1;
- i2c38 = &i2c10mux0ch2;
- i2c39 = &i2c10mux0ch3;
- i2c40 = &i2c10mux0ch4;
- i2c41 = &i2c10mux0ch5;
- i2c42 = &i2c10mux0ch6;
- i2c43 = &i2c10mux0ch7;
- i2c44 = &i2c11mux0ch0;
- i2c45 = &i2c11mux0ch1;
- i2c46 = &i2c11mux0ch2;
- i2c47 = &i2c11mux0ch3;
- i2c48 = &i2c11mux0ch4;
- i2c49 = &i2c11mux0ch5;
- i2c50 = &i2c11mux0ch6;
- i2c51 = &i2c11mux0ch7;
- i2c52 = &i2c13mux0ch0;
- i2c53 = &i2c13mux0ch1;
- i2c54 = &i2c13mux0ch2;
- i2c55 = &i2c13mux0ch3;
- i2c56 = &i2c13mux0ch4;
- i2c57 = &i2c13mux0ch5;
- i2c58 = &i2c13mux0ch6;
- i2c59 = &i2c13mux0ch7;
- };
-
- chosen {
- stdout-path = "serial4:57600n8";
- };
-
- iio-hwmon {
- compatible = "iio-hwmon";
- io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>, <&adc0 3>,
- <&adc0 4>, <&adc0 5>, <&adc0 6>, <&adc0 7>,
- <&adc1 2>;
- };
-
- leds {
- compatible = "gpio-leds";
-
- led-0 {
- label = "bmc_heartbeat_amber";
- gpios = <&gpio0 ASPEED_GPIO(P, 7) GPIO_ACTIVE_LOW>;
- linux,default-trigger = "heartbeat";
- };
-
- led-1 {
- label = "fp_id_amber";
- default-state = "off";
- gpios = <&gpio0 ASPEED_GPIO(B, 5) GPIO_ACTIVE_HIGH>;
- };
- };
-
- memory@80000000 {
- device_type = "memory";
- reg = <0x80000000 0x80000000>;
- };
-
- reserved-memory {
- #address-cells = <1>;
- #size-cells = <1>;
- ranges;
-
- video_engine_memory: video {
- size = <0x02c00000>;
- alignment = <0x00100000>;
- compatible = "shared-dma-pool";
- reusable;
- };
-
- gfx_memory: framebuffer {
- size = <0x01000000>;
- alignment = <0x01000000>;
- compatible = "shared-dma-pool";
- reusable;
- };
- };
-
- p3v3_bmc_aux: regulator-p3v3-bmc-aux {
- compatible = "regulator-fixed";
- regulator-name = "p3v3_bmc_aux";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- regulator-always-on;
- };
-
- spi_gpio: spi {
- compatible = "spi-gpio";
- #address-cells = <1>;
- #size-cells = <0>;
-
- sck-gpios = <&gpio0 ASPEED_GPIO(Z, 3) GPIO_ACTIVE_HIGH>;
- mosi-gpios = <&gpio0 ASPEED_GPIO(Z, 4) GPIO_ACTIVE_HIGH>;
- miso-gpios = <&gpio0 ASPEED_GPIO(Z, 5) GPIO_ACTIVE_HIGH>;
- cs-gpios = <&gpio0 ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>;
- num-chipselects = <1>;
- status = "okay";
-
- tpm@0 {
- compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
- spi-max-frequency = <33000000>;
- reg = <0>;
- };
- };
-};
-
-&adc0 {
- aspeed,int-vref-microvolt = <2500000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_adc0_default &pinctrl_adc1_default
- &pinctrl_adc2_default &pinctrl_adc3_default
- &pinctrl_adc4_default &pinctrl_adc5_default
- &pinctrl_adc6_default &pinctrl_adc7_default>;
- status = "okay";
-};
-
-&adc1 {
- aspeed,int-vref-microvolt = <2500000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_adc10_default>;
- status = "okay";
-};
-
-&ehci1 {
- status = "okay";
-};
-
-&fmc {
- status = "okay";
-
- flash@0 {
- status = "okay";
- m25p,fast-read;
- label = "bmc";
- spi-max-frequency = <50000000>;
-#include "openbmc-flash-layout-128.dtsi"
- };
-
- flash@1 {
- status = "okay";
- m25p,fast-read;
- label = "alt-bmc";
- spi-max-frequency = <50000000>;
- };
-};
-
-&gfx {
- status = "okay";
- memory-region = <&gfx_memory>;
-};
-
-&gpio0 {
- gpio-line-names =
-
- /*A0-A7*/
- "","","","","","","","",
-
- /*B0-B7*/
- "BATTERY_DETECT", "", "", "BMC_READY",
- "", "FM_ID_LED", "", "",
-
- /*C0-C7*/
- "","","","","","","","",
-
- /*D0-D7*/
- "","","","","","","","",
-
- /*E0-E7*/
- "","","","","","","","",
-
- /*F0-F7*/
- "","","","","","","","",
-
- /*G0-G7*/
- "FM_MUX1_SEL", "", "", "",
- "", "", "FM_DEBUG_PORT_PRSNT_N", "FM_BMC_DBP_PRESENT_N",
-
- /*H0-H7*/
- "","","","","","","","",
-
- /*I0-I7*/
- "", "", "", "",
- "", "FLASH_WP_STATUS", "BMC_JTAG_MUX_SEL", "",
-
- /*J0-J7*/
- "","","","","","","","",
-
- /*K0-K7*/
- "","","","","","","","",
-
- /*L0-L7*/
- "","","","","","","","",
-
- /*M0-M7*/
- "", "BMC_FRU_WP", "", "",
- "", "", "", "",
-
- /*N0-N7*/
- "LED_POSTCODE_0", "LED_POSTCODE_1", "LED_POSTCODE_2", "LED_POSTCODE_3",
- "LED_POSTCODE_4", "LED_POSTCODE_5", "LED_POSTCODE_6", "LED_POSTCODE_7",
-
- /*O0-O7*/
- "","","","","","","","",
-
- /*P0-P7*/
- "PWR_BTN_BMC_BUF_N", "", "ID_RST_BTN_BMC_N", "",
- "PWR_LED", "", "", "BMC_HEARTBEAT_N",
-
- /*Q0-Q7*/
- "","","","","","","","",
-
- /*R0-R7*/
- "","","","","","","","",
-
- /*S0-S7*/
- "", "", "SYS_BMC_PWRBTN_N", "",
- "", "", "", "RUN_POWER_FAULT",
-
- /*T0-T7*/
- "","","","","","","","",
-
- /*U0-U7*/
- "","","","","","","","",
-
- /*V0-V7*/
- "","","","","","","","",
-
- /*W0-W7*/
- "","","","","","","","",
-
- /*X0-X7*/
- "","","","","","","","",
-
- /*Y0-Y7*/
- "","","","","","","","",
-
- /*Z0-Z7*/
- "SPI_BMC_TPM_CS2_N", "", "", "SPI_BMC_TPM_CLK",
- "SPI_BMC_TPM_MOSI", "SPI_BMC_TPM_MISO", "", "";
-};
-
-&gpio1 {
- gpio-line-names =
- /*18A0-18A7*/
- "","","","","","","","",
-
- /*18B0-18B7*/
- "","","","",
- "FM_BOARD_BMC_REV_ID0", "FM_BOARD_BMC_REV_ID1",
- "FM_BOARD_BMC_REV_ID2", "",
-
- /*18C0-18C7*/
- "","","","","","","","",
-
- /*18D0-18D7*/
- "","","","","","","","",
-
- /*18E0-18E3*/
- "FM_BMC_PROT_LS_EN", "AC_PWR_BMC_BTN_N", "", "";
-};
-
-// L Bridge Board
-&i2c0 {
- status = "okay";
-
- eeprom@50 {
- compatible = "atmel,24c2048";
- reg = <0x50>;
- pagesize = <128>;
- };
-
- i2c-mux@70 {
- compatible = "nxp,pca9546";
- reg = <0x70>;
- #address-cells = <1>;
- #size-cells = <0>;
- i2c-mux-idle-disconnect;
-
- i2c0mux0ch0: i2c@0 {
- reg = <0>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c0mux0ch1: i2c@1 {
- reg = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c0mux0ch2: i2c@2 {
- reg = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c0mux0ch3: i2c@3 {
- reg = <3>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- };
-};
-
-// R Bridge Board
-&i2c1 {
- status = "okay";
-
- eeprom@50 {
- compatible = "atmel,24c2048";
- reg = <0x50>;
- pagesize = <128>;
- };
-
- i2c-mux@70 {
- compatible = "nxp,pca9546";
- reg = <0x70>;
- #address-cells = <1>;
- #size-cells = <0>;
- i2c-mux-idle-disconnect;
-
- i2c1mux0ch0: i2c@0 {
- reg = <0>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c1mux0ch1: i2c@1 {
- reg = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c1mux0ch2: i2c@2 {
- reg = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c1mux0ch3: i2c@3 {
- reg = <3>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- };
-};
-
-// MB - E1.S
-&i2c4 {
- status = "okay";
-
- i2c-mux@70 {
- compatible = "nxp,pca9548";
- reg = <0x70>;
- #address-cells = <1>;
- #size-cells = <0>;
- i2c-mux-idle-disconnect;
-
- i2c4mux0ch0: i2c@0 {
- reg = <0>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c4mux0ch1: i2c@1 {
- reg = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c4mux0ch2: i2c@2 {
- reg = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c4mux0ch3: i2c@3 {
- reg = <3>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c4mux0ch4: i2c@4 {
- reg = <4>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c4mux0ch5: i2c@5 {
- reg = <5>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c4mux0ch6: i2c@6 {
- reg = <6>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c4mux0ch7: i2c@7 {
- reg = <7>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- };
-};
-
-// AMC
-&i2c5 {
- status = "okay";
-};
-
-// MB
-&i2c6 {
- status = "okay";
-
- // HPM FRU
- eeprom@50 {
- compatible = "atmel,24c256";
- reg = <0x50>;
- };
-};
-
-// SCM
-&i2c7 {
- status = "okay";
-
-
-};
-
-// MB - PDB
-&i2c8 {
- status = "okay";
-
- i2c-mux@72 {
- compatible = "nxp,pca9546";
- reg = <0x72>;
- #address-cells = <1>;
- #size-cells = <0>;
- i2c-mux-idle-disconnect;
-
- i2c8mux0ch0: i2c@0 {
- reg = <0>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- adc@1f {
- compatible = "ti,adc128d818";
- reg = <0x1f>;
- ti,mode = /bits/ 8 <1>;
- };
-
- gpio@22 {
- compatible = "nxp,pca9555";
- reg = <0x22>;
- gpio-controller;
- #gpio-cells = <2>;
-
- gpio-line-names =
- "RPDB_FAN_FULL_SPEED_R_N", "RPDB_I2C_TEMP75_U8_ALERT_R_N",
- "RPDB_I2C_TMP432_U29_ALERT_R_N", "RPDB_GLOBAL_WP",
- "RPDB_FAN_CT_FAN_FAIL_R_N", "",
- "", "",
- "RPDB_ALERT_P50V_HSC2_R_N", "RPDB_ALERT_P50V_HSC3_R_N",
- "RPDB_ALERT_P50V_HSC4_R_N", "RPDB_ALERT_P50V_STBY_R_N",
- "RPDB_I2C_P12V_MB_VRM_ALERT_R_N",
- "RPDB_I2C_P12V_STBY_VRM_ALERT_R_N",
- "RPDB_PGD_P3V3_STBY_PWRGD_R",
- "RPDB_P12V_STBY_VRM_PWRGD_BUF_R";
- };
-
- gpio@24 {
- compatible = "nxp,pca9555";
- reg = <0x24>;
- gpio-controller;
- #gpio-cells = <2>;
-
- gpio-line-names =
- "RPDB_EAM2_PRSNT_MOS_N_R", "RPDB_EAM3_PRSNT_MOS_N_R",
- "RPDB_PWRGD_P50V_HSC4_SYS_R",
- "RPDB_PWRGD_P50V_STBY_SYS_BUF_R",
- "RPDB_P50V_FAN1_R2_PG", "RPDB_P50V_FAN2_R2_PG",
- "RPDB_P50V_FAN3_R2_PG", "RPDB_P50V_FAN4_R2_PG",
- "", "RPDB_FAN1_PRSNT_N_R",
- "", "RPDB_FAN2_PRSNT_N_R",
- "RPDB_FAN3_PRSNT_N_R", "RPDB_FAN4_PRSNT_N_R",
- "", "";
- };
-
- // R-PDB FRU
- eeprom@50 {
- compatible = "atmel,24c128";
- reg = <0x50>;
- };
- };
- i2c8mux0ch1: i2c@1 {
- reg = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- gpio@22 {
- compatible = "nxp,pca9555";
- reg = <0x22>;
- gpio-controller;
- #gpio-cells = <2>;
-
- gpio-line-names =
- "LPDB_FAN_FULL_SPEED_R_N","LPDB_I2C_TEMP75_U8_ALERT_R_N",
- "LPDB_I2C_TMP432_U29_ALERT_R_N","LPDB_GLOBAL_WP",
- "LPDB_FAN_CT_FAN_FAIL_R_N","",
- "","",
- "LPDB_ALERT_P50V_HSC0_R_N","LPDB_ALERT_P50V_HSC1_R_N",
- "LPDB_ALERT_P50V_HSC5_R_N","LPDB_I2C_P12V_SW_VRM_ALERT_R_N",
- "LPDB_EAM0_PRSNT_MOS_N_R","LPDB_EAM1_PRSNT_MOS_N_R",
- "LPDB_PWRGD_P50V_HSC5_SYS_R","";
- };
-
- gpio@24 {
- compatible = "nxp,pca9555";
- reg = <0x24>;
- gpio-controller;
- #gpio-cells = <2>;
-
- gpio-line-names =
- "LPDB_P50V_FAN1_R2_PG","LPDB_P50V_FAN2_R2_PG",
- "LPDB_P50V_FAN3_R2_PG","LPDB_P50V_FAN4_R2_PG",
- "LPDB_P50V_FAN5_R2_PG","LPDB_FAN1_PRSNT_N_R",
- "LPDB_FAN2_PRSNT_N_R","LPDB_FAN3_PRSNT_N_R",
- "LPDB_FAN4_PRSNT_N_R","LPDB_FAN5_PRSNT_N_R",
- "","",
- "","",
- "","";
- };
-
- // L-PDB FRU
- eeprom@50 {
- compatible = "atmel,24c128";
- reg = <0x50>;
- };
- };
- i2c8mux0ch2: i2c@2 {
- reg = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c8mux0ch3: i2c@3 {
- reg = <3>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- };
-};
-
-// SCM
-&i2c9 {
- status = "okay";
-
- // SCM FRU
- eeprom@50 {
- compatible = "atmel,24c128";
- reg = <0x50>;
- };
-
- // BSM FRU
- eeprom@56 {
- compatible = "atmel,24c64";
- reg = <0x56>;
- };
-};
-
-// R Bridge Board
-&i2c10 {
- status = "okay";
-
- i2c-mux@71 {
- compatible = "nxp,pca9548";
- reg = <0x71>;
- #address-cells = <1>;
- #size-cells = <0>;
- i2c-mux-idle-disconnect;
-
- i2c10mux0ch0: i2c@0 {
- reg = <0>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c10mux0ch1: i2c@1 {
- reg = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c10mux0ch2: i2c@2 {
- reg = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c10mux0ch3: i2c@3 {
- reg = <3>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c10mux0ch4: i2c@4 {
- reg = <4>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c10mux0ch5: i2c@5 {
- reg = <5>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- gpio@22 {
- compatible = "nxp,pca9555";
- reg = <0x22>;
- gpio-controller;
- #gpio-cells = <2>;
-
- gpio-line-names =
- "","",
- "","RBB_CPLD_REFRESH_IN_PRGRS_R_L",
- "RBB_EAM0_NIC_CBL_PRSNT_R_L","RBB_EAM1_NIC_CBL_PRSNT_R_L",
- "RBB_AINIC_JTAG_MUX_R2_SEL","RBB_SPI_MUX0_R2_SEL",
- "RBB_AINIC_PRSNT_R_L","RBB_AINIC_OE_R_N",
- "RBB_AINIC_BOARD_R2_ID","RBB_RST_USB2_HUB_R_N",
- "RBB_RST_FT4222_R_N","RBB_RST_MCP2210_R_N",
- "","";
- };
-
- // R Bridge Board FRU
- eeprom@52 {
- compatible = "atmel,24c256";
- reg = <0x52>;
- };
- };
- i2c10mux0ch6: i2c@6 {
- reg = <6>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c10mux0ch7: i2c@7 {
- reg = <7>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- };
-};
-
-// L Bridge Board
-&i2c11 {
- status = "okay";
-
- i2c-mux@71 {
- compatible = "nxp,pca9548";
- reg = <0x71>;
- #address-cells = <1>;
- #size-cells = <0>;
- i2c-mux-idle-disconnect;
-
- i2c11mux0ch0: i2c@0 {
- reg = <0>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c11mux0ch1: i2c@1 {
- reg = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c11mux0ch2: i2c@2 {
- reg = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c11mux0ch3: i2c@3 {
- reg = <3>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c11mux0ch4: i2c@4 {
- reg = <4>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c11mux0ch5: i2c@5 {
- reg = <5>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- gpio@22 {
- compatible = "nxp,pca9555";
- reg = <0x22>;
- gpio-controller;
- #gpio-cells = <2>;
-
- gpio-line-names =
- "","",
- "","LBB_CPLD_REFRESH_IN_PRGRS_R_L",
- "LBB_EAM0_NIC_CBL_PRSNT_R_L","LBB_EAM1_NIC_CBL_PRSNT_R_L",
- "LBB_AINIC_JTAG_MUX_R2_SEL","LBB_SPI_MUX0_R2_SEL",
- "LBB_AINIC_PRSNT_R_L","LBB_AINIC_OE_R_N",
- "LBB_AINIC_BOARD_R2_ID","LBB_RST_USB2_HUB_R_N",
- "LBB_RST_FT4222_R_N","LBB_RST_MCP2210_R_N",
- "","";
- };
-
- // L Bridge Board FRU
- eeprom@52 {
- compatible = "atmel,24c256";
- reg = <0x52>;
- };
- };
- i2c11mux0ch6: i2c@6 {
- reg = <6>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c11mux0ch7: i2c@7 {
- reg = <7>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- };
-};
-
-// Debug Card
-&i2c12 {
- status = "okay";
-};
-
-// MB
-&i2c13 {
- status = "okay";
-
- i2c-mux@70 {
- compatible = "nxp,pca9548";
- reg = <0x70>;
- #address-cells = <1>;
- #size-cells = <0>;
- i2c-mux-idle-disconnect;
-
- i2c13mux0ch0: i2c@0 {
- reg = <0>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c13mux0ch1: i2c@1 {
- reg = <1>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c13mux0ch2: i2c@2 {
- reg = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c13mux0ch3: i2c@3 {
- reg = <3>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- adc@1f {
- compatible = "ti,adc128d818";
- reg = <0x1f>;
- ti,mode = /bits/ 8 <1>;
- };
- };
- i2c13mux0ch4: i2c@4 {
- reg = <4>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- // HPM BRD ID FRU
- eeprom@51 {
- compatible = "atmel,24c256";
- reg = <0x51>;
- };
- };
- i2c13mux0ch5: i2c@5 {
- reg = <5>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c13mux0ch6: i2c@6 {
- reg = <6>;
- #address-cells = <1>;
- #size-cells = <0>;
- };
- i2c13mux0ch7: i2c@7 {
- reg = <7>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- nfc@28 {
- compatible = "nxp,nxp-nci-i2c";
- reg = <0x28>;
-
- interrupt-parent = <&sgpiom0>;
- interrupts = <156 IRQ_TYPE_LEVEL_HIGH>;
-
- enable-gpios = <&sgpiom0 241 GPIO_ACTIVE_HIGH>;
- };
- };
- };
-};
-
-// SCM
-&i2c14 {
- status = "okay";
-};
-
-&i2c15 {
- status = "okay";
-};
-
-&kcs2 {
- aspeed,lpc-io-reg = <0xca8>;
- status = "okay";
-};
-
-&kcs3 {
- aspeed,lpc-io-reg = <0xca2>;
- status = "okay";
-};
-
-&lpc_ctrl {
- status = "okay";
-};
-
-&mac2 {
- status = "okay";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ncsi3_default>;
- use-ncsi;
-};
-
-&sgpiom0 {
- ngpios = <128>;
- bus-frequency = <2000000>;
- gpio-line-names =
- /*in - out - in - out */
- /* A0-A7 line 0-15 */
- "", "FM_CPU0_SYS_RESET_N", "", "CPU0_KBRST_N",
- "", "FM_CPU0_PROCHOT_trigger_N", "", "FM_CLR_CMOS_R_P0",
- "", "Force_I3C_SEL", "", "SYSTEM_Force_Run_AC_Cycle",
- "", "", "", "",
-
- /* B0-B7 line 16-31 */
- "Channel0_leakage_EAM3", "FM_CPU_FPGA_JTAG_MUX_SEL",
- "Channel1_leakage_EAM0", "FM_SCM_JTAG_MUX_SEL",
- "Channel2_leakage_Manifold1", "FM_BRIDGE_JTAG_MUX_SEL",
- "Channel3_leakage", "FM_CPU0_NMI_SYNC_FLOOD_N",
- "Channel4_leakage_Manifold2", "",
- "Channel5_leakage_EAM1", "",
- "Channel6_leakage_CPU_DIMM", "",
- "Channel7_leakage_EAM2", "",
-
- /* C0-C7 line 32-47 */
- "RSVD_RMC_GPIO3", "", "", "",
- "", "", "", "",
- "LEAK_DETECT_RMC_N", "", "", "",
- "", "", "", "",
-
- /* D0-D7 line 48-63 */
- "PWRGD_PDB_EAMHSC0_CPLD_PG_R", "",
- "PWRGD_PDB_EAMHSC1_CPLD_PG_R", "",
- "PWRGD_PDB_EAMHSC2_CPLD_PG_R", "",
- "PWRGD_PDB_EAMHSC3_CPLD_PG_R", "",
- "AMC_BRD_PRSNT_CPLD_L", "", "", "",
- "", "", "", "",
-
- /* E0-E7 line 64-79 */
- "AMC_PDB_EAMHSC0_CPLD_EN_R", "",
- "AMC_PDB_EAMHSC1_CPLD_EN_R", "",
- "AMC_PDB_EAMHSC2_CPLD_EN_R", "",
- "AMC_PDB_EAMHSC3_CPLD_EN_R", "",
- "", "", "", "",
- "", "", "", "",
-
- /* F0-F7 line 80-95 */
- "PWRGD_PVDDCR_CPU1_P0", "SGPIO_READY",
- "PWRGD_PVDDCR_CPU0_P0", "",
- "", "", "", "",
- "", "", "", "",
-
- /* G0-G7 line 96-111 */
- "PWRGD_PVDDCR_SOC_P0", "",
- "PWRGD_PVDDIO_P0", "",
- "PWRGD_PVDDIO_MEM_S3_P0", "",
- "PWRGD_CHMP_CPU0_FPGA", "",
- "PWRGD_CHIL_CPU0_FPGA", "",
- "PWRGD_CHEH_CPU0_FPGA", "",
- "PWRGD_CHAD_CPU0_FPGA", "FM_BMC_READY_PLD",
- "", "",
-
- /* H0-H7 line 112-127 */
- "PWRGD_P3V3", "",
- "P12V_DDR_IP_PWRGD_R", "",
- "P12V_DDR_AH_PWRGD_R", "",
- "PWRGD_P12V_VRM1_CPLD_PG_R", "",
- "PWRGD_P12V_VRM0_CPLD_PG_R", "",
- "PWRGD_PDB_HSC4_CPLD_PG_R", "",
- "PWRGD_PVDD18_S5_P0_PG", "",
- "PWRGD_PVDD33_S5_P0_PG", "",
-
- /* I0-I7 line 128-143 */
- "EAM0_BRD_PRSNT_R_L", "",
- "EAM1_BRD_PRSNT_R_L", "",
- "EAM2_BRD_PRSNT_R_L", "",
- "EAM3_BRD_PRSNT_R_L", "",
- "EAM0_CPU_MOD_PWR_GD_R", "",
- "EAM1_CPU_MOD_PWR_GD_R", "",
- "EAM2_CPU_MOD_PWR_GD_R", "",
- "EAM3_CPU_MOD_PWR_GD_R", "",
-
- /* J0-J7 line 144-159 */
- "PRSNT_L_BIRDGE_R", "",
- "PRSNT_R_BIRDGE_R", "",
- "BRIDGE_L_MAIN_PG_R", "",
- "BRIDGE_R_MAIN_PG_R", "",
- "BRIDGE_L_STBY_PG_R", "",
- "BRIDGE_R_STBY_PG_R", "",
- "", "", "", "",
-
- /* K0-K7 line 160-175 */
- "ADC_I2C_ALERT_N", "",
- "TEMP_I2C_ALERT_R_L", "",
- "CPU0_VR_SMB_ALERT_CPLD_N", "",
- "COVER_INTRUDER_R_N", "",
- "HANDLE_INTRUDER_CPLD_N", "",
- "IRQ_MCIO_CPLD_WAKE_R_N", "",
- "APML_CPU0_ALERT_R_N", "",
- "PDB_ALERT_R_N", "",
-
- /* L0-L7 line 176-191 */
- "CPU0_SP7R1", "", "CPU0_SP7R2", "",
- "CPU0_SP7R3", "", "CPU0_SP7R4", "",
- "CPU0_CORETYPE0", "", "CPU0_CORETYPE1", "",
- "CPU0_CORETYPE2", "", "FM_BIOS_POST_CMPLT_R_N", "",
-
- /* M0-M7 line 192-207 */
- "EAM0_SMERR_CPLD_R_L", "",
- "EAM1_SMERR_CPLD_R_L", "",
- "EAM2_SMERR_CPLD_R_L", "",
- "EAM3_SMERR_CPLD_R_L", "",
- "CPU0_SMERR_N_R", "",
- "CPU0_NV_SAVE_N_R", "",
- "PDB_PWR_LOSS_CPLD_N", "",
- "IRQ_BMC_SMI_ACTIVE_R_N", "",
-
- /* N0-N7 line 208-223 */
- "AMCROT_BMC_S5_RDY_R", "",
- "AMC_RDY_R", "",
- "AMC_STBY_PGOOD_R", "",
- "CPU_AMC_SLP_S5_R_L", "",
- "AMC_CPU_EAMPG_R", "",
- "", "", "", "",
-
- /* O0-O7 line 224-239 */
- "HPM_PWR_FAIL", "Port80_b0",
- "FM_DIMM_IP_FAIL", "Port80_b1",
- "FM_DIMM_AH_FAIL", "Port80_b2",
- "HPM_AMC_THERMTRIP_R_L", "Port80_b3",
- "FM_CPU0_THERMTRIP_N", "Port80_b4",
- "PVDDCR_SOC_P0_OCP_L", "Port80_b5",
- "CPLD_SGPIO_RDY", "Port80_b6",
- "", "Port80_b7",
-
- /* P0-P7 line 240-255 */
- "CPU0_SLP_S5_N_R", "NFC_VEN",
- "CPU0_SLP_S3_N_R", "",
- "FM_CPU0_PWRGD", "",
- "PWRGD_RMC", "",
- "FM_RST_CPU0_RESET_N", "",
- "FM_PWRGD_CPU0_PWROK", "",
- "wS5_PWR_Ready", "",
- "wS0_ON_N", "PWRGD_P1V0_AUX";
- status = "okay";
-};
-
-// BIOS Flash
-&spi2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_spi2_default>;
- status = "okay";
- reg = <0x1e631000 0xc4>, <0x50000000 0x8000000>;
-
- flash@0 {
- compatible = "jedec,spi-nor";
- label = "pnor";
- spi-max-frequency = <12000000>;
- spi-tx-bus-width = <2>;
- spi-rx-bus-width = <2>;
- status = "okay";
- };
-};
-
-// HOST BIOS Debug
-&uart1 {
- status = "okay";
-};
-
-&uart3 {
- status = "okay";
-};
-
-&uart4 {
- status = "okay";
-};
-
-// BMC Debug Console
-&uart5 {
- status = "okay";
-};
-
-&uart_routing {
- status = "okay";
-};
-
-&uhci {
- status = "okay";
-};
-
-&vhub {
- status = "okay";
- pinctrl-names = "default";
-};
-
-&video {
- status = "okay";
- memory-region = <&video_engine_memory>;
-};
-
-&wdt1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_wdtrst1_default>;
- aspeed,reset-type = "soc";
- aspeed,external-signal;
- aspeed,ext-push-pull;
- aspeed,ext-active-high;
- aspeed,ext-pulse-duration = <256>;
- status = "okay";
-};
--
2.34.1
^ permalink raw reply related
* [PATCH v2 1/3] dt-bindings: arm: aspeed: add Anacapa EVT1 EVT2 board
From: Colin Huang @ 2026-04-09 11:40 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
Andrew Jeffery
Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel,
colin.huang2, Colin Huang
In-Reply-To: <20260409-anacapa-devlop-phase-devicetree-v2-0-68f328671653@gmail.com>
Document Anacapa BMC EVT1 and EVT2 compatibles.
Signed-off-by: Colin Huang <u8813345@gmail.com>
---
Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
index 8ec7a3e74a21..c4b87c014941 100644
--- a/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
+++ b/Documentation/devicetree/bindings/arm/aspeed/aspeed.yaml
@@ -84,6 +84,8 @@ properties:
- asus,ast2600-kommando-ipmi-card
- asus,x4tf-bmc
- facebook,anacapa-bmc
+ - facebook,anacapa-bmc-evt1
+ - facebook,anacapa-bmc-evt2
- facebook,bletchley-bmc
- facebook,catalina-bmc
- facebook,clemente-bmc
--
2.34.1
^ permalink raw reply related
* [PATCH v2 0/3] ARM: dts: aspeed: anacapa: restructure devicetree for development-phase
From: Colin Huang @ 2026-04-09 11:40 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
Andrew Jeffery
Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel,
colin.huang2, Colin Huang
This series refactors the Anacapa BMC devicetree layout to better support
development-phase hardware revisions (EVT1/EVT2) while keeping a platform
entrypoint.
Signed-off-by: Colin Huang <u8813345@gmail.com>
---
Changes in v2:
- Fix dtbs_check fail.
Validated by following command:
make dt_binding_check DT_SCHEMA_FILES=arm/aspeed/aspeed.yaml
make CHECK_DTBS=y DT_SCHEMA_FILES=arm/aspeed/aspeed.yaml aspeed/aspeed-bmc-facebook-anacapa.dtb
make CHECK_DTBS=y DT_SCHEMA_FILES=arm/aspeed/aspeed.yaml aspeed/aspeed-bmc-facebook-anacapa-evt1.dtb
make CHECK_DTBS=y DT_SCHEMA_FILES=arm/aspeed/aspeed.yaml aspeed/aspeed-bmc-facebook-anacapa-evt2.dtb
- Link to v1: https://lore.kernel.org/r/20260407-anacapa-devlop-phase-devicetree-v1-0-97b96367cac3@gmail.com
---
Colin Huang (3):
dt-bindings: arm: aspeed: add Anacapa EVT1 EVT2 board
ARM: dts: aspeed: anacapa: add EVT1 devicetree and point wrapper to it
ARM: dts: aspeed: anacapa: add EVT2 devicetree and update wrapper
.../devicetree/bindings/arm/aspeed/aspeed.yaml | 2 +
.../aspeed/aspeed-bmc-facebook-anacapa-evt1.dts | 1067 +++++++++++++++++++
.../aspeed/aspeed-bmc-facebook-anacapa-evt2.dts | 1123 ++++++++++++++++++++
.../dts/aspeed/aspeed-bmc-facebook-anacapa.dts | 1064 +------------------
4 files changed, 2193 insertions(+), 1063 deletions(-)
---
base-commit: cd44dc5ead3042f2873244b0598e39a16dc7b940
change-id: 20260407-anacapa-devlop-phase-devicetree-4101d3f312c0
Best regards,
--
Colin Huang <u8813345@gmail.com>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox