diff options
author | Peng Fan <peng.fan@nxp.com> | 2020-03-22 15:23:06 +0800 |
---|---|---|
committer | Peng Fan <peng.fan@nxp.com> | 2020-04-09 10:35:39 +0800 |
commit | 189e62437de43a4721343d092c1015c07b39053c (patch) | |
tree | 759a4c38ef5c9f5a9872eb2853d2d0c6233f6fd0 | |
parent | d91238cf8c86dfe50350a3bac9cb75aad01d70cd (diff) |
MLK-23754-8 remoteproc: imx: using reset api
Support using reset API to start/stop remote processors.
Currently to i.MX7/8MQ, there are four bits in SRC M4RCR relating
to M4.
SW_M4C_NON_SCLR_RST BIT(0)
SW_M4C_RST BIT(1)
SW_M4P_RST BIT(2)
ENABLE_M4 BIT(3)
We are using BIT(0) and BIT(3) to start/stop M4 in driver.
Reviewed-by: Richard Zhu <hongxing.zhu@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
-rw-r--r-- | drivers/remoteproc/imx_rproc.c | 48 |
1 files changed, 39 insertions, 9 deletions
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c index 100932fe144e..2dabcefb33be 100644 --- a/drivers/remoteproc/imx_rproc.c +++ b/drivers/remoteproc/imx_rproc.c @@ -13,6 +13,7 @@ #include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/regmap.h> +#include <linux/reset.h> #include <linux/remoteproc.h> #define IMX7D_SRC_SCR 0x0C @@ -81,6 +82,8 @@ struct imx_rproc_dcfg { struct imx_rproc { struct device *dev; struct regmap *regmap; + struct reset_control *enable; + struct reset_control *non_sclr_rst; struct rproc *rproc; const struct imx_rproc_dcfg *dcfg; struct imx_rproc_mem mem[IMX7D_RPROC_MEM_MAX]; @@ -162,11 +165,18 @@ static int imx_rproc_start(struct rproc *rproc) struct device *dev = priv->dev; int ret; - if (!priv->regmap) - return -ENOTSUPP; + if (priv->enable) { + ret = reset_control_deassert(priv->enable); + if (!ret) + ret = reset_control_deassert(priv->non_sclr_rst); + } else { + if (!priv->regmap) + return -ENOTSUPP; + + ret = regmap_update_bits(priv->regmap, dcfg->src_reg, + dcfg->src_mask, dcfg->src_start); + } - ret = regmap_update_bits(priv->regmap, dcfg->src_reg, - dcfg->src_mask, dcfg->src_start); if (ret) dev_err(dev, "Failed to enable M4!\n"); @@ -180,11 +190,18 @@ static int imx_rproc_stop(struct rproc *rproc) struct device *dev = priv->dev; int ret; - if (!priv->regmap) - return -ENOTSUPP; + if (priv->enable) { + ret = reset_control_assert(priv->enable); + if (!ret) + ret = reset_control_assert(priv->non_sclr_rst); + } else { + if (!priv->regmap) + return -ENOTSUPP; + + ret = regmap_update_bits(priv->regmap, dcfg->src_reg, + dcfg->src_mask, dcfg->src_stop); + } - ret = regmap_update_bits(priv->regmap, dcfg->src_reg, - dcfg->src_mask, dcfg->src_stop); if (ret) dev_err(dev, "Failed to stop M4!\n"); @@ -323,7 +340,8 @@ static int imx_rproc_probe(struct platform_device *pdev) struct rproc *rproc; struct regmap_config config = { .name = "imx-rproc" }; const struct imx_rproc_dcfg *dcfg; - struct regmap *regmap; + struct regmap *regmap = NULL; + struct reset_control *non_sclr_rst, *enable; int ret; regmap = syscon_regmap_lookup_by_phandle(np, "syscon"); @@ -334,6 +352,16 @@ static int imx_rproc_probe(struct platform_device *pdev) regmap_attach_dev(dev, regmap, &config); } + non_sclr_rst = devm_reset_control_get_optional(dev, "non_sclr_rst"); + if (IS_ERR(non_sclr_rst)) { + if (PTR_ERR(non_sclr_rst) == -EPROBE_DEFER) + return PTR_ERR(non_sclr_rst); + } + + enable = devm_reset_control_get_optional(dev, "enable"); + if (IS_ERR(enable)) + return PTR_ERR(enable); + /* set some other name then imx */ rproc = rproc_alloc(dev, "imx-rproc", &imx_rproc_ops, NULL, sizeof(*priv)); @@ -349,6 +377,8 @@ static int imx_rproc_probe(struct platform_device *pdev) priv = rproc->priv; priv->rproc = rproc; priv->regmap = regmap; + priv->non_sclr_rst = non_sclr_rst; + priv->enable = enable; priv->dcfg = dcfg; priv->dev = dev; |