devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Patch v3 0/8] Qualcomm SCM Rework
@ 2016-05-04 22:50 Andy Gross
  2016-05-04 22:50 ` [Patch v3 1/8] dt/bindings: firmware: Add Qualcomm SCM binding Andy Gross
                   ` (7 more replies)
  0 siblings, 8 replies; 12+ messages in thread
From: Andy Gross @ 2016-05-04 22:50 UTC (permalink / raw)
  To: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Stephen Boyd,
	Bjorn Andersson, jilai wang, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Andy Gross

The following set of patches does a bit of rework on the existing
Qualcomm SCM firmware.  The first couple of patches deals with turning
the current SCM into a platform driver.  The next couple are cleanups
that make adding the 64 support a little easier.  I added in a patch to
convert the scm-32 to use DMA streaming APIs.

I took Kumar's 64 bit support patch and modified it to use the arm_smccc
calls.  This simplified things quite a bit.

Lastly, there are a few DT patches to add the firmware node for a couple of the
supported platforms.

Changes from v2:
  * Added use of streaming DMA APIs for scm-32.
  * Changed DT binding to simplify compats.
  * Removed Kconfig.platform change that selected QCOM_SCM for ARM64
  * Fixed misc comments
  * Changed init function to populate the device differently.
  * Fixed missing of_node_put

Changes from v1:
  * Changed binding to reflect proper firmware node usage
  * Added arch_initcall to populate the firmware device, if present
  * Fixed various review comments
  * Removed extraneous includes from SCM 64 file.

Andy Gross (7):
  dt/bindings: firmware: Add Qualcomm SCM binding
  firmware: qcom: scm: Convert SCM to platform driver
  firmware: qcom: scm: Use atomic SCM for cold boot
  firmware: qcom: scm: Generalize shared error map
  firmware: qcom: scm: Convert to streaming DMA APIS
  dts: qcom: apq8084: Add SCM firmware node
  arm64: dts: msm8916: Add SCM firmware node

Kumar Gala (1):
  firmware: qcom: scm: Add support for ARM64 SoCs

 .../devicetree/bindings/firmware/qcom,scm.txt      |  26 +++
 arch/arm/boot/dts/qcom-apq8084.dtsi                |   8 +
 arch/arm64/boot/dts/qcom/msm8916.dtsi              |   8 +
 drivers/firmware/qcom_scm-32.c                     | 234 +++++++++------------
 drivers/firmware/qcom_scm-64.c                     | 208 +++++++++++++++++-
 drivers/firmware/qcom_scm.c                        | 169 ++++++++++++++-
 drivers/firmware/qcom_scm.h                        |  31 ++-
 7 files changed, 522 insertions(+), 162 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/firmware/qcom,scm.txt

-- 
1.9.1

--
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] 12+ messages in thread

* [Patch v3 1/8] dt/bindings: firmware: Add Qualcomm SCM binding
  2016-05-04 22:50 [Patch v3 0/8] Qualcomm SCM Rework Andy Gross
@ 2016-05-04 22:50 ` Andy Gross
  2016-05-05 22:17   ` Rob Herring
  2016-05-04 22:50 ` [Patch v3 2/8] firmware: qcom: scm: Convert SCM to platform driver Andy Gross
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 12+ messages in thread
From: Andy Gross @ 2016-05-04 22:50 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: linux-arm-kernel, linux-kernel, Stephen Boyd, Bjorn Andersson,
	jilai wang, devicetree, Andy Gross

This patch adds the device tree support for the Qualcomm SCM firmware.

Signed-off-by: Andy Gross <andy.gross@linaro.org>
---
 .../devicetree/bindings/firmware/qcom,scm.txt      | 26 ++++++++++++++++++++++
 1 file changed, 26 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/firmware/qcom,scm.txt

diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.txt b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
new file mode 100644
index 0000000..ee7cd12
--- /dev/null
+++ b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
@@ -0,0 +1,26 @@
+QCOM Secure Channel Manager (SCM)
+
+Qualcomm processors include an interface to communicate to the secure firmware.
+This interface allows for clients to request different types of actions.  These
+can include CPU power up/down, HDCP requests, loading of firmware, and other
+assorted actions.
+
+Required properties:
+- compatible: must contain one of the following:
+ * "qcom,scm-a-family" for A family Qualcomm processors (APQ8064, MSM8960, etc)
+ * "qcom,scm" for B family and later processors (MSM8916, APQ8084, MSM8974, etc)
+- clocks: One to three clocks may be required based on compatible.
+ * Only core clock required for "qcom,scm-apq8064"
+ * Core, iface, and bus clocks required for "qcom,scm"
+- clock-names: Must contain "core" for the core clock, "iface" for the interface
+  clock and "bus" for the bus clock per the requirements of the compatible.
+
+Example for MSM8916:
+
+	firmware {
+		scm {
+			compatible = "qcom,scm";
+			clocks = <&gcc GCC_CRYPTO_CLK> , <&gcc GCC_CRYPTO_AXI_CLK>, <&gcc GCC_CRYPTO_AHB_CLK>;
+			clock-names = "core", "bus", "iface";
+		};
+	};
-- 
1.9.1

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

* [Patch v3 2/8] firmware: qcom: scm: Convert SCM to platform driver
  2016-05-04 22:50 [Patch v3 0/8] Qualcomm SCM Rework Andy Gross
  2016-05-04 22:50 ` [Patch v3 1/8] dt/bindings: firmware: Add Qualcomm SCM binding Andy Gross
@ 2016-05-04 22:50 ` Andy Gross
  2016-05-04 22:50 ` [Patch v3 3/8] firmware: qcom: scm: Use atomic SCM for cold boot Andy Gross
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Andy Gross @ 2016-05-04 22:50 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: devicetree, Stephen Boyd, linux-kernel, Bjorn Andersson,
	Andy Gross, jilai wang, linux-arm-kernel

This patch converts the Qualcomm SCM firmware driver into a platform
driver.

Signed-off-by: Andy Gross <andy.gross@linaro.org>
---
 drivers/firmware/qcom_scm.c | 163 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 154 insertions(+), 9 deletions(-)

diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
index 45c008d..63a2bfa 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom_scm.c
@@ -10,19 +10,61 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
  */
-
+#include <linux/platform_device.h>
+#include <linux/module.h>
 #include <linux/cpumask.h>
 #include <linux/export.h>
 #include <linux/types.h>
 #include <linux/qcom_scm.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>
 
 #include "qcom_scm.h"
 
+struct qcom_scm {
+	struct device *dev;
+	struct clk *core_clk;
+	struct clk *iface_clk;
+	struct clk *bus_clk;
+};
+
+static struct qcom_scm *__scm;
+
+static int qcom_scm_clk_enable(void)
+{
+	int ret;
+
+	ret = clk_prepare_enable(__scm->core_clk);
+	if (ret)
+		goto bail;
+
+	ret = clk_prepare_enable(__scm->iface_clk);
+	if (ret)
+		goto disable_core;
+
+	ret = clk_prepare_enable(__scm->bus_clk);
+	if (ret)
+		goto disable_iface;
+
+	return 0;
+
+disable_iface:
+	clk_disable_unprepare(__scm->iface_clk);
+disable_core:
+	clk_disable_unprepare(__scm->core_clk);
+bail:
+	return ret;
+}
+
+static void qcom_scm_clk_disable(void)
+{
+	clk_disable_unprepare(__scm->core_clk);
+	clk_disable_unprepare(__scm->iface_clk);
+	clk_disable_unprepare(__scm->bus_clk);
+}
+
 /**
  * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
  * @entry: Entry point function for the cpus
@@ -72,12 +114,17 @@ EXPORT_SYMBOL(qcom_scm_cpu_power_down);
  */
 bool qcom_scm_hdcp_available(void)
 {
-	int ret;
+	int ret = qcom_scm_clk_enable();
+
+	if (ret)
+		return ret;
 
 	ret = __qcom_scm_is_call_available(QCOM_SCM_SVC_HDCP,
-		QCOM_SCM_CMD_HDCP);
+						QCOM_SCM_CMD_HDCP);
+
+	qcom_scm_clk_disable();
 
-	return (ret > 0) ? true : false;
+	return ret > 0 ? true : false;
 }
 EXPORT_SYMBOL(qcom_scm_hdcp_available);
 
@@ -91,6 +138,104 @@ EXPORT_SYMBOL(qcom_scm_hdcp_available);
  */
 int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
 {
-	return __qcom_scm_hdcp_req(req, req_cnt, resp);
+	int ret = qcom_scm_clk_enable();
+
+	if (ret)
+		return ret;
+
+	ret = __qcom_scm_hdcp_req(req, req_cnt, resp);
+	qcom_scm_clk_disable();
+	return ret;
 }
 EXPORT_SYMBOL(qcom_scm_hdcp_req);
+
+static int qcom_scm_probe(struct platform_device *pdev)
+{
+	struct qcom_scm *scm;
+	int ret;
+
+	scm = devm_kzalloc(&pdev->dev, sizeof(*scm), GFP_KERNEL);
+	if (!scm)
+		return -ENOMEM;
+
+	scm->core_clk = devm_clk_get(&pdev->dev, "core");
+	if (IS_ERR(scm->core_clk)) {
+		if (PTR_ERR(scm->core_clk) != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "failed to acquire core clk\n");
+		return PTR_ERR(scm->core_clk);
+	}
+
+	if (!of_device_is_compatible(pdev->dev.of_node, "qcom,scm-apq8064")) {
+		scm->iface_clk = devm_clk_get(&pdev->dev, "iface");
+		if (IS_ERR(scm->iface_clk)) {
+			if (PTR_ERR(scm->iface_clk) != -EPROBE_DEFER)
+				dev_err(&pdev->dev, "failed to acquire iface clk\n");
+			return PTR_ERR(scm->iface_clk);
+		}
+
+		scm->bus_clk = devm_clk_get(&pdev->dev, "bus");
+		if (IS_ERR(scm->bus_clk)) {
+			if (PTR_ERR(scm->bus_clk) != -EPROBE_DEFER)
+				dev_err(&pdev->dev, "failed to acquire bus clk\n");
+			return PTR_ERR(scm->bus_clk);
+		}
+	}
+
+	/* vote for max clk rate for highest performance */
+	ret = clk_set_rate(scm->core_clk, INT_MAX);
+	if (ret)
+		return ret;
+
+	__scm = scm;
+	__scm->dev = &pdev->dev;
+
+	return 0;
+}
+
+static const struct of_device_id qcom_scm_dt_match[] = {
+	{ .compatible = "qcom,scm-a-family",},
+	{ .compatible = "qcom,scm",},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, qcom_scm_dt_match);
+
+static struct platform_driver qcom_scm_driver = {
+	.driver = {
+		.name	= "qcom_scm",
+		.of_match_table = qcom_scm_dt_match,
+	},
+	.probe = qcom_scm_probe,
+};
+
+static int __init qcom_scm_init(void)
+{
+	struct device_node *np, *parent;
+	int ret;
+
+	np = of_find_matching_node_and_match(NULL, qcom_scm_dt_match, NULL);
+
+	if (!np)
+		return -ENODEV;
+
+	parent = of_get_next_parent(np);
+	ret = of_platform_populate(parent, qcom_scm_dt_match, NULL, NULL);
+
+	of_node_put(parent);
+
+	if (ret)
+		return ret;
+
+	return platform_driver_register(&qcom_scm_driver);
+}
+
+arch_initcall(qcom_scm_init);
+
+static void __exit qcom_scm_exit(void)
+{
+	platform_driver_unregister(&qcom_scm_driver);
+}
+module_exit(qcom_scm_exit);
+
+MODULE_DESCRIPTION("Qualcomm SCM driver");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

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

* [Patch v3 3/8] firmware: qcom: scm: Use atomic SCM for cold boot
  2016-05-04 22:50 [Patch v3 0/8] Qualcomm SCM Rework Andy Gross
  2016-05-04 22:50 ` [Patch v3 1/8] dt/bindings: firmware: Add Qualcomm SCM binding Andy Gross
  2016-05-04 22:50 ` [Patch v3 2/8] firmware: qcom: scm: Convert SCM to platform driver Andy Gross
@ 2016-05-04 22:50 ` Andy Gross
  2016-05-04 22:50 ` [Patch v3 4/8] firmware: qcom: scm: Generalize shared error map Andy Gross
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Andy Gross @ 2016-05-04 22:50 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: devicetree, Stephen Boyd, linux-kernel, Bjorn Andersson,
	Andy Gross, jilai wang, linux-arm-kernel

This patch changes the cold_set_boot_addr function to use atomic SCM
calls.  cold_set_boot_addr required adding qcom_scm_call_atomic2 to
support the two arguments going to the smc call.  Using atomic removes
the need for memory allocation and instead places all arguments in
registers.

Signed-off-by: Andy Gross <andy.gross@linaro.org>
---
 drivers/firmware/qcom_scm-32.c | 63 ++++++++++++++++++++++++++++++------------
 1 file changed, 45 insertions(+), 18 deletions(-)

diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c
index 0883292..5be6a12 100644
--- a/drivers/firmware/qcom_scm-32.c
+++ b/drivers/firmware/qcom_scm-32.c
@@ -342,6 +342,41 @@ static s32 qcom_scm_call_atomic1(u32 svc, u32 cmd, u32 arg1)
 	return r0;
 }
 
+/**
+ * qcom_scm_call_atomic2() - Send an atomic SCM command with two arguments
+ * @svc_id:	service identifier
+ * @cmd_id:	command identifier
+ * @arg1:	first argument
+ * @arg2:	second argument
+ *
+ * This shall only be used with commands that are guaranteed to be
+ * uninterruptable, atomic and SMP safe.
+ */
+static s32 qcom_scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2)
+{
+	int context_id;
+
+	register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 2);
+	register u32 r1 asm("r1") = (u32)&context_id;
+	register u32 r2 asm("r2") = arg1;
+	register u32 r3 asm("r3") = arg2;
+
+	asm volatile(
+			__asmeq("%0", "r0")
+			__asmeq("%1", "r0")
+			__asmeq("%2", "r1")
+			__asmeq("%3", "r2")
+			__asmeq("%4", "r3")
+#ifdef REQUIRES_SEC
+			".arch_extension sec\n"
+#endif
+			"smc    #0      @ switch to secure world\n"
+			: "=r" (r0)
+			: "r" (r0), "r" (r1), "r" (r2), "r" (r3)
+			);
+	return r0;
+}
+
 u32 qcom_scm_get_version(void)
 {
 	int context_id;
@@ -378,22 +413,6 @@ u32 qcom_scm_get_version(void)
 }
 EXPORT_SYMBOL(qcom_scm_get_version);
 
