Loading drivers/gpu/msm/adreno.c +40 −1 Original line number Diff line number Diff line Loading @@ -532,6 +532,44 @@ static inline void refcount_group(struct adreno_perfcount_group *group, *hi = group->regs[reg].offset_hi; } /** * adreno_idle_unsafe() - wait for the GPU hardware to go idle * * This doesn't check for dispatcher mutex owner. Hence this function * should be called only if we are sure that we dont own dispatcher mutex * in this thread. * * @device: Pointer to the KGSL device structure for the GPU * * Wait up to ADRENO_IDLE_TIMEOUT milliseconds for the GPU hardware to go quiet. */ static int adreno_idle_unsafe(struct kgsl_device *device) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); int ret; /* * Make sure the device mutex is held so the dispatcher can't send any * more commands to the hardware */ BUG_ON(!mutex_is_locked(&device->mutex)); /* Check if we are already idle before idling dispatcher */ if (adreno_isidle(device)) return 0; /* * Wait for dispatcher to finish completing commands * already submitted */ ret = adreno_dispatcher_idle_unsafe(adreno_dev); if (ret) return ret; return adreno_spin_idle(device); } /** * adreno_perfcounter_get: Try to put a countable in an available counter * @adreno_dev: Adreno device to configure Loading Loading @@ -614,7 +652,8 @@ int adreno_perfcounter_get(struct adreno_device *adreno_dev, if (empty == -1) return -EBUSY; ret = adreno_idle(&adreno_dev->dev); ret = adreno_idle_unsafe(&adreno_dev->dev); if (ret) return ret; Loading drivers/gpu/msm/adreno.h +1 −0 Original line number Diff line number Diff line Loading @@ -730,6 +730,7 @@ void adreno_dispatcher_start(struct kgsl_device *device); int adreno_dispatcher_init(struct adreno_device *adreno_dev); void adreno_dispatcher_close(struct adreno_device *adreno_dev); int adreno_dispatcher_idle(struct adreno_device *adreno_dev); int adreno_dispatcher_idle_unsafe(struct adreno_device *adreno_dev); void adreno_dispatcher_irq_fault(struct kgsl_device *device); void adreno_dispatcher_stop(struct adreno_device *adreno_dev); Loading drivers/gpu/msm/adreno_dispatch.c +28 −4 Original line number Diff line number Diff line Loading @@ -2020,7 +2020,6 @@ int adreno_dispatcher_idle(struct adreno_device *adreno_dev) { struct kgsl_device *device = &adreno_dev->dev; struct adreno_dispatcher *dispatcher = &adreno_dev->dispatcher; int ret; BUG_ON(!mutex_is_locked(&device->mutex)); if (!test_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv)) Loading @@ -2034,15 +2033,40 @@ int adreno_dispatcher_idle(struct adreno_device *adreno_dev) dispatcher->mutex.owner == current) BUG_ON(1); return adreno_dispatcher_idle_unsafe(adreno_dev); } /* * adreno_dispatcher_idle_unsafe() - Wait for dispatcher to idle * * * @adreno_dev: Adreno device whose dispatcher needs to idle * * Signal dispatcher to stop sending more commands and complete * the commands that have already been submitted. * This function should not be called when dispatcher mutex is held * since it doesnt check for dispatcher mutex owner. */ int adreno_dispatcher_idle_unsafe(struct adreno_device *adreno_dev) { struct kgsl_device *device = &adreno_dev->dev; struct adreno_dispatcher *dispatcher = &adreno_dev->dispatcher; int ret; BUG_ON(!mutex_is_locked(&device->mutex)); if (!test_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv)) return 0; adreno_get_gpu_halt(adreno_dev); kgsl_mutex_unlock(&device->mutex, &device->mutex_owner); ret = wait_for_completion_timeout(&dispatcher->idle_gate, msecs_to_jiffies(ADRENO_IDLE_TIMEOUT)); if (ret <= 0) { if (!ret) if (ret == 0) { ret = -ETIMEDOUT; WARN(1, "Dispatcher halt timeout "); } else if (ret < 0) { KGSL_DRV_ERR(device, "Dispatcher halt failed %d\n", ret); } else { ret = 0; Loading Loading
drivers/gpu/msm/adreno.c +40 −1 Original line number Diff line number Diff line Loading @@ -532,6 +532,44 @@ static inline void refcount_group(struct adreno_perfcount_group *group, *hi = group->regs[reg].offset_hi; } /** * adreno_idle_unsafe() - wait for the GPU hardware to go idle * * This doesn't check for dispatcher mutex owner. Hence this function * should be called only if we are sure that we dont own dispatcher mutex * in this thread. * * @device: Pointer to the KGSL device structure for the GPU * * Wait up to ADRENO_IDLE_TIMEOUT milliseconds for the GPU hardware to go quiet. */ static int adreno_idle_unsafe(struct kgsl_device *device) { struct adreno_device *adreno_dev = ADRENO_DEVICE(device); int ret; /* * Make sure the device mutex is held so the dispatcher can't send any * more commands to the hardware */ BUG_ON(!mutex_is_locked(&device->mutex)); /* Check if we are already idle before idling dispatcher */ if (adreno_isidle(device)) return 0; /* * Wait for dispatcher to finish completing commands * already submitted */ ret = adreno_dispatcher_idle_unsafe(adreno_dev); if (ret) return ret; return adreno_spin_idle(device); } /** * adreno_perfcounter_get: Try to put a countable in an available counter * @adreno_dev: Adreno device to configure Loading Loading @@ -614,7 +652,8 @@ int adreno_perfcounter_get(struct adreno_device *adreno_dev, if (empty == -1) return -EBUSY; ret = adreno_idle(&adreno_dev->dev); ret = adreno_idle_unsafe(&adreno_dev->dev); if (ret) return ret; Loading
drivers/gpu/msm/adreno.h +1 −0 Original line number Diff line number Diff line Loading @@ -730,6 +730,7 @@ void adreno_dispatcher_start(struct kgsl_device *device); int adreno_dispatcher_init(struct adreno_device *adreno_dev); void adreno_dispatcher_close(struct adreno_device *adreno_dev); int adreno_dispatcher_idle(struct adreno_device *adreno_dev); int adreno_dispatcher_idle_unsafe(struct adreno_device *adreno_dev); void adreno_dispatcher_irq_fault(struct kgsl_device *device); void adreno_dispatcher_stop(struct adreno_device *adreno_dev); Loading
drivers/gpu/msm/adreno_dispatch.c +28 −4 Original line number Diff line number Diff line Loading @@ -2020,7 +2020,6 @@ int adreno_dispatcher_idle(struct adreno_device *adreno_dev) { struct kgsl_device *device = &adreno_dev->dev; struct adreno_dispatcher *dispatcher = &adreno_dev->dispatcher; int ret; BUG_ON(!mutex_is_locked(&device->mutex)); if (!test_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv)) Loading @@ -2034,15 +2033,40 @@ int adreno_dispatcher_idle(struct adreno_device *adreno_dev) dispatcher->mutex.owner == current) BUG_ON(1); return adreno_dispatcher_idle_unsafe(adreno_dev); } /* * adreno_dispatcher_idle_unsafe() - Wait for dispatcher to idle * * * @adreno_dev: Adreno device whose dispatcher needs to idle * * Signal dispatcher to stop sending more commands and complete * the commands that have already been submitted. * This function should not be called when dispatcher mutex is held * since it doesnt check for dispatcher mutex owner. */ int adreno_dispatcher_idle_unsafe(struct adreno_device *adreno_dev) { struct kgsl_device *device = &adreno_dev->dev; struct adreno_dispatcher *dispatcher = &adreno_dev->dispatcher; int ret; BUG_ON(!mutex_is_locked(&device->mutex)); if (!test_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv)) return 0; adreno_get_gpu_halt(adreno_dev); kgsl_mutex_unlock(&device->mutex, &device->mutex_owner); ret = wait_for_completion_timeout(&dispatcher->idle_gate, msecs_to_jiffies(ADRENO_IDLE_TIMEOUT)); if (ret <= 0) { if (!ret) if (ret == 0) { ret = -ETIMEDOUT; WARN(1, "Dispatcher halt timeout "); } else if (ret < 0) { KGSL_DRV_ERR(device, "Dispatcher halt failed %d\n", ret); } else { ret = 0; Loading