summaryrefslogtreecommitdiff
path: root/drivers/iommu
diff options
context:
space:
mode:
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,