remoteproc/k3-r5: fix probe failure on Split-mode _only_ devices
authorSuman Anna <s-anna@ti.com>
Fri, 20 Dec 2019 21:48:58 +0000 (15:48 -0600)
committerSuman Anna <s-anna@ti.com>
Mon, 23 Dec 2019 16:54:59 +0000 (10:54 -0600)
The R5F subsystem/cluster on K3 SoCs can support both LockStep and
Split-modes (superset) or just Split-mode depending on an eFUSE
capability register. The k3_r5_rproc_configure() function is used to
configure the R5F remote processors in remoteproc mode, and performs
this by requesting the System Firmware as per the requested DT properties.
This function initializes identical settings for both cores in LockStep
mode by first programming it for Split-mode and then reverting back
to LockStep mode after the settings initialization. The Split-mode
setting is done on Core0 always irrespective of the mode.

The LockStep configuration bit is Read-only though on Split-mode _only_
devices and as such the System Firmware does not allow the LockStep
mode bit to be configured on such devices. The current logic in
k3_r5_rproc_configure() fails on Split-mode devices because of this
unconditional programming of the LockStep mode bit.

Fix this by limiting the LockStep mode bit clear configuration only on
devices supporting both LockStep/Split-modes.

Reported-by: Andreas Dannenberg <dannenberg@ti.com>
Signed-off-by: Suman Anna <s-anna@ti.com>
drivers/remoteproc/ti_k3_r5_remoteproc.c

index 3d993ec1f5ea3bb8c90ef5b1a71c22dc632b1a82..51b0bd3ab99c6a0f9e45cf67512fee7e72ddc025 100644 (file)
@@ -661,6 +661,7 @@ static int k3_r5_rproc_configure(struct k3_r5_rproc *kproc)
        u32 ctrl = 0, cfg = 0, stat = 0;
        u32 set_cfg = 0, clr_cfg = 0;
        u64 boot_vec = 0;
+       bool lockstep_en;
        int ret;
 
        core0 = list_first_entry(&cluster->cores, struct k3_r5_core, elem);
@@ -674,8 +675,8 @@ 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);
 
-       if (!(stat & PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED) &&
-           cluster->mode) {
+       lockstep_en = !!(stat & PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED);
+       if (!lockstep_en && cluster->mode) {
                dev_err(cluster->dev, "lockstep mode not permitted, force configuring for split-mode\n");
                cluster->mode = 0;
        }
@@ -684,7 +685,8 @@ static int k3_r5_rproc_configure(struct k3_r5_rproc *kproc)
        boot_vec = 0x0;
        if (core == core0) {
                clr_cfg = PROC_BOOT_CFG_FLAG_R5_TEINIT;
-               clr_cfg |= PROC_BOOT_CFG_FLAG_R5_LOCKSTEP;
+               if (lockstep_en)
+                       clr_cfg |= PROC_BOOT_CFG_FLAG_R5_LOCKSTEP;
        }
 
        if (core->atcm_enable)