All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/6] remoteproc: Add driver for STMicroelectronics platforms
@ 2015-09-02 15:38 ` Lee Jones
  0 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: kernel, ohad, devicetree, Nathan_Lynch, f.fainelli, Lee Jones

ST's platforms often have multiple co-processors (usually ST40s or ST231s)
on-board.  This provides the Linux-side infrastructure to flash and boot
them successfully.
  
This set has been tested on an STiH410-B2120.
  
v2 => v3:
 - Generify syscon property (st,syscfg-boot => st,syscfg-boot)
 - Rename IP in DT bindings doc (Remote Processor => Co-Processor)
 - Remove superfluous 'clock-names' property
 - Remove superfluous 'reg-names' property
 - Populate MAINTAINERS
 - Clean-up DTS formatting
 - Use strings in debugfs to control procs ('1|0' => 'start|stop')
 - Align copyright statement with MODULE() macros
 - Rename driver data structure ('st_rproc' => 'ddata')
 - Addition of a full error path in .start()

v1 => v2:
 - Remove Linux implementation specific comment from binding document
 - Force debugfs '0' to shutdown co-processor - rather than !1
 - Supply more detailed commit message
 - Propagate errors back from .stop()
 - Review GPL wording
 - Supply original author's SoBs
  
Lee Jones (4):
  ARM: STiH407: Add nodes for RemoteProc
  remoteproc: dt: Provide bindings for ST's Remote Processor Controller
    driver
  remoteproc: Supply controller driver for ST's Remote Processors
  remoteproc: debugfs: Add ability to boot remote processor using
    debugfs

Lee Jones (6):
  ARM: STi: Add DT defines for co-processor reset lines
  remoteproc: dt: Provide bindings for ST's Remote Processor Controller
    driver
  remoteproc: Supply controller driver for ST's Remote Processors
  remoteproc: debugfs: Add ability to boot remote processor using
    debugfs
  ARM: STiH407: Add nodes for RemoteProc
  MAINTAINERS: Add ST's Remote Processor Driver to ARM/STI ARCHITECTURE

 .../devicetree/bindings/remoteproc/st-rproc.txt    |  35 +++
 MAINTAINERS                                        |   1 +
 arch/arm/boot/dts/stih407-family.dtsi              |  40 +++
 drivers/remoteproc/Kconfig                         |   9 +
 drivers/remoteproc/Makefile                        |   1 +
 drivers/remoteproc/remoteproc_debugfs.c            |  34 +++
 drivers/remoteproc/st_remoteproc.c                 | 307 +++++++++++++++++++++
 .../dt-bindings/reset-controller/stih407-resets.h  |   4 +
 8 files changed, 431 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/st-rproc.txt
 create mode 100644 drivers/remoteproc/st_remoteproc.c

-- 
1.9.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v3 0/6] remoteproc: Add driver for STMicroelectronics platforms
@ 2015-09-02 15:38 ` Lee Jones
  0 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: ohad, devicetree, f.fainelli, kernel, Nathan_Lynch, Lee Jones

ST's platforms often have multiple co-processors (usually ST40s or ST231s)
on-board.  This provides the Linux-side infrastructure to flash and boot
them successfully.
  
This set has been tested on an STiH410-B2120.
  
v2 => v3:
 - Generify syscon property (st,syscfg-boot => st,syscfg-boot)
 - Rename IP in DT bindings doc (Remote Processor => Co-Processor)
 - Remove superfluous 'clock-names' property
 - Remove superfluous 'reg-names' property
 - Populate MAINTAINERS
 - Clean-up DTS formatting
 - Use strings in debugfs to control procs ('1|0' => 'start|stop')
 - Align copyright statement with MODULE() macros
 - Rename driver data structure ('st_rproc' => 'ddata')
 - Addition of a full error path in .start()

v1 => v2:
 - Remove Linux implementation specific comment from binding document
 - Force debugfs '0' to shutdown co-processor - rather than !1
 - Supply more detailed commit message
 - Propagate errors back from .stop()
 - Review GPL wording
 - Supply original author's SoBs
  
Lee Jones (4):
  ARM: STiH407: Add nodes for RemoteProc
  remoteproc: dt: Provide bindings for ST's Remote Processor Controller
    driver
  remoteproc: Supply controller driver for ST's Remote Processors
  remoteproc: debugfs: Add ability to boot remote processor using
    debugfs

Lee Jones (6):
  ARM: STi: Add DT defines for co-processor reset lines
  remoteproc: dt: Provide bindings for ST's Remote Processor Controller
    driver
  remoteproc: Supply controller driver for ST's Remote Processors
  remoteproc: debugfs: Add ability to boot remote processor using
    debugfs
  ARM: STiH407: Add nodes for RemoteProc
  MAINTAINERS: Add ST's Remote Processor Driver to ARM/STI ARCHITECTURE

 .../devicetree/bindings/remoteproc/st-rproc.txt    |  35 +++
 MAINTAINERS                                        |   1 +
 arch/arm/boot/dts/stih407-family.dtsi              |  40 +++
 drivers/remoteproc/Kconfig                         |   9 +
 drivers/remoteproc/Makefile                        |   1 +
 drivers/remoteproc/remoteproc_debugfs.c            |  34 +++
 drivers/remoteproc/st_remoteproc.c                 | 307 +++++++++++++++++++++
 .../dt-bindings/reset-controller/stih407-resets.h  |   4 +
 8 files changed, 431 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/st-rproc.txt
 create mode 100644 drivers/remoteproc/st_remoteproc.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v3 0/6] remoteproc: Add driver for STMicroelectronics platforms
@ 2015-09-02 15:38 ` Lee Jones
  0 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel

ST's platforms often have multiple co-processors (usually ST40s or ST231s)
on-board.  This provides the Linux-side infrastructure to flash and boot
them successfully.
  
This set has been tested on an STiH410-B2120.
  
v2 => v3:
 - Generify syscon property (st,syscfg-boot => st,syscfg-boot)
 - Rename IP in DT bindings doc (Remote Processor => Co-Processor)
 - Remove superfluous 'clock-names' property
 - Remove superfluous 'reg-names' property
 - Populate MAINTAINERS
 - Clean-up DTS formatting
 - Use strings in debugfs to control procs ('1|0' => 'start|stop')
 - Align copyright statement with MODULE() macros
 - Rename driver data structure ('st_rproc' => 'ddata')
 - Addition of a full error path in .start()

v1 => v2:
 - Remove Linux implementation specific comment from binding document
 - Force debugfs '0' to shutdown co-processor - rather than !1
 - Supply more detailed commit message
 - Propagate errors back from .stop()
 - Review GPL wording
 - Supply original author's SoBs
  
Lee Jones (4):
  ARM: STiH407: Add nodes for RemoteProc
  remoteproc: dt: Provide bindings for ST's Remote Processor Controller
    driver
  remoteproc: Supply controller driver for ST's Remote Processors
  remoteproc: debugfs: Add ability to boot remote processor using
    debugfs

Lee Jones (6):
  ARM: STi: Add DT defines for co-processor reset lines
  remoteproc: dt: Provide bindings for ST's Remote Processor Controller
    driver
  remoteproc: Supply controller driver for ST's Remote Processors
  remoteproc: debugfs: Add ability to boot remote processor using
    debugfs
  ARM: STiH407: Add nodes for RemoteProc
  MAINTAINERS: Add ST's Remote Processor Driver to ARM/STI ARCHITECTURE

 .../devicetree/bindings/remoteproc/st-rproc.txt    |  35 +++
 MAINTAINERS                                        |   1 +
 arch/arm/boot/dts/stih407-family.dtsi              |  40 +++
 drivers/remoteproc/Kconfig                         |   9 +
 drivers/remoteproc/Makefile                        |   1 +
 drivers/remoteproc/remoteproc_debugfs.c            |  34 +++
 drivers/remoteproc/st_remoteproc.c                 | 307 +++++++++++++++++++++
 .../dt-bindings/reset-controller/stih407-resets.h  |   4 +
 8 files changed, 431 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/st-rproc.txt
 create mode 100644 drivers/remoteproc/st_remoteproc.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v3 1/6] ARM: STi: Add DT defines for co-processor reset lines
  2015-09-02 15:38 ` Lee Jones
@ 2015-09-02 15:38   ` Lee Jones
  -1 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: kernel, ohad, devicetree, Nathan_Lynch, f.fainelli, Lee Jones

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 include/dt-bindings/reset-controller/stih407-resets.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/dt-bindings/reset-controller/stih407-resets.h b/include/dt-bindings/reset-controller/stih407-resets.h
index 02d4328..4ab3a1c 100644
--- a/include/dt-bindings/reset-controller/stih407-resets.h
+++ b/include/dt-bindings/reset-controller/stih407-resets.h
@@ -52,6 +52,10 @@
 #define STIH407_KEYSCAN_SOFTRESET	26
 #define STIH407_USB2_PORT0_SOFTRESET	27
 #define STIH407_USB2_PORT1_SOFTRESET	28
+#define STIH407_ST231_AUD_SOFTRESET	29
+#define STIH407_ST231_DMU_SOFTRESET	30
+#define STIH407_ST231_GP0_SOFTRESET	31
+#define STIH407_ST231_GP1_SOFTRESET	32
 
 /* Picophy reset defines */
 #define STIH407_PICOPHY0_RESET		0
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 1/6] ARM: STi: Add DT defines for co-processor reset lines
@ 2015-09-02 15:38   ` Lee Jones
  0 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 include/dt-bindings/reset-controller/stih407-resets.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/dt-bindings/reset-controller/stih407-resets.h b/include/dt-bindings/reset-controller/stih407-resets.h
index 02d4328..4ab3a1c 100644
--- a/include/dt-bindings/reset-controller/stih407-resets.h
+++ b/include/dt-bindings/reset-controller/stih407-resets.h
@@ -52,6 +52,10 @@
 #define STIH407_KEYSCAN_SOFTRESET	26
 #define STIH407_USB2_PORT0_SOFTRESET	27
 #define STIH407_USB2_PORT1_SOFTRESET	28
+#define STIH407_ST231_AUD_SOFTRESET	29
+#define STIH407_ST231_DMU_SOFTRESET	30
+#define STIH407_ST231_GP0_SOFTRESET	31
+#define STIH407_ST231_GP1_SOFTRESET	32
 
 /* Picophy reset defines */
 #define STIH407_PICOPHY0_RESET		0
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 2/6] remoteproc: dt: Provide bindings for ST's Remote Processor Controller driver
  2015-09-02 15:38 ` Lee Jones
@ 2015-09-02 15:38   ` Lee Jones
  -1 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: kernel, ohad, devicetree, Nathan_Lynch, f.fainelli, Lee Jones,
	Ludovic Barre

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 .../devicetree/bindings/remoteproc/st-rproc.txt    | 35 ++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/st-rproc.txt

diff --git a/Documentation/devicetree/bindings/remoteproc/st-rproc.txt b/Documentation/devicetree/bindings/remoteproc/st-rproc.txt
new file mode 100644
index 0000000..c3848f6
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/st-rproc.txt
@@ -0,0 +1,35 @@
+STMicroelectronics Co-Processor Bindings
+----------------------------------------
+
+This binding provides support for adjunct processors found on ST SoCs.
+
+Co-processors can be controlled from the bootloader or the primary OS. If
+the bootloader starts a co-processor, the primary OS must detect its state
+and act accordingly.
+
+Required properties:
+- compatible		Should be one of:
+				"st,st231-rproc"
+				"st,st40-rproc"
+- reg			Size and length of reserved co-processor memory
+- resets		Reset lines (See: ../reset/reset.txt)
+- reset-names		Must be "sw_reset" and "pwr_reset"
+- clocks		Clock for co-processor (See: ../clock/clock-bindings.txt)
+- clock-frequency	Clock frequency to set co-processor at if the bootloader
+			hasn't already done so
+- st,syscfg		System configuration register which holds the boot vector
+			for the co-processor
+				1st cell: Phandle to syscon block
+				2nd cell: Boot vector register offset
+
+Example:
+
+	st231-audio@bae00000 {
+		compatible	= "st,st231-rproc";
+		reg		= <0xbae00000 0x01000000>;
+		resets		= <&softreset STIH407_ST231_AUD_SOFTRESET>;
+		reset-names	= "sw_reset";
+		clocks		= <&clk_s_c0_flexgen CLK_ST231_AUD_0>;
+		clock-frequency	= <600000000>;
+		st,syscfg	= <&syscfg_core 0x228>;
+	};
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 2/6] remoteproc: dt: Provide bindings for ST's Remote Processor Controller driver
@ 2015-09-02 15:38   ` Lee Jones
  0 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 .../devicetree/bindings/remoteproc/st-rproc.txt    | 35 ++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/st-rproc.txt

diff --git a/Documentation/devicetree/bindings/remoteproc/st-rproc.txt b/Documentation/devicetree/bindings/remoteproc/st-rproc.txt
new file mode 100644
index 0000000..c3848f6
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/st-rproc.txt
@@ -0,0 +1,35 @@
+STMicroelectronics Co-Processor Bindings
+----------------------------------------
+
+This binding provides support for adjunct processors found on ST SoCs.
+
+Co-processors can be controlled from the bootloader or the primary OS. If
+the bootloader starts a co-processor, the primary OS must detect its state
+and act accordingly.
+
+Required properties:
+- compatible		Should be one of:
+				"st,st231-rproc"
+				"st,st40-rproc"
+- reg			Size and length of reserved co-processor memory
+- resets		Reset lines (See: ../reset/reset.txt)
+- reset-names		Must be "sw_reset" and "pwr_reset"
+- clocks		Clock for co-processor (See: ../clock/clock-bindings.txt)
+- clock-frequency	Clock frequency to set co-processor at if the bootloader
+			hasn't already done so
+- st,syscfg		System configuration register which holds the boot vector
+			for the co-processor
+				1st cell: Phandle to syscon block
+				2nd cell: Boot vector register offset
+
+Example:
+
+	st231-audio at bae00000 {
+		compatible	= "st,st231-rproc";
+		reg		= <0xbae00000 0x01000000>;
+		resets		= <&softreset STIH407_ST231_AUD_SOFTRESET>;
+		reset-names	= "sw_reset";
+		clocks		= <&clk_s_c0_flexgen CLK_ST231_AUD_0>;
+		clock-frequency	= <600000000>;
+		st,syscfg	= <&syscfg_core 0x228>;
+	};
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 3/6] remoteproc: Supply controller driver for ST's Remote Processors
  2015-09-02 15:38 ` Lee Jones
  (?)
