From f52365651426e11c427a88e40b177e540d1afb85 Mon Sep 17 00:00:00 2001
From: Carter Cooper <ccooper@codeaurora.org>
Date: Tue, 25 Nov 2014 10:55:49 -0700
Subject: [PATCH] msm: kgsl: Modify which MMU clocks are enabled/disabled

There is no need to try to attach a clock if it is already attached,
or detach a clock if it is already detached. Restructure this
logic to only attach/detach the clocks when needed. As well as
protect ourselves using the MMU lock more readily.

Signed-off-by: Carter Cooper <ccooper@codeaurora.org>
Change-Id: Ib5edfe7800cc246bc4b5e9aca8e02621aa6f7c3c
---
 drivers/gpu/msm/adreno.c     | 11 ++++++--
 drivers/gpu/msm/kgsl_iommu.c | 54 +++++++++++++++++++-----------------
 2 files changed, 36 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 12da1c4076e1..84ab89dc3d67 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1808,14 +1808,14 @@ static int adreno_stop(struct kgsl_device *device)
 	adreno_dispatcher_stop(adreno_dev);
 	adreno_ringbuffer_stop(&adreno_dev->ringbuffer);
 
-	kgsl_mmu_stop(&device->mmu);
-
 	device->ftbl->irqctrl(device, 0);
 	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
 	del_timer_sync(&device->idle_timer);
 
 	adreno_ocmem_gmem_free(adreno_dev);
 
+	kgsl_mmu_stop(&device->mmu);
+
 	/* Power down the device */
 	kgsl_pwrctrl_disable(device);
 
@@ -2406,6 +2406,8 @@ int adreno_soft_reset(struct kgsl_device *device)
 		return -EINVAL;
 	}
 
+	clear_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv);
+
 	if (adreno_dev->drawctxt_active)
 		kgsl_context_put(&adreno_dev->drawctxt_active->base);
 
@@ -2449,8 +2451,11 @@ int adreno_soft_reset(struct kgsl_device *device)
 
 	if (ret)
 		return ret;
+	else {
+		device->reset_counter++;
+		set_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv);
+	}
 
-	device->reset_counter++;
 
 	return 0;
 }
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 4c2862bb7919..f8f56a8dea0b 100644
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -80,12 +80,14 @@ kgsl_iommu_get_current_ptbase(struct kgsl_mmu *mmu);
 
 static void _iommu_lock(void)
 {
+	msm_iommu_lock();
 	return;
 }
 
 /* naming mismatch with iommu things */
 static void _iommu_unlock(void)
 {
+	msm_iommu_unlock();
 	return;
 }
 
@@ -782,9 +784,12 @@ static int kgsl_attach_pagetable_iommu_domain(struct kgsl_mmu *mmu)
 			 * If there is a 2nd default pagetable then priv domain
 			 * is attached to this pagetable
 			 */
