From 14198a0ca55ebec9890e33cb025a138542e2949d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Matti=20Lehtim=C3=A4ki?= Date: Thu, 6 Feb 2025 20:56:47 +0100 Subject: [PATCH 01/16] dt-bindings: remoteproc: qcom,wcnss-pil: Add support for single power-domain platforms MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Support platforms such as MSM8226 and MSM8974 with only one power rail (CX) modelled as power domain while MX and PX are regulators. [luca: reword commit message, expand based on feedback from Stephan Gerhold] Signed-off-by: Matti Lehtimäki Signed-off-by: Luca Weiss Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250206-wcnss-singlepd-v2-1-9a53ee953dee@lucaweiss.eu Signed-off-by: Bjorn Andersson --- .../bindings/remoteproc/qcom,wcnss-pil.yaml | 45 +++++++++++++++---- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.yaml index 8e033b22d28c..117fb4d0c4ad 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.yaml @@ -69,9 +69,11 @@ properties: CX regulator to be held on behalf of the booting of the WCNSS core. power-domains: + minItems: 1 maxItems: 2 power-domain-names: + minItems: 1 items: - const: cx - const: mx @@ -187,22 +189,43 @@ allOf: - qcom,pronto-v1-pil - qcom,pronto-v2-pil then: - properties: - vddmx-supply: - deprecated: true - description: Deprecated for qcom,pronto-v1/2-pil - - vddcx-supply: - deprecated: true - description: Deprecated for qcom,pronto-v1/2-pil - + # CX and MX must be present either as power domains or regulators oneOf: + # Both CX and MX represented as power domains - required: - power-domains - power-domain-names + properties: + power-domains: + minItems: 2 + power-domain-names: + minItems: 2 + vddmx-supply: false + vddcx-supply: false + # CX represented as power domain, MX as regulator + - required: + - power-domains + - power-domain-names + - vddmx-supply + properties: + power-domains: + maxItems: 1 + power-domain-names: + maxItems: 1 + vddcx-supply: false + # Both CX and MX represented as regulators - required: - vddmx-supply - vddcx-supply + properties: + power-domains: false + power-domain-names: false + vddmx-supply: + deprecated: true + description: Deprecated for qcom,pronto-v1/2-pil + vddcx-supply: + deprecated: true + description: Deprecated for qcom,pronto-v1/2-pil - if: properties: @@ -212,6 +235,10 @@ allOf: - qcom,pronto-v3-pil then: properties: + power-domains: + minItems: 2 + power-domain-names: + minItems: 2 vddmx-supply: false vddcx-supply: false -- 2.51.0 From 65991ea8a6d1e68effdc01d95ebe39f1653f7b71 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Matti=20Lehtim=C3=A4ki?= Date: Thu, 6 Feb 2025 20:56:48 +0100 Subject: [PATCH 02/16] remoteproc: qcom_wcnss: Handle platforms with only single power domain MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 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(-) 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), -- 2.51.0 From cd9ccebfa5c16acb28173e09e81b3c764aec9758 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Tue, 11 Mar 2025 10:58:04 +0200 Subject: [PATCH 03/16] dt-bindings: reset: audiomix: Add reset ids for EARC and DSP Add reset ids used for EARC and DSP on i.MX8MP platform. Acked-by: Rob Herring (Arm) Reviewed-by: Frank Li Signed-off-by: Daniel Baluta Acked-by: Philipp Zabel Link: https://lore.kernel.org/r/20250311085812.1296243-2-daniel.baluta@nxp.com Signed-off-by: Mathieu Poirier --- include/dt-bindings/reset/imx8mp-reset-audiomix.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 include/dt-bindings/reset/imx8mp-reset-audiomix.h diff --git a/include/dt-bindings/reset/imx8mp-reset-audiomix.h b/include/dt-bindings/reset/imx8mp-reset-audiomix.h new file mode 100644 index 000000000000..746c1337ed99 --- /dev/null +++ b/include/dt-bindings/reset/imx8mp-reset-audiomix.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ +/* + * Copyright 2025 NXP + */ + +#ifndef DT_BINDING_RESET_IMX8MP_AUDIOMIX_H +#define DT_BINDING_RESET_IMX8MP_AUDIOMIX_H + +#define IMX8MP_AUDIOMIX_EARC_RESET 0 +#define IMX8MP_AUDIOMIX_EARC_PHY_RESET 1 +#define IMX8MP_AUDIOMIX_DSP_RUNSTALL 2 + +#endif /* DT_BINDING_RESET_IMX8MP_AUDIOMIX_H */ -- 2.51.0 From e1b312356d7adb17f20ac49c036c3f99c4f8d141 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Tue, 11 Mar 2025 10:58:05 +0200 Subject: [PATCH 04/16] dt-bindings: dsp: fsl,dsp: Add resets property Assert and deassert functionality of the DSP found on i.MX8MP is realized by combining control bits from two modules: Audio Block Control and Debug Access Port. Audio block control bits are used to Run/Stall the DSP core while the DAP bits are used for software reset the core. The original plan was to use fsl,dsp-ctrl property and to refer the audiomix bits via syscon interface. This proposal received NACK from community we shouldn't abuse the syscon interface [1]. So remove fsl,dsp-ctrl property for i.MX8MP and use reset control interface instead. Example dts node only uses runstall control now, but softreset will be added in the future when we will convert the softreset functionality to use reset controller API. [1] https://patchwork.kernel.org/project/imx/patch/20250212085222.107102-6-daniel.baluta@nxp.com/ Reviewed-by: Rob Herring (Arm) Reviewed-by: Frank Li Signed-off-by: Daniel Baluta Acked-by: Philipp Zabel Link: https://lore.kernel.org/r/20250311085812.1296243-3-daniel.baluta@nxp.com Signed-off-by: Mathieu Poirier --- .../devicetree/bindings/dsp/fsl,dsp.yaml | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/dsp/fsl,dsp.yaml b/Documentation/devicetree/bindings/dsp/fsl,dsp.yaml index ab93ffd3d2e5..b8693e4b4b0d 100644 --- a/Documentation/devicetree/bindings/dsp/fsl,dsp.yaml +++ b/Documentation/devicetree/bindings/dsp/fsl,dsp.yaml @@ -82,6 +82,15 @@ properties: description: Phandle to syscon block which provide access for processor enablement + resets: + minItems: 1 + + reset-names: + minItems: 1 + items: + - const: runstall + - const: softreset + required: - compatible - reg @@ -164,6 +173,17 @@ allOf: - const: txdb1 - const: rxdb0 - const: rxdb1 + - if: + properties: + compatible: + contains: + enum: + - fsl,imx8mp-dsp + - fsl,imx8mp-hifi4 + then: + required: + - resets + - reset-names additionalProperties: false @@ -186,6 +206,7 @@ examples: }; - | #include + #include dsp_reserved: dsp@92400000 { reg = <0x92400000 0x1000000>; no-map; @@ -220,5 +241,6 @@ examples: <&mu2 3 0>; memory-region = <&dsp_vdev0buffer>, <&dsp_vdev0vring0>, <&dsp_vdev0vring1>, <&dsp_reserved>; - fsl,dsp-ctrl = <&audio_blk_ctrl>; + resets = <&audio_blk_ctrl IMX8MP_AUDIOMIX_DSP_RUNSTALL>; + reset-names = "runstall"; }; -- 2.51.0 From 9df5c535a274c97f92d462ac3bf77f2bef417ef9 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Tue, 11 Mar 2025 10:58:07 +0200 Subject: [PATCH 05/16] 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(-) 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; -- 2.51.0 From a83bc87cd30a4cc544891a0dd4cb752e094125e0 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Tue, 11 Mar 2025 10:58:08 +0200 Subject: [PATCH 06/16] 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(-) 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; -- 2.51.0 From 9fba66374deec0c1158570ff474bacd46651397d Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Tue, 11 Mar 2025 10:58:09 +0200 Subject: [PATCH 07/16] 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(-) 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 = { -- 2.51.0 From c133ec126af841b284f91bcf8c0742e6b42032f5 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Tue, 11 Mar 2025 10:58:10 +0200 Subject: [PATCH 08/16] 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(+) 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 { -- 2.51.0 From 0184b4fdbad1eafbdab385af8ce8a0e68af88dbb Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Tue, 11 Mar 2025 10:58:11 +0200 Subject: [PATCH 09/16] 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(-) 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 */ -- 2.51.0 From 89f95f2108de52431bbf0ca432e337fc1f40ee00 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 21 Feb 2025 17:02:59 +0100 Subject: [PATCH 10/16] dt-bindings: remoteproc: Add SM8750 MPSS Add remote processor PAS loader for SM8750 MPSS (modem). Device looks fully compatible with SM8650, however it lacks fifth memory region for Qlink Logging, according to downstream sources. This is a bit tricky, because updated downstream sources for newer downstream release dropped that fifth memory region as well. There might be other differences against SM8650, because the modem currently crashes after starting. Acked-by: Conor Dooley Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250221160300.160404-1-krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson --- .../bindings/remoteproc/qcom,sm8550-pas.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml index 8bfded3c66ef..2dd479cf4821 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml @@ -24,6 +24,7 @@ properties: - qcom,sm8650-adsp-pas - qcom,sm8650-cdsp-pas - qcom,sm8650-mpss-pas + - qcom,sm8750-mpss-pas - qcom,x1e80100-adsp-pas - qcom,x1e80100-cdsp-pas - items: @@ -164,6 +165,21 @@ allOf: minItems: 5 maxItems: 5 + - if: + properties: + compatible: + enum: + - qcom,sm8750-mpss-pas + then: + properties: + interrupts: + minItems: 6 + interrupt-names: + minItems: 6 + memory-region: + minItems: 4 + maxItems: 4 + - if: properties: compatible: @@ -191,6 +207,7 @@ allOf: - qcom,sdx75-mpss-pas - qcom,sm8550-mpss-pas - qcom,sm8650-mpss-pas + - qcom,sm8750-mpss-pas then: properties: power-domains: -- 2.51.0 From 6174206a4b5bebc0b4e01a684672e2bf79df38d8 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 21 Feb 2025 17:03:00 +0100 Subject: [PATCH 11/16] 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(+) 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}, { }, -- 2.51.0 From aac584d35060083bd566a41f48c1b7df2a5270a3 Mon Sep 17 00:00:00 2001 From: Daniel Baluta Date: Fri, 14 Mar 2025 17:17:19 +0200 Subject: [PATCH 12/16] 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(+) 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 -- 2.51.0 From d2909538bff0189d4d038f4e903c70be5f5c2bfc Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Fri, 14 Mar 2025 09:24:31 +0100 Subject: [PATCH 13/16] 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(+) 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", -- 2.51.0 From 5208cc34bb720649cebbf6e7e4e77feda0880cf0 Mon Sep 17 00:00:00 2001 From: "Jiri Slaby (SUSE)" Date: Wed, 19 Mar 2025 10:29:02 +0100 Subject: [PATCH 14/16] 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(-) 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; -- 2.51.0 From 4b4ab93ddc5f28f70640f883d53c331b1a9b8d7a Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Sat, 16 Nov 2024 12:40:04 +0100 Subject: [PATCH 15/16] dt-bindings: remoteproc: Consolidate SC8180X and SM8150 PAS files SC8180X PAS bindings are plain wrong, resulting in false-positive dt checker errors. SC8180X's remoteprocs happen to be identical to SM8150's from the kernel point of view, so reuse that binding instead. Fixes: 4865ed136045 ("dt-bindings: remoteproc: qcom: pas: Add SC8180X adsp, cdsp and mpss") Signed-off-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20241116-topic-sc8180x_rproc_bindings-v1-1-ae5d3f7ab261@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- .../bindings/remoteproc/qcom,sc8180x-pas.yaml | 96 ------------------- .../bindings/remoteproc/qcom,sm8150-pas.yaml | 7 ++ 2 files changed, 7 insertions(+), 96 deletions(-) delete mode 100644 Documentation/devicetree/bindings/remoteproc/qcom,sc8180x-pas.yaml diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sc8180x-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sc8180x-pas.yaml deleted file mode 100644 index 45ee9fbe0966..000000000000 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sc8180x-pas.yaml +++ /dev/null @@ -1,96 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/remoteproc/qcom,sc8180x-pas.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Qualcomm SC8180X Peripheral Authentication Service - -maintainers: - - Manivannan Sadhasivam - -description: - Qualcomm SC8180X SoC Peripheral Authentication Service loads and boots - firmware on the Qualcomm DSP Hexagon cores. - -properties: - compatible: - enum: - - qcom,sc8180x-adsp-pas - - qcom,sc8180x-cdsp-pas - - qcom,sc8180x-mpss-pas - - reg: - maxItems: 1 - - clocks: - items: - - description: XO clock - - clock-names: - items: - - const: xo - - qcom,qmp: - $ref: /schemas/types.yaml#/definitions/phandle - description: Reference to the AOSS side-channel message RAM. - - smd-edge: false - - memory-region: - maxItems: 1 - description: Reference to the reserved-memory for the Hexagon core - - firmware-name: - maxItems: 1 - description: Firmware name for the Hexagon core - -required: - - compatible - - reg - - memory-region - -allOf: - - $ref: /schemas/remoteproc/qcom,pas-common.yaml# - - if: - properties: - compatible: - enum: - - qcom,sc8180x-adsp-pas - - qcom,sc8180x-cdsp-pas - then: - properties: - interrupts: - maxItems: 5 - interrupt-names: - maxItems: 5 - else: - properties: - interrupts: - minItems: 6 - interrupt-names: - minItems: 6 - - - if: - properties: - compatible: - enum: - - qcom,sc8180x-adsp-pas - - qcom,sc8180x-cdsp-pas - then: - properties: - power-domains: - items: - - description: LCX power domain - - description: LMX power domain - power-domain-names: - items: - - const: lcx - - const: lmx - else: - properties: - # TODO: incomplete - power-domains: false - power-domain-names: false - -unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm8150-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sm8150-pas.yaml index d67386c50fa4..56ff6386534d 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sm8150-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm8150-pas.yaml @@ -60,6 +60,9 @@ allOf: properties: compatible: enum: + - qcom,sc8180x-adsp-pas + - qcom,sc8180x-cdsp-pas + - qcom,sc8180x-slpi-pas - qcom,sm8150-adsp-pas - qcom,sm8150-cdsp-pas - qcom,sm8150-slpi-pas @@ -83,6 +86,8 @@ allOf: properties: compatible: enum: + - qcom,sc8180x-adsp-pas + - qcom,sc8180x-cdsp-pas - qcom,sm8150-adsp-pas - qcom,sm8150-cdsp-pas - qcom,sm8250-cdsp-pas @@ -99,6 +104,7 @@ allOf: properties: compatible: enum: + - qcom,sc8180x-mpss-pas - qcom,sm8150-mpss-pas then: properties: @@ -115,6 +121,7 @@ allOf: properties: compatible: enum: + - qcom,sc8180x-slpi-pas - qcom,sm8150-slpi-pas - qcom,sm8250-adsp-pas - qcom,sm8250-slpi-pas -- 2.51.0 From 61e13f95d8314f205ebf792f8f2fd2fcb8733e01 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 21 Mar 2025 17:35:44 +0300 Subject: [PATCH 16/16] 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(-) 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, -- 2.51.0