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

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
...@@ -10,6 +10,8 @@ struct nvkm_gr { ...@@ -10,6 +10,8 @@ struct nvkm_gr {
u64 nvkm_gr_units(struct nvkm_gr *); u64 nvkm_gr_units(struct nvkm_gr *);
int nvkm_gr_tlb_flush(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 nv04_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int nv10_gr_new(struct nvkm_device *, int, struct nvkm_gr **); int nv10_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
......
...@@ -25,6 +25,24 @@ ...@@ -25,6 +25,24 @@
#include <engine/fifo.h> #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 static bool
nvkm_gr_chsw_load(struct nvkm_engine *engine) nvkm_gr_chsw_load(struct nvkm_engine *engine)
{ {
......
...@@ -715,6 +715,56 @@ gf100_gr_pack_mmio[] = { ...@@ -715,6 +715,56 @@ gf100_gr_pack_mmio[] = {
* PGRAPH engine/subdev functions * 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 int
gf100_gr_fecs_bind_pointer(struct gf100_gr *gr, u32 inst) gf100_gr_fecs_bind_pointer(struct gf100_gr *gr, u32 inst)
{ {
...@@ -1891,6 +1941,8 @@ gf100_gr_oneinit(struct nvkm_gr *base) ...@@ -1891,6 +1941,8 @@ gf100_gr_oneinit(struct nvkm_gr *base)
if (ret) if (ret)
return ret; return ret;
mutex_init(&gr->fecs.mutex);
ret = nvkm_falcon_v1_new(subdev, "GPCCS", 0x41a000, &gr->gpccs.falcon); ret = nvkm_falcon_v1_new(subdev, "GPCCS", 0x41a000, &gr->gpccs.falcon);
if (ret) if (ret)
return ret; return ret;
...@@ -2004,6 +2056,8 @@ gf100_gr_ = { ...@@ -2004,6 +2056,8 @@ gf100_gr_ = {
.chan_new = gf100_gr_chan_new, .chan_new = gf100_gr_chan_new,
.object_get = gf100_gr_object_get, .object_get = gf100_gr_object_get,
.chsw_load = gf100_gr_chsw_load, .chsw_load = gf100_gr_chsw_load,
.ctxsw.pause = gf100_gr_fecs_stop_ctxsw,
.ctxsw.resume = gf100_gr_fecs_start_ctxsw,
}; };
int int
......
...@@ -84,6 +84,8 @@ struct gf100_gr { ...@@ -84,6 +84,8 @@ struct gf100_gr {
struct { struct {
struct nvkm_falcon *falcon; struct nvkm_falcon *falcon;
struct mutex mutex;
u32 disable;
} fecs; } fecs;
struct { struct {
......
...@@ -27,6 +27,10 @@ struct nvkm_gr_func { ...@@ -27,6 +27,10 @@ struct nvkm_gr_func {
*/ */
u64 (*units)(struct nvkm_gr *); u64 (*units)(struct nvkm_gr *);
bool (*chsw_load)(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[]; struct nvkm_sclass sclass[];
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment