From 539c3845d320c33bcfd28885378905d5260b8bd2 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 17 Feb 2025 15:58:58 +0800 Subject: remoteproc: omap: Add comment for is_iomem Address warning: "Function parameter or struct member 'is_iomem' not described in 'omap_rproc_da_to_va'" with adding comment for is_iomem. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202502161648.WZWrFV7I-lkp@intel.com/ Cc: Andrew Davis Signed-off-by: Peng Fan Link: https://lore.kernel.org/r/20250217075858.616737-1-peng.fan@oss.nxp.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/omap_remoteproc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c index 5f463937cbbf..9c7182b3b038 100644 --- a/drivers/remoteproc/omap_remoteproc.c +++ b/drivers/remoteproc/omap_remoteproc.c @@ -724,6 +724,7 @@ out: * @rproc: remote processor to apply the address translation for * @da: device address to translate * @len: length of the memory buffer + * @is_iomem: pointer filled in to indicate if @da is iomapped memory * * Custom function implementing the rproc .da_to_va ops to provide address * translation (device address to kernel virtual address) for internal RAMs -- cgit v1.2.3-59-g8ed1b From 4641840341f37dc8231e0840ec1514b4061b4322 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Mon, 17 Feb 2025 23:05:18 +0100 Subject: remoteproc: qcom_q6v5_mss: Handle platforms with one power domain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For example MSM8974 has mx voltage rail exposed as regulator and only cx voltage rail is exposed as power domain. This power domain (cx) is attached internally in power domain and cannot be attached in this driver. Fixes: 8750cf392394 ("remoteproc: qcom_q6v5_mss: Allow replacing regulators with power domains") Co-developed-by: Matti Lehtimäki Signed-off-by: Matti Lehtimäki Reviewed-by: Stephan Gerhold Signed-off-by: Luca Weiss Link: https://lore.kernel.org/r/20250217-msm8226-modem-v5-4-2bc74b80e0ae@lucaweiss.eu Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_mss.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c index e78bd986dc3f..2c80d7fe39f8 100644 --- a/drivers/remoteproc/qcom_q6v5_mss.c +++ b/drivers/remoteproc/qcom_q6v5_mss.c @@ -1831,6 +1831,13 @@ static int q6v5_pds_attach(struct device *dev, struct device **devs, while (pd_names[num_pds]) num_pds++; + /* Handle single power domain */ + if (num_pds == 1 && dev->pm_domain) { + devs[0] = dev; + pm_runtime_enable(dev); + return 1; + } + for (i = 0; i < num_pds; i++) { devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]); if (IS_ERR_OR_NULL(devs[i])) { @@ -1851,8 +1858,15 @@ unroll_attach: static void q6v5_pds_detach(struct q6v5 *qproc, struct device **pds, size_t pd_count) { + struct device *dev = qproc->dev; int i; + /* Handle single power domain */ + if (pd_count == 1 && dev->pm_domain) { + pm_runtime_disable(dev); + return; + } + for (i = 0; i < pd_count; i++) dev_pm_domain_detach(pds[i], false); } @@ -2449,13 +2463,13 @@ static const struct rproc_hexagon_res msm8974_mss = { .supply = "pll", .uA = 100000, }, - {} - }, - .fallback_proxy_supply = (struct qcom_mss_reg_res[]) { { .supply = "mx", .uV = 1050000, }, + {} + }, + .fallback_proxy_supply = (struct qcom_mss_reg_res[]) { { .supply = "cx", .uA = 100000, @@ -2481,7 +2495,6 @@ static const struct rproc_hexagon_res msm8974_mss = { NULL }, .proxy_pd_names = (char*[]){ - "mx", "cx", NULL }, -- cgit v1.2.3-59-g8ed1b From 155cd99d7d8e770f719846b2307c24260593be98 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Mon, 17 Feb 2025 23:05:19 +0100 Subject: remoteproc: qcom_q6v5_mss: Add modem support on MSM8226 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for the external power block headswitch register needed by MSM8226 and some other qcom platforms. Co-developed-by: Matti Lehtimäki Signed-off-by: Matti Lehtimäki Reviewed-by: Stephan Gerhold Signed-off-by: Luca Weiss Link: https://lore.kernel.org/r/20250217-msm8226-modem-v5-5-2bc74b80e0ae@lucaweiss.eu Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_mss.c | 117 ++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c index 2c80d7fe39f8..6f590f912840 100644 --- a/drivers/remoteproc/qcom_q6v5_mss.c +++ b/drivers/remoteproc/qcom_q6v5_mss.c @@ -134,6 +134,11 @@ #define BOOT_FSM_TIMEOUT 10000 #define BHS_CHECK_MAX_LOOPS 200 +/* External power block headswitch */ +#define EXTERNAL_BHS_ON BIT(0) +#define EXTERNAL_BHS_STATUS BIT(4) +#define EXTERNAL_BHS_TIMEOUT_US 50 + struct reg_info { struct regulator *reg; int uV; @@ -161,6 +166,7 @@ struct rproc_hexagon_res { bool has_mba_logs; bool has_spare_reg; bool has_qaccept_regs; + bool has_ext_bhs_reg; bool has_ext_cntl_regs; bool has_vq6; }; @@ -180,6 +186,7 @@ struct q6v5 { u32 halt_nc; u32 halt_vq6; u32 conn_box; + u32 ext_bhs; u32 qaccept_mdm; u32 qaccept_cx; @@ -237,6 +244,7 @@ struct q6v5 { bool has_mba_logs; bool has_spare_reg; bool has_qaccept_regs; + bool has_ext_bhs_reg; bool has_ext_cntl_regs; bool has_vq6; u64 mpss_perm; @@ -246,6 +254,7 @@ struct q6v5 { }; enum { + MSS_MSM8226, MSS_MSM8909, MSS_MSM8916, MSS_MSM8953, @@ -415,6 +424,34 @@ static void q6v5_pds_disable(struct q6v5 *qproc, struct device **pds, } } +static int q6v5_external_bhs_enable(struct q6v5 *qproc) +{ + u32 val; + int ret = 0; + + /* + * Enable external power block headswitch and wait for it to + * stabilize + */ + regmap_set_bits(qproc->conn_map, qproc->ext_bhs, EXTERNAL_BHS_ON); + + ret = regmap_read_poll_timeout(qproc->conn_map, qproc->ext_bhs, + val, val & EXTERNAL_BHS_STATUS, + 1, EXTERNAL_BHS_TIMEOUT_US); + + if (ret) { + dev_err(qproc->dev, "External BHS timed out\n"); + ret = -ETIMEDOUT; + } + + return ret; +} + +static void q6v5_external_bhs_disable(struct q6v5 *qproc) +{ + regmap_clear_bits(qproc->conn_map, qproc->ext_bhs, EXTERNAL_BHS_ON); +} + static int q6v5_xfer_mem_ownership(struct q6v5 *qproc, u64 *current_perm, bool local, bool remote, phys_addr_t addr, size_t size) @@ -1112,11 +1149,17 @@ static int q6v5_mba_load(struct q6v5 *qproc) goto disable_proxy_clk; } + if (qproc->has_ext_bhs_reg) { + ret = q6v5_external_bhs_enable(qproc); + if (ret < 0) + goto disable_vdd; + } + ret = q6v5_clk_enable(qproc->dev, qproc->reset_clks, qproc->reset_clk_count); if (ret) { dev_err(qproc->dev, "failed to enable reset clocks\n"); - goto disable_vdd; + goto disable_ext_bhs; } ret = q6v5_reset_deassert(qproc); @@ -1214,6 +1257,9 @@ assert_reset: disable_reset_clks: q6v5_clk_disable(qproc->dev, qproc->reset_clks, qproc->reset_clk_count); +disable_ext_bhs: + if (qproc->has_ext_bhs_reg) + q6v5_external_bhs_disable(qproc); disable_vdd: q6v5_regulator_disable(qproc, qproc->active_regs, qproc->active_reg_count); @@ -1281,6 +1327,8 @@ static void q6v5_mba_reclaim(struct q6v5 *qproc) qproc->reset_clk_count); q6v5_clk_disable(qproc->dev, qproc->active_clks, qproc->active_clk_count); + if (qproc->has_ext_bhs_reg) + q6v5_external_bhs_disable(qproc); q6v5_regulator_disable(qproc, qproc->active_regs, qproc->active_reg_count); @@ -1750,6 +1798,23 @@ static int q6v5_init_mem(struct q6v5 *qproc, struct platform_device *pdev) qproc->qaccept_axi = args.args[2]; } + if (qproc->has_ext_bhs_reg) { + ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, + "qcom,ext-bhs-reg", + 1, 0, &args); + if (ret < 0) { + dev_err(&pdev->dev, "failed to parse ext-bhs-reg index 0\n"); + return -EINVAL; + } + + qproc->conn_map = syscon_node_to_regmap(args.np); + of_node_put(args.np); + if (IS_ERR(qproc->conn_map)) + return PTR_ERR(qproc->conn_map); + + qproc->ext_bhs = args.args[0]; + } + if (qproc->has_ext_cntl_regs) { ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, "qcom,ext-regs", @@ -2021,6 +2086,7 @@ static int q6v5_probe(struct platform_device *pdev) platform_set_drvdata(pdev, qproc); qproc->has_qaccept_regs = desc->has_qaccept_regs; + qproc->has_ext_bhs_reg = desc->has_ext_bhs_reg; qproc->has_ext_cntl_regs = desc->has_ext_cntl_regs; qproc->has_vq6 = desc->has_vq6; qproc->has_spare_reg = desc->has_spare_reg; @@ -2174,6 +2240,7 @@ static const struct rproc_hexagon_res sc7180_mss = { .has_mba_logs = true, .has_spare_reg = true, .has_qaccept_regs = false, + .has_ext_bhs_reg = false, .has_ext_cntl_regs = false, .has_vq6 = false, .version = MSS_SC7180, @@ -2202,6 +2269,7 @@ static const struct rproc_hexagon_res sc7280_mss = { .has_mba_logs = true, .has_spare_reg = false, .has_qaccept_regs = true, + .has_ext_bhs_reg = false, .has_ext_cntl_regs = true, .has_vq6 = true, .version = MSS_SC7280, @@ -2233,6 +2301,7 @@ static const struct rproc_hexagon_res sdm660_mss = { .has_mba_logs = false, .has_spare_reg = false, .has_qaccept_regs = false, + .has_ext_bhs_reg = false, .has_ext_cntl_regs = false, .has_vq6 = false, .version = MSS_SDM660, @@ -2268,6 +2337,7 @@ static const struct rproc_hexagon_res sdm845_mss = { .has_mba_logs = false, .has_spare_reg = false, .has_qaccept_regs = false, + .has_ext_bhs_reg = false, .has_ext_cntl_regs = false, .has_vq6 = false, .version = MSS_SDM845, @@ -2299,6 +2369,7 @@ static const struct rproc_hexagon_res msm8998_mss = { .has_mba_logs = false, .has_spare_reg = false, .has_qaccept_regs = false, + .has_ext_bhs_reg = false, .has_ext_cntl_regs = false, .has_vq6 = false, .version = MSS_MSM8998, @@ -2337,6 +2408,7 @@ static const struct rproc_hexagon_res msm8996_mss = { .has_mba_logs = false, .has_spare_reg = false, .has_qaccept_regs = false, + .has_ext_bhs_reg = false, .has_ext_cntl_regs = false, .has_vq6 = false, .version = MSS_MSM8996, @@ -2371,6 +2443,7 @@ static const struct rproc_hexagon_res msm8909_mss = { .has_mba_logs = false, .has_spare_reg = false, .has_qaccept_regs = false, + .has_ext_bhs_reg = false, .has_ext_cntl_regs = false, .has_vq6 = false, .version = MSS_MSM8909, @@ -2416,6 +2489,7 @@ static const struct rproc_hexagon_res msm8916_mss = { .has_mba_logs = false, .has_spare_reg = false, .has_qaccept_regs = false, + .has_ext_bhs_reg = false, .has_ext_cntl_regs = false, .has_vq6 = false, .version = MSS_MSM8916, @@ -2451,6 +2525,7 @@ static const struct rproc_hexagon_res msm8953_mss = { .has_mba_logs = false, .has_spare_reg = false, .has_qaccept_regs = false, + .has_ext_bhs_reg = false, .has_ext_cntl_regs = false, .has_vq6 = false, .version = MSS_MSM8953, @@ -2503,13 +2578,53 @@ static const struct rproc_hexagon_res msm8974_mss = { .has_mba_logs = false, .has_spare_reg = false, .has_qaccept_regs = false, + .has_ext_bhs_reg = false, .has_ext_cntl_regs = false, .has_vq6 = false, .version = MSS_MSM8974, }; +static const struct rproc_hexagon_res msm8226_mss = { + .hexagon_mba_image = "mba.b00", + .proxy_supply = (struct qcom_mss_reg_res[]) { + { + .supply = "pll", + .uA = 100000, + }, + { + .supply = "mx", + .uV = 1050000, + }, + {} + }, + .proxy_clk_names = (char*[]){ + "xo", + NULL + }, + .active_clk_names = (char*[]){ + "iface", + "bus", + "mem", + NULL + }, + .proxy_pd_names = (char*[]){ + "cx", + NULL + }, + .need_mem_protection = false, + .has_alt_reset = false, + .has_mba_logs = false, + .has_spare_reg = false, + .has_qaccept_regs = false, + .has_ext_bhs_reg = true, + .has_ext_cntl_regs = false, + .has_vq6 = false, + .version = MSS_MSM8226, +}; + static const struct of_device_id q6v5_of_match[] = { { .compatible = "qcom,q6v5-pil", .data = &msm8916_mss}, + { .compatible = "qcom,msm8226-mss-pil", .data = &msm8226_mss}, { .compatible = "qcom,msm8909-mss-pil", .data = &msm8909_mss}, { .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss}, { .compatible = "qcom,msm8953-mss-pil", .data = &msm8953_mss}, -- cgit v1.2.3-59-g8ed1b From df9e5103a2855ba3352f2c6e862adad17810605c Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Mon, 17 Feb 2025 23:05:20 +0100 Subject: remoteproc: qcom_q6v5_mss: Add modem support on MSM8926 While MSM8926 being 'just' an LTE-capable variant of MSM8226 it appears the modem setup has changed significantly, by requiring mss-supply and not using the ext-bhs-reg. Add a new compatible and new struct to support that. Reviewed-by: Stephan Gerhold Signed-off-by: Luca Weiss Link: https://lore.kernel.org/r/20250217-msm8226-modem-v5-6-2bc74b80e0ae@lucaweiss.eu Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_mss.c | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'drivers') diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c index 6f590f912840..0c0199fb0e68 100644 --- a/drivers/remoteproc/qcom_q6v5_mss.c +++ b/drivers/remoteproc/qcom_q6v5_mss.c @@ -257,6 +257,7 @@ enum { MSS_MSM8226, MSS_MSM8909, MSS_MSM8916, + MSS_MSM8926, MSS_MSM8953, MSS_MSM8974, MSS_MSM8996, @@ -2622,11 +2623,58 @@ static const struct rproc_hexagon_res msm8226_mss = { .version = MSS_MSM8226, }; +static const struct rproc_hexagon_res msm8926_mss = { + .hexagon_mba_image = "mba.b00", + .proxy_supply = (struct qcom_mss_reg_res[]) { + { + .supply = "pll", + .uA = 100000, + }, + { + .supply = "mx", + .uV = 1050000, + }, + {} + }, + .active_supply = (struct qcom_mss_reg_res[]) { + { + .supply = "mss", + .uV = 1050000, + .uA = 100000, + }, + {} + }, + .proxy_clk_names = (char*[]){ + "xo", + NULL + }, + .active_clk_names = (char*[]){ + "iface", + "bus", + "mem", + NULL + }, + .proxy_pd_names = (char*[]){ + "cx", + NULL + }, + .need_mem_protection = false, + .has_alt_reset = false, + .has_mba_logs = false, + .has_spare_reg = false, + .has_qaccept_regs = false, + .has_ext_bhs_reg = false, + .has_ext_cntl_regs = false, + .has_vq6 = false, + .version = MSS_MSM8926, +}; + static const struct of_device_id q6v5_of_match[] = { { .compatible = "qcom,q6v5-pil", .data = &msm8916_mss}, { .compatible = "qcom,msm8226-mss-pil", .data = &msm8226_mss}, { .compatible = "qcom,msm8909-mss-pil", .data = &msm8909_mss}, { .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss}, + { .compatible = "qcom,msm8926-mss-pil", .data = &msm8926_mss}, { .compatible = "qcom,msm8953-mss-pil", .data = &msm8953_mss}, { .compatible = "qcom,msm8974-mss-pil", .data = &msm8974_mss}, { .compatible = "qcom,msm8996-mss-pil", .data = &msm8996_mss}, -- cgit v1.2.3-59-g8ed1b From 65991ea8a6d1e68effdc01d95ebe39f1653f7b71 Mon Sep 17 00:00:00 2001 From: Matti Lehtimäki Date: Thu, 6 Feb 2025 20:56:48 +0100 Subject: remoteproc: qcom_wcnss: Handle platforms with only single power domain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both MSM8974 and MSM8226 have only CX as power domain with MX & PX being handled as regulators. Handle this case by reodering pd_names to have CX first, and handling that the driver core will already attach a single power domain internally. Signed-off-by: Matti Lehtimäki [luca: minor changes] Signed-off-by: Luca Weiss Link: https://lore.kernel.org/r/20250206-wcnss-singlepd-v2-2-9a53ee953dee@lucaweiss.eu [bjorn: Added missing braces to else after multi-statement if] Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_wcnss.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c index 5b5664603eed..775b056d795a 100644 --- a/drivers/remoteproc/qcom_wcnss.c +++ b/drivers/remoteproc/qcom_wcnss.c @@ -117,10 +117,10 @@ static const struct wcnss_data pronto_v1_data = { .pmu_offset = 0x1004, .spare_offset = 0x1088, - .pd_names = { "mx", "cx" }, + .pd_names = { "cx", "mx" }, .vregs = (struct wcnss_vreg_info[]) { - { "vddmx", 950000, 1150000, 0 }, { "vddcx", .super_turbo = true}, + { "vddmx", 950000, 1150000, 0 }, { "vddpx", 1800000, 1800000, 0 }, }, .num_pd_vregs = 2, @@ -131,10 +131,10 @@ static const struct wcnss_data pronto_v2_data = { .pmu_offset = 0x1004, .spare_offset = 0x1088, - .pd_names = { "mx", "cx" }, + .pd_names = { "cx", "mx" }, .vregs = (struct wcnss_vreg_info[]) { - { "vddmx", 1287500, 1287500, 0 }, { "vddcx", .super_turbo = true }, + { "vddmx", 1287500, 1287500, 0 }, { "vddpx", 1800000, 1800000, 0 }, }, .num_pd_vregs = 2, @@ -397,8 +397,17 @@ static irqreturn_t wcnss_stop_ack_interrupt(int irq, void *dev) static int wcnss_init_pds(struct qcom_wcnss *wcnss, const char * const pd_names[WCNSS_MAX_PDS]) { + struct device *dev = wcnss->dev; int i, ret; + /* Handle single power domain */ + if (dev->pm_domain) { + wcnss->pds[0] = dev; + wcnss->num_pds = 1; + pm_runtime_enable(dev); + return 0; + } + for (i = 0; i < WCNSS_MAX_PDS; i++) { if (!pd_names[i]) break; @@ -418,8 +427,15 @@ static int wcnss_init_pds(struct qcom_wcnss *wcnss, static void wcnss_release_pds(struct qcom_wcnss *wcnss) { + struct device *dev = wcnss->dev; int i; + /* Handle single power domain */ + if (wcnss->num_pds == 1 && dev->pm_domain) { + pm_runtime_disable(dev); + return; + } + for (i = 0; i < wcnss->num_pds; i++) dev_pm_domain_detach(wcnss->pds[i], false); } @@ -437,10 +453,13 @@ static int wcnss_init_regulators(struct qcom_wcnss *wcnss, * the regulators for the power domains. For old device trees we need to * reserve extra space to manage them through the regulator interface. */ - if (wcnss->num_pds) - info += num_pd_vregs; - else + if (wcnss->num_pds) { + info += wcnss->num_pds; + /* Handle single power domain case */ + num_vregs += num_pd_vregs - wcnss->num_pds; + } else { num_vregs += num_pd_vregs; + } bulk = devm_kcalloc(wcnss->dev, num_vregs, sizeof(struct regulator_bulk_data), -- cgit v1.2.3-59-g8ed1b From 9df5c535a274c97f92d462ac3bf77f2bef417ef9 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Tue, 11 Mar 2025 10:58:07 +0200 Subject: reset: imx8mp-audiomix: Add prefix for internal macro This adds IMX8MP_AUDIOMIX_ prefix to internal macros in order to show that specific macros are related to audiomix. Reviewed-by: Philipp Zabel Reviewed-by: Frank Li Reviewed-by: Peng Fan Signed-off-by: Daniel Baluta Link: https://lore.kernel.org/r/20250311085812.1296243-5-daniel.baluta@nxp.com Signed-off-by: Mathieu Poirier --- drivers/reset/reset-imx8mp-audiomix.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/reset/reset-imx8mp-audiomix.c b/drivers/reset/reset-imx8mp-audiomix.c index 6e3f3069f727..c2c3e8113182 100644 --- a/drivers/reset/reset-imx8mp-audiomix.c +++ b/drivers/reset/reset-imx8mp-audiomix.c @@ -11,8 +11,8 @@ #include #include -#define EARC 0x200 -#define EARC_RESET_MASK 0x3 +#define IMX8MP_AUDIOMIX_EARC_RESET_OFFSET 0x200 +#define IMX8MP_AUDIOMIX_EARC_RESET_MASK 0x3 struct imx8mp_audiomix_reset { struct reset_controller_dev rcdev; @@ -35,8 +35,8 @@ static int imx8mp_audiomix_reset_assert(struct reset_controller_dev *rcdev, mask = BIT(id); spin_lock_irqsave(&priv->lock, flags); - reg = readl(reg_addr + EARC); - writel(reg & ~mask, reg_addr + EARC); + reg = readl(reg_addr + IMX8MP_AUDIOMIX_EARC_RESET_OFFSET); + writel(reg & ~mask, reg_addr + IMX8MP_AUDIOMIX_EARC_RESET_OFFSET); spin_unlock_irqrestore(&priv->lock, flags); return 0; @@ -52,8 +52,8 @@ static int imx8mp_audiomix_reset_deassert(struct reset_controller_dev *rcdev, mask = BIT(id); spin_lock_irqsave(&priv->lock, flags); - reg = readl(reg_addr + EARC); - writel(reg | mask, reg_addr + EARC); + reg = readl(reg_addr + IMX8MP_AUDIOMIX_EARC_RESET_OFFSET); + writel(reg | mask, reg_addr + IMX8MP_AUDIOMIX_EARC_RESET_OFFSET); spin_unlock_irqrestore(&priv->lock, flags); return 0; @@ -78,7 +78,7 @@ static int imx8mp_audiomix_reset_probe(struct auxiliary_device *adev, spin_lock_init(&priv->lock); priv->rcdev.owner = THIS_MODULE; - priv->rcdev.nr_resets = fls(EARC_RESET_MASK); + priv->rcdev.nr_resets = fls(IMX8MP_AUDIOMIX_EARC_RESET_MASK); priv->rcdev.ops = &imx8mp_audiomix_reset_ops; priv->rcdev.of_node = dev->parent->of_node; priv->rcdev.dev = dev; -- cgit v1.2.3-59-g8ed1b From a83bc87cd30a4cc544891a0dd4cb752e094125e0 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Tue, 11 Mar 2025 10:58:08 +0200 Subject: reset: imx8mp-audiomix: Prepare the code for more reset bits Current code supports EARC PHY Software Reset and EARC Software Reset but it is not easily extensible to more reset bits. So, refactor the code in order to easily allow more reset bits in the future. Reviewed-by: Peng Fan Reviewed-by: Frank Li Signed-off-by: Daniel Baluta Reviewed-by: Philipp Zabel Link: https://lore.kernel.org/r/20250311085812.1296243-6-daniel.baluta@nxp.com Signed-off-by: Mathieu Poirier --- drivers/reset/reset-imx8mp-audiomix.c | 43 +++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/reset/reset-imx8mp-audiomix.c b/drivers/reset/reset-imx8mp-audiomix.c index c2c3e8113182..abef6d768e62 100644 --- a/drivers/reset/reset-imx8mp-audiomix.c +++ b/drivers/reset/reset-imx8mp-audiomix.c @@ -3,6 +3,8 @@ * Copyright 2024 NXP */ +#include + #include #include #include @@ -12,7 +14,24 @@ #include #define IMX8MP_AUDIOMIX_EARC_RESET_OFFSET 0x200 -#define IMX8MP_AUDIOMIX_EARC_RESET_MASK 0x3 +#define IMX8MP_AUDIOMIX_EARC_RESET_MASK BIT(1) +#define IMX8MP_AUDIOMIX_EARC_PHY_RESET_MASK BIT(2) + +struct imx8mp_reset_map { + unsigned int offset; + unsigned int mask; +}; + +static const struct imx8mp_reset_map reset_map[] = { + [IMX8MP_AUDIOMIX_EARC_RESET] = { + .offset = IMX8MP_AUDIOMIX_EARC_RESET_OFFSET, + .mask = IMX8MP_AUDIOMIX_EARC_RESET_MASK, + }, + [IMX8MP_AUDIOMIX_EARC_PHY_RESET] = { + .offset = IMX8MP_AUDIOMIX_EARC_RESET_OFFSET, + .mask = IMX8MP_AUDIOMIX_EARC_PHY_RESET_MASK, + }, +}; struct imx8mp_audiomix_reset { struct reset_controller_dev rcdev; @@ -30,13 +49,15 @@ static int imx8mp_audiomix_reset_assert(struct reset_controller_dev *rcdev, { struct imx8mp_audiomix_reset *priv = to_imx8mp_audiomix_reset(rcdev); void __iomem *reg_addr = priv->base; - unsigned int mask, reg; + unsigned int mask, offset, reg; unsigned long flags; - mask = BIT(id); + mask = reset_map[id].mask; + offset = reset_map[id].offset; + spin_lock_irqsave(&priv->lock, flags); - reg = readl(reg_addr + IMX8MP_AUDIOMIX_EARC_RESET_OFFSET); - writel(reg & ~mask, reg_addr + IMX8MP_AUDIOMIX_EARC_RESET_OFFSET); + reg = readl(reg_addr + offset); + writel(reg & ~mask, reg_addr + offset); spin_unlock_irqrestore(&priv->lock, flags); return 0; @@ -47,13 +68,15 @@ static int imx8mp_audiomix_reset_deassert(struct reset_controller_dev *rcdev, { struct imx8mp_audiomix_reset *priv = to_imx8mp_audiomix_reset(rcdev); void __iomem *reg_addr = priv->base; - unsigned int mask, reg; + unsigned int mask, offset, reg; unsigned long flags; - mask = BIT(id); + mask = reset_map[id].mask; + offset = reset_map[id].offset; + spin_lock_irqsave(&priv->lock, flags); - reg = readl(reg_addr + IMX8MP_AUDIOMIX_EARC_RESET_OFFSET); - writel(reg | mask, reg_addr + IMX8MP_AUDIOMIX_EARC_RESET_OFFSET); + reg = readl(reg_addr + offset); + writel(reg | mask, reg_addr + offset); spin_unlock_irqrestore(&priv->lock, flags); return 0; @@ -78,7 +101,7 @@ static int imx8mp_audiomix_reset_probe(struct auxiliary_device *adev, spin_lock_init(&priv->lock); priv->rcdev.owner = THIS_MODULE; - priv->rcdev.nr_resets = fls(IMX8MP_AUDIOMIX_EARC_RESET_MASK); + priv->rcdev.nr_resets = ARRAY_SIZE(reset_map); priv->rcdev.ops = &imx8mp_audiomix_reset_ops; priv->rcdev.of_node = dev->parent->of_node; priv->rcdev.dev = dev; -- cgit v1.2.3-59-g8ed1b From 9fba66374deec0c1158570ff474bacd46651397d Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Tue, 11 Mar 2025 10:58:09 +0200 Subject: reset: imx8mp-audiomix: Introduce active_low configuration option For EARC and EARC PHY the reset happens when clearing the reset bits. Refactor assert/deassert function in order to take into account the active_low configuration option. Reviewed-by: Philipp Zabel Reviewed-by: Peng Fan Reviewed-by: Frank Li Signed-off-by: Daniel Baluta Link: https://lore.kernel.org/r/20250311085812.1296243-7-daniel.baluta@nxp.com Signed-off-by: Mathieu Poirier --- drivers/reset/reset-imx8mp-audiomix.c | 41 +++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/reset/reset-imx8mp-audiomix.c b/drivers/reset/reset-imx8mp-audiomix.c index abef6d768e62..04ad27aca806 100644 --- a/drivers/reset/reset-imx8mp-audiomix.c +++ b/drivers/reset/reset-imx8mp-audiomix.c @@ -20,16 +20,19 @@ struct imx8mp_reset_map { unsigned int offset; unsigned int mask; + bool active_low; }; static const struct imx8mp_reset_map reset_map[] = { [IMX8MP_AUDIOMIX_EARC_RESET] = { .offset = IMX8MP_AUDIOMIX_EARC_RESET_OFFSET, .mask = IMX8MP_AUDIOMIX_EARC_RESET_MASK, + .active_low = true, }, [IMX8MP_AUDIOMIX_EARC_PHY_RESET] = { .offset = IMX8MP_AUDIOMIX_EARC_RESET_OFFSET, .mask = IMX8MP_AUDIOMIX_EARC_PHY_RESET_MASK, + .active_low = true, }, }; @@ -44,42 +47,42 @@ static struct imx8mp_audiomix_reset *to_imx8mp_audiomix_reset(struct reset_contr return container_of(rcdev, struct imx8mp_audiomix_reset, rcdev); } -static int imx8mp_audiomix_reset_assert(struct reset_controller_dev *rcdev, - unsigned long id) +static int imx8mp_audiomix_update(struct reset_controller_dev *rcdev, + unsigned long id, bool assert) { struct imx8mp_audiomix_reset *priv = to_imx8mp_audiomix_reset(rcdev); void __iomem *reg_addr = priv->base; - unsigned int mask, offset, reg; - unsigned long flags; + unsigned int mask, offset, active_low; + unsigned long reg, flags; mask = reset_map[id].mask; offset = reset_map[id].offset; + active_low = reset_map[id].active_low; spin_lock_irqsave(&priv->lock, flags); + reg = readl(reg_addr + offset); - writel(reg & ~mask, reg_addr + offset); + if (active_low ^ assert) + reg |= mask; + else + reg &= ~mask; + writel(reg, reg_addr + offset); + spin_unlock_irqrestore(&priv->lock, flags); return 0; } +static int imx8mp_audiomix_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return imx8mp_audiomix_update(rcdev, id, true); +} + static int imx8mp_audiomix_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) { - struct imx8mp_audiomix_reset *priv = to_imx8mp_audiomix_reset(rcdev); - void __iomem *reg_addr = priv->base; - unsigned int mask, offset, reg; - unsigned long flags; - - mask = reset_map[id].mask; - offset = reset_map[id].offset; - - spin_lock_irqsave(&priv->lock, flags); - reg = readl(reg_addr + offset); - writel(reg | mask, reg_addr + offset); - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; + return imx8mp_audiomix_update(rcdev, id, false); } static const struct reset_control_ops imx8mp_audiomix_reset_ops = { -- cgit v1.2.3-59-g8ed1b From c133ec126af841b284f91bcf8c0742e6b42032f5 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Tue, 11 Mar 2025 10:58:10 +0200 Subject: reset: imx8mp-audiomix: Add support for DSP run/stall We can Run/Stall the DSP via audio block control bits found in audiomix. Implement this functionality using the reset controller and use assert for Stall and deassert for Run. Reviewed-by: Peng Fan Reviewed-by: Frank Li Signed-off-by: Daniel Baluta Reviewed-by: Philipp Zabel Link: https://lore.kernel.org/r/20250311085812.1296243-8-daniel.baluta@nxp.com Signed-off-by: Mathieu Poirier --- drivers/reset/reset-imx8mp-audiomix.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/reset/reset-imx8mp-audiomix.c b/drivers/reset/reset-imx8mp-audiomix.c index 04ad27aca806..6b357adfe646 100644 --- a/drivers/reset/reset-imx8mp-audiomix.c +++ b/drivers/reset/reset-imx8mp-audiomix.c @@ -17,6 +17,9 @@ #define IMX8MP_AUDIOMIX_EARC_RESET_MASK BIT(1) #define IMX8MP_AUDIOMIX_EARC_PHY_RESET_MASK BIT(2) +#define IMX8MP_AUDIOMIX_DSP_RUNSTALL_OFFSET 0x108 +#define IMX8MP_AUDIOMIX_DSP_RUNSTALL_MASK BIT(5) + struct imx8mp_reset_map { unsigned int offset; unsigned int mask; @@ -34,6 +37,11 @@ static const struct imx8mp_reset_map reset_map[] = { .mask = IMX8MP_AUDIOMIX_EARC_PHY_RESET_MASK, .active_low = true, }, + [IMX8MP_AUDIOMIX_DSP_RUNSTALL] = { + .offset = IMX8MP_AUDIOMIX_DSP_RUNSTALL_OFFSET, + .mask = IMX8MP_AUDIOMIX_DSP_RUNSTALL_MASK, + .active_low = false, + }, }; struct imx8mp_audiomix_reset { -- cgit v1.2.3-59-g8ed1b From 0184b4fdbad1eafbdab385af8ce8a0e68af88dbb Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Tue, 11 Mar 2025 10:58:11 +0200 Subject: imx_dsp_rproc: Use reset controller API to control the DSP DSP on i.MX8MP doesn't have a direct reset line so according to hardware design team in order to handle assert/deassert/reset functionality we need to use a combination of control bits from two modules. Audio block control module for Run/Stall control of the DSP and DAP module in order to do software reset. In a first step, for i.MX8MP we are switching on using the reset controller API to handle the DSP Run/Stall bits i.MX8MP. This comes with the advantage of offering a better probe ordering and a more natural way of abstracting the Audio block control bits. Reviewed-by: Peng Fan Reviewed-by: Frank Li Signed-off-by: Daniel Baluta Acked-by: Philipp Zabel Link: https://lore.kernel.org/r/20250311085812.1296243-9-daniel.baluta@nxp.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/imx_dsp_rproc.c | 25 +++++++++++++++++-------- drivers/remoteproc/imx_rproc.h | 2 ++ 2 files changed, 19 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c index ea5024919c2f..bc60edcdd661 100644 --- a/drivers/remoteproc/imx_dsp_rproc.c +++ b/drivers/remoteproc/imx_dsp_rproc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "imx_rproc.h" @@ -111,6 +112,7 @@ enum imx_dsp_rp_mbox_messages { */ struct imx_dsp_rproc { struct regmap *regmap; + struct reset_control *run_stall; struct rproc *rproc; const struct imx_dsp_rproc_dcfg *dsp_dcfg; struct clk_bulk_data clks[DSP_RPROC_CLK_MAX]; @@ -192,9 +194,7 @@ static int imx8mp_dsp_reset(struct imx_dsp_rproc *priv) /* Keep reset asserted for 10 cycles */ usleep_range(1, 2); - regmap_update_bits(priv->regmap, IMX8M_AudioDSP_REG2, - IMX8M_AudioDSP_REG2_RUNSTALL, - IMX8M_AudioDSP_REG2_RUNSTALL); + reset_control_assert(priv->run_stall); /* Take the DSP out of reset and keep stalled for FW loading */ pwrctl = readl(dap + IMX8M_DAP_PWRCTL); @@ -231,13 +231,9 @@ static int imx8ulp_dsp_reset(struct imx_dsp_rproc *priv) /* Specific configuration for i.MX8MP */ static const struct imx_rproc_dcfg dsp_rproc_cfg_imx8mp = { - .src_reg = IMX8M_AudioDSP_REG2, - .src_mask = IMX8M_AudioDSP_REG2_RUNSTALL, - .src_start = 0, - .src_stop = IMX8M_AudioDSP_REG2_RUNSTALL, .att = imx_dsp_rproc_att_imx8mp, .att_size = ARRAY_SIZE(imx_dsp_rproc_att_imx8mp), - .method = IMX_RPROC_MMIO, + .method = IMX_RPROC_RESET_CONTROLLER, }; static const struct imx_dsp_rproc_dcfg imx_dsp_rproc_cfg_imx8mp = { @@ -329,6 +325,9 @@ static int imx_dsp_rproc_start(struct rproc *rproc) true, rproc->bootaddr); break; + case IMX_RPROC_RESET_CONTROLLER: + ret = reset_control_deassert(priv->run_stall); + break; default: return -EOPNOTSUPP; } @@ -369,6 +368,9 @@ static int imx_dsp_rproc_stop(struct rproc *rproc) false, rproc->bootaddr); break; + case IMX_RPROC_RESET_CONTROLLER: + ret = reset_control_assert(priv->run_stall); + break; default: return -EOPNOTSUPP; } @@ -995,6 +997,13 @@ static int imx_dsp_rproc_detect_mode(struct imx_dsp_rproc *priv) priv->regmap = regmap; break; + case IMX_RPROC_RESET_CONTROLLER: + priv->run_stall = devm_reset_control_get_exclusive(dev, "runstall"); + if (IS_ERR(priv->run_stall)) { + dev_err(dev, "Failed to get DSP runstall reset control\n"); + return PTR_ERR(priv->run_stall); + } + break; default: ret = -EOPNOTSUPP; break; diff --git a/drivers/remoteproc/imx_rproc.h b/drivers/remoteproc/imx_rproc.h index 17a7d051c531..cfd38d37e146 100644 --- a/drivers/remoteproc/imx_rproc.h +++ b/drivers/remoteproc/imx_rproc.h @@ -24,6 +24,8 @@ enum imx_rproc_method { IMX_RPROC_SMC, /* Through System Control Unit API */ IMX_RPROC_SCU_API, + /* Through Reset Controller API */ + IMX_RPROC_RESET_CONTROLLER, }; /* dcfg flags */ -- cgit v1.2.3-59-g8ed1b From 6174206a4b5bebc0b4e01a684672e2bf79df38d8 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 21 Feb 2025 17:03:00 +0100 Subject: remoteproc: qcom: pas: Add SM8750 MPSS Add remote processor PAS loaders for SM8750 MPSS (modem), which differs from SM8650 by lack of fifth memory region for Qlink Logging. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250221160300.160404-2-krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_pas.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 97c4bdd9222a..c34b7780f786 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -1409,6 +1409,30 @@ static const struct adsp_data sm8650_mpss_resource = { .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, }; +static const struct adsp_data sm8750_mpss_resource = { + .crash_reason_smem = 421, + .firmware_name = "modem.mdt", + .dtb_firmware_name = "modem_dtb.mdt", + .pas_id = 4, + .dtb_pas_id = 0x26, + .minidump_id = 3, + .auto_boot = false, + .decrypt_shutdown = true, + .proxy_pd_names = (char*[]){ + "cx", + "mss", + NULL + }, + .load_state = "modem", + .ssr_name = "mpss", + .sysmon_name = "modem", + .ssctl_id = 0x12, + .smem_host_id = 1, + .region_assign_idx = 2, + .region_assign_count = 2, + .region_assign_vmid = QCOM_SCM_VMID_MSS_MSA, +}; + static const struct of_device_id adsp_of_match[] = { { .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init}, { .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource}, @@ -1474,6 +1498,7 @@ static const struct of_device_id adsp_of_match[] = { { .compatible = "qcom,sm8650-adsp-pas", .data = &sm8550_adsp_resource}, { .compatible = "qcom,sm8650-cdsp-pas", .data = &sm8650_cdsp_resource}, { .compatible = "qcom,sm8650-mpss-pas", .data = &sm8650_mpss_resource}, + { .compatible = "qcom,sm8750-mpss-pas", .data = &sm8750_mpss_resource}, { .compatible = "qcom,x1e80100-adsp-pas", .data = &x1e80100_adsp_resource}, { .compatible = "qcom,x1e80100-cdsp-pas", .data = &x1e80100_cdsp_resource}, { }, -- cgit v1.2.3-59-g8ed1b From aac584d35060083bd566a41f48c1b7df2a5270a3 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Fri, 14 Mar 2025 17:17:19 +0200 Subject: remoteproc: imx_dsp_rproc: Document run_stall struct member Add documentation for 'run_stall' imx_dsp_rproc struct member. This also fixes the following warning: warning: Function parameter or struct member 'run_stall' not described in 'imx_dsp_rproc' Fixes: 0184b4fdbad1 ("imx_dsp_rproc: Use reset controller API to control the DSP") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202503142125.IE33sCto-lkp@intel.com/ Signed-off-by: Daniel Baluta Link: https://lore.kernel.org/r/20250314151720.1793719-1-daniel.baluta@nxp.com Signed-off-by: Mathieu Poirier --- drivers/remoteproc/imx_dsp_rproc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c index bc60edcdd661..90cb1fc13e71 100644 --- a/drivers/remoteproc/imx_dsp_rproc.c +++ b/drivers/remoteproc/imx_dsp_rproc.c @@ -96,6 +96,7 @@ enum imx_dsp_rp_mbox_messages { /** * struct imx_dsp_rproc - DSP remote processor state * @regmap: regmap handler + * @run_stall: reset control handle used for Run/Stall operation * @rproc: rproc handler * @dsp_dcfg: device configuration pointer * @clks: clocks needed by this device -- cgit v1.2.3-59-g8ed1b From d2909538bff0189d4d038f4e903c70be5f5c2bfc Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Fri, 14 Mar 2025 09:24:31 +0100 Subject: remoteproc: qcom: pas: add minidump_id to SC7280 WPSS Add the minidump ID to the wpss resources, based on msm-5.4 devicetree. Fixes: 300ed425dfa9 ("remoteproc: qcom_q6v5_pas: Add SC7280 ADSP, CDSP & WPSS") Signed-off-by: Luca Weiss Link: https://lore.kernel.org/r/20250314-sc7280-wpss-minidump-v1-1-d869d53fd432@fairphone.com Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_pas.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index c34b7780f786..534e88b84849 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -1348,6 +1348,7 @@ static const struct adsp_data sc7280_wpss_resource = { .crash_reason_smem = 626, .firmware_name = "wpss.mdt", .pas_id = 6, + .minidump_id = 4, .auto_boot = false, .proxy_pd_names = (char*[]){ "cx", -- cgit v1.2.3-59-g8ed1b From 5208cc34bb720649cebbf6e7e4e77feda0880cf0 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:02 +0100 Subject: irqdomain: remoteproc: Switch to of_fwnode_handle() of_node_to_fwnode() is irqdomain's reimplementation of the "officially" defined of_fwnode_handle(). The former is in the process of being removed, so use the latter instead. Signed-off-by: Jiri Slaby (SUSE) Cc: Bjorn Andersson Cc: Mathieu Poirier Cc: linux-remoteproc@vger.kernel.org Link: https://lore.kernel.org/r/20250319092951.37667-10-jirislaby@kernel.org Signed-off-by: Mathieu Poirier --- drivers/remoteproc/pru_rproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c index 1656574b7317..4a4eb9c0b133 100644 --- a/drivers/remoteproc/pru_rproc.c +++ b/drivers/remoteproc/pru_rproc.c @@ -563,7 +563,7 @@ static int pru_handle_intrmap(struct rproc *rproc) return -ENODEV; } - fwspec.fwnode = of_node_to_fwnode(irq_parent); + fwspec.fwnode = of_fwnode_handle(irq_parent); fwspec.param_count = 3; for (i = 0; i < pru->evt_count; i++) { fwspec.param[0] = rsc->pru_intc_map[i].event; -- cgit v1.2.3-59-g8ed1b From 61e13f95d8314f205ebf792f8f2fd2fcb8733e01 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 21 Mar 2025 17:35:44 +0300 Subject: remoteproc: sysmon: Update qcom_add_sysmon_subdev() comment The comment says the qcom_add_sysmon_subdev() returns NULL on error but it actually returns error pointers. Signed-off-by: Dan Carpenter Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/77a6b65b-5f3f-4a21-a837-7a4a7e09b099@stanley.mountain Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_sysmon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/remoteproc/qcom_sysmon.c b/drivers/remoteproc/qcom_sysmon.c index c24e4a882873..660ac6fc4082 100644 --- a/drivers/remoteproc/qcom_sysmon.c +++ b/drivers/remoteproc/qcom_sysmon.c @@ -619,7 +619,7 @@ static irqreturn_t sysmon_shutdown_interrupt(int irq, void *data) * @name: name of this subdev, to use in SSR * @ssctl_instance: instance id of the ssctl QMI service * - * Return: A new qcom_sysmon object, or NULL on failure + * Return: A new qcom_sysmon object, or an error pointer on failure */ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc, const char *name, -- cgit v1.2.3-59-g8ed1b From efdde3d73ab25cef4ff2d06783b0aad8b093c0e4 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 19 Mar 2025 18:01:05 +0800 Subject: remoteproc: core: Clear table_sz when rproc_shutdown There is case as below could trigger kernel dump: Use U-Boot to start remote processor(rproc) with resource table published to a fixed address by rproc. After Kernel boots up, stop the rproc, load a new firmware which doesn't have resource table ,and start rproc. When starting rproc with a firmware not have resource table, `memcpy(loaded_table, rproc->cached_table, rproc->table_sz)` will trigger dump, because rproc->cache_table is set to NULL during the last stop operation, but rproc->table_sz is still valid. This issue is found on i.MX8MP and i.MX9. Dump as below: Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 Mem abort info: ESR = 0x0000000096000004 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x04: level 0 translation fault Data abort info: ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000 CM = 0, WnR = 0, TnD = 0, TagAccess = 0 GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 user pgtable: 4k pages, 48-bit VAs, pgdp=000000010af63000 [0000000000000000] pgd=0000000000000000, p4d=0000000000000000 Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP Modules linked in: CPU: 2 UID: 0 PID: 1060 Comm: sh Not tainted 6.14.0-rc7-next-20250317-dirty #38 Hardware name: NXP i.MX8MPlus EVK board (DT) pstate: a0000005 (NzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __pi_memcpy_generic+0x110/0x22c lr : rproc_start+0x88/0x1e0 Call trace: __pi_memcpy_generic+0x110/0x22c (P) rproc_boot+0x198/0x57c state_store+0x40/0x104 dev_attr_store+0x18/0x2c sysfs_kf_write+0x7c/0x94 kernfs_fop_write_iter+0x120/0x1cc vfs_write+0x240/0x378 ksys_write+0x70/0x108 __arm64_sys_write+0x1c/0x28 invoke_syscall+0x48/0x10c el0_svc_common.constprop.0+0xc0/0xe0 do_el0_svc+0x1c/0x28 el0_svc+0x30/0xcc el0t_64_sync_handler+0x10c/0x138 el0t_64_sync+0x198/0x19c Clear rproc->table_sz to address the issue. Fixes: 9dc9507f1880 ("remoteproc: Properly deal with the resource table when detaching") Signed-off-by: Peng Fan Link: https://lore.kernel.org/r/20250319100106.3622619-1-peng.fan@oss.nxp.com Signed-off-by: Bjorn Andersson --- drivers/remoteproc/remoteproc_core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index c2cf0d277729..b21eedefff87 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -2025,6 +2025,7 @@ int rproc_shutdown(struct rproc *rproc) kfree(rproc->cached_table); rproc->cached_table = NULL; rproc->table_ptr = NULL; + rproc->table_sz = 0; out: mutex_unlock(&rproc->lock); return ret; -- cgit v1.2.3-59-g8ed1b From ba785ff4162a65f18ed501019637a998b752b5ad Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Tue, 28 Jan 2025 22:53:59 +0100 Subject: remoteproc: qcom_q6v5_pas: Use resource with CX PD for MSM8226 MSM8226 requires the CX power domain, so use the msm8996_adsp_resource which has cx under proxy_pd_names and is otherwise equivalent. Suggested-by: Stephan Gerhold Fixes: fb4f07cc9399 ("remoteproc: qcom: pas: Add MSM8226 ADSP support") Signed-off-by: Luca Weiss Reviewed-by: Stephan Gerhold Link: https://lore.kernel.org/r/20250128-pas-singlepd-v1-1-85d9ae4b0093@lucaweiss.eu Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_pas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 534e88b84849..8f6de1b3a79b 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -1435,7 +1435,7 @@ static const struct adsp_data sm8750_mpss_resource = { }; static const struct of_device_id adsp_of_match[] = { - { .compatible = "qcom,msm8226-adsp-pil", .data = &adsp_resource_init}, + { .compatible = "qcom,msm8226-adsp-pil", .data = &msm8996_adsp_resource}, { .compatible = "qcom,msm8953-adsp-pil", .data = &msm8996_adsp_resource}, { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init}, { .compatible = "qcom,msm8996-adsp-pil", .data = &msm8996_adsp_resource}, -- cgit v1.2.3-59-g8ed1b From e917b73234b02aa4966325e7380d2559bf127ba9 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Tue, 28 Jan 2025 22:54:00 +0100 Subject: remoteproc: qcom_q6v5_pas: Make single-PD handling more robust Only go into the if condition for single-PD handling when there's actually just one power domain specified there. Otherwise it'll be an issue in the dts and we should fail in the regular code path. This also mirrors the latest changes in the qcom_q6v5_mss driver. Suggested-by: Stephan Gerhold Fixes: 17ee2fb4e856 ("remoteproc: qcom: pas: Vote for active/proxy power domains") Signed-off-by: Luca Weiss Reviewed-by: Stephan Gerhold Link: https://lore.kernel.org/r/20250128-pas-singlepd-v1-2-85d9ae4b0093@lucaweiss.eu Signed-off-by: Bjorn Andersson --- drivers/remoteproc/qcom_q6v5_pas.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/remoteproc/qcom_q6v5_pas.c b/drivers/remoteproc/qcom_q6v5_pas.c index 8f6de1b3a79b..b306f223127c 100644 --- a/drivers/remoteproc/qcom_q6v5_pas.c +++ b/drivers/remoteproc/qcom_q6v5_pas.c @@ -501,16 +501,16 @@ static int adsp_pds_attach(struct device *dev, struct device **devs, if (!pd_names) return 0; + while (pd_names[num_pds]) + num_pds++; + /* Handle single power domain */ - if (dev->pm_domain) { + if (num_pds == 1 && dev->pm_domain) { devs[0] = dev; pm_runtime_enable(dev); return 1; } - while (pd_names[num_pds]) - num_pds++; - for (i = 0; i < num_pds; i++) { devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]); if (IS_ERR_OR_NULL(devs[i])) { @@ -535,7 +535,7 @@ static void adsp_pds_detach(struct qcom_adsp *adsp, struct device **pds, int i; /* Handle single power domain */ - if (dev->pm_domain && pd_count) { + if (pd_count == 1 && dev->pm_domain) { pm_runtime_disable(dev); return; } -- cgit v1.2.3-59-g8ed1b