提交 2e26c73a 编写于 作者: D Dave Airlie

Merge branch 'drm-nouveau-fixes' of git://git.freedesktop.org/git/nouveau/linux-2.6 into drm-fixes

* 'drm-nouveau-fixes' of git://git.freedesktop.org/git/nouveau/linux-2.6:
  drm/nv86/fifo: suspend fix
  drm/nouveau: disable copy engine on NVAF
  nouveau: fixup scanout enable in nvc0_pm
  drm/nouveau/aux: mask off higher bits of auxch index in i2c table entry
  drm/nvd0/disp: mask off high 16 bit of negative cursor x-coordinate
  drm/nve0/fifo: add support for the flip completion swmthd
...@@ -229,7 +229,7 @@ nouveau_i2c_init(struct drm_device *dev) ...@@ -229,7 +229,7 @@ nouveau_i2c_init(struct drm_device *dev)
} }
break; break;
case 6: /* NV50- DP AUX */ case 6: /* NV50- DP AUX */
port->drive = entry[0]; port->drive = entry[0] & 0x0f;
port->sense = port->drive; port->sense = port->drive;
port->adapter.algo = &nouveau_dp_i2c_algo; port->adapter.algo = &nouveau_dp_i2c_algo;
break; break;
......
...@@ -731,7 +731,6 @@ nouveau_card_init(struct drm_device *dev) ...@@ -731,7 +731,6 @@ nouveau_card_init(struct drm_device *dev)
case 0xa3: case 0xa3:
case 0xa5: case 0xa5:
case 0xa8: case 0xa8:
case 0xaf:
nva3_copy_create(dev); nva3_copy_create(dev);
break; break;
} }
......
...@@ -117,17 +117,22 @@ nv84_fifo_context_del(struct nouveau_channel *chan, int engine) ...@@ -117,17 +117,22 @@ nv84_fifo_context_del(struct nouveau_channel *chan, int engine)
struct drm_device *dev = chan->dev; struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
unsigned long flags; unsigned long flags;
u32 save;
/* remove channel from playlist, will context switch if active */ /* remove channel from playlist, will context switch if active */
spin_lock_irqsave(&dev_priv->context_switch_lock, flags); spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
nv_mask(dev, 0x002600 + (chan->id * 4), 0x80000000, 0x00000000); nv_mask(dev, 0x002600 + (chan->id * 4), 0x80000000, 0x00000000);
nv50_fifo_playlist_update(dev); nv50_fifo_playlist_update(dev);
save = nv_mask(dev, 0x002520, 0x0000003f, 0x15);
/* tell any engines on this channel to unload their contexts */ /* tell any engines on this channel to unload their contexts */
nv_wr32(dev, 0x0032fc, chan->ramin->vinst >> 12); nv_wr32(dev, 0x0032fc, chan->ramin->vinst >> 12);
if (!nv_wait_ne(dev, 0x0032fc, 0xffffffff, 0xffffffff)) if (!nv_wait_ne(dev, 0x0032fc, 0xffffffff, 0xffffffff))
NV_INFO(dev, "PFIFO: channel %d unload timeout\n", chan->id); NV_INFO(dev, "PFIFO: channel %d unload timeout\n", chan->id);
nv_wr32(dev, 0x002520, save);
nv_wr32(dev, 0x002600 + (chan->id * 4), 0x00000000); nv_wr32(dev, 0x002600 + (chan->id * 4), 0x00000000);
spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
...@@ -184,10 +189,13 @@ nv84_fifo_fini(struct drm_device *dev, int engine, bool suspend) ...@@ -184,10 +189,13 @@ nv84_fifo_fini(struct drm_device *dev, int engine, bool suspend)
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nv84_fifo_priv *priv = nv_engine(dev, engine); struct nv84_fifo_priv *priv = nv_engine(dev, engine);
int i; int i;
u32 save;
/* set playlist length to zero, fifo will unload context */ /* set playlist length to zero, fifo will unload context */
nv_wr32(dev, 0x0032ec, 0); nv_wr32(dev, 0x0032ec, 0);
save = nv_mask(dev, 0x002520, 0x0000003f, 0x15);
/* tell all connected engines to unload their contexts */ /* tell all connected engines to unload their contexts */
for (i = 0; i < priv->base.channels; i++) { for (i = 0; i < priv->base.channels; i++) {
struct nouveau_channel *chan = dev_priv->channels.ptr[i]; struct nouveau_channel *chan = dev_priv->channels.ptr[i];
...@@ -199,6 +207,7 @@ nv84_fifo_fini(struct drm_device *dev, int engine, bool suspend) ...@@ -199,6 +207,7 @@ nv84_fifo_fini(struct drm_device *dev, int engine, bool suspend)
} }
} }
nv_wr32(dev, 0x002520, save);
nv_wr32(dev, 0x002140, 0); nv_wr32(dev, 0x002140, 0);
return 0; return 0;
} }
......
...@@ -557,7 +557,7 @@ prog_mem(struct drm_device *dev, struct nvc0_pm_state *info) ...@@ -557,7 +557,7 @@ prog_mem(struct drm_device *dev, struct nvc0_pm_state *info)
nouveau_mem_exec(&exec, info->perflvl); nouveau_mem_exec(&exec, info->perflvl);
if (dev_priv->chipset < 0xd0) if (dev_priv->chipset < 0xd0)
nv_wr32(dev, 0x611200, 0x00003300); nv_wr32(dev, 0x611200, 0x00003330);
else else
nv_wr32(dev, 0x62c000, 0x03030300); nv_wr32(dev, 0x62c000, 0x03030300);
} }
......
...@@ -790,7 +790,7 @@ nvd0_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) ...@@ -790,7 +790,7 @@ nvd0_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
int ch = EVO_CURS(nv_crtc->index); int ch = EVO_CURS(nv_crtc->index);
evo_piow(crtc->dev, ch, 0x0084, (y << 16) | x); evo_piow(crtc->dev, ch, 0x0084, (y << 16) | (x & 0xffff));
evo_piow(crtc->dev, ch, 0x0080, 0x00000000); evo_piow(crtc->dev, ch, 0x0080, 0x00000000);
return 0; return 0;
} }
......
...@@ -294,6 +294,25 @@ nve0_fifo_isr_vm_fault(struct drm_device *dev, int unit) ...@@ -294,6 +294,25 @@ nve0_fifo_isr_vm_fault(struct drm_device *dev, int unit)
printk(" on channel 0x%010llx\n", (u64)inst << 12); printk(" on channel 0x%010llx\n", (u64)inst << 12);
} }
static int
nve0_fifo_page_flip(struct drm_device *dev, u32 chid)
{
struct nve0_fifo_priv *priv = nv_engine(dev, NVOBJ_ENGINE_FIFO);
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_channel *chan = NULL;
unsigned long flags;
int ret = -EINVAL;
spin_lock_irqsave(&dev_priv->channels.lock, flags);
if (likely(chid >= 0 && chid < priv->base.channels)) {
chan = dev_priv->channels.ptr[chid];
if (likely(chan))
ret = nouveau_finish_page_flip(chan, NULL);
}
spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
return ret;
}
static void static void
nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
{ {
...@@ -303,11 +322,21 @@ nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) ...@@ -303,11 +322,21 @@ nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f; u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f;
u32 subc = (addr & 0x00070000); u32 subc = (addr & 0x00070000);
u32 mthd = (addr & 0x00003ffc); u32 mthd = (addr & 0x00003ffc);
u32 show = stat;
if (stat & 0x00200000) {
if (mthd == 0x0054) {
if (!nve0_fifo_page_flip(dev, chid))
show &= ~0x00200000;
}
}
NV_INFO(dev, "PSUBFIFO %d:", unit); if (show) {
nouveau_bitfield_print(nve0_fifo_subfifo_intr, stat); NV_INFO(dev, "PFIFO%d:", unit);
NV_INFO(dev, "PSUBFIFO %d: ch %d subc %d mthd 0x%04x data 0x%08x\n", nouveau_bitfield_print(nve0_fifo_subfifo_intr, show);
unit, chid, subc, mthd, data); NV_INFO(dev, "PFIFO%d: ch %d subc %d mthd 0x%04x data 0x%08x\n",
unit, chid, subc, mthd, data);
}
nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008); nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008);
nv_wr32(dev, 0x040108 + (unit * 0x2000), stat); nv_wr32(dev, 0x040108 + (unit * 0x2000), stat);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册