Loading drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h +18 −10 Original line number Diff line number Diff line Loading @@ -28,6 +28,18 @@ struct nvkm_timer { u64 nvkm_timer_read(struct nvkm_timer *); void nvkm_timer_alarm(struct nvkm_timer *, u32 nsec, struct nvkm_alarm *); struct nvkm_timer_wait { struct nvkm_timer *tmr; u64 limit; u64 time0; u64 time1; int reads; }; void nvkm_timer_wait_init(struct nvkm_device *, u64 nsec, struct nvkm_timer_wait *); s64 nvkm_timer_wait_test(struct nvkm_timer_wait *); /* Delay based on GPU time (ie. PTIMER). * * Will return -ETIMEDOUT unless the loop was terminated with 'break', Loading @@ -38,21 +50,17 @@ void nvkm_timer_alarm(struct nvkm_timer *, u32 nsec, struct nvkm_alarm *); */ #define NVKM_DELAY _warn = false; #define nvkm_nsec(d,n,cond...) ({ \ struct nvkm_device *_device = (d); \ struct nvkm_timer *_tmr = _device->timer; \ u64 _nsecs = (n), _time0 = nvkm_timer_read(_tmr); \ s64 _taken = 0; \ struct nvkm_timer_wait _wait; \ bool _warn = true; \ s64 _taken = 0; \ \ nvkm_timer_wait_init((d), (n), &_wait); \ do { \ cond \ } while (_taken = nvkm_timer_read(_tmr) - _time0, _taken < _nsecs); \ } while ((_taken = nvkm_timer_wait_test(&_wait)) >= 0); \ \ if (_taken >= _nsecs) { \ if (_warn) \ dev_WARN(_device->dev, "timeout\n"); \ _taken = -ETIMEDOUT; \ } \ if (_warn && _taken < 0) \ dev_WARN(_wait.tmr->subdev.device->dev, "timeout\n"); \ _taken; \ }) #define nvkm_usec(d,u,cond...) nvkm_nsec((d), (u) * 1000, ##cond) Loading drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c +36 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading
drivers/gpu/drm/nouveau/include/nvkm/subdev/timer.h +18 −10 Original line number Diff line number Diff line Loading @@ -28,6 +28,18 @@ struct nvkm_timer { u64 nvkm_timer_read(struct nvkm_timer *); void nvkm_timer_alarm(struct nvkm_timer *, u32 nsec, struct nvkm_alarm *); struct nvkm_timer_wait { struct nvkm_timer *tmr; u64 limit; u64 time0; u64 time1; int reads; }; void nvkm_timer_wait_init(struct nvkm_device *, u64 nsec, struct nvkm_timer_wait *); s64 nvkm_timer_wait_test(struct nvkm_timer_wait *); /* Delay based on GPU time (ie. PTIMER). * * Will return -ETIMEDOUT unless the loop was terminated with 'break', Loading @@ -38,21 +50,17 @@ void nvkm_timer_alarm(struct nvkm_timer *, u32 nsec, struct nvkm_alarm *); */ #define NVKM_DELAY _warn = false; #define nvkm_nsec(d,n,cond...) ({ \ struct nvkm_device *_device = (d); \ struct nvkm_timer *_tmr = _device->timer; \ u64 _nsecs = (n), _time0 = nvkm_timer_read(_tmr); \ s64 _taken = 0; \ struct nvkm_timer_wait _wait; \ bool _warn = true; \ s64 _taken = 0; \ \ nvkm_timer_wait_init((d), (n), &_wait); \ do { \ cond \ } while (_taken = nvkm_timer_read(_tmr) - _time0, _taken < _nsecs); \ } while ((_taken = nvkm_timer_wait_test(&_wait)) >= 0); \ \ if (_taken >= _nsecs) { \ if (_warn) \ dev_WARN(_device->dev, "timeout\n"); \ _taken = -ETIMEDOUT; \ } \ if (_warn && _taken < 0) \ dev_WARN(_wait.tmr->subdev.device->dev, "timeout\n"); \ _taken; \ }) #define nvkm_usec(d,u,cond...) nvkm_nsec((d), (u) * 1000, ##cond) Loading
drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c +36 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading