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 <olivia.wen@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://lore.kernel.org/r/20240430011534.9587-3-olivia.wen@mediatek.com Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
This commit is contained in:
parent
91e0d560b9
commit
928a55ab1b
@ -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(&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, 0);
|
||||
}
|
||||
|
||||
scp_cluster->l2tcm_refcnt += 1;
|
||||
|
||||
mutex_unlock(&scp_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(&scp_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(&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, 0);
|
||||
}
|
||||
|
||||
mutex_unlock(&scp_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 mt8188_scp_c1_stop(struct mtk_scp *scp)
|
||||
{
|
||||
mt8188_scp_l2tcm_off(scp);
|
||||
|
||||
/* Power off CPU SRAM */
|
||||
scp_sram_power_off(scp->cluster->reg_base + MT8195_CPU1_SRAM_PD, 0);
|
||||
|
||||
/* Disable SCP watchdog */
|
||||
writel(0, scp->cluster->reg_base + MT8195_CORE1_WDT_CFG);
|
||||
}
|
||||
|
||||
static void mt8192_scp_stop(struct mtk_scp *scp)
|
||||
{
|
||||
/* Disable SRAM clock */
|
||||
@ -1264,16 +1385,28 @@ static const struct mtk_scp_of_data mt8186_of_data = {
|
||||
|
||||
static const struct mtk_scp_of_data mt8188_of_data = {
|
||||
.scp_clk_get = mt8195_scp_clk_get,
|
||||
.scp_before_load = mt8192_scp_before_load,
|
||||
.scp_irq_handler = mt8192_scp_irq_handler,
|
||||
.scp_before_load = mt8188_scp_before_load,
|
||||
.scp_irq_handler = mt8195_scp_irq_handler,
|
||||
.scp_reset_assert = mt8192_scp_reset_assert,
|
||||
.scp_reset_deassert = mt8192_scp_reset_deassert,
|
||||
.scp_stop = mt8192_scp_stop,
|
||||
.scp_stop = mt8188_scp_stop,
|
||||
.scp_da_to_va = mt8192_scp_da_to_va,
|
||||
.host_to_scp_reg = MT8192_GIPC_IN_SET,
|
||||
.host_to_scp_int_bit = MT8192_HOST_IPC_INT_BIT,
|
||||
};
|
||||
|
||||
static const struct mtk_scp_of_data mt8188_of_data_c1 = {
|
||||
.scp_clk_get = mt8195_scp_clk_get,
|
||||
.scp_before_load = mt8188_scp_c1_before_load,
|
||||
.scp_irq_handler = mt8195_scp_c1_irq_handler,
|
||||
.scp_reset_assert = mt8195_scp_c1_reset_assert,
|
||||
.scp_reset_deassert = mt8195_scp_c1_reset_deassert,
|
||||
.scp_stop = mt8188_scp_c1_stop,
|
||||
.scp_da_to_va = mt8192_scp_da_to_va,
|
||||
.host_to_scp_reg = MT8192_GIPC_IN_SET,
|
||||
.host_to_scp_int_bit = MT8195_CORE1_HOST_IPC_INT_BIT,
|
||||
};
|
||||
|
||||
static const struct mtk_scp_of_data mt8192_of_data = {
|
||||
.scp_clk_get = mt8192_scp_clk_get,
|
||||
.scp_before_load = mt8192_scp_before_load,
|
||||
@ -1310,6 +1443,12 @@ static const struct mtk_scp_of_data mt8195_of_data_c1 = {
|
||||
.host_to_scp_int_bit = MT8195_CORE1_HOST_IPC_INT_BIT,
|
||||
};
|
||||
|
||||
static const struct mtk_scp_of_data *mt8188_of_data_cores[] = {
|
||||
&mt8188_of_data,
|
||||
&mt8188_of_data_c1,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct mtk_scp_of_data *mt8195_of_data_cores[] = {
|
||||
&mt8195_of_data,
|
||||
&mt8195_of_data_c1,
|
||||
@ -1320,6 +1459,7 @@ static const struct of_device_id mtk_scp_of_match[] = {
|
||||
{ .compatible = "mediatek,mt8183-scp", .data = &mt8183_of_data },
|
||||
{ .compatible = "mediatek,mt8186-scp", .data = &mt8186_of_data },
|
||||
{ .compatible = "mediatek,mt8188-scp", .data = &mt8188_of_data },
|
||||
{ .compatible = "mediatek,mt8188-scp-dual", .data = &mt8188_of_data_cores },
|
||||
{ .compatible = "mediatek,mt8192-scp", .data = &mt8192_of_data },
|
||||
{ .compatible = "mediatek,mt8195-scp", .data = &mt8195_of_data },
|
||||
{ .compatible = "mediatek,mt8195-scp-dual", .data = &mt8195_of_data_cores },
|
||||
|
Loading…
Reference in New Issue
Block a user