-/*
- * Set the cold/warm boot address for one of the CPU cores.
- */
-static int qcom_scm_set_boot_addr(u32 addr, int flags)
-{
-	struct {
-		__le32 flags;
-		__le32 addr;
-	} cmd;
-
-	cmd.addr = cpu_to_le32(addr);
-	cmd.flags = cpu_to_le32(flags);
-	return qcom_scm_call(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_ADDR,
-			&cmd, sizeof(cmd), NULL, 0);
-}
-
 /**
  * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
  * @entry: Entry point function for the cpus
@@ -423,7 +442,8 @@ int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
 			set_cpu_present(cpu, false);
 	}
 
-	return qcom_scm_set_boot_addr(virt_to_phys(entry), flags);
+	return qcom_scm_call_atomic2(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_ADDR,
+				    flags, virt_to_phys(entry));
 }
 
 /**
@@ -439,6 +459,10 @@ int __qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
 	int ret;
 	int flags = 0;
 	int cpu;
+	struct {
+		__le32 flags;
+		__le32 addr;
+	} cmd;
 
 	/*
 	 * Reassign only if we are switching from hotplug entry point
@@ -454,7 +478,10 @@ int __qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
 	if (!flags)
 		return 0;
 
-	ret = qcom_scm_set_boot_addr(virt_to_phys(entry), flags);
+	cmd.addr = cpu_to_le32(virt_to_phys(entry));
+	cmd.flags = cpu_to_le32(flags);
+	ret = qcom_scm_call(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_ADDR,
+			    &cmd, sizeof(cmd), NULL, 0);
 	if (!ret) {
 		for_each_cpu(cpu, cpus)
 			qcom_scm_wb[cpu].entry = entry;
-- 
1.9.1

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

* [Patch v3 4/8] firmware: qcom: scm: Generalize shared error map
  2016-05-04 22:50 [Patch v3 0/8] Qualcomm SCM Rework Andy Gross
                   ` (2 preceding siblings ...)
  2016-05-04 22:50 ` [Patch v3 3/8] firmware: qcom: scm: Use atomic SCM for cold boot Andy Gross
@ 2016-05-04 22:50 ` Andy Gross
  2016-05-04 22:50 ` [Patch v3 5/8] firmware: qcom: scm: Convert to streaming DMA APIS Andy Gross
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Andy Gross @ 2016-05-04 22:50 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: linux-arm-kernel, linux-kernel, Stephen Boyd, Bjorn Andersson,
	jilai wang, devicetree, Andy Gross, Andy Gross

This patch moves the qcom_scm_remap_error function to the include file
where can be used by both the 32 and 64 bit versions of the code.

Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Andy Gross <agross@codeaurora.org>
Signed-off-by: Andy Gross <andy.gross@linaro.org>
---
 drivers/firmware/qcom_scm-32.c | 17 -----------------
 drivers/firmware/qcom_scm.h    | 16 ++++++++++++++++
 2 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c
index 5be6a12..4388d13 100644
--- a/drivers/firmware/qcom_scm-32.c
+++ b/drivers/firmware/qcom_scm-32.c
@@ -168,23 +168,6 @@ static inline void *qcom_scm_get_response_buffer(const struct qcom_scm_response
 	return (void *)rsp + le32_to_cpu(rsp->buf_offset);
 }
 
-static int qcom_scm_remap_error(int err)
-{
-	pr_err("qcom_scm_call failed with error code %d\n", err);
-	switch (err) {
-	case QCOM_SCM_ERROR:
-		return -EIO;
-	case QCOM_SCM_EINVAL_ADDR:
-	case QCOM_SCM_EINVAL_ARG:
-		return -EINVAL;
-	case QCOM_SCM_EOPNOTSUPP:
-		return -EOPNOTSUPP;
-	case QCOM_SCM_ENOMEM:
-		return -ENOMEM;
-	}
-	return -EINVAL;
-}
-
 static u32 smc(u32 cmd_addr)
 {
 	int context_id;
diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h
index 2cce75c..7dcc733 100644
--- a/drivers/firmware/qcom_scm.h
+++ b/drivers/firmware/qcom_scm.h
@@ -44,4 +44,20 @@ extern int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
 #define QCOM_SCM_ERROR		-1
 #define QCOM_SCM_INTERRUPTED	1
 
+static inline int qcom_scm_remap_error(int err)
+{
+	switch (err) {
+	case QCOM_SCM_ERROR:
+		return -EIO;
+	case QCOM_SCM_EINVAL_ADDR:
+	case QCOM_SCM_EINVAL_ARG:
+		return -EINVAL;
+	case QCOM_SCM_EOPNOTSUPP:
+		return -EOPNOTSUPP;
+	case QCOM_SCM_ENOMEM:
+		return -ENOMEM;
+	}
+	return -EINVAL;
+}
+
 #endif
-- 
1.9.1

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

* [Patch v3 5/8] firmware: qcom: scm: Convert to streaming DMA APIS
  2016-05-04 22:50 [Patch v3 0/8] Qualcomm SCM Rework Andy Gross
                   ` (3 preceding siblings ...)
  2016-05-04 22:50 ` [Patch v3 4/8] firmware: qcom: scm: Generalize shared error map Andy Gross
@ 2016-05-04 22:50 ` Andy Gross
  2016-05-09  5:18   ` Sricharan
       [not found] ` <1462402245-18295-1-git-send-email-andy.gross-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 12+ messages in thread
From: Andy Gross @ 2016-05-04 22:50 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: linux-arm-kernel, linux-kernel, Stephen Boyd, Bjorn Andersson,
	jilai wang, devicetree, Andy Gross

This patch converts the Qualcomm SCM driver to use the streaming DMA APIs
for communication buffers.

Signed-off-by: Andy Gross <andy.gross@linaro.org>
---
 drivers/firmware/qcom_scm-32.c | 152 +++++++++++++----------------------------
 drivers/firmware/qcom_scm.c    |   6 +-
 drivers/firmware/qcom_scm.h    |  10 +--
 3 files changed, 58 insertions(+), 110 deletions(-)

diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c
index 4388d13..3e71aec 100644
--- a/drivers/firmware/qcom_scm-32.c
+++ b/drivers/firmware/qcom_scm-32.c
@@ -23,8 +23,7 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/qcom_scm.h>
-
-#include <asm/cacheflush.h>
+#include <linux/dma-mapping.h>
 
 #include "qcom_scm.h"
 
@@ -97,44 +96,6 @@ struct qcom_scm_response {
 };
 
 /**
- * alloc_qcom_scm_command() - Allocate an SCM command
- * @cmd_size: size of the command buffer
- * @resp_size: size of the response buffer
- *
- * Allocate an SCM command, including enough room for the command
- * and response headers as well as the command and response buffers.
- *
- * Returns a valid &qcom_scm_command on success or %NULL if the allocation fails.
- */
-static struct qcom_scm_command *alloc_qcom_scm_command(size_t cmd_size, size_t resp_size)
-{
-	struct qcom_scm_command *cmd;
-	size_t len = sizeof(*cmd) + sizeof(struct qcom_scm_response) + cmd_size +
-		resp_size;
-	u32 offset;
-
-	cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
-	if (cmd) {
-		cmd->len = cpu_to_le32(len);
-		offset = offsetof(struct qcom_scm_command, buf);
-		cmd->buf_offset = cpu_to_le32(offset);
-		cmd->resp_hdr_offset = cpu_to_le32(offset + cmd_size);
-	}
-	return cmd;
-}
-
-/**
- * free_qcom_scm_command() - Free an SCM command
- * @cmd: command to free
- *
- * Free an SCM command.
- */
-static inline void free_qcom_scm_command(struct qcom_scm_command *cmd)
-{
-	kfree(cmd);
-}
-
-/**
  * qcom_scm_command_to_response() - Get a pointer to a qcom_scm_response
  * @cmd: command
  *
@@ -168,7 +129,7 @@ static inline void *qcom_scm_get_response_buffer(const struct qcom_scm_response
 	return (void *)rsp + le32_to_cpu(rsp->buf_offset);
 }
 
-static u32 smc(u32 cmd_addr)
+static u32 smc(dma_addr_t cmd_addr)
 {
 	int context_id;
 	register u32 r0 asm("r0") = 1;
@@ -192,51 +153,15 @@ static u32 smc(u32 cmd_addr)
 	return r0;
 }
 
-static int __qcom_scm_call(const struct qcom_scm_command *cmd)
-{
-	int ret;
-	u32 cmd_addr = virt_to_phys(cmd);
-
-	/*
-	 * Flush the command buffer so that the secure world sees
-	 * the correct data.
-	 */
-	secure_flush_area(cmd, cmd->len);
-
-	ret = smc(cmd_addr);
-	if (ret < 0)
-		ret = qcom_scm_remap_error(ret);
-
-	return ret;
-}
-
-static void qcom_scm_inv_range(unsigned long start, unsigned long end)
-{
-	u32 cacheline_size, ctr;
-
-	asm volatile("mrc p15, 0, %0, c0, c0, 1" : "=r" (ctr));
-	cacheline_size = 4 << ((ctr >> 16) & 0xf);
-
-	start = round_down(start, cacheline_size);
-	end = round_up(end, cacheline_size);
-	outer_inv_range(start, end);
-	while (start < end) {
-		asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
-		     : "memory");
-		start += cacheline_size;
-	}
-	dsb();
-	isb();
-}
-
 /**
  * qcom_scm_call() - Send an SCM command
- * @svc_id: service identifier
- * @cmd_id: command identifier
- * @cmd_buf: command buffer
- * @cmd_len: length of the command buffer
- * @resp_buf: response buffer
- * @resp_len: length of the response buffer
+ * @dev:	struct device
+ * @svc_id:	service identifier
+ * @cmd_id:	command identifier
+ * @cmd_buf:	command buffer
+ * @cmd_len:	length of the command buffer
+ * @resp_buf:	response buffer
+ * @resp_len:	length of the response buffer
  *
  * Sends a command to the SCM and waits for the command to finish processing.
  *
@@ -247,42 +172,60 @@ static void qcom_scm_inv_range(unsigned long start, unsigned long end)
  * and response buffers is taken care of by qcom_scm_call; however, callers are
  * responsible for any other cached buffers passed over to the secure world.
  */
-static int qcom_scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf,
-			size_t cmd_len, void *resp_buf, size_t resp_len)
+static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
+			 const void *cmd_buf, size_t cmd_len, void *resp_buf,
+			 size_t resp_len)
 {
 	int ret;
 	struct qcom_scm_command *cmd;
 	struct qcom_scm_response *rsp;
-	unsigned long start, end;
+	size_t alloc_len = sizeof(*cmd) + sizeof(struct qcom_scm_response) +
+			   cmd_len + resp_len;
+	dma_addr_t cmd_phys;
+	u32 offset;
 
-	cmd = alloc_qcom_scm_command(cmd_len, resp_len);
+	cmd = kzalloc(PAGE_ALIGN(alloc_len), GFP_KERNEL);
 	if (!cmd)
 		return -ENOMEM;
 
+	cmd->len = cpu_to_le32(alloc_len);
+	offset = offsetof(struct qcom_scm_command, buf);
+	cmd->buf_offset = cpu_to_le32(offset);
+	cmd->resp_hdr_offset = cpu_to_le32(offset + cmd_len);
+
 	cmd->id = cpu_to_le32((svc_id << 10) | cmd_id);
 	if (cmd_buf)
 		memcpy(qcom_scm_get_command_buffer(cmd), cmd_buf, cmd_len);
 
+	cmd_phys = dma_map_single(dev, cmd, alloc_len, DMA_TO_DEVICE);
+	if (dma_mapping_error(dev, cmd_phys)) {
+		kfree(cmd);
+		return -ENOMEM;
+	}
+
 	mutex_lock(&qcom_scm_lock);
-	ret = __qcom_scm_call(cmd);
+	ret = smc(cmd_phys);
+	if (ret < 0)
+		ret = qcom_scm_remap_error(ret);
 	mutex_unlock(&qcom_scm_lock);
 	if (ret)
 		goto out;
 
 	rsp = qcom_scm_command_to_response(cmd);
-	start = (unsigned long)rsp;
 
 	do {
-		qcom_scm_inv_range(start, start + sizeof(*rsp));
+		dma_sync_single_for_cpu(dev, cmd_phys + cmd_len + offset,
+					sizeof(*rsp), DMA_FROM_DEVICE);
 	} while (!rsp->is_complete);
 
-	end = (unsigned long)qcom_scm_get_response_buffer(rsp) + resp_len;
-	qcom_scm_inv_range(start, end);
-
-	if (resp_buf)
+	if (resp_buf) {
+		dma_sync_single_for_cpu(dev, cmd_phys + alloc_len - resp_len,
+					resp_len, DMA_FROM_DEVICE);
 		memcpy(resp_buf, qcom_scm_get_response_buffer(rsp), resp_len);
+	}
 out:
-	free_qcom_scm_command(cmd);
+	dma_unmap_single(dev, cmd_phys, alloc_len, DMA_TO_DEVICE);
+	kfree(cmd);
 	return ret;
 }
 
@@ -437,7 +380,8 @@ int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
  * Set the Linux entry point for the SCM to transfer control to when coming
  * out of a power down. CPU power down may be executed on cpuidle or hotplug.
  */
-int __qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
+int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry,
+				  const cpumask_t *cpus)
 {
 	int ret;
 	int flags = 0;
@@ -463,7 +407,7 @@ int __qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
 
 	cmd.addr = cpu_to_le32(virt_to_phys(entry));
 	cmd.flags = cpu_to_le32(flags);
-	ret = qcom_scm_call(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_ADDR,
+	ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_ADDR,
 			    &cmd, sizeof(cmd), NULL, 0);
 	if (!ret) {
 		for_each_cpu(cpu, cpus)
@@ -487,25 +431,27 @@ void __qcom_scm_cpu_power_down(u32 flags)
 			flags & QCOM_SCM_FLUSH_FLAG_MASK);
 }
 
-int __qcom_scm_is_call_available(u32 svc_id, u32 cmd_id)
+int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id)
 {
 	int ret;
 	__le32 svc_cmd = cpu_to_le32((svc_id << 10) | cmd_id);
 	__le32 ret_val = 0;
 
-	ret = qcom_scm_call(QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD, &svc_cmd,
-			sizeof(svc_cmd), &ret_val, sizeof(ret_val));
+	ret = qcom_scm_call(dev, QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD,
+			    &svc_cmd, sizeof(svc_cmd), &ret_val,
+			    sizeof(ret_val));
 	if (ret)
 		return ret;
 
 	return le32_to_cpu(ret_val);
 }
 
-int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
+int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req,
+			u32 req_cnt, u32 *resp)
 {
 	if (req_cnt > QCOM_SCM_HDCP_MAX_REQ_CNT)
 		return -ERANGE;
 
-	return qcom_scm_call(QCOM_SCM_SVC_HDCP, QCOM_SCM_CMD_HDCP,
+	return qcom_scm_call(dev, QCOM_SCM_SVC_HDCP, QCOM_SCM_CMD_HDCP,
 		req, req_cnt * sizeof(*req), resp, sizeof(*resp));
 }
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
index 63a2bfa..9166cbb 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom_scm.c
@@ -89,7 +89,7 @@ EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr);
  */
 int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
 {
-	return __qcom_scm_set_warm_boot_addr(entry, cpus);
+	return __qcom_scm_set_warm_boot_addr(__scm->dev, entry, cpus);
 }
 EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr);
 
@@ -119,7 +119,7 @@ bool qcom_scm_hdcp_available(void)
 	if (ret)
 		return ret;
 
-	ret = __qcom_scm_is_call_available(QCOM_SCM_SVC_HDCP,
+	ret = __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_HDCP,
 						QCOM_SCM_CMD_HDCP);
 
 	qcom_scm_clk_disable();
@@ -143,7 +143,7 @@ int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
 	if (ret)
 		return ret;
 
-	ret = __qcom_scm_hdcp_req(req, req_cnt, resp);
+	ret = __qcom_scm_hdcp_req(__scm->dev, req, req_cnt, resp);
 	qcom_scm_clk_disable();
 	return ret;
 }
diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h
index 7dcc733..afe6676 100644
--- a/drivers/firmware/qcom_scm.h
+++ b/drivers/firmware/qcom_scm.h
@@ -19,7 +19,8 @@
 #define QCOM_SCM_FLAG_HLOS		0x01
 #define QCOM_SCM_FLAG_COLDBOOT_MC	0x02
 #define QCOM_SCM_FLAG_WARMBOOT_MC	0x04
-extern int __qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus);
+extern int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry,
+		const cpumask_t *cpus);
 extern int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus);
 
 #define QCOM_SCM_CMD_TERMINATE_PC	0x2
@@ -29,12 +30,13 @@ extern void __qcom_scm_cpu_power_down(u32 flags);
 
 #define QCOM_SCM_SVC_INFO		0x6
 #define QCOM_IS_CALL_AVAIL_CMD		0x1
-extern int __qcom_scm_is_call_available(u32 svc_id, u32 cmd_id);
+extern int __qcom_scm_is_call_available(struct device *dev, u32 svc_id,
+		u32 cmd_id);
 
 #define QCOM_SCM_SVC_HDCP		0x11
 #define QCOM_SCM_CMD_HDCP		0x01
-extern int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
-		u32 *resp);
+extern int __qcom_scm_hdcp_req(struct device *dev,
+		struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp);
 
 /* common error codes */
 #define QCOM_SCM_ENOMEM		-5
-- 
1.9.1

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

* [Patch v3 6/8] firmware: qcom: scm: Add support for ARM64 SoCs
       [not found] ` <1462402245-18295-1-git-send-email-andy.gross-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2016-05-04 22:50   ` Andy Gross
  0 siblings, 0 replies; 12+ messages in thread
From: Andy Gross @ 2016-05-04 22:50 UTC (permalink / raw)
  To: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Stephen Boyd,
	Bjorn Andersson, jilai wang, devicetree-u79uwXL29TY76Z2rM5mHXA,
	Kumar Gala, Andy Gross

From: Kumar Gala <galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>

Add an implementation of the SCM interface that works on ARM64 SoCs.  This
is used by things like determine if we have HDCP support or not on the
system.

Signed-off-by: Kumar Gala <galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Signed-off-by: Andy Gross <andy.gross-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 drivers/firmware/qcom_scm-32.c |   4 +
 drivers/firmware/qcom_scm-64.c | 208 +++++++++++++++++++++++++++++++++++++++--
 drivers/firmware/qcom_scm.c    |   2 +
 drivers/firmware/qcom_scm.h    |   5 +
 4 files changed, 209 insertions(+), 10 deletions(-)

diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c
index 3e71aec..5c290e7 100644
--- a/drivers/firmware/qcom_scm-32.c
+++ b/drivers/firmware/qcom_scm-32.c
@@ -455,3 +455,7 @@ int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req,
 	return qcom_scm_call(dev, QCOM_SCM_SVC_HDCP, QCOM_SCM_CMD_HDCP,
 		req, req_cnt * sizeof(*req), resp, sizeof(*resp));
 }
+
+void __qcom_scm_init(void)
+{
+}
diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c
index bb6555f..b57468e 100644
--- a/drivers/firmware/qcom_scm-64.c
+++ b/drivers/firmware/qcom_scm-64.c
@@ -12,12 +12,148 @@
 
 #include <linux/io.h>
 #include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/types.h>
 #include <linux/qcom_scm.h>
+#include <linux/arm-smccc.h>
+#include <linux/dma-mapping.h>
+
+#include "qcom_scm.h"
+
+#define QCOM_SCM_FNID(s, c) ((((s) & 0xFF) << 8) | ((c) & 0xFF))
+
+#define MAX_QCOM_SCM_ARGS 10
+#define MAX_QCOM_SCM_RETS 3
+
+#define QCOM_SCM_ARGS_IMPL(num, a, b, c, d, e, f, g, h, i, j, ...) (\
+			   (((a) & 0xff) << 4) | \
+			   (((b) & 0xff) << 6) | \
+			   (((c) & 0xff) << 8) | \
+			   (((d) & 0xff) << 10) | \
+			   (((e) & 0xff) << 12) | \
+			   (((f) & 0xff) << 14) | \
+			   (((g) & 0xff) << 16) | \
+			   (((h) & 0xff) << 18) | \
+			   (((i) & 0xff) << 20) | \
+			   (((j) & 0xff) << 22) | \
+			   (num & 0xffff))
+
+#define QCOM_SCM_ARGS(...) QCOM_SCM_ARGS_IMPL(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+
+/**
+ * struct qcom_scm_desc
+ * @arginfo:	Metadata describing the arguments in args[]
+ * @args:	The array of arguments for the secure syscall
+ * @res:	The values returned by the secure syscall
+ */
+struct qcom_scm_desc {
+	u32 arginfo;
+	u64 args[MAX_QCOM_SCM_ARGS];
+	struct arm_smccc_res res;
+};
+
+static u64 qcom_smccc_convention = -1;
+static DEFINE_MUTEX(qcom_scm_lock);
+
+#define QCOM_SCM_EBUSY_WAIT_MS 30
+#define QCOM_SCM_EBUSY_MAX_RETRY 20
+
+#define N_EXT_QCOM_SCM_ARGS 7
+#define FIRST_EXT_ARG_IDX 3
+#define N_REGISTER_ARGS (MAX_QCOM_SCM_ARGS - N_EXT_QCOM_SCM_ARGS + 1)
+
+/**
+ * qcom_scm_call() - Invoke a syscall in the secure world
+ * @dev:	device
+ * @svc_id:	service identifier
+ * @cmd_id:	command identifier
+ * @fn_id:	The function ID for this syscall
+ * @desc:	Descriptor structure containing arguments and return values
+ *
+ * Sends a command to the SCM and waits for the command to finish processing.
+ * This should *only* be called in pre-emptible context.
+*/
+static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
+			 struct qcom_scm_desc *desc)
+{
+	int arglen = desc->arginfo & 0xf;
+	int ret, retry_count = 0, i;
+	u32 fn_id = QCOM_SCM_FNID(svc_id, cmd_id);
+	u64 cmd, x5 = desc->args[FIRST_EXT_ARG_IDX];
+	dma_addr_t args_phys = 0;
+	void *args_virt = NULL;
+	size_t alloc_len;
+
+	if (unlikely(arglen > N_REGISTER_ARGS)) {
+		alloc_len = N_EXT_QCOM_SCM_ARGS * sizeof(u64);
+		args_virt = kzalloc(PAGE_ALIGN(alloc_len), GFP_KERNEL);
+
+		if (!args_virt)
+			return qcom_scm_remap_error(-ENOMEM);
+
+		if (qcom_smccc_convention == ARM_SMCCC_SMC_32) {
+			__le32 *args = args_virt;
+
+			for (i = 0; i < N_EXT_QCOM_SCM_ARGS; i++)
+				args[i] = cpu_to_le32(desc->args[i +
+						      FIRST_EXT_ARG_IDX]);
+		} else {
+			__le64 *args = args_virt;
+
+			for (i = 0; i < N_EXT_QCOM_SCM_ARGS; i++)
+				args[i] = cpu_to_le64(desc->args[i +
+						      FIRST_EXT_ARG_IDX]);
+		}
+
+		args_phys = dma_map_single(dev, args_virt, alloc_len,
+					   DMA_TO_DEVICE);
+
+		if (dma_mapping_error(dev, args_phys)) {
+			kfree(args_virt);
+			return qcom_scm_remap_error(-ENOMEM);
+		}
+
+		x5 = args_phys;
+	}
+
+	do {
+		mutex_lock(&qcom_scm_lock);
+
+		cmd = ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL,
+					 qcom_smccc_convention,
+					 ARM_SMCCC_OWNER_SIP, fn_id);
+
+		do {
+			arm_smccc_smc(cmd, arglen, desc->args[0], desc->args[1],
+				      desc->args[2], x5, 0, 0, &desc->res);
+		} while (desc->res.a0 == QCOM_SCM_INTERRUPTED);
+
+		mutex_unlock(&qcom_scm_lock);
+
+		if (desc->res.a0 == QCOM_SCM_V2_EBUSY) {
+			if (retry_count++ > QCOM_SCM_EBUSY_MAX_RETRY)
+				break;
+			msleep(QCOM_SCM_EBUSY_WAIT_MS);
+		}
+	}  while (desc->res.a0 == QCOM_SCM_V2_EBUSY);
+
+	if (args_virt) {
+		dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE);
+		kfree(args_virt);
+	}
+
+	if (desc->res.a0 < 0)
+		return qcom_scm_remap_error(ret);
+
+	return 0;
+}
 
 /**
  * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
- * @entry: Entry point function for the cpus
- * @cpus: The cpumask of cpus that will use the entry point
+ * @entry:	Entry point function for the cpus
+ * @cpus:	The cpumask of cpus that will use the entry point
  *
  * Set the cold boot address of the cpus. Any cpu outside the supported
  * range would be removed from the cpu present mask.
@@ -29,20 +165,21 @@ int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
 
 /**
  * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus
- * @entry: Entry point function for the cpus
- * @cpus: The cpumask of cpus that will use the entry point
+ * @entry:	Entry point function for the cpus
+ * @cpus:	The cpumask of cpus that will use the entry point
  *
  * Set the Linux entry point for the SCM to transfer control to when coming
  * out of a power down. CPU power down may be executed on cpuidle or hotplug.
  */
-int __qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
+int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry,
+				  const cpumask_t *cpus)
 {
 	return -ENOTSUPP;
 }
 
 /**
  * qcom_scm_cpu_power_down() - Power down the cpu
- * @flags - Flags to flush cache
+ * @flags:	Flags to flush cache
  *
  * This is an end point to power down cpu. If there was a pending interrupt,
  * the control would return from this function, otherwise, the cpu jumps to the
@@ -52,12 +189,63 @@ void __qcom_scm_cpu_power_down(u32 flags)
 {
 }
 
-int __qcom_scm_is_call_available(u32 svc_id, u32 cmd_id)
+int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id)
 {
-	return -ENOTSUPP;
+	int ret;
+	struct qcom_scm_desc desc = {0};
+
+	desc.arginfo = QCOM_SCM_ARGS(1);
+	desc.args[0] = QCOM_SCM_FNID(svc_id, cmd_id) |
+			(ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT);
+
+	ret = qcom_scm_call(dev, QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD,
+			    &desc);
+
+	return ret ? : desc.res.a1;
 }
 
-int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
+int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req,
+			u32 req_cnt, u32 *resp)
 {
-	return -ENOTSUPP;
+	int ret;
+	struct qcom_scm_desc desc = {0};
+
+	if (req_cnt > QCOM_SCM_HDCP_MAX_REQ_CNT)
+		return -ERANGE;
+
+	desc.args[0] = req[0].addr;
+	desc.args[1] = req[0].val;
+	desc.args[2] = req[1].addr;
+	desc.args[3] = req[1].val;
+	desc.args[4] = req[2].addr;
+	desc.args[5] = req[2].val;
+	desc.args[6] = req[3].addr;
+	desc.args[7] = req[3].val;
+	desc.args[8] = req[4].addr;
+	desc.args[9] = req[4].val;
+	desc.arginfo = QCOM_SCM_ARGS(10);
+
+	ret = qcom_scm_call(dev, QCOM_SCM_SVC_HDCP, QCOM_SCM_CMD_HDCP, &desc);
+	*resp = desc.res.a1;
+
+	return ret;
+}
+
+void __qcom_scm_init(void)
+{
+	u64 cmd;
+	struct arm_smccc_res res;
+	u32 function = QCOM_SCM_FNID(QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD);
+
+	/* First try a SMC64 call */
+	cmd = ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64,
+				 ARM_SMCCC_OWNER_SIP, function);
+
+	arm_smccc_smc(cmd, QCOM_SCM_ARGS(1), cmd & (~BIT(ARM_SMCCC_TYPE_SHIFT)),
+		      0, 0, 0, 0, 0, &res);
+
+	if (!res.a0 && res.a1)
+		qcom_smccc_convention = ARM_SMCCC_SMC_64;
+	else
+		qcom_smccc_convention = ARM_SMCCC_SMC_32;
 }
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
index 9166cbb..f68deba 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom_scm.c
@@ -189,6 +189,8 @@ static int qcom_scm_probe(struct platform_device *pdev)
 	__scm = scm;
 	__scm->dev = &pdev->dev;
 
