[Nouveau] [PATCH 10/11] nvkm/pmu/memx: init script -> memx translation
Roy Spliet
nouveau at spliet.org
Mon Apr 10 19:37:27 UTC 2017
Signed-off-by: Roy Spliet <nouveau at spliet.org>
---
drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h | 2 +
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h | 8 +++
drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c | 66 +++++++++++++++++++++++
3 files changed, 76 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
index f37538eb..b9c46ef 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pmu.h
@@ -50,4 +50,6 @@ void nvkm_memx_train(struct nvkm_memx *);
int nvkm_memx_train_result(struct nvkm_pmu *, u32 *, int);
void nvkm_memx_block(struct nvkm_memx *);
void nvkm_memx_unblock(struct nvkm_memx *);
+void nvkm_memx_init_run(struct nvkm_memx *memx, struct nvkm_bios *bios,
+ u16 offset, u8 ramcfg);
#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
index 9ef9d6a..614e716 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramfuc.h
@@ -160,6 +160,13 @@ ramfuc_unblock(struct ramfuc *ram)
nvkm_memx_unblock(ram->memx);
}
+static inline void
+ramfuc_init_run(struct ramfuc *ram, struct nvkm_bios *bios, u16 offset,
+ u8 ramcfg)
+{
+ nvkm_memx_init_run(ram->memx, bios, offset, ramcfg);
+}
+
#define ram_init(s,p) ramfuc_init(&(s)->base, (p))
#define ram_exec(s,e) ramfuc_exec(&(s)->base, (e))
#define ram_have(s,r) ((s)->r_##r.addr != 0x000000)
@@ -174,4 +181,5 @@ ramfuc_unblock(struct ramfuc *ram)
#define ram_train_result(s,r,l) ramfuc_train_result((s), (r), (l))
#define ram_block(s) ramfuc_block(&(s)->base)
#define ram_unblock(s) ramfuc_unblock(&(s)->base)
+#define ram_init_run(s,b,o,r) ramfuc_init_run(&(s)->base, (b), (o), (r))
#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
index e6f7416..c58a51d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c
@@ -1,6 +1,9 @@
#ifndef __NVKM_PMU_MEMX_H__
#define __NVKM_PMU_MEMX_H__
#include "priv.h"
+#include <subdev/bios.h>
+#include <subdev/bios/init.h>
+#include <subdev/bios/ramcfg.h>
struct nvkm_memx {
struct nvkm_pmu *pmu;
@@ -200,4 +203,67 @@ nvkm_memx_unblock(struct nvkm_memx *memx)
nvkm_debug(&memx->pmu->subdev, " HOST UNBLOCKED\n");
memx_cmd(memx, MEMX_LEAVE, 0, NULL);
}
+
+/******************************************************************************
+ * Turn VBIOS init script into memx command stream. Not-quite as feature rich
+ * as subdev/bios/init.c
+ *****************************************************************************/
+
+static void
+nvkm_memx_init_ram_restrict(struct nvkm_memx *memx, struct nvbios_init *init)
+{
+ struct nvkm_bios *bios = init->bios;
+ struct nvkm_subdev *subdev = &memx->pmu->subdev;
+ struct nvkm_device *device = subdev->device;
+ u32 addr = nvbios_rd32(bios, init->offset + 1);
+ u8 incr = nvbios_rd08(bios, init->offset + 5);
+ u8 num = nvbios_rd08(bios, init->offset + 6);
+ u8 count = nvbios_ramcfg_count(init->bios);
+ u8 index = init->ramcfg;
+ u8 i;
+ u32 oldval, newval;
+
+ init->offset += 7;
+
+ for (i = 0; i < num; i++) {
+ oldval = nvkm_rd32(device, addr);
+ newval = nvbios_rd32(bios, init->offset + (4 * index));
+
+ if (oldval != newval) {
+ nvkm_memx_wr32(memx, addr, newval);
+ }
+ init->offset += 4 * count;
+ addr += incr;
+ }
+}
+
+void
+nvkm_memx_init_run(struct nvkm_memx *memx, struct nvkm_bios *bios, u16 offset,
+ u8 ramcfg)
+{
+ struct nvbios_init init = {
+ .subdev = &bios->subdev,
+ .bios = bios,
+ .offset = offset,
+ .outp = NULL,
+ .execute = 1,
+ .ramcfg = ramcfg,
+ };
+ u8 op;
+
+ while (init.offset)
+ {
+ op = nvbios_rd08(bios, init.offset);
+ switch (op)
+ {
+ case 0x8f:
+ nvkm_memx_init_ram_restrict(memx, &init);
+ break;
+ case 0x71:
+ default:
+ return;
+ }
+ }
+}
+
#endif
--
2.9.3
More information about the Nouveau
mailing list