diff options
| author | Marek Vasut <[email protected]> | 2026-08-11 00:35:06 +0200 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2026-08-20 12:15:23 -0600 |
| commit | 0771457a0ad5c8e48712d227b07c4b4974671bf1 (patch) | |
| tree | 2ff0f698d3840cb9b41b8531960514a26dd94632 | |
| parent | 31bf91b6a44bad0d9bdae28f97a3192c51601b87 (diff) | |
remoteproc: renesas: rsip: Implement SCMI core stop
Currently the driver could only start cores. Add support for stopping
CR52 and CA720AE cores via SCMI. Note that the SCP core is controlled
via direct register IO.
Signed-off-by: Marek Vasut <[email protected]>
| -rw-r--r-- | drivers/remoteproc/renesas_rsip.c | 67 |
1 files changed, 46 insertions, 21 deletions
diff --git a/drivers/remoteproc/renesas_rsip.c b/drivers/remoteproc/renesas_rsip.c index 96f3bf77eb8..7c2643e9728 100644 --- a/drivers/remoteproc/renesas_rsip.c +++ b/drivers/remoteproc/renesas_rsip.c @@ -100,22 +100,53 @@ static void scp_send_interrupt(void) * This must be removed when proper upstream SCP port exists */ #define SCMI_PD_POWER_STATE_SET_BOOTADDR 0x4411 +#define SCMI_PD_POWER_STATE_SET_STATE_ON 0 +#define SCMI_PD_POWER_STATE_SET_STATE_OFF BIT(30) /** - * scp_cpu_core_start() - Boot CPU core by invoking SCP via SCMI + * scp_cpu_core_id_to_domain() - Convert core ID to SCMI domain ID + * @core: CPU core + * @domain: SCMI domain + */ +static int scp_cpu_core_id_to_domain(const u32 core, u32 *domain) +{ + if (core >= RCAR5_SCP_CORES && core < RCAR5_SCP_CORES + RCAR5_CR52_CORES) { + /* CR52 */ + *domain = core - RCAR5_SCP_CORES + SCMI_PD_CORE_RT_CORE00; + return 0; + } + + if (core >= RCAR5_SCP_CORES + RCAR5_CR52_CORES && + core < RCAR5_SCP_CORES + RCAR5_CR52_CORES + RCAR5_CA720_CORES) { + /* CA720 */ + *domain = core - RCAR5_SCP_CORES - RCAR5_CR52_CORES + SCMI_PD_CORE_AP_CORE00; + return 0; + } + + return -EINVAL; +} + +/** + * scp_cpu_core_set() - Start or stop CPU core by invoking SCP via SCMI * @core: CPU core to boot * @ep: Entry point + * @state: Power state, 0: Power on, BIT(30): Power off */ -static void scp_cpu_core_start(const u32 core, const u32 ep) +static int scp_cpu_core_set(const u32 core, const u32 ep, const u32 state) { struct scp_scmi_shmem *shmem = (struct scp_scmi_shmem *)SCP_SCMI_SHMEM_AREA09; struct scp_scmi_pd_power_state_set_a2p scmi_parameter = { .flags = 1, /* Asynchronous power transition using APMU */ - .domain_id = core, - .power_state = 0, /* Power on */ + .domain_id = 0, /* Core ID */ + .power_state = state, /* 0: Power on, BIT(30): Power off */ .boot_addr = ep, }; u32 status; + int ret; + + ret = scp_cpu_core_id_to_domain(core, &scmi_parameter.domain_id); + if (ret) + return ret; /* Wait for SCP to be free, then set it busy */ scp_wait_fw_free(); @@ -136,7 +167,10 @@ static void scp_cpu_core_start(const u32 core, const u32 ep) if (status) { printf("SCP POWER_STATE_SET domain %d failed, status=0x%x (%d)\n", scmi_parameter.domain_id, status, status); + return -EINVAL; } + + return 0; } /** @@ -214,27 +248,16 @@ static int renesas_rsip_rproc_init(struct udevice *dev) static int renesas_rsip_rproc_start(struct udevice *dev) { struct renesas_rsip_rproc_privdata *priv = dev_get_priv(dev); - int scmi_core; if (priv->core_id == 0) { /* SCP */ clrbits_le32(SCP_CPUWAIT, SCP_CPUWAIT_WAIT); return 0; - } else if (priv->core_id >= RCAR5_SCP_CORES && - priv->core_id < RCAR5_SCP_CORES + RCAR5_CR52_CORES) { - /* CR52 */ - scmi_core = priv->core_id - RCAR5_SCP_CORES + - SCMI_PD_CORE_RT_CORE00; - } else if (priv->core_id >= RCAR5_SCP_CORES + RCAR5_CR52_CORES && - priv->core_id < RCAR5_SCP_CORES + RCAR5_CR52_CORES + RCAR5_CA720_CORES) { - /* CA720 */ - scmi_core = priv->core_id - RCAR5_SCP_CORES - RCAR5_CR52_CORES + - SCMI_PD_CORE_AP_CORE00; + } else { + /* CR52 or CA720 */ + return scp_cpu_core_set(priv->core_id, priv->ep, + SCMI_PD_POWER_STATE_SET_STATE_ON); } - - scp_cpu_core_start(scmi_core, priv->ep); - - return 0; } /** @@ -250,9 +273,11 @@ static int renesas_rsip_rproc_stop(struct udevice *dev) if (priv->core_id == 0) { /* SCP */ return renesas_rsip_rproc_init(dev); + } else { + /* CR52 or CA720 */ + return scp_cpu_core_set(priv->core_id, 0, + SCMI_PD_POWER_STATE_SET_STATE_OFF); } - - return 0; } /** |
