Commit ca081fff authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/gr/gf100-: generate golden context during first object alloc

Needed for GV100 (and only GV100 for some reason) for WFI_GOLDEN_SAVE.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent 11375021
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <subdev/fb.h> #include <subdev/fb.h>
#include <subdev/mc.h> #include <subdev/mc.h>
#include <subdev/timer.h> #include <subdev/timer.h>
#include <engine/fifo.h>
/******************************************************************************* /*******************************************************************************
* PGRAPH context register lists * PGRAPH context register lists
...@@ -1433,14 +1434,12 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) ...@@ -1433,14 +1434,12 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
#define CB_RESERVED 0x80000 #define CB_RESERVED 0x80000
int int
gf100_grctx_generate(struct gf100_gr *gr) gf100_grctx_generate(struct gf100_gr *gr, struct gf100_gr_chan *chan, struct nvkm_gpuobj *inst)
{ {
const struct gf100_grctx_func *grctx = gr->func->grctx; const struct gf100_grctx_func *grctx = gr->func->grctx;
struct nvkm_subdev *subdev = &gr->base.engine.subdev; struct nvkm_subdev *subdev = &gr->base.engine.subdev;
struct nvkm_device *device = subdev->device; struct nvkm_device *device = subdev->device;
struct nvkm_memory *inst = NULL;
struct nvkm_memory *data = NULL; struct nvkm_memory *data = NULL;
struct nvkm_vmm *vmm = NULL;
struct nvkm_vma *ctx = NULL; struct nvkm_vma *ctx = NULL;
struct gf100_grctx info; struct gf100_grctx info;
int ret, i; int ret, i;
...@@ -1472,38 +1471,20 @@ gf100_grctx_generate(struct gf100_gr *gr) ...@@ -1472,38 +1471,20 @@ gf100_grctx_generate(struct gf100_gr *gr)
/* Init SCC RAM. */ /* Init SCC RAM. */
nvkm_wr32(device, 0x40802c, 0x00000001); nvkm_wr32(device, 0x40802c, 0x00000001);
/* Allocate memory to for a "channel", which we'll use to generate /* Allocate memory to store context, and dummy global context buffers. */
* the default context values.
*/
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
0x1000, 0x1000, true, &inst);
if (ret)
goto done;
ret = nvkm_vmm_new(device, 0, 0, NULL, 0, NULL, "grctx", &vmm);
if (ret)
goto done;
vmm->debug = subdev->debug;
ret = nvkm_vmm_join(vmm, inst);
if (ret)
goto done;
ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
CB_RESERVED + gr->size, 0, true, &data); CB_RESERVED + gr->size, 0, true, &data);
if (ret) if (ret)
goto done; goto done;
ret = nvkm_vmm_get(vmm, 0, nvkm_memory_size(data), &ctx); ret = nvkm_vmm_get(chan->vmm, 0, nvkm_memory_size(data), &ctx);
if (ret) if (ret)
goto done; goto done;
ret = nvkm_memory_map(data, 0, vmm, ctx, NULL, 0); ret = nvkm_memory_map(data, 0, chan->vmm, ctx, NULL, 0);
if (ret) if (ret)
goto done; goto done;
/* Setup context pointer. */ /* Setup context pointer. */
nvkm_kmap(inst); nvkm_kmap(inst);
nvkm_wo32(inst, 0x0210, lower_32_bits(ctx->addr + CB_RESERVED) | 4); nvkm_wo32(inst, 0x0210, lower_32_bits(ctx->addr + CB_RESERVED) | 4);
...@@ -1518,11 +1499,11 @@ gf100_grctx_generate(struct gf100_gr *gr) ...@@ -1518,11 +1499,11 @@ gf100_grctx_generate(struct gf100_gr *gr)
info.buffer_nr = 0; info.buffer_nr = 0;
/* Make channel current. */ /* Make channel current. */
addr = nvkm_memory_addr(inst) >> 12; addr = inst->addr >> 12;
if (gr->firmware) { if (gr->firmware) {
ret = gf100_gr_fecs_bind_pointer(gr, 0x80000000 | addr); ret = gf100_gr_fecs_bind_pointer(gr, 0x80000000 | addr);
if (ret) if (ret)
goto done; goto done_inst;
nvkm_kmap(data); nvkm_kmap(data);
nvkm_wo32(data, 0x1c, 1); nvkm_wo32(data, 0x1c, 1);
...@@ -1552,7 +1533,7 @@ gf100_grctx_generate(struct gf100_gr *gr) ...@@ -1552,7 +1533,7 @@ gf100_grctx_generate(struct gf100_gr *gr)
break; break;
) < 0) { ) < 0) {
ret = -EBUSY; ret = -EBUSY;
goto done; goto done_inst;
} }
gr->data = kmalloc(gr->size, GFP_KERNEL); gr->data = kmalloc(gr->size, GFP_KERNEL);
...@@ -1566,12 +1547,14 @@ gf100_grctx_generate(struct gf100_gr *gr) ...@@ -1566,12 +1547,14 @@ gf100_grctx_generate(struct gf100_gr *gr)
ret = -ENOMEM; ret = -ENOMEM;
} }
done_inst:
nvkm_kmap(inst);
nvkm_wo32(inst, 0x0210, 0);
nvkm_wo32(inst, 0x0214, 0);
nvkm_done(inst);
done: done:
nvkm_vmm_put(vmm, &ctx); nvkm_vmm_put(chan->vmm, &ctx);
nvkm_memory_unref(&data); nvkm_memory_unref(&data);
nvkm_vmm_part(vmm, inst);
nvkm_vmm_unref(&vmm);
nvkm_memory_unref(&inst);
return ret; return ret;
} }
......
...@@ -81,7 +81,7 @@ struct gf100_grctx_func { ...@@ -81,7 +81,7 @@ struct gf100_grctx_func {
}; };
extern const struct gf100_grctx_func gf100_grctx; extern const struct gf100_grctx_func gf100_grctx;
int gf100_grctx_generate(struct gf100_gr *); int gf100_grctx_generate(struct gf100_gr *, struct gf100_gr_chan *, struct nvkm_gpuobj *inst);
void gf100_grctx_generate_main(struct gf100_gr *, struct gf100_grctx *); void gf100_grctx_generate_main(struct gf100_gr *, struct gf100_grctx *);
void gf100_grctx_generate_bundle(struct gf100_grctx *); void gf100_grctx_generate_bundle(struct gf100_grctx *);
void gf100_grctx_generate_pagepool(struct gf100_grctx *); void gf100_grctx_generate_pagepool(struct gf100_grctx *);
......
...@@ -394,6 +394,17 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch, ...@@ -394,6 +394,17 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_fifo_chan *fifoch,
chan->vmm = nvkm_vmm_ref(fifoch->vmm); chan->vmm = nvkm_vmm_ref(fifoch->vmm);
*pobject = &chan->object; *pobject = &chan->object;
/* Generate golden context image. */
mutex_lock(&gr->fecs.mutex);
if (gr->data == NULL) {
ret = gf100_grctx_generate(gr, chan, fifoch->inst);
if (ret) {
nvkm_error(&base->engine.subdev, "failed to construct context\n");
return ret;
}
}
mutex_unlock(&gr->fecs.mutex);
/* allocate memory for a "mmio list" buffer that's used by the HUB /* allocate memory for a "mmio list" buffer that's used by the HUB
* fuc to modify some per-context register settings on first load * fuc to modify some per-context register settings on first load
* of the context. * of the context.
...@@ -1763,15 +1774,6 @@ gf100_gr_init_ctxctl_ext(struct gf100_gr *gr) ...@@ -1763,15 +1774,6 @@ gf100_gr_init_ctxctl_ext(struct gf100_gr *gr)
return ret; return ret;
} }
/* Generate golden context image. */
if (gr->data == NULL) {
int ret = gf100_grctx_generate(gr);
if (ret) {
nvkm_error(subdev, "failed to construct context\n");
return ret;
}
}
return 0; return 0;
} }
...@@ -1823,14 +1825,6 @@ gf100_gr_init_ctxctl_int(struct gf100_gr *gr) ...@@ -1823,14 +1825,6 @@ gf100_gr_init_ctxctl_int(struct gf100_gr *gr)
} }
gr->size = nvkm_rd32(device, 0x409804); gr->size = nvkm_rd32(device, 0x409804);
if (gr->data == NULL) {
int ret = gf100_grctx_generate(gr);
if (ret) {
nvkm_error(subdev, "failed to construct context\n");
return ret;
}
}
return 0; return 0;
} }
......
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