diff options
| author | Mitchel Humpherys <mitchelh@codeaurora.org> | 2015-02-18 10:34:23 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-22 11:11:47 -0700 |
| commit | b1399c801542f7508f299decdb460a0558228afb (patch) | |
| tree | ad5d0f4386a52301625b23b75ee4443fa9cf3a78 | |
| parent | 7ed677cb8e6aa1dbb41bb6e4967de6c0b1afc8f2 (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.txt | 3 | ||||
| -rw-r--r-- | drivers/soc/qcom/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/soc/qcom/Makefile | 2 | ||||
| -rw-r--r-- | drivers/soc/qcom/msm_tz_smmu.c | 139 | ||||
| -rw-r--r-- | include/soc/qcom/msm_tz_smmu.h | 37 |
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__ */ |
