[PATCH v7 1/3] remoteproc: k3-r5: Simplify cluster mode setting usage

From: Devarsh Thakkar
Date: Fri Mar 10 2023 - 11:29:44 EST


Check the validity of mode against SoC supported modes right
at the probe to minimize the usage of same check further in the code.

Set default value of cluster-mode only if cluster-mode device tree property
is empty.

In case devicetree provided cluster-mode property is invalid For e.g. using
CLUSTER_MODE_SINGLECPU on any SoC other than am64x then return error.

If firmware has set the PROC_BOOT_STATUS_FLAG_R5_SINGLECORE_ONLY flag then
what it means is that only CLUSTER_MODE_SINGLECPU is possible to use [1]
and hence there is no need to check for soc_data->single_cpu_mode first and
then checking cluster mode.

PROC_BOOT_CFG_FLAG_R5_SINGLE_CORE flag can be set directly for
CLUSTER_MODE_SINGLECPU without checking for soc_data->single_cpu_mode since
that check has already been done during probe.

Link:
[1] https://software-dl.ti.com/tisci/esd/latest/2_tisci_msgs/security/PROC_BOOT.html?highlight=singlecore_only#arm-r5

Signed-off-by: Devarsh Thakkar <devarsht@xxxxxx>
---
V1->V6: No changelog (Patch introduced in V6)
V6->V7:
- Override to appropriate cluster mode per firmware status flag directly
without checking for soc_data
- Set appropriate mode as default if not provided in DT
- Check mode validity against SoC data during probe
- Rebase on top of 6.3 linux-next
---
drivers/remoteproc/ti_k3_r5_remoteproc.c | 57 +++++++++++++-----------
1 file changed, 30 insertions(+), 27 deletions(-)

diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c b/drivers/remoteproc/ti_k3_r5_remoteproc.c
index 0481926c6975..c2ec0f432921 100644
--- a/drivers/remoteproc/ti_k3_r5_remoteproc.c
+++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c
@@ -852,38 +852,33 @@ static int k3_r5_rproc_configure(struct k3_r5_rproc *kproc)
dev_dbg(dev, "boot_vector = 0x%llx, cfg = 0x%x ctrl = 0x%x stat = 0x%x\n",
boot_vec, cfg, ctrl, stat);

- /* check if only Single-CPU mode is supported on applicable SoCs */
- if (cluster->soc_data->single_cpu_mode) {
- single_cpu =
- !!(stat & PROC_BOOT_STATUS_FLAG_R5_SINGLECORE_ONLY);
- if (single_cpu && cluster->mode == CLUSTER_MODE_SPLIT) {
- dev_err(cluster->dev, "split-mode not permitted, force configuring for single-cpu mode\n");
- cluster->mode = CLUSTER_MODE_SINGLECPU;
- }
- goto config;
+ single_cpu = !!(stat & PROC_BOOT_STATUS_FLAG_R5_SINGLECORE_ONLY);
+ lockstep_en = !!(stat & PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED);
+
+ /* Override to single CPU mode if set in status flag */
+ if (single_cpu && cluster->mode == CLUSTER_MODE_SPLIT) {
+ dev_err(cluster->dev, "split-mode not permitted, force configuring for single-cpu mode\n");
+ cluster->mode = CLUSTER_MODE_SINGLECPU;
}

- /* check conventional LockStep vs Split mode configuration */
- lockstep_en = !!(stat & PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED);
+ /* Override to split mode if lockstep enable bit is not set in status flag */
if (!lockstep_en && cluster->mode == CLUSTER_MODE_LOCKSTEP) {
dev_err(cluster->dev, "lockstep mode not permitted, force configuring for split-mode\n");
cluster->mode = CLUSTER_MODE_SPLIT;
}

-config:
/* always enable ARM mode and set boot vector to 0 */
boot_vec = 0x0;
if (core == core0) {
clr_cfg = PROC_BOOT_CFG_FLAG_R5_TEINIT;
- if (cluster->soc_data->single_cpu_mode) {
- /*
- * Single-CPU configuration bit can only be configured
- * on Core0 and system firmware will NACK any requests
- * with the bit configured, so program it only on
- * permitted cores
- */
- if (cluster->mode == CLUSTER_MODE_SINGLECPU)
- set_cfg = PROC_BOOT_CFG_FLAG_R5_SINGLE_CORE;
+ /*
+ * Single-CPU configuration bit can only be configured
+ * on Core0 and system firmware will NACK any requests
+ * with the bit configured, so program it only on
+ * permitted cores
+ */
+ if (cluster->mode == CLUSTER_MODE_SINGLECPU) {
+ set_cfg = PROC_BOOT_CFG_FLAG_R5_SINGLE_CORE;
} else {
/*
* LockStep configuration bit is Read-only on Split-mode
@@ -1700,12 +1695,6 @@ static int k3_r5_probe(struct platform_device *pdev)
return -ENOMEM;

cluster->dev = dev;
- /*
- * default to most common efuse configurations - Split-mode on AM64x
- * and LockStep-mode on all others
- */
- cluster->mode = data->single_cpu_mode ?
- CLUSTER_MODE_SPLIT : CLUSTER_MODE_LOCKSTEP;
cluster->soc_data = data;
INIT_LIST_HEAD(&cluster->cores);

@@ -1716,6 +1705,20 @@ static int k3_r5_probe(struct platform_device *pdev)
return ret;
}

+ if (ret == -EINVAL) {
+ /*
+ * default to most common efuse configurations - Split-mode on AM64x
+ * and LockStep-mode on all others
+ */
+ cluster->mode = data->single_cpu_mode ?
+ CLUSTER_MODE_SPLIT : CLUSTER_MODE_LOCKSTEP;
+ }
+
+ if (cluster->mode == CLUSTER_MODE_SINGLECPU && !data->single_cpu_mode) {
+ dev_err(dev, "Cluster mode = %d is not supported on this SoC\n", cluster->mode);
+ return -EINVAL;
+ }
+
num_cores = of_get_available_child_count(np);
if (num_cores != 2) {
dev_err(dev, "MCU cluster requires both R5F cores to be enabled, num_cores = %d\n",
--
2.34.1