Commit 60770fa2 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/gr/gf100-: virtualise dist_skip_table + improve algorithm

The algorithm for GM200 and newer matches RM for all the boards I have, but
I don't have enough data to try and figure something out for earlier boards,
so these will still write zeroes to the table as we did before.

The code in NVGPU isn't helpful here, it appears to handle specific cases.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent c4a2b638
...@@ -1360,6 +1360,8 @@ gf100_grctx_generate_floorsweep(struct gf100_gr *gr) ...@@ -1360,6 +1360,8 @@ gf100_grctx_generate_floorsweep(struct gf100_gr *gr)
func->alpha_beta_tables(gr); func->alpha_beta_tables(gr);
if (func->max_ways_evict) if (func->max_ways_evict)
func->max_ways_evict(gr); func->max_ways_evict(gr);
if (func->dist_skip_table)
func->dist_skip_table(gr);
} }
void void
......
...@@ -57,6 +57,7 @@ struct gf100_grctx_func { ...@@ -57,6 +57,7 @@ struct gf100_grctx_func {
void (*rop_mapping)(struct gf100_gr *); void (*rop_mapping)(struct gf100_gr *);
void (*alpha_beta_tables)(struct gf100_gr *); void (*alpha_beta_tables)(struct gf100_gr *);
void (*max_ways_evict)(struct gf100_gr *); void (*max_ways_evict)(struct gf100_gr *);
void (*dist_skip_table)(struct gf100_gr *);
}; };
extern const struct gf100_grctx_func gf100_grctx; extern const struct gf100_grctx_func gf100_grctx;
...@@ -84,6 +85,7 @@ extern const struct gf100_grctx_func gf110_grctx; ...@@ -84,6 +85,7 @@ extern const struct gf100_grctx_func gf110_grctx;
extern const struct gf100_grctx_func gf117_grctx; extern const struct gf100_grctx_func gf117_grctx;
void gf117_grctx_generate_attrib(struct gf100_grctx *); void gf117_grctx_generate_attrib(struct gf100_grctx *);
void gf117_grctx_generate_rop_mapping(struct gf100_gr *); void gf117_grctx_generate_rop_mapping(struct gf100_gr *);
void gf117_grctx_generate_dist_skip_table(struct gf100_gr *);
extern const struct gf100_grctx_func gf119_grctx; extern const struct gf100_grctx_func gf119_grctx;
...@@ -112,6 +114,7 @@ void gm107_grctx_generate_pagepool(struct gf100_grctx *); ...@@ -112,6 +114,7 @@ void gm107_grctx_generate_pagepool(struct gf100_grctx *);
void gm107_grctx_generate_attrib(struct gf100_grctx *); void gm107_grctx_generate_attrib(struct gf100_grctx *);
extern const struct gf100_grctx_func gm200_grctx; extern const struct gf100_grctx_func gm200_grctx;
void gm200_grctx_generate_dist_skip_table(struct gf100_gr *);
void gm200_grctx_generate_405b60(struct gf100_gr *); void gm200_grctx_generate_405b60(struct gf100_gr *);
extern const struct gf100_grctx_func gm20b_grctx; extern const struct gf100_grctx_func gm20b_grctx;
......
...@@ -179,6 +179,16 @@ gf117_grctx_pack_ppc[] = { ...@@ -179,6 +179,16 @@ gf117_grctx_pack_ppc[] = {
* PGRAPH context implementation * PGRAPH context implementation
******************************************************************************/ ******************************************************************************/
void
gf117_grctx_generate_dist_skip_table(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
int i;
for (i = 0; i < 8; i++)
nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000);
}
void void
gf117_grctx_generate_rop_mapping(struct gf100_gr *gr) gf117_grctx_generate_rop_mapping(struct gf100_gr *gr)
{ {
...@@ -282,7 +292,6 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) ...@@ -282,7 +292,6 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
struct nvkm_device *device = gr->base.engine.subdev.device; struct nvkm_device *device = gr->base.engine.subdev.device;
const struct gf100_grctx_func *grctx = gr->func->grctx; const struct gf100_grctx_func *grctx = gr->func->grctx;
u32 idle_timeout; u32 idle_timeout;
int i;
nvkm_mc_unk260(device, 0); nvkm_mc_unk260(device, 0);
...@@ -301,9 +310,6 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) ...@@ -301,9 +310,6 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
gf100_grctx_generate_floorsweep(gr); gf100_grctx_generate_floorsweep(gr);
for (i = 0; i < 8; i++)
nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000);
gf100_gr_icmd(gr, grctx->icmd); gf100_gr_icmd(gr, grctx->icmd);
nvkm_wr32(device, 0x404154, idle_timeout); nvkm_wr32(device, 0x404154, idle_timeout);
gf100_gr_mthd(gr, grctx->mthd); gf100_gr_mthd(gr, grctx->mthd);
...@@ -336,4 +342,5 @@ gf117_grctx = { ...@@ -336,4 +342,5 @@ gf117_grctx = {
.rop_mapping = gf117_grctx_generate_rop_mapping, .rop_mapping = gf117_grctx_generate_rop_mapping,
.alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables,
.max_ways_evict = gf100_grctx_generate_max_ways_evict, .max_ways_evict = gf100_grctx_generate_max_ways_evict,
.dist_skip_table = gf117_grctx_generate_dist_skip_table,
}; };
...@@ -898,7 +898,6 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) ...@@ -898,7 +898,6 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
struct nvkm_device *device = gr->base.engine.subdev.device; struct nvkm_device *device = gr->base.engine.subdev.device;
const struct gf100_grctx_func *grctx = gr->func->grctx; const struct gf100_grctx_func *grctx = gr->func->grctx;
u32 idle_timeout; u32 idle_timeout;
int i;
nvkm_mc_unk260(device, 0); nvkm_mc_unk260(device, 0);
...@@ -917,9 +916,6 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) ...@@ -917,9 +916,6 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
gf100_grctx_generate_floorsweep(gr); gf100_grctx_generate_floorsweep(gr);
for (i = 0; i < 8; i++)
nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000);
nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr);
nvkm_mask(device, 0x419f78, 0x00000001, 0x00000000); nvkm_mask(device, 0x419f78, 0x00000001, 0x00000000);
...@@ -1006,4 +1002,5 @@ gk104_grctx = { ...@@ -1006,4 +1002,5 @@ gk104_grctx = {
.tpc_nr = gf100_grctx_generate_tpc_nr, .tpc_nr = gf100_grctx_generate_tpc_nr,
.rop_mapping = gf117_grctx_generate_rop_mapping, .rop_mapping = gf117_grctx_generate_rop_mapping,
.alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables,
.dist_skip_table = gf117_grctx_generate_dist_skip_table,
}; };
...@@ -835,4 +835,5 @@ gk110_grctx = { ...@@ -835,4 +835,5 @@ gk110_grctx = {
.tpc_nr = gf100_grctx_generate_tpc_nr, .tpc_nr = gf100_grctx_generate_tpc_nr,
.rop_mapping = gf117_grctx_generate_rop_mapping, .rop_mapping = gf117_grctx_generate_rop_mapping,
.alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables,
.dist_skip_table = gf117_grctx_generate_dist_skip_table,
}; };
...@@ -96,4 +96,5 @@ gk110b_grctx = { ...@@ -96,4 +96,5 @@ gk110b_grctx = {
.tpc_nr = gf100_grctx_generate_tpc_nr, .tpc_nr = gf100_grctx_generate_tpc_nr,
.rop_mapping = gf117_grctx_generate_rop_mapping, .rop_mapping = gf117_grctx_generate_rop_mapping,
.alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables,
.dist_skip_table = gf117_grctx_generate_dist_skip_table,
}; };
...@@ -557,4 +557,5 @@ gk208_grctx = { ...@@ -557,4 +557,5 @@ gk208_grctx = {
.tpc_nr = gf100_grctx_generate_tpc_nr, .tpc_nr = gf100_grctx_generate_tpc_nr,
.rop_mapping = gf117_grctx_generate_rop_mapping, .rop_mapping = gf117_grctx_generate_rop_mapping,
.alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables,
.dist_skip_table = gf117_grctx_generate_dist_skip_table,
}; };
...@@ -945,7 +945,6 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) ...@@ -945,7 +945,6 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
struct nvkm_device *device = gr->base.engine.subdev.device; struct nvkm_device *device = gr->base.engine.subdev.device;
const struct gf100_grctx_func *grctx = gr->func->grctx; const struct gf100_grctx_func *grctx = gr->func->grctx;
u32 idle_timeout; u32 idle_timeout;
int i;
gf100_gr_mmio(gr, grctx->hub); gf100_gr_mmio(gr, grctx->hub);
gf100_gr_mmio(gr, grctx->gpc); gf100_gr_mmio(gr, grctx->gpc);
...@@ -962,9 +961,6 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) ...@@ -962,9 +961,6 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
gf100_grctx_generate_floorsweep(gr); gf100_grctx_generate_floorsweep(gr);
nvkm_wr32(device, 0x4064d0, 0x00000001);
for (i = 1; i < 8; i++)
nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000);
nvkm_wr32(device, 0x406500, 0x00000001); nvkm_wr32(device, 0x406500, 0x00000001);
nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr);
...@@ -1005,4 +1001,5 @@ gm107_grctx = { ...@@ -1005,4 +1001,5 @@ gm107_grctx = {
.tpc_nr = gf100_grctx_generate_tpc_nr, .tpc_nr = gf100_grctx_generate_tpc_nr,
.rop_mapping = gf117_grctx_generate_rop_mapping, .rop_mapping = gf117_grctx_generate_rop_mapping,
.alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables, .alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables,
.dist_skip_table = gf117_grctx_generate_dist_skip_table,
}; };
...@@ -78,8 +78,6 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) ...@@ -78,8 +78,6 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
gf100_grctx_generate_floorsweep(gr); gf100_grctx_generate_floorsweep(gr);
for (i = 0; i < 8; i++)
nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000);
nvkm_wr32(device, 0x406500, 0x00000000); nvkm_wr32(device, 0x406500, 0x00000000);
nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr);
...@@ -98,6 +96,28 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) ...@@ -98,6 +96,28 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
nvkm_mask(device, 0x418e4c, 0xffffffff, 0x70000000); nvkm_mask(device, 0x418e4c, 0xffffffff, 0x70000000);
} }
void
gm200_grctx_generate_dist_skip_table(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
u32 data[8] = {};
int gpc, ppc, i;
for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
for (ppc = 0; ppc < gr->ppc_nr[gpc]; ppc++) {
u8 ppc_tpcs = gr->ppc_tpc_nr[gpc][ppc];
u8 ppc_tpcm = gr->ppc_tpc_mask[gpc][ppc];
while (ppc_tpcs-- > gr->ppc_tpc_min)
ppc_tpcm &= ppc_tpcm - 1;
ppc_tpcm ^= gr->ppc_tpc_mask[gpc][ppc];
((u8 *)data)[gpc] |= ppc_tpcm;
}
}
for (i = 0; i < ARRAY_SIZE(data); i++)
nvkm_wr32(device, 0x4064d0 + (i * 0x04), data[i]);
}
const struct gf100_grctx_func const struct gf100_grctx_func
gm200_grctx = { gm200_grctx = {
.main = gm200_grctx_generate_main, .main = gm200_grctx_generate_main,
...@@ -115,4 +135,5 @@ gm200_grctx = { ...@@ -115,4 +135,5 @@ gm200_grctx = {
.alpha_nr = 0x1000, .alpha_nr = 0x1000,
.sm_id = gm107_grctx_generate_sm_id, .sm_id = gm107_grctx_generate_sm_id,
.rop_mapping = gf117_grctx_generate_rop_mapping, .rop_mapping = gf117_grctx_generate_rop_mapping,
.dist_skip_table = gm200_grctx_generate_dist_skip_table,
}; };
...@@ -140,8 +140,6 @@ gp100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) ...@@ -140,8 +140,6 @@ gp100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
gf100_grctx_generate_floorsweep(gr); gf100_grctx_generate_floorsweep(gr);
for (i = 0; i < 8; i++)
nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000);
nvkm_wr32(device, 0x406500, 0x00000000); nvkm_wr32(device, 0x406500, 0x00000000);
nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr); nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr);
...@@ -174,4 +172,5 @@ gp100_grctx = { ...@@ -174,4 +172,5 @@ gp100_grctx = {
.alpha_nr = 0x800, .alpha_nr = 0x800,
.sm_id = gm107_grctx_generate_sm_id, .sm_id = gm107_grctx_generate_sm_id,
.rop_mapping = gf117_grctx_generate_rop_mapping, .rop_mapping = gf117_grctx_generate_rop_mapping,
.dist_skip_table = gm200_grctx_generate_dist_skip_table,
}; };
...@@ -96,4 +96,5 @@ gp102_grctx = { ...@@ -96,4 +96,5 @@ gp102_grctx = {
.alpha_nr = 0x800, .alpha_nr = 0x800,
.sm_id = gm107_grctx_generate_sm_id, .sm_id = gm107_grctx_generate_sm_id,
.rop_mapping = gf117_grctx_generate_rop_mapping, .rop_mapping = gf117_grctx_generate_rop_mapping,
.dist_skip_table = gm200_grctx_generate_dist_skip_table,
}; };
...@@ -46,4 +46,5 @@ gp107_grctx = { ...@@ -46,4 +46,5 @@ gp107_grctx = {
.alpha_nr = 0x800, .alpha_nr = 0x800,
.sm_id = gm107_grctx_generate_sm_id, .sm_id = gm107_grctx_generate_sm_id,
.rop_mapping = gf117_grctx_generate_rop_mapping, .rop_mapping = gf117_grctx_generate_rop_mapping,
.dist_skip_table = gm200_grctx_generate_dist_skip_table,
}; };
...@@ -1685,6 +1685,9 @@ gf100_gr_oneinit(struct nvkm_gr *base) ...@@ -1685,6 +1685,9 @@ gf100_gr_oneinit(struct nvkm_gr *base)
continue; continue;
gr->ppc_mask[i] |= (1 << j); gr->ppc_mask[i] |= (1 << j);
gr->ppc_tpc_nr[i][j] = hweight8(gr->ppc_tpc_mask[i][j]); gr->ppc_tpc_nr[i][j] = hweight8(gr->ppc_tpc_mask[i][j]);
if (gr->ppc_tpc_min == 0 ||
gr->ppc_tpc_min > gr->ppc_tpc_nr[i][j])
gr->ppc_tpc_min = gr->ppc_tpc_nr[i][j];
} }
} }
......
...@@ -105,6 +105,7 @@ struct gf100_gr { ...@@ -105,6 +105,7 @@ struct gf100_gr {
u8 ppc_mask[GPC_MAX]; u8 ppc_mask[GPC_MAX];
u8 ppc_tpc_mask[GPC_MAX][4]; u8 ppc_tpc_mask[GPC_MAX][4];
u8 ppc_tpc_nr[GPC_MAX][4]; u8 ppc_tpc_nr[GPC_MAX][4];
u8 ppc_tpc_min;
struct gf100_gr_data mmio_data[4]; struct gf100_gr_data mmio_data[4];
struct gf100_gr_mmio mmio_list[4096/8]; struct gf100_gr_mmio mmio_list[4096/8];
......
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