aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-10-25 01:23:59 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-12-03 00:11:47 -0500
commitdc1e5c0dbff27c2b5147eaea16c578d2337870c3 (patch)
tree82b7bd25bd162d5a9bcc5ee0598e697e1ddbd08e
parentfce2bad0ee2666d6a10bfeb634b1021469cc3d79 (diff)
drm/nouveau: simplify gpuobj suspend/resume
Reviewed-by: Francisco Jerez <currojerez@riseup.net> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.c14
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_object.c56
-rw-r--r--drivers/gpu/drm/nouveau/nv50_instmem.c21
4 files changed, 21 insertions, 73 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
index 52f9307d7396..7ff5b4369f03 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
@@ -222,17 +222,17 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
222 pfifo->unload_context(dev); 222 pfifo->unload_context(dev);
223 pgraph->unload_context(dev); 223 pgraph->unload_context(dev);
224 224
225 NV_INFO(dev, "Suspending GPU objects...\n"); 225 ret = pinstmem->suspend(dev);
226 ret = nouveau_gpuobj_suspend(dev);
227 if (ret) { 226 if (ret) {
228 NV_ERROR(dev, "... failed: %d\n", ret); 227 NV_ERROR(dev, "... failed: %d\n", ret);
229 goto out_abort; 228 goto out_abort;
230 } 229 }
231 230
232 ret = pinstmem->suspend(dev); 231 NV_INFO(dev, "Suspending GPU objects...\n");
232 ret = nouveau_gpuobj_suspend(dev);
233 if (ret) { 233 if (ret) {
234 NV_ERROR(dev, "... failed: %d\n", ret); 234 NV_ERROR(dev, "... failed: %d\n", ret);
235 nouveau_gpuobj_suspend_cleanup(dev); 235 pinstmem->resume(dev);
236 goto out_abort; 236 goto out_abort;
237 } 237 }
238 238
@@ -297,6 +297,9 @@ nouveau_pci_resume(struct pci_dev *pdev)
297 } 297 }
298 } 298 }
299 299
300 NV_INFO(dev, "Restoring GPU objects...\n");
301 nouveau_gpuobj_resume(dev);
302
300 NV_INFO(dev, "Reinitialising engines...\n"); 303 NV_INFO(dev, "Reinitialising engines...\n");
301 engine->instmem.resume(dev); 304 engine->instmem.resume(dev);
302 engine->mc.init(dev); 305 engine->mc.init(dev);
@@ -306,9 +309,6 @@ nouveau_pci_resume(struct pci_dev *pdev)
306 engine->crypt.init(dev); 309 engine->crypt.init(dev);
307 engine->fifo.init(dev); 310 engine->fifo.init(dev);
308 311
309 NV_INFO(dev, "Restoring GPU objects...\n");
310 nouveau_gpuobj_resume(dev);
311
312 nouveau_irq_postinstall(dev); 312 nouveau_irq_postinstall(dev);
313 313
314 /* Re-write SKIPS, they'll have been lost over the suspend */ 314 /* Re-write SKIPS, they'll have been lost over the suspend */
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 912c9f785222..18a611e1ab80 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -153,7 +153,7 @@ struct nouveau_gpuobj {
153 153
154 struct drm_mm_node *im_pramin; 154 struct drm_mm_node *im_pramin;
155 struct nouveau_bo *im_backing; 155 struct nouveau_bo *im_backing;
156 uint32_t *im_backing_suspend; 156 u32 *suspend;
157 int im_bound; 157 int im_bound;
158 158
159 uint32_t flags; 159 uint32_t flags;
@@ -865,7 +865,6 @@ extern int nouveau_gpuobj_early_init(struct drm_device *);
865extern int nouveau_gpuobj_init(struct drm_device *); 865extern int nouveau_gpuobj_init(struct drm_device *);
866extern void nouveau_gpuobj_takedown(struct drm_device *); 866extern void nouveau_gpuobj_takedown(struct drm_device *);
867extern int nouveau_gpuobj_suspend(struct drm_device *dev); 867extern int nouveau_gpuobj_suspend(struct drm_device *dev);
868extern void nouveau_gpuobj_suspend_cleanup(struct drm_device *dev);
869extern void nouveau_gpuobj_resume(struct drm_device *dev); 868extern void nouveau_gpuobj_resume(struct drm_device *dev);
870extern int nouveau_gpuobj_class_new(struct drm_device *, u32 class, u32 eng); 869extern int nouveau_gpuobj_class_new(struct drm_device *, u32 class, u32 eng);
871extern int nouveau_gpuobj_mthd_new(struct drm_device *, u32 class, u32 mthd, 870extern int nouveau_gpuobj_mthd_new(struct drm_device *, u32 class, u32 mthd,
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c
index 94429553433c..8c5e35cc04df 100644
--- a/drivers/gpu/drm/nouveau/nouveau_object.c
+++ b/drivers/gpu/drm/nouveau/nouveau_object.c
@@ -934,78 +934,42 @@ nouveau_gpuobj_suspend(struct drm_device *dev)
934 struct nouveau_gpuobj *gpuobj; 934 struct nouveau_gpuobj *gpuobj;
935 int i; 935 int i;
936 936
937 if (dev_priv->card_type < NV_50) {
938 dev_priv->susres.ramin_copy = vmalloc(dev_priv->ramin_rsvd_vram);
939 if (!dev_priv->susres.ramin_copy)
940 return -ENOMEM;
941
942 for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4)
943 dev_priv->susres.ramin_copy[i/4] = nv_ri32(dev, i);
944 return 0;
945 }
946
947 list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) { 937 list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
948 if (!gpuobj->im_backing) 938 if (gpuobj->cinst != 0xdeadbeef)
949 continue; 939 continue;
950 940
951 gpuobj->im_backing_suspend = vmalloc(gpuobj->size); 941 gpuobj->suspend = vmalloc(gpuobj->size);
952 if (!gpuobj->im_backing_suspend) { 942 if (!gpuobj->suspend) {
953 nouveau_gpuobj_resume(dev); 943 nouveau_gpuobj_resume(dev);
954 return -ENOMEM; 944 return -ENOMEM;
955 } 945 }
956 946
957 for (i = 0; i < gpuobj->size; i += 4) 947 for (i = 0; i < gpuobj->size; i += 4)
958 gpuobj->im_backing_suspend[i/4] = nv_ro32(gpuobj, i); 948 gpuobj->suspend[i/4] = nv_ro32(gpuobj, i);
959 } 949 }
960 950
961 return 0; 951 return 0;
962} 952}
963 953
964void 954void
965nouveau_gpuobj_suspend_cleanup(struct drm_device *dev)
966{
967 struct drm_nouveau_private *dev_priv = dev->dev_private;
968 struct nouveau_gpuobj *gpuobj;
969
970 if (dev_priv->card_type < NV_50) {
971 vfree(dev_priv->susres.ramin_copy);
972 dev_priv->susres.ramin_copy = NULL;
973 return;
974 }
975
976 list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
977 if (!gpuobj->im_backing_suspend)
978 continue;
979
980 vfree(gpuobj->im_backing_suspend);
981 gpuobj->im_backing_suspend = NULL;
982 }
983}
984
985void
986nouveau_gpuobj_resume(struct drm_device *dev) 955nouveau_gpuobj_resume(struct drm_device *dev)
987{ 956{
988 struct drm_nouveau_private *dev_priv = dev->dev_private; 957 struct drm_nouveau_private *dev_priv = dev->dev_private;
989 struct nouveau_gpuobj *gpuobj; 958 struct nouveau_gpuobj *gpuobj;
990 int i; 959 int i;
991 960
992 if (dev_priv->card_type < NV_50) {
993 for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4)
994 nv_wi32(dev, i, dev_priv->susres.ramin_copy[i/4]);
995 nouveau_gpuobj_suspend_cleanup(dev);
996 return;
997 }
998
999 list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) { 961 list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
1000 if (!gpuobj->im_backing_suspend) 962 if (!gpuobj->suspend)
1001 continue; 963 continue;
1002 964
1003 for (i = 0; i < gpuobj->size; i += 4) 965 for (i = 0; i < gpuobj->size; i += 4)
1004 nv_wo32(gpuobj, i, gpuobj->im_backing_suspend[i/4]); 966 nv_wo32(gpuobj, i, gpuobj->suspend[i/4]);
1005 dev_priv->engine.instmem.flush(dev); 967
968 vfree(gpuobj->suspend);
969 gpuobj->suspend = NULL;
1006 } 970 }
1007 971
1008 nouveau_gpuobj_suspend_cleanup(dev); 972 dev_priv->engine.instmem.flush(dev);
1009} 973}
1010 974
1011int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, 975int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c
index 2c98eb176d64..1640c12d8b3a 100644
--- a/drivers/gpu/drm/nouveau/nv50_instmem.c
+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c
@@ -276,16 +276,8 @@ int
276nv50_instmem_suspend(struct drm_device *dev) 276nv50_instmem_suspend(struct drm_device *dev)
277{ 277{
278 struct drm_nouveau_private *dev_priv = dev->dev_private; 278 struct drm_nouveau_private *dev_priv = dev->dev_private;
279 struct nouveau_channel *chan = dev_priv->channels.ptr[0];
280 struct nouveau_gpuobj *ramin = chan->ramin;
281 int i;
282 279
283 ramin->im_backing_suspend = vmalloc(ramin->size); 280 dev_priv->ramin_available = false;
284 if (!ramin->im_backing_suspend)
285 return -ENOMEM;
286
287 for (i = 0; i < ramin->size; i += 4)
288 ramin->im_backing_suspend[i/4] = nv_ri32(dev, i);
289 return 0; 281 return 0;
290} 282}
291 283
@@ -295,17 +287,8 @@ nv50_instmem_resume(struct drm_device *dev)
295 struct drm_nouveau_private *dev_priv = dev->dev_private; 287 struct drm_nouveau_private *dev_priv = dev->dev_private;
296 struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; 288 struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
297 struct nouveau_channel *chan = dev_priv->channels.ptr[0]; 289 struct nouveau_channel *chan = dev_priv->channels.ptr[0];
298 struct nouveau_gpuobj *ramin = chan->ramin;
299 int i; 290 int i;
300 291
301 dev_priv->ramin_available = false;
302 dev_priv->ramin_base = ~0;
303 for (i = 0; i < ramin->size; i += 4)
304 nv_wo32(ramin, i, ramin->im_backing_suspend[i/4]);
305 dev_priv->ramin_available = true;
306 vfree(ramin->im_backing_suspend);
307 ramin->im_backing_suspend = NULL;
308
309 /* Poke the relevant regs, and pray it works :) */ 292 /* Poke the relevant regs, and pray it works :) */
310 nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12)); 293 nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12));
311 nv_wr32(dev, NV50_PUNK_UNK1710, 0); 294 nv_wr32(dev, NV50_PUNK_UNK1710, 0);
@@ -318,6 +301,8 @@ nv50_instmem_resume(struct drm_device *dev)
318 301
319 for (i = 0; i < 8; i++) 302 for (i = 0; i < 8; i++)
320 nv_wr32(dev, 0x1900 + (i*4), 0); 303 nv_wr32(dev, 0x1900 + (i*4), 0);
304
305 dev_priv->ramin_available = true;
321} 306}
322 307
323int 308int