Commit a6fd8f93 authored by Ben Skeggs's avatar Ben Skeggs Committed by Dave Airlie
Browse files

drm/nouveau/disp: add supervisor mutex



Will be used to protect NVIF_CLASS_OUTP method calls from racing with
in-progress supervisor handling.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 32dd9236
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ struct nvkm_disp {
		struct workqueue_struct *wq;
		struct work_struct work;
		u32 pending;
		struct mutex mutex;
	} super;

#define NVKM_DISP_EVENT_CHAN_AWAKEN BIT(0)
+5 −1
Original line number Diff line number Diff line
@@ -399,8 +399,11 @@ nvkm_disp_dtor(struct nvkm_engine *engine)
	nvkm_gpuobj_del(&disp->inst);

	nvkm_event_fini(&disp->uevent);
	if (disp->super.wq)

	if (disp->super.wq) {
		destroy_workqueue(disp->super.wq);
		mutex_destroy(&disp->super.mutex);
	}

	nvkm_event_fini(&disp->vblank);
	nvkm_event_fini(&disp->hpd);
@@ -467,6 +470,7 @@ nvkm_disp_new_(const struct nvkm_disp_func *func, struct nvkm_device *device,
			return -ENOMEM;

		INIT_WORK(&disp->super.work, func->super);
		mutex_init(&disp->super.mutex);
	}

	return nvkm_event_init(func->uevent, 1, ARRAY_SIZE(disp->chan), &disp->uevent);
+4 −0
Original line number Diff line number Diff line
@@ -995,6 +995,8 @@ gf119_disp_super(struct work_struct *work)
	u32 mask[4];

	nvkm_debug(subdev, "supervisor %d\n", ffs(disp->super.pending));
	mutex_lock(&disp->super.mutex);

	list_for_each_entry(head, &disp->heads, head) {
		mask[head->id] = nvkm_rd32(device, 0x6101d4 + (head->id * 0x800));
		HEAD_DBG(head, "%08x", mask[head->id]);
@@ -1037,7 +1039,9 @@ gf119_disp_super(struct work_struct *work)

	list_for_each_entry(head, &disp->heads, head)
		nvkm_wr32(device, 0x6101d4 + (head->id * 0x800), 0x00000000);

	nvkm_wr32(device, 0x6101d0, 0x80000000);
	mutex_unlock(&disp->super.mutex);
}

void
+6 −2
Original line number Diff line number Diff line
@@ -818,8 +818,10 @@ gv100_disp_super(struct work_struct *work)
	struct nvkm_subdev *subdev = &disp->engine.subdev;
	struct nvkm_device *device = subdev->device;
	struct nvkm_head *head;
	u32 stat = nvkm_rd32(device, 0x6107a8);
	u32 mask[4];
	u32 stat, mask[4];

	mutex_lock(&disp->super.mutex);
	stat = nvkm_rd32(device, 0x6107a8);

	nvkm_debug(subdev, "supervisor %d: %08x\n", ffs(disp->super.pending), stat);
	list_for_each_entry(head, &disp->heads, head) {
@@ -864,7 +866,9 @@ gv100_disp_super(struct work_struct *work)

	list_for_each_entry(head, &disp->heads, head)
		nvkm_wr32(device, 0x6107ac + (head->id * 4), 0x00000000);

	nvkm_wr32(device, 0x6107a8, 0x80000000);
	mutex_unlock(&disp->super.mutex);
}

static void
+5 −1
Original line number Diff line number Diff line
@@ -1345,7 +1345,10 @@ nv50_disp_super(struct work_struct *work)
	struct nvkm_subdev *subdev = &disp->engine.subdev;
	struct nvkm_device *device = subdev->device;
	struct nvkm_head *head;
	u32 super = nvkm_rd32(device, 0x610030);
	u32 super;

	mutex_lock(&disp->super.mutex);
	super = nvkm_rd32(device, 0x610030);

	nvkm_debug(subdev, "supervisor %08x %08x\n", disp->super.pending, super);

@@ -1387,6 +1390,7 @@ nv50_disp_super(struct work_struct *work)
	}

	nvkm_wr32(device, 0x610030, 0x80000000);
	mutex_unlock(&disp->super.mutex);
}

const struct nvkm_enum