From: Ben Skeggs Date: Wed, 1 Nov 2017 03:56:19 +1000 Subject: drm/nouveau/imem: separate pre-BAR2-bootstrap objects from the rest Git-commit: b00b8430468d2922c5ea9a0557c7a36136df98c2 Patch-mainline: v4.15-rc1 References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166 These will require slow-path access during suspend/resume. Signed-off-by: Ben Skeggs Acked-by: Petr Tesarik --- drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h | 1 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c | 27 ++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 1 drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h | 1 4 files changed, 30 insertions(+) --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/instmem.h @@ -9,6 +9,7 @@ struct nvkm_instmem { spinlock_t lock; struct list_head list; + struct list_head boot; u32 reserved; struct nvkm_memory *vbios; --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c @@ -129,6 +129,21 @@ nvkm_instmem_wr32(struct nvkm_instmem *i return imem->func->wr32(imem, addr, data); } +void +nvkm_instmem_boot(struct nvkm_instmem *imem) +{ + /* Separate bootstrapped objects from normal list, as we need + * to make sure they're accessed with the slowpath on suspend + * and resume. + */ + struct nvkm_instobj *iobj, *itmp; + spin_lock(&imem->lock); + list_for_each_entry_safe(iobj, itmp, &imem->list, head) { + list_move_tail(&iobj->head, &imem->boot); + } + spin_unlock(&imem->lock); +} + static int nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend) { @@ -141,6 +156,12 @@ nvkm_instmem_fini(struct nvkm_subdev *su if (ret) return ret; } + + list_for_each_entry(iobj, &imem->boot, head) { + int ret = nvkm_instobj_save(iobj); + if (ret) + return ret; + } } if (imem->func->fini) @@ -155,6 +176,11 @@ nvkm_instmem_init(struct nvkm_subdev *su 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); + } + list_for_each_entry(iobj, &imem->list, head) { if (iobj->suspend) nvkm_instobj_load(iobj); @@ -198,4 +224,5 @@ nvkm_instmem_ctor(const struct nvkm_inst imem->func = func; spin_lock_init(&imem->lock); INIT_LIST_HEAD(&imem->list); + INIT_LIST_HEAD(&imem->boot); } --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -271,6 +271,7 @@ nv50_instobj_boot(struct nvkm_memory *me } nv50_instobj_kmap(iobj, vmm); + nvkm_instmem_boot(imem); mutex_unlock(&imem->subdev.mutex); } --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/priv.h @@ -16,6 +16,7 @@ struct nvkm_instmem_func { void nvkm_instmem_ctor(const struct nvkm_instmem_func *, struct nvkm_device *, int index, struct nvkm_instmem *); +void nvkm_instmem_boot(struct nvkm_instmem *); #include