Эх сурвалжийг харах

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>
Ben Skeggs 14 жил өмнө
parent
commit
af6d9fe536

+ 14 - 17
drivers/gpu/drm/nouveau/nvc0_grctx.c

@@ -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)
 
 
 	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; 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);
 		}
 		}
 	}
 	}