From: Russell King <rmk+kernel@xxxxxxxxxxxxxxxx> 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@xxxxxxxxxxxxxxxx> --- 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 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel