[PATCH RFC 062/111] staging: etnaviv: ensure GPU reset times out
Lucas Stach
l.stach at pengutronix.de
Thu Apr 2 08:30:04 PDT 2015
From: Russell King <rmk+kernel at arm.linux.org.uk>
Rather than waiting indefinitely for the GPU to reset, bound this and
if it doesn't appear to be successful, bail out and report why we
failed.
Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
drivers/staging/etnaviv/etnaviv_gpu.c | 32 +++++++++++++++++++++++++++-----
1 file changed, 27 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/etnaviv/etnaviv_gpu.c b/drivers/staging/etnaviv/etnaviv_gpu.c
index 4cd84740eac8..f2ce3c71e583 100644
--- a/drivers/staging/etnaviv/etnaviv_gpu.c
+++ b/drivers/staging/etnaviv/etnaviv_gpu.c
@@ -287,9 +287,11 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
etnaviv_hw_specs(gpu);
}
-static void etnaviv_hw_reset(struct etnaviv_gpu *gpu)
+static int etnaviv_hw_reset(struct etnaviv_gpu *gpu)
{
u32 control, idle;
+ unsigned long timeout;
+ bool failed = true;
/* TODO
*
@@ -298,7 +300,10 @@ static void etnaviv_hw_reset(struct etnaviv_gpu *gpu)
* - what about VG?
*/
- while (true) {
+ /* We hope that the GPU resets in under one second */
+ timeout = jiffies + msecs_to_jiffies(1000);
+
+ while (time_is_after_jiffies(timeout)) {
control = VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS |
VIVS_HI_CLOCK_CONTROL_FSCALE_VAL(0x40);
@@ -342,15 +347,28 @@ static void etnaviv_hw_reset(struct etnaviv_gpu *gpu)
control = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
/* is the GPU idle? */
- if (((control & VIVS_HI_CLOCK_CONTROL_IDLE_3D) == 0)
- || ((control & VIVS_HI_CLOCK_CONTROL_IDLE_2D) == 0)) {
+ if (((control & VIVS_HI_CLOCK_CONTROL_IDLE_3D) == 0) ||
+ ((control & VIVS_HI_CLOCK_CONTROL_IDLE_2D) == 0)) {
dev_dbg(gpu->dev, "GPU is not idle\n");
continue;
}
+ failed = false;
break;
}
+ if (failed) {
+ idle = gpu_read(gpu, VIVS_HI_IDLE_STATE);
+ control = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
+
+ dev_err(gpu->dev, "GPU failed to reset: FE %sidle, 3D %sidle, 2D %sidle\n",
+ idle & VIVS_HI_IDLE_STATE_FE ? "" : "not ",
+ control & VIVS_HI_CLOCK_CONTROL_IDLE_3D ? "" : "not ",
+ control & VIVS_HI_CLOCK_CONTROL_IDLE_2D ? "" : "not ");
+
+ return -EBUSY;
+ }
+
/* We rely on the GPU running, so program the clock */
control = VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS |
VIVS_HI_CLOCK_CONTROL_FSCALE_VAL(0x40);
@@ -359,6 +377,8 @@ static void etnaviv_hw_reset(struct etnaviv_gpu *gpu)
gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control |
VIVS_HI_CLOCK_CONTROL_FSCALE_CMD_LOAD);
gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control);
+
+ return 0;
}
int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
@@ -369,7 +389,9 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
bool mmuv2;
etnaviv_hw_identify(gpu);
- etnaviv_hw_reset(gpu);
+ ret = etnaviv_hw_reset(gpu);
+ if (ret)
+ return ret;
/* set base addresses */
gpu_write(gpu, VIVS_MC_MEMORY_BASE_ADDR_RA, 0x0);
--
2.1.4
More information about the dri-devel
mailing list