diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c index 29ab01be71ec..01e213e4d1a9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c @@ -120,11 +120,40 @@ gf117_gr_gpccs_ucode = { .data.size = sizeof(gf117_grgpc_data), }; +void +gf117_gr_init_zcull(struct gf100_gr *gr) +{ + struct nvkm_device *device = gr->base.engine.subdev.device; + const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total); + u32 data[TPC_MAX / 8] = {}; + u8 tpcnr[GPC_MAX]; + int gpc, tpc; + int i; + + memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr)); + for (i = 0, gpc = -1; i < gr->tpc_total; i++) { + do { + gpc = (gpc + 1) % gr->gpc_nr; + } while (!tpcnr[gpc]); + tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--; + + data[i / 8] |= tpc << ((i % 8) * 4); + } + + nvkm_wr32(device, GPC_BCAST(0x0980), data[0]); + nvkm_wr32(device, GPC_BCAST(0x0984), data[1]); + nvkm_wr32(device, GPC_BCAST(0x0988), data[2]); + nvkm_wr32(device, GPC_BCAST(0x098c), data[3]); + + nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918); +} + static const struct gf100_gr_func gf117_gr = { .init = gf100_gr_init, .init_gpc_mmu = gf100_gr_init_gpc_mmu, .init_vsc_stream_master = gf100_gr_init_vsc_stream_master, + .init_zcull = gf117_gr_init_zcull, .mmio = gf117_gr_pack_mmio, .fecs.ucode = &gf117_gr_fecs_ucode, .gpccs.ucode = &gf117_gr_gpccs_ucode, |