aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv84_fifo.c
diff options
context:
space:
mode:
authorMaxim Levitsky <maximlevitsky@gmail.com>2012-08-13 19:22:07 -0400
committerBen Skeggs <bskeggs@redhat.com>2012-08-13 19:36:53 -0400
commit2064db725cc6d4ea19a24c138bc37939b63e3ae6 (patch)
tree5e55c8a87408bfc2382676a763021842f70ed286 /drivers/gpu/drm/nouveau/nv84_fifo.c
parentfe0aac129c247be62fd8ad697ff510523fd71f74 (diff)
drm/nv86/fifo: suspend fix
This fix is a backport from the reworked nouveau driver. It masks off the engines we're not expecting to use before attempting a channel kickoff. Signed-off-by: Maxim Levitsky <maximlevitsky@gmail.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv84_fifo.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv84_fifo.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nv84_fifo.c b/drivers/gpu/drm/nouveau/nv84_fifo.c
index cc82d799fc3b..c564c5e4c30a 100644
--- a/drivers/gpu/drm/nouveau/nv84_fifo.c
+++ b/drivers/gpu/drm/nouveau/nv84_fifo.c
@@ -117,17 +117,22 @@ nv84_fifo_context_del(struct nouveau_channel *chan, int engine)
117 struct drm_device *dev = chan->dev; 117 struct drm_device *dev = chan->dev;
118 struct drm_nouveau_private *dev_priv = dev->dev_private; 118 struct drm_nouveau_private *dev_priv = dev->dev_private;
119 unsigned long flags; 119 unsigned long flags;
120 u32 save;
120 121
121 /* remove channel from playlist, will context switch if active */ 122 /* remove channel from playlist, will context switch if active */
122 spin_lock_irqsave(&dev_priv->context_switch_lock, flags); 123 spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
123 nv_mask(dev, 0x002600 + (chan->id * 4), 0x80000000, 0x00000000); 124 nv_mask(dev, 0x002600 + (chan->id * 4), 0x80000000, 0x00000000);
124 nv50_fifo_playlist_update(dev); 125 nv50_fifo_playlist_update(dev);
125 126
127 save = nv_mask(dev, 0x002520, 0x0000003f, 0x15);
128
126 /* tell any engines on this channel to unload their contexts */ 129 /* tell any engines on this channel to unload their contexts */
127 nv_wr32(dev, 0x0032fc, chan->ramin->vinst >> 12); 130 nv_wr32(dev, 0x0032fc, chan->ramin->vinst >> 12);
128 if (!nv_wait_ne(dev, 0x0032fc, 0xffffffff, 0xffffffff)) 131 if (!nv_wait_ne(dev, 0x0032fc, 0xffffffff, 0xffffffff))
129 NV_INFO(dev, "PFIFO: channel %d unload timeout\n", chan->id); 132 NV_INFO(dev, "PFIFO: channel %d unload timeout\n", chan->id);
130 133
134 nv_wr32(dev, 0x002520, save);
135
131 nv_wr32(dev, 0x002600 + (chan->id * 4), 0x00000000); 136 nv_wr32(dev, 0x002600 + (chan->id * 4), 0x00000000);
132 spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); 137 spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
133 138
@@ -184,10 +189,13 @@ nv84_fifo_fini(struct drm_device *dev, int engine, bool suspend)
184 struct drm_nouveau_private *dev_priv = dev->dev_private; 189 struct drm_nouveau_private *dev_priv = dev->dev_private;
185 struct nv84_fifo_priv *priv = nv_engine(dev, engine); 190 struct nv84_fifo_priv *priv = nv_engine(dev, engine);
186 int i; 191 int i;
192 u32 save;
187 193
188 /* set playlist length to zero, fifo will unload context */ 194 /* set playlist length to zero, fifo will unload context */
189 nv_wr32(dev, 0x0032ec, 0); 195 nv_wr32(dev, 0x0032ec, 0);
190 196
197 save = nv_mask(dev, 0x002520, 0x0000003f, 0x15);
198
191 /* tell all connected engines to unload their contexts */ 199 /* tell all connected engines to unload their contexts */
192 for (i = 0; i < priv->base.channels; i++) { 200 for (i = 0; i < priv->base.channels; i++) {
193 struct nouveau_channel *chan = dev_priv->channels.ptr[i]; 201 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 } 207 }
200 } 208 }
201 209
210 nv_wr32(dev, 0x002520, save);
202 nv_wr32(dev, 0x002140, 0); 211 nv_wr32(dev, 0x002140, 0);
203 return 0; 212 return 0;
204} 213}