diff options
| author | Dave Airlie <airlied@redhat.com> | 2013-05-19 23:31:36 -0400 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2013-05-19 23:31:36 -0400 |
| commit | b7cb1c50c828adaee95e8ada0e55918686245992 (patch) | |
| tree | 88694170f862f156e6f4a38b8fa207dba9200d45 | |
| parent | e9ced8e040ebe40e9953db90acbe7d0b58702ebb (diff) | |
| parent | 81dff21b643f48c14010a97ffc799e1920d751e5 (diff) | |
Merge branch 'drm-nouveau-fixes-3.10' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next
Fixes some s/r problem with copy engines and ZCULL issues and playlist issues
* 'drm-nouveau-fixes-3.10' of git://anongit.freedesktop.org/git/nouveau/linux-2.6:
drm/nouveau: ensure channels are stopped before saving fences for suspend
drm/nv50/fifo: prevent races between clients updating playlists
drm/nvc0/fifo: prevent CHAN_TABLE_ERROR:CHANNEL_PENDING on fifo fini
drm/nvc0/fifo: prevent races between clients updating playlists
drm/nve0/fifo: prevent races between clients updating playlists
drm/nve0/ltcg: poke the partition count into yet another register
drm/nvc0/ltcg: fix handling of disabled partitions
drm/nvc0/ce: disable ce1 on a number of chipsets
drm/nouveau/bios: fix thinko in ZM_MASK_ADD opcode
drm/nouveau: fix build with nv50->nvc0
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/device/nvc0.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c | 10 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/bios/init.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c | 17 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drm.c | 25 |
7 files changed, 47 insertions, 16 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c index 955af122c3a6..a36e64e98ef3 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c | |||
| @@ -138,7 +138,6 @@ nvc0_identify(struct nouveau_device *device) | |||
| 138 | device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; | 138 | device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; |
| 139 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 139 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
| 140 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; | 140 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; |
| 141 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; | ||
| 142 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; | 141 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; |
| 143 | break; | 142 | break; |
| 144 | case 0xce: | 143 | case 0xce: |
| @@ -225,7 +224,6 @@ nvc0_identify(struct nouveau_device *device) | |||
| 225 | device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; | 224 | device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; |
| 226 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 225 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
| 227 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; | 226 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; |
| 228 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; | ||
| 229 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; | 227 | device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; |
| 230 | break; | 228 | break; |
| 231 | case 0xc8: | 229 | case 0xc8: |
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c index ddaeb5572903..89bf459d584b 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c | |||
| @@ -47,6 +47,7 @@ nv50_fifo_playlist_update(struct nv50_fifo_priv *priv) | |||
| 47 | struct nouveau_gpuobj *cur; | 47 | struct nouveau_gpuobj *cur; |
| 48 | int i, p; | 48 | int i, p; |
| 49 | 49 | ||
| 50 | mutex_lock(&nv_subdev(priv)->mutex); | ||
| 50 | cur = priv->playlist[priv->cur_playlist]; | 51 | cur = priv->playlist[priv->cur_playlist]; |
| 51 | priv->cur_playlist = !priv->cur_playlist; | 52 | priv->cur_playlist = !priv->cur_playlist; |
| 52 | 53 | ||
| @@ -60,6 +61,7 @@ nv50_fifo_playlist_update(struct nv50_fifo_priv *priv) | |||
| 60 | nv_wr32(priv, 0x0032f4, cur->addr >> 12); | 61 | nv_wr32(priv, 0x0032f4, cur->addr >> 12); |
| 61 | nv_wr32(priv, 0x0032ec, p); | 62 | nv_wr32(priv, 0x0032ec, p); |
| 62 | nv_wr32(priv, 0x002500, 0x00000101); | 63 | nv_wr32(priv, 0x002500, 0x00000101); |
| 64 | mutex_unlock(&nv_subdev(priv)->mutex); | ||
| 63 | } | 65 | } |
| 64 | 66 | ||
| 65 | static int | 67 | static int |
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c index 4d4a6b905370..46dfa68c47bb 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c | |||
| @@ -71,6 +71,7 @@ nvc0_fifo_playlist_update(struct nvc0_fifo_priv *priv) | |||
| 71 | struct nouveau_gpuobj *cur; | 71 | struct nouveau_gpuobj *cur; |
| 72 | int i, p; | 72 | int i, p; |
| 73 | 73 | ||
| 74 | mutex_lock(&nv_subdev(priv)->mutex); | ||
| 74 | cur = priv->playlist[priv->cur_playlist]; | 75 | cur = priv->playlist[priv->cur_playlist]; |
| 75 | priv->cur_playlist = !priv->cur_playlist; | 76 | priv->cur_playlist = !priv->cur_playlist; |
| 76 | 77 | ||
| @@ -87,6 +88,7 @@ nvc0_fifo_playlist_update(struct nvc0_fifo_priv *priv) | |||
| 87 | nv_wr32(priv, 0x002274, 0x01f00000 | (p >> 3)); | 88 | nv_wr32(priv, 0x002274, 0x01f00000 | (p >> 3)); |
| 88 | if (!nv_wait(priv, 0x00227c, 0x00100000, 0x00000000)) | 89 | if (!nv_wait(priv, 0x00227c, 0x00100000, 0x00000000)) |
| 89 | nv_error(priv, "playlist update failed\n"); | 90 | nv_error(priv, "playlist update failed\n"); |
| 91 | mutex_unlock(&nv_subdev(priv)->mutex); | ||
| 90 | } | 92 | } |
| 91 | 93 | ||
| 92 | static int | 94 | static int |
| @@ -248,9 +250,17 @@ nvc0_fifo_chan_fini(struct nouveau_object *object, bool suspend) | |||
| 248 | struct nvc0_fifo_priv *priv = (void *)object->engine; | 250 | struct nvc0_fifo_priv *priv = (void *)object->engine; |
| 249 | struct nvc0_fifo_chan *chan = (void *)object; | 251 | struct nvc0_fifo_chan *chan = (void *)object; |
| 250 | u32 chid = chan->base.chid; | 252 | u32 chid = chan->base.chid; |
| 253 | u32 mask, engine; | ||
| 251 | 254 | ||
| 252 | nv_mask(priv, 0x003004 + (chid * 8), 0x00000001, 0x00000000); | 255 | nv_mask(priv, 0x003004 + (chid * 8), 0x00000001, 0x00000000); |
| 253 | nvc0_fifo_playlist_update(priv); | 256 | nvc0_fifo_playlist_update(priv); |
| 257 | mask = nv_rd32(priv, 0x0025a4); | ||
| 258 | for (engine = 0; mask && engine < 16; engine++) { | ||
| 259 | if (!(mask & (1 << engine))) | ||
| 260 | continue; | ||
| 261 | nv_mask(priv, 0x0025a8 + (engine * 4), 0x00000000, 0x00000000); | ||
| 262 | mask &= ~(1 << engine); | ||
| 263 | } | ||
| 254 | nv_wr32(priv, 0x003000 + (chid * 8), 0x00000000); | 264 | nv_wr32(priv, 0x003000 + (chid * 8), 0x00000000); |
| 255 | 265 | ||
| 256 | return nouveau_fifo_channel_fini(&chan->base, suspend); | 266 | return nouveau_fifo_channel_fini(&chan->base, suspend); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index 9151919fb831..56192a7242ae 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c | |||
| @@ -94,11 +94,13 @@ nve0_fifo_playlist_update(struct nve0_fifo_priv *priv, u32 engine) | |||
| 94 | u32 match = (engine << 16) | 0x00000001; | 94 | u32 match = (engine << 16) | 0x00000001; |
| 95 | int i, p; | 95 | int i, p; |
| 96 | 96 | ||
| 97 | mutex_lock(&nv_subdev(priv)->mutex); | ||
| 97 | cur = engn->playlist[engn->cur_playlist]; | 98 | cur = engn->playlist[engn->cur_playlist]; |
| 98 | if (unlikely(cur == NULL)) { | 99 | if (unlikely(cur == NULL)) { |
| 99 | int ret = nouveau_gpuobj_new(nv_object(priv), NULL, | 100 | int ret = nouveau_gpuobj_new(nv_object(priv), NULL, |
| 100 | 0x8000, 0x1000, 0, &cur); | 101 | 0x8000, 0x1000, 0, &cur); |
| 101 | if (ret) { | 102 | if (ret) { |
| 103 | mutex_unlock(&nv_subdev(priv)->mutex); | ||
| 102 | nv_error(priv, "playlist alloc failed\n"); | 104 | nv_error(priv, "playlist alloc failed\n"); |
| 103 | return; | 105 | return; |
| 104 | } | 106 | } |
| @@ -122,6 +124,7 @@ nve0_fifo_playlist_update(struct nve0_fifo_priv *priv, u32 engine) | |||
| 122 | nv_wr32(priv, 0x002274, (engine << 20) | (p >> 3)); | 124 | nv_wr32(priv, 0x002274, (engine << 20) | (p >> 3)); |
| 123 | if (!nv_wait(priv, 0x002284 + (engine * 4), 0x00100000, 0x00000000)) | 125 | if (!nv_wait(priv, 0x002284 + (engine * 4), 0x00100000, 0x00000000)) |
| 124 | nv_error(priv, "playlist %d update timeout\n", engine); | 126 | nv_error(priv, "playlist %d update timeout\n", engine); |
| 127 | mutex_unlock(&nv_subdev(priv)->mutex); | ||
| 125 | } | 128 | } |
| 126 | 129 | ||
| 127 | static int | 130 | static int |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c index c300b5e7b670..c434d398d16f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c | |||
| @@ -1940,8 +1940,8 @@ init_zm_mask_add(struct nvbios_init *init) | |||
| 1940 | trace("ZM_MASK_ADD\tR[0x%06x] &= 0x%08x += 0x%08x\n", addr, mask, add); | 1940 | trace("ZM_MASK_ADD\tR[0x%06x] &= 0x%08x += 0x%08x\n", addr, mask, add); |
| 1941 | init->offset += 13; | 1941 | init->offset += 13; |
| 1942 | 1942 | ||
| 1943 | data = init_rd32(init, addr) & mask; | 1943 | data = init_rd32(init, addr); |
| 1944 | data |= ((data + add) & ~mask); | 1944 | data = (data & mask) | ((data + add) & ~mask); |
| 1945 | init_wr32(init, addr, data); | 1945 | init_wr32(init, addr, data); |
| 1946 | } | 1946 | } |
| 1947 | 1947 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c index e4940fb166e8..fb794e997fbc 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | struct nvc0_ltcg_priv { | 29 | struct nvc0_ltcg_priv { |
| 30 | struct nouveau_ltcg base; | 30 | struct nouveau_ltcg base; |
| 31 | u32 part_nr; | 31 | u32 part_nr; |
| 32 | u32 part_mask; | ||
| 33 | u32 subp_nr; | 32 | u32 subp_nr; |
| 34 | struct nouveau_mm tags; | 33 | struct nouveau_mm tags; |
| 35 | u32 num_tags; | 34 | u32 num_tags; |
| @@ -105,8 +104,6 @@ nvc0_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count) | |||
| 105 | 104 | ||
| 106 | /* wait until it's finished with clearing */ | 105 | /* wait until it's finished with clearing */ |
| 107 | for (p = 0; p < priv->part_nr; ++p) { | 106 | for (p = 0; p < priv->part_nr; ++p) { |
| 108 | if (!(priv->part_mask & (1 << p))) | ||
| 109 | continue; | ||
| 110 | for (i = 0; i < priv->subp_nr; ++i) | ||
