Commit af6d9fe5 authored by Ben Skeggs's avatar Ben Skeggs

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