void nvkm_fifo_fault(struct nvkm_fifo *, struct nvkm_fault_data *);
void nvkm_fifo_pause(struct nvkm_fifo *, unsigned long *);
void nvkm_fifo_start(struct nvkm_fifo *, unsigned long *);
+bool nvkm_fifo_ctxsw_in_progress(struct nvkm_engine *);
int nv04_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int nv10_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
#include <nvif/cl0080.h>
#include <nvif/unpack.h>
+bool
+nvkm_fifo_ctxsw_in_progress(struct nvkm_engine *engine)
+{
+ struct nvkm_runl *runl;
+ struct nvkm_engn *engn;
+
+ nvkm_runl_foreach(runl, engine->subdev.device->fifo) {
+ nvkm_runl_foreach_engn(engn, runl) {
+ if (engn->engine == engine)
+ return engn->func->chsw ? engn->func->chsw(engn) : false;
+ }
+ }
+
+ return false;
+}
+
void
nvkm_fifo_pause(struct nvkm_fifo *fifo, unsigned long *flags)
{
nvkm_rd32(device, 0x400700);
gr_enabled = nvkm_rd32(device, 0x200) & 0x1000;
- ctxsw_active = nvkm_rd32(device, 0x2640) & 0x8000;
+ ctxsw_active = nvkm_fifo_ctxsw_in_progress(&gr->base.engine);
gr_busy = nvkm_rd32(device, 0x40060c) & 0x1;
if (!gr_enabled || (!gr_busy && !ctxsw_active))