summaryrefslogtreecommitdiff
path: root/drivers/remoteproc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/remoteproc')
-rw-r--r--drivers/remoteproc/mtk_common.h3
-rw-r--r--drivers/remoteproc/mtk_scp.c71
2 files changed, 59 insertions, 15 deletions
diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
index 1438159ae736..fea05bbba9aa 100644
--- a/drivers/remoteproc/mtk_common.h
+++ b/drivers/remoteproc/mtk_common.h
@@ -106,6 +106,9 @@ struct mtk_scp_of_cluster {
size_t l1tcm_size;
phys_addr_t l1tcm_phys;
struct list_head mtk_scp_list;
+ /* Prevent concurrent operations of this structure and L2TCM power control. */
+ struct mutex cluster_lock;
+ u32 l2tcm_refcnt;
};
struct mtk_scp {
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 4b0e1ae3a4b8..6926fd9e4c2e 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -454,19 +454,37 @@ static int mt8192_scp_before_load(struct mtk_scp *scp)
return 0;
}
-static int mt8195_scp_before_load(struct mtk_scp *scp)
+static int mt8195_scp_l2tcm_on(struct mtk_scp *scp)
{
- /* clear SPM interrupt, SCP2SPM_IPC_CLR */
- writel(0xff, scp->cluster->reg_base + MT8192_SCP2SPM_IPC_CLR);
+ struct mtk_scp_of_cluster *scp_cluster = scp->cluster;
+
+ mutex_lock(&scp_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,
+ MT8195_L1TCM_SRAM_PDN_RESERVED_RSI_BITS);
+ }
+
+ scp_cluster->l2tcm_refcnt += 1;
+ mutex_unlock(&scp_cluster->cluster_lock);
+
+ return 0;
+}
+
+static int mt8195_scp_before_load(struct mtk_scp *scp)
+{
writel(1, scp->cluster->reg_base + MT8192_CORE0_SW_RSTN_SET);
- /* enable SRAM clock */
- 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,
- MT8195_L1TCM_SRAM_PDN_RESERVED_RSI_BITS);
+ mt8195_scp_l2tcm_on(scp);
+
scp_sram_power_on(scp->cluster->reg_base + MT8192_CPU0_SRAM_PD, 0);
/* enable MPU for all memory regions */
@@ -479,6 +497,8 @@ static int mt8195_scp_c1_before_load(struct mtk_scp *scp)
{
scp->data->scp_reset_assert(scp);
+ mt8195_scp_l2tcm_on(scp);
+
scp_sram_power_on(scp->cluster->reg_base + MT8195_CPU1_SRAM_PD, 0);
/* enable MPU for all memory regions */
@@ -645,14 +665,31 @@ static void mt8192_scp_stop(struct mtk_scp *scp)
writel(0, scp->cluster->reg_base + MT8192_CORE0_WDT_CFG);
}
+static void mt8195_scp_l2tcm_off(struct mtk_scp *scp)
+{
+ struct mtk_scp_of_cluster *scp_cluster = scp->cluster;
+
+ mutex_lock(&scp_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,
+ MT8195_L1TCM_SRAM_PDN_RESERVED_RSI_BITS);
+ }
+
+ mutex_unlock(&scp_cluster->cluster_lock);
+}
+
static void mt8195_scp_stop(struct mtk_scp *scp)
{
- /* Disable SRAM clock */
- 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,
- MT8195_L1TCM_SRAM_PDN_RESERVED_RSI_BITS);
+ mt8195_scp_l2tcm_off(scp);
+
scp_sram_power_off(scp->cluster->reg_base + MT8192_CPU0_SRAM_PD, 0);
/* Disable SCP watchdog */
@@ -661,6 +698,8 @@ static void mt8195_scp_stop(struct mtk_scp *scp)
static void mt8195_scp_c1_stop(struct mtk_scp *scp)
{
+ mt8195_scp_l2tcm_off(scp);
+
/* Power off CPU SRAM */
scp_sram_power_off(scp->cluster->reg_base + MT8195_CPU1_SRAM_PD, 0);
@@ -1109,6 +1148,7 @@ static int scp_probe(struct platform_device *pdev)
}
INIT_LIST_HEAD(&scp_cluster->mtk_scp_list);
+ mutex_init(&scp_cluster->cluster_lock);
ret = devm_of_platform_populate(dev);
if (ret)
@@ -1132,6 +1172,7 @@ static void scp_remove(struct platform_device *pdev)
rproc_del(scp->rproc);
scp_free(scp);
}
+ mutex_destroy(&scp_cluster->cluster_lock);
}
static const struct mtk_scp_of_data mt8183_of_data = {