Loading drivers/gpu/msm/adreno.c +6 −14 Original line number Diff line number Diff line Loading @@ -1345,9 +1345,8 @@ static int _adreno_start(struct adreno_device *adreno_dev) { struct kgsl_device *device = &adreno_dev->dev; struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); int i, status = -EINVAL; int status = -EINVAL; unsigned int state = device->state; unsigned int regulator_left_on = 0; unsigned int pmqos_wakeup_vote = device->pwrctrl.pm_qos_wakeup_latency; unsigned int pmqos_active_vote = device->pwrctrl.pm_qos_active_latency; Loading @@ -1359,27 +1358,20 @@ static int _adreno_start(struct adreno_device *adreno_dev) kgsl_cffdump_open(device); for (i = 0; i < KGSL_MAX_REGULATORS; i++) { if (device->pwrctrl.gpu_reg[i] && regulator_is_enabled(device->pwrctrl.gpu_reg[i])) { regulator_left_on = 1; break; } } /* Clear any GPU faults that might have been left over */ adreno_clear_gpu_fault(adreno_dev); /* Put the GPU in a responsive state */ device->regulator_left_on = false; status = kgsl_pwrctrl_change_state(device, KGSL_STATE_AWARE); if (status) goto error_pwr_off; /* Clear any GPU faults that might have been left over */ adreno_clear_gpu_fault(adreno_dev); /* Set the bit to indicate that we've just powered on */ set_bit(ADRENO_DEVICE_PWRON, &adreno_dev->priv); /* Soft reset the GPU if a regulator is stuck on*/ if (regulator_left_on) if (device->regulator_left_on) _soft_reset(adreno_dev); status = kgsl_mmu_start(device); Loading drivers/gpu/msm/kgsl_device.h +3 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,7 @@ struct kgsl_device { int open_count; struct mutex mutex; struct mutex mutex_pc_smmu; uint32_t state; uint32_t requested_state; Loading Loading @@ -289,6 +290,7 @@ struct kgsl_device { struct workqueue_struct *events_wq; struct device *busmondev; /* pseudo dev for GPU BW voting governor */ bool regulator_left_on; }; Loading @@ -303,6 +305,7 @@ struct kgsl_device { .wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER((_dev).wait_queue),\ .active_cnt_wq = __WAIT_QUEUE_HEAD_INITIALIZER((_dev).active_cnt_wq),\ .mutex = __MUTEX_INITIALIZER((_dev).mutex),\ .mutex_pc_smmu = __MUTEX_INITIALIZER((_dev).mutex_pc_smmu),\ .state = KGSL_STATE_NONE,\ .ver_major = DRIVER_VERSION_MAJOR,\ .ver_minor = DRIVER_VERSION_MINOR Loading drivers/gpu/msm/kgsl_iommu.c +20 −3 Original line number Diff line number Diff line Loading @@ -1022,6 +1022,7 @@ static int kgsl_iommu_start(struct kgsl_mmu *mmu) kgsl_map_global_pt_entries(mmu->defaultpagetable); kgsl_iommu_enable_clk(mmu); KGSL_IOMMU_SET_CTX_REG(iommu, 0, TLBIALL, 1); /* Get the lsb value of pagetables set in the IOMMU ttbr0 register as * that value should not change when we change pagetables, so while Loading Loading @@ -1130,13 +1131,18 @@ kgsl_iommu_unmap(struct kgsl_pagetable *pt, mutex_lock(&device->mutex); ret = kgsl_active_count_get(device); if (!ret) { mutex_lock(&device->mutex_pc_smmu); unmapped = iommu_unmap(iommu_pt->domain, gpuaddr, range); mutex_unlock(&device->mutex_pc_smmu); kgsl_active_count_put(device); } mutex_unlock(&device->mutex); } else } else { mutex_lock(&device->mutex_pc_smmu); unmapped = iommu_unmap(iommu_pt->domain, gpuaddr, range); mutex_unlock(&device->mutex_pc_smmu); } if (unmapped != range) { KGSL_CORE_ERR( "iommu_unmap(%p, %llx, %lld) failed with unmapped size: %zd\n", Loading Loading @@ -1197,9 +1203,11 @@ int _iommu_add_guard_page(struct kgsl_pagetable *pt, physaddr = kgsl_secure_guard_page_memdesc.physaddr; } mutex_lock(&pt->mmu->device->mutex_pc_smmu); ret = iommu_map(iommu_pt->domain, gpuaddr, physaddr, kgsl_memdesc_guard_page_size(memdesc), protflags & ~IOMMU_WRITE); mutex_unlock(&pt->mmu->device->mutex_pc_smmu); if (ret) { KGSL_CORE_ERR( "iommu_map(%p, addr %016llX, flags %x) err: %d\n", Loading Loading @@ -1247,15 +1255,21 @@ kgsl_iommu_map(struct kgsl_pagetable *pt, mutex_lock(&device->mutex); ret = kgsl_active_count_get(device); if (!ret) { mutex_lock(&device->mutex_pc_smmu); mapped = iommu_map_sg(iommu_pt->domain, addr, memdesc->sgt->sgl, memdesc->sgt->nents, flags); mutex_unlock(&device->mutex_pc_smmu); kgsl_active_count_put(device); } mutex_unlock(&device->mutex); } else } else { mutex_lock(&device->mutex_pc_smmu); mapped = iommu_map_sg(iommu_pt->domain, addr, memdesc->sgt->sgl, memdesc->sgt->nents, flags); mutex_unlock(&device->mutex_pc_smmu); } if (mapped != size) { KGSL_CORE_ERR("iommu_map_sg(%p, %016llX, %lld, %x) err: %zd\n", Loading @@ -1265,9 +1279,12 @@ kgsl_iommu_map(struct kgsl_pagetable *pt, } ret = _iommu_add_guard_page(pt, memdesc, addr + size, flags); if (ret) if (ret) { /* cleanup the partial mapping */ mutex_lock(&device->mutex_pc_smmu); iommu_unmap(iommu_pt->domain, addr, size); mutex_unlock(&device->mutex_pc_smmu); } /* * IOMMU V1 BFBs pre-fetch data beyond what is being used by the core. Loading drivers/gpu/msm/kgsl_pwrctrl.c +9 −0 Original line number Diff line number Diff line Loading @@ -1286,15 +1286,21 @@ static int kgsl_pwrctrl_pwrrail(struct kgsl_device *device, int state) if (test_and_clear_bit(KGSL_PWRFLAGS_POWER_ON, &pwr->power_flags)) { trace_kgsl_rail(device, state); mutex_lock(&device->mutex_pc_smmu); for (i = KGSL_MAX_REGULATORS - 1; i >= 0; i--) { if (pwr->gpu_reg[i]) regulator_disable(pwr->gpu_reg[i]); } mutex_unlock(&device->mutex_pc_smmu); } } else if (state == KGSL_PWRFLAGS_ON) { if (!test_and_set_bit(KGSL_PWRFLAGS_POWER_ON, &pwr->power_flags)) { mutex_lock(&device->mutex_pc_smmu); for (i = 0; i < KGSL_MAX_REGULATORS; i++) { if (regulator_is_enabled( device->pwrctrl.gpu_reg[i])) device->regulator_left_on = true; if (pwr->gpu_reg[i]) status = regulator_enable( pwr->gpu_reg[i]); Loading @@ -1306,13 +1312,16 @@ static int kgsl_pwrctrl_pwrrail(struct kgsl_device *device, int state) break; } } mutex_unlock(&device->mutex_pc_smmu); if (status) { mutex_lock(&device->mutex_pc_smmu); for (j = i - 1; j >= 0; j--) { if (pwr->gpu_reg[j]) regulator_disable( pwr->gpu_reg[j]); } mutex_unlock(&device->mutex_pc_smmu); clear_bit(KGSL_PWRFLAGS_POWER_ON, &pwr->power_flags); } else Loading Loading
drivers/gpu/msm/adreno.c +6 −14 Original line number Diff line number Diff line Loading @@ -1345,9 +1345,8 @@ static int _adreno_start(struct adreno_device *adreno_dev) { struct kgsl_device *device = &adreno_dev->dev; struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); int i, status = -EINVAL; int status = -EINVAL; unsigned int state = device->state; unsigned int regulator_left_on = 0; unsigned int pmqos_wakeup_vote = device->pwrctrl.pm_qos_wakeup_latency; unsigned int pmqos_active_vote = device->pwrctrl.pm_qos_active_latency; Loading @@ -1359,27 +1358,20 @@ static int _adreno_start(struct adreno_device *adreno_dev) kgsl_cffdump_open(device); for (i = 0; i < KGSL_MAX_REGULATORS; i++) { if (device->pwrctrl.gpu_reg[i] && regulator_is_enabled(device->pwrctrl.gpu_reg[i])) { regulator_left_on = 1; break; } } /* Clear any GPU faults that might have been left over */ adreno_clear_gpu_fault(adreno_dev); /* Put the GPU in a responsive state */ device->regulator_left_on = false; status = kgsl_pwrctrl_change_state(device, KGSL_STATE_AWARE); if (status) goto error_pwr_off; /* Clear any GPU faults that might have been left over */ adreno_clear_gpu_fault(adreno_dev); /* Set the bit to indicate that we've just powered on */ set_bit(ADRENO_DEVICE_PWRON, &adreno_dev->priv); /* Soft reset the GPU if a regulator is stuck on*/ if (regulator_left_on) if (device->regulator_left_on) _soft_reset(adreno_dev); status = kgsl_mmu_start(device); Loading
drivers/gpu/msm/kgsl_device.h +3 −0 Original line number Diff line number Diff line Loading @@ -250,6 +250,7 @@ struct kgsl_device { int open_count; struct mutex mutex; struct mutex mutex_pc_smmu; uint32_t state; uint32_t requested_state; Loading Loading @@ -289,6 +290,7 @@ struct kgsl_device { struct workqueue_struct *events_wq; struct device *busmondev; /* pseudo dev for GPU BW voting governor */ bool regulator_left_on; }; Loading @@ -303,6 +305,7 @@ struct kgsl_device { .wait_queue = __WAIT_QUEUE_HEAD_INITIALIZER((_dev).wait_queue),\ .active_cnt_wq = __WAIT_QUEUE_HEAD_INITIALIZER((_dev).active_cnt_wq),\ .mutex = __MUTEX_INITIALIZER((_dev).mutex),\ .mutex_pc_smmu = __MUTEX_INITIALIZER((_dev).mutex_pc_smmu),\ .state = KGSL_STATE_NONE,\ .ver_major = DRIVER_VERSION_MAJOR,\ .ver_minor = DRIVER_VERSION_MINOR Loading
drivers/gpu/msm/kgsl_iommu.c +20 −3 Original line number Diff line number Diff line Loading @@ -1022,6 +1022,7 @@ static int kgsl_iommu_start(struct kgsl_mmu *mmu) kgsl_map_global_pt_entries(mmu->defaultpagetable); kgsl_iommu_enable_clk(mmu); KGSL_IOMMU_SET_CTX_REG(iommu, 0, TLBIALL, 1); /* Get the lsb value of pagetables set in the IOMMU ttbr0 register as * that value should not change when we change pagetables, so while Loading Loading @@ -1130,13 +1131,18 @@ kgsl_iommu_unmap(struct kgsl_pagetable *pt, mutex_lock(&device->mutex); ret = kgsl_active_count_get(device); if (!ret) { mutex_lock(&device->mutex_pc_smmu); unmapped = iommu_unmap(iommu_pt->domain, gpuaddr, range); mutex_unlock(&device->mutex_pc_smmu); kgsl_active_count_put(device); } mutex_unlock(&device->mutex); } else } else { mutex_lock(&device->mutex_pc_smmu); unmapped = iommu_unmap(iommu_pt->domain, gpuaddr, range); mutex_unlock(&device->mutex_pc_smmu); } if (unmapped != range) { KGSL_CORE_ERR( "iommu_unmap(%p, %llx, %lld) failed with unmapped size: %zd\n", Loading Loading @@ -1197,9 +1203,11 @@ int _iommu_add_guard_page(struct kgsl_pagetable *pt, physaddr = kgsl_secure_guard_page_memdesc.physaddr; } mutex_lock(&pt->mmu->device->mutex_pc_smmu); ret = iommu_map(iommu_pt->domain, gpuaddr, physaddr, kgsl_memdesc_guard_page_size(memdesc), protflags & ~IOMMU_WRITE); mutex_unlock(&pt->mmu->device->mutex_pc_smmu); if (ret) { KGSL_CORE_ERR( "iommu_map(%p, addr %016llX, flags %x) err: %d\n", Loading Loading @@ -1247,15 +1255,21 @@ kgsl_iommu_map(struct kgsl_pagetable *pt, mutex_lock(&device->mutex); ret = kgsl_active_count_get(device); if (!ret) { mutex_lock(&device->mutex_pc_smmu); mapped = iommu_map_sg(iommu_pt->domain, addr, memdesc->sgt->sgl, memdesc->sgt->nents, flags); mutex_unlock(&device->mutex_pc_smmu); kgsl_active_count_put(device); } mutex_unlock(&device->mutex); } else } else { mutex_lock(&device->mutex_pc_smmu); mapped = iommu_map_sg(iommu_pt->domain, addr, memdesc->sgt->sgl, memdesc->sgt->nents, flags); mutex_unlock(&device->mutex_pc_smmu); } if (mapped != size) { KGSL_CORE_ERR("iommu_map_sg(%p, %016llX, %lld, %x) err: %zd\n", Loading @@ -1265,9 +1279,12 @@ kgsl_iommu_map(struct kgsl_pagetable *pt, } ret = _iommu_add_guard_page(pt, memdesc, addr + size, flags); if (ret) if (ret) { /* cleanup the partial mapping */ mutex_lock(&device->mutex_pc_smmu); iommu_unmap(iommu_pt->domain, addr, size); mutex_unlock(&device->mutex_pc_smmu); } /* * IOMMU V1 BFBs pre-fetch data beyond what is being used by the core. Loading
drivers/gpu/msm/kgsl_pwrctrl.c +9 −0 Original line number Diff line number Diff line Loading @@ -1286,15 +1286,21 @@ static int kgsl_pwrctrl_pwrrail(struct kgsl_device *device, int state) if (test_and_clear_bit(KGSL_PWRFLAGS_POWER_ON, &pwr->power_flags)) { trace_kgsl_rail(device, state); mutex_lock(&device->mutex_pc_smmu); for (i = KGSL_MAX_REGULATORS - 1; i >= 0; i--) { if (pwr->gpu_reg[i]) regulator_disable(pwr->gpu_reg[i]); } mutex_unlock(&device->mutex_pc_smmu); } } else if (state == KGSL_PWRFLAGS_ON) { if (!test_and_set_bit(KGSL_PWRFLAGS_POWER_ON, &pwr->power_flags)) { mutex_lock(&device->mutex_pc_smmu); for (i = 0; i < KGSL_MAX_REGULATORS; i++) { if (regulator_is_enabled( device->pwrctrl.gpu_reg[i])) device->regulator_left_on = true; if (pwr->gpu_reg[i]) status = regulator_enable( pwr->gpu_reg[i]); Loading @@ -1306,13 +1312,16 @@ static int kgsl_pwrctrl_pwrrail(struct kgsl_device *device, int state) break; } } mutex_unlock(&device->mutex_pc_smmu); if (status) { mutex_lock(&device->mutex_pc_smmu); for (j = i - 1; j >= 0; j--) { if (pwr->gpu_reg[j]) regulator_disable( pwr->gpu_reg[j]); } mutex_unlock(&device->mutex_pc_smmu); clear_bit(KGSL_PWRFLAGS_POWER_ON, &pwr->power_flags); } else Loading