drm/nvc0/gr: fix some bugs in grctx generation

Most serious is for chips with only 1 TPC, we'd get stuck in an infinite
loop.  The fix here will slightly change the setup for all other chipsets
too, but, it shouldn't matter too much, and this all needs figuring out
and likely redone anyway.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
tirimbino
Ben Skeggs 14 years ago
parent 80859760da
commit af6d9fe536
  1. 31
      drivers/gpu/drm/nouveau/nvc0_grctx.c

@ -1812,6 +1812,7 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
/* calculate first set of magics */
memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));
gpc = -1;
for (tp = 0; tp < priv->tp_total; tp++) {
do {
gpc = (gpc + 1) % priv->gpc_nr;
@ -1861,30 +1862,26 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
if (1) {
u32 tp_mask = 0, tp_set = 0;
u8 tpnr[GPC_MAX];
u8 tpnr[GPC_MAX], a, b;
memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));
for (gpc = 0; gpc < priv->gpc_nr; gpc++)
tp_mask |= ((1 << priv->tp_nr[gpc]) - 1) << (gpc * 8);
gpc = -1;
for (i = 0, gpc = -1; i < 32; i++) {
int ltp = i * (priv->tp_total - 1) / 32;
do {
gpc = (gpc + 1) % priv->gpc_nr;
} while (!tpnr[gpc]);
tp = priv->tp_nr[gpc] - tpnr[gpc]--;
for (i = 0, gpc = -1, b = -1; i < 32; i++) {
a = (i * (priv->tp_total - 1)) / 32;
if (a != b) {
b = a;
do {
gpc = (gpc + 1) % priv->gpc_nr;
} while (!tpnr[gpc]);
tp = priv->tp_nr[gpc] - tpnr[gpc]--;
tp_set |= 1 << ((gpc * 8) + tp);
tp_set |= 1 << ((gpc * 8) + tp);
}
do {
nv_wr32(dev, 0x406800 + (i * 0x20), tp_set);
tp_set ^= tp_mask;
nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set);
tp_set ^= tp_mask;
} while (ltp == (++i * (priv->tp_total - 1) / 32));
i--;
nv_wr32(dev, 0x406800 + (i * 0x20), tp_set);
nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set ^ tp_mask);
}
}

Loading…
Cancel
Save