From bde4889aaa2d59c1febfeadd7f690be0ed143ed5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 4 Jul 2011 12:52:27 +1000 Subject: drm: make sure drm_vblank_init() has been called before touching vbl_lock Signed-off-by: Ben Skeggs --- drivers/gpu/drm/drm_irq.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index cb3794a00f9..4d3760c6396 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -407,13 +407,16 @@ int drm_irq_uninstall(struct drm_device *dev) /* * Wake up any waiters so they don't hang. */ - spin_lock_irqsave(&dev->vbl_lock, irqflags); - for (i = 0; i < dev->num_crtcs; i++) { - DRM_WAKEUP(&dev->vbl_queue[i]); - dev->vblank_enabled[i] = 0; - dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i); + if (dev->num_crtcs) { + spin_lock_irqsave(&dev->vbl_lock, irqflags); + for (i = 0; i < dev->num_crtcs; i++) { + DRM_WAKEUP(&dev->vbl_queue[i]); + dev->vblank_enabled[i] = 0; + dev->last_vblank[i] = + dev->driver->get_vblank_counter(dev, i); + } + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); } - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); if (!irq_enabled) return -EINVAL; -- cgit v1.2.3 From 46b348865011bf0d706fe1ec8c9cef08cf86ad40 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 22 Sep 2011 12:51:31 +1000 Subject: drm/nouveau: fix oops if i2c bus not found in nouveau_i2c_identify() Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index c6143df48b9..d39b2202b19 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c @@ -333,7 +333,7 @@ nouveau_i2c_identify(struct drm_device *dev, const char *what, NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index); - for (i = 0; info[i].addr; i++) { + for (i = 0; i2c && info[i].addr; i++) { if (nouveau_probe_i2c_addr(i2c, info[i].addr) && (!match || match(i2c, &info[i]))) { NV_INFO(dev, "Detected %s: %s\n", what, info[i].type); -- cgit v1.2.3 From ee9f7ef99f4422463634c075b22197c22c5cfa71 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 23 Sep 2011 15:37:38 +1000 Subject: drm/nv50/bios: fixup mpll programming from the init table parser Reportedly this has been causing stability and corruption issues after resuming from suspend for a few people. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bios.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 032a8209813..5fc201b49d3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -640,10 +640,9 @@ static int nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk) { struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t reg0 = nv_rd32(dev, reg + 0); - uint32_t reg1 = nv_rd32(dev, reg + 4); struct nouveau_pll_vals pll; struct pll_lims pll_limits; + u32 ctrl, mask, coef; int ret; ret = get_pll_limits(dev, reg, &pll_limits); @@ -654,15 +653,20 @@ nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk) if (!clk) return -ERANGE; - reg0 = (reg0 & 0xfff8ffff) | (pll.log2P << 16); - reg1 = (reg1 & 0xffff0000) | (pll.N1 << 8) | pll.M1; - - if (dev_priv->vbios.execute) { - still_alive(); - nv_wr32(dev, reg + 4, reg1); - nv_wr32(dev, reg + 0, reg0); + coef = pll.N1 << 8 | pll.M1; + ctrl = pll.log2P << 16; + mask = 0x00070000; + if (reg == 0x004008) { + mask |= 0x01f80000; + ctrl |= (pll_limits.log2p_bias << 19); + ctrl |= (pll.log2P << 22); } + if (!dev_priv->vbios.execute) + return 0; + + nv_mask(dev, reg + 0, mask, ctrl); + nv_wr32(dev, reg + 4, coef); return 0; } -- cgit v1.2.3 From dce411cdf60eb64638443f953b52c18192378305 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 29 Sep 2011 13:15:17 +1000 Subject: drm/nv50/gr: typo fix, how about we not reset fifo during graph init? Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_graph.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 8c979b31ff6..ac601f7c4e1 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -131,8 +131,8 @@ nv50_graph_init(struct drm_device *dev, int engine) NV_DEBUG(dev, "\n"); /* master reset */ - nv_mask(dev, 0x000200, 0x00200100, 0x00000000); - nv_mask(dev, 0x000200, 0x00200100, 0x00200100); + nv_mask(dev, 0x000200, 0x00201000, 0x00000000); + nv_mask(dev, 0x000200, 0x00201000, 0x00201000); nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */ /* reset/enable traps and interrupts */ -- cgit v1.2.3 From 7b4b98fa0c4d3a975b36bfe9984e4cd117f2ddff Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 7 Oct 2011 16:00:31 +1000 Subject: drm/nv50/vram: fix incorrect detection of bank count on newer chipsets NVA3+ has an extra bit here compared to NV50:NVA3 chipsets. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_vram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nv50_vram.c b/drivers/gpu/drm/nouveau/nv50_vram.c index 9da23838e63..2e45e57fd86 100644 --- a/drivers/gpu/drm/nouveau/nv50_vram.c +++ b/drivers/gpu/drm/nouveau/nv50_vram.c @@ -160,7 +160,7 @@ nv50_vram_rblock(struct drm_device *dev) colbits = (r4 & 0x0000f000) >> 12; rowbitsa = ((r4 & 0x000f0000) >> 16) + 8; rowbitsb = ((r4 & 0x00f00000) >> 20) + 8; - banks = ((r4 & 0x01000000) ? 8 : 4); + banks = 1 << (((r4 & 0x03000000) >> 24) + 2); rowsize = parts * banks * (1 << colbits) * 8; predicted = rowsize << rowbitsa; -- cgit v1.2.3 From 5e60ee780e792efe6dce97eceb110b1d30bab850 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Fri, 9 Sep 2011 14:16:42 +0200 Subject: drm/nouveau: initialize chan->fence.lock before use Fence lock needs to be initialized before any call to nouveau_channel_put because it calls nouveau_channel_idle->nouveau_fence_update which uses fence lock. BUG: spinlock bad magic on CPU#0, test/24134 lock: ffff88019f90dba8, .magic: 00000000, .owner: /-1, .owner_cpu: 0 Pid: 24134, comm: test Not tainted 3.0.0-nv+ #800 Call Trace: spin_bug+0x9c/0xa3 do_raw_spin_lock+0x29/0x13c _raw_spin_lock+0x1e/0x22 nouveau_fence_update+0x2d/0xf1 nouveau_channel_idle+0x22/0xa0 nouveau_channel_put_unlocked+0x84/0x1bd nouveau_channel_put+0x20/0x24 nouveau_channel_alloc+0x4ec/0x585 nouveau_ioctl_fifo_alloc+0x50/0x130 drm_ioctl+0x289/0x361 do_vfs_ioctl+0x4dd/0x52c sys_ioctl+0x42/0x65 system_call_fastpath+0x16/0x1b It's easily triggerable from userspace. Additionally remove double initialization of chan->fence.pending. Signed-off-by: Marcin Slusarz Cc: stable@kernel.org Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_channel.c | 1 + drivers/gpu/drm/nouveau/nouveau_fence.c | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index a319d5646ea..bb6ec9ef867 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -158,6 +158,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, INIT_LIST_HEAD(&chan->nvsw.vbl_wait); INIT_LIST_HEAD(&chan->nvsw.flip); INIT_LIST_HEAD(&chan->fence.pending); + spin_lock_init(&chan->fence.lock); /* setup channel's memory and vm */ ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle); diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 81116cfea27..2f6daae68b9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -539,8 +539,6 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) return ret; } - INIT_LIST_HEAD(&chan->fence.pending); - spin_lock_init(&chan->fence.lock); atomic_set(&chan->fence.last_sequence_irq, 0); return 0; } -- cgit v1.2.3 From 71856abefb49bae5d67275752ada02853c16660d Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Sun, 9 Oct 2011 22:58:31 +0200 Subject: drm/nv50: fix stability issue on NV86. Confirmed to fix random hangs while running all Unegine demos on NV86. Signed-off-by: Maxim Levitsky Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_grctx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.c b/drivers/gpu/drm/nouveau/nv50_grctx.c index d05c2c3b244..4b46d696856 100644 --- a/drivers/gpu/drm/nouveau/nv50_grctx.c +++ b/drivers/gpu/drm/nouveau/nv50_grctx.c @@ -601,7 +601,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) gr_def(ctx, offset + 0x1c, 0x00880000); break; case 0x86: - gr_def(ctx, offset + 0x1c, 0x008c0000); + gr_def(ctx, offset + 0x1c, 0x018c0000); break; case 0x92: case 0x96: -- cgit v1.2.3 From 12b6d9d881ccb64a833d53565a3579e12ab1d026 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Fri, 7 Oct 2011 18:10:45 +0200 Subject: drm/nvc0/vram: storage type 0xc3 is not compressed Signed-off-by: Christoph Bumiller Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvc0_vram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nvc0_vram.c b/drivers/gpu/drm/nouveau/nvc0_vram.c index edbfe9360ae..041ff2b2b60 100644 --- a/drivers/gpu/drm/nouveau/nvc0_vram.c +++ b/drivers/gpu/drm/nouveau/nvc0_vram.c @@ -43,7 +43,7 @@ static const u8 types[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, - 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, + 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0 -- cgit v1.2.3 From ef5ced4bfe48ba2acb16e867ceb9c473dd0ef192 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 18 Oct 2011 09:07:51 +0300 Subject: drm/nouveau: testing the wrong variable memtimings is a valid pointer here, the intent was to test for kcalloc() failure. Signed-off-by: Dan Carpenter Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_perf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c index 9f178aa9416..33d03fbf00d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_perf.c +++ b/drivers/gpu/drm/nouveau/nouveau_perf.c @@ -239,7 +239,7 @@ nouveau_perf_init(struct drm_device *dev) if(version == 0x15) { memtimings->timing = kcalloc(entries, sizeof(*memtimings->timing), GFP_KERNEL); - if(!memtimings) { + if (!memtimings->timing) { NV_WARN(dev,"Could not allocate memtiming table\n"); return; } -- cgit v1.2.3 From 2bfa7482224903097a50c14a4389a29f56e19c3b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 19 Oct 2011 14:06:59 +1000 Subject: drm/nv40/pm: fix issues on igp chipsets, which don't have memory Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv40_pm.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nv40_pm.c b/drivers/gpu/drm/nouveau/nv40_pm.c index bbc0b9c7e1f..e676b0d5347 100644 --- a/drivers/gpu/drm/nouveau/nv40_pm.c +++ b/drivers/gpu/drm/nouveau/nv40_pm.c @@ -57,12 +57,14 @@ read_pll_2(struct drm_device *dev, u32 reg) int P = (ctrl & 0x00070000) >> 16; u32 ref = 27000, clk = 0; - if (ctrl & 0x80000000) + if ((ctrl & 0x80000000) && M1) { clk = ref * N1 / M1; - - if (!(ctrl & 0x00000100)) { - if (ctrl & 0x40000000) - clk = clk * N2 / M2; + if ((ctrl & 0x40000100) == 0x40000000) { + if (M2) + clk = clk * N2 / M2; + else + clk = 0; + } } return clk >> P; @@ -177,6 +179,11 @@ nv40_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) } /* memory clock */ + if (!perflvl->memory) { + info->mpll_ctrl = 0x00000000; + goto out; + } + ret = nv40_calc_pll(dev, 0x004020, &pll, perflvl->memory, &N1, &M1, &N2, &M2, &log2P); if (ret < 0) @@ -264,6 +271,9 @@ nv40_pm_clocks_set(struct drm_device *dev, void *pre_state) mdelay(5); nv_mask(dev, 0x00c040, 0x00000333, info->ctrl); + if (!info->mpll_ctrl) + goto resume; + /* wait for vblank start on active crtcs, disable memory access */ for (i = 0; i < 2; i++) { if (!(crtc_mask & (1 << i))) -- cgit v1.2.3 From d4547ed8cc219f2e06078ac05147a873b2a03d5a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 27 Oct 2011 11:26:17 +1000 Subject: drm/nvc0/vram: skip disabled PBFB subunits Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvc0_vram.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvc0_vram.c b/drivers/gpu/drm/nouveau/nvc0_vram.c index 041ff2b2b60..ce984d573a5 100644 --- a/drivers/gpu/drm/nouveau/nvc0_vram.c +++ b/drivers/gpu/drm/nouveau/nvc0_vram.c @@ -110,22 +110,26 @@ nvc0_vram_init(struct drm_device *dev) u32 bsize = nv_rd32(dev, 0x10f20c); u32 offset, length; bool uniform = true; - int ret, i; + int ret, part; NV_DEBUG(dev, "0x100800: 0x%08x\n", nv_rd32(dev, 0x100800)); NV_DEBUG(dev, "parts 0x%08x bcast_mem_amount 0x%08x\n", parts, bsize); /* read amount of vram attached to each memory controller */ - for (i = 0; i < parts; i++) { - u32 psize = nv_rd32(dev, 0x11020c + (i * 0x1000)); + part = 0; + while (parts) { + u32 psize = nv_rd32(dev, 0x11020c + (part++ * 0x1000)); + if (psize == 0) + continue; + parts--; + if (psize != bsize) { if (psize < bsize) bsize = psize; uniform = false; } - NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", i, psize); - + NV_DEBUG(dev, "%d: mem_amount 0x%08x\n", part, psize); dev_priv->vram_size += (u64)psize << 20; } -- cgit v1.2.3 From 80859760daa01fb38497aa6326a32a16489d8c97 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 27 Oct 2011 11:31:49 +1000 Subject: drm/nvc0: enable acceleration on 0xc8 by default Worked well enough for glxgears and gnome-shell at least, no reason to have this off anymore. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_state.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 82478e0998e..2afd5b13dc4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -1103,7 +1103,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) if (nouveau_noaccel == -1) { switch (dev_priv->chipset) { case 0xc1: /* known broken */ - case 0xc8: /* never tested */ NV_INFO(dev, "acceleration disabled by default, pass " "noaccel=0 to force enable\n"); dev_priv->noaccel = true; -- cgit v1.2.3 From af6d9fe5368aadd8f0f3647b38405ffcd3ed5f81 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 11 Jul 2011 15:40:43 +1000 Subject: 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 --- drivers/gpu/drm/nouveau/nvc0_grctx.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvc0_grctx.c b/drivers/gpu/drm/nouveau/nvc0_grctx.c index dd0e6a736b3..96b0b93d94c 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); } } -- cgit v1.2.3 From 4c5df493eb30089ff0b8d03a50a86293f758a786 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 28 Oct 2011 10:59:45 +1000 Subject: drm/nvc1: hacky workaround to fix accel issues Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_state.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 2afd5b13dc4..9a5ab6121b8 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); -- cgit v1.2.3 From 6688a4dd20bf774d654203a0629d454447b80502 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 28 Oct 2011 11:43:04 +1000 Subject: drm/nvc0/gr: fixup the mmio list register writes for 0xc1 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvc0_graph.c | 41 ++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c index bbdbc51830c..a74e501afd2 100644 --- a/drivers/gpu/drm/nouveau/nvc0_graph.c +++ b/drivers/gpu/drm/nouveau/nvc0_graph.c @@ -157,8 +157,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); @@ -207,14 +207,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; + } } } -- cgit v1.2.3 From 1c77e0f7fa4b398652f8e03f125aed258fa7018e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 28 Oct 2011 11:00:39 +1000 Subject: drm/nvc0: enable acceleration for nvc1 by default Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_state.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 9a5ab6121b8..d8831ab42bb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -1110,11 +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 */ +#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; -- cgit v1.2.3 From 4beb116a454867cc3a98d02d906e0f0459aefe72 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 6 Nov 2011 21:21:28 +0100 Subject: drm/nv10: Change the BO size threshold determining the memory placement range. Fixes the framebuffer memory allocation failure seen on some low-memory cards, followed by X refusing to start. https://bugs.freedesktop.org/show_bug.cgi?id=42384 Reported-by: Chris Paulson-Ellis Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 7226f419e17..7cc37e69086 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -148,7 +148,7 @@ set_placement_range(struct nouveau_bo *nvbo, uint32_t type) if (dev_priv->card_type == NV_10 && nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) && - nvbo->bo.mem.num_pages < vram_pages / 2) { + nvbo->bo.mem.num_pages < vram_pages / 4) { /* * Make sure that the color and depth buffers are handled * by independent memory controller units. Up to a 9x -- cgit v1.2.3 From 1e482f75f169861e992eb6b5602dc73a9e0b63a2 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sun, 6 Nov 2011 20:32:04 +0100 Subject: drm/nouveau: by default use low bpp framebuffer on low memory cards Framebuffer's BPP is not that important but can waste significant part of memory on low-VRAM cards. Lower it to 8bpp on < 32MB cards and to 16bpp on 64MB cards. It can still be overridden by video= option. Signed-off-by: Marcin Slusarz Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 14a8627efe4..3a4cc32b9e4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -487,6 +487,7 @@ int nouveau_fbcon_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_fbdev *nfbdev; + int preferred_bpp; int ret; nfbdev = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL); @@ -505,7 +506,15 @@ int nouveau_fbcon_init(struct drm_device *dev) } drm_fb_helper_single_add_all_connectors(&nfbdev->helper); - drm_fb_helper_initial_config(&nfbdev->helper, 32); + + if (dev_priv->vram_size <= 32 * 1024 * 1024) + preferred_bpp = 8; + else if (dev_priv->vram_size <= 64 * 1024 * 1024) + preferred_bpp = 16; + else + preferred_bpp = 32; + + drm_fb_helper_initial_config(&nfbdev->helper, preferred_bpp); return 0; } -- cgit v1.2.3 From 5c79507b2c50ddab8f51bc692e3c0a39e3da2ad6 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 25 Oct 2011 13:09:43 -0400 Subject: drm/nouveau: Fix bandwidth calculation for DisplayPort Ported from the equivalent fix in drm-intel-next: http://cgit.freedesktop.org/~keithp/linux/commit/?h=drm-intel-next&id=cd9dde44f47501394b9f0715b6a36a92aa74c0d0 Signed-off-by: Adam Jackson Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_connector.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index e0d275e1c96..cea6696b190 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -710,7 +710,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector, case OUTPUT_DP: max_clock = nv_encoder->dp.link_nr; max_clock *= nv_encoder->dp.link_bw; - clock = clock * nouveau_connector_bpp(connector) / 8; + clock = clock * nouveau_connector_bpp(connector) / 10; break; default: BUG_ON(1); -- cgit v1.2.3