-			if (mmu->priv_bank_table &&
-				(KGSL_IOMMU_CONTEXT_PRIV == j))
-				iommu_pt = mmu->priv_bank_table->priv;
+			if (KGSL_IOMMU_CONTEXT_PRIV == j) {
+				if (mmu->priv_bank_table)
+					iommu_pt = mmu->priv_bank_table->priv;
+				else
+					continue;
+			}
 			if (!iommu_unit->dev[j].attached) {
 				ret = iommu_attach_device(iommu_pt->domain,
 							iommu_unit->dev[j].dev);
@@ -1564,6 +1569,8 @@ static void kgsl_iommu_lock_rb_in_tlb(struct kgsl_mmu *mmu)
 	for (i = 0; i < iommu->unit_count; i++) {
 		struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
 		for (j = 0; j < iommu_unit->dev_count; j++) {
+			if (!iommu_unit->dev[j].attached)
+				continue;
 			tlblkcr = 0;
 			if (cpu_is_msm8960())
 				tlblkcr |= ((num_tlb_entries &
@@ -1589,6 +1596,8 @@ static void kgsl_iommu_lock_rb_in_tlb(struct kgsl_mmu *mmu)
 					TLBLKCR, tlblkcr);
 		}
 		for (j = 0; j < iommu_unit->dev_count; j++) {
+			if (!iommu_unit->dev[j].attached)
+				continue;
 			/* skip locking entries for private bank on 8960 */
 			if (cpu_is_msm8960() &&  KGSL_IOMMU_CONTEXT_PRIV == j)
 				continue;
@@ -1628,6 +1637,8 @@ static void kgsl_iommu_lock_rb_in_tlb(struct kgsl_mmu *mmu)
 			}
 		}
 		for (j = 0; j < iommu_unit->dev_count; j++) {
+			if (!iommu_unit->dev[j].attached)
+				continue;
 			tlblkcr = KGSL_IOMMU_GET_CTX_REG(iommu, iommu_unit,
 						iommu_unit->dev[j].ctx_id,
 						TLBLKCR);
@@ -1688,11 +1699,12 @@ static int kgsl_iommu_start(struct kgsl_mmu *mmu)
 	 * changing pagetables we can use this lsb value of the pagetable w/o
 	 * having to read it again
 	 */
-	msm_iommu_lock();
+	_iommu_lock();
 	for (i = 0; i < iommu->unit_count; i++) {
 		struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
 		for (j = 0; j < iommu_unit->dev_count; j++) {
-
+			if (!iommu_unit->dev[j].attached)
+				continue;
 			/*
 			 * For IOMMU V1 do not halt IOMMU on pagefault if
 			 * FT pagefault policy is set accordingly
@@ -1711,23 +1723,16 @@ static int kgsl_iommu_start(struct kgsl_mmu *mmu)
 						iommu_unit->dev[j].ctx_id,
 						SCTLR, sctlr_val);
 			}
-			if (sizeof(phys_addr_t) > sizeof(unsigned long)) {
-				iommu_unit->dev[j].default_ttbr0 =
-						KGSL_IOMMU_GET_CTX_REG_LL(iommu,
-						iommu_unit,
-						iommu_unit->dev[j].ctx_id,
-						TTBR0);
-			} else {
-				iommu_unit->dev[j].default_ttbr0 =
-						KGSL_IOMMU_GET_CTX_REG(iommu,
+
+			iommu_unit->dev[j].default_ttbr0 =
+				KGSL_IOMMU_GET_CTX_REG_LL(iommu,
 						iommu_unit,
 						iommu_unit->dev[j].ctx_id,
 						TTBR0);
-			}
 		}
 	}
 	kgsl_iommu_lock_rb_in_tlb(mmu);
-	msm_iommu_unlock();
+	_iommu_unlock();
 
 	/* For complete CFF */
 	kgsl_cffdump_setmem(mmu->device, mmu->setstate_memory.gpuaddr +
@@ -1851,6 +1856,8 @@ void kgsl_iommu_pagefault_resume(struct kgsl_mmu *mmu)
 			struct kgsl_iommu_unit *iommu_unit =
 						&iommu->iommu_units[i];
 			for (j = 0; j < iommu_unit->dev_count; j++) {
+				if (!iommu_unit->dev[j].attached)
+					continue;
 				if (iommu_unit->dev[j].fault) {
 					_iommu_lock();
 					KGSL_IOMMU_SET_CTX_REG(iommu,
@@ -1871,7 +1878,6 @@ void kgsl_iommu_pagefault_resume(struct kgsl_mmu *mmu)
 	}
 }
 
-
 static void kgsl_iommu_stop(struct kgsl_mmu *mmu)
 {
 	/*
@@ -1980,7 +1986,7 @@ static int kgsl_iommu_default_setstate(struct kgsl_mmu *mmu,
 	}
 
 	/* Acquire GPU-CPU sync Lock here */
-	msm_iommu_lock();
+	_iommu_lock();
 
 	if (flags & KGSL_MMUFLAGS_PTUPDATE) {
 	/* naming mismatch for iommu */
@@ -1998,15 +2004,9 @@ static int kgsl_iommu_default_setstate(struct kgsl_mmu *mmu,
 			pt_base &= KGSL_IOMMU_CTX_TTBR0_ADDR_MASK;
 			pt_val &= ~KGSL_IOMMU_CTX_TTBR0_ADDR_MASK;
 			pt_val |= pt_base;
-			if (sizeof(phys_addr_t) > sizeof(unsigned long)) {
-				KGSL_IOMMU_SET_CTX_REG_LL(iommu,
+			KGSL_IOMMU_SET_CTX_REG_LL(iommu,
 					(&iommu->iommu_units[i]),
 					KGSL_IOMMU_CONTEXT_USER, TTBR0, pt_val);
-			} else {
-				KGSL_IOMMU_SET_CTX_REG(iommu,
-					(&iommu->iommu_units[i]),
-					KGSL_IOMMU_CONTEXT_USER, TTBR0, pt_val);
-			}
 
 			mb();
 			temp = KGSL_IOMMU_GET_CTX_REG_LL(iommu,
@@ -2053,7 +2053,7 @@ static int kgsl_iommu_default_setstate(struct kgsl_mmu *mmu,
 unlock:
 
 	/* Release GPU-CPU sync Lock here */
-	msm_iommu_unlock();
+	_iommu_unlock();
 
 	/* Disable smmu clock */
 	kgsl_iommu_disable_clk(mmu, KGSL_IOMMU_MAX_UNITS);
@@ -2180,6 +2180,8 @@ static void kgsl_iommu_set_pagefault(struct kgsl_mmu *mmu)
 	/* Loop through all IOMMU devices to check for fault */
 	for (i = 0; i < iommu->unit_count; i++) {
 		for (j = 0; j < iommu->iommu_units[i].dev_count; j++) {
+			if (!iommu->iommu_units[i].dev[j].attached)
+				continue;
 			fsr = KGSL_IOMMU_GET_CTX_REG(iommu,
 				(&(iommu->iommu_units[i])),
 				iommu->iommu_units[i].dev[j].ctx_id, FSR);
-- 
GitLab