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: Ben Skeggs <bskeggs@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230918202149.4343-15-skeggsb@gmail.com
This commit is contained in:
parent
a25a5d560d
commit
624c6f78cc
@ -8,6 +8,8 @@ struct nvkm_instmem {
|
||||
const struct nvkm_instmem_func *func;
|
||||
struct nvkm_subdev subdev;
|
||||
|
||||
bool suspend;
|
||||
|
||||
spinlock_t lock;
|
||||
struct list_head list;
|
||||
struct list_head boot;
|
||||
|
@ -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;
|
||||
@ -179,24 +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) {
|
||||
if (iobj->preserve) {
|
||||
int ret = nvkm_instobj_save(iobj);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret = imem->func->suspend(imem);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
nvkm_bar_bar2_fini(subdev->device);
|
||||
|
||||
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)
|
||||
@ -209,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);
|
||||
|
||||
imem->suspend = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
nvkm_bar_bar2_init(subdev->device);
|
||||
|
||||
list_for_each_entry(iobj, &imem->list, head) {
|
||||
if (iobj->suspend)
|
||||
nvkm_instobj_load(iobj);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -564,6 +564,8 @@ gk20a_instmem_dtor(struct nvkm_instmem *base)
|
||||
static const struct nvkm_instmem_func
|
||||
gk20a_instmem = {
|
||||
.dtor = gk20a_instmem_dtor,
|
||||
.suspend = nv04_instmem_suspend,
|
||||
.resume = nv04_instmem_resume,
|
||||
.memory_new = gk20a_instobj_new,
|
||||
.zero = false,
|
||||
};
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "priv.h"
|
||||
|
||||
#include <core/ramht.h>
|
||||
#include <subdev/bar.h>
|
||||
|
||||
struct nv04_instmem {
|
||||
struct nvkm_instmem base;
|
||||
@ -154,6 +155,48 @@ nv04_instmem_wr32(struct nvkm_instmem *imem, u32 addr, u32 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
|
||||
nv04_instmem_oneinit(struct nvkm_instmem *base)
|
||||
{
|
||||
@ -210,6 +253,8 @@ static const struct nvkm_instmem_func
|
||||
nv04_instmem = {
|
||||
.dtor = nv04_instmem_dtor,
|
||||
.oneinit = nv04_instmem_oneinit,
|
||||
.suspend = nv04_instmem_suspend,
|
||||
.resume = nv04_instmem_resume,
|
||||
.rd32 = nv04_instmem_rd32,
|
||||
.wr32 = nv04_instmem_wr32,
|
||||
.memory_new = nv04_instobj_new,
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <core/memory.h>
|
||||
#include <subdev/bar.h>
|
||||
#include <subdev/fb.h>
|
||||
#include <subdev/gsp.h>
|
||||
#include <subdev/mmu.h>
|
||||
|
||||
struct nv50_instmem {
|
||||
@ -394,24 +395,44 @@ nv50_instmem_fini(struct nvkm_instmem *base)
|
||||
nv50_instmem(base)->addr = ~0ULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
nv50_instmem_dtor(struct nvkm_instmem *base)
|
||||
{
|
||||
return nv50_instmem(base);
|
||||
}
|
||||
|
||||
static const struct nvkm_instmem_func
|
||||
nv50_instmem = {
|
||||
.dtor = nv50_instmem_dtor,
|
||||
.fini = nv50_instmem_fini,
|
||||
.suspend = nv04_instmem_suspend,
|
||||
.resume = nv04_instmem_resume,
|
||||
.memory_new = nv50_instobj_new,
|
||||
.memory_wrap = nv50_instobj_wrap,
|
||||
.zero = false,
|
||||
};
|
||||
|
||||
int
|
||||
nv50_instmem_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
|
||||
struct nvkm_instmem **pimem)
|
||||
nv50_instmem_new_(const struct nvkm_instmem_func *func,
|
||||
struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
|
||||
struct nvkm_instmem **pimem)
|
||||
{
|
||||
struct nv50_instmem *imem;
|
||||
|
||||
if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL)))
|
||||
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);
|
||||
*pimem = &imem->base;
|
||||
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 @@
|
||||
struct nvkm_instmem_func {
|
||||
void *(*dtor)(struct nvkm_instmem *);
|
||||
int (*oneinit)(struct nvkm_instmem *);
|
||||
int (*suspend)(struct nvkm_instmem *);
|
||||
void (*resume)(struct nvkm_instmem *);
|
||||
void (*fini)(struct nvkm_instmem *);
|
||||
u32 (*rd32)(struct nvkm_instmem *, u32 addr);
|
||||
void (*wr32)(struct nvkm_instmem *, u32 addr, u32 data);
|
||||
@ -16,10 +18,16 @@ struct nvkm_instmem_func {
|
||||
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 *,
|
||||
enum nvkm_subdev_type, int, 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>
|
||||
|
||||
struct nvkm_instobj {
|
||||
@ -32,4 +40,6 @@ struct nvkm_instobj {
|
||||
void nvkm_instobj_ctor(const struct nvkm_memory_func *func,
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user