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