@ 2015-09-02 15:38   ` Lee Jones
  -1 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: kernel, ohad, devicetree, Nathan_Lynch, f.fainelli, Lee Jones,
	Ludovic Barre

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/remoteproc/Kconfig         |   9 ++
 drivers/remoteproc/Makefile        |   1 +
 drivers/remoteproc/st_remoteproc.c | 307 +++++++++++++++++++++++++++++++++++++
 3 files changed, 317 insertions(+)
 create mode 100644 drivers/remoteproc/st_remoteproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 28c711f..72e97d7 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -77,4 +77,13 @@ config DA8XX_REMOTEPROC
 	  It's safe to say n here if you're not interested in multimedia
 	  offloading.
 
+config ST_REMOTEPROC
+	tristate "ST remoteproc support"
+	depends on ARCH_STI
+	select REMOTEPROC
+	help
+	  Say y here to support ST's adjunct processors via the remote
+	  processor framework.
+	  This can be either built-in or a loadable module.
+
 endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 81b04d1..279cb2e 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_OMAP_REMOTEPROC)		+= omap_remoteproc.o
 obj-$(CONFIG_STE_MODEM_RPROC)	 	+= ste_modem_rproc.o
 obj-$(CONFIG_WKUP_M3_RPROC)		+= wkup_m3_rproc.o
 obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
+obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c
new file mode 100644
index 0000000..24ae6d3
--- /dev/null
+++ b/drivers/remoteproc/st_remoteproc.c
@@ -0,0 +1,307 @@
+/*
+ * ST's Remote Processor Control Driver
+ *
+ * Copyright (C) 2015 STMicroelectronics - All Rights Reserved
+ *
+ * Author: Ludovic Barre <ludovic.barre@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/remoteproc.h>
+#include <linux/reset.h>
+
+struct st_rproc_config {
+	bool			sw_reset;
+	bool			pwr_reset;
+	u32			bootaddr_mask;
+};
+
+struct st_rproc {
+	struct st_rproc_config	*config;
+	struct reset_control	*sw_reset;
+	struct reset_control	*pwr_reset;
+	struct clk		*clk;
+	u32			clk_rate;
+	struct regmap		*boot_base;
+	u32			boot_offset;
+};
+
+static int st_rproc_stop(struct rproc *rproc)
+{
+	struct st_rproc *ddata = rproc->priv;
+	int sw_err = 0, pwr_err = 0;
+
+	if (ddata->config->sw_reset) {
+		sw_err = reset_control_assert(ddata->sw_reset);
+		if (sw_err)
+			dev_err(&rproc->dev, "Failed to assert S/W Reset\n");
+	}
+
+	if (ddata->config->pwr_reset) {
+		pwr_err = reset_control_assert(ddata->pwr_reset);
+		if (pwr_err)
+			dev_err(&rproc->dev, "Failed to assert Power Reset\n");
+	}
+
+	clk_disable(ddata->clk);
+
+	return sw_err ?: pwr_err;
+}
+
+static int st_rproc_start(struct rproc *rproc)
+{
+	struct st_rproc *ddata = rproc->priv;
+	int err;
+
+	regmap_update_bits(ddata->boot_base, ddata->boot_offset,
+			   ddata->config->bootaddr_mask, rproc->bootaddr);
+
+	err = clk_enable(ddata->clk);
+	if (err) {
+		dev_err(&rproc->dev, "Failed to enable clock\n");
+		return err;
+	}
+
+	if (ddata->config->sw_reset) {
+		err = reset_control_deassert(ddata->sw_reset);
+		if (err) {
+			dev_err(&rproc->dev, "Failed to deassert S/W Reset\n");
+			goto sw_reset_fail;
+		}
+	}
+
+	if (ddata->config->pwr_reset) {
+		err = reset_control_deassert(ddata->pwr_reset);
+		if (err) {
+			dev_err(&rproc->dev, "Failed to deassert Power Reset\n");
+			goto pwr_reset_fail;
+		}
+	}
+
+	dev_info(&rproc->dev, "Started from 0x%x\n", rproc->bootaddr);
+
+	return 0;
+
+
+pwr_reset_fail:
+	reset_control_assert(ddata->sw_reset);
+sw_reset_fail:
+	clk_disable(ddata->clk);
+
+	return err;
+}
+
+static struct rproc_ops st_rproc_ops = {
+	.start		= st_rproc_start,
+	.stop		= st_rproc_stop,
+};
+
+/*
+ * Fetch state of the processor: 0 is off, 1 is on.
+ */
+static int st_rproc_state(struct platform_device *pdev)
+{
+	struct rproc *rproc = platform_get_drvdata(pdev);
+	struct st_rproc *ddata = rproc->priv;
+	int reset_sw = 0, reset_pwr = 0;
+
+	if (ddata->config->sw_reset)
+		reset_sw = reset_control_status(ddata->sw_reset);
+
+	if (ddata->config->pwr_reset)
+		reset_pwr = reset_control_status(ddata->pwr_reset);
+
+	if (reset_sw < 0 || reset_pwr < 0)
+		return -EINVAL;
+
+	return !reset_sw && !reset_pwr;
+}
+
+static const struct st_rproc_config st40_rproc_cfg = {
+	.sw_reset = true,
+	.pwr_reset = true,
+	.bootaddr_mask = GENMASK(28, 1),
+};
+
+static const struct st_rproc_config st231_rproc_cfg = {
+	.sw_reset = true,
+	.pwr_reset = false,
+	.bootaddr_mask = GENMASK(31, 6),
+};
+
+static const struct of_device_id st_rproc_match[] = {
+	{ .compatible = "st,st40-rproc", .data = &st40_rproc_cfg },
+	{ .compatible = "st,st231-rproc", .data = &st231_rproc_cfg },
+	{},
+};
+MODULE_DEVICE_TABLE(of, st_rproc_match);
+
+static int st_rproc_parse_dt(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rproc *rproc = platform_get_drvdata(pdev);
+	struct st_rproc *ddata = rproc->priv;
+	struct device_node *np = dev->of_node;
+	struct resource	*mem;
+	int err;
+
+	if (ddata->config->sw_reset) {
+		ddata->sw_reset = devm_reset_control_get(dev, "sw_reset");
+		if (IS_ERR(ddata->sw_reset)) {
+			dev_err(dev, "Failed to get S/W Reset\n");
+			return PTR_ERR(ddata->sw_reset);
+		}
+	}
+
+	if (ddata->config->pwr_reset) {
+		ddata->pwr_reset = devm_reset_control_get(dev, "pwr_reset");
+		if (IS_ERR(ddata->pwr_reset)) {
+			dev_err(dev, "Failed to get Power Reset\n");
+			return PTR_ERR(ddata->pwr_reset);
+		}
+	}
+
+	ddata->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(ddata->clk)) {
+		dev_err(dev, "Failed to get clock\n");
+		return PTR_ERR(ddata->clk);
+	}
+
+	err = of_property_read_u32(np, "clock-frequency", &ddata->clk_rate);
+	if (err) {
+		dev_err(dev, "failed to get clock frequency\n");
+		return err;
+	}
+
+	ddata->boot_base = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
+	if (!ddata->boot_base) {
+		dev_err(dev, "Boot base not found\n");
+		return -EINVAL;
+	}
+
+	err = of_property_read_u32_index(np, "st,syscfg", 1,
+					 &ddata->boot_offset);
+	if (err) {
+		dev_err(dev, "Boot offset not found\n");
+		return -EINVAL;
+	}
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		dev_err(dev, "no rproc memory definition\n");
+		return -ENXIO;
+	}
+
+	if (!devm_request_mem_region(dev, mem->start,
+				     resource_size(mem), pdev->name)) {
+		dev_err(dev, "failed to get memory region resource\n");
+		return -EBUSY;
+	}
+	err = dmam_declare_coherent_memory(dev, mem->start, mem->start,
+					  resource_size(mem),
+					  DMA_MEMORY_MAP |
+					  DMA_MEMORY_EXCLUSIVE);
+	if (err < 0) {
+		dev_err(dev, "cannot declare coherent memory: %d\n", err);
+		return -ENXIO;
+	}
+
+	err = clk_prepare(ddata->clk);
+	if (err)
+		dev_err(dev, "failed to get clock\n");
+
+	return err;
+}
+
+static int st_rproc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	const struct of_device_id *match;
+	struct st_rproc *ddata;
+	struct device_node *np = dev->of_node;
+	struct rproc *rproc;
+	int enabled;
+	int ret;
+
+	match = of_match_device((st_rproc_match), dev);
+	if (!match || !match->data) {
+		dev_err(dev, "No device match found\n");
+		return -ENODEV;
+	}
+
+	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
+	if (!rproc)
+		return -ENOMEM;
+
+	ddata = rproc->priv;
+	ddata->config = (struct st_rproc_config *)match->data;
+
+	platform_set_drvdata(pdev, rproc);
+
+	ret = st_rproc_parse_dt(pdev);
+	if (ret)
+		goto free_rproc;
+
+	enabled = st_rproc_state(pdev);
+	if (enabled < 0)
+		goto free_rproc;
+
+	if (enabled) {
+		atomic_inc(&rproc->power);
+		rproc->state = RPROC_RUNNING;
+	} else {
+		clk_set_rate(ddata->clk, ddata->clk_rate);
+	}
+
+	ret = rproc_add(rproc);
+	if (ret)
+		goto free_rproc;
+
+	return 0;
+
+free_rproc:
+	rproc_put(rproc);
+	return ret;
+}
+
+static int st_rproc_remove(struct platform_device *pdev)
+{
+	struct rproc *rproc = platform_get_drvdata(pdev);
+	struct st_rproc *ddata = rproc->priv;
+
+	rproc_del(rproc);
+
+	clk_disable_unprepare(ddata->clk);
+
+	rproc_put(rproc);
+
+	return 0;
+}
+
+static struct platform_driver st_rproc_driver = {
+	.probe = st_rproc_probe,
+	.remove = st_rproc_remove,
+	.driver = {
+		.name = "st-rproc",
+		.of_match_table = of_match_ptr(st_rproc_match),
+	},
+};
+module_platform_driver(st_rproc_driver);
+
+MODULE_DESCRIPTION("ST Remote Processor Control Driver");
+MODULE_AUTHOR("Ludovic Barre <ludovic.barre@st.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 3/6] remoteproc: Supply controller driver for ST's Remote Processors
@ 2015-09-02 15:38   ` Lee Jones
  0 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: ohad, devicetree, f.fainelli, kernel, Nathan_Lynch, Lee Jones,
	Ludovic Barre

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/remoteproc/Kconfig         |   9 ++
 drivers/remoteproc/Makefile        |   1 +
 drivers/remoteproc/st_remoteproc.c | 307 +++++++++++++++++++++++++++++++++++++
 3 files changed, 317 insertions(+)
 create mode 100644 drivers/remoteproc/st_remoteproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 28c711f..72e97d7 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -77,4 +77,13 @@ config DA8XX_REMOTEPROC
 	  It's safe to say n here if you're not interested in multimedia
 	  offloading.
 
+config ST_REMOTEPROC
+	tristate "ST remoteproc support"
+	depends on ARCH_STI
+	select REMOTEPROC
+	help
+	  Say y here to support ST's adjunct processors via the remote
+	  processor framework.
+	  This can be either built-in or a loadable module.
+
 endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 81b04d1..279cb2e 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_OMAP_REMOTEPROC)		+= omap_remoteproc.o
 obj-$(CONFIG_STE_MODEM_RPROC)	 	+= ste_modem_rproc.o
 obj-$(CONFIG_WKUP_M3_RPROC)		+= wkup_m3_rproc.o
 obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
+obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c
new file mode 100644
index 0000000..24ae6d3
--- /dev/null
+++ b/drivers/remoteproc/st_remoteproc.c
@@ -0,0 +1,307 @@
+/*
+ * ST's Remote Processor Control Driver
+ *
+ * Copyright (C) 2015 STMicroelectronics - All Rights Reserved
+ *
+ * Author: Ludovic Barre <ludovic.barre@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/remoteproc.h>
+#include <linux/reset.h>
+
+struct st_rproc_config {
+	bool			sw_reset;
+	bool			pwr_reset;
+	u32			bootaddr_mask;
+};
+
+struct st_rproc {
+	struct st_rproc_config	*config;
+	struct reset_control	*sw_reset;
+	struct reset_control	*pwr_reset;
+	struct clk		*clk;
+	u32			clk_rate;
+	struct regmap		*boot_base;
+	u32			boot_offset;
+};
+
+static int st_rproc_stop(struct rproc *rproc)
+{
+	struct st_rproc *ddata = rproc->priv;
+	int sw_err = 0, pwr_err = 0;
+
+	if (ddata->config->sw_reset) {
+		sw_err = reset_control_assert(ddata->sw_reset);
+		if (sw_err)
+			dev_err(&rproc->dev, "Failed to assert S/W Reset\n");
+	}
+
+	if (ddata->config->pwr_reset) {
+		pwr_err = reset_control_assert(ddata->pwr_reset);
+		if (pwr_err)
+			dev_err(&rproc->dev, "Failed to assert Power Reset\n");
+	}
+
+	clk_disable(ddata->clk);
+
+	return sw_err ?: pwr_err;
+}
+
+static int st_rproc_start(struct rproc *rproc)
+{
+	struct st_rproc *ddata = rproc->priv;
+	int err;
+
+	regmap_update_bits(ddata->boot_base, ddata->boot_offset,
+			   ddata->config->bootaddr_mask, rproc->bootaddr);
+
+	err = clk_enable(ddata->clk);
+	if (err) {
+		dev_err(&rproc->dev, "Failed to enable clock\n");
+		return err;
+	}
+
+	if (ddata->config->sw_reset) {
+		err = reset_control_deassert(ddata->sw_reset);
+		if (err) {
+			dev_err(&rproc->dev, "Failed to deassert S/W Reset\n");
+			goto sw_reset_fail;
+		}
+	}
+
+	if (ddata->config->pwr_reset) {
+		err = reset_control_deassert(ddata->pwr_reset);
+		if (err) {
+			dev_err(&rproc->dev, "Failed to deassert Power Reset\n");
+			goto pwr_reset_fail;
+		}
+	}
+
+	dev_info(&rproc->dev, "Started from 0x%x\n", rproc->bootaddr);
+
+	return 0;
+
+
+pwr_reset_fail:
+	reset_control_assert(ddata->sw_reset);
+sw_reset_fail:
+	clk_disable(ddata->clk);
+
+	return err;
+}
+
+static struct rproc_ops st_rproc_ops = {
+	.start		= st_rproc_start,
+	.stop		= st_rproc_stop,
+};
+
+/*
+ * Fetch state of the processor: 0 is off, 1 is on.
+ */
+static int st_rproc_state(struct platform_device *pdev)
+{
+	struct rproc *rproc = platform_get_drvdata(pdev);
+	struct st_rproc *ddata = rproc->priv;
+	int reset_sw = 0, reset_pwr = 0;
+
+	if (ddata->config->sw_reset)
+		reset_sw = reset_control_status(ddata->sw_reset);
+
+	if (ddata->config->pwr_reset)
+		reset_pwr = reset_control_status(ddata->pwr_reset);
+
+	if (reset_sw < 0 || reset_pwr < 0)
+		return -EINVAL;
+
+	return !reset_sw && !reset_pwr;
+}
+
+static const struct st_rproc_config st40_rproc_cfg = {
+	.sw_reset = true,
+	.pwr_reset = true,
+	.bootaddr_mask = GENMASK(28, 1),
+};
+
+static const struct st_rproc_config st231_rproc_cfg = {
+	.sw_reset = true,
+	.pwr_reset = false,
+	.bootaddr_mask = GENMASK(31, 6),
+};
+
+static const struct of_device_id st_rproc_match[] = {
+	{ .compatible = "st,st40-rproc", .data = &st40_rproc_cfg },
+	{ .compatible = "st,st231-rproc", .data = &st231_rproc_cfg },
+	{},
+};
+MODULE_DEVICE_TABLE(of, st_rproc_match);
+
+static int st_rproc_parse_dt(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rproc *rproc = platform_get_drvdata(pdev);
+	struct st_rproc *ddata = rproc->priv;
+	struct device_node *np = dev->of_node;
+	struct resource	*mem;
+	int err;
+
+	if (ddata->config->sw_reset) {
+		ddata->sw_reset = devm_reset_control_get(dev, "sw_reset");
+		if (IS_ERR(ddata->sw_reset)) {
+			dev_err(dev, "Failed to get S/W Reset\n");
+			return PTR_ERR(ddata->sw_reset);
+		}
+	}
+
+	if (ddata->config->pwr_reset) {
+		ddata->pwr_reset = devm_reset_control_get(dev, "pwr_reset");
+		if (IS_ERR(ddata->pwr_reset)) {
+			dev_err(dev, "Failed to get Power Reset\n");
+			return PTR_ERR(ddata->pwr_reset);
+		}
+	}
+
+	ddata->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(ddata->clk)) {
+		dev_err(dev, "Failed to get clock\n");
+		return PTR_ERR(ddata->clk);
+	}
+
+	err = of_property_read_u32(np, "clock-frequency", &ddata->clk_rate);
+	if (err) {
+		dev_err(dev, "failed to get clock frequency\n");
+		return err;
+	}
+
+	ddata->boot_base = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
+	if (!ddata->boot_base) {
+		dev_err(dev, "Boot base not found\n");
+		return -EINVAL;
+	}
+
+	err = of_property_read_u32_index(np, "st,syscfg", 1,
+					 &ddata->boot_offset);
+	if (err) {
+		dev_err(dev, "Boot offset not found\n");
+		return -EINVAL;
+	}
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		dev_err(dev, "no rproc memory definition\n");
+		return -ENXIO;
+	}
+
+	if (!devm_request_mem_region(dev, mem->start,
+				     resource_size(mem), pdev->name)) {
+		dev_err(dev, "failed to get memory region resource\n");
+		return -EBUSY;
+	}
+	err = dmam_declare_coherent_memory(dev, mem->start, mem->start,
+					  resource_size(mem),
+					  DMA_MEMORY_MAP |
+					  DMA_MEMORY_EXCLUSIVE);
+	if (err < 0) {
+		dev_err(dev, "cannot declare coherent memory: %d\n", err);
+		return -ENXIO;
+	}
+
+	err = clk_prepare(ddata->clk);
+	if (err)
+		dev_err(dev, "failed to get clock\n");
+
+	return err;
+}
+
+static int st_rproc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	const struct of_device_id *match;
+	struct st_rproc *ddata;
+	struct device_node *np = dev->of_node;
+	struct rproc *rproc;
+	int enabled;
+	int ret;
+
+	match = of_match_device((st_rproc_match), dev);
+	if (!match || !match->data) {
+		dev_err(dev, "No device match found\n");
+		return -ENODEV;
+	}
+
+	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
+	if (!rproc)
+		return -ENOMEM;
+
+	ddata = rproc->priv;
+	ddata->config = (struct st_rproc_config *)match->data;
+
+	platform_set_drvdata(pdev, rproc);
+
+	ret = st_rproc_parse_dt(pdev);
+	if (ret)
+		goto free_rproc;
+
+	enabled = st_rproc_state(pdev);
+	if (enabled < 0)
+		goto free_rproc;
+
+	if (enabled) {
+		atomic_inc(&rproc->power);
+		rproc->state = RPROC_RUNNING;
+	} else {
+		clk_set_rate(ddata->clk, ddata->clk_rate);
+	}
+
+	ret = rproc_add(rproc);
+	if (ret)
+		goto free_rproc;
+
+	return 0;
+
+free_rproc:
+	rproc_put(rproc);
+	return ret;
+}
+
+static int st_rproc_remove(struct platform_device *pdev)
+{
+	struct rproc *rproc = platform_get_drvdata(pdev);
+	struct st_rproc *ddata = rproc->priv;
+
+	rproc_del(rproc);
+
+	clk_disable_unprepare(ddata->clk);
+
+	rproc_put(rproc);
+
+	return 0;
+}
+
+static struct platform_driver st_rproc_driver = {
+	.probe = st_rproc_probe,
+	.remove = st_rproc_remove,
+	.driver = {
+		.name = "st-rproc",
+		.of_match_table = of_match_ptr(st_rproc_match),
+	},
+};
+module_platform_driver(st_rproc_driver);
+
+MODULE_DESCRIPTION("ST Remote Processor Control Driver");
+MODULE_AUTHOR("Ludovic Barre <ludovic.barre@st.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 3/6] remoteproc: Supply controller driver for ST's Remote Processors
@ 2015-09-02 15:38   ` Lee Jones
  0 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/remoteproc/Kconfig         |   9 ++
 drivers/remoteproc/Makefile        |   1 +
 drivers/remoteproc/st_remoteproc.c | 307 +++++++++++++++++++++++++++++++++++++
 3 files changed, 317 insertions(+)
 create mode 100644 drivers/remoteproc/st_remoteproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 28c711f..72e97d7 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -77,4 +77,13 @@ config DA8XX_REMOTEPROC
 	  It's safe to say n here if you're not interested in multimedia
 	  offloading.
 
+config ST_REMOTEPROC
+	tristate "ST remoteproc support"
+	depends on ARCH_STI
+	select REMOTEPROC
+	help
+	  Say y here to support ST's adjunct processors via the remote
+	  processor framework.
+	  This can be either built-in or a loadable module.
+
 endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 81b04d1..279cb2e 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_OMAP_REMOTEPROC)		+= omap_remoteproc.o
 obj-$(CONFIG_STE_MODEM_RPROC)	 	+= ste_modem_rproc.o
 obj-$(CONFIG_WKUP_M3_RPROC)		+= wkup_m3_rproc.o
 obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
+obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c
new file mode 100644
index 0000000..24ae6d3
--- /dev/null
+++ b/drivers/remoteproc/st_remoteproc.c
@@ -0,0 +1,307 @@
+/*
+ * ST's Remote Processor Control Driver
+ *
+ * Copyright (C) 2015 STMicroelectronics - All Rights Reserved
+ *
+ * Author: Ludovic Barre <ludovic.barre@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/remoteproc.h>
+#include <linux/reset.h>
+
+struct st_rproc_config {
+	bool			sw_reset;
+	bool			pwr_reset;
+	u32			bootaddr_mask;
+};
+
+struct st_rproc {
+	struct st_rproc_config	*config;
+	struct reset_control	*sw_reset;
+	struct reset_control	*pwr_reset;
+	struct clk		*clk;
+	u32			clk_rate;
+	struct regmap		*boot_base;
+	u32			boot_offset;
+};
+
+static int st_rproc_stop(struct rproc *rproc)
+{
+	struct st_rproc *ddata = rproc->priv;
+	int sw_err = 0, pwr_err = 0;
+
+	if (ddata->config->sw_reset) {
+		sw_err = reset_control_assert(ddata->sw_reset);
+		if (sw_err)
+			dev_err(&rproc->dev, "Failed to assert S/W Reset\n");
+	}
+
+	if (ddata->config->pwr_reset) {
+		pwr_err = reset_control_assert(ddata->pwr_reset);
+		if (pwr_err)
+			dev_err(&rproc->dev, "Failed to assert Power Reset\n");
+	}
+
+	clk_disable(ddata->clk);
+
+	return sw_err ?: pwr_err;
+}
+
+static int st_rproc_start(struct rproc *rproc)
+{
+	struct st_rproc *ddata = rproc->priv;
+	int err;
+
+	regmap_update_bits(ddata->boot_base, ddata->boot_offset,
+			   ddata->config->bootaddr_mask, rproc->bootaddr);
+
+	err = clk_enable(ddata->clk);
+	if (err) {
+		dev_err(&rproc->dev, "Failed to enable clock\n");
+		return err;
+	}
+
+	if (ddata->config->sw_reset) {
+		err = reset_control_deassert(ddata->sw_reset);
+		if (err) {
+			dev_err(&rproc->dev, "Failed to deassert S/W Reset\n");
+			goto sw_reset_fail;
+		}
+	}
+
+	if (ddata->config->pwr_reset) {
+		err = reset_control_deassert(ddata->pwr_reset);
+		if (err) {
+			dev_err(&rproc->dev, "Failed to deassert Power Reset\n");
+			goto pwr_reset_fail;
+		}
+	}
+
+	dev_info(&rproc->dev, "Started from 0x%x\n", rproc->bootaddr);
+
+	return 0;
+
+
+pwr_reset_fail:
+	reset_control_assert(ddata->sw_reset);
+sw_reset_fail:
+	clk_disable(ddata->clk);
+
+	return err;
+}
+
+static struct rproc_ops st_rproc_ops = {
+	.start		= st_rproc_start,
+	.stop		= st_rproc_stop,
+};
+
+/*
+ * Fetch state of the processor: 0 is off, 1 is on.
+ */
+static int st_rproc_state(struct platform_device *pdev)
+{
+	struct rproc *rproc = platform_get_drvdata(pdev);
+	struct st_rproc *ddata = rproc->priv;
+	int reset_sw = 0, reset_pwr = 0;
+
+	if (ddata->config->sw_reset)
+		reset_sw = reset_control_status(ddata->sw_reset);
+
+	if (ddata->config->pwr_reset)
+		reset_pwr = reset_control_status(ddata->pwr_reset);
+
+	if (reset_sw < 0 || reset_pwr < 0)
+		return -EINVAL;
+
+	return !reset_sw && !reset_pwr;
+}
+
+static const struct st_rproc_config st40_rproc_cfg = {
+	.sw_reset = true,
+	.pwr_reset = true,
+	.bootaddr_mask = GENMASK(28, 1),
+};
+
+static const struct st_rproc_config st231_rproc_cfg = {
+	.sw_reset = true,
+	.pwr_reset = false,
+	.bootaddr_mask = GENMASK(31, 6),
+};
+
+static const struct of_device_id st_rproc_match[] = {
+	{ .compatible = "st,st40-rproc", .data = &st40_rproc_cfg },
+	{ .compatible = "st,st231-rproc", .data = &st231_rproc_cfg },
+	{},
+};
+MODULE_DEVICE_TABLE(of, st_rproc_match);
+
+static int st_rproc_parse_dt(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rproc *rproc = platform_get_drvdata(pdev);
+	struct st_rproc *ddata = rproc->priv;
+	struct device_node *np = dev->of_node;
+	struct resource	*mem;
+	int err;
+
+	if (ddata->config->sw_reset) {
+		ddata->sw_reset = devm_reset_control_get(dev, "sw_reset");
+		if (IS_ERR(ddata->sw_reset)) {
+			dev_err(dev, "Failed to get S/W Reset\n");
+			return PTR_ERR(ddata->sw_reset);
+		}
+	}
+
+	if (ddata->config->pwr_reset) {
+		ddata->pwr_reset = devm_reset_control_get(dev, "pwr_reset");
+		if (IS_ERR(ddata->pwr_reset)) {
+			dev_err(dev, "Failed to get Power Reset\n");
+			return PTR_ERR(ddata->pwr_reset);
+		}
+	}
+
+	ddata->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(ddata->clk)) {
+		dev_err(dev, "Failed to get clock\n");
+		return PTR_ERR(ddata->clk);
+	}
+
+	err = of_property_read_u32(np, "clock-frequency", &ddata->clk_rate);
+	if (err) {
+		dev_err(dev, "failed to get clock frequency\n");
+		return err;
+	}
+
+	ddata->boot_base = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
+	if (!ddata->boot_base) {
+		dev_err(dev, "Boot base not found\n");
+		return -EINVAL;
+	}
+
+	err = of_property_read_u32_index(np, "st,syscfg", 1,
+					 &ddata->boot_offset);
+	if (err) {
+		dev_err(dev, "Boot offset not found\n");
+		return -EINVAL;
+	}
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		dev_err(dev, "no rproc memory definition\n");
+		return -ENXIO;
+	}
+
+	if (!devm_request_mem_region(dev, mem->start,
+				     resource_size(mem), pdev->name)) {
+		dev_err(dev, "failed to get memory region resource\n");
+		return -EBUSY;
+	}
+	err = dmam_declare_coherent_memory(dev, mem->start, mem->start,
+					  resource_size(mem),
+					  DMA_MEMORY_MAP |
+					  DMA_MEMORY_EXCLUSIVE);
+	if (err < 0) {
+		dev_err(dev, "cannot declare coherent memory: %d\n", err);
+		return -ENXIO;
+	}
+
+	err = clk_prepare(ddata->clk);
+	if (err)
+		dev_err(dev, "failed to get clock\n");
+
+	return err;
+}
+
+static int st_rproc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	const struct of_device_id *match;
+	struct st_rproc *ddata;
+	struct device_node *np = dev->of_node;
+	struct rproc *rproc;
+	int enabled;
+	int ret;
+
+	match = of_match_device((st_rproc_match), dev);
+	if (!match || !match->data) {
+		dev_err(dev, "No device match found\n");
+		return -ENODEV;
+	}
+
+	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
+	if (!rproc)
+		return -ENOMEM;
+
+	ddata = rproc->priv;
+	ddata->config = (struct st_rproc_config *)match->data;
+
+	platform_set_drvdata(pdev, rproc);
+
+	ret = st_rproc_parse_dt(pdev);
+	if (ret)
+		goto free_rproc;
+
+	enabled = st_rproc_state(pdev);
+	if (enabled < 0)
+		goto free_rproc;
+
+	if (enabled) {
+		atomic_inc(&rproc->power);
+		rproc->state = RPROC_RUNNING;
+	} else {
+		clk_set_rate(ddata->clk, ddata->clk_rate);
+	}
+
+	ret = rproc_add(rproc);
+	if (ret)
+		goto free_rproc;
+
+	return 0;
+
+free_rproc:
+	rproc_put(rproc);
+	return ret;
+}
+
+static int st_rproc_remove(struct platform_device *pdev)
+{
+	struct rproc *rproc = platform_get_drvdata(pdev);
+	struct st_rproc *ddata = rproc->priv;
+
+	rproc_del(rproc);
+
+	clk_disable_unprepare(ddata->clk);
+
+	rproc_put(rproc);
+
+	return 0;
+}
+
+static struct platform_driver st_rproc_driver = {
+	.probe = st_rproc_probe,
+	.remove = st_rproc_remove,
+	.driver = {
+		.name = "st-rproc",
+		.of_match_table = of_match_ptr(st_rproc_match),
+	},
+};
+module_platform_driver(st_rproc_driver);
+
+MODULE_DESCRIPTION("ST Remote Processor Control Driver");
+MODULE_AUTHOR("Ludovic Barre <ludovic.barre@st.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 4/6] remoteproc: debugfs: Add ability to boot remote processor using debugfs
  2015-09-02 15:38 ` Lee Jones
  (?)
@ 2015-09-02 15:38   ` Lee Jones
  -1 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: kernel, ohad, devicetree, Nathan_Lynch, f.fainelli, Lee Jones,
	Ludovic Barre

This functionality is especially useful during the testing phase.  When
used in conjunction with Mailbox's Test Framework we can trivially conduct
end-to-end testing i.e. boot co-processor, send and receive messages to
the co-processor, then shut it down again (repeat as required).

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/remoteproc/remoteproc_debugfs.c | 34 +++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c
index 9d30809..8113c18 100644
--- a/drivers/remoteproc/remoteproc_debugfs.c
+++ b/drivers/remoteproc/remoteproc_debugfs.c
@@ -88,8 +88,42 @@ static ssize_t rproc_state_read(struct file *filp, char __user *userbuf,
 	return simple_read_from_buffer(userbuf, count, ppos, buf, i);
 }
 
+static ssize_t rproc_state_write(struct file *filp, const char __user *userbuf,
+				 size_t count, loff_t *ppos)
+{
+	struct rproc *rproc = filp->private_data;
+	char buf[10];
+	int ret;
+
+	if (count > sizeof(buf))
+		return count;
+
+	ret = copy_from_user(buf, userbuf, count);
+	if (ret)
+		return -EFAULT;
+
+	if (buf[count - 1] == '\n')
+		buf[count - 1] = '\0';
+
+	if (!strncmp(buf, "start", count)) {
+		ret = rproc_boot(rproc);
+		if (ret) {
+			dev_err(&rproc->dev, "Boot failed: %d\n", ret);
+			return ret;
+		}
+	} else if (!strncmp(buf, "stop", count)) {
+		rproc_shutdown(rproc);
+	} else {
+		dev_err(&rproc->dev, "Unrecognised option: %s\n", buf);
+		return -EINVAL;
+	}
+
+	return count;
+}
+
 static const struct file_operations rproc_state_ops = {
 	.read = rproc_state_read,
+	.write = rproc_state_write,
 	.open = simple_open,
 	.llseek	= generic_file_llseek,
 };
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 4/6] remoteproc: debugfs: Add ability to boot remote processor using debugfs
@ 2015-09-02 15:38   ` Lee Jones
  0 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: ohad, devicetree, f.fainelli, kernel, Nathan_Lynch, Lee Jones,
	Ludovic Barre

This functionality is especially useful during the testing phase.  When
used in conjunction with Mailbox's Test Framework we can trivially conduct
end-to-end testing i.e. boot co-processor, send and receive messages to
the co-processor, then shut it down again (repeat as required).

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/remoteproc/remoteproc_debugfs.c | 34 +++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c
index 9d30809..8113c18 100644
--- a/drivers/remoteproc/remoteproc_debugfs.c
+++ b/drivers/remoteproc/remoteproc_debugfs.c
@@ -88,8 +88,42 @@ static ssize_t rproc_state_read(struct file *filp, char __user *userbuf,
 	return simple_read_from_buffer(userbuf, count, ppos, buf, i);
 }
 
+static ssize_t rproc_state_write(struct file *filp, const char __user *userbuf,
+				 size_t count, loff_t *ppos)
+{
+	struct rproc *rproc = filp->private_data;
+	char buf[10];
+	int ret;
+
+	if (count > sizeof(buf))
+		return count;
+
+	ret = copy_from_user(buf, userbuf, count);
+	if (ret)
+		return -EFAULT;
+
+	if (buf[count - 1] == '\n')
+		buf[count - 1] = '\0';
+
+	if (!strncmp(buf, "start", count)) {
+		ret = rproc_boot(rproc);
+		if (ret) {
+			dev_err(&rproc->dev, "Boot failed: %d\n", ret);
+			return ret;
+		}
+	} else if (!strncmp(buf, "stop", count)) {
+		rproc_shutdown(rproc);
+	} else {
+		dev_err(&rproc->dev, "Unrecognised option: %s\n", buf);
+		return -EINVAL;
+	}
+
+	return count;
+}
+
 static const struct file_operations rproc_state_ops = {
 	.read = rproc_state_read,
+	.write = rproc_state_write,
 	.open = simple_open,
 	.llseek	= generic_file_llseek,
 };
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 4/6] remoteproc: debugfs: Add ability to boot remote processor using debugfs
@ 2015-09-02 15:38   ` Lee Jones
  0 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel

This functionality is especially useful during the testing phase.  When
used in conjunction with Mailbox's Test Framework we can trivially conduct
end-to-end testing i.e. boot co-processor, send and receive messages to
the co-processor, then shut it down again (repeat as required).

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/remoteproc/remoteproc_debugfs.c | 34 +++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_debugfs.c b/drivers/remoteproc/remoteproc_debugfs.c
index 9d30809..8113c18 100644
--- a/drivers/remoteproc/remoteproc_debugfs.c
+++ b/drivers/remoteproc/remoteproc_debugfs.c
@@ -88,8 +88,42 @@ static ssize_t rproc_state_read(struct file *filp, char __user *userbuf,
 	return simple_read_from_buffer(userbuf, count, ppos, buf, i);
 }
 
+static ssize_t rproc_state_write(struct file *filp, const char __user *userbuf,
+				 size_t count, loff_t *ppos)
+{
+	struct rproc *rproc = filp->private_data;
+	char buf[10];
+	int ret;
+
+	if (count > sizeof(buf))
+		return count;
+
+	ret = copy_from_user(buf, userbuf, count);
+	if (ret)
+		return -EFAULT;
+
+	if (buf[count - 1] == '\n')
+		buf[count - 1] = '\0';
+
+	if (!strncmp(buf, "start", count)) {
+		ret = rproc_boot(rproc);
+		if (ret) {
+			dev_err(&rproc->dev, "Boot failed: %d\n", ret);
+			return ret;
+		}
+	} else if (!strncmp(buf, "stop", count)) {
+		rproc_shutdown(rproc);
+	} else {
+		dev_err(&rproc->dev, "Unrecognised option: %s\n", buf);
+		return -EINVAL;
+	}
+
+	return count;
+}
+
 static const struct file_operations rproc_state_ops = {
 	.read = rproc_state_read,
+	.write = rproc_state_write,
 	.open = simple_open,
 	.llseek	= generic_file_llseek,
 };
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 5/6] ARM: STiH407: Add nodes for RemoteProc
  2015-09-02 15:38 ` Lee Jones
