drm/nouveau/gr/gf100-: virtualise dist_skip_table + improve algorithm
authorBen Skeggs <bskeggs@redhat.com>
Tue, 8 May 2018 10:39:46 +0000 (20:39 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 18 May 2018 05:01:24 +0000 (15:01 +1000)
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>
14 files changed:
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk110b.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk208.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp100.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp102.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgp107.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h

index cdf74f31d4be91a3c3bd1ffd0f6c081f18803817..176be7124f2907b602f3e3c1c0d76f6953d75464 100644 (file)
@@ -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
index 41cb875464de95241e92cfb1fefc0655efaa114c..dd1c73b725cde0e271ddf1772b8046155cd71e17 100644 (file)
@@ -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;
index 423b09753bb7d9d07bdb9be696b338d6df034f31..b3f4127f7520fe049551959c028722e1fccae1f5 100644 (file)
@@ -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,
 };
index 25576c1ea9cc1ca2bccbc199cad3c215f4c51f49..12169314f3e2388d529ccd58c3c42b3a83c62d4e 100644 (file)
@@ -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,
 };
index 284570a0b5cc1921445700368b8f20f6cabf6bb9..e6a54dc1a01a93260fe3119967ca861dc7f705c9 100644 (file)
@@ -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,
 };
index ffd8cf989309bca228f25d65dcf5d8fa79f6dc20..ef82ebee82c9f1b2ea6986fbe060ff4e16729cf5 100644 (file)
@@ -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,
 };
index e5e4d4dce86e996e4b10b56591272f85674d800e..226f8aa9e7f684460f51e8ebe917ef46a65cf350 100644 (file)
@@ -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,
 };
index c209bf38b5d99dcd198383b0fa1a16e6c550d865..cdf9d60683e01ed9bad7eac257db363a18f34dd9 100644 (file)
@@ -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,
 };
index cfccd75dbc301bb493af41c4c017fb4322e2534d..689120683fb47dbc14be8acebad76ed929bc59f7 100644 (file)
@@ -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,
 };
index e09990785cb931108e53715fdf89fbf1ad17db42..1a3d0c566fea461d969d663215c0272aca83bf9f 100644 (file)
@@ -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,
 };
index 553a609c4f98bafa7e74fde7c23a9865be0a0548..2aeabb362447092ecc29bb9f13a679519c0cc93a 100644 (file)
@@ -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,
 };
index db3fff89bc2f17ed53561d1481111e7bfe115b6e..4aea2f6552cc17a1e0eaf1a1f7096daed80ec1a9 100644 (file)
@@ -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,
 };
index fe3b44d18a67198252e482fb58f01c892b29f769..dd4a4104306c1aac55d5f3bba88c7199a86036fd 100644 (file)
@@ -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];
                }
        }
 
index 6f7a7864d66f256f18b23a69b8f11b65c2e4725f..c2a1b2adff360fd6f94538017363f13ead9b8766 100644 (file)
@@ -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];