Commit dc1e5c0d authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau: simplify gpuobj suspend/resume

Reviewed-by: default avatarFrancisco Jerez <currojerez@riseup.net>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent fce2bad0
...@@ -222,17 +222,17 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) ...@@ -222,17 +222,17 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
pfifo->unload_context(dev); pfifo->unload_context(dev);
pgraph->unload_context(dev); pgraph->unload_context(dev);
NV_INFO(dev, "Suspending GPU objects...\n"); ret = pinstmem->suspend(dev);
ret = nouveau_gpuobj_suspend(dev);
if (ret) { if (ret) {
NV_ERROR(dev, "... failed: %d\n", ret); NV_ERROR(dev, "... failed: %d\n", ret);
goto out_abort; goto out_abort;
} }
ret = pinstmem->suspend(dev); NV_INFO(dev, "Suspending GPU objects...\n");
ret = nouveau_gpuobj_suspend(dev);
if (ret) { if (ret) {
NV_ERROR(dev, "... failed: %d\n", ret); NV_ERROR(dev, "... failed: %d\n", ret);
nouveau_gpuobj_suspend_cleanup(dev); pinstmem->resume(dev);
goto out_abort; goto out_abort;
} }
...@@ -297,6 +297,9 @@ nouveau_pci_resume(struct pci_dev *pdev) ...@@ -297,6 +297,9 @@ nouveau_pci_resume(struct pci_dev *pdev)
} }
} }
NV_INFO(dev, "Restoring GPU objects...\n");
nouveau_gpuobj_resume(dev);
NV_INFO(dev, "Reinitialising engines...\n"); NV_INFO(dev, "Reinitialising engines...\n");
engine->instmem.resume(dev); engine->instmem.resume(dev);
engine->mc.init(dev); engine->mc.init(dev);
...@@ -306,9 +309,6 @@ nouveau_pci_resume(struct pci_dev *pdev) ...@@ -306,9 +309,6 @@ nouveau_pci_resume(struct pci_dev *pdev)
engine->crypt.init(dev); engine->crypt.init(dev);
engine->fifo.init(dev); engine->fifo.init(dev);
NV_INFO(dev, "Restoring GPU objects...\n");
nouveau_gpuobj_resume(dev);
nouveau_irq_postinstall(dev); nouveau_irq_postinstall(dev);
/* Re-write SKIPS, they'll have been lost over the suspend */ /* Re-write SKIPS, they'll have been lost over the suspend */
......
...@@ -153,7 +153,7 @@ struct nouveau_gpuobj { ...@@ -153,7 +153,7 @@ struct nouveau_gpuobj {
struct drm_mm_node *im_pramin; struct drm_mm_node *im_pramin;
struct nouveau_bo *im_backing; struct nouveau_bo *im_backing;
uint32_t *im_backing_suspend; u32 *suspend;
int im_bound; int im_bound;
uint32_t flags; uint32_t flags;
...@@ -865,7 +865,6 @@ extern int nouveau_gpuobj_early_init(struct drm_device *); ...@@ -865,7 +865,6 @@ extern int nouveau_gpuobj_early_init(struct drm_device *);
extern int nouveau_gpuobj_init(struct drm_device *); extern int nouveau_gpuobj_init(struct drm_device *);
extern void nouveau_gpuobj_takedown(struct drm_device *); extern void nouveau_gpuobj_takedown(struct drm_device *);
extern int nouveau_gpuobj_suspend(struct drm_device *dev); extern int nouveau_gpuobj_suspend(struct drm_device *dev);
extern void nouveau_gpuobj_suspend_cleanup(struct drm_device *dev);
extern void nouveau_gpuobj_resume(struct drm_device *dev); extern void nouveau_gpuobj_resume(struct drm_device *dev);
extern int nouveau_gpuobj_class_new(struct drm_device *, u32 class, u32 eng); extern int nouveau_gpuobj_class_new(struct drm_device *, u32 class, u32 eng);
extern int nouveau_gpuobj_mthd_new(struct drm_device *, u32 class, u32 mthd, extern int nouveau_gpuobj_mthd_new(struct drm_device *, u32 class, u32 mthd,
......
...@@ -934,54 +934,23 @@ nouveau_gpuobj_suspend(struct drm_device *dev) ...@@ -934,54 +934,23 @@ nouveau_gpuobj_suspend(struct drm_device *dev)
struct nouveau_gpuobj *gpuobj; struct nouveau_gpuobj *gpuobj;
int i; int i;
if (dev_priv->card_type < NV_50) {
dev_priv->susres.ramin_copy = vmalloc(dev_priv->ramin_rsvd_vram);
if (!dev_priv->susres.ramin_copy)
return -ENOMEM;
for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4)
dev_priv->susres.ramin_copy[i/4] = nv_ri32(dev, i);
return 0;
}
list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) { list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
if (!gpuobj->im_backing) if (gpuobj->cinst != 0xdeadbeef)
continue; continue;
gpuobj->im_backing_suspend = vmalloc(gpuobj->size); gpuobj->suspend = vmalloc(gpuobj->size);
if (!gpuobj->im_backing_suspend) { if (!gpuobj->suspend) {
nouveau_gpuobj_resume(dev); nouveau_gpuobj_resume(dev);
return -ENOMEM; return -ENOMEM;
} }
for (i = 0; i < gpuobj->size; i += 4) for (i = 0; i < gpuobj->size; i += 4)
gpuobj->im_backing_suspend[i/4] = nv_ro32(gpuobj, i); gpuobj->suspend[i/4] = nv_ro32(gpuobj, i);
} }
return 0; return 0;
} }
void
nouveau_gpuobj_suspend_cleanup(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_gpuobj *gpuobj;
if (dev_priv->card_type < NV_50) {
vfree(dev_priv->susres.ramin_copy);
dev_priv->susres.ramin_copy = NULL;
return;
}
list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
if (!gpuobj->im_backing_suspend)
continue;
vfree(gpuobj->im_backing_suspend);
gpuobj->im_backing_suspend = NULL;
}
}
void void
nouveau_gpuobj_resume(struct drm_device *dev) nouveau_gpuobj_resume(struct drm_device *dev)
{ {
...@@ -989,23 +958,18 @@ nouveau_gpuobj_resume(struct drm_device *dev) ...@@ -989,23 +958,18 @@ nouveau_gpuobj_resume(struct drm_device *dev)
struct nouveau_gpuobj *gpuobj; struct nouveau_gpuobj *gpuobj;
int i; int i;
if (dev_priv->card_type < NV_50) {
for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4)
nv_wi32(dev, i, dev_priv->susres.ramin_copy[i/4]);
nouveau_gpuobj_suspend_cleanup(dev);
return;
}
list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) { list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
if (!gpuobj->im_backing_suspend) if (!gpuobj->suspend)
continue; continue;
for (i = 0; i < gpuobj->size; i += 4) for (i = 0; i < gpuobj->size; i += 4)
nv_wo32(gpuobj, i, gpuobj->im_backing_suspend[i/4]); nv_wo32(gpuobj, i, gpuobj->suspend[i/4]);
dev_priv->engine.instmem.flush(dev);
vfree(gpuobj->suspend);
gpuobj->suspend = NULL;
} }
nouveau_gpuobj_suspend_cleanup(dev); dev_priv->engine.instmem.flush(dev);
} }
int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data,
......
...@@ -276,16 +276,8 @@ int ...@@ -276,16 +276,8 @@ int
nv50_instmem_suspend(struct drm_device *dev) nv50_instmem_suspend(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_channel *chan = dev_priv->channels.ptr[0];
struct nouveau_gpuobj *ramin = chan->ramin;
int i;
ramin->im_backing_suspend = vmalloc(ramin->size); dev_priv->ramin_available = false;
if (!ramin->im_backing_suspend)
return -ENOMEM;
for (i = 0; i < ramin->size; i += 4)
ramin->im_backing_suspend[i/4] = nv_ri32(dev, i);
return 0; return 0;
} }
...@@ -295,17 +287,8 @@ nv50_instmem_resume(struct drm_device *dev) ...@@ -295,17 +287,8 @@ nv50_instmem_resume(struct drm_device *dev)
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
struct nouveau_channel *chan = dev_priv->channels.ptr[0]; struct nouveau_channel *chan = dev_priv->channels.ptr[0];
struct nouveau_gpuobj *ramin = chan->ramin;
int i; int i;
dev_priv->ramin_available = false;
dev_priv->ramin_base = ~0;
for (i = 0; i < ramin->size; i += 4)
nv_wo32(ramin, i, ramin->im_backing_suspend[i/4]);
dev_priv->ramin_available = true;
vfree(ramin->im_backing_suspend);
ramin->im_backing_suspend = NULL;
/* Poke the relevant regs, and pray it works :) */ /* Poke the relevant regs, and pray it works :) */
nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12)); nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12));
nv_wr32(dev, NV50_PUNK_UNK1710, 0); nv_wr32(dev, NV50_PUNK_UNK1710, 0);
...@@ -318,6 +301,8 @@ nv50_instmem_resume(struct drm_device *dev) ...@@ -318,6 +301,8 @@ nv50_instmem_resume(struct drm_device *dev)
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
nv_wr32(dev, 0x1900 + (i*4), 0); nv_wr32(dev, 0x1900 + (i*4), 0);
dev_priv->ramin_available = true;
} }
int int
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment