[PATCH] net: ti: icssg: Read firmware name from device-tree

MD Danish Anwar danishanwar at ti.com
Wed Jul 2 13:35:45 CEST 2025


Update the ICSSG PRU Ethernet driver to read PRU/RTU/TXPRU firmware names
from the Device Tree using the "firmware-name" property, instead of relying
on the hard-coded firmware names. The firmware names are parsed during
prueth_probe() and stored in the prueth->firmwares for each slice. The
driver now uses these dynamically loaded names when starting the PRU cores.

This change improves flexibility and allows firmware selection to be
controlled via the device tree, making the driver more adaptable to
different platforms and firmware configurations.

Signed-off-by: MD Danish Anwar <danishanwar at ti.com>
---
This change is already part of the upstream Linux ICSSG driver.
Corresponding Linux commit [1]

All u-boot CI/CD checks [2] are passing for this patch. PR for this patch in u-boot is [3]

[1] https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=ffe8a4909176
[2] https://dev.azure.com/u-boot/u-boot/_build/results?buildId=11536&view=results
[3] https://github.com/u-boot/u-boot/pull/793

 drivers/net/ti/icssg_prueth.c | 54 ++++++++++++++++++++++-------------
 drivers/net/ti/icssg_prueth.h |  7 +++++
 2 files changed, 41 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ti/icssg_prueth.c b/drivers/net/ti/icssg_prueth.c
index 2639f960631..d8df3c9afb0 100644
--- a/drivers/net/ti/icssg_prueth.c
+++ b/drivers/net/ti/icssg_prueth.c
@@ -63,6 +63,7 @@
 
 /* Number of PRU Cores per Slice */
 #define ICSSG_NUM_PRU_CORES		3
+#define ICSSG_NUM_FIRMWARES		6
 
 static int icssg_gmii_select(struct prueth_priv *priv)
 {
@@ -192,25 +193,6 @@ static int icssg_update_link(struct prueth_priv *priv)
 	return phy->link;
 }
 
-struct icssg_firmwares {
-	char *pru;
-	char *rtu;
-	char *txpru;
-};
-
-static struct icssg_firmwares icssg_emac_firmwares[] = {
-	{
-		.pru = "/lib/firmware/ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
-		.rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
-		.txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
-	},
-	{
-		.pru = "/lib/firmware/ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
-		.rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
-		.txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru1-prueth-fw.elf",
-	}
-};
-
 static int icssg_start_pru_cores(struct udevice *dev)
 {
 	struct prueth_priv *priv = dev_get_priv(dev);
@@ -223,7 +205,7 @@ static int icssg_start_pru_cores(struct udevice *dev)
 
 	slice = priv->port_id;
 	index = slice * ICSSG_NUM_PRU_CORES;
-	firmwares = icssg_emac_firmwares;
+	firmwares = prueth->firmwares;
 
 	ofnode_read_u32_index(dev_ofnode(prueth->dev), "ti,prus", index, &phandle);
 	ret = uclass_get_device_by_phandle_id(UCLASS_REMOTEPROC, phandle, &rproc_dev);
@@ -476,6 +458,24 @@ static const struct eth_ops prueth_ops = {
 	.stop		= prueth_stop,
 };
 
+static char *prepend_fw_path(const char *fw_name)
+{
+	static const char fw_dir[] = "/lib/firmware/";
+	char *result;
+	int len;
+
+	if (!fw_name)
+		return NULL;
+
+	len = strlen(fw_dir) + strlen(fw_name) + 1;
+	result = malloc(len);
+	if (!result)
+		return NULL;
+
+	sprintf(result, "%s%s", fw_dir, fw_name);
+	return result;
+}
+
 static int icssg_ofdata_parse_phy(struct udevice *dev)
 {
 	struct prueth_priv *priv = dev_get_priv(dev);
@@ -534,6 +534,8 @@ static int prueth_probe(struct udevice *dev)
 	struct udevice **prussdev = NULL;
 	ofnode eth_ports_node, eth_node;
 	struct udevice *port_dev;
+	const char **fw_names;
+	int fw_count, i;
 	int ret = 0;
 
 	prueth->dev = dev;
@@ -659,6 +661,18 @@ static int prueth_probe(struct udevice *dev)
 		}
 	}
 
+	/* Parse firmware-name property from DT */
+	fw_count = dev_read_string_list(dev, "firmware-name", &fw_names);
+	if (fw_count != ICSSG_NUM_FIRMWARES) {
+		dev_err(dev, "Expected %d firmware names, got %d\n", ICSSG_NUM_FIRMWARES, fw_count);
+		return -EINVAL;
+	}
+	for (i = 0; i < 2; i++) {
+		prueth->firmwares[i].pru   = prepend_fw_path(fw_names[i * 3 + 0]);
+		prueth->firmwares[i].rtu   = prepend_fw_path(fw_names[i * 3 + 1]);
+		prueth->firmwares[i].txpru = prepend_fw_path(fw_names[i * 3 + 2]);
+	}
+
 	return 0;
 out:
 	clk_disable(&prueth->mdiofck);
diff --git a/drivers/net/ti/icssg_prueth.h b/drivers/net/ti/icssg_prueth.h
index c69cfd4f162..d88b6fa88e7 100644
--- a/drivers/net/ti/icssg_prueth.h
+++ b/drivers/net/ti/icssg_prueth.h
@@ -38,6 +38,12 @@ enum prueth_port {
 	PRUETH_PORT_MII1,	/* physical port MII 1 */
 };
 
+struct icssg_firmwares {
+	char *pru;
+	char *rtu;
+	char *txpru;
+};
+
 struct prueth {
 	struct udevice		*dev;
 	struct udevice		*pruss;
@@ -66,6 +72,7 @@ struct prueth {
 	u8			rtu_core_id;
 	u8			txpru_core_id;
 	u8			icssg_hwcmdseq;
+	struct icssg_firmwares  firmwares[PRUETH_NUM_MACS];
 };
 
 struct prueth_priv {

base-commit: 7027b445cc0bfb86204ecb1f1fe596f5895048d9
-- 
2.34.1



More information about the U-Boot mailing list