+	__qcom_scm_init();
+
 	return 0;
 }
 
diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h
index afe6676..0ea55d7 100644
--- a/drivers/firmware/qcom_scm.h
+++ b/drivers/firmware/qcom_scm.h
@@ -38,7 +38,10 @@ extern int __qcom_scm_is_call_available(struct device *dev, u32 svc_id,
 extern int __qcom_scm_hdcp_req(struct device *dev,
 		struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp);
 
+extern void __qcom_scm_init(void);
+
 /* common error codes */
+#define QCOM_SCM_V2_EBUSY	-12
 #define QCOM_SCM_ENOMEM		-5
 #define QCOM_SCM_EOPNOTSUPP	-4
 #define QCOM_SCM_EINVAL_ADDR	-3
@@ -58,6 +61,8 @@ static inline int qcom_scm_remap_error(int err)
 		return -EOPNOTSUPP;
 	case QCOM_SCM_ENOMEM:
 		return -ENOMEM;
+	case QCOM_SCM_V2_EBUSY:
+		return -EBUSY;
 	}
 	return -EINVAL;
 }
-- 
1.9.1

--
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 related	[flat|nested] 12+ messages in thread

* [Patch v3 7/8] dts: qcom: apq8084: Add SCM firmware node
  2016-05-04 22:50 [Patch v3 0/8] Qualcomm SCM Rework Andy Gross
                   ` (5 preceding siblings ...)
       [not found] ` <1462402245-18295-1-git-send-email-andy.gross-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2016-05-04 22:50 ` Andy Gross
  2016-05-04 22:50 ` [Patch v3 8/8] arm64: dts: msm8916: " Andy Gross
  7 siblings, 0 replies; 12+ messages in thread
From: Andy Gross @ 2016-05-04 22:50 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: linux-arm-kernel, linux-kernel, Stephen Boyd, Bjorn Andersson,
	jilai wang, devicetree, Andy Gross

This patch adds the firmware node for the SCM

Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Andy Gross <andy.gross@linaro.org>
---
 arch/arm/boot/dts/qcom-apq8084.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi
index a33a09f..7c2df06 100644
--- a/arch/arm/boot/dts/qcom-apq8084.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8084.dtsi
@@ -86,6 +86,14 @@
 		};
 	};
 
