msm: kgsl: Allow pagefault policy to be controlled by userspace

GPU pagefault policy can be set to below options:
   a) enable/disable GPU HALT on pagefaults
   b) log only one pagefault per page.
GPU pagefault policy can be controled using panel file
and debugfs.

Change-Id: I0613e0d087fc45eb5e519e1c834a33f32376672f
Signed-off-by: Tarun Karra <tkarra@codeaurora.org>
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 3e6b77c..ea595b2 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -2245,6 +2245,12 @@
 			else
 				adreno_dev->ft_policy = KGSL_FT_DEFAULT_POLICY;
 
+			if (ftd.ft_pf_policy)
+				adreno_dev->ft_pf_policy = ftd.ft_policy;
+			else
+				adreno_dev->ft_pf_policy =
+					KGSL_FT_PAGEFAULT_DEFAULT_POLICY;
+
 			if (ftd.ft_pm_dump)
 				device->pm_dump_enable = 1;
 			else
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 3dc70b0..4b593d5 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -106,6 +106,7 @@
 	unsigned int long_ib_detect;
 	unsigned int long_ib;
 	unsigned int long_ib_ts;
+	unsigned int ft_pf_policy;
 	unsigned int gpulist_index;
 	struct ocmem_buf *ocmem_hdl;
 	unsigned int ocmem_base;
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index 70379e5..5acf5c4 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -73,10 +73,25 @@
 	 * by default set FT policy to KGSL_FT_DEFAULT_POLICY
 	 */
 	adreno_dev->ft_policy = KGSL_FT_DEFAULT_POLICY;
-	debugfs_create_u32("fault_tolerance_policy", 0644, device->d_debugfs,
+	debugfs_create_u32("ft_policy", 0644, device->d_debugfs,
 			   &adreno_dev->ft_policy);
+
 	/* By default enable long IB detection */
 	adreno_dev->long_ib_detect = 1;
 	debugfs_create_u32("long_ib_detect", 0644, device->d_debugfs,
 			   &adreno_dev->long_ib_detect);
+
+	/*
+	 * FT pagefault policy can be set to any of the options below.
+	 * KGSL_FT_PAGEFAULT_INT_ENABLE -> BIT(0) set to enable pagefault INT
+	 * KGSL_FT_PAGEFAULT_GPUHALT_ENABLE  -> BIT(1) Set to enable GPU HALT on
+	 * pagefaults. This stalls the GPU on a pagefault on IOMMU v1 HW.
+	 * KGSL_FT_PAGEFAULT_LOG_ONE_PER_PAGE  -> BIT(2) Set to log only one
+	 * pagefault per page.
+	 * KGSL_FT_PAGEFAULT_LOG_ONE_PER_INT -> BIT(3) Set to log only one
+	 * pagefault per INT.
+	 */
+	adreno_dev->ft_pf_policy = KGSL_FT_PAGEFAULT_DEFAULT_POLICY;
+	debugfs_create_u32("ft_pagefault_policy", 0644, device->d_debugfs,
+			   &adreno_dev->ft_pf_policy);
 }
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index a143971..f2393e4 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -110,7 +110,8 @@
 	struct kgsl_iommu_device *iommu_dev;
 	unsigned int ptbase, fsr;
 	struct kgsl_device *device;
-	unsigned int no_page_fault_log;
+	struct adreno_device *adreno_dev;
+	unsigned int no_page_fault_log = 0;
 
 	ret = get_iommu_unit(dev, &mmu, &iommu_unit);
 	if (ret)
@@ -123,6 +124,7 @@
 	}
 	iommu = mmu->priv;
 	device = mmu->device;
+	adreno_dev = ADRENO_DEVICE(device);
 
 	ptbase = KGSL_IOMMU_GET_CTX_REG(iommu, iommu_unit,
 					iommu_dev->ctx_id, TTBR0);
@@ -130,7 +132,8 @@
 	fsr = KGSL_IOMMU_GET_CTX_REG(iommu, iommu_unit,
 		iommu_dev->ctx_id, FSR);
 
-	no_page_fault_log = kgsl_mmu_log_fault_addr(mmu, ptbase, addr);
+	if (adreno_dev->ft_pf_policy & KGSL_FT_PAGEFAULT_LOG_ONE_PER_PAGE)
+		no_page_fault_log = kgsl_mmu_log_fault_addr(mmu, ptbase, addr);
 
 	if (!no_page_fault_log) {
 		KGSL_MEM_CRIT(iommu_dev->kgsldev,
@@ -152,7 +155,8 @@
 	 * the GPU and trigger a snapshot. To stall the transaction return
 	 * EBUSY error.
 	 */
-	ret = -EBUSY;
+	if (adreno_dev->ft_pf_policy & KGSL_FT_PAGEFAULT_GPUHALT_ENABLE)
+		ret = -EBUSY;
 done:
 	return ret;
 }