diff options
-rw-r--r-- | Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml | 26 | ||||
-rw-r--r-- | drivers/remoteproc/imx_dsp_rproc.c | 105 | ||||
-rw-r--r-- | drivers/remoteproc/imx_rproc.c | 3 | ||||
-rw-r--r-- | drivers/remoteproc/mtk_common.h | 2 | ||||
-rw-r--r-- | drivers/remoteproc/mtk_scp.c | 69 | ||||
-rw-r--r-- | drivers/remoteproc/qcom_q6v5_pas.c | 33 | ||||
-rw-r--r-- | drivers/remoteproc/remoteproc_cdev.c | 11 | ||||
-rw-r--r-- | drivers/remoteproc/remoteproc_core.c | 15 | ||||
-rw-r--r-- | drivers/remoteproc/remoteproc_debugfs.c | 17 | ||||
-rw-r--r-- | drivers/remoteproc/remoteproc_elf_loader.c | 2 | ||||
-rw-r--r-- | drivers/remoteproc/remoteproc_sysfs.c | 11 |
11 files changed, 140 insertions, 154 deletions
diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml index a4409c398193..df8286296c37 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml @@ -29,6 +29,9 @@ properties: - qcom,sc8180x-adsp-pas - qcom,sc8180x-cdsp-pas - qcom,sc8180x-mpss-pas + - qcom,sc8280xp-adsp-pas + - qcom,sc8280xp-nsp0-pas + - qcom,sc8280xp-nsp1-pas - qcom,sdm660-adsp-pas - qcom,sdm845-adsp-pas - qcom,sdm845-cdsp-pas @@ -169,6 +172,9 @@ allOf: - qcom,sc8180x-adsp-pas - qcom,sc8180x-cdsp-pas - qcom,sc8180x-mpss-pas + - qcom,sc8280xp-adsp-pas + - qcom,sc8280xp-nsp0-pas + - qcom,sc8280xp-nsp1-pas - qcom,sdm845-adsp-pas - qcom,sdm845-cdsp-pas - qcom,sm6350-adsp-pas @@ -284,6 +290,9 @@ allOf: - qcom,qcs404-wcss-pas - qcom,sc8180x-adsp-pas - qcom,sc8180x-cdsp-pas + - qcom,sc8280xp-adsp-pas + - qcom,sc8280xp-nsp0-pas + - qcom,sc8280xp-nsp1-pas - qcom,sdm845-adsp-pas - qcom,sdm845-cdsp-pas - qcom,sm6350-adsp-pas @@ -471,6 +480,7 @@ allOf: enum: - qcom,sc8180x-adsp-pas - qcom,sc8180x-cdsp-pas + - qcom,sc8280xp-adsp-pas - qcom,sm6350-adsp-pas - qcom,sm8150-slpi-pas - qcom,sm8250-adsp-pas @@ -513,6 +523,22 @@ allOf: compatible: contains: enum: + - qcom,sc8280xp-nsp0-pas + - qcom,sc8280xp-nsp1-pas + then: + properties: + power-domains: + items: + - description: NSP power domain + power-domain-names: + items: + - const: nsp + + - if: + properties: + compatible: + contains: + enum: - qcom,qcs404-cdsp-pas then: properties: diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c index 2abee78df96e..ca0817f8e41e 100644 --- a/drivers/remoteproc/imx_dsp_rproc.c +++ b/drivers/remoteproc/imx_dsp_rproc.c @@ -649,99 +649,6 @@ static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv) return 0; } -/** - * imx_dsp_rproc_elf_load_segments() - load firmware segments to memory - * @rproc: remote processor which will be booted using these fw segments - * @fw: the ELF firmware image - * - * This function specially checks if memsz is zero or not, otherwise it - * is mostly same as rproc_elf_load_segments(). - */ -static int imx_dsp_rproc_elf_load_segments(struct rproc *rproc, - const struct firmware *fw) -{ - struct device *dev = &rproc->dev; - u8 class = fw_elf_get_class(fw); - u32 elf_phdr_get_size = elf_size_of_phdr(class); - const u8 *elf_data = fw->data; - const void *ehdr, *phdr; - int i, ret = 0; - u16 phnum; - - ehdr = elf_data; - phnum = elf_hdr_get_e_phnum(class, ehdr); - phdr = elf_data + elf_hdr_get_e_phoff(class, ehdr); - - /* go through the available ELF segments */ - for (i = 0; i < phnum; i++, phdr += elf_phdr_get_size) { - u64 da = elf_phdr_get_p_paddr(class, phdr); - u64 memsz = elf_phdr_get_p_memsz(class, phdr); - u64 filesz = elf_phdr_get_p_filesz(class, phdr); - u64 offset = elf_phdr_get_p_offset(class, phdr); - u32 type = elf_phdr_get_p_type(class, phdr); - void *ptr; - - /* - * There is a case that with PT_LOAD type, the - * filesz = memsz = 0. If memsz = 0, rproc_da_to_va - * should return NULL ptr, then error is returned. - * So this case should be skipped from the loop. - * Add !memsz checking here. - */ - if (type != PT_LOAD || !memsz) - continue; - - dev_dbg(dev, "phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n", - type, da, memsz, filesz); - - if (filesz > memsz) { - dev_err(dev, "bad phdr filesz 0x%llx memsz 0x%llx\n", - filesz, memsz); - ret = -EINVAL; - break; - } - - if (offset + filesz > fw->size) { - dev_err(dev, "truncated fw: need 0x%llx avail 0x%zx\n", - offset + filesz, fw->size); - ret = -EINVAL; - break; - } - - if (!rproc_u64_fit_in_size_t(memsz)) { - dev_err(dev, "size (%llx) does not fit in size_t type\n", - memsz); - ret = -EOVERFLOW; - break; - } - - /* grab the kernel address for this device address */ - ptr = rproc_da_to_va(rproc, da, memsz, NULL); - if (!ptr) { - dev_err(dev, "bad phdr da 0x%llx mem 0x%llx\n", da, - memsz); - ret = -EINVAL; - break; - } - - /* put the segment where the remote processor expects it */ - if (filesz) - memcpy(ptr, elf_data + offset, filesz); - - /* - * Zero out remaining memory for this segment. - * - * This isn't strictly required since dma_alloc_coherent already - * did this for us. albeit harmless, we may consider removing - * this. - */ - if (memsz > filesz) - memset(ptr + filesz, 0, memsz - filesz); - } - - return ret; -} - /* Prepare function for rproc_ops */ static int imx_dsp_rproc_prepare(struct rproc *rproc) { @@ -802,14 +709,22 @@ static void imx_dsp_rproc_kick(struct rproc *rproc, int vqid) dev_err(dev, "%s: failed (%d, err:%d)\n", __func__, vqid, err); } +static int imx_dsp_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw) +{ + if (rproc_elf_load_rsc_table(rproc, fw)) + dev_warn(&rproc->dev, "no resource table found for this firmware\n"); + + return 0; +} + static const struct rproc_ops imx_dsp_rproc_ops = { .prepare = imx_dsp_rproc_prepare, .unprepare = imx_dsp_rproc_unprepare, .start = imx_dsp_rproc_start, .stop = imx_dsp_rproc_stop, .kick = imx_dsp_rproc_kick, - .load = imx_dsp_rproc_elf_load_segments, - .parse_fw = rproc_elf_load_rsc_table, + .load = rproc_elf_load_segments, + .parse_fw = imx_dsp_rproc_parse_fw, .sanity_check = rproc_elf_sanity_check, .get_boot_addr = rproc_elf_get_boot_addr, }; diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c index 7a096f1891e6..91eb037089ef 100644 --- a/drivers/remoteproc/imx_rproc.c +++ b/drivers/remoteproc/imx_rproc.c @@ -423,6 +423,9 @@ static int imx_rproc_prepare(struct rproc *rproc) if (!strcmp(it.node->name, "vdev0buffer")) continue; + if (!strcmp(it.node->name, "rsc-table")) + continue; + rmem = of_reserved_mem_lookup(it.node); if (!rmem) { dev_err(priv->dev, "unable to acquire memory-region\n"); diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h index 71ce4977cb0b..ea6fa1100a00 100644 --- a/drivers/remoteproc/mtk_common.h +++ b/drivers/remoteproc/mtk_common.h @@ -54,6 +54,8 @@ #define MT8192_CORE0_WDT_IRQ 0x10030 #define MT8192_CORE0_WDT_CFG 0x10034 +#define MT8195_L1TCM_SRAM_PDN_RESERVED_RSI_BITS GENMASK(7, 4) + #define SCP_FW_VER_LEN 32 #define SCP_SHARE_BUFFER_SIZE 288 diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c index 4a0e6c4bc6f4..621174ea7fd6 100644 --- a/drivers/remoteproc/mtk_scp.c +++ b/drivers/remoteproc/mtk_scp.c @@ -365,22 +365,22 @@ static int mt8183_scp_before_load(struct mtk_scp *scp) return 0; } -static void mt8192_power_on_sram(void __iomem *addr) +static void scp_sram_power_on(void __iomem *addr, u32 reserved_mask) { int i; for (i = 31; i >= 0; i--) - writel(GENMASK(i, 0), addr); + writel(GENMASK(i, 0) & ~reserved_mask, addr); writel(0, addr); } -static void mt8192_power_off_sram(void __iomem *addr) +static void scp_sram_power_off(void __iomem *addr, u32 reserved_mask) { int i; writel(0, addr); for (i = 0; i < 32; i++) - writel(GENMASK(i, 0), addr); + writel(GENMASK(i, 0) & ~reserved_mask, addr); } static int mt8186_scp_before_load(struct mtk_scp *scp) @@ -393,7 +393,7 @@ static int mt8186_scp_before_load(struct mtk_scp *scp) 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); + scp_sram_power_on(scp->reg_base + MT8183_SCP_SRAM_PDN, 0); /* Initialize TCM before loading FW. */ writel(0x0, scp->reg_base + MT8183_SCP_L1_SRAM_PD); @@ -412,11 +412,32 @@ static int mt8192_scp_before_load(struct mtk_scp *scp) writel(1, scp->reg_base + MT8192_CORE0_SW_RSTN_SET); /* enable SRAM clock */ - mt8192_power_on_sram(scp->reg_base + MT8192_L2TCM_SRAM_PD_0); - mt8192_power_on_sram(scp->reg_base + MT8192_L2TCM_SRAM_PD_1); - mt8192_power_on_sram(scp->reg_base + MT8192_L2TCM_SRAM_PD_2); - mt8192_power_on_sram(scp->reg_base + MT8192_L1TCM_SRAM_PDN); - mt8192_power_on_sram(scp->reg_base + MT8192_CPU0_SRAM_PD); + scp_sram_power_on(scp->reg_base + MT8192_L2TCM_SRAM_PD_0, 0); + scp_sram_power_on(scp->reg_base + MT8192_L2TCM_SRAM_PD_1, 0); + scp_sram_power_on(scp->reg_base + MT8192_L2TCM_SRAM_PD_2, 0); + scp_sram_power_on(scp->reg_base + MT8192_L1TCM_SRAM_PDN, 0); + scp_sram_power_on(scp->reg_base + MT8192_CPU0_SRAM_PD, 0); + + /* enable MPU for all memory regions */ + writel(0xff, scp->reg_base + MT8192_CORE0_MEM_ATT_PREDEF); + + return 0; +} + +static int mt8195_scp_before_load(struct mtk_scp *scp) +{ + /* clear SPM interrupt, SCP2SPM_IPC_CLR */ + writel(0xff, scp->reg_base + MT8192_SCP2SPM_IPC_CLR); + + writel(1, scp->reg_base + MT8192_CORE0_SW_RSTN_SET); + + /* enable SRAM clock */ + scp_sram_power_on(scp->reg_base + MT8192_L2TCM_SRAM_PD_0, 0); + scp_sram_power_on(scp->reg_base + MT8192_L2TCM_SRAM_PD_1, 0); + scp_sram_power_on(scp->reg_base + MT8192_L2TCM_SRAM_PD_2, 0); + scp_sram_power_on(scp->reg_base + MT8192_L1TCM_SRAM_PDN, + MT8195_L1TCM_SRAM_PDN_RESERVED_RSI_BITS); + scp_sram_power_on(scp->reg_base + MT8192_CPU0_SRAM_PD, 0); /* enable MPU for all memory regions */ writel(0xff, scp->reg_base + MT8192_CORE0_MEM_ATT_PREDEF); @@ -572,11 +593,25 @@ static void mt8183_scp_stop(struct mtk_scp *scp) static void mt8192_scp_stop(struct mtk_scp *scp) { /* Disable SRAM clock */ - mt8192_power_off_sram(scp->reg_base + MT8192_L2TCM_SRAM_PD_0); - mt8192_power_off_sram(scp->reg_base + MT8192_L2TCM_SRAM_PD_1); - mt8192_power_off_sram(scp->reg_base + MT8192_L2TCM_SRAM_PD_2); - mt8192_power_off_sram(scp->reg_base + MT8192_L1TCM_SRAM_PDN); - mt8192_power_off_sram(scp->reg_base + MT8192_CPU0_SRAM_PD); + scp_sram_power_off(scp->reg_base + MT8192_L2TCM_SRAM_PD_0, 0); + scp_sram_power_off(scp->reg_base + MT8192_L2TCM_SRAM_PD_1, 0); + scp_sram_power_off(scp->reg_base + MT8192_L2TCM_SRAM_PD_2, 0); + scp_sram_power_off(scp->reg_base + MT8192_L1TCM_SRAM_PDN, 0); + scp_sram_power_off(scp->reg_base + MT8192_CPU0_SRAM_PD, 0); + + /* Disable SCP watchdog */ + writel(0, scp->reg_base + MT8192_CORE0_WDT_CFG); +} + +static void mt8195_scp_stop(struct mtk_scp *scp) +{ + /* Disable SRAM clock */ + scp_sram_power_off(scp->reg_base + MT8192_L2TCM_SRAM_PD_0, 0); + scp_sram_power_off(scp->reg_base + MT8192_L2TCM_SRAM_PD_1, 0); + scp_sram_power_off(scp->reg_base + MT8192_L2TCM_SRAM_PD_2, 0); + scp_sram_power_off(scp->reg_base + MT8192_L1TCM_SRAM_PDN, + MT8195_L1TCM_SRAM_PDN_RESERVED_RSI_BITS); + scp_sram_power_off(scp->reg_base + MT8192_CPU0_SRAM_PD, 0); /* Disable SCP watchdog */ writel(0, scp->reg_base + MT8192_CORE0_WDT_CFG); @@ -921,11 +956,11 @@ static const struct mtk_scp_of_data mt8192_of_data = { static const struct mtk_scp_of_data mt8195_of_data = { .scp_clk_get = mt8195_scp_clk_get, - .scp_before_load = mt8192_scp_before_load, + .scp_before_load = mt8195_scp_before_load, .scp_irq_handler = mt8192_scp_irq_handler, .scp_reset_assert = mt8192_scp_reset_assert, .scp_reset_deassert = mt8192_scp_reset_deassert, - .scp_stop = mt8192_scp_stop, + .scp_stop = mt8195_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, diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 1ae47cc153e5..06c6dc34f2e0 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -704,6 +704,36 @@ static const struct adsp_data sm8250_cdsp_resource = { .ssctl_id = 0x17, }; +static const struct adsp_data sc8280xp_nsp0_resource = { + .crash_reason_smem = 601, + .firmware_name = "cdsp.mdt", + .pas_id = 18, + .has_aggre2_clk = false, + .auto_boot = true, + .proxy_pd_names = (char*[]){ + "nsp", + NULL + }, + .ssr_name = "cdsp0", + .sysmon_name = "cdsp", + .ssctl_id = 0x17, +}; + +static const struct adsp_data sc8280xp_nsp1_resource = { + .crash_reason_smem = 633, + .firmware_name = "cdsp.mdt", + .pas_id = 30, + .has_aggre2_clk = false, + .auto_boot = true, + .proxy_pd_names = (char*[]){ + "nsp", + NULL + }, + .ssr_name = "cdsp1", + .sysmon_name = "cdsp1", + .ssctl_id = 0x20, +}; + static const struct adsp_data sm8350_cdsp_resource = { .crash_reason_smem = 601, .firmware_name = "cdsp.mdt", @@ -861,6 +891,9 @@ static const struct of_device_id adsp_of_match[] = { { .compatible = "qcom,sc8180x-adsp-pas", .data = &sm8150_adsp_resource}, { .compatible = "qcom,sc8180x-cdsp-pas", .data = &sm8150_cdsp_resource}, { .compatible = "qcom,sc8180x-mpss-pas", .data = &sc8180x_mpss_resource}, + { .compatible = "qcom,sc8280xp-adsp-pas", .data = &sm8250_adsp_resource}, + { .compatible = "qcom,sc8280xp-nsp0-pas", .data = &sc8280xp_nsp0_resource}, + { .compatible = "qcom,sc8280xp-nsp1-pas", .data = &sc8280xp_nsp1_resource}, { .compatible = "qcom,sdm660-adsp-pas", .data = &adsp_resource_init}, { .compatible = "qcom,sdm845-adsp-pas", .data = &sdm845_adsp_resource_init}, { .compatible = "qcom,sdm845-cdsp-pas", .data = &sdm845_cdsp_resource_init}, diff --git a/drivers/remoteproc/remoteproc_cdev.c b/drivers/remoteproc/remoteproc_cdev.c index 906ff3c4dfdd..687f205fd70a 100644 --- a/drivers/remoteproc/remoteproc_cdev.c +++ b/drivers/remoteproc/remoteproc_cdev.c @@ -32,21 +32,10 @@ static ssize_t rproc_cdev_write(struct file *filp, const char __user *buf, size_ return -EFAULT; if (!strncmp(cmd, "start", len)) { - if (rproc->state == RPROC_RUNNING || - rproc->state == RPROC_ATTACHED) - return -EBUSY; - ret = rproc_boot(rproc); } else if (!strncmp(cmd, "stop", len)) { - if (rproc->state != RPROC_RUNNING && - rproc->state != RPROC_ATTACHED) - return -EINVAL; - ret = rproc_shutdown(rproc); } else if (!strncmp(cmd, "detach", len)) { - if (rproc->state != RPROC_ATTACHED) - return -EINVAL; - ret = rproc_detach(rproc); } else { dev_err(&rproc->dev, "Unrecognized option\n"); diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index c510125769b9..02a04ab34a23 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -684,10 +684,6 @@ static int rproc_handle_trace(struct rproc *rproc, void *ptr, /* create the debugfs entry */ trace->tfile = rproc_create_trace_file(name, rproc, trace); - if (!trace->tfile) { - kfree(trace); - return -EINVAL; - } list_add_tail(&trace->node, &rproc->traces); @@ -2075,6 +2071,12 @@ int rproc_shutdown(struct rproc *rproc) return ret; } + if (rproc->state != RPROC_RUNNING && + rproc->state != RPROC_ATTACHED) { + ret = -EINVAL; + goto out; + } + /* if the remote proc is still needed, bail out */ if (!atomic_dec_and_test(&rproc->power)) goto out; @@ -2134,6 +2136,11 @@ int rproc_detach(struct rproc *rproc) return ret; } + if (rproc->state != RPROC_ATTACHED) { + ret = -EINVAL; + goto out; + } + /* if the remote proc is still needed, bail out */ if (!atomic_dec_and_test(&rproc->power)) { ret = 0; diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c index 581930483ef8..b86c1d09c70c 100644 --- a/drivers/remoteproc/remoteproc_debugfs.c +++ b/drivers/remoteproc/remoteproc_debugfs.c @@ -386,16 +386,8 @@ void rproc_remove_trace_file(struct dentry *tfile) struct dentry *rproc_create_trace_file(const char *name, struct rproc *rproc, struct rproc_debug_trace *trace) { - struct dentry *tfile; - - tfile = debugfs_create_file(name, 0400, rproc->dbg_dir, trace, + return debugfs_create_file(name, 0400, rproc->dbg_dir, trace, &trace_rproc_ops); - if (!tfile) { - dev_err(&rproc->dev, "failed to create debugfs trace entry\n"); - return NULL; - } - - return tfile; } void rproc_delete_debug_dir(struct rproc *rproc) @@ -411,8 +403,6 @@ void rproc_create_debug_dir(struct rproc *rproc) return; rproc->dbg_dir = debugfs_create_dir(dev_name(dev), rproc_dbg); - if (!rproc->dbg_dir) - return; debugfs_create_file("name", 0400, rproc->dbg_dir, rproc, &rproc_name_ops); @@ -430,11 +420,8 @@ void rproc_create_debug_dir(struct rproc *rproc) void __init rproc_init_debugfs(void) { - if (debugfs_initialized()) { + if (debugfs_initialized()) rproc_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (!rproc_dbg) - pr_err("can't create debugfs dir\n"); - } } void __exit rproc_exit_debugfs(void) diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c index d635d19a5aa8..5a412d7b6e0b 100644 --- a/drivers/remoteproc/remoteproc_elf_loader.c +++ b/drivers/remoteproc/remoteproc_elf_loader.c @@ -181,7 +181,7 @@ int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw) bool is_iomem = false; void *ptr; - if (type != PT_LOAD) + if (type != PT_LOAD || !memsz) continue; dev_dbg(dev, "phdr: type %d da 0x%llx memsz 0x%llx filesz 0x%llx\n", diff --git a/drivers/remoteproc/remoteproc_sysfs.c b/drivers/remoteproc/remoteproc_sysfs.c index 51a04bc6ba7a..8c7ea8922638 100644 --- a/drivers/remoteproc/remoteproc_sysfs.c +++ b/drivers/remoteproc/remoteproc_sysfs.c @@ -194,23 +194,12 @@ static ssize_t state_store(struct device *dev, int ret = 0; if (sysfs_streq(buf, "start")) { - if (rproc->state == RPROC_RUNNING || - rproc->state == RPROC_ATTACHED) - return -EBUSY; - ret = rproc_boot(rproc); if (ret) dev_err(&rproc->dev, "Boot failed: %d\n", ret); } else if (sysfs_streq(buf, "stop")) { - if (rproc->state != RPROC_RUNNING && - rproc->state != RPROC_ATTACHED) - return -EINVAL; - ret = rproc_shutdown(rproc); } else if (sysfs_streq(buf, "detach")) { - if (rproc->state != RPROC_ATTACHED) - return -EINVAL; - ret = rproc_detach(rproc); } else { dev_err(&rproc->dev, "Unrecognised option: %s\n", buf); |