Commit 169f30b3 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/gr/gf100-: expose fecs methods for pausing ctxsw



MMU will need access to these.

v2. Apply fix from Rhys Kidd to send correct FECS method for STOP_CTXSW.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 8e083686
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@ struct nvkm_gr {

u64 nvkm_gr_units(struct nvkm_gr *);
int nvkm_gr_tlb_flush(struct nvkm_gr *);
int nvkm_gr_ctxsw_pause(struct nvkm_device *);
int nvkm_gr_ctxsw_resume(struct nvkm_device *);

int nv04_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int nv10_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
+18 −0
Original line number Diff line number Diff line
@@ -25,6 +25,24 @@

#include <engine/fifo.h>

int
nvkm_gr_ctxsw_resume(struct nvkm_device *device)
{
	struct nvkm_gr *gr = device->gr;
	if (gr && gr->func->ctxsw.resume)
		return gr->func->ctxsw.resume(gr);
	return 0;
}

int
nvkm_gr_ctxsw_pause(struct nvkm_device *device)
{
	struct nvkm_gr *gr = device->gr;
	if (gr && gr->func->ctxsw.pause)
		return gr->func->ctxsw.pause(gr);
	return 0;
}

static bool
nvkm_gr_chsw_load(struct nvkm_engine *engine)
{
+54 −0
Original line number Diff line number Diff line
@@ -715,6 +715,56 @@ gf100_gr_pack_mmio[] = {
 * PGRAPH engine/subdev functions
 ******************************************************************************/

static int
gf100_gr_fecs_ctrl_ctxsw(struct gf100_gr *gr, u32 mthd)
{
	struct nvkm_device *device = gr->base.engine.subdev.device;

	nvkm_wr32(device, 0x409804, 0xffffffff);
	nvkm_wr32(device, 0x409840, 0xffffffff);
	nvkm_wr32(device, 0x409500, 0xffffffff);
	nvkm_wr32(device, 0x409504, mthd);
	nvkm_msec(device, 2000,
		u32 stat = nvkm_rd32(device, 0x409804);
		if (stat == 0x00000002)
			return -EIO;
		if (stat == 0x00000001)
			return 0;
	);

	return -ETIMEDOUT;
}

int
gf100_gr_fecs_start_ctxsw(struct nvkm_gr *base)
{
	struct gf100_gr *gr = gf100_gr(base);
	int ret = 0;

	mutex_lock(&gr->fecs.mutex);
	if (!--gr->fecs.disable) {
		if (WARN_ON(ret = gf100_gr_fecs_ctrl_ctxsw(gr, 0x39)))
			gr->fecs.disable++;
	}
	mutex_unlock(&gr->fecs.mutex);
	return ret;
}

int
gf100_gr_fecs_stop_ctxsw(struct nvkm_gr *base)
{
	struct gf100_gr *gr = gf100_gr(base);
	int ret = 0;

	mutex_lock(&gr->fecs.mutex);
	if (!gr->fecs.disable++) {
		if (WARN_ON(ret = gf100_gr_fecs_ctrl_ctxsw(gr, 0x38)))
			gr->fecs.disable--;
	}
	mutex_unlock(&gr->fecs.mutex);
	return ret;
}

int
gf100_gr_fecs_bind_pointer(struct gf100_gr *gr, u32 inst)
{
@@ -1891,6 +1941,8 @@ gf100_gr_oneinit(struct nvkm_gr *base)
	if (ret)
		return ret;

	mutex_init(&gr->fecs.mutex);

	ret = nvkm_falcon_v1_new(subdev, "GPCCS", 0x41a000, &gr->gpccs.falcon);
	if (ret)
		return ret;
@@ -2004,6 +2056,8 @@ gf100_gr_ = {
	.chan_new = gf100_gr_chan_new,
	.object_get = gf100_gr_object_get,
	.chsw_load = gf100_gr_chsw_load,
	.ctxsw.pause = gf100_gr_fecs_stop_ctxsw,
	.ctxsw.resume = gf100_gr_fecs_start_ctxsw,
};

int
+2 −0
Original line number Diff line number Diff line
@@ -84,6 +84,8 @@ struct gf100_gr {

	struct {
		struct nvkm_falcon *falcon;
		struct mutex mutex;
		u32 disable;
	} fecs;

	struct {
+4 −0
Original line number Diff line number Diff line
@@ -27,6 +27,10 @@ struct nvkm_gr_func {
	 */
	u64 (*units)(struct nvkm_gr *);
	bool (*chsw_load)(struct nvkm_gr *);
	struct {
		int (*pause)(struct nvkm_gr *);
		int (*resume)(struct nvkm_gr *);
	} ctxsw;
	struct nvkm_sclass sclass[];
};