From e4f90a35c9668f8d0469a0160482b1856d07c2b5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 11 Dec 2018 14:50:02 +1000 Subject: drm/nouveau/tmr: detect stalled gpu timer and break out of waits Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c') diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c index 36de23d12ae4..dd922033628c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c @@ -23,6 +23,42 @@ */ #include "priv.h" +s64 +nvkm_timer_wait_test(struct nvkm_timer_wait *wait) +{ + struct nvkm_subdev *subdev = &wait->tmr->subdev; + u64 time = nvkm_timer_read(wait->tmr); + + if (wait->reads == 0) { + wait->time0 = time; + wait->time1 = time; + } + + if (wait->time1 == time) { + if (wait->reads++ == 16) { + nvkm_fatal(subdev, "stalled at %016llx\n", time); + return -ETIMEDOUT; + } + } else { + wait->time1 = time; + wait->reads = 1; + } + + if (wait->time1 - wait->time0 > wait->limit) + return -ETIMEDOUT; + + return wait->time1 - wait->time0; +} + +void +nvkm_timer_wait_init(struct nvkm_device *device, u64 nsec, + struct nvkm_timer_wait *wait) +{ + wait->tmr = device->timer; + wait->limit = nsec; + wait->reads = 0; +} + u64 nvkm_timer_read(struct nvkm_timer *tmr) { -- cgit v1.2.3-55-g7522