@ 2015-09-02 15:38   ` Lee Jones
  -1 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: kernel, ohad, devicetree, Nathan_Lynch, f.fainelli, Lee Jones,
	Ludovic Barre

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 arch/arm/boot/dts/stih407-family.dtsi | 40 +++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 33daa49..1c31918 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -608,5 +608,45 @@
 			status		= "okay";
 			tx-only;
 		};
+
+		st231_gp0: st231-gp0@40000000 {
+			compatible	= "st,st231-rproc";
+			reg		= <0x40000000 0x01000000>;
+			resets		= <&softreset STIH407_ST231_GP0_SOFTRESET>;
+			reset-names	= "sw_reset";
+			clocks		= <&clk_s_c0_flexgen CLK_ST231_GP_0>;
+			clock-frequency	= <600000000>;
+			st,syscfg	= <&syscfg_core 0x22c>;
+		};
+
+		st231_gp1: st231-gp1@41000000 {
+			compatible	= "st,st231-rproc";
+			reg		= <0x41000000 0x01000000>;
+			resets		= <&softreset STIH407_ST231_GP1_SOFTRESET>;
+			reset-names	= "sw_reset";
+			clocks		= <&clk_s_c0_flexgen CLK_ST231_GP_1>;
+			clock-frequency = <600000000>;
+			st,syscfg	= <&syscfg_core 0x220>;
+		};
+
+		st231_audio: st231-audio@42000000 {
+			compatible	= "st,st231-rproc";
+			reg		= <0x42000000 0x01000000>;
+			resets		= <&softreset STIH407_ST231_AUD_SOFTRESET>;
+			reset-names	= "sw_reset";
+			clocks		= <&clk_s_c0_flexgen CLK_ST231_AUD_0>;
+			clock-frequency	= <600000000>;
+			st,syscfg	= <&syscfg_core 0x228>;
+		};
+
+		st231_dmu: st231-dmu@43000000 {
+			compatible	= "st,st231-rproc";
+			reg		= <0x43000000 0x01000000>;
+			resets		= <&softreset STIH407_ST231_DMU_SOFTRESET>;
+			reset-names	= "sw_reset";
+			clocks		= <&clk_s_c0_flexgen CLK_ST231_DMU>;
+			clock-frequency	= <600000000>;
+			st,syscfg	= <&syscfg_core 0x224>;
+		};
 	};
 };
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 5/6] ARM: STiH407: Add nodes for RemoteProc
@ 2015-09-02 15:38   ` Lee Jones
  0 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 arch/arm/boot/dts/stih407-family.dtsi | 40 +++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 33daa49..1c31918 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -608,5 +608,45 @@
 			status		= "okay";
 			tx-only;
 		};
+
+		st231_gp0: st231-gp0 at 40000000 {
+			compatible	= "st,st231-rproc";
+			reg		= <0x40000000 0x01000000>;
+			resets		= <&softreset STIH407_ST231_GP0_SOFTRESET>;
+			reset-names	= "sw_reset";
+			clocks		= <&clk_s_c0_flexgen CLK_ST231_GP_0>;
+			clock-frequency	= <600000000>;
+			st,syscfg	= <&syscfg_core 0x22c>;
+		};
+
+		st231_gp1: st231-gp1 at 41000000 {
+			compatible	= "st,st231-rproc";
+			reg		= <0x41000000 0x01000000>;
+			resets		= <&softreset STIH407_ST231_GP1_SOFTRESET>;
+			reset-names	= "sw_reset";
+			clocks		= <&clk_s_c0_flexgen CLK_ST231_GP_1>;
+			clock-frequency = <600000000>;
+			st,syscfg	= <&syscfg_core 0x220>;
+		};
+
+		st231_audio: st231-audio at 42000000 {
+			compatible	= "st,st231-rproc";
+			reg		= <0x42000000 0x01000000>;
+			resets		= <&softreset STIH407_ST231_AUD_SOFTRESET>;
+			reset-names	= "sw_reset";
+			clocks		= <&clk_s_c0_flexgen CLK_ST231_AUD_0>;
+			clock-frequency	= <600000000>;
+			st,syscfg	= <&syscfg_core 0x228>;
+		};
+
+		st231_dmu: st231-dmu at 43000000 {
+			compatible	= "st,st231-rproc";
+			reg		= <0x43000000 0x01000000>;
+			resets		= <&softreset STIH407_ST231_DMU_SOFTRESET>;
+			reset-names	= "sw_reset";
+			clocks		= <&clk_s_c0_flexgen CLK_ST231_DMU>;
+			clock-frequency	= <600000000>;
+			st,syscfg	= <&syscfg_core 0x224>;
+		};
 	};
 };
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 6/6] MAINTAINERS: Add ST's Remote Processor Driver to ARM/STI ARCHITECTURE
  2015-09-02 15:38 ` Lee Jones
@ 2015-09-02 15:38   ` Lee Jones
  -1 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: kernel, ohad, devicetree, Nathan_Lynch, f.fainelli, Lee Jones

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index fd60784..cd48a93 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1511,6 +1511,7 @@ F:	drivers/phy/phy-miphy365x.c
 F:	drivers/phy/phy-stih407-usb.c
 F:	drivers/phy/phy-stih41x-usb.c
 F:	drivers/pinctrl/pinctrl-st.c
+F:	drivers/remoteproc/st_remoteproc.c
 F:	drivers/reset/sti/
 F:	drivers/rtc/rtc-st-lpc.c
 F:	drivers/tty/serial/st-asc.c
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 6/6] MAINTAINERS: Add ST's Remote Processor Driver to ARM/STI ARCHITECTURE
@ 2015-09-02 15:38   ` Lee Jones
  0 siblings, 0 replies; 25+ messages in thread
From: Lee Jones @ 2015-09-02 15:38 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index fd60784..cd48a93 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1511,6 +1511,7 @@ F:	drivers/phy/phy-miphy365x.c
 F:	drivers/phy/phy-stih407-usb.c
 F:	drivers/phy/phy-stih41x-usb.c
 F:	drivers/pinctrl/pinctrl-st.c
+F:	drivers/remoteproc/st_remoteproc.c
 F:	drivers/reset/sti/
 F:	drivers/rtc/rtc-st-lpc.c
 F:	drivers/tty/serial/st-asc.c
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [STLinux Kernel] [PATCH v3 5/6] ARM: STiH407: Add nodes for RemoteProc
@ 2015-09-03 15:26     ` Peter Griffin
  0 siblings, 0 replies; 25+ messages in thread
From: Peter Griffin @ 2015-09-03 15:26 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-arm-kernel, linux-kernel, ohad, devicetree, f.fainelli,
	kernel, Nathan_Lynch

Hi Lee,

On Wed, 02 Sep 2015, Lee Jones wrote:

> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> ---
>  arch/arm/boot/dts/stih407-family.dtsi | 40 +++++++++++++++++++++++++++++++++++
>  1 file changed, 40 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> index 33daa49..1c31918 100644
> --- a/arch/arm/boot/dts/stih407-family.dtsi
> +++ b/arch/arm/boot/dts/stih407-family.dtsi
> @@ -608,5 +608,45 @@
>  			status		= "okay";
>  			tx-only;
>  		};
> +
> +		st231_gp0: st231-gp0@40000000 {
> +			compatible	= "st,st231-rproc";
> +			reg		= <0x40000000 0x01000000>;
> +			resets		= <&softreset STIH407_ST231_GP0_SOFTRESET>;
> +			reset-names	= "sw_reset";
> +			clocks		= <&clk_s_c0_flexgen CLK_ST231_GP_0>;
> +			clock-frequency	= <600000000>;
> +			st,syscfg	= <&syscfg_core 0x22c>;
> +		};
> +
> +		st231_gp1: st231-gp1@41000000 {
> +			compatible	= "st,st231-rproc";
> +			reg		= <0x41000000 0x01000000>;
> +			resets		= <&softreset STIH407_ST231_GP1_SOFTRESET>;
> +			reset-names	= "sw_reset";
> +			clocks		= <&clk_s_c0_flexgen CLK_ST231_GP_1>;
> +			clock-frequency = <600000000>;
> +			st,syscfg	= <&syscfg_core 0x220>;
> +		};
> +
> +		st231_audio: st231-audio@42000000 {
> +			compatible	= "st,st231-rproc";
> +			reg		= <0x42000000 0x01000000>;
> +			resets		= <&softreset STIH407_ST231_AUD_SOFTRESET>;
> +			reset-names	= "sw_reset";
> +			clocks		= <&clk_s_c0_flexgen CLK_ST231_AUD_0>;
> +			clock-frequency	= <600000000>;
> +			st,syscfg	= <&syscfg_core 0x228>;
> +		};
> +
> +		st231_dmu: st231-dmu@43000000 {
> +			compatible	= "st,st231-rproc";
> +			reg		= <0x43000000 0x01000000>;
> +			resets		= <&softreset STIH407_ST231_DMU_SOFTRESET>;
> +			reset-names	= "sw_reset";
> +			clocks		= <&clk_s_c0_flexgen CLK_ST231_DMU>;

Thinking more about this more, I believe you will actually need to support enabling
and setting the frequency on a list of clocks.

The reason being that for the video ST231 for example you also need to enable
CLK_VID_DMU. This clock clocks the DeltaMU hw used by the video ST231 for
video decoding. I suspect if the video firmware is loading and working correctly
with this patchset, then it is most likely because the clock is being enabled
by the bootloader and not being disabled by CCF due to our platform booting
with clk_ignore_unused.

When yours (or Mikes) critical clock patches get merged, and we stop booting with
"clk_ignore_unused" you will find it no longer works.

I'm not aware of other hw which is used by the audio of gp ST231, but as the driver
also covers ST40 and potentially other co-processors in the future, having a list
of clocks seems nicely extendable to cover other permutations.

regards,

Peter.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [STLinux Kernel] [PATCH v3 5/6] ARM: STiH407: Add nodes for RemoteProc
@ 2015-09-03 15:26     ` Peter Griffin
  0 siblings, 0 replies; 25+ messages in thread
From: Peter Griffin @ 2015-09-03 15:26 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, ohad-Ix1uc/W3ht7QT0dZR+AlfA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	f.fainelli-Re5JQEeQqe8AvxtiuMwx3w, kernel-F5mvAk5X5gdBDgjK7y7TUQ,
	Nathan_Lynch-nmGgyN9QBj3QT0dZR+AlfA

Hi Lee,

On Wed, 02 Sep 2015, Lee Jones wrote:

> Signed-off-by: Ludovic Barre <ludovic.barre-qxv4g6HH51o@public.gmane.org>
> Signed-off-by: Lee Jones <lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
>  arch/arm/boot/dts/stih407-family.dtsi | 40 +++++++++++++++++++++++++++++++++++
>  1 file changed, 40 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> index 33daa49..1c31918 100644
> --- a/arch/arm/boot/dts/stih407-family.dtsi
> +++ b/arch/arm/boot/dts/stih407-family.dtsi
> @@ -608,5 +608,45 @@
>  			status		= "okay";
>  			tx-only;
>  		};
> +
> +		st231_gp0: st231-gp0@40000000 {
> +			compatible	= "st,st231-rproc";
> +			reg		= <0x40000000 0x01000000>;
> +			resets		= <&softreset STIH407_ST231_GP0_SOFTRESET>;
> +			reset-names	= "sw_reset";
> +			clocks		= <&clk_s_c0_flexgen CLK_ST231_GP_0>;
> +			clock-frequency	= <600000000>;
> +			st,syscfg	= <&syscfg_core 0x22c>;
> +		};
> +
> +		st231_gp1: st231-gp1@41000000 {
> +			compatible	= "st,st231-rproc";
> +			reg		= <0x41000000 0x01000000>;
> +			resets		= <&softreset STIH407_ST231_GP1_SOFTRESET>;
> +			reset-names	= "sw_reset";
> +			clocks		= <&clk_s_c0_flexgen CLK_ST231_GP_1>;
> +			clock-frequency = <600000000>;
> +			st,syscfg	= <&syscfg_core 0x220>;
> +		};
> +
> +		st231_audio: st231-audio@42000000 {
> +			compatible	= "st,st231-rproc";
> +			reg		= <0x42000000 0x01000000>;
> +			resets		= <&softreset STIH407_ST231_AUD_SOFTRESET>;
> +			reset-names	= "sw_reset";
> +			clocks		= <&clk_s_c0_flexgen CLK_ST231_AUD_0>;
> +			clock-frequency	= <600000000>;
> +			st,syscfg	= <&syscfg_core 0x228>;
> +		};
> +
> +		st231_dmu: st231-dmu@43000000 {
> +			compatible	= "st,st231-rproc";
> +			reg		= <0x43000000 0x01000000>;
> +			resets		= <&softreset STIH407_ST231_DMU_SOFTRESET>;
> +			reset-names	= "sw_reset";
> +			clocks		= <&clk_s_c0_flexgen CLK_ST231_DMU>;

Thinking more about this more, I believe you will actually need to support enabling
and setting the frequency on a list of clocks.

The reason being that for the video ST231 for example you also need to enable
CLK_VID_DMU. This clock clocks the DeltaMU hw used by the video ST231 for
video decoding. I suspect if the video firmware is loading and working correctly
with this patchset, then it is most likely because the clock is being enabled
by the bootloader and not being disabled by CCF due to our platform booting
with clk_ignore_unused.

When yours (or Mikes) critical clock patches get merged, and we stop booting with
"clk_ignore_unused" you will find it no longer works.

I'm not aware of other hw which is used by the audio of gp ST231, but as the driver
also covers ST40 and potentially other co-processors in the future, having a list
of clocks seems nicely extendable to cover other permutations.

regards,

Peter.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [STLinux Kernel] [PATCH v3 5/6] ARM: STiH407: Add nodes for RemoteProc
@ 2015-09-03 15:26     ` Peter Griffin
  0 siblings, 0 replies; 25+ messages in thread
From: Peter Griffin @ 2015-09-03 15:26 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lee,

On Wed, 02 Sep 2015, Lee Jones wrote:

> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> ---
>  arch/arm/boot/dts/stih407-family.dtsi | 40 +++++++++++++++++++++++++++++++++++
>  1 file changed, 40 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> index 33daa49..1c31918 100644
> --- a/arch/arm/boot/dts/stih407-family.dtsi
> +++ b/arch/arm/boot/dts/stih407-family.dtsi
> @@ -608,5 +608,45 @@
>  			status		= "okay";
>  			tx-only;
>  		};
> +
> +		st231_gp0: st231-gp0 at 40000000 {
> +			compatible	= "st,st231-rproc";
> +			reg		= <0x40000000 0x01000000>;
> +			resets		= <&softreset STIH407_ST231_GP0_SOFTRESET>;
> +			reset-names	= "sw_reset";
> +			clocks		= <&clk_s_c0_flexgen CLK_ST231_GP_0>;
> +			clock-frequency	= <600000000>;
> +			st,syscfg	= <&syscfg_core 0x22c>;
> +		};
> +
> +		st231_gp1: st231-gp1 at 41000000 {
> +			compatible	= "st,st231-rproc";
> +			reg		= <0x41000000 0x01000000>;
> +			resets		= <&softreset STIH407_ST231_GP1_SOFTRESET>;
> +			reset-names	= "sw_reset";
> +			clocks		= <&clk_s_c0_flexgen CLK_ST231_GP_1>;
> +			clock-frequency = <600000000>;
> +			st,syscfg	= <&syscfg_core 0x220>;
> +		};
> +
> +		st231_audio: st231-audio at 42000000 {
> +			compatible	= "st,st231-rproc";
> +			reg		= <0x42000000 0x01000000>;
> +			resets		= <&softreset STIH407_ST231_AUD_SOFTRESET>;
> +			reset-names	= "sw_reset";
> +			clocks		= <&clk_s_c0_flexgen CLK_ST231_AUD_0>;
> +			clock-frequency	= <600000000>;
> +			st,syscfg	= <&syscfg_core 0x228>;
> +		};
> +
> +		st231_dmu: st231-dmu at 43000000 {
> +			compatible	= "st,st231-rproc";
> +			reg		= <0x43000000 0x01000000>;
> +			resets		= <&softreset STIH407_ST231_DMU_SOFTRESET>;
> +			reset-names	= "sw_reset";
> +			clocks		= <&clk_s_c0_flexgen CLK_ST231_DMU>;

Thinking more about this more, I believe you will actually need to support enabling
and setting the frequency on a list of clocks.

The reason being that for the video ST231 for example you also need to enable
CLK_VID_DMU. This clock clocks the DeltaMU hw used by the video ST231 for
video decoding. I suspect if the video firmware is loading and working correctly
with this patchset, then it is most likely because the clock is being enabled
by the bootloader and not being disabled by CCF due to our platform booting
with clk_ignore_unused.

When yours (or Mikes) critical clock patches get merged, and we stop booting with
"clk_ignore_unused" you will find it no longer works.

I'm not aware of other hw which is used by the audio of gp ST231, but as the driver
also covers ST40 and potentially other co-processors in the future, having a list
of clocks seems nicely extendable to cover other permutations.

regards,

Peter.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [STLinux Kernel] [PATCH v3 1/6] ARM: STi: Add DT defines for co-processor reset lines
  2015-09-02 15:38   ` Lee Jones
@ 2015-09-03 16:31     ` Peter Griffin
  -1 siblings, 0 replies; 25+ messages in thread
From: Peter Griffin @ 2015-09-03 16:31 UTC (permalink / raw)
  To: Lee Jones
  Cc: linux-arm-kernel, linux-kernel, ohad, devicetree, f.fainelli,
	kernel, Nathan_Lynch

Hi Lee,

On Wed, 02 Sep 2015, Lee Jones wrote:

> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> ---
>  include/dt-bindings/reset-controller/stih407-resets.h | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/include/dt-bindings/reset-controller/stih407-resets.h b/include/dt-bindings/reset-controller/stih407-resets.h
> index 02d4328..4ab3a1c 100644
> --- a/include/dt-bindings/reset-controller/stih407-resets.h
> +++ b/include/dt-bindings/reset-controller/stih407-resets.h
> @@ -52,6 +52,10 @@
>  #define STIH407_KEYSCAN_SOFTRESET	26
>  #define STIH407_USB2_PORT0_SOFTRESET	27
>  #define STIH407_USB2_PORT1_SOFTRESET	28
> +#define STIH407_ST231_AUD_SOFTRESET	29
> +#define STIH407_ST231_DMU_SOFTRESET	30
> +#define STIH407_ST231_GP0_SOFTRESET	31
> +#define STIH407_ST231_GP1_SOFTRESET	32

You've added the #defines, so the DT should compile with v3.

However you don't appear to have added the code which
uses these #defines to drivers/reset/reset-stih407.c. So v3
still won't take the co-processors out of reset.

regards,

Peter.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [STLinux Kernel] [PATCH v3 1/6] ARM: STi: Add DT defines for co-processor reset lines
@ 2015-09-03 16:31     ` Peter Griffin
  0 siblings, 0 replies; 25+ messages in thread
From: Peter Griffin @ 2015-09-03 16:31 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lee,

On Wed, 02 Sep 2015, Lee Jones wrote:

> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> ---
>  include/dt-bindings/reset-controller/stih407-resets.h | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/include/dt-bindings/reset-controller/stih407-resets.h b/include/dt-bindings/reset-controller/stih407-resets.h
> index 02d4328..4ab3a1c 100644
> --- a/include/dt-bindings/reset-controller/stih407-resets.h
> +++ b/include/dt-bindings/reset-controller/stih407-resets.h
> @@ -52,6 +52,10 @@
>  #define STIH407_KEYSCAN_SOFTRESET	26
>  #define STIH407_USB2_PORT0_SOFTRESET	27
>  #define STIH407_USB2_PORT1_SOFTRESET	28
> +#define STIH407_ST231_AUD_SOFTRESET	29
> +#define STIH407_ST231_DMU_SOFTRESET	30
> +#define STIH407_ST231_GP0_SOFTRESET	31
> +#define STIH407_ST231_GP1_SOFTRESET	32

You've added the #defines, so the DT should compile with v3.

However you don't appear to have added the code which
uses these #defines to drivers/reset/reset-stih407.c. So v3
still won't take the co-processors out of reset.

regards,

Peter.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v3 3/6] remoteproc: Supply controller driver for ST's Remote Processors
  2015-09-02 15:38   ` Lee Jones
  (?)
@ 2015-09-03 19:52     ` Suman Anna
  -1 siblings, 0 replies; 25+ messages in thread
From: Suman Anna @ 2015-09-03 19:52 UTC (permalink / raw)
  To: Lee Jones, linux-arm-kernel, linux-kernel
  Cc: kernel, ohad, devicetree, Nathan_Lynch, f.fainelli, Ludovic Barre

Hi Lee,

On 09/02/2015 10:38 AM, Lee Jones wrote:
> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> ---
>  drivers/remoteproc/Kconfig         |   9 ++
>  drivers/remoteproc/Makefile        |   1 +
>  drivers/remoteproc/st_remoteproc.c | 307 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 317 insertions(+)
>  create mode 100644 drivers/remoteproc/st_remoteproc.c
> 
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 28c711f..72e97d7 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -77,4 +77,13 @@ config DA8XX_REMOTEPROC
>  	  It's safe to say n here if you're not interested in multimedia
>  	  offloading.
>  
> +config ST_REMOTEPROC
> +	tristate "ST remoteproc support"
> +	depends on ARCH_STI
> +	select REMOTEPROC
> +	help
> +	  Say y here to support ST's adjunct processors via the remote
> +	  processor framework.
> +	  This can be either built-in or a loadable module.
> +
>  endmenu
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> index 81b04d1..279cb2e 100644
> --- a/drivers/remoteproc/Makefile
> +++ b/drivers/remoteproc/Makefile
> @@ -11,3 +11,4 @@ obj-$(CONFIG_OMAP_REMOTEPROC)		+= omap_remoteproc.o
>  obj-$(CONFIG_STE_MODEM_RPROC)	 	+= ste_modem_rproc.o
>  obj-$(CONFIG_WKUP_M3_RPROC)		+= wkup_m3_rproc.o
>  obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
> +obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
> diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c
> new file mode 100644
> index 0000000..24ae6d3
> --- /dev/null
> +++ b/drivers/remoteproc/st_remoteproc.c
> @@ -0,0 +1,307 @@
> +/*
> + * ST's Remote Processor Control Driver
> + *
> + * Copyright (C) 2015 STMicroelectronics - All Rights Reserved
> + *
> + * Author: Ludovic Barre <ludovic.barre@st.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/remoteproc.h>
> +#include <linux/reset.h>
> +
> +struct st_rproc_config {
> +	bool			sw_reset;
> +	bool			pwr_reset;
> +	u32			bootaddr_mask;
> +};
> +
> +struct st_rproc {
> +	struct st_rproc_config	*config;
> +	struct reset_control	*sw_reset;
> +	struct reset_control	*pwr_reset;
> +	struct clk		*clk;
> +	u32			clk_rate;
> +	struct regmap		*boot_base;
> +	u32			boot_offset;
> +};
> +
> +static int st_rproc_stop(struct rproc *rproc)
> +{
> +	struct st_rproc *ddata = rproc->priv;
> +	int sw_err = 0, pwr_err = 0;
> +
> +	if (ddata->config->sw_reset) {
> +		sw_err = reset_control_assert(ddata->sw_reset);
> +		if (sw_err)
> +			dev_err(&rproc->dev, "Failed to assert S/W Reset\n");
> +	}
> +
> +	if (ddata->config->pwr_reset) {
> +		pwr_err = reset_control_assert(ddata->pwr_reset);
> +		if (pwr_err)
> +			dev_err(&rproc->dev, "Failed to assert Power Reset\n");
> +	}
> +
> +	clk_disable(ddata->clk);
> +
> +	return sw_err ?: pwr_err;
> +}

nit, can you please move st_rproc_stop function after st_rproc_start,
same order as in fw_ops, for better flow.

> +
> +static int st_rproc_start(struct rproc *rproc)
> +{
> +	struct st_rproc *ddata = rproc->priv;
> +	int err;
> +
> +	regmap_update_bits(ddata->boot_base, ddata->boot_offset,
> +			   ddata->config->bootaddr_mask, rproc->bootaddr);
> +
> +	err = clk_enable(ddata->clk);
> +	if (err) {
> +		dev_err(&rproc->dev, "Failed to enable clock\n");
> +		return err;
> +	}
> +
> +	if (ddata->config->sw_reset) {
> +		err = reset_control_deassert(ddata->sw_reset);
> +		if (err) {
> +			dev_err(&rproc->dev, "Failed to deassert S/W Reset\n");
> +			goto sw_reset_fail;
> +		}
> +	}
> +
> +	if (ddata->config->pwr_reset) {
> +		err = reset_control_deassert(ddata->pwr_reset);
> +		if (err) {
> +			dev_err(&rproc->dev, "Failed to deassert Power Reset\n");
> +			goto pwr_reset_fail;
> +		}
> +	}
> +
> +	dev_info(&rproc->dev, "Started from 0x%x\n", rproc->bootaddr);
> +
> +	return 0;
> +
> +
> +pwr_reset_fail:
> +	reset_control_assert(ddata->sw_reset);

Should this be under a check for (ddata->config->sw_reset). It is not
clear from code whether the sw_reset and pwr_reset are exclusive of each
of other or have both.

> +sw_reset_fail:
> +	clk_disable(ddata->clk);
> +
> +	return err;
> +}
> +
> +static struct rproc_ops st_rproc_ops = {
> +	.start		= st_rproc_start,
> +	.stop		= st_rproc_stop,
> +};
> +
> +/*
> + * Fetch state of the processor: 0 is off, 1 is on.
> + */
> +static int st_rproc_state(struct platform_device *pdev)
> +{
> +	struct rproc *rproc = platform_get_drvdata(pdev);
> +	struct st_rproc *ddata = rproc->priv;
> +	int reset_sw = 0, reset_pwr = 0;
> +
> +	if (ddata->config->sw_reset)
> +		reset_sw = reset_control_status(ddata->sw_reset);
> +
> +	if (ddata->config->pwr_reset)
> +		reset_pwr = reset_control_status(ddata->pwr_reset);
> +
> +	if (reset_sw < 0 || reset_pwr < 0)
> +		return -EINVAL;
> +
> +	return !reset_sw && !reset_pwr;
> +}
> +
> +static const struct st_rproc_config st40_rproc_cfg = {
> +	.sw_reset = true,
> +	.pwr_reset = true,
> +	.bootaddr_mask = GENMASK(28, 1),
> +};
> +
> +static const struct st_rproc_config st231_rproc_cfg = {
> +	.sw_reset = true,
> +	.pwr_reset = false,
> +	.bootaddr_mask = GENMASK(31, 6),
> +};
> +
> +static const struct of_device_id st_rproc_match[] = {
> +	{ .compatible = "st,st40-rproc", .data = &st40_rproc_cfg },
> +	{ .compatible = "st,st231-rproc", .data = &st231_rproc_cfg },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, st_rproc_match);
> +
> +static int st_rproc_parse_dt(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct rproc *rproc = platform_get_drvdata(pdev);
> +	struct st_rproc *ddata = rproc->priv;
> +	struct device_node *np = dev->of_node;
> +	struct resource	*mem;
> +	int err;
> +
> +	if (ddata->config->sw_reset) {
> +		ddata->sw_reset = devm_reset_control_get(dev, "sw_reset");
> +		if (IS_ERR(ddata->sw_reset)) {
> +			dev_err(dev, "Failed to get S/W Reset\n");
> +			return PTR_ERR(ddata->sw_reset);
> +		}
> +	}
> +
> +	if (ddata->config->pwr_reset) {
> +		ddata->pwr_reset = devm_reset_control_get(dev, "pwr_reset");
> +		if (IS_ERR(ddata->pwr_reset)) {
> +			dev_err(dev, "Failed to get Power Reset\n");
> +			return PTR_ERR(ddata->pwr_reset);
> +		}
> +	}
> +
> +	ddata->clk = devm_clk_get(dev, NULL);
> +	if (IS_ERR(ddata->clk)) {
> +		dev_err(dev, "Failed to get clock\n");
> +		return PTR_ERR(ddata->clk);
> +	}
> +
> +	err = of_property_read_u32(np, "clock-frequency", &ddata->clk_rate);
> +	if (err) {
> +		dev_err(dev, "failed to get clock frequency\n");
> +		return err;
> +	}
> +
> +	ddata->boot_base = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
> +	if (!ddata->boot_base) {
> +		dev_err(dev, "Boot base not found\n");
> +		return -EINVAL;
> +	}
> +
> +	err = of_property_read_u32_index(np, "st,syscfg", 1,
> +					 &ddata->boot_offset);
> +	if (err) {
> +		dev_err(dev, "Boot offset not found\n");
> +		return -EINVAL;
> +	}
> +
> +	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!mem) {
> +		dev_err(dev, "no rproc memory definition\n");
> +		return -ENXIO;
> +	}
> +
> +	if (!devm_request_mem_region(dev, mem->start,
> +				     resource_size(mem), pdev->name)) {
> +		dev_err(dev, "failed to get memory region resource\n");
> +		return -EBUSY;
> +	}
> +	err = dmam_declare_coherent_memory(dev, mem->start, mem->start,
> +					  resource_size(mem),
> +					  DMA_MEMORY_MAP |
> +					  DMA_MEMORY_EXCLUSIVE);
> +	if (err < 0) {
> +		dev_err(dev, "cannot declare coherent memory: %d\n", err);
> +		return -ENXIO;
> +	}

What kind of memory will this be? If this a carveout memory being
set-aside from DDR, you may want to use a reserved-memory node entry,
with a "memory-region" property added to the rproc device node and use
of_reserved_mem_device_init() and of_reserved_mem_device_release() API,
following the standard semantics of reserved-memory as in
Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt.

Obviously that will need a change in the binding as well.

> +
> +	err = clk_prepare(ddata->clk);
> +	if (err)
> +		dev_err(dev, "failed to get clock\n");
> +
> +	return err;
> +}
> +
> +static int st_rproc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	const struct of_device_id *match;
> +	struct st_rproc *ddata;
> +	struct device_node *np = dev->of_node;
> +	struct rproc *rproc;
> +	int enabled;
> +	int ret;
> +
> +	match = of_match_device((st_rproc_match), dev);
> +	if (!match || !match->data) {
> +		dev_err(dev, "No device match found\n");
> +		return -ENODEV;
> +	}
> +
> +	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
> +	if (!rproc)
> +		return -ENOMEM;
> +
> +	ddata = rproc->priv;
> +	ddata->config = (struct st_rproc_config *)match->data;

I believe Ohad's preference is to explicitly set rproc->has_iommu to false.

> +
> +	platform_set_drvdata(pdev, rproc);
> +
> +	ret = st_rproc_parse_dt(pdev);
> +	if (ret)
> +		goto free_rproc;
> +
> +	enabled = st_rproc_state(pdev);
> +	if (enabled < 0)
> +		goto free_rproc;
> +
> +	if (enabled) {
> +		atomic_inc(&rproc->power);
> +		rproc->state = RPROC_RUNNING;

I am curious about this change, who are you expecting to have booted the
processor before the driver is probed?

> +	} else {
> +		clk_set_rate(ddata->clk, ddata->clk_rate);
> +	}
> +
> +	ret = rproc_add(rproc);
> +	if (ret)
> +		goto free_rproc;
> +
> +	return 0;
> +
> +free_rproc:
> +	rproc_put(rproc);
> +	return ret;
> +}
> +
> +static int st_rproc_remove(struct platform_device *pdev)
> +{
> +	struct rproc *rproc = platform_get_drvdata(pdev);
> +	struct st_rproc *ddata = rproc->priv;
> +
> +	rproc_del(rproc);
> +
> +	clk_disable_unprepare(ddata->clk);
> +
> +	rproc_put(rproc);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver st_rproc_driver = {
> +	.probe = st_rproc_probe,
> +	.remove = st_rproc_remove,
> +	.driver = {
> +		.name = "st-rproc",
> +		.of_match_table = of_match_ptr(st_rproc_match),
> +	},
> +};
> +module_platform_driver(st_rproc_driver);
> +
> +MODULE_DESCRIPTION("ST Remote Processor Control Driver");
> +MODULE_AUTHOR("Ludovic Barre <ludovic.barre@st.com>");
> +MODULE_LICENSE("GPL v2");
> 


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v3 3/6] remoteproc: Supply controller driver for ST's Remote Processors
@ 2015-09-03 19:52     ` Suman Anna
  0 siblings, 0 replies; 25+ messages in thread
From: Suman Anna @ 2015-09-03 19:52 UTC (permalink / raw)
  To: Lee Jones, linux-arm-kernel, linux-kernel
  Cc: kernel, ohad, devicetree, Nathan_Lynch, f.fainelli, Ludovic Barre

Hi Lee,

On 09/02/2015 10:38 AM, Lee Jones wrote:
> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> ---
>  drivers/remoteproc/Kconfig         |   9 ++
>  drivers/remoteproc/Makefile        |   1 +
>  drivers/remoteproc/st_remoteproc.c | 307 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 317 insertions(+)
>  create mode 100644 drivers/remoteproc/st_remoteproc.c
> 
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 28c711f..72e97d7 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -77,4 +77,13 @@ config DA8XX_REMOTEPROC
>  	  It's safe to say n here if you're not interested in multimedia
>  	  offloading.
>  
> +config ST_REMOTEPROC
> +	tristate "ST remoteproc support"
> +	depends on ARCH_STI
> +	select REMOTEPROC
> +	help
> +	  Say y here to support ST's adjunct processors via the remote
> +	  processor framework.
> +	  This can be either built-in or a loadable module.
> +
>  endmenu
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> index 81b04d1..279cb2e 100644
> --- a/drivers/remoteproc/Makefile
> +++ b/drivers/remoteproc/Makefile
> @@ -11,3 +11,4 @@ obj-$(CONFIG_OMAP_REMOTEPROC)		+= omap_remoteproc.o
>  obj-$(CONFIG_STE_MODEM_RPROC)	 	+= ste_modem_rproc.o
>  obj-$(CONFIG_WKUP_M3_RPROC)		+= wkup_m3_rproc.o
>  obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
> +obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
> diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c
> new file mode 100644
> index 0000000..24ae6d3
> --- /dev/null
> +++ b/drivers/remoteproc/st_remoteproc.c
> @@ -0,0 +1,307 @@
> +/*
> + * ST's Remote Processor Control Driver
> + *
> + * Copyright (C) 2015 STMicroelectronics - All Rights Reserved
> + *
> + * Author: Ludovic Barre <ludovic.barre@st.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/remoteproc.h>
> +#include <linux/reset.h>
> +
> +struct st_rproc_config {
> +	bool			sw_reset;
> +	bool			pwr_reset;
> +	u32			bootaddr_mask;
> +};
> +
> +struct st_rproc {
> +	struct st_rproc_config	*config;
> +	struct reset_control	*sw_reset;
> +	struct reset_control	*pwr_reset;
> +	struct clk		*clk;
> +	u32			clk_rate;
> +	struct regmap		*boot_base;
> +	u32			boot_offset;
> +};
> +
> +static int st_rproc_stop(struct rproc *rproc)
> +{
> +	struct st_rproc *ddata = rproc->priv;
> +	int sw_err = 0, pwr_err = 0;
> +
> +	if (ddata->config->sw_reset) {
> +		sw_err = reset_control_assert(ddata->sw_reset);
> +		if (sw_err)
> +			dev_err(&rproc->dev, "Failed to assert S/W Reset\n");
> +	}
> +
> +	if (ddata->config->pwr_reset) {
> +		pwr_err = reset_control_assert(ddata->pwr_reset);
> +		if (pwr_err)
> +			dev_err(&rproc->dev, "Failed to assert Power Reset\n");
> +	}
> +
> +	clk_disable(ddata->clk);
> +
> +	return sw_err ?: pwr_err;
> +}

nit, can you please move st_rproc_stop function after st_rproc_start,
same order as in fw_ops, for better flow.

> +
> +static int st_rproc_start(struct rproc *rproc)
> +{
> +	struct st_rproc *ddata = rproc->priv;
> +	int err;
> +
> +	regmap_update_bits(ddata->boot_base, ddata->boot_offset,
> +			   ddata->config->bootaddr_mask, rproc->bootaddr);
> +
> +	err = clk_enable(ddata->clk);
> +	if (err) {
> +		dev_err(&rproc->dev, "Failed to enable clock\n");
> +		return err;
> +	}
> +
> +	if (ddata->config->sw_reset) {
> +		err = reset_control_deassert(ddata->sw_reset);
> +		if (err) {
> +			dev_err(&rproc->dev, "Failed to deassert S/W Reset\n");
> +			goto sw_reset_fail;
> +		}
> +	}
> +
> +	if (ddata->config->pwr_reset) {
> +		err = reset_control_deassert(ddata->pwr_reset);
> +		if (err) {
> +			dev_err(&rproc->dev, "Failed to deassert Power Reset\n");
> +			goto pwr_reset_fail;
> +		}
> +	}
> +
> +	dev_info(&rproc->dev, "Started from 0x%x\n", rproc->bootaddr);
> +
> +	return 0;
> +
> +
> +pwr_reset_fail:
> +	reset_control_assert(ddata->sw_reset);

Should this be under a check for (ddata->config->sw_reset). It is not
clear from code whether the sw_reset and pwr_reset are exclusive of each
of other or have both.

> +sw_reset_fail:
> +	clk_disable(ddata->clk);
> +
> +	return err;
> +}
> +
> +static struct rproc_ops st_rproc_ops = {
> +	.start		= st_rproc_start,
> +	.stop		= st_rproc_stop,
> +};
> +
> +/*
> + * Fetch state of the processor: 0 is off, 1 is on.
> + */
> +static int st_rproc_state(struct platform_device *pdev)
> +{
> +	struct rproc *rproc = platform_get_drvdata(pdev);
> +	struct st_rproc *ddata = rproc->priv;
> +	int reset_sw = 0, reset_pwr = 0;
> +
> +	if (ddata->config->sw_reset)
> +		reset_sw = reset_control_status(ddata->sw_reset);
> +
> +	if (ddata->config->pwr_reset)
> +		reset_pwr = reset_control_status(ddata->pwr_reset);
> +
> +	if (reset_sw < 0 || reset_pwr < 0)
> +		return -EINVAL;
> +
> +	return !reset_sw && !reset_pwr;
> +}
> +
> +static const struct st_rproc_config st40_rproc_cfg = {
> +	.sw_reset = true,
> +	.pwr_reset = true,
> +	.bootaddr_mask = GENMASK(28, 1),
> +};
> +
> +static const struct st_rproc_config st231_rproc_cfg = {
> +	.sw_reset = true,
> +	.pwr_reset = false,
> +	.bootaddr_mask = GENMASK(31, 6),
> +};
> +
> +static const struct of_device_id st_rproc_match[] = {
> +	{ .compatible = "st,st40-rproc", .data = &st40_rproc_cfg },
> +	{ .compatible = "st,st231-rproc", .data = &st231_rproc_cfg },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, st_rproc_match);
> +
> +static int st_rproc_parse_dt(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct rproc *rproc = platform_get_drvdata(pdev);
> +	struct st_rproc *ddata = rproc->priv;
> +	struct device_node *np = dev->of_node;
> +	struct resource	*mem;
> +	int err;
> +
> +	if (ddata->config->sw_reset) {
> +		ddata->sw_reset = devm_reset_control_get(dev, "sw_reset");
> +		if (IS_ERR(ddata->sw_reset)) {
> +			dev_err(dev, "Failed to get S/W Reset\n");
> +			return PTR_ERR(ddata->sw_reset);
> +		}
> +	}
> +
> +	if (ddata->config->pwr_reset) {
> +		ddata->pwr_reset = devm_reset_control_get(dev, "pwr_reset");
> +		if (IS_ERR(ddata->pwr_reset)) {
> +			dev_err(dev, "Failed to get Power Reset\n");
> +			return PTR_ERR(ddata->pwr_reset);
> +		}
> +	}
> +
> +	ddata->clk = devm_clk_get(dev, NULL);
> +	if (IS_ERR(ddata->clk)) {
> +		dev_err(dev, "Failed to get clock\n");
> +		return PTR_ERR(ddata->clk);
> +	}
> +
> +	err = of_property_read_u32(np, "clock-frequency", &ddata->clk_rate);
> +	if (err) {
> +		dev_err(dev, "failed to get clock frequency\n");
> +		return err;
> +	}
> +
> +	ddata->boot_base = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
> +	if (!ddata->boot_base) {
> +		dev_err(dev, "Boot base not found\n");
> +		return -EINVAL;
> +	}
> +
> +	err = of_property_read_u32_index(np, "st,syscfg", 1,
> +					 &ddata->boot_offset);
> +	if (err) {
> +		dev_err(dev, "Boot offset not found\n");
> +		return -EINVAL;
> +	}
> +
> +	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!mem) {
> +		dev_err(dev, "no rproc memory definition\n");
> +		return -ENXIO;
> +	}
> +
> +	if (!devm_request_mem_region(dev, mem->start,
> +				     resource_size(mem), pdev->name)) {
> +		dev_err(dev, "failed to get memory region resource\n");
> +		return -EBUSY;
> +	}
> +	err = dmam_declare_coherent_memory(dev, mem->start, mem->start,
> +					  resource_size(mem),
> +					  DMA_MEMORY_MAP |
> +					  DMA_MEMORY_EXCLUSIVE);
> +	if (err < 0) {
> +		dev_err(dev, "cannot declare coherent memory: %d\n", err);
> +		return -ENXIO;
> +	}

What kind of memory will this be? If this a carveout memory being
set-aside from DDR, you may want to use a reserved-memory node entry,
with a "memory-region" property added to the rproc device node and use
of_reserved_mem_device_init() and of_reserved_mem_device_release() API,
following the standard semantics of reserved-memory as in
Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt.

Obviously that will need a change in the binding as well.

> +
> +	err = clk_prepare(ddata->clk);
> +	if (err)
> +		dev_err(dev, "failed to get clock\n");
> +
> +	return err;
> +}
> +
> +static int st_rproc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	const struct of_device_id *match;
> +	struct st_rproc *ddata;
> +	struct device_node *np = dev->of_node;
> +	struct rproc *rproc;
> +	int enabled;
> +	int ret;
> +
> +	match = of_match_device((st_rproc_match), dev);
> +	if (!match || !match->data) {
> +		dev_err(dev, "No device match found\n");
> +		return -ENODEV;
> +	}
> +
> +	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
> +	if (!rproc)
> +		return -ENOMEM;
> +
> +	ddata = rproc->priv;
> +	ddata->config = (struct st_rproc_config *)match->data;

