diff options
Diffstat (limited to 'drivers/remoteproc/mtk_scp.c')
-rw-r--r-- | drivers/remoteproc/mtk_scp.c | 90 |
1 files changed, 56 insertions, 34 deletions
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c index 36e48cf58ed6..38609153bf64 100644 --- a/drivers/remoteproc/mtk_scp.c +++ b/drivers/remoteproc/mtk_scp.c @@ -383,6 +383,27 @@ static void mt8192_power_off_sram(void __iomem *addr) writel(GENMASK(i, 0), addr); } +static int mt8186_scp_before_load(struct mtk_scp *scp) +{ + /* Clear SCP to host interrupt */ + writel(MT8183_SCP_IPC_INT_BIT, scp->reg_base + MT8183_SCP_TO_HOST); + + /* Reset clocks before loading FW */ + writel(0x0, scp->reg_base + MT8183_SCP_CLK_SW_SEL); + writel(0x0, scp->reg_base + MT8183_SCP_CLK_DIV_SEL); + + /* Turn on the power of SCP's SRAM before using it. Enable 1 block per time*/ + mt8192_power_on_sram(scp->reg_base + MT8183_SCP_SRAM_PDN); + + /* Initialize TCM before loading FW. */ + writel(0x0, scp->reg_base + MT8183_SCP_L1_SRAM_PD); + writel(0x0, scp->reg_base + MT8183_SCP_TCM_TAIL_SRAM_PD); + writel(0x0, scp->reg_base + MT8186_SCP_L1_SRAM_PD_P1); + writel(0x0, scp->reg_base + MT8186_SCP_L1_SRAM_PD_p2); + + return 0; +} + static int mt8192_scp_before_load(struct mtk_scp *scp) { /* clear SPM interrupt, SCP2SPM_IPC_CLR */ @@ -756,15 +777,9 @@ static int scp_probe(struct platform_device *pdev) char *fw_name = "scp.img"; int ret, i; - rproc = rproc_alloc(dev, - np->name, - &scp_ops, - fw_name, - sizeof(*scp)); - if (!rproc) { - dev_err(dev, "unable to allocate remoteproc\n"); - return -ENOMEM; - } + rproc = devm_rproc_alloc(dev, np->name, &scp_ops, fw_name, sizeof(*scp)); + if (!rproc) + return dev_err_probe(dev, -ENOMEM, "unable to allocate remoteproc\n"); scp = (struct mtk_scp *)rproc->priv; scp->rproc = rproc; @@ -774,46 +789,42 @@ static int scp_probe(struct platform_device *pdev) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram"); scp->sram_base = devm_ioremap_resource(dev, res); - if (IS_ERR((__force void *)scp->sram_base)) { - dev_err(dev, "Failed to parse and map sram memory\n"); - ret = PTR_ERR((__force void *)scp->sram_base); - goto free_rproc; - } + if (IS_ERR(scp->sram_base)) + return dev_err_probe(dev, PTR_ERR(scp->sram_base), + "Failed to parse and map sram memory\n"); + scp->sram_size = resource_size(res); scp->sram_phys = res->start; /* l1tcm is an optional memory region */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "l1tcm"); scp->l1tcm_base = devm_ioremap_resource(dev, res); - if (IS_ERR((__force void *)scp->l1tcm_base)) { - ret = PTR_ERR((__force void *)scp->l1tcm_base); + if (IS_ERR(scp->l1tcm_base)) { + ret = PTR_ERR(scp->l1tcm_base); if (ret != -EINVAL) { - dev_err(dev, "Failed to map l1tcm memory\n"); - goto free_rproc; + return dev_err_probe(dev, ret, "Failed to map l1tcm memory\n"); } } else { scp->l1tcm_size = resource_size(res); scp->l1tcm_phys = res->start; } - mutex_init(&scp->send_lock); - for (i = 0; i < SCP_IPI_MAX; i++) - mutex_init(&scp->ipi_desc[i].lock); - scp->reg_base = devm_platform_ioremap_resource_byname(pdev, "cfg"); - if (IS_ERR((__force void *)scp->reg_base)) { - dev_err(dev, "Failed to parse and map cfg memory\n"); - ret = PTR_ERR((__force void *)scp->reg_base); - goto destroy_mutex; - } + if (IS_ERR(scp->reg_base)) + return dev_err_probe(dev, PTR_ERR(scp->reg_base), + "Failed to parse and map cfg memory\n"); - ret = scp_map_memory_region(scp); + ret = scp->data->scp_clk_get(scp); if (ret) - goto destroy_mutex; + return ret; - ret = scp->data->scp_clk_get(scp); + ret = scp_map_memory_region(scp); if (ret) - goto release_dev_mem; + return ret; + + mutex_init(&scp->send_lock); + for (i = 0; i < SCP_IPI_MAX; i++) + mutex_init(&scp->ipi_desc[i].lock); /* register SCP initialization IPI */ ret = scp_ipi_register(scp, SCP_IPI_INIT, scp_init_ipi_handler, scp); @@ -847,12 +858,9 @@ remove_subdev: scp_ipi_unregister(scp, SCP_IPI_INIT); release_dev_mem: scp_unmap_memory_region(scp); -destroy_mutex: for (i = 0; i < SCP_IPI_MAX; i++) mutex_destroy(&scp->ipi_desc[i].lock); mutex_destroy(&scp->send_lock); -free_rproc: - rproc_free(rproc); return ret; } @@ -887,6 +895,19 @@ static const struct mtk_scp_of_data mt8183_of_data = { .ipi_buf_offset = 0x7bdb0, }; +static const struct mtk_scp_of_data mt8186_of_data = { + .scp_clk_get = mt8195_scp_clk_get, + .scp_before_load = mt8186_scp_before_load, + .scp_irq_handler = mt8183_scp_irq_handler, + .scp_reset_assert = mt8183_scp_reset_assert, + .scp_reset_deassert = mt8183_scp_reset_deassert, + .scp_stop = mt8183_scp_stop, + .scp_da_to_va = mt8183_scp_da_to_va, + .host_to_scp_reg = MT8183_HOST_TO_SCP, + .host_to_scp_int_bit = MT8183_HOST_IPC_INT_BIT, + .ipi_buf_offset = 0x7bdb0, +}; + static const struct mtk_scp_of_data mt8192_of_data = { .scp_clk_get = mt8192_scp_clk_get, .scp_before_load = mt8192_scp_before_load, @@ -913,6 +934,7 @@ static const struct mtk_scp_of_data mt8195_of_data = { 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,mt8192-scp", .data = &mt8192_of_data }, { .compatible = "mediatek,mt8195-scp", .data = &mt8195_of_data }, {}, |