|
@@ -1652,6 +1652,82 @@ gf100_gr_init_ctxctl(struct gf100_gr *gr)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+void
|
|
|
+gf100_gr_oneinit_tiles(struct gf100_gr *gr)
|
|
|
+{
|
|
|
+ static const u8 primes[] = {
|
|
|
+ 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61
|
|
|
+ };
|
|
|
+ int init_frac[GPC_MAX], init_err[GPC_MAX], run_err[GPC_MAX], i, j;
|
|
|
+ u32 mul_factor, comm_denom;
|
|
|
+ u8 gpc_map[GPC_MAX];
|
|
|
+ bool sorted;
|
|
|
+
|
|
|
+ switch (gr->tpc_total) {
|
|
|
+ case 15: gr->screen_tile_row_offset = 0x06; break;
|
|
|
+ case 14: gr->screen_tile_row_offset = 0x05; break;
|
|
|
+ case 13: gr->screen_tile_row_offset = 0x02; break;
|
|
|
+ case 11: gr->screen_tile_row_offset = 0x07; break;
|
|
|
+ case 10: gr->screen_tile_row_offset = 0x06; break;
|
|
|
+ case 7:
|
|
|
+ case 5: gr->screen_tile_row_offset = 0x01; break;
|
|
|
+ case 3: gr->screen_tile_row_offset = 0x02; break;
|
|
|
+ case 2:
|
|
|
+ case 1: gr->screen_tile_row_offset = 0x01; break;
|
|
|
+ default: gr->screen_tile_row_offset = 0x03;
|
|
|
+ for (i = 0; i < ARRAY_SIZE(primes); i++) {
|
|
|
+ if (gr->tpc_total % primes[i]) {
|
|
|
+ gr->screen_tile_row_offset = primes[i];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Sort GPCs by TPC count, highest-to-lowest. */
|
|
|
+ for (i = 0; i < gr->gpc_nr; i++)
|
|
|
+ gpc_map[i] = i;
|
|
|
+ sorted = false;
|
|
|
+
|
|
|
+ while (!sorted) {
|
|
|
+ for (sorted = true, i = 0; i < gr->gpc_nr - 1; i++) {
|
|
|
+ if (gr->tpc_nr[gpc_map[i + 1]] >
|
|
|
+ gr->tpc_nr[gpc_map[i + 0]]) {
|
|
|
+ u8 swap = gpc_map[i];
|
|
|
+ gpc_map[i + 0] = gpc_map[i + 1];
|
|
|
+ gpc_map[i + 1] = swap;
|
|
|
+ sorted = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Determine tile->GPC mapping */
|
|
|
+ mul_factor = gr->gpc_nr * gr->tpc_max;
|
|
|
+ if (mul_factor & 1)
|
|
|
+ mul_factor = 2;
|
|
|
+ else
|
|
|
+ mul_factor = 1;
|
|
|
+
|
|
|
+ comm_denom = gr->gpc_nr * gr->tpc_max * mul_factor;
|
|
|
+
|
|
|
+ for (i = 0; i < gr->gpc_nr; i++) {
|
|
|
+ init_frac[i] = gr->tpc_nr[gpc_map[i]] * gr->gpc_nr * mul_factor;
|
|
|
+ init_err[i] = i * gr->tpc_max * mul_factor - comm_denom/2;
|
|
|
+ run_err[i] = init_frac[i] + init_err[i];
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < gr->tpc_total;) {
|
|
|
+ for (j = 0; j < gr->gpc_nr; j++) {
|
|
|
+ if ((run_err[j] * 2) >= comm_denom) {
|
|
|
+ gr->tile[i++] = gpc_map[j];
|
|
|
+ run_err[j] += init_frac[j] - comm_denom;
|
|
|
+ } else {
|
|
|
+ run_err[j] += init_frac[j];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static int
|
|
|
gf100_gr_oneinit(struct nvkm_gr *base)
|
|
|
{
|
|
@@ -1691,45 +1767,8 @@ gf100_gr_oneinit(struct nvkm_gr *base)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /*XXX: these need figuring out... though it might not even matter */
|
|
|
- switch (device->chipset) {
|
|
|
- case 0xc0:
|
|
|
- if (gr->tpc_total == 11) { /* 465, 3/4/4/0, 4 */
|
|
|
- gr->screen_tile_row_offset = 0x07;
|
|
|
- } else
|
|
|
- if (gr->tpc_total == 14) { /* 470, 3/3/4/4, 5 */
|
|
|
- gr->screen_tile_row_offset = 0x05;
|
|
|
- } else
|
|
|
- if (gr->tpc_total == 15) { /* 480, 3/4/4/4, 6 */
|
|
|
- gr->screen_tile_row_offset = 0x06;
|
|
|
- }
|
|
|
- break;
|
|
|
- case 0xc3: /* 450, 4/0/0/0, 2 */
|
|
|
- gr->screen_tile_row_offset = 0x03;
|
|
|
- break;
|
|
|
- case 0xc4: /* 460, 3/4/0/0, 4 */
|
|
|
- gr->screen_tile_row_offset = 0x01;
|
|
|
- break;
|
|
|
- case 0xc1: /* 2/0/0/0, 1 */
|
|
|
- gr->screen_tile_row_offset = 0x01;
|
|
|
- break;
|
|
|
- case 0xc8: /* 4/4/3/4, 5 */
|
|
|
- gr->screen_tile_row_offset = 0x06;
|
|
|
- break;
|
|
|
- case 0xce: /* 4/4/0/0, 4 */
|
|
|
- gr->screen_tile_row_offset = 0x03;
|
|
|
- break;
|
|
|
- case 0xcf: /* 4/0/0/0, 3 */
|
|
|
- gr->screen_tile_row_offset = 0x03;
|
|
|
- break;
|
|
|
- case 0xd7:
|
|
|
- case 0xd9: /* 1/0/0/0, 1 */
|
|
|
- case 0xea: /* gk20a */
|
|
|
- case 0x12b: /* gm20b */
|
|
|
- gr->screen_tile_row_offset = 0x01;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
+ memset(gr->tile, 0xff, sizeof(gr->tile));
|
|
|
+ gr->func->oneinit_tiles(gr);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -2164,6 +2203,7 @@ gf100_gr_gpccs_ucode = {
|
|
|
|
|
|
static const struct gf100_gr_func
|
|
|
gf100_gr = {
|
|
|
+ .oneinit_tiles = gf100_gr_oneinit_tiles,
|
|
|
.init = gf100_gr_init,
|
|
|
.init_gpc_mmu = gf100_gr_init_gpc_mmu,
|
|
|
.init_vsc_stream_master = gf100_gr_init_vsc_stream_master,
|