summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchel Humpherys <mitchelh@codeaurora.org>2015-02-18 10:34:23 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:11:47 -0700
commitb1399c801542f7508f299decdb460a0558228afb (patch)
treead5d0f4386a52301625b23b75ee4443fa9cf3a78
parent7ed677cb8e6aa1dbb41bb6e4967de6c0b1afc8f2 (diff)
soc: qcom: add library for SMMU TZ interface
Some targets require calling into TZ for various bits of SMMU configuration. Add a library to provide a clean interface for such configuration. Change-Id: I1dc5cd21d4a09e321039d69cc760eaf6f356c6cf Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org> [pdaly@codeaurora.org Resolve minor conflicts] Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
-rw-r--r--Documentation/devicetree/bindings/iommu/arm,smmu.txt3
-rw-r--r--drivers/soc/qcom/Kconfig10
-rw-r--r--drivers/soc/qcom/Makefile2
-rw-r--r--drivers/soc/qcom/msm_tz_smmu.c139
-rw-r--r--include/soc/qcom/msm_tz_smmu.h37
5 files changed, 190 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 602f5f1e5816..61a6f11e9ab0 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -85,6 +85,9 @@ conditions.
address size faults are due to a fundamental programming
error from which we don't care about recovering anyways.
+- qcom,tz-device-id : A string indicating the device ID for this SMMU known
+ to TZ. See msm_tz_smmu.c for a full list of mappings.
+
- clocks : List of clocks to be used during SMMU register access. See
Documentation/devicetree/bindings/clock/clock-bindings.txt
for information about the format. For each clock specified
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index a3dd60ac6e1c..6991305fc4ab 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -342,6 +342,16 @@ config MSM_SECURE_BUFFER
use this memory and no unauthorized access is made to the
buffer
+config MSM_TZ_SMMU
+ bool "Helper functions for SMMU configuration through TZ"
+ depends on ARCH_MSMTHULIUM
+ help
+ Say 'Y' here for targets that need to call into TZ to configure
+ SMMUs for any reason (for example, for errata workarounds or
+ configuration of SMMU virtualization).
+
+ If unsure, say N.
+
config MSM_GLADIATOR_ERP
tristate "GLADIATOR coherency interconnect error reporting driver"
help
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index 863424e91f7b..30bff4c3f6b3 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -57,9 +57,9 @@ obj-$(CONFIG_QCOM_BUS_SCALING) += msm_bus/
obj-$(CONFIG_MSM_SECURE_BUFFER) += secure_buffer.o
obj-$(CONFIG_MSM_MPM_OF) += mpm-of.o
obj-$(CONFIG_MSM_EVENT_TIMER) += event_timer.o
+obj-$(CONFIG_MSM_TZ_SMMU) += msm_tz_smmu.o
obj-$(CONFIG_MSM_GLADIATOR_ERP) += gladiator_erp.o
obj-$(CONFIG_MSM_CORE_HANG_DETECT) += core_hang_detect.o
obj-$(CONFIG_MSM_GLADIATOR_HANG_DETECT) += gladiator_hang_detect.o
obj-$(CONFIG_MSM_RUN_QUEUE_STATS) += msm_rq_stats.o
obj-$(CONFIG_MSM_BOOT_STATS) += boot_stats.o
-
diff --git a/drivers/soc/qcom/msm_tz_smmu.c b/drivers/soc/qcom/msm_tz_smmu.c
new file mode 100644
index 000000000000..887106ff5262
--- /dev/null
+++ b/drivers/soc/qcom/msm_tz_smmu.c
@@ -0,0 +1,139 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/of.h>
+#include <soc/qcom/scm.h>
+#include <soc/qcom/msm_tz_smmu.h>
+
+enum tz_smmu_device_id {
+ TZ_DEVICE_START = 0,
+ TZ_DEVICE_VIDEO = 0,
+ TZ_DEVICE_MDSS,
+ TZ_DEVICE_LPASS,
+ TZ_DEVICE_MDSS_BOOT,
+ TZ_DEVICE_USB1_HS,
+ TZ_DEVICE_OCMEM,
+ TZ_DEVICE_LPASS_CORE,
+ TZ_DEVICE_VPU,
+ TZ_DEVICE_COPSS_SMMU,
+ TZ_DEVICE_USB3_0,
+ TZ_DEVICE_USB3_1,
+ TZ_DEVICE_PCIE_0,
+ TZ_DEVICE_PCIE_1,
+ TZ_DEVICE_BCSS,
+ TZ_DEVICE_VCAP,
+ TZ_DEVICE_PCIE20,
+ TZ_DEVICE_IPA,
+ TZ_DEVICE_APPS,
+ TZ_DEVICE_GPU,
+ TZ_DEVICE_UFS,
+ TZ_DEVICE_ICE,
+ TZ_DEVICE_ROT,
+ TZ_DEVICE_VFE,
+ TZ_DEVICE_ANOC0,
+ TZ_DEVICE_ANOC1,
+ TZ_DEVICE_ANOC2,
+ TZ_DEVICE_CPP,
+ TZ_DEVICE_JPEG,
+ TZ_DEVICE_MAX,
+};
+
+static const char * const device_id_mappings[] = {
+ [TZ_DEVICE_VIDEO] = "VIDEO",
+ [TZ_DEVICE_MDSS] = "MDSS",
+ [TZ_DEVICE_LPASS] = "LPASS",
+ [TZ_DEVICE_MDSS_BOOT] = "MDSS_BOOT",
+ [TZ_DEVICE_USB1_HS] = "USB1_HS",
+ [TZ_DEVICE_OCMEM] = "OCMEM",
+ [TZ_DEVICE_LPASS_CORE] = "LPASS_CORE",
+ [TZ_DEVICE_VPU] = "VPU",
+ [TZ_DEVICE_COPSS_SMMU] = "COPSS_SMMU",
+ [TZ_DEVICE_USB3_0] = "USB3_0",
+ [TZ_DEVICE_USB3_1] = "USB3_1",
+ [TZ_DEVICE_PCIE_0] = "PCIE_0",
+ [TZ_DEVICE_PCIE_1] = "PCIE_1",
+ [TZ_DEVICE_BCSS] = "BCSS",
+ [TZ_DEVICE_VCAP] = "VCAP",
+ [TZ_DEVICE_PCIE20] = "PCIE20",
+ [TZ_DEVICE_IPA] = "IPA",
+ [TZ_DEVICE_APPS] = "APPS",
+ [TZ_DEVICE_GPU] = "GPU",
+ [TZ_DEVICE_UFS] = "UFS",
+ [TZ_DEVICE_ICE] = "ICE",
+ [TZ_DEVICE_ROT] = "ROT",
+ [TZ_DEVICE_VFE] = "VFE",
+ [TZ_DEVICE_ANOC0] = "ANOC0",
+ [TZ_DEVICE_ANOC1] = "ANOC1",
+ [TZ_DEVICE_ANOC2] = "ANOC2",
+ [TZ_DEVICE_CPP] = "CPP",
+ [TZ_DEVICE_JPEG] = "JPEG",
+};
+
+#define MAX_DEVICE_ID_NAME_LEN 20
+
+#define TZ_SMMU_PREPARE_ATOS_ID 0x21
+#define TZ_SMMU_ATOS_START 1
+#define TZ_SMMU_ATOS_END 0
+
+static enum tz_smmu_device_id __dev_to_device_id(struct device *dev)
+{
+ const char *device_id;
+ enum tz_smmu_device_id iter;
+
+ if (of_property_read_string(dev->of_node, "qcom,tz-device-id",
+ &device_id)) {
+ dev_err(dev, "no qcom,device-id property\n");
+ return TZ_DEVICE_MAX;
+ }
+
+ for (iter = TZ_DEVICE_START; iter < TZ_DEVICE_MAX; iter++)
+ if (!strcmp(device_id_mappings[iter], device_id))
+ return iter;
+
+ return TZ_DEVICE_MAX;
+}
+
+static int __msm_tz_smmu_atos(struct device *dev, int cb_num, int operation)
+{
+ int ret;
+ struct scm_desc desc = {0};
+ enum tz_smmu_device_id devid = __dev_to_device_id(dev);
+
+ if (devid == TZ_DEVICE_MAX)
+ return -ENODEV;
+
+ desc.args[0] = devid;
+ desc.args[1] = cb_num;
+ desc.args[2] = operation;
+ desc.arginfo = SCM_ARGS(3, SCM_VAL, SCM_VAL, SCM_VAL);
+
+ ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP, TZ_SMMU_PREPARE_ATOS_ID),
+ &desc);
+ if (ret)
+ pr_info("%s: TZ SMMU ATOS %s failed, ret = %d\n",
+ __func__,
+ operation == TZ_SMMU_ATOS_START ? "start" : "end",
+ ret);
+ return ret;
+}
+
+int msm_tz_smmu_atos_start(struct device *dev, int cb_num)
+{
+ return __msm_tz_smmu_atos(dev, cb_num, TZ_SMMU_ATOS_START);
+}
+
+int msm_tz_smmu_atos_end(struct device *dev, int cb_num)
+{
+ return __msm_tz_smmu_atos(dev, cb_num, TZ_SMMU_ATOS_END);
+}
diff --git a/include/soc/qcom/msm_tz_smmu.h b/include/soc/qcom/msm_tz_smmu.h
new file mode 100644
index 000000000000..c16ea8336d7a
--- /dev/null
+++ b/include/soc/qcom/msm_tz_smmu.h
@@ -0,0 +1,37 @@
+/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MSM_TZ_SMMU_H__
+#define __MSM_TZ_SMMU_H__
+
+#include <linux/device.h>
+
+#ifdef CONFIG_MSM_TZ_SMMU
+
+int msm_tz_smmu_atos_start(struct device *dev, int cb_num);
+int msm_tz_smmu_atos_end(struct device *dev, int cb_num);
+
+#else
+
+static inline int msm_tz_smmu_atos_start(struct device *dev, int cb_num)
+{
+ return 0;
+}
+
+static inline int msm_tz_smmu_atos_end(struct device *dev, int cb_num)
+{
+ return 0;
+}
+
+#endif /* CONFIG_MSM_TZ_SMMU */
+
+#endif /* __MSM_TZ_SMMU_H__ */