]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
imx_dsp_rproc: Use reset controller API to control the DSP
authorDaniel Baluta <daniel.baluta@nxp.com>
Tue, 11 Mar 2025 08:58:11 +0000 (10:58 +0200)
committerMathieu Poirier <mathieu.poirier@linaro.org>
Thu, 13 Mar 2025 15:11:20 +0000 (09:11 -0600)
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 <peng.fan@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
Link: https://lore.kernel.org/r/20250311085812.1296243-9-daniel.baluta@nxp.com
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
drivers/remoteproc/imx_dsp_rproc.c
drivers/remoteproc/imx_rproc.h

index ea5024919c2ffc9efb8816cba48e25d539c809bc..bc60edcdd6616eaeae59aab4f34244687584d883 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/remoteproc.h>
+#include <linux/reset.h>
 #include <linux/slab.h>
 
 #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;
index 17a7d051c5310277bc38ec162c59b486a477b93a..cfd38d37e1467d1d9e6f89be146c0b53262b92a0 100644 (file)
@@ -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 */