aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
index e10f9644140f..52c22b026005 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
@@ -166,14 +166,30 @@ gk104_fifo_context_attach(struct nvkm_object *parent,
166} 166}
167 167
168static int 168static int
169gk104_fifo_chan_kick(struct gk104_fifo_chan *chan)
170{
171 struct nvkm_object *obj = (void *)chan;
172 struct gk104_fifo_priv *priv = (void *)obj->engine;
173
174 nv_wr32(priv, 0x002634, chan->base.chid);
175 if (!nv_wait(priv, 0x002634, 0x100000, 0x000000)) {
176 nv_error(priv, "channel %d [%s] kick timeout\n",
177 chan->base.chid, nvkm_client_name(chan));
178 return -EBUSY;
179 }
180
181 return 0;
182}
183
184static int
169gk104_fifo_context_detach(struct nvkm_object *parent, bool suspend, 185gk104_fifo_context_detach(struct nvkm_object *parent, bool suspend,
170 struct nvkm_object *object) 186 struct nvkm_object *object)
171{ 187{
172 struct nvkm_bar *bar = nvkm_bar(parent); 188 struct nvkm_bar *bar = nvkm_bar(parent);
173 struct gk104_fifo_priv *priv = (void *)parent->engine;
174 struct gk104_fifo_base *base = (void *)parent->parent; 189 struct gk104_fifo_base *base = (void *)parent->parent;
175 struct gk104_fifo_chan *chan = (void *)parent; 190 struct gk104_fifo_chan *chan = (void *)parent;
176 u32 addr; 191 u32 addr;
192 int ret;
177 193
178 switch (nv_engidx(object->engine)) { 194 switch (nv_engidx(object->engine)) {
179 case NVDEV_ENGINE_SW : return 0; 195 case NVDEV_ENGINE_SW : return 0;
@@ -188,13 +204,9 @@ gk104_fifo_context_detach(struct nvkm_object *parent, bool suspend,
188 return -EINVAL; 204 return -EINVAL;
189 } 205 }
190 206
191 nv_wr32(priv, 0x002634, chan->base.chid); 207 ret = gk104_fifo_chan_kick(chan);
192 if (!nv_wait(priv, 0x002634, 0xffffffff, chan->base.chid)) { 208 if (ret && suspend)
193 nv_error(priv, "channel %d [%s] kick timeout\n", 209 return ret;
194 chan->base.chid, nvkm_client_name(chan));
195 if (suspend)
196 return -EBUSY;
197 }
198 210
199 if (addr) { 211 if (addr) {
200 nv_wo32(base, addr + 0x00, 0x00000000); 212 nv_wo32(base, addr + 0x00, 0x00000000);
@@ -319,6 +331,7 @@ gk104_fifo_chan_fini(struct nvkm_object *object, bool suspend)
319 gk104_fifo_runlist_update(priv, chan->engine); 331 gk104_fifo_runlist_update(priv, chan->engine);
320 } 332 }
321 333
334 gk104_fifo_chan_kick(chan);
322 nv_wr32(priv, 0x800000 + (chid * 8), 0x00000000); 335 nv_wr32(priv, 0x800000 + (chid * 8), 0x00000000);
323 return nvkm_fifo_channel_fini(&chan->base, suspend); 336 return nvkm_fifo_channel_fini(&chan->base, suspend);
324} 337}