diff options
| -rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 29 |
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 | ||
| 168 | static int | 168 | static int |
| 169 | gk104_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 | |||
| 184 | static int | ||
| 169 | gk104_fifo_context_detach(struct nvkm_object *parent, bool suspend, | 185 | gk104_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 | } |
