Re: [PATCH v3 2/4] remoteproc: mediatek: Support MT8188 SCP core 1

2024-04-24 Thread AngeloGioacchino Del Regno

Il 24/04/24 05:03, Olivia Wen ha scritto:

MT8188 SCP has two RISC-V cores which is similar to MT8195 but without
L1TCM. We've added MT8188-specific functions to configure L1TCM in
multicore setups.

Signed-off-by: Olivia Wen 


Reviewed-by: AngeloGioacchino Del Regno 






[PATCH v3 2/4] remoteproc: mediatek: Support MT8188 SCP core 1

2024-04-23 Thread Olivia Wen
MT8188 SCP has two RISC-V cores which is similar to MT8195 but without
L1TCM. We've added MT8188-specific functions to configure L1TCM in
multicore setups.

Signed-off-by: Olivia Wen 
---
 drivers/remoteproc/mtk_scp.c | 146 ++-
 1 file changed, 143 insertions(+), 3 deletions(-)

diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 6751829..6295148 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -471,6 +471,86 @@ static int mt8186_scp_before_load(struct mtk_scp *scp)
return 0;
 }
 
+static int mt8188_scp_l2tcm_on(struct mtk_scp *scp)
+{
+   struct mtk_scp_of_cluster *scp_cluster = scp->cluster;
+
+   mutex_lock(_cluster->cluster_lock);
+
+   if (scp_cluster->l2tcm_refcnt == 0) {
+   /* clear SPM interrupt, SCP2SPM_IPC_CLR */
+   writel(0xff, scp->cluster->reg_base + MT8192_SCP2SPM_IPC_CLR);
+
+   /* Power on L2TCM */
+   scp_sram_power_on(scp->cluster->reg_base + 
MT8192_L2TCM_SRAM_PD_0, 0);
+   scp_sram_power_on(scp->cluster->reg_base + 
MT8192_L2TCM_SRAM_PD_1, 0);
+   scp_sram_power_on(scp->cluster->reg_base + 
MT8192_L2TCM_SRAM_PD_2, 0);
+   scp_sram_power_on(scp->cluster->reg_base + 
MT8192_L1TCM_SRAM_PDN, 0);
+   }
+
+   scp_cluster->l2tcm_refcnt += 1;
+
+   mutex_unlock(_cluster->cluster_lock);
+
+   return 0;
+}
+
+static int mt8188_scp_before_load(struct mtk_scp *scp)
+{
+   writel(1, scp->cluster->reg_base + MT8192_CORE0_SW_RSTN_SET);
+
+   mt8188_scp_l2tcm_on(scp);
+
+   scp_sram_power_on(scp->cluster->reg_base + MT8192_CPU0_SRAM_PD, 0);
+
+   /* enable MPU for all memory regions */
+   writel(0xff, scp->cluster->reg_base + MT8192_CORE0_MEM_ATT_PREDEF);
+
+   return 0;
+}
+
+static int mt8188_scp_c1_before_load(struct mtk_scp *scp)
+{
+   u32 sec_ctrl;
+   struct mtk_scp *scp_c0;
+   struct mtk_scp_of_cluster *scp_cluster = scp->cluster;
+
+   scp->data->scp_reset_assert(scp);
+
+   mt8188_scp_l2tcm_on(scp);
+
+   scp_sram_power_on(scp->cluster->reg_base + MT8195_CPU1_SRAM_PD, 0);
+
+   /* enable MPU for all memory regions */
+   writel(0xff, scp->cluster->reg_base + MT8195_CORE1_MEM_ATT_PREDEF);
+
+   /*
+* The L2TCM_OFFSET_RANGE and L2TCM_OFFSET shift the destination address
+* on SRAM when SCP core 1 accesses SRAM.
+*
+* This configuration solves booting the SCP core 0 and core 1 from
+* different SRAM address because core 0 and core 1 both boot from
+* the head of SRAM by default. this must be configured before boot SCP 
core 1.
+*
+* The value of L2TCM_OFFSET_RANGE is from the viewpoint of SCP core 1.
+* When SCP core 1 issues address within the range (L2TCM_OFFSET_RANGE),
+* the address will be added with a fixed offset (L2TCM_OFFSET) on the 
bus.
+* The shift action is tranparent to software.
+*/
+   writel(0, scp->cluster->reg_base + MT8195_L2TCM_OFFSET_RANGE_0_LOW);
+   writel(scp->sram_size, scp->cluster->reg_base + 
MT8195_L2TCM_OFFSET_RANGE_0_HIGH);
+
+   scp_c0 = list_first_entry(_cluster->mtk_scp_list, struct mtk_scp, 
elem);
+   writel(scp->sram_phys - scp_c0->sram_phys, scp->cluster->reg_base + 
MT8195_L2TCM_OFFSET);
+
+   /* enable SRAM offset when fetching instruction and data */
+   sec_ctrl = readl(scp->cluster->reg_base + MT8195_SEC_CTRL);
+   sec_ctrl |= MT8195_CORE_OFFSET_ENABLE_I | MT8195_CORE_OFFSET_ENABLE_D;
+   writel(sec_ctrl, scp->cluster->reg_base + MT8195_SEC_CTRL);
+
+   return 0;
+}
+
 static int mt8192_scp_before_load(struct mtk_scp *scp)
 {
/* clear SPM interrupt, SCP2SPM_IPC_CLR */
@@ -717,6 +797,47 @@ static void mt8183_scp_stop(struct mtk_scp *scp)
writel(0, scp->cluster->reg_base + MT8183_WDT_CFG);
 }
 
+static void mt8188_scp_l2tcm_off(struct mtk_scp *scp)
+{
+   struct mtk_scp_of_cluster *scp_cluster = scp->cluster;
+
+   mutex_lock(_cluster->cluster_lock);
+
+   if (scp_cluster->l2tcm_refcnt > 0)
+   scp_cluster->l2tcm_refcnt -= 1;
+
+   if (scp_cluster->l2tcm_refcnt == 0) {
+   /* Power off L2TCM */
+   scp_sram_power_off(scp->cluster->reg_base + 
MT8192_L2TCM_SRAM_PD_0, 0);
+   scp_sram_power_off(scp->cluster->reg_base + 
MT8192_L2TCM_SRAM_PD_1, 0);
+   scp_sram_power_off(scp->cluster->reg_base + 
MT8192_L2TCM_SRAM_PD_2, 0);
+   scp_sram_power_off(scp->cluster->reg_base + 
MT8192_L1TCM_SRAM_PDN, 0);
+   }
+
+   mutex_unlock(_cluster->cluster_lock);
+}
+
+static void mt8188_scp_stop(struct mtk_scp *scp)
+{
+   mt8188_scp_l2tcm_off(scp);
+
+   scp_sram_power_off(scp->cluster->reg_base + MT8192_CPU0_SRAM_PD, 0);
+
+   /* Disable SCP watchdog */
+   writel(0, scp->cluster->reg_base + MT8192_CORE0_WDT_CFG);
+}
+
+static void