Skip to content

Commit 928a55a

Browse files
Olivia Wenmathieupoirier
authored andcommitted
remoteproc: mediatek: Support MT8188 SCP core 1
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 <[email protected]> Reviewed-by: AngeloGioacchino Del Regno <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mathieu Poirier <[email protected]>
1 parent 91e0d56 commit 928a55a

File tree

1 file changed

+143
-3
lines changed

1 file changed

+143
-3
lines changed

drivers/remoteproc/mtk_scp.c

Lines changed: 143 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,86 @@ static int mt8186_scp_before_load(struct mtk_scp *scp)
471471
return 0;
472472
}
473473

474+
static int mt8188_scp_l2tcm_on(struct mtk_scp *scp)
475+
{
476+
struct mtk_scp_of_cluster *scp_cluster = scp->cluster;
477+
478+
mutex_lock(&scp_cluster->cluster_lock);
479+
480+
if (scp_cluster->l2tcm_refcnt == 0) {
481+
/* clear SPM interrupt, SCP2SPM_IPC_CLR */
482+
writel(0xff, scp->cluster->reg_base + MT8192_SCP2SPM_IPC_CLR);
483+
484+
/* Power on L2TCM */
485+
scp_sram_power_on(scp->cluster->reg_base + MT8192_L2TCM_SRAM_PD_0, 0);
486+
scp_sram_power_on(scp->cluster->reg_base + MT8192_L2TCM_SRAM_PD_1, 0);
487+
scp_sram_power_on(scp->cluster->reg_base + MT8192_L2TCM_SRAM_PD_2, 0);
488+
scp_sram_power_on(scp->cluster->reg_base + MT8192_L1TCM_SRAM_PDN, 0);
489+
}
490+
491+
scp_cluster->l2tcm_refcnt += 1;
492+
493+
mutex_unlock(&scp_cluster->cluster_lock);
494+
495+
return 0;
496+
}
497+
498+
static int mt8188_scp_before_load(struct mtk_scp *scp)
499+
{
500+
writel(1, scp->cluster->reg_base + MT8192_CORE0_SW_RSTN_SET);
501+
502+
mt8188_scp_l2tcm_on(scp);
503+
504+
scp_sram_power_on(scp->cluster->reg_base + MT8192_CPU0_SRAM_PD, 0);
505+
506+
/* enable MPU for all memory regions */
507+
writel(0xff, scp->cluster->reg_base + MT8192_CORE0_MEM_ATT_PREDEF);
508+
509+
return 0;
510+
}
511+
512+
static int mt8188_scp_c1_before_load(struct mtk_scp *scp)
513+
{
514+
u32 sec_ctrl;
515+
struct mtk_scp *scp_c0;
516+
struct mtk_scp_of_cluster *scp_cluster = scp->cluster;
517+
518+
scp->data->scp_reset_assert(scp);
519+
520+
mt8188_scp_l2tcm_on(scp);
521+
522+
scp_sram_power_on(scp->cluster->reg_base + MT8195_CPU1_SRAM_PD, 0);
523+
524+
/* enable MPU for all memory regions */
525+
writel(0xff, scp->cluster->reg_base + MT8195_CORE1_MEM_ATT_PREDEF);
526+
527+
/*
528+
* The L2TCM_OFFSET_RANGE and L2TCM_OFFSET shift the destination address
529+
* on SRAM when SCP core 1 accesses SRAM.
530+
*
531+
* This configuration solves booting the SCP core 0 and core 1 from
532+
* different SRAM address because core 0 and core 1 both boot from
533+
* the head of SRAM by default. this must be configured before boot SCP core 1.
534+
*
535+
* The value of L2TCM_OFFSET_RANGE is from the viewpoint of SCP core 1.
536+
* When SCP core 1 issues address within the range (L2TCM_OFFSET_RANGE),
537+
* the address will be added with a fixed offset (L2TCM_OFFSET) on the bus.
538+
* The shift action is tranparent to software.
539+
*/
540+
writel(0, scp->cluster->reg_base + MT8195_L2TCM_OFFSET_RANGE_0_LOW);
541+
writel(scp->sram_size, scp->cluster->reg_base + MT8195_L2TCM_OFFSET_RANGE_0_HIGH);
542+
543+
scp_c0 = list_first_entry(&scp_cluster->mtk_scp_list, struct mtk_scp, elem);
544+
writel(scp->sram_phys - scp_c0->sram_phys, scp->cluster->reg_base + MT8195_L2TCM_OFFSET);
545+
546+
/* enable SRAM offset when fetching instruction and data */
547+
sec_ctrl = readl(scp->cluster->reg_base + MT8195_SEC_CTRL);
548+
sec_ctrl |= MT8195_CORE_OFFSET_ENABLE_I | MT8195_CORE_OFFSET_ENABLE_D;
549+
writel(sec_ctrl, scp->cluster->reg_base + MT8195_SEC_CTRL);
550+
551+
return 0;
552+
}
553+
474554
static int mt8192_scp_before_load(struct mtk_scp *scp)
475555
{
476556
/* clear SPM interrupt, SCP2SPM_IPC_CLR */
@@ -717,6 +797,47 @@ static void mt8183_scp_stop(struct mtk_scp *scp)
717797
writel(0, scp->cluster->reg_base + MT8183_WDT_CFG);
718798
}
719799

800+
static void mt8188_scp_l2tcm_off(struct mtk_scp *scp)
801+
{
802+
struct mtk_scp_of_cluster *scp_cluster = scp->cluster;
803+
804+
mutex_lock(&scp_cluster->cluster_lock);
805+
806+
if (scp_cluster->l2tcm_refcnt > 0)
807+
scp_cluster->l2tcm_refcnt -= 1;
808+
809+
if (scp_cluster->l2tcm_refcnt == 0) {
810+
/* Power off L2TCM */
811+
scp_sram_power_off(scp->cluster->reg_base + MT8192_L2TCM_SRAM_PD_0, 0);
812+
scp_sram_power_off(scp->cluster->reg_base + MT8192_L2TCM_SRAM_PD_1, 0);
813+
scp_sram_power_off(scp->cluster->reg_base + MT8192_L2TCM_SRAM_PD_2, 0);
814+
scp_sram_power_off(scp->cluster->reg_base + MT8192_L1TCM_SRAM_PDN, 0);
815+
}
816+
817+
mutex_unlock(&scp_cluster->cluster_lock);
818+
}
819+
820+
static void mt8188_scp_stop(struct mtk_scp *scp)
821+
{
822+
mt8188_scp_l2tcm_off(scp);
823+
824+
scp_sram_power_off(scp->cluster->reg_base + MT8192_CPU0_SRAM_PD, 0);
825+
826+
/* Disable SCP watchdog */
827+
writel(0, scp->cluster->reg_base + MT8192_CORE0_WDT_CFG);
828+
}
829+
830+
static void mt8188_scp_c1_stop(struct mtk_scp *scp)
831+
{
832+
mt8188_scp_l2tcm_off(scp);
833+
834+
/* Power off CPU SRAM */
835+
scp_sram_power_off(scp->cluster->reg_base + MT8195_CPU1_SRAM_PD, 0);
836+
837+
/* Disable SCP watchdog */
838+
writel(0, scp->cluster->reg_base + MT8195_CORE1_WDT_CFG);
839+
}
840+
720841
static void mt8192_scp_stop(struct mtk_scp *scp)
721842
{
722843
/* Disable SRAM clock */
@@ -1264,16 +1385,28 @@ static const struct mtk_scp_of_data mt8186_of_data = {
12641385

12651386
static const struct mtk_scp_of_data mt8188_of_data = {
12661387
.scp_clk_get = mt8195_scp_clk_get,
1267-
.scp_before_load = mt8192_scp_before_load,
1268-
.scp_irq_handler = mt8192_scp_irq_handler,
1388+
.scp_before_load = mt8188_scp_before_load,
1389+
.scp_irq_handler = mt8195_scp_irq_handler,
12691390
.scp_reset_assert = mt8192_scp_reset_assert,
12701391
.scp_reset_deassert = mt8192_scp_reset_deassert,
1271-
.scp_stop = mt8192_scp_stop,
1392+
.scp_stop = mt8188_scp_stop,
12721393
.scp_da_to_va = mt8192_scp_da_to_va,
12731394
.host_to_scp_reg = MT8192_GIPC_IN_SET,
12741395
.host_to_scp_int_bit = MT8192_HOST_IPC_INT_BIT,
12751396
};
12761397

1398+
static const struct mtk_scp_of_data mt8188_of_data_c1 = {
1399+
.scp_clk_get = mt8195_scp_clk_get,
1400+
.scp_before_load = mt8188_scp_c1_before_load,
1401+
.scp_irq_handler = mt8195_scp_c1_irq_handler,
1402+
.scp_reset_assert = mt8195_scp_c1_reset_assert,
1403+
.scp_reset_deassert = mt8195_scp_c1_reset_deassert,
1404+
.scp_stop = mt8188_scp_c1_stop,
1405+
.scp_da_to_va = mt8192_scp_da_to_va,
1406+
.host_to_scp_reg = MT8192_GIPC_IN_SET,
1407+
.host_to_scp_int_bit = MT8195_CORE1_HOST_IPC_INT_BIT,
1408+
};
1409+
12771410
static const struct mtk_scp_of_data mt8192_of_data = {
12781411
.scp_clk_get = mt8192_scp_clk_get,
12791412
.scp_before_load = mt8192_scp_before_load,
@@ -1310,6 +1443,12 @@ static const struct mtk_scp_of_data mt8195_of_data_c1 = {
13101443
.host_to_scp_int_bit = MT8195_CORE1_HOST_IPC_INT_BIT,
13111444
};
13121445

1446+
static const struct mtk_scp_of_data *mt8188_of_data_cores[] = {
1447+
&mt8188_of_data,
1448+
&mt8188_of_data_c1,
1449+
NULL
1450+
};
1451+
13131452
static const struct mtk_scp_of_data *mt8195_of_data_cores[] = {
13141453
&mt8195_of_data,
13151454
&mt8195_of_data_c1,
@@ -1320,6 +1459,7 @@ static const struct of_device_id mtk_scp_of_match[] = {
13201459
{ .compatible = "mediatek,mt8183-scp", .data = &mt8183_of_data },
13211460
{ .compatible = "mediatek,mt8186-scp", .data = &mt8186_of_data },
13221461
{ .compatible = "mediatek,mt8188-scp", .data = &mt8188_of_data },
1462+
{ .compatible = "mediatek,mt8188-scp-dual", .data = &mt8188_of_data_cores },
13231463
{ .compatible = "mediatek,mt8192-scp", .data = &mt8192_of_data },
13241464
{ .compatible = "mediatek,mt8195-scp", .data = &mt8195_of_data },
13251465
{ .compatible = "mediatek,mt8195-scp-dual", .data = &mt8195_of_data_cores },

0 commit comments

Comments
 (0)