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

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
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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;
+13 −27
Original line number Diff line number Diff line
@@ -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);
		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);

	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;
}

+2 −0
Original line number Diff line number Diff line
@@ -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,
};
+45 −0
Original line number Diff line number Diff line
@@ -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,
+24 −3
Original line number Diff line number Diff line
@@ -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,
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);
}
Loading