drm/nouveau: simplify gpuobj suspend/resume
Reviewed-by: Francisco Jerez <currojerez@riseup.net> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
fce2bad0ee
commit
dc1e5c0dbf
4 changed files with 21 additions and 73 deletions
|
@ -222,17 +222,17 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
|
|||
pfifo->unload_context(dev);
|
||||
pgraph->unload_context(dev);
|
||||
|
||||
NV_INFO(dev, "Suspending GPU objects...\n");
|
||||
ret = nouveau_gpuobj_suspend(dev);
|
||||
ret = pinstmem->suspend(dev);
|
||||
if (ret) {
|
||||
NV_ERROR(dev, "... failed: %d\n", ret);
|
||||
goto out_abort;
|
||||
}
|
||||
|
||||
ret = pinstmem->suspend(dev);
|
||||
NV_INFO(dev, "Suspending GPU objects...\n");
|
||||
ret = nouveau_gpuobj_suspend(dev);
|
||||
if (ret) {
|
||||
NV_ERROR(dev, "... failed: %d\n", ret);
|
||||
nouveau_gpuobj_suspend_cleanup(dev);
|
||||
pinstmem->resume(dev);
|
||||
goto out_abort;
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
engine->instmem.resume(dev);
|
||||
engine->mc.init(dev);
|
||||
|
@ -306,9 +309,6 @@ nouveau_pci_resume(struct pci_dev *pdev)
|
|||
engine->crypt.init(dev);
|
||||
engine->fifo.init(dev);
|
||||
|
||||
NV_INFO(dev, "Restoring GPU objects...\n");
|
||||
nouveau_gpuobj_resume(dev);
|
||||
|
||||
nouveau_irq_postinstall(dev);
|
||||
|
||||
/* Re-write SKIPS, they'll have been lost over the suspend */
|
||||
|
|
|
@ -153,7 +153,7 @@ struct nouveau_gpuobj {
|
|||
|
||||
struct drm_mm_node *im_pramin;
|
||||
struct nouveau_bo *im_backing;
|
||||
uint32_t *im_backing_suspend;
|
||||
u32 *suspend;
|
||||
int im_bound;
|
||||
|
||||
uint32_t flags;
|
||||
|
@ -865,7 +865,6 @@ extern int nouveau_gpuobj_early_init(struct drm_device *);
|
|||
extern int nouveau_gpuobj_init(struct drm_device *);
|
||||
extern void nouveau_gpuobj_takedown(struct drm_device *);
|
||||
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 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,
|
||||
|
|
|
@ -934,54 +934,23 @@ nouveau_gpuobj_suspend(struct drm_device *dev)
|
|||
struct nouveau_gpuobj *gpuobj;
|
||||
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) {
|
||||
if (!gpuobj->im_backing)
|
||||
if (gpuobj->cinst != 0xdeadbeef)
|
||||
continue;
|
||||
|
||||
gpuobj->im_backing_suspend = vmalloc(gpuobj->size);
|
||||
if (!gpuobj->im_backing_suspend) {
|
||||
gpuobj->suspend = vmalloc(gpuobj->size);
|
||||
if (!gpuobj->suspend) {
|
||||
nouveau_gpuobj_resume(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
nouveau_gpuobj_resume(struct drm_device *dev)
|
||||
{
|
||||
|
@ -989,23 +958,18 @@ nouveau_gpuobj_resume(struct drm_device *dev)
|
|||
struct nouveau_gpuobj *gpuobj;
|
||||
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) {
|
||||
if (!gpuobj->im_backing_suspend)
|
||||
if (!gpuobj->suspend)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < gpuobj->size; i += 4)
|
||||
nv_wo32(gpuobj, i, gpuobj->im_backing_suspend[i/4]);
|
||||
dev_priv->engine.instmem.flush(dev);
|
||||
nv_wo32(gpuobj, i, gpuobj->suspend[i/4]);
|
||||
|
||||
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,
|
||||
|
|
|
@ -276,16 +276,8 @@ int
|
|||
nv50_instmem_suspend(struct drm_device *dev)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
dev_priv->ramin_available = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -295,17 +287,8 @@ nv50_instmem_resume(struct drm_device *dev)
|
|||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
|
||||
struct nouveau_channel *chan = dev_priv->channels.ptr[0];
|
||||
struct nouveau_gpuobj *ramin = chan->ramin;
|
||||
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 :) */
|
||||
nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12));
|
||||
nv_wr32(dev, NV50_PUNK_UNK1710, 0);
|
||||
|
@ -318,6 +301,8 @@ nv50_instmem_resume(struct drm_device *dev)
|
|||
|
||||
for (i = 0; i < 8; i++)
|
||||
nv_wr32(dev, 0x1900 + (i*4), 0);
|
||||
|
||||
dev_priv->ramin_available = true;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
Loading…
Reference in a new issue