diff options
| author | Hareesh Gundu <hareeshg@codeaurora.org> | 2017-03-06 14:53:36 +0530 |
|---|---|---|
| committer | Hareesh Gundu <hareeshg@codeaurora.org> | 2017-03-09 13:07:07 +0530 |
| commit | 6439032d0b0a1fc2ce53bdffde6fe28ae0aa37c0 (patch) | |
| tree | 028c6dee3b6b5189fea0a21b40c9fd8a8fa3a697 /drivers/gpu | |
| parent | c78ba94d64e9a29e697cb5f2b8dcd7998f54b995 (diff) | |
msm: kgsl: Improve GPU soft fault detection
Following changes been made to improve soft fault detection,
which will fix un clocked register access in dispatcher_do_fault()
and incorrect declaration of GPU soft fault.
i) Stop fault timer before entering to NAP state
ii) Don’t start fault timer if the dispatcher inflight count is zero
iii) Add ringbuffer empty check in _isidle()
iv) Add device state check in dispatcher_do_fault()
CRs-Fixed: 2012731
Change-Id: I5ce498029f389eeeb428b4ac7fb07afd84d5764c
Signed-off-by: Hareesh Gundu <hareeshg@codeaurora.org>
Diffstat (limited to 'drivers/gpu')
| -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); /* |
