[PATCH v1 07/23] board: nbxv3: select carrier at boot
Vincent Jardin <[email protected]>
| Newsgroups | org.u-boot-project.lists.u-boot |
|---|---|
| Message-ID | <[email protected]> |
The Nodebox v3 CPU module runs on several carriers. They share one
kernel Image but need different DTBs and different DPAA2 DPC/DPL, so
the kernel FIT carries every carrier's set as fdt-<c> / dpc-<c> /
dpl-<c> with a conf-<c> configuration each, and U-Boot picks one:
mcinitcmd imxtract ... dpc-${carrier} / dpl-${carrier}
mc_init bootm ${kernel_addr_r}#conf-${carrier}
Signed-off-by: Vincent Jardin <[email protected]>
---
board/nxp/lx2160a/nbxv3/Makefile | 1 +
board/nxp/lx2160a/nbxv3/carrier.c | 87 +++++++++++++++++++++++++++++
board/nxp/lx2160a/nbxv3/carrier.h | 17 ++++++
board/nxp/lx2160a/nbxv3/eth_nbxv3.c | 10 ++++
4 files changed, 115 insertions(+)
create mode 100644 board/nxp/lx2160a/nbxv3/carrier.c
create mode 100644 board/nxp/lx2160a/nbxv3/carrier.h
diff --git a/board/nxp/lx2160a/nbxv3/Makefile b/board/nxp/lx2160a/nbxv3/Makefile
index 68fab9bf18f..4ce2508249d 100644
--- a/board/nxp/lx2160a/nbxv3/Makefile
+++ b/board/nxp/lx2160a/nbxv3/Makefile
@@ -3,6 +3,7 @@
#
obj-y += eth_nbxv3.o
+obj-y += carrier.o
obj-y += mps_pmbus.o
obj-y += psu_pmbus.o
obj-y += vid_handoff.o
diff --git a/board/nxp/lx2160a/nbxv3/carrier.c b/board/nxp/lx2160a/nbxv3/carrier.c
new file mode 100644
index 00000000000..231aaf1e3f1
--- /dev/null
+++ b/board/nxp/lx2160a/nbxv3/carrier.c
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2026 Free Mobile - Vincent Jardin
+ *
+ * Nodebox v3 carrier selector.
+ *
+ * The CPU module is used on several carrier boards (nbv30, nbv32, ...).
+ * They share one kernel Image but need different DTBs and different
+ * DPAA2 DPC/DPL, it is up to the build framework (buildroot, etc.) to
+ * puts all of them into the single kernel FIT.
+ *
+ * images: fdt-<carrier>, dpc-<carrier>, dpl-<carrier>
+ * configurations: conf-<carrier>
+ *
+ * and then the boot env picks one with ${carrier}:
+ *
+ * mcinitcmd imxtract ... dpc-${carrier} / dpl-${carrier}
+ * mc_init bootm ${kernel_addr_r}#conf-${carrier}
+ *
+ * Change it from the prompt and make it persistent:
+ *
+ * setenv carrier nbv32 && saveenv && reset
+ *
+ * WHY THIS FILE EXISTS RATHER THAN JUST A DEFAULT IN CFG_EXTRA_ENV_SETTINGS:
+ * A default there only applies when the saved
+ * environment is absent or fails its CRC: env_import() calls himport_r()
+ * WITHOUT H_NOCLEAR, so a valid saved env in NOR replaces the built-in
+ * defaults wholesale rather than merging with them. Every board already
+ * running with a saved env would therefore come up with ${carrier}
+ * EMPTY on the first boot after this feature lands, `bootm
+ * ${kernel_addr_r}#conf-` would fail with
+ * "Could not find configuration node".
+ * Setting
+ * it from C on every boot when it is missing makes any upgrade
+ * invisible, and still lets an explicitly saved value.
+ *
+ * Called from reset_phy() in eth_nbxv3.c ; it is during initr_net,
+ * after initr_env has loaded the saved environment and BEFORE
+ * mc_env_boot() evaluates ${mcinitcmd}, which is the earliest consumer.
+ * (board_late_init() would also be early enough, but it this logic is
+ * specific for the nbx boards, we do not want to touch.
+ * shared arch/arm/cpu/armv8/fsl-layerscape/soc.c
+ *
+ */
+
+#include <env.h>
+#include <linux/kernel.h>
+#include <vsprintf.h>
+
+#include "carrier.h"
+
+#ifndef NBXV3_CARRIER_DEFAULT
+#define NBXV3_CARRIER_DEFAULT "nbv30"
+#endif
+
+/*
+ * Placeholder for strap/EEPROM based identification.
+ * Returning NULL means "cannot tell".
+ */
+static const char *nbxv3_carrier_detect(void)
+{
+ /* TODO, not available yet */
+ return NULL;
+}
+
+void nbxv3_carrier_env_init(void)
+{
+ const char *carrier = env_get("carrier");
+ const char *detected;
+
+ if (carrier && *carrier) {
+ printf("Carrier: %s (from env)\n", carrier);
+ return;
+ }
+
+ detected = nbxv3_carrier_detect();
+ if (!detected)
+ detected = NBXV3_CARRIER_DEFAULT;
+
+ if (env_set("carrier", detected)) {
+ printf("Carrier: WARNING: cannot set ${carrier}\n");
+ return;
+ }
+
+ /* Not saved on purpose: saveenv on every boot would burn our NOR */
+ printf("Carrier: %s (default, not saved - `setenv carrier <name> && saveenv` to pin)\n", detected);
+}
diff --git a/board/nxp/lx2160a/nbxv3/carrier.h b/board/nxp/lx2160a/nbxv3/carrier.h
new file mode 100644
index 00000000000..e7eb42265e4
--- /dev/null
+++ b/board/nxp/lx2160a/nbxv3/carrier.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2026 Free Mobile - Vincent Jardin
+ */
+
+#ifndef __NBXV3_CARRIER_H
+#define __NBXV3_CARRIER_H
+
+/*
+ * Ensure ${carrier} is set before anything consumes it.
+ * It is idempotent, and it never overrides a value already present
+ * in the uboot's environment.
+ * It shall run after initr_env and before ${mcinitcmd} is evaluated.
+ */
+void nbxv3_carrier_env_init(void);
+
+#endif /* __NBXV3_CARRIER_H */
diff --git a/board/nxp/lx2160a/nbxv3/eth_nbxv3.c b/board/nxp/lx2160a/nbxv3/eth_nbxv3.c
index eb91d47add5..58bf8246aa0 100644
--- a/board/nxp/lx2160a/nbxv3/eth_nbxv3.c
+++ b/board/nxp/lx2160a/nbxv3/eth_nbxv3.c
@@ -21,6 +21,8 @@
#include <exports.h>
#include <fsl-mc/fsl_mc.h>
+#include "carrier.h"
+
DECLARE_GLOBAL_DATA_PTR;
int board_eth_init(struct bd_info *bis)
@@ -31,6 +33,14 @@ int board_eth_init(struct bd_info *bis)
#if defined(CONFIG_RESET_PHY_R)
void reset_phy(void)
{
+ /*
+ * MUST come first: mc_env_boot() evaluates ${mcinitcmd}, which
+ * imxtracts dpc-${carrier} / dpl-${carrier} out of the FIT. If
+ * ${carrier} is still unset a subimage named "dpc-" and the MC
+ * firmware never starts.
+ */
+ nbxv3_carrier_env_init();
+
#if defined(CONFIG_FSL_MC_ENET)
mc_env_boot();
#endif
--
2.43.0