+	firmware {
+		scm {
+			compatible = "qcom,scm";
+			clocks = <&gcc GCC_CE1_CLK> , <&gcc GCC_CE1_AXI_CLK>, <&gcc GCC_CE1_AHB_CLK>;
+			clock-names = "core", "bus", "iface";
+		};
+	};
+
 	cpu-pmu {
 		compatible = "qcom,krait-pmu";
 		interrupts = <1 7 0xf04>;
-- 
1.9.1

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

* [Patch v3 8/8] arm64: dts: msm8916: Add SCM firmware node
  2016-05-04 22:50 [Patch v3 0/8] Qualcomm SCM Rework Andy Gross
                   ` (6 preceding siblings ...)
  2016-05-04 22:50 ` [Patch v3 7/8] dts: qcom: apq8084: Add SCM firmware node Andy Gross
@ 2016-05-04 22:50 ` Andy Gross
  7 siblings, 0 replies; 12+ messages in thread
From: Andy Gross @ 2016-05-04 22:50 UTC (permalink / raw)
  To: linux-arm-msm
  Cc: linux-arm-kernel, linux-kernel, Stephen Boyd, Bjorn Andersson,
	jilai wang, devicetree, Andy Gross

This adds the devicetree node for the SCM firmware.

Acked-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: Andy Gross <andy.gross@linaro.org>
---
 arch/arm64/boot/dts/qcom/msm8916.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 9681200..01c7b0c 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -122,6 +122,14 @@
 		hwlocks = <&tcsr_mutex 3>;
 	};
 
+	firmware {
+		scm {
+			compatible = "qcom,scm";
+			clocks = <&gcc GCC_CRYPTO_CLK>, <&gcc GCC_CRYPTO_AXI_CLK>, <&gcc GCC_CRYPTO_AHB_CLK>;
+			clock-names = "core", "bus", "iface";
+		};
+	};
+
 	soc: soc {
 		#address-cells = <1>;
 		#size-cells = <1>;
-- 
1.9.1

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

* Re: [Patch v3 1/8] dt/bindings: firmware: Add Qualcomm SCM binding
  2016-05-04 22:50 ` [Patch v3 1/8] dt/bindings: firmware: Add Qualcomm SCM binding Andy Gross
@ 2016-05-05 22:17   ` Rob Herring
  2016-05-05 23:16     ` Andy Gross
  0 siblings, 1 reply; 12+ messages in thread
From: Rob Herring @ 2016-05-05 22:17 UTC (permalink / raw)
  To: Andy Gross
  Cc: linux-arm-msm, linux-arm-kernel, linux-kernel, Stephen Boyd,
	Bjorn Andersson, jilai wang, devicetree

On Wed, May 04, 2016 at 05:50:38PM -0500, Andy Gross wrote:
> This patch adds the device tree support for the Qualcomm SCM firmware.
> 
> Signed-off-by: Andy Gross <andy.gross@linaro.org>
> ---
>  .../devicetree/bindings/firmware/qcom,scm.txt      | 26 ++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/firmware/qcom,scm.txt
> 
> diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.txt b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
> new file mode 100644
> index 0000000..ee7cd12
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
> @@ -0,0 +1,26 @@
> +QCOM Secure Channel Manager (SCM)
> +
> +Qualcomm processors include an interface to communicate to the secure firmware.
> +This interface allows for clients to request different types of actions.  These
> +can include CPU power up/down, HDCP requests, loading of firmware, and other
> +assorted actions.
> +
> +Required properties:
> +- compatible: must contain one of the following:
> + * "qcom,scm-a-family" for A family Qualcomm processors (APQ8064, MSM8960, etc)
> + * "qcom,scm" for B family and later processors (MSM8916, APQ8084, MSM8974, etc)
> +- clocks: One to three clocks may be required based on compatible.
> + * Only core clock required for "qcom,scm-apq8064"

This is not a compatible string. What happened to the chip ones. I 
thought we decided on chip specific plus one of the above ones.

Rob

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

* Re: [Patch v3 1/8] dt/bindings: firmware: Add Qualcomm SCM binding
  2016-05-05 22:17   ` Rob Herring
@ 2016-05-05 23:16     ` Andy Gross
  0 siblings, 0 replies; 12+ messages in thread
From: Andy Gross @ 2016-05-05 23:16 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-arm-msm, linux-arm-kernel, linux-kernel, Stephen Boyd,
	Bjorn Andersson, jilai wang, devicetree

On 5 May 2016 at 17:17, Rob Herring <robh@kernel.org> wrote:
> On Wed, May 04, 2016 at 05:50:38PM -0500, Andy Gross wrote:
>> This patch adds the device tree support for the Qualcomm SCM firmware.
>>
>> Signed-off-by: Andy Gross <andy.gross@linaro.org>
>> ---
>>  .../devicetree/bindings/firmware/qcom,scm.txt      | 26 ++++++++++++++++++++++
>>  1 file changed, 26 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/firmware/qcom,scm.txt
>>
>> diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.txt b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
>> new file mode 100644
>> index 0000000..ee7cd12
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.txt
>> @@ -0,0 +1,26 @@
>> +QCOM Secure Channel Manager (SCM)
>> +
>> +Qualcomm processors include an interface to communicate to the secure firmware.
>> +This interface allows for clients to request different types of actions.  These
>> +can include CPU power up/down, HDCP requests, loading of firmware, and other
>> +assorted actions.
>> +
>> +Required properties:
>> +- compatible: must contain one of the following:
>> + * "qcom,scm-a-family" for A family Qualcomm processors (APQ8064, MSM8960, etc)
>> + * "qcom,scm" for B family and later processors (MSM8916, APQ8084, MSM8974, etc)
>> +- clocks: One to three clocks may be required based on compatible.
>> + * Only core clock required for "qcom,scm-apq8064"
>
> This is not a compatible string. What happened to the chip ones. I
> thought we decided on chip specific plus one of the above ones.

Stephen specifically didn't like the chip ones due to churn.  We'd
have to add compat tags every time we got a new chip.... which is kind
of frequent.  So I opted for defining one compat for older A family
chips that require only 1 clock.  The qcom,scm would cover the newer
chips.

And it looks like i left a reference to apq8064.  That needs to be
replaced with a-family.  Sorry for that confusion.

Regards,

Andy

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

* RE: [Patch v3 5/8] firmware: qcom: scm: Convert to streaming DMA APIS
  2016-05-04 22:50 ` [Patch v3 5/8] firmware: qcom: scm: Convert to streaming DMA APIS Andy Gross
@ 2016-05-09  5:18   ` Sricharan
  0 siblings, 0 replies; 12+ messages in thread
From: Sricharan @ 2016-05-09  5:18 UTC (permalink / raw)
  To: 'Andy Gross', linux-arm-msm
  Cc: devicetree, 'Stephen Boyd',
	linux-kernel, 'Bjorn Andersson', 'jilai wang',
	linux-arm-kernel

Hi,
> This patch converts the Qualcomm SCM driver to use the streaming DMA
> APIs for communication buffers.
> 
> Signed-off-by: Andy Gross <andy.gross@linaro.org>
> ---

 Reviewed-by: sricharan@codeaurora.org

Regards,
 Sricharan

>  drivers/firmware/qcom_scm-32.c | 152
+++++++++++++------------------------
> ----
>  drivers/firmware/qcom_scm.c    |   6 +-
>  drivers/firmware/qcom_scm.h    |  10 +--
>  3 files changed, 58 insertions(+), 110 deletions(-)
> 
> diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-
> 32.c index 4388d13..3e71aec 100644
> --- a/drivers/firmware/qcom_scm-32.c
> +++ b/drivers/firmware/qcom_scm-32.c
> @@ -23,8 +23,7 @@
>  #include <linux/errno.h>
>  #include <linux/err.h>
>  #include <linux/qcom_scm.h>
> -
> -#include <asm/cacheflush.h>
> +#include <linux/dma-mapping.h>
> 
>  #include "qcom_scm.h"
> 
> @@ -97,44 +96,6 @@ struct qcom_scm_response {  };
> 
>  /**
> - * alloc_qcom_scm_command() - Allocate an SCM command
> - * @cmd_size: size of the command buffer
> - * @resp_size: size of the response buffer
> - *
> - * Allocate an SCM command, including enough room for the command
> - * and response headers as well as the command and response buffers.
> - *
> - * Returns a valid &qcom_scm_command on success or %NULL if the
> allocation fails.
> - */
> -static struct qcom_scm_command *alloc_qcom_scm_command(size_t
> cmd_size, size_t resp_size) -{
> -	struct qcom_scm_command *cmd;
> -	size_t len = sizeof(*cmd) + sizeof(struct qcom_scm_response) +
> cmd_size +
> -		resp_size;
> -	u32 offset;
> -
> -	cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
> -	if (cmd) {
> -		cmd->len = cpu_to_le32(len);
> -		offset = offsetof(struct qcom_scm_command, buf);
> -		cmd->buf_offset = cpu_to_le32(offset);
> -		cmd->resp_hdr_offset = cpu_to_le32(offset + cmd_size);
> -	}
> -	return cmd;
> -}
> -
> -/**
> - * free_qcom_scm_command() - Free an SCM command
> - * @cmd: command to free
> - *
> - * Free an SCM command.
> - */
> -static inline void free_qcom_scm_command(struct qcom_scm_command
> *cmd) -{
> -	kfree(cmd);
> -}
> -
> -/**
>   * qcom_scm_command_to_response() - Get a pointer to a
> qcom_scm_response
>   * @cmd: command
>   *
> @@ -168,7 +129,7 @@ static inline void
> *qcom_scm_get_response_buffer(const struct qcom_scm_response
>  	return (void *)rsp + le32_to_cpu(rsp->buf_offset);  }
> 
> -static u32 smc(u32 cmd_addr)
> +static u32 smc(dma_addr_t cmd_addr)
>  {
>  	int context_id;
>  	register u32 r0 asm("r0") = 1;
> @@ -192,51 +153,15 @@ static u32 smc(u32 cmd_addr)
>  	return r0;
>  }
> 
> -static int __qcom_scm_call(const struct qcom_scm_command *cmd) -{
> -	int ret;
> -	u32 cmd_addr = virt_to_phys(cmd);
> -
> -	/*
> -	 * Flush the command buffer so that the secure world sees
> -	 * the correct data.
> -	 */
> -	secure_flush_area(cmd, cmd->len);
> -
> -	ret = smc(cmd_addr);
> -	if (ret < 0)
> -		ret = qcom_scm_remap_error(ret);
> -
> -	return ret;
> -}
> -
> -static void qcom_scm_inv_range(unsigned long start, unsigned long end) -{
> -	u32 cacheline_size, ctr;
> -
> -	asm volatile("mrc p15, 0, %0, c0, c0, 1" : "=r" (ctr));
> -	cacheline_size = 4 << ((ctr >> 16) & 0xf);
> -
> -	start = round_down(start, cacheline_size);
> -	end = round_up(end, cacheline_size);
> -	outer_inv_range(start, end);
> -	while (start < end) {
> -		asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
> -		     : "memory");
> -		start += cacheline_size;
> -	}
> -	dsb();
> -	isb();
> -}
> -
>  /**
>   * qcom_scm_call() - Send an SCM command
> - * @svc_id: service identifier
> - * @cmd_id: command identifier
> - * @cmd_buf: command buffer
> - * @cmd_len: length of the command buffer
> - * @resp_buf: response buffer
> - * @resp_len: length of the response buffer
> + * @dev:	struct device
> + * @svc_id:	service identifier
> + * @cmd_id:	command identifier
> + * @cmd_buf:	command buffer
> + * @cmd_len:	length of the command buffer
> + * @resp_buf:	response buffer
> + * @resp_len:	length of the response buffer
>   *
>   * Sends a command to the SCM and waits for the command to finish
> processing.
>   *
> @@ -247,42 +172,60 @@ static void qcom_scm_inv_range(unsigned long
> start, unsigned long end)
>   * and response buffers is taken care of by qcom_scm_call; however,
callers
> are
>   * responsible for any other cached buffers passed over to the secure
world.
>   */
> -static int qcom_scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf,
> -			size_t cmd_len, void *resp_buf, size_t resp_len)
> +static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
> +			 const void *cmd_buf, size_t cmd_len, void
> *resp_buf,
> +			 size_t resp_len)
>  {
>  	int ret;
>  	struct qcom_scm_command *cmd;
>  	struct qcom_scm_response *rsp;
> -	unsigned long start, end;
> +	size_t alloc_len = sizeof(*cmd) + sizeof(struct qcom_scm_response) +
> +			   cmd_len + resp_len;
> +	dma_addr_t cmd_phys;
> +	u32 offset;
> 
> -	cmd = alloc_qcom_scm_command(cmd_len, resp_len);
> +	cmd = kzalloc(PAGE_ALIGN(alloc_len), GFP_KERNEL);
>  	if (!cmd)
>  		return -ENOMEM;
> 
> +	cmd->len = cpu_to_le32(alloc_len);
> +	offset = offsetof(struct qcom_scm_command, buf);
> +	cmd->buf_offset = cpu_to_le32(offset);
> +	cmd->resp_hdr_offset = cpu_to_le32(offset + cmd_len);
> +
>  	cmd->id = cpu_to_le32((svc_id << 10) | cmd_id);
>  	if (cmd_buf)
>  		memcpy(qcom_scm_get_command_buffer(cmd), cmd_buf,
> cmd_len);
> 
> +	cmd_phys = dma_map_single(dev, cmd, alloc_len,
> DMA_TO_DEVICE);
> +	if (dma_mapping_error(dev, cmd_phys)) {
> +		kfree(cmd);
> +		return -ENOMEM;
> +	}
> +
>  	mutex_lock(&qcom_scm_lock);
> -	ret = __qcom_scm_call(cmd);
> +	ret = smc(cmd_phys);
> +	if (ret < 0)
> +		ret = qcom_scm_remap_error(ret);
>  	mutex_unlock(&qcom_scm_lock);
>  	if (ret)
>  		goto out;
> 
>  	rsp = qcom_scm_command_to_response(cmd);
> -	start = (unsigned long)rsp;
> 
>  	do {
> -		qcom_scm_inv_range(start, start + sizeof(*rsp));
> +		dma_sync_single_for_cpu(dev, cmd_phys + cmd_len +
> offset,
> +					sizeof(*rsp), DMA_FROM_DEVICE);
>  	} while (!rsp->is_complete);
> 
> -	end = (unsigned long)qcom_scm_get_response_buffer(rsp) +
> resp_len;
> -	qcom_scm_inv_range(start, end);
> -
> -	if (resp_buf)
> +	if (resp_buf) {
> +		dma_sync_single_for_cpu(dev, cmd_phys + alloc_len -
> resp_len,
> +					resp_len, DMA_FROM_DEVICE);
>  		memcpy(resp_buf, qcom_scm_get_response_buffer(rsp),
> resp_len);
> +	}
>  out:
> -	free_qcom_scm_command(cmd);
> +	dma_unmap_single(dev, cmd_phys, alloc_len, DMA_TO_DEVICE);
> +	kfree(cmd);
>  	return ret;
>  }
> 
> @@ -437,7 +380,8 @@ int __qcom_scm_set_cold_boot_addr(void *entry,
> const cpumask_t *cpus)
>   * Set the Linux entry point for the SCM to transfer control to when
coming
>   * out of a power down. CPU power down may be executed on cpuidle or
> hotplug.
>   */
> -int __qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t
> *cpus)
> +int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry,
> +				  const cpumask_t *cpus)
>  {
>  	int ret;
>  	int flags = 0;
> @@ -463,7 +407,7 @@ int __qcom_scm_set_warm_boot_addr(void *entry,
> const cpumask_t *cpus)
> 
>  	cmd.addr = cpu_to_le32(virt_to_phys(entry));
>  	cmd.flags = cpu_to_le32(flags);
> -	ret = qcom_scm_call(QCOM_SCM_SVC_BOOT,
> QCOM_SCM_BOOT_ADDR,
> +	ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT,
> QCOM_SCM_BOOT_ADDR,
>  			    &cmd, sizeof(cmd), NULL, 0);
>  	if (!ret) {
>  		for_each_cpu(cpu, cpus)
> @@ -487,25 +431,27 @@ void __qcom_scm_cpu_power_down(u32 flags)
>  			flags & QCOM_SCM_FLUSH_FLAG_MASK);
>  }
> 
> -int __qcom_scm_is_call_available(u32 svc_id, u32 cmd_id)
> +int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32
> +cmd_id)
>  {
>  	int ret;
>  	__le32 svc_cmd = cpu_to_le32((svc_id << 10) | cmd_id);
>  	__le32 ret_val = 0;
> 
> -	ret = qcom_scm_call(QCOM_SCM_SVC_INFO,
> QCOM_IS_CALL_AVAIL_CMD, &svc_cmd,
> -			sizeof(svc_cmd), &ret_val, sizeof(ret_val));
> +	ret = qcom_scm_call(dev, QCOM_SCM_SVC_INFO,
> QCOM_IS_CALL_AVAIL_CMD,
> +			    &svc_cmd, sizeof(svc_cmd), &ret_val,
> +			    sizeof(ret_val));
>  	if (ret)
>  		return ret;
> 
>  	return le32_to_cpu(ret_val);
>  }
> 
> -int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
> u32 *resp)
> +int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req
> *req,
> +			u32 req_cnt, u32 *resp)
>  {
>  	if (req_cnt > QCOM_SCM_HDCP_MAX_REQ_CNT)
>  		return -ERANGE;
> 
> -	return qcom_scm_call(QCOM_SCM_SVC_HDCP,
> QCOM_SCM_CMD_HDCP,
> +	return qcom_scm_call(dev, QCOM_SCM_SVC_HDCP,
> QCOM_SCM_CMD_HDCP,
>  		req, req_cnt * sizeof(*req), resp, sizeof(*resp));  } diff
--git
> a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index
> 63a2bfa..9166cbb 100644
> --- a/drivers/firmware/qcom_scm.c
> +++ b/drivers/firmware/qcom_scm.c
> @@ -89,7 +89,7 @@ EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr);
>   */
>  int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)  {
> -	return __qcom_scm_set_warm_boot_addr(entry, cpus);
> +	return __qcom_scm_set_warm_boot_addr(__scm->dev, entry,
> cpus);
>  }
>  EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr);
> 
> @@ -119,7 +119,7 @@ bool qcom_scm_hdcp_available(void)
>  	if (ret)
>  		return ret;
> 
> -	ret = __qcom_scm_is_call_available(QCOM_SCM_SVC_HDCP,
> +	ret = __qcom_scm_is_call_available(__scm->dev,
> QCOM_SCM_SVC_HDCP,
>  						QCOM_SCM_CMD_HDCP);
> 
>  	qcom_scm_clk_disable();
> @@ -143,7 +143,7 @@ int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req
> *req, u32 req_cnt, u32 *resp)
>  	if (ret)
>  		return ret;
> 
> -	ret = __qcom_scm_hdcp_req(req, req_cnt, resp);
> +	ret = __qcom_scm_hdcp_req(__scm->dev, req, req_cnt, resp);
>  	qcom_scm_clk_disable();
>  	return ret;
>  }
> diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h
> index 7dcc733..afe6676 100644
> --- a/drivers/firmware/qcom_scm.h
> +++ b/drivers/firmware/qcom_scm.h
> @@ -19,7 +19,8 @@
>  #define QCOM_SCM_FLAG_HLOS		0x01
>  #define QCOM_SCM_FLAG_COLDBOOT_MC	0x02
>  #define QCOM_SCM_FLAG_WARMBOOT_MC	0x04
> -extern int __qcom_scm_set_warm_boot_addr(void *entry, const
> cpumask_t *cpus);
> +extern int __qcom_scm_set_warm_boot_addr(struct device *dev, void
> *entry,
> +		const cpumask_t *cpus);
>  extern int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t
> *cpus);
> 
>  #define QCOM_SCM_CMD_TERMINATE_PC	0x2
> @@ -29,12 +30,13 @@ extern void __qcom_scm_cpu_power_down(u32
> flags);
> 
>  #define QCOM_SCM_SVC_INFO		0x6
>  #define QCOM_IS_CALL_AVAIL_CMD		0x1
> -extern int __qcom_scm_is_call_available(u32 svc_id, u32 cmd_id);
> +extern int __qcom_scm_is_call_available(struct device *dev, u32 svc_id,
> +		u32 cmd_id);
> 
>  #define QCOM_SCM_SVC_HDCP		0x11
>  #define QCOM_SCM_CMD_HDCP		0x01
> -extern int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32
> req_cnt,
> -		u32 *resp);
> +extern int __qcom_scm_hdcp_req(struct device *dev,
> +		struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp);
> 
>  /* common error codes */
>  #define QCOM_SCM_ENOMEM		-5
> --
> 1.9.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2016-05-09  5:18 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-04 22:50 [Patch v3 0/8] Qualcomm SCM Rework Andy Gross
2016-05-04 22:50 ` [Patch v3 1/8] dt/bindings: firmware: Add Qualcomm SCM binding Andy Gross
2016-05-05 22:17   ` Rob Herring
2016-05-05 23:16     ` Andy Gross
2016-05-04 22:50 ` [Patch v3 2/8] firmware: qcom: scm: Convert SCM to platform driver Andy Gross
2016-05-04 22:50 ` [Patch v3 3/8] firmware: qcom: scm: Use atomic SCM for cold boot Andy Gross
2016-05-04 22:50 ` [Patch v3 4/8] firmware: qcom: scm: Generalize shared error map Andy Gross
2016-05-04 22:50 ` [Patch v3 5/8] firmware: qcom: scm: Convert to streaming DMA APIS Andy Gross
2016-05-09  5:18   ` Sricharan
     [not found] ` <1462402245-18295-1-git-send-email-andy.gross-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-05-04 22:50   ` [Patch v3 6/8] firmware: qcom: scm: Add support for ARM64 SoCs Andy Gross
2016-05-04 22:50 ` [Patch v3 7/8] dts: qcom: apq8084: Add SCM firmware node Andy Gross
2016-05-04 22:50 ` [Patch v3 8/8] arm64: dts: msm8916: " Andy Gross

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).