From: Peng Fan <peng.fan@xxxxxxx> Add three methods IMX_RPROC_NONE(no need start/stop), IMX_RPROC_MMIO(start/stop through mmio) and IMX_RPROC_SMC(start/stop through ARM SMCCC). The current SoCs supported are all using IMX_RPROC_MMIO, add a restrict in probe that only SoCs using IMX_RPROC_MMIO needs syscon regmap to access registers. Signed-off-by: Peng Fan <peng.fan@xxxxxxx> --- drivers/remoteproc/imx_rproc.c | 50 +++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c index c576e12d3817..a7fa9d7fc2d1 100644 --- a/drivers/remoteproc/imx_rproc.c +++ b/drivers/remoteproc/imx_rproc.c @@ -74,6 +74,15 @@ struct imx_rproc_att { int flags; }; +/* Remote core start/stop method */ +enum imx_rproc_method { + IMX_RPROC_NONE, + /* Through syscon regmap */ + IMX_RPROC_MMIO, + /* Through ARM SMCCC */ + IMX_RPROC_SMC, +}; + struct imx_rproc_dcfg { u32 src_reg; u32 src_mask; @@ -81,6 +90,7 @@ struct imx_rproc_dcfg { u32 src_stop; const struct imx_rproc_att *att; size_t att_size; + enum imx_rproc_method method; }; enum imx_rproc_mode { @@ -194,6 +204,7 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = { .src_stop = IMX7D_M4_STOP, .att = imx_rproc_att_imx8mq, .att_size = ARRAY_SIZE(imx_rproc_att_imx8mq), + .method = IMX_RPROC_MMIO, }; static const struct imx_rproc_dcfg imx_rproc_cfg_imx7d = { @@ -203,6 +214,7 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx7d = { .src_stop = IMX7D_M4_STOP, .att = imx_rproc_att_imx7d, .att_size = ARRAY_SIZE(imx_rproc_att_imx7d), + .method = IMX_RPROC_MMIO, }; static const struct imx_rproc_dcfg imx_rproc_cfg_imx6sx = { @@ -212,6 +224,7 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx6sx = { .src_stop = IMX6SX_M4_STOP, .att = imx_rproc_att_imx6sx, .att_size = ARRAY_SIZE(imx_rproc_att_imx6sx), + .method = IMX_RPROC_MMIO, }; static int imx_rproc_start(struct rproc *rproc) @@ -578,15 +591,17 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv) priv->mode = IMX_RPROC_NORMAL; - ret = regmap_read(priv->regmap, dcfg->src_reg, &val); - if (ret) { - dev_err(dev, "Failed to read src\n"); - return ret; - } + if (priv->regmap) { + ret = regmap_read(priv->regmap, dcfg->src_reg, &val); + if (ret) { + dev_err(dev, "Failed to read src\n"); + return ret; + } - if (!(val & dcfg->src_stop)) { - priv->mode = IMX_RPROC_EARLY_BOOT; - priv->rproc->state = RPROC_DETACHED; + if (!(val & dcfg->src_stop)) { + priv->rproc->state = RPROC_DETACHED; + priv->mode = IMX_RPROC_EARLY_BOOT; + } } return 0; @@ -600,16 +615,9 @@ 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; int ret; - regmap = syscon_regmap_lookup_by_phandle(np, "syscon"); - if (IS_ERR(regmap)) { - dev_err(dev, "failed to find syscon\n"); - return PTR_ERR(regmap); - } - regmap_attach_dev(dev, regmap, &config); - /* set some other name then imx */ rproc = rproc_alloc(dev, "imx-rproc", &imx_rproc_ops, NULL, sizeof(*priv)); @@ -622,6 +630,16 @@ static int imx_rproc_probe(struct platform_device *pdev) goto err_put_rproc; } + if (dcfg->method == IMX_RPROC_MMIO) { + regmap = syscon_regmap_lookup_by_phandle(np, "syscon"); + if (IS_ERR(regmap)) { + dev_err(dev, "failed to find syscon\n"); + ret = PTR_ERR(regmap); + goto err_put_rproc; + } + regmap_attach_dev(dev, regmap, &config); + } + priv = rproc->priv; priv->rproc = rproc; priv->regmap = regmap; -- 2.30.0