From: Peng Fan <[email protected]>
V4:
Typo fix
patch 4: take state as a check condition
patch 5: move regmap lookup/attach to imx_rproc_detect_mode
patch 6: add imx_rproc_clk_enable for optional clk
patch 8: use switch/case in imx_rproc_detect_mode
V3:
Add A-b tag for Patch 1/2
Fix the checkpatch warning for Patch 6,8
V2:
Patch 1/8, use fsl as vendor, typo fix
Because patchset [1] has v2 version, patch 5,6,7,8 are adapted that
change.
This patchset is to support i.MX7ULP/8MN/8MP, also includes a patch to
parse fsl,auto-boot
Peng Fan (8):
dt-bindings: remoteproc: imx_rproc: add fsl,auto-boot property
dt-bindings: remoteproc: imx_rproc: add i.MX7ULP support
dt-bindings: remoteproc: imx_rproc: support i.MX8MN/P
remoteproc: imx_rproc: parse fsl,auto-boot
remoteproc: imx_rproc: initial support for mutilple start/stop method
remoteproc: imx_rproc: make clk optional
remoteproc: imx_rproc: support i.MX7ULP
remoteproc: imx_rproc: support i.MX8MN/P
.../bindings/remoteproc/fsl,imx-rproc.yaml | 11 +-
drivers/remoteproc/imx_rproc.c | 206 +++++++++++++++++----
2 files changed, 179 insertions(+), 38 deletions(-)
--
2.7.4
From: Peng Fan <[email protected]>
Add an optional property "fsl,auto-boot" to indicate remote processor
auto boot.
Signed-off-by: Peng Fan <[email protected]>
Acked-by: Rob Herring <[email protected]>
---
Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
index 208a628..b13bf8d 100644
--- a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
@@ -49,6 +49,12 @@ properties:
minItems: 1
maxItems: 32
+ fsl,auto-boot:
+ $ref: /schemas/types.yaml#/definitions/flag
+ description:
+ Indicate whether need to load the default firmware and start the remote
+ processor automatically.
+
required:
- compatible
- clocks
--
2.7.4
From: Peng Fan <[email protected]>
Add i.MX7ULP compatible.
We use i.MX7ULP dual mode and in which case i.MX7ULP A7 core runs under
control of M4 core, M4 core starts by ROM and powers most services used
by A7 core, so A7 core has no power to start and stop M4 core. So
clocks and syscon are not required.
Signed-off-by: Peng Fan <[email protected]>
Acked-by: Rob Herring <[email protected]>
---
Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
index b13bf8d..58bc2a2 100644
--- a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
@@ -18,6 +18,7 @@ properties:
- fsl,imx8mq-cm4
- fsl,imx8mm-cm4
- fsl,imx7d-cm4
+ - fsl,imx7ulp-cm4
- fsl,imx6sx-cm4
clocks:
@@ -57,8 +58,6 @@ properties:
required:
- compatible
- - clocks
- - syscon
additionalProperties: false
--
2.7.4
From: Peng Fan <[email protected]>
Add i.MX8MN/P remote processor(Cortex-M7) compatible string
Signed-off-by: Peng Fan <[email protected]>
Acked-by: Rob Herring <[email protected]>
---
Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
index 58bc2a2..1dc34cf 100644
--- a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
@@ -17,6 +17,8 @@ properties:
enum:
- fsl,imx8mq-cm4
- fsl,imx8mm-cm4
+ - fsl,imx8mn-cm7
+ - fsl,imx8mp-cm7
- fsl,imx7d-cm4
- fsl,imx7ulp-cm4
- fsl,imx6sx-cm4
--
2.7.4
From: Peng Fan <[email protected]>
Parse fsl,auto-boot to indicate whether need remoteproc framework
auto boot or not.
When remote processor is booted before Linux Kernel up, do not parse
fsl,auto-boot, so only need to parse the property when rproc state is
RPROC_DETACHED.
Signed-off-by: Peng Fan <[email protected]>
---
drivers/remoteproc/imx_rproc.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index d633887..06dac92 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -654,6 +654,9 @@ static int imx_rproc_probe(struct platform_device *pdev)
INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
+ if (rproc->state != RPROC_DETACHED)
+ rproc->auto_boot = of_property_read_bool(np, "fsl,auto-boot");
+
ret = rproc_add(rproc);
if (ret) {
dev_err(dev, "rproc_add failed\n");
--
2.7.4
From: Peng Fan <[email protected]>
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 imx_rproc_detect_mode that only SoCs using IMX_RPROC_MMIO needs syscon
regmap to access registers.
Signed-off-by: Peng Fan <[email protected]>
---
drivers/remoteproc/imx_rproc.c | 51 +++++++++++++++++++++++++++++-------------
1 file changed, 35 insertions(+), 16 deletions(-)
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 06dac92..2b633fd 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;
};
struct imx_rproc {
@@ -183,6 +193,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 = {
@@ -192,6 +203,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 = {
@@ -201,6 +213,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)
@@ -560,19 +573,35 @@ static void imx_rproc_free_mbox(struct rproc *rproc)
static int imx_rproc_detect_mode(struct imx_rproc *priv)
{
+ struct regmap_config config = { .name = "imx-rproc" };
const struct imx_rproc_dcfg *dcfg = priv->dcfg;
struct device *dev = priv->dev;
+ struct regmap *regmap;
int ret;
u32 val;
- ret = regmap_read(priv->regmap, dcfg->src_reg, &val);
- if (ret) {
- dev_err(dev, "Failed to read src\n");
- return ret;
+ if (dcfg->method != IMX_RPROC_MMIO)
+ return 0;
+
+ regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
+ if (IS_ERR(regmap)) {
+ dev_err(dev, "failed to find syscon\n");
+ return PTR_ERR(regmap);
}
- if (!(val & dcfg->src_stop))
- priv->rproc->state = RPROC_DETACHED;
+ priv->regmap = regmap;
+ regmap_attach_dev(dev, regmap, &config);
+
+ if (regmap) {
+ ret = regmap_read(regmap, dcfg->src_reg, &val);
+ if (ret) {
+ dev_err(dev, "Failed to read src\n");
+ return ret;
+ }
+
+ if (!(val & dcfg->src_stop))
+ priv->rproc->state = RPROC_DETACHED;
+ }
return 0;
}
@@ -583,18 +612,9 @@ static int imx_rproc_probe(struct platform_device *pdev)
struct device_node *np = dev->of_node;
struct imx_rproc *priv;
struct rproc *rproc;
- struct regmap_config config = { .name = "imx-rproc" };
const struct imx_rproc_dcfg *dcfg;
- struct regmap *regmap;
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));
@@ -609,7 +629,6 @@ static int imx_rproc_probe(struct platform_device *pdev)
priv = rproc->priv;
priv->rproc = rproc;
- priv->regmap = regmap;
priv->dcfg = dcfg;
priv->dev = dev;
--
2.7.4
From: Peng Fan <[email protected]>
Add i.MX8MN/P remote processor(Cortex-M7) support, we are using ARM
SMCCC to start/stop M core, not using regmap interface.
Signed-off-by: Peng Fan <[email protected]>
---
drivers/remoteproc/imx_rproc.c | 87 ++++++++++++++++++++++++++++++++++++++----
1 file changed, 80 insertions(+), 7 deletions(-)
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 0592865..0ff16e3 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -3,6 +3,7 @@
* Copyright (c) 2017 Pengutronix, Oleksij Rempel <[email protected]>
*/
+#include <linux/arm-smccc.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/interrupt.h>
@@ -50,6 +51,11 @@
#define IMX_RPROC_MEM_MAX 32
+#define IMX_SIP_RPROC 0xC2000005
+#define IMX_SIP_RPROC_START 0x00
+#define IMX_SIP_RPROC_STARTED 0x01
+#define IMX_SIP_RPROC_STOP 0x02
+
/**
* struct imx_rproc_mem - slim internal memory structure
* @cpu_addr: MPU virtual address of the memory region
@@ -108,6 +114,36 @@ struct imx_rproc {
void __iomem *rsc_table;
};
+static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
+ /* dev addr , sys addr , size , flags */
+ /* ITCM */
+ { 0x00000000, 0x007E0000, 0x00020000, ATT_OWN },
+ /* OCRAM_S */
+ { 0x00180000, 0x00180000, 0x00009000, 0 },
+ /* OCRAM */
+ { 0x00900000, 0x00900000, 0x00020000, 0 },
+ /* OCRAM */
+ { 0x00920000, 0x00920000, 0x00020000, 0 },
+ /* OCRAM */
+ { 0x00940000, 0x00940000, 0x00050000, 0 },
+ /* QSPI Code - alias */
+ { 0x08000000, 0x08000000, 0x08000000, 0 },
+ /* DDR (Code) - alias */
+ { 0x10000000, 0x40000000, 0x0FFE0000, 0 },
+ /* DTCM */
+ { 0x20000000, 0x00800000, 0x00020000, ATT_OWN },
+ /* OCRAM_S - alias */
+ { 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
+ /* OCRAM */
+ { 0x20200000, 0x00900000, 0x00020000, ATT_OWN },
+ /* OCRAM */
+ { 0x20220000, 0x00920000, 0x00020000, ATT_OWN },
+ /* OCRAM */
+ { 0x20240000, 0x00940000, 0x00040000, ATT_OWN },
+ /* DDR (Data) */
+ { 0x40000000, 0x40000000, 0x80000000, 0 },
+};
+
static const struct imx_rproc_att imx_rproc_att_imx8mq[] = {
/* dev addr , sys addr , size , flags */
/* TCML - alias */
@@ -194,6 +230,12 @@ static const struct imx_rproc_att imx_rproc_att_imx6sx[] = {
{ 0x80000000, 0x80000000, 0x60000000, 0 },
};
+static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn = {
+ .att = imx_rproc_att_imx8mn,
+ .att_size = ARRAY_SIZE(imx_rproc_att_imx8mn),
+ .method = IMX_RPROC_SMC,
+};
+
static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = {
.src_reg = IMX7D_SRC_SCR,
.src_mask = IMX7D_M4_RST_MASK,
@@ -235,12 +277,24 @@ static int imx_rproc_start(struct rproc *rproc)
struct imx_rproc *priv = rproc->priv;
const struct imx_rproc_dcfg *dcfg = priv->dcfg;
struct device *dev = priv->dev;
+ struct arm_smccc_res res;
int ret;
- ret = regmap_update_bits(priv->regmap, dcfg->src_reg,
- dcfg->src_mask, dcfg->src_start);
+ switch (dcfg->method) {
+ case IMX_RPROC_MMIO:
+ ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
+ dcfg->src_start);
+ break;
+ case IMX_RPROC_SMC:
+ arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_START, 0, 0, 0, 0, 0, 0, &res);
+ ret = res.a0;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
if (ret)
- dev_err(dev, "Failed to enable M4!\n");
+ dev_err(dev, "Failed to enable remote cores!\n");
return ret;
}
@@ -250,15 +304,26 @@ static int imx_rproc_stop(struct rproc *rproc)
struct imx_rproc *priv = rproc->priv;
const struct imx_rproc_dcfg *dcfg = priv->dcfg;
struct device *dev = priv->dev;
+ struct arm_smccc_res res;
int ret;
- if (dcfg->method == IMX_RPROC_NONE)
+ switch (dcfg->method) {
+ case IMX_RPROC_MMIO:
+ ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
+ dcfg->src_stop);
+ break;
+ case IMX_RPROC_SMC:
+ arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STOP, 0, 0, 0, 0, 0, 0, &res);
+ ret = res.a0;
+ if (res.a1)
+ dev_info(dev, "Not in wfi, force stopped\n");
+ break;
+ default:
return -EOPNOTSUPP;
+ }
- 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");
+ dev_err(dev, "Failed to stop remote cores\n");
return ret;
}
@@ -594,6 +659,7 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
const struct imx_rproc_dcfg *dcfg = priv->dcfg;
struct device *dev = priv->dev;
struct regmap *regmap;
+ struct arm_smccc_res res;
int ret;
u32 val;
@@ -601,6 +667,11 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
case IMX_RPROC_NONE:
priv->rproc->state = RPROC_DETACHED;
return 0;
+ case IMX_RPROC_SMC:
+ arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STARTED, 0, 0, 0, 0, 0, 0, &res);
+ if (res.a0)
+ priv->rproc->state = RPROC_DETACHED;
+ return 0;
default:
break;
}
@@ -753,6 +824,8 @@ static const struct of_device_id imx_rproc_of_match[] = {
{ .compatible = "fsl,imx6sx-cm4", .data = &imx_rproc_cfg_imx6sx },
{ .compatible = "fsl,imx8mq-cm4", .data = &imx_rproc_cfg_imx8mq },
{ .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq },
+ { .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
+ { .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
{},
};
MODULE_DEVICE_TABLE(of, imx_rproc_of_match);
--
2.7.4
From: Peng Fan <[email protected]>
To i.MX7ULP, M4 is the master to control everything, no need to provide
clk from Linux side. So make clk optional when method is IMX_RPROC_NONE.
Signed-off-by: Peng Fan <[email protected]>
---
drivers/remoteproc/imx_rproc.c | 46 ++++++++++++++++++++++++++++--------------
1 file changed, 31 insertions(+), 15 deletions(-)
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 2b633fd..56dfcc1 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -606,6 +606,35 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
return 0;
}
+static int imx_rproc_clk_enable(struct imx_rproc *priv)
+{
+ const struct imx_rproc_dcfg *dcfg = priv->dcfg;
+ struct device *dev = priv->dev;
+ int ret;
+
+ /* Remote core is not under control of Linux */
+ if (dcfg->method == IMX_RPROC_NONE)
+ return 0;
+
+ priv->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ dev_err(dev, "Failed to get clock\n");
+ return PTR_ERR(priv->clk);
+ }
+
+ /*
+ * clk for M4 block including memory. Should be
+ * enabled before .start for FW transfer.
+ */
+ ret = clk_prepare_enable(priv->clk);
+ if (ret) {
+ dev_err(dev, "Failed to enable clock\n");
+ return ret;
+ }
+
+ return 0;
+}
+
static int imx_rproc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -654,22 +683,9 @@ static int imx_rproc_probe(struct platform_device *pdev)
if (ret)
goto err_put_mbox;
- priv->clk = devm_clk_get(dev, NULL);
- if (IS_ERR(priv->clk)) {
- dev_err(dev, "Failed to get clock\n");
- ret = PTR_ERR(priv->clk);
- goto err_put_mbox;
- }
-
- /*
- * clk for M4 block including memory. Should be
- * enabled before .start for FW transfer.
- */
- ret = clk_prepare_enable(priv->clk);
- if (ret) {
- dev_err(&rproc->dev, "Failed to enable clock\n");
+ ret = imx_rproc_clk_enable(priv);
+ if (ret)
goto err_put_mbox;
- }
INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
--
2.7.4
From: Peng Fan <[email protected]>
i.MX7ULP A7 core runs under control of M4 core, M4 core starts by ROM
and powers most serivces used by A7 core, so A7 core has no power to
start and stop M4 core. And the M4 core's state is default RPROC_DETACHED
and remoteproc framework not able to stop the M4 core.
Signed-off-by: Peng Fan <[email protected]>
---
drivers/remoteproc/imx_rproc.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 56dfcc1..0592865 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -136,6 +136,14 @@ static const struct imx_rproc_att imx_rproc_att_imx8mq[] = {
{ 0x40000000, 0x40000000, 0x80000000, 0 },
};
+static const struct imx_rproc_att imx_rproc_att_imx7ulp[] = {
+ {0x1FFD0000, 0x1FFD0000, 0x30000, ATT_OWN},
+ {0x20000000, 0x20000000, 0x10000, ATT_OWN},
+ {0x2F000000, 0x2F000000, 0x20000, ATT_OWN},
+ {0x2F020000, 0x2F020000, 0x20000, ATT_OWN},
+ {0x60000000, 0x60000000, 0x40000000, 0}
+};
+
static const struct imx_rproc_att imx_rproc_att_imx7d[] = {
/* dev addr , sys addr , size , flags */
/* OCRAM_S (M4 Boot code) - alias */
@@ -196,6 +204,12 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = {
.method = IMX_RPROC_MMIO,
};
+static const struct imx_rproc_dcfg imx_rproc_cfg_imx7ulp = {
+ .att = imx_rproc_att_imx7ulp,
+ .att_size = ARRAY_SIZE(imx_rproc_att_imx7ulp),
+ .method = IMX_RPROC_NONE,
+};
+
static const struct imx_rproc_dcfg imx_rproc_cfg_imx7d = {
.src_reg = IMX7D_SRC_SCR,
.src_mask = IMX7D_M4_RST_MASK,
@@ -238,6 +252,9 @@ static int imx_rproc_stop(struct rproc *rproc)
struct device *dev = priv->dev;
int ret;
+ if (dcfg->method == IMX_RPROC_NONE)
+ return -EOPNOTSUPP;
+
ret = regmap_update_bits(priv->regmap, dcfg->src_reg,
dcfg->src_mask, dcfg->src_stop);
if (ret)
@@ -580,8 +597,13 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
int ret;
u32 val;
- if (dcfg->method != IMX_RPROC_MMIO)
+ switch (dcfg->method) {
+ case IMX_RPROC_NONE:
+ priv->rproc->state = RPROC_DETACHED;
return 0;
+ default:
+ break;
+ }
regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
if (IS_ERR(regmap)) {
@@ -726,6 +748,7 @@ static int imx_rproc_remove(struct platform_device *pdev)
}
static const struct of_device_id imx_rproc_of_match[] = {
+ { .compatible = "fsl,imx7ulp-cm4", .data = &imx_rproc_cfg_imx7ulp },
{ .compatible = "fsl,imx7d-cm4", .data = &imx_rproc_cfg_imx7d },
{ .compatible = "fsl,imx6sx-cm4", .data = &imx_rproc_cfg_imx6sx },
{ .compatible = "fsl,imx8mq-cm4", .data = &imx_rproc_cfg_imx8mq },
--
2.7.4
On Thu, Apr 15, 2021 at 09:27:37PM +0800, [email protected] wrote:
> From: Peng Fan <[email protected]>
>
> Parse fsl,auto-boot to indicate whether need remoteproc framework
> auto boot or not.
>
> When remote processor is booted before Linux Kernel up, do not parse
> fsl,auto-boot, so only need to parse the property when rproc state is
> RPROC_DETACHED.
>
> Signed-off-by: Peng Fan <[email protected]>
> ---
> drivers/remoteproc/imx_rproc.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index d633887..06dac92 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -654,6 +654,9 @@ static int imx_rproc_probe(struct platform_device *pdev)
>
> INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
>
> + if (rproc->state != RPROC_DETACHED)
> + rproc->auto_boot = of_property_read_bool(np, "fsl,auto-boot");
> +
Reviewed-by: Mathieu Poirier <[email protected]>
> ret = rproc_add(rproc);
> if (ret) {
> dev_err(dev, "rproc_add failed\n");
> --
> 2.7.4
>
On Thu, Apr 15, 2021 at 09:27:38PM +0800, [email protected] wrote:
> From: Peng Fan <[email protected]>
>
> 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 imx_rproc_detect_mode that only SoCs using IMX_RPROC_MMIO needs syscon
> regmap to access registers.
>
> Signed-off-by: Peng Fan <[email protected]>
> ---
> drivers/remoteproc/imx_rproc.c | 51 +++++++++++++++++++++++++++++-------------
> 1 file changed, 35 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 06dac92..2b633fd 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;
> };
>
> struct imx_rproc {
> @@ -183,6 +193,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 = {
> @@ -192,6 +203,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 = {
> @@ -201,6 +213,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)
> @@ -560,19 +573,35 @@ static void imx_rproc_free_mbox(struct rproc *rproc)
>
> static int imx_rproc_detect_mode(struct imx_rproc *priv)
> {
> + struct regmap_config config = { .name = "imx-rproc" };
> const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> struct device *dev = priv->dev;
> + struct regmap *regmap;
> int ret;
> u32 val;
>
> - ret = regmap_read(priv->regmap, dcfg->src_reg, &val);
> - if (ret) {
> - dev_err(dev, "Failed to read src\n");
> - return ret;
> + if (dcfg->method != IMX_RPROC_MMIO)
> + return 0;
> +
> + regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
> + if (IS_ERR(regmap)) {
> + dev_err(dev, "failed to find syscon\n");
> + return PTR_ERR(regmap);
> }
>
> - if (!(val & dcfg->src_stop))
> - priv->rproc->state = RPROC_DETACHED;
> + priv->regmap = regmap;
> + regmap_attach_dev(dev, regmap, &config);
> +
> + if (regmap) {
This if() statement is not needed. Moreover all the modifications in this
function should go under a IMX_RPROC_MMIO case statement in patch 7.
> + ret = regmap_read(regmap, dcfg->src_reg, &val);
> + if (ret) {
> + dev_err(dev, "Failed to read src\n");
> + return ret;
> + }
> +
> + if (!(val & dcfg->src_stop))
> + priv->rproc->state = RPROC_DETACHED;
> + }
>
> return 0;
> }
> @@ -583,18 +612,9 @@ static int imx_rproc_probe(struct platform_device *pdev)
> struct device_node *np = dev->of_node;
> struct imx_rproc *priv;
> struct rproc *rproc;
> - struct regmap_config config = { .name = "imx-rproc" };
> const struct imx_rproc_dcfg *dcfg;
> - struct regmap *regmap;
> 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));
> @@ -609,7 +629,6 @@ static int imx_rproc_probe(struct platform_device *pdev)
>
> priv = rproc->priv;
> priv->rproc = rproc;
> - priv->regmap = regmap;
> priv->dcfg = dcfg;
> priv->dev = dev;
>
> --
> 2.7.4
>
On Thu, Apr 15, 2021 at 09:27:39PM +0800, [email protected] wrote:
> From: Peng Fan <[email protected]>
>
> To i.MX7ULP, M4 is the master to control everything, no need to provide
> clk from Linux side. So make clk optional when method is IMX_RPROC_NONE.
>
> Signed-off-by: Peng Fan <[email protected]>
> ---
> drivers/remoteproc/imx_rproc.c | 46 ++++++++++++++++++++++++++++--------------
> 1 file changed, 31 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 2b633fd..56dfcc1 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -606,6 +606,35 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
> return 0;
> }
>
> +static int imx_rproc_clk_enable(struct imx_rproc *priv)
> +{
> + const struct imx_rproc_dcfg *dcfg = priv->dcfg;
> + struct device *dev = priv->dev;
> + int ret;
> +
> + /* Remote core is not under control of Linux */
> + if (dcfg->method == IMX_RPROC_NONE)
> + return 0;
> +
> + priv->clk = devm_clk_get(dev, NULL);
> + if (IS_ERR(priv->clk)) {
> + dev_err(dev, "Failed to get clock\n");
> + return PTR_ERR(priv->clk);
> + }
> +
> + /*
> + * clk for M4 block including memory. Should be
> + * enabled before .start for FW transfer.
> + */
> + ret = clk_prepare_enable(priv->clk);
> + if (ret) {
> + dev_err(dev, "Failed to enable clock\n");
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> static int imx_rproc_probe(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
> @@ -654,22 +683,9 @@ static int imx_rproc_probe(struct platform_device *pdev)
> if (ret)
> goto err_put_mbox;
>
> - priv->clk = devm_clk_get(dev, NULL);
> - if (IS_ERR(priv->clk)) {
> - dev_err(dev, "Failed to get clock\n");
> - ret = PTR_ERR(priv->clk);
> - goto err_put_mbox;
> - }
> -
> - /*
> - * clk for M4 block including memory. Should be
> - * enabled before .start for FW transfer.
> - */
> - ret = clk_prepare_enable(priv->clk);
> - if (ret) {
> - dev_err(&rproc->dev, "Failed to enable clock\n");
> + ret = imx_rproc_clk_enable(priv);
> + if (ret)
Much better
Reviewed-by: Mathieu Poirier <[email protected]>
> goto err_put_mbox;
> - }
>
> INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
>
> --
> 2.7.4
>
On Thu, Apr 15, 2021 at 09:27:40PM +0800, [email protected] wrote:
> From: Peng Fan <[email protected]>
>
> i.MX7ULP A7 core runs under control of M4 core, M4 core starts by ROM
> and powers most serivces used by A7 core, so A7 core has no power to
s/serivces/services
> start and stop M4 core. And the M4 core's state is default RPROC_DETACHED
> and remoteproc framework not able to stop the M4 core.
>
> Signed-off-by: Peng Fan <[email protected]>
> ---
> drivers/remoteproc/imx_rproc.c | 25 ++++++++++++++++++++++++-
> 1 file changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 56dfcc1..0592865 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -136,6 +136,14 @@ static const struct imx_rproc_att imx_rproc_att_imx8mq[] = {
> { 0x40000000, 0x40000000, 0x80000000, 0 },
> };
>
> +static const struct imx_rproc_att imx_rproc_att_imx7ulp[] = {
> + {0x1FFD0000, 0x1FFD0000, 0x30000, ATT_OWN},
> + {0x20000000, 0x20000000, 0x10000, ATT_OWN},
> + {0x2F000000, 0x2F000000, 0x20000, ATT_OWN},
> + {0x2F020000, 0x2F020000, 0x20000, ATT_OWN},
> + {0x60000000, 0x60000000, 0x40000000, 0}
> +};
> +
> static const struct imx_rproc_att imx_rproc_att_imx7d[] = {
> /* dev addr , sys addr , size , flags */
> /* OCRAM_S (M4 Boot code) - alias */
> @@ -196,6 +204,12 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = {
> .method = IMX_RPROC_MMIO,
> };
>
> +static const struct imx_rproc_dcfg imx_rproc_cfg_imx7ulp = {
> + .att = imx_rproc_att_imx7ulp,
> + .att_size = ARRAY_SIZE(imx_rproc_att_imx7ulp),
> + .method = IMX_RPROC_NONE,
> +};
> +
> static const struct imx_rproc_dcfg imx_rproc_cfg_imx7d = {
> .src_reg = IMX7D_SRC_SCR,
> .src_mask = IMX7D_M4_RST_MASK,
> @@ -238,6 +252,9 @@ static int imx_rproc_stop(struct rproc *rproc)
> struct device *dev = priv->dev;
> int ret;
>
> + if (dcfg->method == IMX_RPROC_NONE)
> + return -EOPNOTSUPP;
> +
> ret = regmap_update_bits(priv->regmap, dcfg->src_reg,
> dcfg->src_mask, dcfg->src_stop);
> if (ret)
> @@ -580,8 +597,13 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
> int ret;
> u32 val;
>
> - if (dcfg->method != IMX_RPROC_MMIO)
> + switch (dcfg->method) {
> + case IMX_RPROC_NONE:
> + priv->rproc->state = RPROC_DETACHED;
> return 0;
> + default:
> + break;
> + }
>
> regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
> if (IS_ERR(regmap)) {
> @@ -726,6 +748,7 @@ static int imx_rproc_remove(struct platform_device *pdev)
> }
>
> static const struct of_device_id imx_rproc_of_match[] = {
> + { .compatible = "fsl,imx7ulp-cm4", .data = &imx_rproc_cfg_imx7ulp },
> { .compatible = "fsl,imx7d-cm4", .data = &imx_rproc_cfg_imx7d },
> { .compatible = "fsl,imx6sx-cm4", .data = &imx_rproc_cfg_imx6sx },
> { .compatible = "fsl,imx8mq-cm4", .data = &imx_rproc_cfg_imx8mq },
> --
> 2.7.4
>
On Thu, Apr 15, 2021 at 09:27:33PM +0800, [email protected] wrote:
> From: Peng Fan <[email protected]>
>
> V4:
> Typo fix
> patch 4: take state as a check condition
> patch 5: move regmap lookup/attach to imx_rproc_detect_mode
> patch 6: add imx_rproc_clk_enable for optional clk
> patch 8: use switch/case in imx_rproc_detect_mode
> V3:
> Add A-b tag for Patch 1/2
> Fix the checkpatch warning for Patch 6,8
>
> V2:
> Patch 1/8, use fsl as vendor, typo fix
> Because patchset [1] has v2 version, patch 5,6,7,8 are adapted that
> change.
>
> This patchset is to support i.MX7ULP/8MN/8MP, also includes a patch to
> parse fsl,auto-boot
>
Always specify what branch your work applies on and dependencies for it. If
this was ready to go Bjorn would have a fun time figuring out it depends on your
other set[1].
I am done reviewing this pathset.
Mathieu
[1] [PATCH V3 0/8] remoteproc: imx_rproc: support i.MX7ULP/8MN/8MP
>
> Peng Fan (8):
> dt-bindings: remoteproc: imx_rproc: add fsl,auto-boot property
> dt-bindings: remoteproc: imx_rproc: add i.MX7ULP support
> dt-bindings: remoteproc: imx_rproc: support i.MX8MN/P
> remoteproc: imx_rproc: parse fsl,auto-boot
> remoteproc: imx_rproc: initial support for mutilple start/stop method
> remoteproc: imx_rproc: make clk optional
> remoteproc: imx_rproc: support i.MX7ULP
> remoteproc: imx_rproc: support i.MX8MN/P
>
> .../bindings/remoteproc/fsl,imx-rproc.yaml | 11 +-
> drivers/remoteproc/imx_rproc.c | 206 +++++++++++++++++----
> 2 files changed, 179 insertions(+), 38 deletions(-)
>
> --
> 2.7.4
>