summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c')
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c49
1 files changed, 22 insertions, 27 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
index e0e4f97be..a2cd3330e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
@@ -28,7 +28,7 @@
/******************************************************************************
* instmem object base implementation
*****************************************************************************/
-static void
+void
nvkm_instobj_load(struct nvkm_instobj *iobj)
{
struct nvkm_memory *memory = &iobj->memory;
@@ -48,7 +48,7 @@ nvkm_instobj_load(struct nvkm_instobj *iobj)
iobj->suspend = NULL;
}
-static int
+int
nvkm_instobj_save(struct nvkm_instobj *iobj)
{
struct nvkm_memory *memory = &iobj->memory;
@@ -94,15 +94,21 @@ nvkm_instobj_wrap(struct nvkm_device *device,
struct nvkm_memory *memory, struct nvkm_memory **pmemory)
{
struct nvkm_instmem *imem = device->imem;
+ int ret;
if (!imem->func->memory_wrap)
return -ENOSYS;
- return imem->func->memory_wrap(imem, memory, pmemory);
+ ret = imem->func->memory_wrap(imem, memory, pmemory);
+ if (ret)
+ return ret;
+
+ container_of(*pmemory, struct nvkm_instobj, memory)->preserve = true;
+ return 0;
}
int
-nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero,
+nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero, bool preserve,
struct nvkm_memory **pmemory)
{
struct nvkm_subdev *subdev = &imem->subdev;
@@ -130,6 +136,7 @@ nvkm_instobj_new(struct nvkm_instmem *imem, u32 size, u32 align, bool zero,
nvkm_done(memory);
}
+ container_of(memory, struct nvkm_instobj, memory)->preserve = preserve;
done:
if (ret)
nvkm_memory_unref(&memory);
@@ -172,22 +179,14 @@ static int
nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend)
{
struct nvkm_instmem *imem = nvkm_instmem(subdev);
- struct nvkm_instobj *iobj;
+ int ret;
if (suspend) {
- list_for_each_entry(iobj, &imem->list, head) {
- int ret = nvkm_instobj_save(iobj);
- if (ret)
- return ret;
- }
-
- nvkm_bar_bar2_fini(subdev->device);
+ ret = imem->func->suspend(imem);
+ if (ret)
+ return ret;
- list_for_each_entry(iobj, &imem->boot, head) {
- int ret = nvkm_instobj_save(iobj);
- if (ret)
- return ret;
- }
+ imem->suspend = true;
}
if (imem->func->fini)
@@ -200,20 +199,16 @@ static int
nvkm_instmem_init(struct nvkm_subdev *subdev)
{
struct nvkm_instmem *imem = nvkm_instmem(subdev);
- struct nvkm_instobj *iobj;
- list_for_each_entry(iobj, &imem->boot, head) {
- if (iobj->suspend)
- nvkm_instobj_load(iobj);
- }
+ if (imem->suspend) {
+ if (imem->func->resume)
+ imem->func->resume(imem);
- nvkm_bar_bar2_init(subdev->device);
-
- list_for_each_entry(iobj, &imem->list, head) {
- if (iobj->suspend)
- nvkm_instobj_load(iobj);
+ imem->suspend = false;
+ return 0;
}
+ nvkm_bar_bar2_init(subdev->device);
return 0;
}