Currently the driver can not report core status. Determine SCP core
state via SCP_CPUWAIT_WAIT bit and use SCMI PD protocol POWER_STATE_GET
call to determine CR52 and CA720AE core state. Report the core states.

Signed-off-by: Marek Vasut <[email protected]>
---
Cc: Nobuhiro Iwamatsu <[email protected]>
Cc: Tom Rini <[email protected]>
Cc: [email protected]
---
 drivers/remoteproc/renesas_rsip.c | 58 +++++++++++++++++++++++++++++--
 1 file changed, 56 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/renesas_rsip.c 
b/drivers/remoteproc/renesas_rsip.c
index 7c2643e9728..c71424a2c16 100644
--- a/drivers/remoteproc/renesas_rsip.c
+++ b/drivers/remoteproc/renesas_rsip.c
@@ -102,6 +102,7 @@ static void scp_send_interrupt(void)
 #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)
+#define SCMI_PD_POWER_STATE_GET                        0x4405
 
 /**
  * scp_cpu_core_id_to_domain() - Convert core ID to SCMI domain ID
@@ -173,6 +174,52 @@ static int scp_cpu_core_set(const u32 core, const u32 ep, 
const u32 state)
        return 0;
 }
 
+/**
+ * scp_cpu_core_get() - Get CPU core state by invoking SCP via SCMI
+ * @core: CPU core to get
+ */
+static int scp_cpu_core_get(const u32 core)
+{
+       struct scp_scmi_shmem *shmem = (struct scp_scmi_shmem 
*)SCP_SCMI_SHMEM_AREA09;
+       u32 status, pwr;
+       u32 domain_id;  /* Core ID */
+       int ret;
+
+       ret = scp_cpu_core_id_to_domain(core, &domain_id);
+       if (ret)
+               return ret;
+
+       /* Wait for SCP to be free, then set it busy */
+       scp_wait_fw_free();
+       shmem->status &= ~SCP_SCMI_STATUS_FREE;
+       shmem->flags = 0;
+
+       /* Set up the message and copy it to SHMEM */
+       shmem->message_header = SCMI_PD_POWER_STATE_GET;
+       memcpy(shmem->payload, &domain_id, sizeof(domain_id));
+       shmem->length = sizeof(shmem->message_header) + sizeof(domain_id);
+
+       /* Send message to SCP and wait for completion */
+       scp_send_interrupt();
+       scp_wait_fw_free();
+
+       /* Read back the result */
+       status = readl((uintptr_t)shmem->payload);
+       if (status) {
+               printf("SCP POWER_STATE_GET domain %d failed, status=0x%x 
(%d)\n",
+                      domain_id, status, status);
+               return -EINVAL;
+       }
+
+       pwr = readl((uintptr_t)(shmem->payload + 4));
+       if (pwr == SCMI_PD_POWER_STATE_SET_STATE_ON)
+               return 0;
+       else if (pwr == SCMI_PD_POWER_STATE_SET_STATE_OFF)
+               return 1;
+       else
+               return -EINVAL;
+}
+
 /**
  * struct renesas_rsip_rproc_privdata - remote processor private data
  * @core_id:           CPU core id
@@ -301,8 +348,15 @@ static int renesas_rsip_rproc_reset(struct udevice *dev)
  */
 static int renesas_rsip_rproc_is_running(struct udevice *dev)
 {
-       /* We assume the core is stopped. */
-       return 1;
+       struct renesas_rsip_rproc_privdata *priv = dev_get_priv(dev);
+
+       if (priv->core_id == 0) {
+               /* SCP */
+               return readl(SCP_CPUWAIT) & SCP_CPUWAIT_WAIT;
+       } else {
+               /* CR52 or CA720 */
+               return scp_cpu_core_get(priv->core_id);
+       }
 }
 
 /**
-- 
2.53.0

Reply via email to