Skip to content

Commit 61f6f68

Browse files
Apurva Nandanmathieupoirier
authored andcommitted
remoteproc: k3-r5: Wait for core0 power-up before powering up core1
PSC controller has a limitation that it can only power-up the second core when the first core is in ON state. Power-state for core0 should be equal to or higher than core1, else the kernel is seen hanging during rproc loading. Make the powering up of cores sequential, by waiting for the current core to power-up before proceeding to the next core, with a timeout of 2sec. Add a wait queue event in k3_r5_cluster_rproc_init call, that will wait for the current core to be released from reset before proceeding with the next core. Fixes: 6dedbd1 ("remoteproc: k3-r5: Add a remoteproc driver for R5F subsystem") Signed-off-by: Apurva Nandan <[email protected]> Signed-off-by: Beleswar Padhi <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mathieu Poirier <[email protected]>
1 parent faba7db commit 61f6f68

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

drivers/remoteproc/ti_k3_r5_remoteproc.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,14 @@ struct k3_r5_soc_data {
103103
* @dev: cached device pointer
104104
* @mode: Mode to configure the Cluster - Split or LockStep
105105
* @cores: list of R5 cores within the cluster
106+
* @core_transition: wait queue to sync core state changes
106107
* @soc_data: SoC-specific feature data for a R5FSS
107108
*/
108109
struct k3_r5_cluster {
109110
struct device *dev;
110111
enum cluster_mode mode;
111112
struct list_head cores;
113+
wait_queue_head_t core_transition;
112114
const struct k3_r5_soc_data *soc_data;
113115
};
114116

@@ -128,6 +130,7 @@ struct k3_r5_cluster {
128130
* @atcm_enable: flag to control ATCM enablement
129131
* @btcm_enable: flag to control BTCM enablement
130132
* @loczrama: flag to dictate which TCM is at device address 0x0
133+
* @released_from_reset: flag to signal when core is out of reset
131134
*/
132135
struct k3_r5_core {
133136
struct list_head elem;
@@ -144,6 +147,7 @@ struct k3_r5_core {
144147
u32 atcm_enable;
145148
u32 btcm_enable;
146149
u32 loczrama;
150+
bool released_from_reset;
147151
};
148152

149153
/**
@@ -460,6 +464,8 @@ static int k3_r5_rproc_prepare(struct rproc *rproc)
460464
ret);
461465
return ret;
462466
}
467+
core->released_from_reset = true;
468+
wake_up_interruptible(&cluster->core_transition);
463469

464470
/*
465471
* Newer IP revisions like on J7200 SoCs support h/w auto-initialization
@@ -1140,6 +1146,12 @@ static int k3_r5_rproc_configure_mode(struct k3_r5_rproc *kproc)
11401146
return ret;
11411147
}
11421148

1149+
/*
1150+
* Skip the waiting mechanism for sequential power-on of cores if the
1151+
* core has already been booted by another entity.
1152+
*/
1153+
core->released_from_reset = c_state;
1154+
11431155
ret = ti_sci_proc_get_status(core->tsp, &boot_vec, &cfg, &ctrl,
11441156
&stat);
11451157
if (ret < 0) {
@@ -1280,6 +1292,26 @@ static int k3_r5_cluster_rproc_init(struct platform_device *pdev)
12801292
cluster->mode == CLUSTER_MODE_SINGLECPU ||
12811293
cluster->mode == CLUSTER_MODE_SINGLECORE)
12821294
break;
1295+
1296+
/*
1297+
* R5 cores require to be powered on sequentially, core0
1298+
* should be in higher power state than core1 in a cluster
1299+
* So, wait for current core to power up before proceeding
1300+
* to next core and put timeout of 2sec for each core.
1301+
*
1302+
* This waiting mechanism is necessary because
1303+
* rproc_auto_boot_callback() for core1 can be called before
1304+
* core0 due to thread execution order.
1305+
*/
1306+
ret = wait_event_interruptible_timeout(cluster->core_transition,
1307+
core->released_from_reset,
1308+
msecs_to_jiffies(2000));
1309+
if (ret <= 0) {
1310+
dev_err(dev,
1311+
"Timed out waiting for %s core to power up!\n",
1312+
rproc->name);
1313+
return ret;
1314+
}
12831315
}
12841316

12851317
return 0;
@@ -1709,6 +1741,7 @@ static int k3_r5_probe(struct platform_device *pdev)
17091741
cluster->dev = dev;
17101742
cluster->soc_data = data;
17111743
INIT_LIST_HEAD(&cluster->cores);
1744+
init_waitqueue_head(&cluster->core_transition);
17121745

17131746
ret = of_property_read_u32(np, "ti,cluster-mode", &cluster->mode);
17141747
if (ret < 0 && ret != -EINVAL) {

0 commit comments

Comments
 (0)