summaryrefslogtreecommitdiff
path: root/drivers/iommu
diff options
context:
space:
mode:
authorOlav Haugan <ohaugan@codeaurora.org>2014-01-27 17:38:06 -0800
committerOlav Haugan <ohaugan@codeaurora.org>2014-02-19 17:20:53 -0800
commit9916f48440333038cef7df0fd065fcc186077e37 (patch)
treed45517b3e8d8f382244f0f8b06143874fbf118c2 /drivers/iommu
parentce80330cb80b7d8c5182e8e6f36f50e22475e390 (diff)
iommu: msm: Make VFE SMMU conditionally secure
VFE SMMU needs to be secure for new secure camera use cases. Change the VFE to be secure and designate the last context bank (CB) as secure. Also ensure backwards compatability so that when running with old secure environment we fall back to VFE SMMU being non-secure. Change-Id: I25f31b0350ef0c1b16ebb0db531cc0e6bc556fcf Signed-off-by: Olav Haugan <ohaugan@codeaurora.org>
Diffstat (limited to 'drivers/iommu')
-rw-r--r--drivers/iommu/msm_iommu-v1.c2
-rw-r--r--drivers/iommu/msm_iommu_dev-v1.c33
-rw-r--r--drivers/iommu/msm_iommu_sec.c26
3 files changed, 49 insertions, 12 deletions
diff --git a/drivers/iommu/msm_iommu-v1.c b/drivers/iommu/msm_iommu-v1.c
index ee7a1f251dc3..b586a0a1837f 100644
--- a/drivers/iommu/msm_iommu-v1.c
+++ b/drivers/iommu/msm_iommu-v1.c
@@ -824,7 +824,7 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
iommu_resume(iommu_drvdata);
} else {
ret = msm_iommu_sec_program_iommu(
- iommu_drvdata->sec_id);
+ iommu_drvdata->sec_id, ctx_drvdata->num);
if (ret) {
__disable_regulators(iommu_drvdata);
__disable_clocks(iommu_drvdata);
diff --git a/drivers/iommu/msm_iommu_dev-v1.c b/drivers/iommu/msm_iommu_dev-v1.c
index c6572330f317..b7893b3f58f1 100644
--- a/drivers/iommu/msm_iommu_dev-v1.c
+++ b/drivers/iommu/msm_iommu_dev-v1.c
@@ -138,25 +138,43 @@ static inline void get_secure_id(struct device_node *node,
}
static inline void get_secure_ctx(struct device_node *node,
+ struct msm_iommu_drvdata *iommu_drvdata,
struct msm_iommu_ctx_drvdata *ctx_drvdata)
{
ctx_drvdata->secure_context = 0;
}
#else
+
+static inline int is_vfe_smmu(char const *iommu_name)
+{
+ return (strcmp(iommu_name, "vfe_iommu") == 0);
+}
+
static void get_secure_id(struct device_node *node,
struct msm_iommu_drvdata *drvdata)
{
- if (msm_iommu_get_scm_call_avail())
- of_property_read_u32(node, "qcom,iommu-secure-id",
- &drvdata->sec_id);
+ if (msm_iommu_get_scm_call_avail()) {
+ if (!is_vfe_smmu(drvdata->name) || is_vfe_secure())
+ of_property_read_u32(node, "qcom,iommu-secure-id",
+ &drvdata->sec_id);
+ else
+ pr_info("vfe_iommu: Keeping vfe non-secure\n");
+ }
}
static void get_secure_ctx(struct device_node *node,
+ struct msm_iommu_drvdata *iommu_drvdata,
struct msm_iommu_ctx_drvdata *ctx_drvdata)
{
- if (msm_iommu_get_scm_call_avail())
- ctx_drvdata->secure_context =
+ u32 secure_ctx = 0;
+
+ if (msm_iommu_get_scm_call_avail()) {
+ if (!is_vfe_smmu(iommu_drvdata->name) || is_vfe_secure()) {
+ secure_ctx =
of_property_read_bool(node, "qcom,secure-context");
+ }
+ }
+ ctx_drvdata->secure_context = secure_ctx;
}
#endif
@@ -473,7 +491,9 @@ static int msm_iommu_ctx_parse_dt(struct platform_device *pdev,
u32 nsid;
unsigned long cb_offset;
- get_secure_ctx(pdev->dev.of_node, ctx_drvdata);
+ drvdata = dev_get_drvdata(pdev->dev.parent);
+
+ get_secure_ctx(pdev->dev.of_node, drvdata, ctx_drvdata);
if (ctx_drvdata->secure_context) {
irq = platform_get_irq(pdev, 1);
@@ -518,7 +538,6 @@ static int msm_iommu_ctx_parse_dt(struct platform_device *pdev,
* of CBs are <=8. So, assume the offset 0x8000 until mentioned
* explicitely.
*/
- drvdata = dev_get_drvdata(pdev->dev.parent);
cb_offset = drvdata->cb_base - drvdata->base;
ctx_drvdata->num = ((r->start - rp.start - cb_offset)
>> CTX_SHIFT);
diff --git a/drivers/iommu/msm_iommu_sec.c b/drivers/iommu/msm_iommu_sec.c
index 43144b1b8dba..431d14ce3be7 100644
--- a/drivers/iommu/msm_iommu_sec.c
+++ b/drivers/iommu/msm_iommu_sec.c
@@ -56,7 +56,7 @@
#define MAXIMUM_VIRT_SIZE (300*SZ_1M)
-#define MAKE_CP_VERSION(major, minor, patch) \
+#define MAKE_VERSION(major, minor, patch) \
(((major & 0x3FF) << 22) | ((minor & 0x3FF) << 12) | (patch & 0xFFF))
@@ -349,7 +349,7 @@ static int msm_iommu_sec_ptbl_init(void)
version = scm_get_feat_version(SCM_SVC_MP);
- if (version >= MAKE_CP_VERSION(1, 1, 1)) {
+ if (version >= MAKE_VERSION(1, 1, 1)) {
struct msm_cp_pool_size psize;
int retval;
@@ -410,7 +410,7 @@ fail:
return ret;
}
-int msm_iommu_sec_program_iommu(int sec_id)
+int msm_iommu_sec_program_iommu(int sec_id, u32 cb_num)
{
struct msm_scm_sec_cfg {
unsigned int id;
@@ -419,6 +419,7 @@ int msm_iommu_sec_program_iommu(int sec_id)
int ret, scm_ret = 0;
cfg.id = sec_id;
+ cfg.spare = cb_num;
ret = scm_call(SCM_SVC_MP, IOMMU_SECURE_CFG, &cfg, sizeof(cfg),
&scm_ret, sizeof(scm_ret));
@@ -638,7 +639,8 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
goto fail;
}
- ret = msm_iommu_sec_program_iommu(iommu_drvdata->sec_id);
+ ret = msm_iommu_sec_program_iommu(iommu_drvdata->sec_id,
+ ctx_drvdata->num);
/* bfb settings are always programmed by HLOS */
program_iommu_bfb_settings(iommu_drvdata->base,
@@ -830,6 +832,22 @@ int msm_iommu_get_scm_call_avail(void)
return is_secure;
}
+/*
+ * VFE SMMU is changing from being non-secure to being secure.
+ * For backwards compatibility we need to check whether the secure environment
+ * has support for this.
+ */
+static s32 secure_camera_enabled = -1;
+int is_vfe_secure(void)
+{
+ if (secure_camera_enabled == -1) {
+ u32 ver = scm_get_feat_version(SCM_SVC_SEC_CAMERA);
+ secure_camera_enabled = ver >= MAKE_VERSION(1, 0, 0);
+ }
+ return secure_camera_enabled;
+}
+
+
static struct iommu_ops msm_iommu_ops = {
.domain_init = msm_iommu_domain_init,
.domain_destroy = msm_iommu_domain_destroy,