forked from Minki/linux
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: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
c4a2b6385d
commit
60770fa28b
drivers/gpu/drm/nouveau/nvkm/engine/gr
@ -1360,6 +1360,8 @@ gf100_grctx_generate_floorsweep(struct gf100_gr *gr)
|
||||
func->alpha_beta_tables(gr);
|
||||
if (func->max_ways_evict)
|
||||
func->max_ways_evict(gr);
|
||||
if (func->dist_skip_table)
|
||||
func->dist_skip_table(gr);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -57,6 +57,7 @@ struct gf100_grctx_func {
|
||||
void (*rop_mapping)(struct gf100_gr *);
|
||||
void (*alpha_beta_tables)(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;
|
||||
@ -84,6 +85,7 @@ extern const struct gf100_grctx_func gf110_grctx;
|
||||
extern const struct gf100_grctx_func gf117_grctx;
|
||||
void gf117_grctx_generate_attrib(struct gf100_grctx *);
|
||||
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;
|
||||
|
||||
@ -112,6 +114,7 @@ void gm107_grctx_generate_pagepool(struct gf100_grctx *);
|
||||
void gm107_grctx_generate_attrib(struct gf100_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 *);
|
||||
|
||||
extern const struct gf100_grctx_func gm20b_grctx;
|
||||
|
@ -179,6 +179,16 @@ gf117_grctx_pack_ppc[] = {
|
||||
* 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
|
||||
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)
|
||||
struct nvkm_device *device = gr->base.engine.subdev.device;
|
||||
const struct gf100_grctx_func *grctx = gr->func->grctx;
|
||||
u32 idle_timeout;
|
||||
int i;
|
||||
|
||||
nvkm_mc_unk260(device, 0);
|
||||
|
||||
@ -301,9 +310,6 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
|
||||
|
||||
gf100_grctx_generate_floorsweep(gr);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000);
|
||||
|
||||
gf100_gr_icmd(gr, grctx->icmd);
|
||||
nvkm_wr32(device, 0x404154, idle_timeout);
|
||||
gf100_gr_mthd(gr, grctx->mthd);
|
||||
@ -336,4 +342,5 @@ gf117_grctx = {
|
||||
.rop_mapping = gf117_grctx_generate_rop_mapping,
|
||||
.alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables,
|
||||
.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)
|
||||
struct nvkm_device *device = gr->base.engine.subdev.device;
|
||||
const struct gf100_grctx_func *grctx = gr->func->grctx;
|
||||
u32 idle_timeout;
|
||||
int i;
|
||||
|
||||
nvkm_mc_unk260(device, 0);
|
||||
|
||||
@ -917,9 +916,6 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
|
||||
|
||||
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_mask(device, 0x419f78, 0x00000001, 0x00000000);
|
||||
|
||||
@ -1006,4 +1002,5 @@ gk104_grctx = {
|
||||
.tpc_nr = gf100_grctx_generate_tpc_nr,
|
||||
.rop_mapping = gf117_grctx_generate_rop_mapping,
|
||||
.alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables,
|
||||
.dist_skip_table = gf117_grctx_generate_dist_skip_table,
|
||||
};
|
||||
|
@ -835,4 +835,5 @@ gk110_grctx = {
|
||||
.tpc_nr = gf100_grctx_generate_tpc_nr,
|
||||
.rop_mapping = gf117_grctx_generate_rop_mapping,
|
||||
.alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables,
|
||||
.dist_skip_table = gf117_grctx_generate_dist_skip_table,
|
||||
};
|
||||
|
@ -96,4 +96,5 @@ gk110b_grctx = {
|
||||
.tpc_nr = gf100_grctx_generate_tpc_nr,
|
||||
.rop_mapping = gf117_grctx_generate_rop_mapping,
|
||||
.alpha_beta_tables = gk104_grctx_generate_alpha_beta_tables,
|
||||
.dist_skip_table = gf117_grctx_generate_dist_skip_table,
|
||||
};
|
||||
|
@ -557,4 +557,5 @@ gk208_grctx = {
|
||||
.tpc_nr = gf100_grctx_generate_tpc_nr,
|
||||
.rop_mapping = gf117_grctx_generate_rop_mapping,
|
||||
.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)
|
||||
struct nvkm_device *device = gr->base.engine.subdev.device;
|
||||
const struct gf100_grctx_func *grctx = gr->func->grctx;
|
||||
u32 idle_timeout;
|
||||
int i;
|
||||
|
||||
gf100_gr_mmio(gr, grctx->hub);
|
||||
gf100_gr_mmio(gr, grctx->gpc);
|
||||
@ -962,9 +961,6 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
|
||||
|
||||
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, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr);
|
||||
@ -1005,4 +1001,5 @@ gm107_grctx = {
|
||||
.tpc_nr = gf100_grctx_generate_tpc_nr,
|
||||
.rop_mapping = gf117_grctx_generate_rop_mapping,
|
||||
.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)
|
||||
|
||||
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, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr);
|
||||
@ -98,6 +96,28 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
|
||||
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
|
||||
gm200_grctx = {
|
||||
.main = gm200_grctx_generate_main,
|
||||
@ -115,4 +135,5 @@ gm200_grctx = {
|
||||
.alpha_nr = 0x1000,
|
||||
.sm_id = gm107_grctx_generate_sm_id,
|
||||
.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)
|
||||
|
||||
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, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr);
|
||||
@ -174,4 +172,5 @@ gp100_grctx = {
|
||||
.alpha_nr = 0x800,
|
||||
.sm_id = gm107_grctx_generate_sm_id,
|
||||
.rop_mapping = gf117_grctx_generate_rop_mapping,
|
||||
.dist_skip_table = gm200_grctx_generate_dist_skip_table,
|
||||
};
|
||||
|
@ -96,4 +96,5 @@ gp102_grctx = {
|
||||
.alpha_nr = 0x800,
|
||||
.sm_id = gm107_grctx_generate_sm_id,
|
||||
.rop_mapping = gf117_grctx_generate_rop_mapping,
|
||||
.dist_skip_table = gm200_grctx_generate_dist_skip_table,
|
||||
};
|
||||
|
@ -46,4 +46,5 @@ gp107_grctx = {
|
||||
.alpha_nr = 0x800,
|
||||
.sm_id = gm107_grctx_generate_sm_id,
|
||||
.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)
|
||||
continue;
|
||||
gr->ppc_mask[i] |= (1 << 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 {
|
||||
u8 ppc_mask[GPC_MAX];
|
||||
u8 ppc_tpc_mask[GPC_MAX][4];
|
||||
u8 ppc_tpc_nr[GPC_MAX][4];
|
||||
u8 ppc_tpc_min;
|
||||
|
||||
struct gf100_gr_data mmio_data[4];
|
||||
struct gf100_gr_mmio mmio_list[4096/8];
|
||||
|
Loading…
Reference in New Issue
Block a user