diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-10-25 01:23:59 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-12-03 00:11:47 -0500 |
commit | dc1e5c0dbff27c2b5147eaea16c578d2337870c3 (patch) | |
tree | 82b7bd25bd162d5a9bcc5ee0598e697e1ddbd08e /drivers/gpu/drm | |
parent | fce2bad0ee2666d6a10bfeb634b1021469cc3d79 (diff) |
drm/nouveau: simplify gpuobj suspend/resume
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_object.c | 56 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_instmem.c | 21 |
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 *); | |||
865 | extern int nouveau_gpuobj_init(struct drm_device *); | 865 | extern int nouveau_gpuobj_init(struct drm_device *); |
866 | extern void nouveau_gpuobj_takedown(struct drm_device *); | 866 | extern void nouveau_gpuobj_takedown(struct drm_device *); |
867 | extern int nouveau_gpuobj_suspend(struct drm_device *dev); | 867 | extern int nouveau_gpuobj_suspend(struct drm_device *dev); |
868 | extern void nouveau_gpuobj_suspend_cleanup(struct drm_device *dev); | ||
869 | extern void nouveau_gpuobj_resume(struct drm_device *dev); | 868 | extern void nouveau_gpuobj_resume(struct drm_device *dev); |
870 | extern int nouveau_gpuobj_class_new(struct drm_device *, u32 class, u32 eng); | 869 | extern int nouveau_gpuobj_class_new(struct drm_device *, u32 class, u32 eng); |
871 | extern int nouveau_gpuobj_mthd_new(struct drm_device *, u32 class, u32 mthd, | 870 | extern 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 | ||
964 | void | 954 | void |
965 | nouveau_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 | |||
985 | void | ||
986 | nouveau_gpuobj_resume(struct drm_device *dev) | 955 | nouveau_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 | ||
1011 | int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, | 975 | int 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 | |||
276 | nv50_instmem_suspend(struct drm_device *dev) | 276 | nv50_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 | ||
323 | int | 308 | int |