From: Jun Yang <jun.yang at nxp.com>
Calculate the maximum BPID dynamically from the device tree
configuration instead of using a hardcoded value. This ensures
correct operation across different DPAA hardware configurations.
Also update the default BMAN HW version for Layerscape devices.
Signed-off-by: Jun Yang <jun.yang at nxp.com>
---
drivers/bus/dpaa/base/qbman/bman_driver.c | 65 ++++++++++++++++-------
drivers/bus/dpaa/include/fsl_bman.h | 5 ++
2 files changed, 52 insertions(+), 18 deletions(-)
diff --git a/drivers/bus/dpaa/base/qbman/bman_driver.c b/drivers/bus/dpaa/base/qbman/bman_driver.c
index 71a2028383..9021d43688 100644
--- a/drivers/bus/dpaa/base/qbman/bman_driver.c
+++ b/drivers/bus/dpaa/base/qbman/bman_driver.c
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
*
* Copyright 2008-2016 Freescale Semiconductor Inc.
- * Copyright 2017 NXP
+ * Copyright 2017,2026 NXP
*
*/
@@ -17,7 +17,7 @@
* Global variables of the max portal/pool number this bman version supported
*/
static u16 bman_ip_rev;
-u16 bman_pool_max;
+u16 bman_pool_max = BMAN_MAX_POOLS;
static void *bman_ccsr_map;
/*****************/
@@ -180,9 +180,16 @@ int bman_init_ccsr(const struct device_node *node)
return 0;
}
+#define BPID_RANGE_START_INDEX 0
+#define BPID_RANGE_COUNT_INDEX 1
+
int bman_global_init(void)
{
const struct device_node *dt_node;
+ const rte_be32_t *range;
+ uint32_t start = 0, count = 0;
+ int ret;
+ size_t len;
static int done;
if (done)
@@ -198,7 +205,6 @@ int bman_global_init(void)
if (of_device_is_compatible(dt_node, "fsl,bman-portal-1.0") ||
of_device_is_compatible(dt_node, "fsl,bman-portal-1.0.0")) {
bman_ip_rev = BMAN_REV10;
- bman_pool_max = 64;
} else if (of_device_is_compatible(dt_node, "fsl,bman-portal-2.0") ||
of_device_is_compatible(dt_node, "fsl,bman-portal-2.0.8")) {
bman_ip_rev = BMAN_REV20;
@@ -208,26 +214,49 @@ int bman_global_init(void)
of_device_is_compatible(dt_node, "fsl,bman-portal-2.1.2") ||
of_device_is_compatible(dt_node, "fsl,bman-portal-2.1.3")) {
bman_ip_rev = BMAN_REV21;
- bman_pool_max = 64;
} else {
- pr_warn("unknown BMan version in portal node,default "
- "to rev1.0");
- bman_ip_rev = BMAN_REV10;
- bman_pool_max = 64;
+ pr_warn("unknown bman version in portal node, default to rev2.1.0");
+ bman_ip_rev = BMAN_REV21;
+ }
+
+ for_each_compatible_node(dt_node, NULL, "fsl,bpid-range") {
+ range = of_get_property(dt_node, "fsl,bpid-range", &len);
+ if (!range || len < (int)(2 * sizeof(rte_be32_t)))
+ continue;
+ start = rte_be_to_cpu_32(range[BPID_RANGE_START_INDEX]);
+ count = rte_be_to_cpu_32(range[BPID_RANGE_COUNT_INDEX]);
+ if (!count) {
+ pr_warn("Empty BPID range in DTS, using default pool max\n");
+ continue;
+ }
+ /* The depletion mask and the SCN registers only describe
+ * BPID 0..BMAN_MAX_POOLS-1, and bman_create_portal() walks
+ * this bound with a u8, so a larger value from the DTS would
+ * write past the last SCN register and never terminate.
+ */
+ if (start + count > BMAN_MAX_POOLS) {
+ pr_warn("BPID range %u+%u exceeds max %u, clamping\n",
+ start, count, BMAN_MAX_POOLS);
+ bman_pool_max = BMAN_MAX_POOLS;
+ } else {
+ bman_pool_max = start + count;
+ }
+ pr_info("Max BPID: %d, fixed BPID < %d", bman_pool_max, start);
+ break;
}
+ if (!count)
+ pr_warn("No BPID range found in DTS, using default pool max\n");
- if (!bman_ip_rev) {
- pr_err("Unknown bman portal version\n");
+ dt_node = of_find_compatible_node(NULL, NULL, "fsl,bman");
+ if (!dt_node) {
+ pr_err("No bman device node available");
return -ENODEV;
}
- {
- const struct device_node *dn = of_find_compatible_node(NULL,
- NULL, "fsl,bman");
- if (!dn)
- pr_err("No bman device node available");
-
- if (bman_init_ccsr(dn))
- pr_err("BMan CCSR map failed.");
+
+ ret = bman_init_ccsr(dt_node);
+ if (ret) {
+ pr_err("Failed(%d) to init bman ccsr", ret);
+ return ret;
}
done = 1;
diff --git a/drivers/bus/dpaa/include/fsl_bman.h b/drivers/bus/dpaa/include/fsl_bman.h
index 2d24b89889..639e0edc96 100644
--- a/drivers/bus/dpaa/include/fsl_bman.h
+++ b/drivers/bus/dpaa/include/fsl_bman.h
@@ -21,6 +21,11 @@ struct bman_depletion {
u32 state[2];
};
+/* Number of buffer pools the depletion mask above, and the BMan portal SCN
+ * registers, can describe. BPIDs are limited to this range.
+ */
+#define BMAN_MAX_POOLS 64U
+
static inline void bman_depletion_init(struct bman_depletion *c)
{
c->state[0] = c->state[1] = 0;
--
2.25.1