diff options
| -rw-r--r-- | drivers/gpu/msm/adreno.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/msm/adreno_dispatch.c | 31 | ||||
| -rw-r--r-- | drivers/gpu/msm/adreno_dispatch.h | 3 | ||||
| -rw-r--r-- | drivers/gpu/msm/kgsl_device.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/msm/kgsl_pwrctrl.c | 1 |
5 files changed, 35 insertions, 2 deletions
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 0f582cf35e6b..b852330d5671 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -2771,6 +2771,7 @@ static const struct kgsl_functable adreno_functable = { .regulator_disable_poll = adreno_regulator_disable_poll, .clk_set_options = adreno_clk_set_options, .gpu_model = adreno_gpu_model, + .stop_fault_timer = adreno_dispatcher_stop_fault_timer, }; static struct platform_driver adreno_platform_driver = { diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c index 89218b62bb7d..f084ca9a62a1 100644 --- a/drivers/gpu/msm/adreno_dispatch.c +++ b/drivers/gpu/msm/adreno_dispatch.c @@ -208,6 +208,9 @@ static inline bool _isidle(struct adreno_device *adreno_dev) if (!kgsl_state_is_awake(KGSL_DEVICE(adreno_dev))) goto ret; + if (adreno_rb_empty(adreno_dev->cur_rb)) + goto ret; + /* only check rbbm status to determine if GPU is idle */ adreno_readreg(adreno_dev, ADRENO_REG_RBBM_STATUS, ®_rbbm_status); @@ -2051,6 +2054,18 @@ static int dispatcher_do_fault(struct adreno_device *adreno_dev) return 0; /* + * In the very unlikely case that the power is off, do nothing - the + * state will be reset on power up and everybody will be happy + */ + + if (!kgsl_state_is_awake(device) && (fault & ADRENO_SOFT_FAULT)) { + /* Clear the existing register values */ + memset(adreno_ft_regs_val, 0, + adreno_ft_regs_num * sizeof(unsigned int)); + return 0; + } + + /* * On A5xx, read RBBM_STATUS3:SMMU_STALLED_ON_FAULT (BIT 24) to * tell if this function was entered after a pagefault. If so, only * proceed if the fault handler has already run in the IRQ thread, @@ -2505,7 +2520,7 @@ static void adreno_dispatcher_fault_timer(unsigned long data) if (!fault_detect_read_compare(adreno_dev)) { adreno_set_gpu_fault(adreno_dev, ADRENO_SOFT_FAULT); adreno_dispatcher_schedule(KGSL_DEVICE(adreno_dev)); - } else { + } else if (dispatcher->inflight > 0) { mod_timer(&dispatcher->fault_timer, jiffies + msecs_to_jiffies(_fault_timer_interval)); } @@ -2550,6 +2565,20 @@ void adreno_dispatcher_stop(struct adreno_device *adreno_dev) } /** + * adreno_dispatcher_stop() - stop the dispatcher fault timer + * @adreno_dev: pointer to the adreno device structure + * + * Stop the dispatcher fault timer + */ +void adreno_dispatcher_stop_fault_timer(struct kgsl_device *device) +{ + struct adreno_device *adreno_dev = ADRENO_DEVICE(device); + struct adreno_dispatcher *dispatcher = &adreno_dev->dispatcher; + + del_timer_sync(&dispatcher->fault_timer); +} + +/** * adreno_dispatcher_close() - close the dispatcher * @adreno_dev: pointer to the adreno device structure * diff --git a/drivers/gpu/msm/adreno_dispatch.h b/drivers/gpu/msm/adreno_dispatch.h index cb9106fedc82..72545db12f90 100644 --- a/drivers/gpu/msm/adreno_dispatch.h +++ b/drivers/gpu/msm/adreno_dispatch.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -108,6 +108,7 @@ void adreno_dispatcher_close(struct adreno_device *adreno_dev); int adreno_dispatcher_idle(struct adreno_device *adreno_dev); void adreno_dispatcher_irq_fault(struct adreno_device *adreno_dev); void adreno_dispatcher_stop(struct adreno_device *adreno_dev); +void adreno_dispatcher_stop_fault_timer(struct kgsl_device *device); int adreno_dispatcher_queue_cmds(struct kgsl_device_private *dev_priv, struct kgsl_context *context, struct kgsl_drawobj *drawobj[], diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 0a2c39b82781..aca484618268 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -169,6 +169,7 @@ struct kgsl_functable { const char *name, struct clk *clk); void (*gpu_model)(struct kgsl_device *device, char *str, size_t bufsz); + void (*stop_fault_timer)(struct kgsl_device *device); }; struct kgsl_ioctl { diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c index e639e197de93..e4c431546d2a 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -2600,6 +2600,7 @@ _nap(struct kgsl_device *device) return -EBUSY; } + device->ftbl->stop_fault_timer(device); kgsl_pwrscale_midframe_timer_cancel(device); /* |