I believe Ohad's preference is to explicitly set rproc->has_iommu to false.

> +
> +	platform_set_drvdata(pdev, rproc);
> +
> +	ret = st_rproc_parse_dt(pdev);
> +	if (ret)
> +		goto free_rproc;
> +
> +	enabled = st_rproc_state(pdev);
> +	if (enabled < 0)
> +		goto free_rproc;
> +
> +	if (enabled) {
> +		atomic_inc(&rproc->power);
> +		rproc->state = RPROC_RUNNING;

I am curious about this change, who are you expecting to have booted the
processor before the driver is probed?

> +	} else {
> +		clk_set_rate(ddata->clk, ddata->clk_rate);
> +	}
> +
> +	ret = rproc_add(rproc);
> +	if (ret)
> +		goto free_rproc;
> +
> +	return 0;
> +
> +free_rproc:
> +	rproc_put(rproc);
> +	return ret;
> +}
> +
> +static int st_rproc_remove(struct platform_device *pdev)
> +{
> +	struct rproc *rproc = platform_get_drvdata(pdev);
> +	struct st_rproc *ddata = rproc->priv;
> +
> +	rproc_del(rproc);
> +
> +	clk_disable_unprepare(ddata->clk);
> +
> +	rproc_put(rproc);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver st_rproc_driver = {
> +	.probe = st_rproc_probe,
> +	.remove = st_rproc_remove,
> +	.driver = {
> +		.name = "st-rproc",
> +		.of_match_table = of_match_ptr(st_rproc_match),
> +	},
> +};
> +module_platform_driver(st_rproc_driver);
> +
> +MODULE_DESCRIPTION("ST Remote Processor Control Driver");
> +MODULE_AUTHOR("Ludovic Barre <ludovic.barre@st.com>");
> +MODULE_LICENSE("GPL v2");
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v3 3/6] remoteproc: Supply controller driver for ST's Remote Processors
@ 2015-09-03 19:52     ` Suman Anna
  0 siblings, 0 replies; 25+ messages in thread
From: Suman Anna @ 2015-09-03 19:52 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Lee,

On 09/02/2015 10:38 AM, Lee Jones wrote:
> Signed-off-by: Ludovic Barre <ludovic.barre@st.com>
> Signed-off-by: Lee Jones <lee.jones@linaro.org>
> ---
>  drivers/remoteproc/Kconfig         |   9 ++
>  drivers/remoteproc/Makefile        |   1 +
>  drivers/remoteproc/st_remoteproc.c | 307 +++++++++++++++++++++++++++++++++++++
>  3 files changed, 317 insertions(+)
>  create mode 100644 drivers/remoteproc/st_remoteproc.c
> 
> diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
> index 28c711f..72e97d7 100644
> --- a/drivers/remoteproc/Kconfig
> +++ b/drivers/remoteproc/Kconfig
> @@ -77,4 +77,13 @@ config DA8XX_REMOTEPROC
>  	  It's safe to say n here if you're not interested in multimedia
>  	  offloading.
>  
> +config ST_REMOTEPROC
> +	tristate "ST remoteproc support"
> +	depends on ARCH_STI
> +	select REMOTEPROC
> +	help
> +	  Say y here to support ST's adjunct processors via the remote
> +	  processor framework.
> +	  This can be either built-in or a loadable module.
> +
>  endmenu
> diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
> index 81b04d1..279cb2e 100644
> --- a/drivers/remoteproc/Makefile
> +++ b/drivers/remoteproc/Makefile
> @@ -11,3 +11,4 @@ obj-$(CONFIG_OMAP_REMOTEPROC)		+= omap_remoteproc.o
>  obj-$(CONFIG_STE_MODEM_RPROC)	 	+= ste_modem_rproc.o
>  obj-$(CONFIG_WKUP_M3_RPROC)		+= wkup_m3_rproc.o
>  obj-$(CONFIG_DA8XX_REMOTEPROC)		+= da8xx_remoteproc.o
> +obj-$(CONFIG_ST_REMOTEPROC)		+= st_remoteproc.o
> diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c
> new file mode 100644
> index 0000000..24ae6d3
> --- /dev/null
> +++ b/drivers/remoteproc/st_remoteproc.c
> @@ -0,0 +1,307 @@
> +/*
> + * ST's Remote Processor Control Driver
> + *
> + * Copyright (C) 2015 STMicroelectronics - All Rights Reserved
> + *
> + * Author: Ludovic Barre <ludovic.barre@st.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/remoteproc.h>
> +#include <linux/reset.h>
> +
> +struct st_rproc_config {
> +	bool			sw_reset;
> +	bool			pwr_reset;
> +	u32			bootaddr_mask;
> +};
> +
> +struct st_rproc {
> +	struct st_rproc_config	*config;
> +	struct reset_control	*sw_reset;
> +	struct reset_control	*pwr_reset;
> +	struct clk		*clk;
> +	u32			clk_rate;
> +	struct regmap		*boot_base;
> +	u32			boot_offset;
> +};
> +
> +static int st_rproc_stop(struct rproc *rproc)
> +{
> +	struct st_rproc *ddata = rproc->priv;
> +	int sw_err = 0, pwr_err = 0;
> +
> +	if (ddata->config->sw_reset) {
> +		sw_err = reset_control_assert(ddata->sw_reset);
> +		if (sw_err)
> +			dev_err(&rproc->dev, "Failed to assert S/W Reset\n");
> +	}
> +
> +	if (ddata->config->pwr_reset) {
> +		pwr_err = reset_control_assert(ddata->pwr_reset);
> +		if (pwr_err)
> +			dev_err(&rproc->dev, "Failed to assert Power Reset\n");
> +	}
> +
> +	clk_disable(ddata->clk);
> +
> +	return sw_err ?: pwr_err;
> +}

nit, can you please move st_rproc_stop function after st_rproc_start,
same order as in fw_ops, for better flow.

> +
> +static int st_rproc_start(struct rproc *rproc)
> +{
> +	struct st_rproc *ddata = rproc->priv;
> +	int err;
> +
> +	regmap_update_bits(ddata->boot_base, ddata->boot_offset,
> +			   ddata->config->bootaddr_mask, rproc->bootaddr);
> +
> +	err = clk_enable(ddata->clk);
> +	if (err) {
> +		dev_err(&rproc->dev, "Failed to enable clock\n");
> +		return err;
> +	}
> +
> +	if (ddata->config->sw_reset) {
> +		err = reset_control_deassert(ddata->sw_reset);
> +		if (err) {
> +			dev_err(&rproc->dev, "Failed to deassert S/W Reset\n");
> +			goto sw_reset_fail;
> +		}
> +	}
> +
> +	if (ddata->config->pwr_reset) {
> +		err = reset_control_deassert(ddata->pwr_reset);
> +		if (err) {
> +			dev_err(&rproc->dev, "Failed to deassert Power Reset\n");
> +			goto pwr_reset_fail;
> +		}
> +	}
> +
> +	dev_info(&rproc->dev, "Started from 0x%x\n", rproc->bootaddr);
> +
> +	return 0;
> +
> +
> +pwr_reset_fail:
> +	reset_control_assert(ddata->sw_reset);

Should this be under a check for (ddata->config->sw_reset). It is not
clear from code whether the sw_reset and pwr_reset are exclusive of each
of other or have both.

> +sw_reset_fail:
> +	clk_disable(ddata->clk);
> +
> +	return err;
> +}
> +
> +static struct rproc_ops st_rproc_ops = {
> +	.start		= st_rproc_start,
> +	.stop		= st_rproc_stop,
> +};
> +
> +/*
> + * Fetch state of the processor: 0 is off, 1 is on.
> + */
> +static int st_rproc_state(struct platform_device *pdev)
> +{
> +	struct rproc *rproc = platform_get_drvdata(pdev);
> +	struct st_rproc *ddata = rproc->priv;
> +	int reset_sw = 0, reset_pwr = 0;
> +
> +	if (ddata->config->sw_reset)
> +		reset_sw = reset_control_status(ddata->sw_reset);
> +
> +	if (ddata->config->pwr_reset)
> +		reset_pwr = reset_control_status(ddata->pwr_reset);
> +
> +	if (reset_sw < 0 || reset_pwr < 0)
> +		return -EINVAL;
> +
> +	return !reset_sw && !reset_pwr;
> +}
> +
> +static const struct st_rproc_config st40_rproc_cfg = {
> +	.sw_reset = true,
> +	.pwr_reset = true,
> +	.bootaddr_mask = GENMASK(28, 1),
> +};
> +
> +static const struct st_rproc_config st231_rproc_cfg = {
> +	.sw_reset = true,
> +	.pwr_reset = false,
> +	.bootaddr_mask = GENMASK(31, 6),
> +};
> +
> +static const struct of_device_id st_rproc_match[] = {
> +	{ .compatible = "st,st40-rproc", .data = &st40_rproc_cfg },
> +	{ .compatible = "st,st231-rproc", .data = &st231_rproc_cfg },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, st_rproc_match);
> +
> +static int st_rproc_parse_dt(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct rproc *rproc = platform_get_drvdata(pdev);
> +	struct st_rproc *ddata = rproc->priv;
> +	struct device_node *np = dev->of_node;
> +	struct resource	*mem;
> +	int err;
> +
> +	if (ddata->config->sw_reset) {
> +		ddata->sw_reset = devm_reset_control_get(dev, "sw_reset");
> +		if (IS_ERR(ddata->sw_reset)) {
> +			dev_err(dev, "Failed to get S/W Reset\n");
> +			return PTR_ERR(ddata->sw_reset);
> +		}
> +	}
> +
> +	if (ddata->config->pwr_reset) {
> +		ddata->pwr_reset = devm_reset_control_get(dev, "pwr_reset");
> +		if (IS_ERR(ddata->pwr_reset)) {
> +			dev_err(dev, "Failed to get Power Reset\n");
> +			return PTR_ERR(ddata->pwr_reset);
> +		}
> +	}
> +
> +	ddata->clk = devm_clk_get(dev, NULL);
> +	if (IS_ERR(ddata->clk)) {
> +		dev_err(dev, "Failed to get clock\n");
> +		return PTR_ERR(ddata->clk);
> +	}
> +
> +	err = of_property_read_u32(np, "clock-frequency", &ddata->clk_rate);
> +	if (err) {
> +		dev_err(dev, "failed to get clock frequency\n");
> +		return err;
> +	}
> +
> +	ddata->boot_base = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
> +	if (!ddata->boot_base) {
> +		dev_err(dev, "Boot base not found\n");
> +		return -EINVAL;
> +	}
> +
> +	err = of_property_read_u32_index(np, "st,syscfg", 1,
> +					 &ddata->boot_offset);
> +	if (err) {
> +		dev_err(dev, "Boot offset not found\n");
> +		return -EINVAL;
> +	}
> +
> +	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!mem) {
> +		dev_err(dev, "no rproc memory definition\n");
> +		return -ENXIO;
> +	}
> +
> +	if (!devm_request_mem_region(dev, mem->start,
> +				     resource_size(mem), pdev->name)) {
> +		dev_err(dev, "failed to get memory region resource\n");
> +		return -EBUSY;
> +	}
> +	err = dmam_declare_coherent_memory(dev, mem->start, mem->start,
> +					  resource_size(mem),
> +					  DMA_MEMORY_MAP |
> +					  DMA_MEMORY_EXCLUSIVE);
> +	if (err < 0) {
> +		dev_err(dev, "cannot declare coherent memory: %d\n", err);
> +		return -ENXIO;
> +	}

What kind of memory will this be? If this a carveout memory being
set-aside from DDR, you may want to use a reserved-memory node entry,
with a "memory-region" property added to the rproc device node and use
of_reserved_mem_device_init() and of_reserved_mem_device_release() API,
following the standard semantics of reserved-memory as in
Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt.

Obviously that will need a change in the binding as well.

> +
> +	err = clk_prepare(ddata->clk);
> +	if (err)
> +		dev_err(dev, "failed to get clock\n");
> +
> +	return err;
> +}
> +
> +static int st_rproc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	const struct of_device_id *match;
> +	struct st_rproc *ddata;
> +	struct device_node *np = dev->of_node;
> +	struct rproc *rproc;
> +	int enabled;
> +	int ret;
> +
> +	match = of_match_device((st_rproc_match), dev);
> +	if (!match || !match->data) {
> +		dev_err(dev, "No device match found\n");
> +		return -ENODEV;
> +	}
> +
> +	rproc = rproc_alloc(dev, np->name, &st_rproc_ops, NULL, sizeof(*ddata));
> +	if (!rproc)
> +		return -ENOMEM;
> +
> +	ddata = rproc->priv;
> +	ddata->config = (struct st_rproc_config *)match->data;

I believe Ohad's preference is to explicitly set rproc->has_iommu to false.

> +
> +	platform_set_drvdata(pdev, rproc);
> +
> +	ret = st_rproc_parse_dt(pdev);
> +	if (ret)
> +		goto free_rproc;
> +
> +	enabled = st_rproc_state(pdev);
> +	if (enabled < 0)
> +		goto free_rproc;
> +
> +	if (enabled) {
> +		atomic_inc(&rproc->power);
> +		rproc->state = RPROC_RUNNING;

I am curious about this change, who are you expecting to have booted the
processor before the driver is probed?

> +	} else {
> +		clk_set_rate(ddata->clk, ddata->clk_rate);
> +	}
> +
> +	ret = rproc_add(rproc);
> +	if (ret)
> +		goto free_rproc;
> +
> +	return 0;
> +
> +free_rproc:
> +	rproc_put(rproc);
> +	return ret;
> +}
> +
> +static int st_rproc_remove(struct platform_device *pdev)
> +{
> +	struct rproc *rproc = platform_get_drvdata(pdev);
> +	struct st_rproc *ddata = rproc->priv;
> +
> +	rproc_del(rproc);
> +
> +	clk_disable_unprepare(ddata->clk);
> +
> +	rproc_put(rproc);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver st_rproc_driver = {
> +	.probe = st_rproc_probe,
> +	.remove = st_rproc_remove,
> +	.driver = {
> +		.name = "st-rproc",
> +		.of_match_table = of_match_ptr(st_rproc_match),
> +	},
> +};
> +module_platform_driver(st_rproc_driver);
> +
> +MODULE_DESCRIPTION("ST Remote Processor Control Driver");
> +MODULE_AUTHOR("Ludovic Barre <ludovic.barre@st.com>");
> +MODULE_LICENSE("GPL v2");
> 

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2015-09-03 19:53 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-02 15:38 [PATCH v3 0/6] remoteproc: Add driver for STMicroelectronics platforms Lee Jones
2015-09-02 15:38 ` Lee Jones
2015-09-02 15:38 ` Lee Jones
2015-09-02 15:38 ` [PATCH v3 1/6] ARM: STi: Add DT defines for co-processor reset lines Lee Jones
2015-09-02 15:38   ` Lee Jones
2015-09-03 16:31   ` [STLinux Kernel] " Peter Griffin
2015-09-03 16:31     ` Peter Griffin
2015-09-02 15:38 ` [PATCH v3 2/6] remoteproc: dt: Provide bindings for ST's Remote Processor Controller driver Lee Jones
2015-09-02 15:38   ` Lee Jones
2015-09-02 15:38 ` [PATCH v3 3/6] remoteproc: Supply controller driver for ST's Remote Processors Lee Jones
2015-09-02 15:38   ` Lee Jones
2015-09-02 15:38   ` Lee Jones
2015-09-03 19:52   ` Suman Anna
2015-09-03 19:52     ` Suman Anna
2015-09-03 19:52     ` Suman Anna
2015-09-02 15:38 ` [PATCH v3 4/6] remoteproc: debugfs: Add ability to boot remote processor using debugfs Lee Jones
2015-09-02 15:38   ` Lee Jones
2015-09-02 15:38   ` Lee Jones
2015-09-02 15:38 ` [PATCH v3 5/6] ARM: STiH407: Add nodes for RemoteProc Lee Jones
2015-09-02 15:38   ` Lee Jones
2015-09-03 15:26   ` [STLinux Kernel] " Peter Griffin
2015-09-03 15:26     ` Peter Griffin
2015-09-03 15:26     ` Peter Griffin
2015-09-02 15:38 ` [PATCH v3 6/6] MAINTAINERS: Add ST's Remote Processor Driver to ARM/STI ARCHITECTURE Lee Jones
2015-09-02 15:38   ` Lee Jones

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.