Commit 624c6f78 authored by Ben Skeggs's avatar Ben Skeggs Committed by Dave Airlie

drm/nouveau/imem/tu102-: prepare for GSP-RM

- move suspend/resume paths to HW-specific code
- allow (future) RM paths to be based on nv50_instmem
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230918202149.4343-15-skeggsb@gmail.com
parent a25a5d56
...@@ -8,6 +8,8 @@ struct nvkm_instmem { ...@@ -8,6 +8,8 @@ struct nvkm_instmem {
const struct nvkm_instmem_func *func; const struct nvkm_instmem_func *func;
struct nvkm_subdev subdev; struct nvkm_subdev subdev;
bool suspend;
spinlock_t lock; spinlock_t lock;
struct list_head list; struct list_head list;
struct list_head boot; struct list_head boot;
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
/****************************************************************************** /******************************************************************************
* instmem object base implementation * instmem object base implementation
*****************************************************************************/ *****************************************************************************/
static void void
nvkm_instobj_load(struct nvkm_instobj *iobj) nvkm_instobj_load(struct nvkm_instobj *iobj)
{ {
struct nvkm_memory *memory = &iobj->memory; struct nvkm_memory *memory = &iobj->memory;
...@@ -48,7 +48,7 @@ nvkm_instobj_load(struct nvkm_instobj *iobj) ...@@ -48,7 +48,7 @@ nvkm_instobj_load(struct nvkm_instobj *iobj)
iobj->suspend = NULL; iobj->suspend = NULL;
} }
static int int
nvkm_instobj_save(struct nvkm_instobj *iobj) nvkm_instobj_save(struct nvkm_instobj *iobj)
{ {
struct nvkm_memory *memory = &iobj->memory; struct nvkm_memory *memory = &iobj->memory;
...@@ -179,24 +179,14 @@ static int ...@@ -179,24 +179,14 @@ static int
nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend) nvkm_instmem_fini(struct nvkm_subdev *subdev, bool suspend)
{ {
struct nvkm_instmem *imem = nvkm_instmem(subdev); struct nvkm_instmem *imem = nvkm_instmem(subdev);
struct nvkm_instobj *iobj; int ret;
if (suspend) { if (suspend) {
list_for_each_entry(iobj, &imem->list, head) { ret = imem->func->suspend(imem);
if (iobj->preserve) { if (ret)
int ret = nvkm_instobj_save(iobj); return ret;
if (ret)
return ret;
}
}
nvkm_bar_bar2_fini(subdev->device);
list_for_each_entry(iobj, &imem->boot, head) { imem->suspend = true;
int ret = nvkm_instobj_save(iobj);
if (ret)
return ret;
}
} }
if (imem->func->fini) if (imem->func->fini)
...@@ -209,20 +199,16 @@ static int ...@@ -209,20 +199,16 @@ static int
nvkm_instmem_init(struct nvkm_subdev *subdev) nvkm_instmem_init(struct nvkm_subdev *subdev)
{ {
struct nvkm_instmem *imem = nvkm_instmem(subdev); struct nvkm_instmem *imem = nvkm_instmem(subdev);
struct nvkm_instobj *iobj;
list_for_each_entry(iobj, &imem->boot, head) { if (imem->suspend) {
if (iobj->suspend) if (imem->func->resume)
nvkm_instobj_load(iobj); imem->func->resume(imem);
}
nvkm_bar_bar2_init(subdev->device); imem->suspend = false;
return 0;
list_for_each_entry(iobj, &imem->list, head) {
if (iobj->suspend)
nvkm_instobj_load(iobj);
} }
nvkm_bar_bar2_init(subdev->device);
return 0; return 0;
} }
......
...@@ -564,6 +564,8 @@ gk20a_instmem_dtor(struct nvkm_instmem *base) ...@@ -564,6 +564,8 @@ gk20a_instmem_dtor(struct nvkm_instmem *base)
static const struct nvkm_instmem_func static const struct nvkm_instmem_func
gk20a_instmem = { gk20a_instmem = {
.dtor = gk20a_instmem_dtor, .dtor = gk20a_instmem_dtor,
.suspend = nv04_instmem_suspend,
.resume = nv04_instmem_resume,
.memory_new = gk20a_instobj_new, .memory_new = gk20a_instobj_new,
.zero = false, .zero = false,
}; };
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "priv.h" #include "priv.h"
#include <core/ramht.h> #include <core/ramht.h>
#include <subdev/bar.h>
struct nv04_instmem { struct nv04_instmem {
struct nvkm_instmem base; struct nvkm_instmem base;
...@@ -154,6 +155,48 @@ nv04_instmem_wr32(struct nvkm_instmem *imem, u32 addr, u32 data) ...@@ -154,6 +155,48 @@ nv04_instmem_wr32(struct nvkm_instmem *imem, u32 addr, u32 data)
nvkm_wr32(imem->subdev.device, 0x700000 + addr, data); nvkm_wr32(imem->subdev.device, 0x700000 + addr, data);
} }
void
nv04_instmem_resume(struct nvkm_instmem *imem)
{
struct nvkm_instobj *iobj;
list_for_each_entry(iobj, &imem->boot, head) {
if (iobj->suspend)
nvkm_instobj_load(iobj);
}
nvkm_bar_bar2_init(imem->subdev.device);
list_for_each_entry(iobj, &imem->list, head) {
if (iobj->suspend)
nvkm_instobj_load(iobj);
}
}
int
nv04_instmem_suspend(struct nvkm_instmem *imem)
{
struct nvkm_instobj *iobj;
list_for_each_entry(iobj, &imem->list, head) {
if (iobj->preserve) {
int ret = nvkm_instobj_save(iobj);
if (ret)
return ret;
}
}
nvkm_bar_bar2_fini(imem->subdev.device);
list_for_each_entry(iobj, &imem->boot, head) {
int ret = nvkm_instobj_save(iobj);
if (ret)
return ret;
}
return 0;
}
static int static int
nv04_instmem_oneinit(struct nvkm_instmem *base) nv04_instmem_oneinit(struct nvkm_instmem *base)
{ {
...@@ -210,6 +253,8 @@ static const struct nvkm_instmem_func ...@@ -210,6 +253,8 @@ static const struct nvkm_instmem_func
nv04_instmem = { nv04_instmem = {
.dtor = nv04_instmem_dtor, .dtor = nv04_instmem_dtor,
.oneinit = nv04_instmem_oneinit, .oneinit = nv04_instmem_oneinit,
.suspend = nv04_instmem_suspend,
.resume = nv04_instmem_resume,
.rd32 = nv04_instmem_rd32, .rd32 = nv04_instmem_rd32,
.wr32 = nv04_instmem_wr32, .wr32 = nv04_instmem_wr32,
.memory_new = nv04_instobj_new, .memory_new = nv04_instobj_new,
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <core/memory.h> #include <core/memory.h>
#include <subdev/bar.h> #include <subdev/bar.h>
#include <subdev/fb.h> #include <subdev/fb.h>
#include <subdev/gsp.h>
#include <subdev/mmu.h> #include <subdev/mmu.h>
struct nv50_instmem { struct nv50_instmem {
...@@ -394,24 +395,44 @@ nv50_instmem_fini(struct nvkm_instmem *base) ...@@ -394,24 +395,44 @@ nv50_instmem_fini(struct nvkm_instmem *base)
nv50_instmem(base)->addr = ~0ULL; nv50_instmem(base)->addr = ~0ULL;
} }
static void *
nv50_instmem_dtor(struct nvkm_instmem *base)
{
return nv50_instmem(base);
}
static const struct nvkm_instmem_func static const struct nvkm_instmem_func
nv50_instmem = { nv50_instmem = {
.dtor = nv50_instmem_dtor,
.fini = nv50_instmem_fini, .fini = nv50_instmem_fini,
.suspend = nv04_instmem_suspend,
.resume = nv04_instmem_resume,
.memory_new = nv50_instobj_new, .memory_new = nv50_instobj_new,
.memory_wrap = nv50_instobj_wrap, .memory_wrap = nv50_instobj_wrap,
.zero = false, .zero = false,
}; };
int int
nv50_instmem_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, nv50_instmem_new_(const struct nvkm_instmem_func *func,
struct nvkm_instmem **pimem) struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
struct nvkm_instmem **pimem)
{ {
struct nv50_instmem *imem; struct nv50_instmem *imem;
if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL))) if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL)))
return -ENOMEM; return -ENOMEM;
nvkm_instmem_ctor(&nv50_instmem, device, type, inst, &imem->base); nvkm_instmem_ctor(func, device, type, inst, &imem->base);
INIT_LIST_HEAD(&imem->lru); INIT_LIST_HEAD(&imem->lru);
*pimem = &imem->base; *pimem = &imem->base;
return 0; return 0;
} }
int
nv50_instmem_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
struct nvkm_instmem **pimem)
{
if (nvkm_gsp_rm(device->gsp))
return -ENODEV;
return nv50_instmem_new_(&nv50_instmem, device, type, inst, pimem);
}
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
struct nvkm_instmem_func { struct nvkm_instmem_func {
void *(*dtor)(struct nvkm_instmem *); void *(*dtor)(struct nvkm_instmem *);
int (*oneinit)(struct nvkm_instmem *); int (*oneinit)(struct nvkm_instmem *);
int (*suspend)(struct nvkm_instmem *);
void (*resume)(struct nvkm_instmem *);
void (*fini)(struct nvkm_instmem *); void (*fini)(struct nvkm_instmem *);
u32 (*rd32)(struct nvkm_instmem *, u32 addr); u32 (*rd32)(struct nvkm_instmem *, u32 addr);
void (*wr32)(struct nvkm_instmem *, u32 addr, u32 data); void (*wr32)(struct nvkm_instmem *, u32 addr, u32 data);
...@@ -16,10 +18,16 @@ struct nvkm_instmem_func { ...@@ -16,10 +18,16 @@ struct nvkm_instmem_func {
bool zero; bool zero;
}; };
int nv50_instmem_new_(const struct nvkm_instmem_func *, struct nvkm_device *,
enum nvkm_subdev_type, int, struct nvkm_instmem **);
void nvkm_instmem_ctor(const struct nvkm_instmem_func *, struct nvkm_device *, void nvkm_instmem_ctor(const struct nvkm_instmem_func *, struct nvkm_device *,
enum nvkm_subdev_type, int, struct nvkm_instmem *); enum nvkm_subdev_type, int, struct nvkm_instmem *);
void nvkm_instmem_boot(struct nvkm_instmem *); void nvkm_instmem_boot(struct nvkm_instmem *);
int nv04_instmem_suspend(struct nvkm_instmem *);
void nv04_instmem_resume(struct nvkm_instmem *);
#include <core/memory.h> #include <core/memory.h>
struct nvkm_instobj { struct nvkm_instobj {
...@@ -32,4 +40,6 @@ struct nvkm_instobj { ...@@ -32,4 +40,6 @@ struct nvkm_instobj {
void nvkm_instobj_ctor(const struct nvkm_memory_func *func, void nvkm_instobj_ctor(const struct nvkm_memory_func *func,
struct nvkm_instmem *, struct nvkm_instobj *); struct nvkm_instmem *, struct nvkm_instobj *);
void nvkm_instobj_dtor(struct nvkm_instmem *, struct nvkm_instobj *); void nvkm_instobj_dtor(struct nvkm_instmem *, struct nvkm_instobj *);
int nvkm_instobj_save(struct nvkm_instobj *);
void nvkm_instobj_load(struct nvkm_instobj *);
#endif #endif
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