152 lines
5.0 KiB
Diff
152 lines
5.0 KiB
Diff
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
|
|
index 82478e0..d8831ab 100644
|
|
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
|
|
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
|
|
@@ -579,6 +579,14 @@ nouveau_card_init(struct drm_device *dev)
|
|
if (ret)
|
|
goto out_display_early;
|
|
|
|
+ /* workaround an odd issue on nvc1 by disabling the device's
|
|
+ * nosnoop capability. hopefully won't cause issues until a
|
|
+ * better fix is found - assuming there is one...
|
|
+ */
|
|
+ if (dev_priv->chipset == 0xc1) {
|
|
+ nv_mask(dev, 0x00088080, 0x00000800, 0x00000000);
|
|
+ }
|
|
+
|
|
nouveau_pm_init(dev);
|
|
|
|
ret = engine->vram.init(dev);
|
|
@@ -1102,12 +1110,13 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
|
|
dev_priv->noaccel = !!nouveau_noaccel;
|
|
if (nouveau_noaccel == -1) {
|
|
switch (dev_priv->chipset) {
|
|
- case 0xc1: /* known broken */
|
|
- case 0xc8: /* never tested */
|
|
+#if 0
|
|
+ case 0xXX: /* known broken */
|
|
NV_INFO(dev, "acceleration disabled by default, pass "
|
|
"noaccel=0 to force enable\n");
|
|
dev_priv->noaccel = true;
|
|
break;
|
|
+#endif
|
|
default:
|
|
dev_priv->noaccel = false;
|
|
break;
|
|
diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c
|
|
index 4b8d0b3..3cc1c60 100644
|
|
--- a/drivers/gpu/drm/nouveau/nvc0_graph.c
|
|
+++ b/drivers/gpu/drm/nouveau/nvc0_graph.c
|
|
@@ -156,8 +156,8 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)
|
|
struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
|
|
struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
|
|
struct drm_device *dev = chan->dev;
|
|
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
|
|
int i = 0, gpc, tp, ret;
|
|
- u32 magic;
|
|
|
|
ret = nouveau_gpuobj_new(dev, chan, 0x2000, 256, NVOBJ_FLAG_VM,
|
|
&grch->unk408004);
|
|
@@ -206,14 +206,37 @@ nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)
|
|
nv_wo32(grch->mmio, i++ * 4, 0x0041880c);
|
|
nv_wo32(grch->mmio, i++ * 4, 0x80000018);
|
|
|
|
- magic = 0x02180000;
|
|
- nv_wo32(grch->mmio, i++ * 4, 0x00405830);
|
|
- nv_wo32(grch->mmio, i++ * 4, magic);
|
|
- for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
|
|
- for (tp = 0; tp < priv->tp_nr[gpc]; tp++, magic += 0x0324) {
|
|
- u32 reg = 0x504520 + (gpc * 0x8000) + (tp * 0x0800);
|
|
- nv_wo32(grch->mmio, i++ * 4, reg);
|
|
- nv_wo32(grch->mmio, i++ * 4, magic);
|
|
+ if (dev_priv->chipset != 0xc1) {
|
|
+ u32 magic = 0x02180000;
|
|
+ nv_wo32(grch->mmio, i++ * 4, 0x00405830);
|
|
+ nv_wo32(grch->mmio, i++ * 4, magic);
|
|
+ for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
|
|
+ for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
|
|
+ u32 reg = TP_UNIT(gpc, tp, 0x520);
|
|
+ nv_wo32(grch->mmio, i++ * 4, reg);
|
|
+ nv_wo32(grch->mmio, i++ * 4, magic);
|
|
+ magic += 0x0324;
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ u32 magic = 0x02180000;
|
|
+ nv_wo32(grch->mmio, i++ * 4, 0x00405830);
|
|
+ nv_wo32(grch->mmio, i++ * 4, magic | 0x0000218);
|
|
+ nv_wo32(grch->mmio, i++ * 4, 0x004064c4);
|
|
+ nv_wo32(grch->mmio, i++ * 4, 0x0086ffff);
|
|
+ for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
|
|
+ for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
|
|
+ u32 reg = TP_UNIT(gpc, tp, 0x520);
|
|
+ nv_wo32(grch->mmio, i++ * 4, reg);
|
|
+ nv_wo32(grch->mmio, i++ * 4, (1 << 28) | magic);
|
|
+ magic += 0x0324;
|
|
+ }
|
|
+ for (tp = 0; tp < priv->tp_nr[gpc]; tp++) {
|
|
+ u32 reg = TP_UNIT(gpc, tp, 0x544);
|
|
+ nv_wo32(grch->mmio, i++ * 4, reg);
|
|
+ nv_wo32(grch->mmio, i++ * 4, magic);
|
|
+ magic += 0x0324;
|
|
+ }
|
|
}
|
|
}
|
|
|
|
diff --git a/drivers/gpu/drm/nouveau/nvc0_grctx.c b/drivers/gpu/drm/nouveau/nvc0_grctx.c
|
|
index dd0e6a7..96b0b93d 100644
|
|
--- a/drivers/gpu/drm/nouveau/nvc0_grctx.c
|
|
+++ b/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);
|
|
}
|
|
}
|
|
|