msm: kgsl: Add scm call for SMMU aperture programming

For truly dynamic context bank allocation/mapping to work, we
need to set the aperture register CP utilizes to the SMMU
context bank we receive. This aperture register is protected so
we use a new scm call for trustzone to do this for us.

Change-Id: I50ba3d8f4287f3cc251bbce14db4702e1c8f7ebc
Signed-off-by: Shrenuj Bansal <shrenujb@codeaurora.org>
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 73c0d71..c02046a 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -34,6 +34,8 @@
 #include "kgsl_trace.h"
 #include "kgsl_pwrctrl.h"
 
+#define CP_APERTURE_REG	0
+
 #define _IOMMU_PRIV(_mmu) (&((_mmu)->priv.iommu))
 
 #define ADDR_IN_GLOBAL(_a) \
@@ -1220,6 +1222,19 @@
 		"System cache not enabled for GPU pagetable walks: %d\n", ret);
 }
 
+static int program_smmu_aperture(unsigned int cb, unsigned int aperture_reg)
+{
+	struct scm_desc desc = {0};
+
+	desc.args[0] = 0xFFFF0000 | ((aperture_reg & 0xff) << 8) | (cb & 0xff);
+	desc.args[1] = 0xFFFFFFFF;
+	desc.args[2] = 0xFFFFFFFF;
+	desc.args[3] = 0xFFFFFFFF;
+	desc.arginfo = SCM_ARGS(4);
+
+	return scm_call2(SCM_SIP_FNID(SCM_SVC_MP, 0x1B), &desc);
+}
+
 static int _init_global_pt(struct kgsl_mmu *mmu, struct kgsl_pagetable *pt)
 {
 	int ret = 0;
@@ -1260,6 +1275,15 @@
 		goto done;
 	}
 
+	if (!MMU_FEATURE(mmu, KGSL_MMU_GLOBAL_PAGETABLE)) {
+		ret = program_smmu_aperture(cb_num, CP_APERTURE_REG);
+		if (ret) {
+			pr_err("SMMU aperture programming call failed with error %d\n",
+									ret);
+			return ret;
+		}
+	}
+
 	ctx->cb_num = cb_num;
 	ctx->regbase = iommu->regbase + KGSL_IOMMU_CB0_OFFSET
 			+ (cb_num << KGSL_IOMMU_CB_SHIFT);