summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nvkm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm')
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/engine.c14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/subdev.c12
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/ce/gk104.c14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/ce/gm107.c14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/ce/gm200.c14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/cipher/g84.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/base.c128
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/falcon.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c395
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h29
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c36
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c8
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3.h11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3.h11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5.h11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5.h11
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hub.fuc7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3.h13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3.h13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3.h13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3.h13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5.h13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5.h13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c67
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c43
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c60
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/priv.h3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mpeg/g84.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gt215.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/msppp/gt215.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/msvld/gt215.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/msvld/mcp89.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/sw/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/vp/g84.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/bus/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c8
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c26
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c60
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fuse/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c251
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/priv.h16
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c48
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/g84.c68
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c38
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c49
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk104.c64
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gt215.c70
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv11.c50
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv17.c59
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c21
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/top/Kbuild2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/top/base.c148
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c110
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/top/priv.h25
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c2
145 files changed, 1766 insertions, 781 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/engine.c b/drivers/gpu/drm/nouveau/nvkm/core/engine.c
index 8a7bae7bd995..ee8e5831fe37 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/engine.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/engine.c
@@ -137,11 +137,10 @@ nvkm_engine_func = {
int
nvkm_engine_ctor(const struct nvkm_engine_func *func,
- struct nvkm_device *device, int index, u32 pmc_enable,
- bool enable, struct nvkm_engine *engine)
+ struct nvkm_device *device, int index, bool enable,
+ struct nvkm_engine *engine)
{
- nvkm_subdev_ctor(&nvkm_engine_func, device, index,
- pmc_enable, &engine->subdev);
+ nvkm_subdev_ctor(&nvkm_engine_func, device, index, &engine->subdev);
engine->func = func;
if (!nvkm_boolopt(device->cfgopt, nvkm_subdev_name[index], enable)) {
@@ -155,11 +154,10 @@ nvkm_engine_ctor(const struct nvkm_engine_func *func,
int
nvkm_engine_new_(const struct nvkm_engine_func *func,
- struct nvkm_device *device, int index, u32 pmc_enable,
- bool enable, struct nvkm_engine **pengine)
+ struct nvkm_device *device, int index, bool enable,
+ struct nvkm_engine **pengine)
{
if (!(*pengine = kzalloc(sizeof(**pengine), GFP_KERNEL)))
return -ENOMEM;
- return nvkm_engine_ctor(func, device, index, pmc_enable,
- enable, *pengine);
+ return nvkm_engine_ctor(func, device, index, enable, *pengine);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c
index 3bf08cb1a289..b18557858f19 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c
@@ -24,6 +24,7 @@
#include <core/subdev.h>
#include <core/device.h>
#include <core/option.h>
+#include <subdev/mc.h>
static struct lock_class_key nvkm_subdev_lock_class[NVKM_SUBDEV_NR];
@@ -50,6 +51,7 @@ nvkm_subdev_name[NVKM_SUBDEV_NR] = {
[NVKM_SUBDEV_SECBOOT ] = "secboot",
[NVKM_SUBDEV_THERM ] = "therm",
[NVKM_SUBDEV_TIMER ] = "tmr",
+ [NVKM_SUBDEV_TOP ] = "top",
[NVKM_SUBDEV_VOLT ] = "volt",
[NVKM_ENGINE_BSP ] = "bsp",
[NVKM_ENGINE_CE0 ] = "ce0",
@@ -89,7 +91,6 @@ nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend)
{
struct nvkm_device *device = subdev->device;
const char *action = suspend ? "suspend" : "fini";
- u32 pmc_enable = subdev->pmc_enable;
s64 time;
nvkm_trace(subdev, "%s running...\n", action);
@@ -104,11 +105,7 @@ nvkm_subdev_fini(struct nvkm_subdev *subdev, bool suspend)
}
}
- if (pmc_enable) {
- nvkm_mask(device, 0x000200, pmc_enable, 0x00000000);
- nvkm_mask(device, 0x000200, pmc_enable, pmc_enable);
- nvkm_rd32(device, 0x000200);
- }
+ nvkm_mc_reset(device->mc, subdev->index);
time = ktime_to_us(ktime_get()) - time;
nvkm_trace(subdev, "%s completed in %lldus\n", action, time);
@@ -193,14 +190,13 @@ nvkm_subdev_del(struct nvkm_subdev **psubdev)
void
nvkm_subdev_ctor(const struct nvkm_subdev_func *func,
- struct nvkm_device *device, int index, u32 pmc_enable,
+ struct nvkm_device *device, int index,
struct nvkm_subdev *subdev)
{
const char *name = nvkm_subdev_name[index];
subdev->func = func;
subdev->device = device;
subdev->index = index;
- subdev->pmc_enable = pmc_enable;
__mutex_init(&subdev->mutex, name, &nvkm_subdev_lock_class[index]);
subdev->debug = nvkm_dbgopt(device->dbgopt, name);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c
index 3ef01071f073..8e2e24a74774 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c
@@ -27,7 +27,6 @@
static const struct nvkm_xtensa_func
g84_bsp = {
- .pmc_enable = 0x04008000,
.fifo_val = 0x1111,
.unkd28 = 0x90044,
.sclass = {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c
index 92a9f35df1a6..ad9f855c9a40 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c
@@ -40,7 +40,6 @@ gf100_ce0 = {
.code.size = sizeof(gf100_ce_code),
.data.data = gf100_ce_data,
.data.size = sizeof(gf100_ce_data),
- .pmc_enable = 0x00000040,
.init = gf100_ce_init,
.intr = gt215_ce_intr,
.sclass = {
@@ -55,7 +54,6 @@ gf100_ce1 = {
.code.size = sizeof(gf100_ce_code),
.data.data = gf100_ce_data,
.data.size = sizeof(gf100_ce_data),
- .pmc_enable = 0x00000080,
.init = gf100_ce_init,
.intr = gt215_ce_intr,
.sclass = {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gk104.c
index e2b944dce9b8..9e0b53a10f77 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gk104.c
@@ -97,17 +97,5 @@ int
gk104_ce_new(struct nvkm_device *device, int index,
struct nvkm_engine **pengine)
{
- if (index == NVKM_ENGINE_CE0) {
- return nvkm_engine_new_(&gk104_ce, device, index,
- 0x00000040, true, pengine);
- } else
- if (index == NVKM_ENGINE_CE1) {
- return nvkm_engine_new_(&gk104_ce, device, index,
- 0x00000080, true, pengine);
- } else
- if (index == NVKM_ENGINE_CE2) {
- return nvkm_engine_new_(&gk104_ce, device, index,
- 0x00200000, true, pengine);
- }
- return -ENODEV;
+ return nvkm_engine_new_(&gk104_ce, device, index, true, pengine);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gm107.c
index 4c2f42919c1f..c0df7daa85e2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gm107.c
@@ -39,17 +39,5 @@ int
gm107_ce_new(struct nvkm_device *device, int index,
struct nvkm_engine **pengine)
{
- if (index == NVKM_ENGINE_CE0) {
- return nvkm_engine_new_(&gm107_ce, device, index,
- 0x00000040, true, pengine);
- } else
- if (index == NVKM_ENGINE_CE1) {
- return nvkm_engine_new_(&gm107_ce, device, index,
- 0x00000080, true, pengine);
- } else
- if (index == NVKM_ENGINE_CE2) {
- return nvkm_engine_new_(&gm107_ce, device, index,
- 0x00200000, true, pengine);
- }
- return -ENODEV;
+ return nvkm_engine_new_(&gm107_ce, device, index, true, pengine);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gm200.c
index 13f07b32cd9c..c6fa8b20737e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gm200.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gm200.c
@@ -38,17 +38,5 @@ int
gm200_ce_new(struct nvkm_device *device, int index,
struct nvkm_engine **pengine)
{
- if (index == NVKM_ENGINE_CE0) {
- return nvkm_engine_new_(&gm200_ce, device, index,
- 0x00000040, true, pengine);
- } else
- if (index == NVKM_ENGINE_CE1) {
- return nvkm_engine_new_(&gm200_ce, device, index,
- 0x00000080, true, pengine);
- } else
- if (index == NVKM_ENGINE_CE2) {
- return nvkm_engine_new_(&gm200_ce, device, index,
- 0x00200000, true, pengine);
- }
- return -ENODEV;
+ return nvkm_engine_new_(&gm200_ce, device, index, true, pengine);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c
index 402dcbcc2192..63ac51a54fd3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c
@@ -67,7 +67,6 @@ gt215_ce = {
.code.size = sizeof(gt215_ce_code),
.data.data = gt215_ce_data,
.data.size = sizeof(gt215_ce_data),
- .pmc_enable = 0x00802000,
.intr = gt215_ce_intr,
.sclass = {
{ -1, -1, GT212_DMA },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/cipher/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/cipher/g84.c
index bfd01625ec7f..68ffb520531e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/cipher/g84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/cipher/g84.c
@@ -130,6 +130,5 @@ int
g84_cipher_new(struct nvkm_device *device, int index,
struct nvkm_engine **pengine)
{
- return nvkm_engine_new_(&g84_cipher, device, index,
- 0x00004000, true, pengine);
+ return nvkm_engine_new_(&g84_cipher, device, index, true, pengine);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
index 9f32c8739254..4572debcb0c9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
@@ -146,7 +146,7 @@ nv11_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv04_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv11_mc_new,
.mmu = nv04_mmu_new,
.pci = nv04_pci_new,
.timer = nv04_timer_new,
@@ -190,7 +190,7 @@ nv17_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv04_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv04_mmu_new,
.pci = nv04_pci_new,
.timer = nv04_timer_new,
@@ -212,7 +212,7 @@ nv18_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv04_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv04_mmu_new,
.pci = nv04_pci_new,
.timer = nv04_timer_new,
@@ -256,7 +256,7 @@ nv1f_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv04_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv04_mmu_new,
.pci = nv04_pci_new,
.timer = nv04_timer_new,
@@ -278,7 +278,7 @@ nv20_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv04_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv04_mmu_new,
.pci = nv04_pci_new,
.timer = nv04_timer_new,
@@ -300,7 +300,7 @@ nv25_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv04_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv04_mmu_new,
.pci = nv04_pci_new,
.timer = nv04_timer_new,
@@ -322,7 +322,7 @@ nv28_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv04_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv04_mmu_new,
.pci = nv04_pci_new,
.timer = nv04_timer_new,
@@ -344,7 +344,7 @@ nv2a_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv04_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv04_mmu_new,
.pci = nv04_pci_new,
.timer = nv04_timer_new,
@@ -366,7 +366,7 @@ nv30_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv04_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv04_mmu_new,
.pci = nv04_pci_new,
.timer = nv04_timer_new,
@@ -388,7 +388,7 @@ nv31_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv04_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv04_mmu_new,
.pci = nv04_pci_new,
.timer = nv04_timer_new,
@@ -411,7 +411,7 @@ nv34_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv04_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv04_mmu_new,
.pci = nv04_pci_new,
.timer = nv04_timer_new,
@@ -434,7 +434,7 @@ nv35_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv04_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv04_mmu_new,
.pci = nv04_pci_new,
.timer = nv04_timer_new,
@@ -456,7 +456,7 @@ nv36_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv04_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv04_mmu_new,
.pci = nv04_pci_new,
.timer = nv04_timer_new,
@@ -479,7 +479,7 @@ nv40_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv40_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv04_mmu_new,
.pci = nv40_pci_new,
.therm = nv40_therm_new,
@@ -505,7 +505,7 @@ nv41_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv40_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv41_mmu_new,
.pci = nv40_pci_new,
.therm = nv40_therm_new,
@@ -531,7 +531,7 @@ nv42_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv40_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv41_mmu_new,
.pci = nv40_pci_new,
.therm = nv40_therm_new,
@@ -557,7 +557,7 @@ nv43_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv40_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv41_mmu_new,
.pci = nv40_pci_new,
.therm = nv40_therm_new,
@@ -609,7 +609,7 @@ nv45_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv40_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv04_mmu_new,
.pci = nv40_pci_new,
.therm = nv40_therm_new,
@@ -661,7 +661,7 @@ nv47_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv40_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv41_mmu_new,
.pci = nv40_pci_new,
.therm = nv40_therm_new,
@@ -687,7 +687,7 @@ nv49_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv40_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv41_mmu_new,
.pci = nv40_pci_new,
.therm = nv40_therm_new,
@@ -739,7 +739,7 @@ nv4b_chipset = {
.gpio = nv10_gpio_new,
.i2c = nv04_i2c_new,
.imem = nv40_instmem_new,
- .mc = nv04_mc_new,
+ .mc = nv17_mc_new,
.mmu = nv41_mmu_new,
.pci = nv40_pci_new,
.therm = nv40_therm_new,
@@ -926,7 +926,7 @@ nv84_chipset = {
.gpio = nv50_gpio_new,
.i2c = nv50_i2c_new,
.imem = nv50_instmem_new,
- .mc = nv50_mc_new,
+ .mc = g84_mc_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.pci = g84_pci_new,
@@ -958,7 +958,7 @@ nv86_chipset = {
.gpio = nv50_gpio_new,
.i2c = nv50_i2c_new,
.imem = nv50_instmem_new,
- .mc = nv50_mc_new,
+ .mc = g84_mc_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.pci = g84_pci_new,
@@ -990,7 +990,7 @@ nv92_chipset = {
.gpio = nv50_gpio_new,
.i2c = nv50_i2c_new,
.imem = nv50_instmem_new,
- .mc = nv50_mc_new,
+ .mc = g84_mc_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.pci = g84_pci_new,
@@ -1022,7 +1022,7 @@ nv94_chipset = {
.gpio = g94_gpio_new,
.i2c = g94_i2c_new,
.imem = nv50_instmem_new,
- .mc = nv50_mc_new,
+ .mc = g84_mc_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
@@ -1054,7 +1054,7 @@ nv96_chipset = {
.gpio = g94_gpio_new,
.i2c = g94_i2c_new,
.imem = nv50_instmem_new,
- .mc = nv50_mc_new,
+ .mc = g84_mc_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
@@ -1118,7 +1118,7 @@ nva0_chipset = {
.gpio = g94_gpio_new,
.i2c = nv50_i2c_new,
.imem = nv50_instmem_new,
- .mc = g98_mc_new,
+ .mc = g84_mc_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
@@ -1150,7 +1150,7 @@ nva3_chipset = {
.gpio = g94_gpio_new,
.i2c = g94_i2c_new,
.imem = nv50_instmem_new,
- .mc = g98_mc_new,
+ .mc = gt215_mc_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
@@ -1184,7 +1184,7 @@ nva5_chipset = {
.gpio = g94_gpio_new,
.i2c = g94_i2c_new,
.imem = nv50_instmem_new,
- .mc = g98_mc_new,
+ .mc = gt215_mc_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
@@ -1217,7 +1217,7 @@ nva8_chipset = {
.gpio = g94_gpio_new,
.i2c = g94_i2c_new,
.imem = nv50_instmem_new,
- .mc = g98_mc_new,
+ .mc = gt215_mc_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
@@ -1314,7 +1314,7 @@ nvaf_chipset = {
.gpio = g94_gpio_new,
.i2c = g94_i2c_new,
.imem = nv50_instmem_new,
- .mc = g98_mc_new,
+ .mc = gt215_mc_new,
.mmu = nv50_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
@@ -1676,13 +1676,14 @@ nve4_chipset = {
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gk104_ltc_new,
- .mc = gf100_mc_new,
+ .mc = gk104_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = gk104_pci_new,
.pmu = gk104_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
+ .top = gk104_top_new,
.volt = gk104_volt_new,
.ce[0] = gk104_ce_new,
.ce[1] = gk104_ce_new,
@@ -1714,13 +1715,14 @@ nve6_chipset = {
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gk104_ltc_new,
- .mc = gf100_mc_new,
+ .mc = gk104_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = gk104_pci_new,
.pmu = gk104_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
+ .top = gk104_top_new,
.volt = gk104_volt_new,
.ce[0] = gk104_ce_new,
.ce[1] = gk104_ce_new,
@@ -1752,13 +1754,14 @@ nve7_chipset = {
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gk104_ltc_new,
- .mc = gf100_mc_new,
+ .mc = gk104_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = gk104_pci_new,
.pmu = gk104_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
+ .top = gk104_top_new,
.volt = gk104_volt_new,
.ce[0] = gk104_ce_new,
.ce[1] = gk104_ce_new,
@@ -1789,6 +1792,7 @@ nvea_chipset = {
.mmu = gf100_mmu_new,
.pmu = gk20a_pmu_new,
.timer = gk20a_timer_new,
+ .top = gk104_top_new,
.volt = gk20a_volt_new,
.ce[2] = gk104_ce_new,
.dma = gf119_dma_new,
@@ -1814,13 +1818,14 @@ nvf0_chipset = {
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gk104_ltc_new,
- .mc = gf100_mc_new,
+ .mc = gk104_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = gk104_pci_new,
.pmu = gk110_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
+ .top = gk104_top_new,
.volt = gk104_volt_new,
.ce[0] = gk104_ce_new,
.ce[1] = gk104_ce_new,
@@ -1851,13 +1856,14 @@ nvf1_chipset = {
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
.ltc = gk104_ltc_new,
- .mc = gf100_mc_new,
+ .mc = gk104_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = gk104_pci_new,
.pmu = gk110_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
+ .top = gk104_top_new,
.volt = gk104_volt_new,
.ce[0] = gk104_ce_new,
.ce[1] = gk104_ce_new,
@@ -1895,6 +1901,7 @@ nv106_chipset = {
.pmu = gk208_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
+ .top = gk104_top_new,
.volt = gk104_volt_new,
.ce[0] = gk104_ce_new,
.ce[1] = gk104_ce_new,
@@ -1932,6 +1939,7 @@ nv108_chipset = {
.pmu = gk208_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
+ .top = gk104_top_new,
.volt = gk104_volt_new,
.ce[0] = gk104_ce_new,
.ce[1] = gk104_ce_new,
@@ -1969,6 +1977,41 @@ nv117_chipset = {
.pmu = gm107_pmu_new,
.therm = gm107_therm_new,
.timer = gk20a_timer_new,
+ .top = gk104_top_new,
+ .volt = gk104_volt_new,
+ .ce[0] = gm107_ce_new,
+ .ce[2] = gm107_ce_new,
+ .disp = gm107_disp_new,
+ .dma = gf119_dma_new,
+ .fifo = gm107_fifo_new,
+ .gr = gm107_gr_new,
+ .sw = gf100_sw_new,
+};
+
+static const struct nvkm_device_chip
+nv118_chipset = {
+ .name = "GM108",
+ .bar = gf100_bar_new,
+ .bios = nvkm_bios_new,
+ .bus = gf100_bus_new,
+ .clk = gk104_clk_new,
+ .devinit = gm107_devinit_new,
+ .fb = gm107_fb_new,
+ .fuse = gm107_fuse_new,
+ .gpio = gk104_gpio_new,
+ .i2c = gf119_i2c_new,
+ .ibus = gk104_ibus_new,
+ .iccsense = gf100_iccsense_new,
+ .imem = nv50_instmem_new,
+ .ltc = gm107_ltc_new,
+ .mc = gk20a_mc_new,
+ .mmu = gf100_mmu_new,
+ .mxm = nv50_mxm_new,
+ .pci = gk104_pci_new,
+ .pmu = gm107_pmu_new,
+ .therm = gm107_therm_new,
+ .timer = gk20a_timer_new,
+ .top = gk104_top_new,
.volt = gk104_volt_new,
.ce[0] = gm107_ce_new,
.ce[2] = gm107_ce_new,
@@ -1986,7 +2029,7 @@ nv120_chipset = {
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
.devinit = gm200_devinit_new,
- .fb = gm107_fb_new,
+ .fb = gm200_fb_new,
.fuse = gm107_fuse_new,
.gpio = gk104_gpio_new,
.i2c = gm200_i2c_new,
@@ -2001,6 +2044,7 @@ nv120_chipset = {
.pmu = gm107_pmu_new,
.secboot = gm200_secboot_new,
.timer = gk20a_timer_new,
+ .top = gk104_top_new,
.volt = gk104_volt_new,
.ce[0] = gm200_ce_new,
.ce[1] = gm200_ce_new,
@@ -2019,7 +2063,7 @@ nv124_chipset = {
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
.devinit = gm200_devinit_new,
- .fb = gm107_fb_new,
+ .fb = gm200_fb_new,
.fuse = gm107_fuse_new,
.gpio = gk104_gpio_new,
.i2c = gm200_i2c_new,
@@ -2034,6 +2078,7 @@ nv124_chipset = {
.pmu = gm107_pmu_new,
.secboot = gm200_secboot_new,
.timer = gk20a_timer_new,
+ .top = gk104_top_new,
.volt = gk104_volt_new,
.ce[0] = gm200_ce_new,
.ce[1] = gm200_ce_new,
@@ -2052,7 +2097,7 @@ nv126_chipset = {
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
.devinit = gm200_devinit_new,
- .fb = gm107_fb_new,
+ .fb = gm200_fb_new,
.fuse = gm107_fuse_new,
.gpio = gk104_gpio_new,
.i2c = gm200_i2c_new,
@@ -2067,6 +2112,7 @@ nv126_chipset = {
.pmu = gm107_pmu_new,
.secboot = gm200_secboot_new,
.timer = gk20a_timer_new,
+ .top = gk104_top_new,
.volt = gk104_volt_new,
.ce[0] = gm200_ce_new,
.ce[1] = gm200_ce_new,
@@ -2093,6 +2139,7 @@ nv12b_chipset = {
.mmu = gf100_mmu_new,
.secboot = gm20b_secboot_new,
.timer = gk20a_timer_new,
+ .top = gk104_top_new,
.ce[2] = gm200_ce_new,
.volt = gm20b_volt_new,
.dma = gf119_dma_new,
@@ -2150,6 +2197,7 @@ nvkm_device_subdev(struct nvkm_device *device, int index)
_(SECBOOT , device->secboot , &device->secboot->subdev);
_(THERM , device->therm , &device->therm->subdev);
_(TIMER , device->timer , &device->timer->subdev);
+ _(TOP , device->top , &device->top->subdev);
_(VOLT , device->volt , &device->volt->subdev);
#undef _
default:
@@ -2523,6 +2571,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
case 0x106: device->chip = &nv106_chipset; break;
case 0x108: device->chip = &nv108_chipset; break;
case 0x117: device->chip = &nv117_chipset; break;
+ case 0x118: device->chip = &nv118_chipset; break;
case 0x120: device->chip = &nv120_chipset; break;
case 0x124: device->chip = &nv124_chipset; break;
case 0x126: device->chip = &nv126_chipset; break;
@@ -2604,6 +2653,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
_(NVKM_SUBDEV_SECBOOT , secboot);
_(NVKM_SUBDEV_THERM , therm);
_(NVKM_SUBDEV_TIMER , timer);
+ _(NVKM_SUBDEV_TOP , top);
_(NVKM_SUBDEV_VOLT , volt);
_(NVKM_ENGINE_BSP , bsp);
_(NVKM_ENGINE_CE0 , ce[0]);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h
index e80f6ab1c415..1a06ac175f55 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/priv.h
@@ -22,6 +22,7 @@
#include <subdev/pmu.h>
#include <subdev/therm.h>
#include <subdev/timer.h>
+#include <subdev/top.h>
#include <subdev/volt.h>
#include <subdev/secboot.h>
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
index 785fa76d0fbf..1efe91b1e22b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
@@ -298,8 +298,7 @@ nvkm_disp_ctor(const struct nvkm_disp_func *func, struct nvkm_device *device,
disp->func = func;
disp->head.nr = heads;
- ret = nvkm_engine_ctor(&nvkm_disp, device, index, 0,
- true, &disp->engine);
+ ret = nvkm_engine_ctor(&nvkm_disp, device, index, true, &disp->engine);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c
index 9769fc0d5351..f11ebdd16c77 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c
@@ -152,6 +152,5 @@ nvkm_dma_new_(const struct nvkm_dma_func *func, struct nvkm_device *device,
return -ENOMEM;
dma->func = func;
- return nvkm_engine_ctor(&nvkm_dma, device, index,
- 0, true, &dma->engine);
+ return nvkm_engine_ctor(&nvkm_dma, device, index, true, &dma->engine);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c b/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c
index 74000602fbb1..2e7b4e2105ef 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c
@@ -348,6 +348,6 @@ nvkm_falcon_new_(const struct nvkm_falcon_func *func,
falcon->data.size = func->data.size;
*pengine = &falcon->engine;
- return nvkm_engine_ctor(&nvkm_falcon, device, index, func->pmc_enable,
+ return nvkm_engine_ctor(&nvkm_falcon, device, index,
enable, &falcon->engine);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
index cfc7d5725a61..1c9682ae3a6b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
@@ -178,6 +178,17 @@ nvkm_fifo_class_get(struct nvkm_oclass *oclass, int index,
const struct nvkm_fifo_chan_oclass *sclass;
int c = 0;
+ if (fifo->func->class_get) {
+ int ret = fifo->func->class_get(fifo, index, &sclass);
+ if (ret == 0) {
+ oclass->base = sclass->base;
+ oclass->engn = sclass;
+ *class = &nvkm_fifo_class;
+ return 0;
+ }
+ return ret;
+ }
+
while ((sclass = fifo->func->chan[c])) {
if (c++ == index) {
oclass->base = sclass->base;
@@ -261,8 +272,7 @@ nvkm_fifo_ctor(const struct nvkm_fifo_func *func, struct nvkm_device *device,
fifo->nr = nr;
bitmap_clear(fifo->mask, 0, fifo->nr);
- ret = nvkm_engine_ctor(&nvkm_fifo, device, index, 0x00000100,
- true, &fifo->engine);
+ ret = nvkm_engine_ctor(&nvkm_fifo, device, index, true, &fifo->engine);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
index 68acb36b3e6d..743f3a189f28 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
@@ -25,21 +25,36 @@
#include "changk104.h"
#include <core/client.h>
-#include <core/enum.h>
#include <core/gpuobj.h>
#include <subdev/bar.h>
+#include <subdev/top.h>
#include <engine/sw.h>
#include <nvif/class.h>
-void
+static int
+gk104_fifo_class_get(struct nvkm_fifo *base, int index,
+ const struct nvkm_fifo_chan_oclass **psclass)
+{
+ struct gk104_fifo *fifo = gk104_fifo(base);
+ int c = 0;
+
+ while ((*psclass = fifo->func->chan[c])) {
+ if (c++ == index)
+ return 0;
+ }
+
+ return c;
+}
+
+static void
gk104_fifo_uevent_fini(struct nvkm_fifo *fifo)
{
struct nvkm_device *device = fifo->engine.subdev.device;
nvkm_mask(device, 0x002140, 0x80000000, 0x00000000);
}
-void
+static void
gk104_fifo_uevent_init(struct nvkm_fifo *fifo)
{
struct nvkm_device *device = fifo->engine.subdev.device;
@@ -267,111 +282,6 @@ gk104_fifo_intr_dropped_fault(struct gk104_fifo *fifo)
nvkm_error(subdev, "DROPPED_MMU_FAULT %08x\n", stat);
}
-static const struct nvkm_enum
-gk104_fifo_fault_engine[] = {
- { 0x00, "GR", NULL, NVKM_ENGINE_GR },
- { 0x03, "IFB", NULL, NVKM_ENGINE_IFB },
- { 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR },
- { 0x05, "BAR3", NULL, NVKM_SUBDEV_INSTMEM },
- { 0x07, "PBDMA0", NULL, NVKM_ENGINE_FIFO },
- { 0x08, "PBDMA1", NULL, NVKM_ENGINE_FIFO },
- { 0x09, "PBDMA2", NULL, NVKM_ENGINE_FIFO },
- { 0x10, "MSVLD", NULL, NVKM_ENGINE_MSVLD },
- { 0x11, "MSPPP", NULL, NVKM_ENGINE_MSPPP },
- { 0x13, "PERF" },
- { 0x14, "MSPDEC", NULL, NVKM_ENGINE_MSPDEC },
- { 0x15, "CE0", NULL, NVKM_ENGINE_CE0 },
- { 0x16, "CE1", NULL, NVKM_ENGINE_CE1 },
- { 0x17, "PMU" },
- { 0x19, "MSENC", NULL, NVKM_ENGINE_MSENC },
- { 0x1b, "CE2", NULL, NVKM_ENGINE_CE2 },
- {}
-};
-
-static const struct nvkm_enum
-gk104_fifo_fault_reason[] = {
- { 0x00, "PDE" },
- { 0x01, "PDE_SIZE" },
- { 0x02, "PTE" },
- { 0x03, "VA_LIMIT_VIOLATION" },
- { 0x04, "UNBOUND_INST_BLOCK" },
- { 0x05, "PRIV_VIOLATION" },
- { 0x06, "RO_VIOLATION" },
- { 0x07, "WO_VIOLATION" },
- { 0x08, "PITCH_MASK_VIOLATION" },
- { 0x09, "WORK_CREATION" },
- { 0x0a, "UNSUPPORTED_APERTURE" },
- { 0x0b, "COMPRESSION_FAILURE" },
- { 0x0c, "UNSUPPORTED_KIND" },
- { 0x0d, "REGION_VIOLATION" },
- { 0x0e, "BOTH_PTES_VALID" },
- { 0x0f, "INFO_TYPE_POISONED" },
- {}
-};
-
-static const struct nvkm_enum
-gk104_fifo_fault_hubclient[] = {
- { 0x00, "VIP" },
- { 0x01, "CE0" },
- { 0x02, "CE1" },
- { 0x03, "DNISO" },
- { 0x04, "FE" },
- { 0x05, "FECS" },
- { 0x06, "HOST" },
- { 0x07, "HOST_CPU" },
- { 0x08, "HOST_CPU_NB" },
- { 0x09, "ISO" },
- { 0x0a, "MMU" },
- { 0x0b, "MSPDEC" },
- { 0x0c, "MSPPP" },
- { 0x0d, "MSVLD" },
- { 0x0e, "NISO" },
- { 0x0f, "P2P" },
- { 0x10, "PD" },
- { 0x11, "PERF" },
- { 0x12, "PMU" },
- { 0x13, "RASTERTWOD" },
- { 0x14, "SCC" },
- { 0x15, "SCC_NB" },
- { 0x16, "SEC" },
- { 0x17, "SSYNC" },
- { 0x18, "GR_CE" },
- { 0x19, "CE2" },
- { 0x1a, "XV" },
- { 0x1b, "MMU_NB" },
- { 0x1c, "MSENC" },
- { 0x1d, "DFALCON" },
- { 0x1e, "SKED" },
- { 0x1f, "AFALCON" },
- {}
-};
-
-static const struct nvkm_enum
-gk104_fifo_fault_gpcclient[] = {
- { 0x00, "L1_0" }, { 0x01, "T1_0" }, { 0x02, "PE_0" },
- { 0x03, "L1_1" }, { 0x04, "T1_1" }, { 0x05, "PE_1" },
- { 0x06, "L1_2" }, { 0x07, "T1_2" }, { 0x08, "PE_2" },
- { 0x09, "L1_3" }, { 0x0a, "T1_3" }, { 0x0b, "PE_3" },
- { 0x0c, "RAST" },
- { 0x0d, "GCC" },
- { 0x0e, "GPCCS" },
- { 0x0f, "PROP_0" },
- { 0x10, "PROP_1" },
- { 0x11, "PROP_2" },
- { 0x12, "PROP_3" },
- { 0x13, "L1_4" }, { 0x14, "T1_4" }, { 0x15, "PE_4" },
- { 0x16, "L1_5" }, { 0x17, "T1_5" }, { 0x18, "PE_5" },
- { 0x19, "L1_6" }, { 0x1a, "T1_6" }, { 0x1b, "PE_6" },
- { 0x1c, "L1_7" }, { 0x1d, "T1_7" }, { 0x1e, "PE_7" },
- { 0x1f, "GPM" },
- { 0x20, "LTP_UTLB_0" },
- { 0x21, "LTP_UTLB_1" },
- { 0x22, "LTP_UTLB_2" },
- { 0x23, "LTP_UTLB_3" },
- { 0x24, "GPC_RGG_UTLB" },
- {}
-};
-
static void
gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit)
{
@@ -390,14 +300,14 @@ gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit)
struct nvkm_engine *engine = NULL;
struct nvkm_fifo_chan *chan;
unsigned long flags;
- char gpcid[8] = "";
+ char gpcid[8] = "", en[16] = "";
- er = nvkm_enum_find(gk104_fifo_fault_reason, reason);
- eu = nvkm_enum_find(gk104_fifo_fault_engine, unit);
+ er = nvkm_enum_find(fifo->func->fault.reason, reason);
+ eu = nvkm_enum_find(fifo->func->fault.engine, unit);
if (hub) {
- ec = nvkm_enum_find(gk104_fifo_fault_hubclient, client);
+ ec = nvkm_enum_find(fifo->func->fault.hubclient, client);
} else {
- ec = nvkm_enum_find(gk104_fifo_fault_gpcclient, client);
+ ec = nvkm_enum_find(fifo->func->fault.gpcclient, client);
snprintf(gpcid, sizeof(gpcid), "GPC%d/", gpc);
}
@@ -418,13 +328,27 @@ gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit)
}
}
+ if (eu == NULL) {
+ enum nvkm_devidx engidx = nvkm_top_fault(device->top, unit);
+ if (engidx < NVKM_SUBDEV_NR) {
+ const char *src = nvkm_subdev_name[engidx];
+ char *dst = en;
+ do {
+ *dst++ = toupper(*src++);
+ } while(*src);
+ engine = nvkm_device_engine(device, engidx);
+ }
+ } else {
+ snprintf(en, sizeof(en), "%s", eu->name);
+ }
+
chan = nvkm_fifo_chan_inst(&fifo->base, (u64)inst << 12, &flags);
nvkm_error(subdev,
"%s fault at %010llx engine %02x [%s] client %02x [%s%s] "
"reason %02x [%s] on channel %d [%010llx %s]\n",
write ? "write" : "read", (u64)vahi << 32 | valo,
- unit, eu ? eu->name : "", client, gpcid, ec ? ec->name : "",
+ unit, en, client, gpcid, ec ? ec->name : "",
reason, er ? er->name : "", chan ? chan->chid : -1,
(u64)inst << 12,
chan ? chan->object.client->name : "unknown");
@@ -557,7 +481,7 @@ gk104_fifo_intr_engine(struct gk104_fifo *fifo)
nvkm_fifo_uevent(&fifo->base);
}
-void
+static void
gk104_fifo_intr(struct nvkm_fifo *base)
{
struct gk104_fifo *fifo = gk104_fifo(base);
@@ -649,7 +573,7 @@ gk104_fifo_intr(struct nvkm_fifo *base)
}
}
-void
+static void
gk104_fifo_fini(struct nvkm_fifo *base)
{
struct gk104_fifo *fifo = gk104_fifo(base);
@@ -659,13 +583,15 @@ gk104_fifo_fini(struct nvkm_fifo *base)
nvkm_mask(device, 0x002140, 0x10000000, 0x10000000);
}
-int
+static int
gk104_fifo_oneinit(struct nvkm_fifo *base)
{
struct gk104_fifo *fifo = gk104_fifo(base);
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
struct nvkm_device *device = subdev->device;
- int ret, i;
+ struct nvkm_top *top = device->top;
+ int engn, runl, pbid, ret, i, j;
+ enum nvkm_devidx engidx;
u32 *map;
/* Determine number of PBDMAs by checking valid enable bits. */
@@ -680,86 +606,26 @@ gk104_fifo_oneinit(struct nvkm_fifo *base)
for (i = 0; i < fifo->pbdma_nr; i++)
map[i] = nvkm_rd32(device, 0x002390 + (i * 0x04));
- /* Read device topology from HW. */
- for (i = 0; i < 64; i++) {
- int type = -1, pbid = -1, engidx = -1;
- int engn = -1, runl = -1, intr = -1, mcen = -1;
- int fault = -1, j;
- u32 data, addr = 0;
-
- do {
- data = nvkm_rd32(device, 0x022700 + (i * 0x04));
- nvkm_trace(subdev, "%02x: %08x\n", i, data);
- switch (data & 0x00000003) {
- case 0x00000000: /* NOT_VALID */
- continue;
- case 0x00000001: /* DATA */
- addr = (data & 0x00fff000);
- fault = (data & 0x000000f8) >> 3;
- break;
- case 0x00000002: /* ENUM */
- if (data & 0x00000020)
- engn = (data & 0x3c000000) >> 26;
- if (data & 0x00000010)
- runl = (data & 0x01e00000) >> 21;
- if (data & 0x00000008)
- intr = (data & 0x000f8000) >> 15;
- if (data & 0x00000004)
- mcen = (data & 0x00003e00) >> 9;
- break;
- case 0x00000003: /* ENGINE_TYPE */
- type = (data & 0x7ffffffc) >> 2;
- break;
- }
- } while ((data & 0x80000000) && ++i < 64);
-
- if (!data)
- continue;
-
+ /* Determine runlist configuration from topology device info. */
+ i = 0;
+ while ((int)(engidx = nvkm_top_engine(top, i++, &runl, &engn)) >= 0) {
/* Determine which PBDMA handles requests for this engine. */
- for (j = 0; runl >= 0 && j < fifo->pbdma_nr; j++) {
+ for (j = 0, pbid = -1; j < fifo->pbdma_nr; j++) {
if (map[j] & (1 << runl)) {
pbid = j;
break;
}
}
- /* Translate engine type to NVKM engine identifier. */
- switch (type) {
- case 0x00000000: engidx = NVKM_ENGINE_GR; break;
- case 0x00000001: engidx = NVKM_ENGINE_CE0; break;
- case 0x00000002: engidx = NVKM_ENGINE_CE1; break;
- case 0x00000003: engidx = NVKM_ENGINE_CE2; break;
- case 0x00000008: engidx = NVKM_ENGINE_MSPDEC; break;
- case 0x00000009: engidx = NVKM_ENGINE_MSPPP; break;
- case 0x0000000a: engidx = NVKM_ENGINE_MSVLD; break;
- case 0x0000000b: engidx = NVKM_ENGINE_MSENC; break;
- case 0x0000000c: engidx = NVKM_ENGINE_VIC; break;
- case 0x0000000d: engidx = NVKM_ENGINE_SEC; break;
- case 0x0000000e: engidx = NVKM_ENGINE_NVENC0; break;
- case 0x0000000f: engidx = NVKM_ENGINE_NVENC1; break;
- case 0x00000010: engidx = NVKM_ENGINE_NVDEC; break;
- break;
- default:
- break;
- }
+ nvkm_debug(subdev, "engine %2d: runlist %2d pbdma %2d\n",
+ engn, runl, pbid);
- nvkm_debug(subdev, "%02x (%8s): engine %2d runlist %2d "
- "pbdma %2d intr %2d reset %2d "
- "fault %2d addr %06x\n", type,
- engidx < 0 ? NULL : nvkm_subdev_name[engidx],
- engn, runl, pbid, intr, mcen, fault, addr);
-
- /* Mark the engine as supported if everything checks out. */
- if (engn >= 0 && runl >= 0) {
- fifo->engine[engn].engine = engidx < 0 ? NULL :
- nvkm_device_engine(device, engidx);
- fifo->engine[engn].runl = runl;
- fifo->engine[engn].pbid = pbid;
- fifo->engine_nr = max(fifo->engine_nr, engn + 1);
- fifo->runlist[runl].engm |= 1 << engn;
- fifo->runlist_nr = max(fifo->runlist_nr, runl + 1);
- }
+ fifo->engine[engn].engine = nvkm_device_engine(device, engidx);
+ fifo->engine[engn].runl = runl;
+ fifo->engine[engn].pbid = pbid;
+ fifo->engine_nr = max(fifo->engine_nr, engn + 1);
+ fifo->runlist[runl].engm |= 1 << engn;
+ fifo->runlist_nr = max(fifo->runlist_nr, runl + 1);
}
kfree(map);
@@ -796,7 +662,7 @@ gk104_fifo_oneinit(struct nvkm_fifo *base)
return 0;
}
-void
+static void
gk104_fifo_init(struct nvkm_fifo *base)
{
struct gk104_fifo *fifo = gk104_fifo(base);
@@ -825,7 +691,7 @@ gk104_fifo_init(struct nvkm_fifo *base)
nvkm_wr32(device, 0x002140, 0x7fffffff);
}
-void *
+static void *
gk104_fifo_dtor(struct nvkm_fifo *base)
{
struct gk104_fifo *fifo = gk104_fifo(base);
@@ -842,29 +708,154 @@ gk104_fifo_dtor(struct nvkm_fifo *base)
return fifo;
}
+static const struct nvkm_fifo_func
+gk104_fifo_ = {
+ .dtor = gk104_fifo_dtor,
+ .oneinit = gk104_fifo_oneinit,
+ .init = gk104_fifo_init,
+ .fini = gk104_fifo_fini,
+ .intr = gk104_fifo_intr,
+ .uevent_init = gk104_fifo_uevent_init,
+ .uevent_fini = gk104_fifo_uevent_fini,
+ .class_get = gk104_fifo_class_get,
+};
+
int
-gk104_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device,
+gk104_fifo_new_(const struct gk104_fifo_func *func, struct nvkm_device *device,
int index, int nr, struct nvkm_fifo **pfifo)
{
struct gk104_fifo *fifo;
if (!(fifo = kzalloc(sizeof(*fifo), GFP_KERNEL)))
return -ENOMEM;
+ fifo->func = func;
INIT_WORK(&fifo->recover.work, gk104_fifo_recover_work);
*pfifo = &fifo->base;
- return nvkm_fifo_ctor(func, device, index, nr, &fifo->base);
+ return nvkm_fifo_ctor(&gk104_fifo_, device, index, nr, &fifo->base);
}
-static const struct nvkm_fifo_func
+const struct nvkm_enum
+gk104_fifo_fault_engine[] = {
+ { 0x00, "GR", NULL, NVKM_ENGINE_GR },
+ { 0x01, "DISPLAY" },
+ { 0x02, "CAPTURE" },
+ { 0x03, "IFB", NULL, NVKM_ENGINE_IFB },
+ { 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR },
+ { 0x05, "BAR2", NULL, NVKM_SUBDEV_INSTMEM },
+ { 0x06, "SCHED" },
+ { 0x07, "HOST0" },
+ { 0x08, "HOST1" },
+ { 0x09, "HOST2" },
+ { 0x0a, "HOST3" },
+ { 0x0b, "HOST4" },
+ { 0x0c, "HOST5" },
+ { 0x0d, "HOST6" },
+ { 0x0e, "HOST7" },
+ { 0x0f, "HOSTSR" },
+ { 0x10, "MSVLD", NULL, NVKM_ENGINE_MSVLD },
+ { 0x11, "MSPPP", NULL, NVKM_ENGINE_MSPPP },
+ { 0x13, "PERF" },
+ { 0x14, "MSPDEC", NULL, NVKM_ENGINE_MSPDEC },
+ { 0x15, "CE0", NULL, NVKM_ENGINE_CE0 },
+ { 0x16, "CE1", NULL, NVKM_ENGINE_CE1 },
+ { 0x17, "PMU" },
+ { 0x18, "PTP" },
+ { 0x19, "MSENC", NULL, NVKM_ENGINE_MSENC },
+ { 0x1b, "CE2", NULL, NVKM_ENGINE_CE2 },
+ {}
+};
+
+const struct nvkm_enum
+gk104_fifo_fault_reason[] = {
+ { 0x00, "PDE" },
+ { 0x01, "PDE_SIZE" },
+ { 0x02, "PTE" },
+ { 0x03, "VA_LIMIT_VIOLATION" },
+ { 0x04, "UNBOUND_INST_BLOCK" },
+ { 0x05, "PRIV_VIOLATION" },
+ { 0x06, "RO_VIOLATION" },
+ { 0x07, "WO_VIOLATION" },
+ { 0x08, "PITCH_MASK_VIOLATION" },
+ { 0x09, "WORK_CREATION" },
+ { 0x0a, "UNSUPPORTED_APERTURE" },
+ { 0x0b, "COMPRESSION_FAILURE" },
+ { 0x0c, "UNSUPPORTED_KIND" },
+ { 0x0d, "REGION_VIOLATION" },
+ { 0x0e, "BOTH_PTES_VALID" },
+ { 0x0f, "INFO_TYPE_POISONED" },
+ {}
+};
+
+const struct nvkm_enum
+gk104_fifo_fault_hubclient[] = {
+ { 0x00, "VIP" },
+ { 0x01, "CE0" },
+ { 0x02, "CE1" },
+ { 0x03, "DNISO" },
+ { 0x04, "FE" },
+ { 0x05, "FECS" },
+ { 0x06, "HOST" },
+ { 0x07, "HOST_CPU" },
+ { 0x08, "HOST_CPU_NB" },
+ { 0x09, "ISO" },
+ { 0x0a, "MMU" },
+ { 0x0b, "MSPDEC" },
+ { 0x0c, "MSPPP" },
+ { 0x0d, "MSVLD" },
+ { 0x0e, "NISO" },
+ { 0x0f, "P2P" },
+ { 0x10, "PD" },
+ { 0x11, "PERF" },
+ { 0x12, "PMU" },
+ { 0x13, "RASTERTWOD" },
+ { 0x14, "SCC" },
+ { 0x15, "SCC_NB" },
+ { 0x16, "SEC" },
+ { 0x17, "SSYNC" },
+ { 0x18, "GR_CE" },
+ { 0x19, "CE2" },
+ { 0x1a, "XV" },
+ { 0x1b, "MMU_NB" },
+ { 0x1c, "MSENC" },
+ { 0x1d, "DFALCON" },
+ { 0x1e, "SKED" },
+ { 0x1f, "AFALCON" },
+ {}
+};
+
+const struct nvkm_enum
+gk104_fifo_fault_gpcclient[] = {
+ { 0x00, "L1_0" }, { 0x01, "T1_0" }, { 0x02, "PE_0" },
+ { 0x03, "L1_1" }, { 0x04, "T1_1" }, { 0x05, "PE_1" },
+ { 0x06, "L1_2" }, { 0x07, "T1_2" }, { 0x08, "PE_2" },
+ { 0x09, "L1_3" }, { 0x0a, "T1_3" }, { 0x0b, "PE_3" },
+ { 0x0c, "RAST" },
+ { 0x0d, "GCC" },
+ { 0x0e, "GPCCS" },
+ { 0x0f, "PROP_0" },
+ { 0x10, "PROP_1" },
+ { 0x11, "PROP_2" },
+ { 0x12, "PROP_3" },
+ { 0x13, "L1_4" }, { 0x14, "T1_4" }, { 0x15, "PE_4" },
+ { 0x16, "L1_5" }, { 0x17, "T1_5" }, { 0x18, "PE_5" },
+ { 0x19, "L1_6" }, { 0x1a, "T1_6" }, { 0x1b, "PE_6" },
+ { 0x1c, "L1_7" }, { 0x1d, "T1_7" }, { 0x1e, "PE_7" },
+ { 0x1f, "GPM" },
+ { 0x20, "LTP_UTLB_0" },
+ { 0x21, "LTP_UTLB_1" },
+ { 0x22, "LTP_UTLB_2" },
+ { 0x23, "LTP_UTLB_3" },
+ { 0x24, "GPC_RGG_UTLB" },
+ {}
+};
+
+static const struct gk104_fifo_func
gk104_fifo = {
- .dtor = gk104_fifo_dtor,
- .oneinit = gk104_fifo_oneinit,
- .init = gk104_fifo_init,
- .fini = gk104_fifo_fini,
- .intr = gk104_fifo_intr,
- .uevent_init = gk104_fifo_uevent_init,
- .uevent_fini = gk104_fifo_uevent_fini,
+ .fault.engine = gk104_fifo_fault_engine,
+ .fault.reason = gk104_fifo_fault_reason,
+ .fault.hubclient = gk104_fifo_fault_hubclient,
+ .fault.gpcclient = gk104_fifo_fault_gpcclient,
.chan = {
&gk104_fifo_gpfifo_oclass,
NULL
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h
index 9e5d00ba34a2..679f3ec311e9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h
@@ -3,10 +3,12 @@
#define gk104_fifo(p) container_of((p), struct gk104_fifo, base)
#include "priv.h"
+#include <core/enum.h>
#include <subdev/mmu.h>
struct gk104_fifo_chan;
struct gk104_fifo {
+ const struct gk104_fifo_func *func;
struct nvkm_fifo base;
struct {
@@ -39,15 +41,19 @@ struct gk104_fifo {
} user;
};
-int gk104_fifo_new_(const struct nvkm_fifo_func *, struct nvkm_device *,
+struct gk104_fifo_func {
+ struct {
+ const struct nvkm_enum *engine;
+ const struct nvkm_enum *reason;
+ const struct nvkm_enum *hubclient;
+ const struct nvkm_enum *gpcclient;
+ } fault;
+
+ const struct nvkm_fifo_chan_oclass *chan[];
+};
+
+int gk104_fifo_new_(const struct gk104_fifo_func *, struct nvkm_device *,
int index, int nr, struct nvkm_fifo **);
-void *gk104_fifo_dtor(struct nvkm_fifo *);
-int gk104_fifo_oneinit(struct nvkm_fifo *);
-void gk104_fifo_init(struct nvkm_fifo *);
-void gk104_fifo_fini(struct nvkm_fifo *);
-void gk104_fifo_intr(struct nvkm_fifo *);
-void gk104_fifo_uevent_init(struct nvkm_fifo *);
-void gk104_fifo_uevent_fini(struct nvkm_fifo *);
void gk104_fifo_runlist_insert(struct gk104_fifo *, struct gk104_fifo_chan *);
void gk104_fifo_runlist_remove(struct gk104_fifo *, struct gk104_fifo_chan *);
void gk104_fifo_runlist_commit(struct gk104_fifo *, int runl);
@@ -70,4 +76,11 @@ gk104_fifo_engine_subdev(int engine)
return 0;
}
}
+
+extern const struct nvkm_enum gk104_fifo_fault_engine[];
+extern const struct nvkm_enum gk104_fifo_fault_reason[];
+extern const struct nvkm_enum gk104_fifo_fault_hubclient[];
+extern const struct nvkm_enum gk104_fifo_fault_gpcclient[];
+
+extern const struct nvkm_enum gm107_fifo_fault_engine[];
#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c
index 41307fcd4bb3..b2f8ab7bf847 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c
@@ -24,15 +24,12 @@
#include "gk104.h"
#include "changk104.h"
-static const struct nvkm_fifo_func
+static const struct gk104_fifo_func
gk110_fifo = {
- .dtor = gk104_fifo_dtor,
- .oneinit = gk104_fifo_oneinit,
- .init = gk104_fifo_init,
- .fini = gk104_fifo_fini,
- .intr = gk104_fifo_intr,
- .uevent_init = gk104_fifo_uevent_init,
- .uevent_fini = gk104_fifo_uevent_fini,
+ .fault.engine = gk104_fifo_fault_engine,
+ .fault.reason = gk104_fifo_fault_reason,
+ .fault.hubclient = gk104_fifo_fault_hubclient,
+ .fault.gpcclient = gk104_fifo_fault_gpcclient,
.chan = {
&gk110_fifo_gpfifo_oclass,
NULL
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c
index ce01c1a7d41c..160617d376e4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c
@@ -24,15 +24,12 @@
#include "gk104.h"
#include "changk104.h"
-static const struct nvkm_fifo_func
+static const struct gk104_fifo_func
gk208_fifo = {
- .dtor = gk104_fifo_dtor,
- .oneinit = gk104_fifo_oneinit,
- .init = gk104_fifo_init,
- .fini = gk104_fifo_fini,
- .intr = gk104_fifo_intr,
- .uevent_init = gk104_fifo_uevent_init,
- .uevent_fini = gk104_fifo_uevent_fini,
+ .fault.engine = gk104_fifo_fault_engine,
+ .fault.reason = gk104_fifo_fault_reason,
+ .fault.hubclient = gk104_fifo_fault_hubclient,
+ .fault.gpcclient = gk104_fifo_fault_gpcclient,
.chan = {
&gk104_fifo_gpfifo_oclass,
NULL
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c
index b47fe98f4181..be9f5c16ed7d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c
@@ -22,15 +22,12 @@
#include "gk104.h"
#include "changk104.h"
-static const struct nvkm_fifo_func
+static const struct gk104_fifo_func
gk20a_fifo = {
- .dtor = gk104_fifo_dtor,
- .oneinit = gk104_fifo_oneinit,
- .init = gk104_fifo_init,
- .fini = gk104_fifo_fini,
- .intr = gk104_fifo_intr,
- .uevent_init = gk104_fifo_uevent_init,
- .uevent_fini = gk104_fifo_uevent_fini,
+ .fault.engine = gk104_fifo_fault_engine,
+ .fault.reason = gk104_fifo_fault_reason,
+ .fault.hubclient = gk104_fifo_fault_hubclient,
+ .fault.gpcclient = gk104_fifo_fault_gpcclient,
.chan = {
&gk104_fifo_gpfifo_oclass,
NULL
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c
index 6d59d65794a1..bd1ff877aa06 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c
@@ -24,15 +24,35 @@
#include "gk104.h"
#include "changk104.h"
-static const struct nvkm_fifo_func
+const struct nvkm_enum
+gm107_fifo_fault_engine[] = {
+ { 0x01, "DISPLAY" },
+ { 0x02, "CAPTURE" },
+ { 0x03, "IFB", NULL, NVKM_ENGINE_IFB },
+ { 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR },
+ { 0x05, "BAR2", NULL, NVKM_SUBDEV_INSTMEM },
+ { 0x06, "SCHED" },
+ { 0x07, "HOST0" },
+ { 0x08, "HOST1" },
+ { 0x09, "HOST2" },
+ { 0x0a, "HOST3" },
+ { 0x0b, "HOST4" },
+ { 0x0c, "HOST5" },
+ { 0x0d, "HOST6" },
+ { 0x0e, "HOST7" },
+ { 0x0f, "HOSTSR" },
+ { 0x13, "PERF" },
+ { 0x17, "PMU" },
+ { 0x18, "PTP" },
+ {}
+};
+
+static const struct gk104_fifo_func
gm107_fifo = {
- .dtor = gk104_fifo_dtor,
- .oneinit = gk104_fifo_oneinit,
- .init = gk104_fifo_init,
- .fini = gk104_fifo_fini,
- .intr = gk104_fifo_intr,
- .uevent_init = gk104_fifo_uevent_init,
- .uevent_fini = gk104_fifo_uevent_fini,
+ .fault.engine = gm107_fifo_fault_engine,
+ .fault.reason = gk104_fifo_fault_reason,
+ .fault.hubclient = gk104_fifo_fault_hubclient,
+ .fault.gpcclient = gk104_fifo_fault_gpcclient,
.chan = {
&gk110_fifo_gpfifo_oclass,
NULL
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c
index 4bdd43078df9..b069f785c5d8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c
@@ -24,15 +24,12 @@
#include "gk104.h"
#include "changk104.h"
-static const struct nvkm_fifo_func
+static const struct gk104_fifo_func
gm200_fifo = {
- .dtor = gk104_fifo_dtor,
- .oneinit = gk104_fifo_oneinit,
- .init = gk104_fifo_init,
- .fini = gk104_fifo_fini,
- .intr = gk104_fifo_intr,
- .uevent_init = gk104_fifo_uevent_init,
- .uevent_fini = gk104_fifo_uevent_fini,
+ .fault.engine = gm107_fifo_fault_engine,
+ .fault.reason = gk104_fifo_fault_reason,
+ .fault.hubclient = gk104_fifo_fault_hubclient,
+ .fault.gpcclient = gk104_fifo_fault_gpcclient,
.chan = {
&gm200_fifo_gpfifo_oclass,
NULL
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c
index 4c91d4aa1e9e..2ed87c2e8299 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm20b.c
@@ -22,15 +22,12 @@
#include "gk104.h"
#include "changk104.h"
-static const struct nvkm_fifo_func
+static const struct gk104_fifo_func
gm20b_fifo = {
- .dtor = gk104_fifo_dtor,
- .oneinit = gk104_fifo_oneinit,
- .init = gk104_fifo_init,
- .fini = gk104_fifo_fini,
- .intr = gk104_fifo_intr,
- .uevent_init = gk104_fifo_uevent_init,
- .uevent_fini = gk104_fifo_uevent_fini,
+ .fault.engine = gm107_fifo_fault_engine,
+ .fault.reason = gk104_fifo_fault_reason,
+ .fault.hubclient = gk104_fifo_fault_hubclient,
+ .fault.gpcclient = gk104_fifo_fault_gpcclient,
.chan = {
&gm200_fifo_gpfifo_oclass,
NULL
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
index cb1432e9be08..f6dfb37d9429 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
@@ -7,6 +7,7 @@ int nvkm_fifo_ctor(const struct nvkm_fifo_func *, struct nvkm_device *,
int index, int nr, struct nvkm_fifo *);
void nvkm_fifo_uevent(struct nvkm_fifo *);
+struct nvkm_fifo_chan_oclass;
struct nvkm_fifo_func {
void *(*dtor)(struct nvkm_fifo *);
int (*oneinit)(struct nvkm_fifo *);
@@ -17,6 +18,8 @@ struct nvkm_fifo_func {
void (*start)(struct nvkm_fifo *, unsigned long *);
void (*uevent_init)(struct nvkm_fifo *);
void (*uevent_fini)(struct nvkm_fifo *);
+ int (*class_get)(struct nvkm_fifo *, int index,
+ const struct nvkm_fifo_chan_oclass **);
const struct nvkm_fifo_chan_oclass *chan[];
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c
index 090765ff070d..467065d1b4e6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c
@@ -128,9 +128,8 @@ nvkm_gr = {
int
nvkm_gr_ctor(const struct nvkm_gr_func *func, struct nvkm_device *device,
- int index, u32 pmc_enable, bool enable, struct nvkm_gr *gr)
+ int index, bool enable, struct nvkm_gr *gr)
{
gr->func = func;
- return nvkm_engine_ctor(&nvkm_gr, device, index, pmc_enable,
- enable, &gr->engine);
+ return nvkm_engine_ctor(&nvkm_gr, device, index, enable, &gr->engine);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c
index 56f392d3d4fd..b02d8f50ea6a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.c
@@ -1181,20 +1181,20 @@ gf100_grctx_generate_r418bb8(struct gf100_gr *gr)
/* GPC_BROADCAST */
nvkm_wr32(device, 0x418bb8, (gr->tpc_total << 8) |
- gr->magic_not_rop_nr);
+ gr->screen_tile_row_offset);
for (i = 0; i < 6; i++)
nvkm_wr32(device, 0x418b08 + (i * 4), data[i]);
/* GPC_BROADCAST.TP_BROADCAST */
nvkm_wr32(device, 0x419bd0, (gr->tpc_total << 8) |
- gr->magic_not_rop_nr | data2[0]);
+ gr->screen_tile_row_offset | data2[0]);
nvkm_wr32(device, 0x419be4, data2[1]);
for (i = 0; i < 6; i++)
nvkm_wr32(device, 0x419b00 + (i * 4), data[i]);
/* UNK78xx */
nvkm_wr32(device, 0x4078bc, (gr->tpc_total << 8) |
- gr->magic_not_rop_nr);
+ gr->screen_tile_row_offset);
for (i = 0; i < 6; i++)
nvkm_wr32(device, 0x40780c + (i * 4), data[i]);
}
@@ -1238,6 +1238,7 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
const struct gf100_grctx_func *grctx = gr->func->grctx;
+ u32 idle_timeout;
nvkm_mc_unk260(device->mc, 0);
@@ -1247,7 +1248,7 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
gf100_gr_mmio(gr, grctx->tpc);
gf100_gr_mmio(gr, grctx->ppc);
- nvkm_wr32(device, 0x404154, 0x00000000);
+ idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000);
grctx->bundle(info);
grctx->pagepool(info);
@@ -1261,7 +1262,7 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
gf100_grctx_generate_r406800(gr);
gf100_gr_icmd(gr, grctx->icmd);
- nvkm_wr32(device, 0x404154, 0x00000400);
+ nvkm_wr32(device, 0x404154, idle_timeout);
gf100_gr_mthd(gr, grctx->mthd);
nvkm_mc_unk260(device->mc, 1);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h
index 3c8673958f22..ac895edce164 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf100.h
@@ -81,8 +81,6 @@ void gk104_grctx_generate_bundle(struct gf100_grctx *);
void gk104_grctx_generate_pagepool(struct gf100_grctx *);
void gk104_grctx_generate_unkn(struct gf100_gr *);
void gk104_grctx_generate_r418bb8(struct gf100_gr *);
-void gk104_grctx_generate_rop_active_fbps(struct gf100_gr *);
-
void gm107_grctx_generate_bundle(struct gf100_grctx *);
void gm107_grctx_generate_pagepool(struct gf100_grctx *);
@@ -98,7 +96,6 @@ void gm107_grctx_generate_pagepool(struct gf100_grctx *);
void gm107_grctx_generate_attrib(struct gf100_grctx *);
extern const struct gf100_grctx_func gm200_grctx;
-void gm200_grctx_generate_main(struct gf100_gr *, struct gf100_grctx *);
void gm200_grctx_generate_tpcid(struct gf100_gr *);
void gm200_grctx_generate_405b60(struct gf100_gr *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c
index 74de7a96c22a..f521de11a299 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c
@@ -223,6 +223,7 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
const struct gf100_grctx_func *grctx = gr->func->grctx;
+ u32 idle_timeout;
int i;
nvkm_mc_unk260(device->mc, 0);
@@ -233,7 +234,7 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
gf100_gr_mmio(gr, grctx->tpc);
gf100_gr_mmio(gr, grctx->ppc);
- nvkm_wr32(device, 0x404154, 0x00000000);
+ idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000);
grctx->bundle(info);
grctx->pagepool(info);
@@ -250,7 +251,7 @@ gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000);
gf100_gr_icmd(gr, grctx->icmd);
- nvkm_wr32(device, 0x404154, 0x00000400);
+ nvkm_wr32(device, 0x404154, idle_timeout);
gf100_gr_mthd(gr, grctx->mthd);
nvkm_mc_unk260(device->mc, 1);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c
index a843e3689c3c..9ba337778ef5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk104.c
@@ -924,38 +924,30 @@ gk104_grctx_generate_r418bb8(struct gf100_gr *gr)
/* GPC_BROADCAST */
nvkm_wr32(device, 0x418bb8, (gr->tpc_total << 8) |
- gr->magic_not_rop_nr);
+ gr->screen_tile_row_offset);
for (i = 0; i < 6; i++)
nvkm_wr32(device, 0x418b08 + (i * 4), data[i]);
/* GPC_BROADCAST.TP_BROADCAST */
nvkm_wr32(device, 0x41bfd0, (gr->tpc_total << 8) |
- gr->magic_not_rop_nr | data2[0]);
+ gr->screen_tile_row_offset | data2[0]);
nvkm_wr32(device, 0x41bfe4, data2[1]);
for (i = 0; i < 6; i++)
nvkm_wr32(device, 0x41bf00 + (i * 4), data[i]);
/* UNK78xx */
nvkm_wr32(device, 0x4078bc, (gr->tpc_total << 8) |
- gr->magic_not_rop_nr);
+ gr->screen_tile_row_offset);
for (i = 0; i < 6; i++)
nvkm_wr32(device, 0x40780c + (i * 4), data[i]);
}
void
-gk104_grctx_generate_rop_active_fbps(struct gf100_gr *gr)
-{
- struct nvkm_device *device = gr->base.engine.subdev.device;
- const u32 fbp_count = nvkm_rd32(device, 0x120074);
- nvkm_mask(device, 0x408850, 0x0000000f, fbp_count); /* zrop */
- nvkm_mask(device, 0x408958, 0x0000000f, fbp_count); /* crop */
-}
-
-void
gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
const struct gf100_grctx_func *grctx = gr->func->grctx;
+ u32 idle_timeout;
int i;
nvkm_mc_unk260(device->mc, 0);
@@ -966,7 +958,7 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
gf100_gr_mmio(gr, grctx->tpc);
gf100_gr_mmio(gr, grctx->ppc);
- nvkm_wr32(device, 0x404154, 0x00000000);
+ idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000);
grctx->bundle(info);
grctx->pagepool(info);
@@ -982,11 +974,10 @@ gk104_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000);
nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr);
- gk104_grctx_generate_rop_active_fbps(gr);
nvkm_mask(device, 0x419f78, 0x00000001, 0x00000000);
gf100_gr_icmd(gr, grctx->icmd);
- nvkm_wr32(device, 0x404154, 0x00000400);
+ nvkm_wr32(device, 0x404154, idle_timeout);
gf100_gr_mthd(gr, grctx->mthd);
nvkm_mc_unk260(device->mc, 1);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c
index ad0a6cfe7580..da7c35a6a3d2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgk20a.c
@@ -29,15 +29,14 @@ gk20a_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
const struct gf100_grctx_func *grctx = gr->func->grctx;
- int idle_timeout_save;
+ u32 idle_timeout;
int i;
gf100_gr_mmio(gr, gr->fuc_sw_ctx);
gf100_gr_wait_idle(gr);
- idle_timeout_save = nvkm_rd32(device, 0x404154);
- nvkm_wr32(device, 0x404154, 0x00000000);
+ idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000);
grctx->attrib(info);
@@ -53,13 +52,11 @@ gk20a_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr);
- gk104_grctx_generate_rop_active_fbps(gr);
-
nvkm_mask(device, 0x5044b0, 0x08000000, 0x08000000);
gf100_gr_wait_idle(gr);
- nvkm_wr32(device, 0x404154, idle_timeout_save);
+ nvkm_wr32(device, 0x404154, idle_timeout);
gf100_gr_wait_idle(gr);
gf100_gr_mthd(gr, gr->fuc_method);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c
index 95f59e3169f2..6d3c5011e18c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c
@@ -920,13 +920,15 @@ gm107_grctx_generate_attrib(struct gf100_grctx *info)
const u32 bs = attrib * gr->ppc_tpc_nr[gpc][ppc];
const u32 u = 0x418ea0 + (n * 0x04);
const u32 o = PPC_UNIT(gpc, ppc, 0);
+ if (!(gr->ppc_mask[gpc] & (1 << ppc)))
+ continue;
mmio_wr32(info, o + 0xc0, bs);
mmio_wr32(info, o + 0xf4, bo);
bo += grctx->attrib_nr_max * gr->ppc_tpc_nr[gpc][ppc];
mmio_wr32(info, o + 0xe4, as);
mmio_wr32(info, o + 0xf8, ao);
ao += grctx->alpha_nr_max * gr->ppc_tpc_nr[gpc][ppc];
- mmio_wr32(info, u, ((bs / 3 /*XXX*/) << 16) | bs);
+ mmio_wr32(info, u, ((bs / 3) << 16) | bs);
}
}
}
@@ -957,6 +959,7 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
const struct gf100_grctx_func *grctx = gr->func->grctx;
+ u32 idle_timeout;
int i;
gf100_gr_mmio(gr, grctx->hub);
@@ -965,7 +968,7 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
gf100_gr_mmio(gr, grctx->tpc);
gf100_gr_mmio(gr, grctx->ppc);
- nvkm_wr32(device, 0x404154, 0x00000000);
+ idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000);
grctx->bundle(info);
grctx->pagepool(info);
@@ -984,10 +987,8 @@ gm107_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr);
- gk104_grctx_generate_rop_active_fbps(gr);
-
gf100_gr_icmd(gr, grctx->icmd);
- nvkm_wr32(device, 0x404154, 0x00000400);
+ nvkm_wr32(device, 0x404154, idle_timeout);
gf100_gr_mthd(gr, grctx->mthd);
nvkm_mask(device, 0x419e00, 0x00808080, 0x00808080);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c
index e586699fc43f..db209d33f486 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm200.c
@@ -33,7 +33,7 @@ gm200_grctx_generate_tpcid(struct gf100_gr *gr)
struct nvkm_device *device = gr->base.engine.subdev.device;
int gpc, tpc, id;
- for (tpc = 0, id = 0; tpc < 4; tpc++) {
+ for (tpc = 0, id = 0; tpc < TPC_MAX_PER_GPC; tpc++) {
for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
if (tpc < gr->tpc_nr[gpc]) {
nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x698), id);
@@ -45,15 +45,6 @@ gm200_grctx_generate_tpcid(struct gf100_gr *gr)
}
}
-static void
-gm200_grctx_generate_rop_active_fbps(struct gf100_gr *gr)
-{
- struct nvkm_device *device = gr->base.engine.subdev.device;
- const u32 fbp_count = nvkm_rd32(device, 0x12006c);
- nvkm_mask(device, 0x408850, 0x0000000f, fbp_count); /* zrop */
- nvkm_mask(device, 0x408958, 0x0000000f, fbp_count); /* crop */
-}
-
void
gm200_grctx_generate_405b60(struct gf100_gr *gr)
{
@@ -86,17 +77,17 @@ gm200_grctx_generate_405b60(struct gf100_gr *gr)
nvkm_wr32(device, 0x405ba0 + (i * 4), gpcs[i]);
}
-void
+static void
gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
const struct gf100_grctx_func *grctx = gr->func->grctx;
- u32 tmp;
+ u32 idle_timeout, tmp;
int i;
gf100_gr_mmio(gr, gr->fuc_sw_ctx);
- nvkm_wr32(device, 0x404154, 0x00000000);
+ idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000);
grctx->bundle(info);
grctx->pagepool(info);
@@ -113,8 +104,6 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr);
- gm200_grctx_generate_rop_active_fbps(gr);
-
for (tmp = 0, i = 0; i < gr->gpc_nr; i++)
tmp |= ((1 << gr->tpc_nr[i]) - 1) << (i * 4);
nvkm_wr32(device, 0x4041c4, tmp);
@@ -122,7 +111,7 @@ gm200_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
gm200_grctx_generate_405b60(gr);
gf100_gr_icmd(gr, gr->fuc_bundle);
- nvkm_wr32(device, 0x404154, 0x00000800);
+ nvkm_wr32(device, 0x404154, idle_timeout);
gf100_gr_mthd(gr, gr->fuc_method);
nvkm_mask(device, 0x418e94, 0xffffffff, 0xc4230000);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c
index a8827efa90ae..e5702e3e0a5a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm20b.c
@@ -40,15 +40,14 @@ gm20b_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
const struct gf100_grctx_func *grctx = gr->func->grctx;
- int idle_timeout_save;
+ u32 idle_timeout;
int i, tmp;
gf100_gr_mmio(gr, gr->fuc_sw_ctx);
gf100_gr_wait_idle(gr);
- idle_timeout_save = nvkm_rd32(device, 0x404154);
- nvkm_wr32(device, 0x404154, 0x00000000);
+ idle_timeout = nvkm_mask(device, 0x404154, 0xffffffff, 0x00000000);
grctx->attrib(info);
@@ -63,7 +62,6 @@ gm20b_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
nvkm_wr32(device, 0x405b00, (gr->tpc_total << 8) | gr->gpc_nr);
- gk104_grctx_generate_rop_active_fbps(gr);
nvkm_wr32(device, 0x408908, nvkm_rd32(device, 0x410108) | 0x80000000);
for (tmp = 0, i = 0; i < gr->gpc_nr; i++)
@@ -74,7 +72,7 @@ gm20b_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
gf100_gr_wait_idle(gr);
- nvkm_wr32(device, 0x404154, idle_timeout_save);
+ nvkm_wr32(device, 0x404154, idle_timeout);
gf100_gr_wait_idle(gr);
gf100_gr_mthd(gr, gr->fuc_method);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc
index dc60509f76f7..4984b0069dfd 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpc.fuc
@@ -291,12 +291,13 @@ init:
// Main program loop, very simple, sleeps until woken up by the interrupt
// handler, pulls a command from the queue and executes its handler
//
-main:
- bset $flags $p0
+wait:
sleep $p0
+ bset $flags $p0
+main:
mov $r13 #cmd_queue
call(queue_get)
- bra $p1 #main
+ bra $p1 #wait
// 0x0000-0x0003 are all context transfers
cmpu b32 $r14 0x04
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h
index 5f4ddfee48a2..8cb240b65ec2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h
@@ -370,9 +370,10 @@ uint32_t gf100_grgpc_code[] = {
0xf11f29f0,
0xf0080007,
0x02d00203,
-/* 0x04bb: main */
+/* 0x04bb: wait */
0xf404bd00,
- 0x28f40031,
+ 0x31f40028,
+/* 0x04c1: main */
0x1cd7f000,
0xf43921f4,
0xe4b0f401,
@@ -384,10 +385,10 @@ uint32_t gf100_grgpc_code[] = {
0x0018fe05,
0x05b421f5,
/* 0x04eb: main_not_ctx_xfer */
- 0x94d30ef4,
+ 0x94d90ef4,
0xf5f010ef,
0x7e21f501,
- 0xc60ef403,
+ 0xcc0ef403,
/* 0x04f8: ih */
0x80f900f9,
0xf90188fe,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h
index 03381b163cfc..550d6ba0933b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h
@@ -397,9 +397,10 @@ uint32_t gf117_grgpc_code[] = {
0x080007f1,
0xd00203f0,
0x04bd0002,
-/* 0x0508: main */
- 0xf40031f4,
- 0xd7f00028,
+/* 0x0508: wait */
+ 0xf40028f4,
+/* 0x050e: main */
+ 0xd7f00031,
0x3921f424,
0xb0f401f4,
0x18f404e4,
@@ -409,13 +410,13 @@ uint32_t gf117_grgpc_code[] = {
0xfd01e4b6,
0x18fe051e,
0x0121f500,
- 0xd30ef406,
+ 0xd90ef406,
/* 0x0538: main_not_ctx_xfer */
0xf010ef94,
0x21f501f5,
0x0ef4037e,
/* 0x0545: ih */
- 0xf900f9c6,
+ 0xf900f9cc,
0x0188fe80,
0x90f980f9,
0xb0f9a0f9,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3.h
index 99d9b48a3b50..271b59d365e5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3.h
@@ -397,9 +397,10 @@ uint32_t gk104_grgpc_code[] = {
0x080007f1,
0xd00203f0,
0x04bd0002,
-/* 0x0508: main */
- 0xf40031f4,
- 0xd7f00028,
+/* 0x0508: wait */
+ 0xf40028f4,
+/* 0x050e: main */
+ 0xd7f00031,
0x3921f424,
0xb0f401f4,
0x18f404e4,
@@ -409,13 +410,13 @@ uint32_t gk104_grgpc_code[] = {
0xfd01e4b6,
0x18fe051e,
0x0121f500,
- 0xd30ef406,
+ 0xd90ef406,
/* 0x0538: main_not_ctx_xfer */
0xf010ef94,
0x21f501f5,
0x0ef4037e,
/* 0x0545: ih */
- 0xf900f9c6,
+ 0xf900f9cc,
0x0188fe80,
0x90f980f9,
0xb0f9a0f9,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3.h
index f7267696cbfd..73b4a32c5d29 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3.h
@@ -397,9 +397,10 @@ uint32_t gk110_grgpc_code[] = {
0x300007f1,
0xd00203f0,
0x04bd0002,
-/* 0x0508: main */
- 0xf40031f4,
- 0xd7f00028,
+/* 0x0508: wait */
+ 0xf40028f4,
+/* 0x050e: main */
+ 0xd7f00031,
0x3921f424,
0xb0f401f4,
0x18f404e4,
@@ -409,13 +410,13 @@ uint32_t gk110_grgpc_code[] = {
0xfd01e4b6,
0x18fe051e,
0x0121f500,
- 0xd30ef406,
+ 0xd90ef406,
/* 0x0538: main_not_ctx_xfer */
0xf010ef94,
0x21f501f5,
0x0ef4037e,
/* 0x0545: ih */
- 0xf900f9c6,
+ 0xf900f9cc,
0x0188fe80,
0x90f980f9,
0xb0f9a0f9,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5.h
index 387d1fa3e231..018169818317 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5.h
@@ -349,9 +349,10 @@ uint32_t gk208_grgpc_code[] = {
0x801f29f0,
0xf6023000,
0x04bd0002,
-/* 0x0448: main */
- 0xf40031f4,
- 0x240d0028,
+/* 0x0448: wait */
+ 0xf40028f4,
+/* 0x044e: main */
+ 0x240d0031,
0x0000377e,
0xb0f401f4,
0x18f404e4,
@@ -362,10 +363,10 @@ uint32_t gk208_grgpc_code[] = {
0x0018fe05,
0x00051f7e,
/* 0x0477: main_not_ctx_xfer */
- 0x94d40ef4,
+ 0x94da0ef4,
0xf5f010ef,
0x02f87e01,
- 0xc70ef400,
+ 0xcd0ef400,
/* 0x0484: ih */
0x80f900f9,
0xf90188fe,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5.h
index fa9f3c0c5994..eca007f03fa9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5.h
@@ -427,9 +427,10 @@ uint32_t gm107_grgpc_code[] = {
0x1f29f024,
0x02300080,
0xbd0002f6,
-/* 0x0571: main */
- 0x0031f404,
- 0x0d0028f4,
+/* 0x0571: wait */
+ 0x0028f404,
+/* 0x0577: main */
+ 0x0d0031f4,
0x00377e24,
0xf401f400,
0xf404e4b0,
@@ -439,13 +440,13 @@ uint32_t gm107_grgpc_code[] = {
0xfd01e4b6,
0x18fe051e,
0x06487e00,
- 0xd40ef400,
+ 0xda0ef400,
/* 0x05a0: main_not_ctx_xfer */
0xf010ef94,
0xf87e01f5,
0x0ef40002,
/* 0x05ad: ih */
- 0xf900f9c7,
+ 0xf900f9cd,
0x0188fe80,
0x90f980f9,
0xb0f9a0f9,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hub.fuc b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hub.fuc
index e3a2fb308271..4d416d4f82d7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hub.fuc
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hub.fuc
@@ -218,13 +218,14 @@ init:
// Main program loop, very simple, sleeps until woken up by the interrupt
// handler, pulls a command from the queue and executes its handler
//
-main:
+wait:
// sleep until we have something to do
- bset $flags $p0
sleep $p0
+ bset $flags $p0
+main:
mov $r13 #cmd_queue
call(queue_get)
- bra $p1 #main
+ bra $p1 #wait
// context switch, requested by GPU?
cmpu b32 $r14 0x4001
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3.h
index 397921a9a46c..8015b40a61d6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3.h
@@ -584,9 +584,10 @@ uint32_t gf100_grhub_code[] = {
0x080007f1,
0xd00203f0,
0x04bd0001,
-/* 0x0564: main */
- 0xf40031f4,
- 0xd7f00028,
+/* 0x0564: wait */
+ 0xf40028f4,
+/* 0x056a: main */
+ 0xd7f00031,
0x3921f410,
0xb1f401f4,
0xf54001e4,
@@ -650,7 +651,7 @@ uint32_t gf100_grhub_code[] = {
0x170007f1,
0xd00203f0,
0x04bd0009,
- 0xff080ef5,
+ 0xff0e0ef5,
/* 0x0660: main_not_ctx_switch */
0xf401e4b0,
0xf2b90d1b,
@@ -675,12 +676,12 @@ uint32_t gf100_grhub_code[] = {
0xf501f5f0,
0xf5037e21,
/* 0x06b3: main_done */
- 0xbdfeb50e,
+ 0xbdfebb0e,
0x1f29f024,
0x080007f1,
0xd00203f0,
0x04bd0002,
- 0xfea00ef5,
+ 0xfea60ef5,
/* 0x06c8: ih */
0x80f900f9,
0xf90188fe,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3.h
index 50c97163dcdb..2af90ec6852a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3.h
@@ -584,9 +584,10 @@ uint32_t gf117_grhub_code[] = {
0x080007f1,
0xd00203f0,
0x04bd0001,
-/* 0x0564: main */
- 0xf40031f4,
- 0xd7f00028,
+/* 0x0564: wait */
+ 0xf40028f4,
+/* 0x056a: main */
+ 0xd7f00031,
0x3921f410,
0xb1f401f4,
0xf54001e4,
@@ -650,7 +651,7 @@ uint32_t gf117_grhub_code[] = {
0x170007f1,
0xd00203f0,
0x04bd0009,
- 0xff080ef5,
+ 0xff0e0ef5,
/* 0x0660: main_not_ctx_switch */
0xf401e4b0,
0xf2b90d1b,
@@ -675,12 +676,12 @@ uint32_t gf117_grhub_code[] = {
0xf501f5f0,
0xf5037e21,
/* 0x06b3: main_done */
- 0xbdfeb50e,
+ 0xbdfebb0e,
0x1f29f024,
0x080007f1,
0xd00203f0,
0x04bd0002,
- 0xfea00ef5,
+ 0xfea60ef5,
/* 0x06c8: ih */
0x80f900f9,
0xf90188fe,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3.h
index 125824b394bb..e8b8c1c94700 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3.h
@@ -584,9 +584,10 @@ uint32_t gk104_grhub_code[] = {
0x080007f1,
0xd00203f0,
0x04bd0001,
-/* 0x0564: main */
- 0xf40031f4,
- 0xd7f00028,
+/* 0x0564: wait */
+ 0xf40028f4,
+/* 0x056a: main */
+ 0xd7f00031,
0x3921f410,
0xb1f401f4,
0xf54001e4,
@@ -650,7 +651,7 @@ uint32_t gk104_grhub_code[] = {
0x170007f1,
0xd00203f0,
0x04bd0009,
- 0xff080ef5,
+ 0xff0e0ef5,
/* 0x0660: main_not_ctx_switch */
0xf401e4b0,
0xf2b90d1b,
@@ -675,12 +676,12 @@ uint32_t gk104_grhub_code[] = {
0xf501f5f0,
0xf5037e21,
/* 0x06b3: main_done */
- 0xbdfeb50e,
+ 0xbdfebb0e,
0x1f29f024,
0x080007f1,
0xd00203f0,
0x04bd0002,
- 0xfea00ef5,
+ 0xfea60ef5,
/* 0x06c8: ih */
0x80f900f9,
0xf90188fe,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3.h
index 0a1b8c0b8b82..f4ed2fb6f714 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3.h
@@ -584,9 +584,10 @@ uint32_t gk110_grhub_code[] = {
0x300007f1,
0xd00203f0,
0x04bd0001,
-/* 0x0564: main */
- 0xf40031f4,
- 0xd7f00028,
+/* 0x0564: wait */
+ 0xf40028f4,
+/* 0x056a: main */
+ 0xd7f00031,
0x3921f410,
0xb1f401f4,
0xf54001e4,
@@ -650,7 +651,7 @@ uint32_t gk110_grhub_code[] = {
0x170007f1,
0xd00203f0,
0x04bd0009,
- 0xff080ef5,
+ 0xff0e0ef5,
/* 0x0660: main_not_ctx_switch */
0xf401e4b0,
0xf2b90d1b,
@@ -675,12 +676,12 @@ uint32_t gk110_grhub_code[] = {
0xf501f5f0,
0xf5037e21,
/* 0x06b3: main_done */
- 0xbdfeb50e,
+ 0xbdfebb0e,
0x1f29f024,
0x300007f1,
0xd00203f0,
0x04bd0002,
- 0xfea00ef5,
+ 0xfea60ef5,
/* 0x06c8: ih */
0x80f900f9,
0xf90188fe,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5.h
index 16869d0b109b..ed488973c117 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5.h
@@ -531,9 +531,10 @@ uint32_t gk208_grhub_code[] = {
0x1f19f014,
0x02300080,
0xbd0001f6,
-/* 0x0491: main */
- 0x0031f404,
- 0x0d0028f4,
+/* 0x0491: wait */
+ 0x0028f404,
+/* 0x0497: main */
+ 0x0d0031f4,
0x00377e10,
0xf401f400,
0x4001e4b1,
@@ -590,7 +591,7 @@ uint32_t gk208_grhub_code[] = {
0x09f60217,
0xf504bd00,
/* 0x056b: main_not_ctx_switch */
- 0xb0ff2a0e,
+ 0xb0ff300e,
0x1bf401e4,
0x7ef2b20c,
0xf4000820,
@@ -612,11 +613,11 @@ uint32_t gk208_grhub_code[] = {
0x7e01f5f0,
0xf50002f8,
/* 0x05b7: main_done */
- 0xbdfede0e,
+ 0xbdfee40e,
0x1f29f024,
0x02300080,
0xbd0002f6,
- 0xcc0ef504,
+ 0xd20ef504,
/* 0x05c9: ih */
0xf900f9fe,
0x0188fe80,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5.h
index d6343d2a614c..5c9051839557 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5.h
@@ -531,9 +531,10 @@ uint32_t gm107_grhub_code[] = {
0x1f19f014,
0x02300080,
0xbd0001f6,
-/* 0x0491: main */
- 0x0031f404,
- 0x0d0028f4,
+/* 0x0491: wait */
+ 0x0028f404,
+/* 0x0497: main */
+ 0x0d0031f4,
0x00377e10,
0xf401f400,
0x4001e4b1,
@@ -590,7 +591,7 @@ uint32_t gm107_grhub_code[] = {
0x09f60217,
0xf504bd00,
/* 0x056b: main_not_ctx_switch */
- 0xb0ff2a0e,
+ 0xb0ff300e,
0x1bf401e4,
0x7ef2b20c,
0xf4000820,
@@ -612,11 +613,11 @@ uint32_t gm107_grhub_code[] = {
0x7e01f5f0,
0xf50002f8,
/* 0x05b7: main_done */
- 0xbdfede0e,
+ 0xbdfee40e,
0x1f29f024,
0x02300080,
0xbd0002f6,
- 0xcc0ef504,
+ 0xd20ef504,
/* 0x05c9: ih */
0xf900f9fe,
0x0188fe80,
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
index b2de290da16f..9513badb8220 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
@@ -702,6 +702,13 @@ gf100_gr_pack_mmio[] = {
* PGRAPH engine/subdev functions
******************************************************************************/
+int
+gf100_gr_rops(struct gf100_gr *gr)
+{
+ struct nvkm_device *device = gr->base.engine.subdev.device;
+ return (nvkm_rd32(device, 0x409604) & 0x001f0000) >> 16;
+}
+
void
gf100_gr_zbc_init(struct gf100_gr *gr)
{
@@ -1609,32 +1616,12 @@ gf100_gr_oneinit(struct nvkm_gr *base)
{
struct gf100_gr *gr = gf100_gr(base);
struct nvkm_device *device = gr->base.engine.subdev.device;
- int ret, i, j;
+ int i, j;
nvkm_pmu_pgob(device->pmu, false);
- ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 256, false,
- &gr->unk4188b4);
- if (ret)
- return ret;
-
- ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 256, false,
- &gr->unk4188b8);
- if (ret)
- return ret;
-
- nvkm_kmap(gr->unk4188b4);
- for (i = 0; i < 0x1000; i += 4)
- nvkm_wo32(gr->unk4188b4, i, 0x00000010);
- nvkm_done(gr->unk4188b4);
-
- nvkm_kmap(gr->unk4188b8);
- for (i = 0; i < 0x1000; i += 4)
- nvkm_wo32(gr->unk4188b8, i, 0x00000010);
- nvkm_done(gr->unk4188b8);
-
- gr->rop_nr = (nvkm_rd32(device, 0x409604) & 0x001f0000) >> 16;
- gr->gpc_nr = nvkm_rd32(device, 0x409604) & 0x0000001f;
+ gr->rop_nr = gr->func->rops(gr);
+ gr->gpc_nr = nvkm_rd32(device, 0x409604) & 0x0000001f;
for (i = 0; i < gr->gpc_nr; i++) {
gr->tpc_nr[i] = nvkm_rd32(device, GPC_UNIT(i, 0x2608));
gr->tpc_total += gr->tpc_nr[i];
@@ -1651,38 +1638,38 @@ gf100_gr_oneinit(struct nvkm_gr *base)
switch (device->chipset) {
case 0xc0:
if (gr->tpc_total == 11) { /* 465, 3/4/4/0, 4 */
- gr->magic_not_rop_nr = 0x07;
+ gr->screen_tile_row_offset = 0x07;
} else
if (gr->tpc_total == 14) { /* 470, 3/3/4/4, 5 */
- gr->magic_not_rop_nr = 0x05;
+ gr->screen_tile_row_offset = 0x05;
} else
if (gr->tpc_total == 15) { /* 480, 3/4/4/4, 6 */
- gr->magic_not_rop_nr = 0x06;
+ gr->screen_tile_row_offset = 0x06;
}
break;
case 0xc3: /* 450, 4/0/0/0, 2 */
- gr->magic_not_rop_nr = 0x03;
+ gr->screen_tile_row_offset = 0x03;
break;
case 0xc4: /* 460, 3/4/0/0, 4 */
- gr->magic_not_rop_nr = 0x01;
+ gr->screen_tile_row_offset = 0x01;
break;
case 0xc1: /* 2/0/0/0, 1 */
- gr->magic_not_rop_nr = 0x01;
+ gr->screen_tile_row_offset = 0x01;
break;
case 0xc8: /* 4/4/3/4, 5 */
- gr->magic_not_rop_nr = 0x06;
+ gr->screen_tile_row_offset = 0x06;
break;
case 0xce: /* 4/4/0/0, 4 */
- gr->magic_not_rop_nr = 0x03;
+ gr->screen_tile_row_offset = 0x03;
break;
case 0xcf: /* 4/0/0/0, 3 */
- gr->magic_not_rop_nr = 0x03;
+ gr->screen_tile_row_offset = 0x03;
break;
case 0xd7:
case 0xd9: /* 1/0/0/0, 1 */
case 0xea: /* gk20a */
case 0x12b: /* gm20b */
- gr->magic_not_rop_nr = 0x01;
+ gr->screen_tile_row_offset = 0x01;
break;
}
@@ -1729,8 +1716,6 @@ gf100_gr_dtor(struct nvkm_gr *base)
gf100_gr_dtor_init(gr->fuc_sw_ctx);
gf100_gr_dtor_init(gr->fuc_sw_nonctx);
- nvkm_memory_del(&gr->unk4188b8);
- nvkm_memory_del(&gr->unk4188b4);
return gr;
}
@@ -1776,7 +1761,7 @@ gf100_gr_ctor(const struct gf100_gr_func *func, struct nvkm_device *device,
gr->firmware = nvkm_boolopt(device->cfgopt, "NvGrUseFW",
func->fecs.ucode == NULL);
- ret = nvkm_gr_ctor(&gf100_gr_, device, index, 0x08001000,
+ ret = nvkm_gr_ctor(&gf100_gr_, device, index,
gr->firmware || func->fecs.ucode != NULL,
&gr->base);
if (ret)
@@ -1815,6 +1800,7 @@ int
gf100_gr_init(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
+ struct nvkm_fb *fb = device->fb;
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total);
u32 data[TPC_MAX / 8] = {};
u8 tpcnr[GPC_MAX];
@@ -1827,8 +1813,8 @@ gf100_gr_init(struct gf100_gr *gr)
nvkm_wr32(device, GPC_BCAST(0x088c), 0x00000000);
nvkm_wr32(device, GPC_BCAST(0x0890), 0x00000000);
nvkm_wr32(device, GPC_BCAST(0x0894), 0x00000000);
- nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(gr->unk4188b4) >> 8);
- nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(gr->unk4188b8) >> 8);
+ nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(fb->mmu_wr) >> 8);
+ nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(fb->mmu_rd) >> 8);
gf100_gr_mmio(gr, gr->func->mmio);
@@ -1851,9 +1837,9 @@ gf100_gr_init(struct gf100_gr *gr)
for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
nvkm_wr32(device, GPC_UNIT(gpc, 0x0914),
- gr->magic_not_rop_nr << 8 | gr->tpc_nr[gpc]);
+ gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 |
- gr->tpc_total);
+ gr->tpc_total);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918);
}
@@ -1946,6 +1932,7 @@ gf100_gr = {
.mmio = gf100_gr_pack_mmio,
.fecs.ucode = &gf100_gr_fecs_ucode,
.gpccs.ucode = &gf100_gr_gpccs_ucode,
+ .rops = gf100_gr_rops,
.grctx = &gf100_grctx,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
index f0c6acb0f8fd..2b98abdb9270 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
@@ -31,7 +31,8 @@
#include <subdev/mmu.h>
#define GPC_MAX 32
-#define TPC_MAX (GPC_MAX * 8)
+#define TPC_MAX_PER_GPC 8
+#define TPC_MAX (GPC_MAX * TPC_MAX_PER_GPC)
#define ROP_BCAST(r) (0x408800 + (r))
#define ROP_UNIT(u, r) (0x410000 + (u) * 0x400 + (r))
@@ -100,15 +101,12 @@ struct gf100_gr {
u8 ppc_mask[GPC_MAX];
u8 ppc_tpc_nr[GPC_MAX][4];
- struct nvkm_memory *unk4188b4;
- struct nvkm_memory *unk4188b8;
-
struct gf100_gr_data mmio_data[4];
struct gf100_gr_mmio mmio_list[4096/8];
u32 size;
u32 *data;
- u8 magic_not_rop_nr;
+ u8 screen_tile_row_offset;
};
int gf100_gr_ctor(const struct gf100_gr_func *, struct nvkm_device *,
@@ -121,6 +119,8 @@ struct gf100_gr_func {
void (*dtor)(struct gf100_gr *);
int (*init)(struct gf100_gr *);
void (*init_gpc_mmu)(struct gf100_gr *);
+ void (*init_rop_active_fbps)(struct gf100_gr *);
+ void (*init_ppc_exceptions)(struct gf100_gr *);
void (*set_hww_esr_report_mask)(struct gf100_gr *);
const struct gf100_gr_pack *mmio;
struct {
@@ -129,18 +129,23 @@ struct gf100_gr_func {
struct {
struct gf100_gr_ucode *ucode;
} gpccs;
+ int (*rops)(struct gf100_gr *);
int ppc_nr;
const struct gf100_grctx_func *grctx;
struct nvkm_sclass sclass[];
};
int gf100_gr_init(struct gf100_gr *);
+int gf100_gr_rops(struct gf100_gr *);
int gk104_gr_init(struct gf100_gr *);
+void gk104_gr_init_rop_active_fbps(struct gf100_gr *);
+void gk104_gr_init_ppc_exceptions(struct gf100_gr *);
int gk20a_gr_init(struct gf100_gr *);
int gm200_gr_init(struct gf100_gr *);
+int gm200_gr_rops(struct gf100_gr *);
#define gf100_gr_chan(p) container_of((p), struct gf100_gr_chan, object)
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c
index 8f253e0a22f4..d736dcd55ea2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf104.c
@@ -118,6 +118,7 @@ gf104_gr = {
.mmio = gf104_gr_pack_mmio,
.fecs.ucode = &gf100_gr_fecs_ucode,
.gpccs.ucode = &gf100_gr_gpccs_ucode,
+ .rops = gf100_gr_rops,
.grctx = &gf104_grctx,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c
index 815a5aafa245..2f0d24498427 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf108.c
@@ -109,6 +109,7 @@ gf108_gr = {
.mmio = gf108_gr_pack_mmio,
.fecs.ucode = &gf100_gr_fecs_ucode,
.gpccs.ucode = &gf100_gr_gpccs_ucode,
+ .rops = gf100_gr_rops,
.grctx = &gf108_grctx,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c
index d081ee41fc14..d1d942eb86af 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf110.c
@@ -90,6 +90,7 @@ gf110_gr = {
.mmio = gf110_gr_pack_mmio,
.fecs.ucode = &gf100_gr_fecs_ucode,
.gpccs.ucode = &gf100_gr_gpccs_ucode,
+ .rops = gf100_gr_rops,
.grctx = &gf110_grctx,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c
index d8e8af4d3b30..70335f65c51e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c
@@ -126,6 +126,7 @@ gf117_gr = {
.mmio = gf117_gr_pack_mmio,
.fecs.ucode = &gf117_gr_fecs_ucode,
.gpccs.ucode = &gf117_gr_gpccs_ucode,
+ .rops = gf100_gr_rops,
.ppc_nr = 1,
.grctx = &gf117_grctx,
.sclass = {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c
index 01faf9a73774..8d8e4cafe28f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf119.c
@@ -181,6 +181,7 @@ gf119_gr = {
.mmio = gf119_gr_pack_mmio,
.fecs.ucode = &gf100_gr_fecs_ucode,
.gpccs.ucode = &gf100_gr_gpccs_ucode,
+ .rops = gf100_gr_rops,
.grctx = &gf119_grctx,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c
index abf54928a1a4..ec22da6c99fc 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk104.c
@@ -24,6 +24,8 @@
#include "gf100.h"
#include "ctxgf100.h"
+#include <subdev/fb.h>
+
#include <nvif/class.h>
/*******************************************************************************
@@ -177,10 +179,35 @@ gk104_gr_pack_mmio[] = {
* PGRAPH engine/subdev functions
******************************************************************************/
+void
+gk104_gr_init_rop_active_fbps(struct gf100_gr *gr)
+{
+ struct nvkm_device *device = gr->base.engine.subdev.device;
+ const u32 fbp_count = nvkm_rd32(device, 0x120074);
+ nvkm_mask(device, 0x408850, 0x0000000f, fbp_count); /* zrop */
+ nvkm_mask(device, 0x408958, 0x0000000f, fbp_count); /* crop */
+}
+
+void
+gk104_gr_init_ppc_exceptions(struct gf100_gr *gr)
+{
+ struct nvkm_device *device = gr->base.engine.subdev.device;
+ int gpc, ppc;
+
+ for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
+ for (ppc = 0; ppc < gr->ppc_nr[gpc]; ppc++) {
+ if (!(gr->ppc_mask[gpc] & (1 << ppc)))
+ continue;
+ nvkm_wr32(device, PPC_UNIT(gpc, ppc, 0x038), 0xc0000000);
+ }
+ }
+}
+
int
gk104_gr_init(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
+ struct nvkm_fb *fb = device->fb;
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total);
u32 data[TPC_MAX / 8] = {};
u8 tpcnr[GPC_MAX];
@@ -193,8 +220,8 @@ gk104_gr_init(struct gf100_gr *gr)
nvkm_wr32(device, GPC_BCAST(0x088c), 0x00000000);
nvkm_wr32(device, GPC_BCAST(0x0890), 0x00000000);
nvkm_wr32(device, GPC_BCAST(0x0894), 0x00000000);
- nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(gr->unk4188b4) >> 8);
- nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(gr->unk4188b8) >> 8);
+ nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(fb->mmu_wr) >> 8);
+ nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(fb->mmu_rd) >> 8);
gf100_gr_mmio(gr, gr->func->mmio);
@@ -218,15 +245,17 @@ gk104_gr_init(struct gf100_gr *gr)
for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
nvkm_wr32(device, GPC_UNIT(gpc, 0x0914),
- gr->magic_not_rop_nr << 8 | gr->tpc_nr[gpc]);
+ gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 |
- gr->tpc_total);
+ gr->tpc_total);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918);
}
nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918);
nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800));
+ gr->func->init_rop_active_fbps(gr);
+
nvkm_wr32(device, 0x400500, 0x00010001);
nvkm_wr32(device, 0x400100, 0xffffffff);
@@ -246,8 +275,9 @@ gk104_gr_init(struct gf100_gr *gr)
nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008);
nvkm_mask(device, 0x419eb4, 0x00001000, 0x00001000);
+ gr->func->init_ppc_exceptions(gr);
+
for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
- nvkm_wr32(device, GPC_UNIT(gpc, 0x3038), 0xc0000000);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0420), 0xc0000000);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0900), 0xc0000000);
nvkm_wr32(device, GPC_UNIT(gpc, 0x1028), 0xc0000000);
@@ -309,9 +339,12 @@ gk104_gr_gpccs_ucode = {
static const struct gf100_gr_func
gk104_gr = {
.init = gk104_gr_init,
+ .init_rop_active_fbps = gk104_gr_init_rop_active_fbps,
+ .init_ppc_exceptions = gk104_gr_init_ppc_exceptions,
.mmio = gk104_gr_pack_mmio,
.fecs.ucode = &gk104_gr_fecs_ucode,
.gpccs.ucode = &gk104_gr_gpccs_ucode,
+ .rops = gf100_gr_rops,
.ppc_nr = 1,
.grctx = &gk104_grctx,
.sclass = {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c
index 32aa2946e7b7..f31b171a4102 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110.c
@@ -183,9 +183,12 @@ gk110_gr_gpccs_ucode = {
static const struct gf100_gr_func
gk110_gr = {
.init = gk104_gr_init,
+ .init_rop_active_fbps = gk104_gr_init_rop_active_fbps,
+ .init_ppc_exceptions = gk104_gr_init_ppc_exceptions,
.mmio = gk110_gr_pack_mmio,
.fecs.ucode = &gk110_gr_fecs_ucode,
.gpccs.ucode = &gk110_gr_gpccs_ucode,
+ .rops = gf100_gr_rops,
.ppc_nr = 2,
.grctx = &gk110_grctx,
.sclass = {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c
index 22f88afbf35f..d76dd178007f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk110b.c
@@ -103,9 +103,12 @@ gk110b_gr_pack_mmio[] = {
static const struct gf100_gr_func
gk110b_gr = {
.init = gk104_gr_init,
+ .init_rop_active_fbps = gk104_gr_init_rop_active_fbps,
+ .init_ppc_exceptions = gk104_gr_init_ppc_exceptions,
.mmio = gk110b_gr_pack_mmio,
.fecs.ucode = &gk110_gr_fecs_ucode,
.gpccs.ucode = &gk110_gr_gpccs_ucode,
+ .rops = gf100_gr_rops,
.ppc_nr = 2,
.grctx = &gk110b_grctx,
.sclass = {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c
index ee7554fc87dc..14bbe6ed02a9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk208.c
@@ -162,9 +162,12 @@ gk208_gr_gpccs_ucode = {
static const struct gf100_gr_func
gk208_gr = {
.init = gk104_gr_init,
+ .init_rop_active_fbps = gk104_gr_init_rop_active_fbps,
+ .init_ppc_exceptions = gk104_gr_init_ppc_exceptions,
.mmio = gk208_gr_pack_mmio,
.fecs.ucode = &gk208_gr_fecs_ucode,
.gpccs.ucode = &gk208_gr_gpccs_ucode,
+ .rops = gf100_gr_rops,
.ppc_nr = 1,
.grctx = &gk208_grctx,
.sclass = {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c
index 7ffb8a626196..4ca8ed15191c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gk20a.c
@@ -239,9 +239,6 @@ gk20a_gr_init(struct gf100_gr *gr)
return ret;
/* MMU debug buffer */
- nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(gr->unk4188b4) >> 8);
- nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(gr->unk4188b8) >> 8);
-
if (gr->func->init_gpc_mmu)
gr->func->init_gpc_mmu(gr);
@@ -267,7 +264,7 @@ gk20a_gr_init(struct gf100_gr *gr)
for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
nvkm_wr32(device, GPC_UNIT(gpc, 0x0914),
- gr->magic_not_rop_nr << 8 | gr->tpc_nr[gpc]);
+ gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 |
gr->tpc_total);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918);
@@ -275,6 +272,8 @@ gk20a_gr_init(struct gf100_gr *gr)
nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918);
+ gr->func->init_rop_active_fbps(gr);
+
/* Enable FIFO access */
nvkm_wr32(device, 0x400500, 0x00010001);
@@ -312,7 +311,9 @@ gk20a_gr_init(struct gf100_gr *gr)
static const struct gf100_gr_func
gk20a_gr = {
.init = gk20a_gr_init,
+ .init_rop_active_fbps = gk104_gr_init_rop_active_fbps,
.set_hww_esr_report_mask = gk20a_gr_set_hww_esr_report_mask,
+ .rops = gf100_gr_rops,
.ppc_nr = 1,
.grctx = &gk20a_grctx,
.sclass = {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c
index 56e960212e5d..45f965f608a7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c
@@ -26,6 +26,7 @@
#include <subdev/bios.h>
#include <subdev/bios/P0260.h>
+#include <subdev/fb.h>
#include <nvif/class.h>
@@ -311,17 +312,18 @@ int
gm107_gr_init(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
+ struct nvkm_fb *fb = device->fb;
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total);
u32 data[TPC_MAX / 8] = {};
u8 tpcnr[GPC_MAX];
- int gpc, tpc, ppc, rop;
+ int gpc, tpc, rop;
int i;
nvkm_wr32(device, GPC_BCAST(0x0880), 0x00000000);
nvkm_wr32(device, GPC_BCAST(0x0890), 0x00000000);
nvkm_wr32(device, GPC_BCAST(0x0894), 0x00000000);
- nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(gr->unk4188b4) >> 8);
- nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(gr->unk4188b8) >> 8);
+ nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(fb->mmu_wr) >> 8);
+ nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(fb->mmu_rd) >> 8);
gf100_gr_mmio(gr, gr->func->mmio);
@@ -347,15 +349,17 @@ gm107_gr_init(struct gf100_gr *gr)
for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
nvkm_wr32(device, GPC_UNIT(gpc, 0x0914),
- gr->magic_not_rop_nr << 8 | gr->tpc_nr[gpc]);
+ gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 |
- gr->tpc_total);
+ gr->tpc_total);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918);
}
nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918);
nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800));
+ gr->func->init_rop_active_fbps(gr);
+
nvkm_wr32(device, 0x400500, 0x00010001);
nvkm_wr32(device, 0x400100, 0xffffffff);
@@ -373,9 +377,9 @@ gm107_gr_init(struct gf100_gr *gr)
nvkm_wr32(device, 0x405844, 0x00ffffff);
nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008);
+ gr->func->init_ppc_exceptions(gr);
+
for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
- for (ppc = 0; ppc < 2 /* gr->ppc_nr[gpc] */; ppc++)
- nvkm_wr32(device, PPC_UNIT(gpc, ppc, 0x038), 0xc0000000);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0420), 0xc0000000);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0900), 0xc0000000);
nvkm_wr32(device, GPC_UNIT(gpc, 0x1028), 0xc0000000);
@@ -438,9 +442,12 @@ gm107_gr_gpccs_ucode = {
static const struct gf100_gr_func
gm107_gr = {
.init = gm107_gr_init,
+ .init_rop_active_fbps = gk104_gr_init_rop_active_fbps,
+ .init_ppc_exceptions = gk104_gr_init_ppc_exceptions,
.mmio = gm107_gr_pack_mmio,
.fecs.ucode = &gm107_gr_fecs_ucode,
.gpccs.ucode = &gm107_gr_gpccs_ucode,
+ .rops = gf100_gr_rops,
.ppc_nr = 2,
.grctx = &gm107_grctx,
.sclass = {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c
index 058fc1d22c09..4dfa4513bb6c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm200.c
@@ -33,27 +33,45 @@
******************************************************************************/
int
+gm200_gr_rops(struct gf100_gr *gr)
+{
+ return nvkm_rd32(gr->base.engine.subdev.device, 0x12006c);
+}
+
+static void
+gm200_gr_init_gpc_mmu(struct gf100_gr *gr)
+{
+ struct nvkm_device *device = gr->base.engine.subdev.device;
+
+ nvkm_wr32(device, 0x418880, nvkm_rd32(device, 0x100c80) & 0xf0001fff);
+ nvkm_wr32(device, 0x418890, 0x00000000);
+ nvkm_wr32(device, 0x418894, 0x00000000);
+
+ nvkm_wr32(device, 0x4188b4, nvkm_rd32(device, 0x100cc8));
+ nvkm_wr32(device, 0x4188b8, nvkm_rd32(device, 0x100ccc));
+ nvkm_wr32(device, 0x4188b0, nvkm_rd32(device, 0x100cc4));
+}
+
+static void
+gm200_gr_init_rop_active_fbps(struct gf100_gr *gr)
+{
+ struct nvkm_device *device = gr->base.engine.subdev.device;
+ const u32 fbp_count = nvkm_rd32(device, 0x12006c);
+ nvkm_mask(device, 0x408850, 0x0000000f, fbp_count); /* zrop */
+ nvkm_mask(device, 0x408958, 0x0000000f, fbp_count); /* crop */
+}
+
+int
gm200_gr_init(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total);
- u32 data[TPC_MAX / 8] = {}, tmp;
+ u32 data[TPC_MAX / 8] = {};
u8 tpcnr[GPC_MAX];
- int gpc, tpc, ppc, rop;
+ int gpc, tpc, rop;
int i;
- tmp = nvkm_rd32(device, 0x100c80); /*XXX: mask? */
- nvkm_wr32(device, 0x418880, 0x00001000 | (tmp & 0x00000fff));
- nvkm_wr32(device, 0x418890, 0x00000000);
- nvkm_wr32(device, 0x418894, 0x00000000);
- nvkm_wr32(device, 0x4188b4, nvkm_memory_addr(gr->unk4188b4) >> 8);
- nvkm_wr32(device, 0x4188b8, nvkm_memory_addr(gr->unk4188b8) >> 8);
- nvkm_mask(device, 0x4188b0, 0x00040000, 0x00040000);
-
- /*XXX: belongs in fb */
- nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(gr->unk4188b4) >> 8);
- nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(gr->unk4188b8) >> 8);
- nvkm_mask(device, 0x100cc4, 0x00040000, 0x00040000);
+ gr->func->init_gpc_mmu(gr);
gf100_gr_mmio(gr, gr->fuc_sw_nonctx);
@@ -79,9 +97,9 @@ gm200_gr_init(struct gf100_gr *gr)
for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
nvkm_wr32(device, GPC_UNIT(gpc, 0x0914),
- gr->magic_not_rop_nr << 8 | gr->tpc_nr[gpc]);
+ gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 |
- gr->tpc_total);
+ gr->tpc_total);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918);
}
@@ -89,6 +107,8 @@ gm200_gr_init(struct gf100_gr *gr)
nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800));
nvkm_wr32(device, GPC_BCAST(0x033c), nvkm_rd32(device, 0x100804));
+ gr->func->init_rop_active_fbps(gr);
+
nvkm_wr32(device, 0x400500, 0x00010001);
nvkm_wr32(device, 0x400100, 0xffffffff);
nvkm_wr32(device, 0x40013c, 0xffffffff);
@@ -106,9 +126,9 @@ gm200_gr_init(struct gf100_gr *gr)
nvkm_wr32(device, 0x405844, 0x00ffffff);
nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008);
+ gr->func->init_ppc_exceptions(gr);
+
for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
- for (ppc = 0; ppc < gr->ppc_nr[gpc]; ppc++)
- nvkm_wr32(device, PPC_UNIT(gpc, ppc, 0x038), 0xc0000000);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0420), 0xc0000000);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0900), 0xc0000000);
nvkm_wr32(device, GPC_UNIT(gpc, 0x1028), 0xc0000000);
@@ -189,6 +209,10 @@ gm200_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device,
static const struct gf100_gr_func
gm200_gr = {
.init = gm200_gr_init,
+ .init_gpc_mmu = gm200_gr_init_gpc_mmu,
+ .init_rop_active_fbps = gm200_gr_init_rop_active_fbps,
+ .init_ppc_exceptions = gk104_gr_init_ppc_exceptions,
+ .rops = gm200_gr_rops,
.ppc_nr = 2,
.grctx = &gm200_grctx,
.sclass = {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c
index 29732bc14415..69479af1d829 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm20b.c
@@ -42,7 +42,7 @@ gm20b_gr_init_gpc_mmu(struct gf100_gr *gr)
}
val = nvkm_rd32(device, 0x100c80);
- val &= 0xf000087f;
+ val &= 0xf000187f;
nvkm_wr32(device, 0x418880, val);
nvkm_wr32(device, 0x418890, 0);
nvkm_wr32(device, 0x418894, 0);
@@ -66,7 +66,9 @@ static const struct gf100_gr_func
gm20b_gr = {
.init = gk20a_gr_init,
.init_gpc_mmu = gm20b_gr_init_gpc_mmu,
+ .init_rop_active_fbps = gk104_gr_init_rop_active_fbps,
.set_hww_esr_report_mask = gm20b_gr_set_hww_esr_report_mask,
+ .rops = gm200_gr_rops,
.ppc_nr = 1,
.grctx = &gm20b_grctx,
.sclass = {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c
index 85c5b7fea5f5..9c2e985dc079 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c
@@ -1422,6 +1422,5 @@ nv04_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
spin_lock_init(&gr->lock);
*pgr = &gr->base;
- return nvkm_gr_ctor(&nv04_gr, device, index, 0x00001000,
- true, &gr->base);
+ return nvkm_gr_ctor(&nv04_gr, device, index, true, &gr->base);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c
index 4542867fa9e6..4ebbfbdd8240 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c
@@ -1182,7 +1182,7 @@ nv10_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device,
spin_lock_init(&gr->lock);
*pgr = &gr->base;
- return nvkm_gr_ctor(func, device, index, 0x00001000, true, &gr->base);
+ return nvkm_gr_ctor(func, device, index, true, &gr->base);
}
static const struct nvkm_gr_func
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c
index 5caef65d3c6e..d1dc92999dc0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c
@@ -337,7 +337,7 @@ nv20_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device,
return -ENOMEM;
*pgr = &gr->base;
- return nvkm_gr_ctor(func, device, index, 0x00001000, true, &gr->base);
+ return nvkm_gr_ctor(func, device, index, true, &gr->base);
}
static const struct nvkm_gr_func
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c
index 05a895496fc6..5f1ad8344ea9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c
@@ -438,7 +438,7 @@ nv40_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device,
*pgr = &gr->base;
INIT_LIST_HEAD(&gr->chan);
- return nvkm_gr_ctor(func, device, index, 0x00001000, true, &gr->base);
+ return nvkm_gr_ctor(func, device, index, true, &gr->base);
}
static const struct nvkm_gr_func
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c
index b19b912d5787..fca67de43f2b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c
@@ -768,7 +768,7 @@ nv50_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device,
spin_lock_init(&gr->lock);
*pgr = &gr->base;
- return nvkm_gr_ctor(func, device, index, 0x00201000, true, &gr->base);
+ return nvkm_gr_ctor(func, device, index, true, &gr->base);
}
static const struct nvkm_gr_func
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/priv.h
index a234590be88e..d8adcdf6985a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/priv.h
@@ -7,8 +7,7 @@ struct nvkm_fb_tile;
struct nvkm_fifo_chan;
int nvkm_gr_ctor(const struct nvkm_gr_func *, struct nvkm_device *,
- int index, u32 pmc_enable, bool enable,
- struct nvkm_gr *);
+ int index, bool enable, struct nvkm_gr *);
bool nv04_gr_idle(struct nvkm_gr *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/g84.c
index 34ff0014a6c1..c0e11a071843 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/g84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/g84.c
@@ -39,6 +39,5 @@ g84_mpeg = {
int
g84_mpeg_new(struct nvkm_device *device, int index, struct nvkm_engine **pmpeg)
{
- return nvkm_engine_new_(&g84_mpeg, device, index, 0x00000002,
- true, pmpeg);
+ return nvkm_engine_new_(&g84_mpeg, device, index, true, pmpeg);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c
index d4d8942b1347..003ac915eaad 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c
@@ -278,7 +278,7 @@ nv31_mpeg_new_(const struct nv31_mpeg_func *func, struct nvkm_device *device,
mpeg->func = func;
*pmpeg = &mpeg->engine;
- return nvkm_engine_ctor(&nv31_mpeg_, device, index, 0x00000002,
+ return nvkm_engine_ctor(&nv31_mpeg_, device, index,
true, &mpeg->engine);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c
index d433cfa4a8ab..e536f37e24b0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c
@@ -212,6 +212,5 @@ nv44_mpeg_new(struct nvkm_device *device, int index, struct nvkm_engine **pmpeg)
INIT_LIST_HEAD(&mpeg->chan);
*pmpeg = &mpeg->engine;
- return nvkm_engine_ctor(&nv44_mpeg, device, index, 0x00000002,
- true, &mpeg->engine);
+ return nvkm_engine_ctor(&nv44_mpeg, device, index, true, &mpeg->engine);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c
index c3a85dffc782..4e528851e9c0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv50.c
@@ -130,6 +130,5 @@ nv50_mpeg = {
int
nv50_mpeg_new(struct nvkm_device *device, int index, struct nvkm_engine **pmpeg)
{
- return nvkm_engine_new_(&nv50_mpeg, device, index, 0x00400002,
- true, pmpeg);
+ return nvkm_engine_new_(&nv50_mpeg, device, index, true, pmpeg);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.c b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.c
index 1f1a99e927b2..f30cf1dcfb30 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.c
@@ -35,7 +35,6 @@ g98_mspdec_init(struct nvkm_falcon *mspdec)
static const struct nvkm_falcon_func
g98_mspdec = {
- .pmc_enable = 0x01020000,
.init = g98_mspdec_init,
.sclass = {
{ -1, -1, G98_MSPDEC },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.c
index 371fd6c3c663..cfe1aa81bd14 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.c
@@ -35,7 +35,6 @@ gf100_mspdec_init(struct nvkm_falcon *mspdec)
static const struct nvkm_falcon_func
gf100_mspdec = {
- .pmc_enable = 0x00020000,
.init = gf100_mspdec_init,
.sclass = {
{ -1, -1, GF100_MSPDEC },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.c
index de804a15bfd4..24272b4927bc 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.c
@@ -27,7 +27,6 @@
static const struct nvkm_falcon_func
gk104_mspdec = {
- .pmc_enable = 0x00020000,
.init = gf100_mspdec_init,
.sclass = {
{ -1, -1, GK104_MSPDEC },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gt215.c
index 835631713c95..cf6e59ad6ee2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gt215.c
@@ -27,7 +27,6 @@
static const struct nvkm_falcon_func
gt215_mspdec = {
- .pmc_enable = 0x01020000,
.init = g98_mspdec_init,
.sclass = {
{ -1, -1, GT212_MSPDEC },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.c b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.c
index 73f633ae2ee7..c45dbf79d1f9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.c
@@ -35,7 +35,6 @@ g98_msppp_init(struct nvkm_falcon *msppp)
static const struct nvkm_falcon_func
g98_msppp = {
- .pmc_enable = 0x00400002,
.init = g98_msppp_init,
.sclass = {
{ -1, -1, G98_MSPPP },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.c
index c42c0c07e2db..803c62ab516e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.c
@@ -35,7 +35,6 @@ gf100_msppp_init(struct nvkm_falcon *msppp)
static const struct nvkm_falcon_func
gf100_msppp = {
- .pmc_enable = 0x00000002,
.init = gf100_msppp_init,
.sclass = {
{ -1, -1, GF100_MSPPP },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gt215.c
index 00e7795f1d51..49cbf72cee4b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gt215.c
@@ -27,7 +27,6 @@
static const struct nvkm_falcon_func
gt215_msppp = {
- .pmc_enable = 0x00400002,
.init = g98_msppp_init,
.sclass = {
{ -1, -1, GT212_MSPPP },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.c b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.c
index 47e2929bfaf0..4a2a9f0494af 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.c
@@ -35,7 +35,6 @@ g98_msvld_init(struct nvkm_falcon *msvld)
static const struct nvkm_falcon_func
g98_msvld = {
- .pmc_enable = 0x04008000,
.init = g98_msvld_init,
.sclass = {
{ -1, -1, G98_MSVLD },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.c
index 1ac581ba9f96..1695e532c081 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.c
@@ -35,7 +35,6 @@ gf100_msvld_init(struct nvkm_falcon *msvld)
static const struct nvkm_falcon_func
gf100_msvld = {
- .pmc_enable = 0x00008000,
.init = gf100_msvld_init,
.sclass = {
{ -1, -1, GF100_MSVLD },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.c
index 4bba16e0f560..b640cd63ebe8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.c
@@ -27,7 +27,6 @@
static const struct nvkm_falcon_func
gk104_msvld = {
- .pmc_enable = 0x00008000,
.init = gf100_msvld_init,
.sclass = {
{ -1, -1, GK104_MSVLD },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gt215.c
index e17cb5605b2d..201e8ef3519e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gt215.c
@@ -27,7 +27,6 @@
static const struct nvkm_falcon_func
gt215_msvld = {
- .pmc_enable = 0x04008000,
.init = g98_msvld_init,
.sclass = {
{ -1, -1, GT212_MSVLD },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/mcp89.c b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/mcp89.c
index 511800f6a43b..a0f540ef257b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/mcp89.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/mcp89.c
@@ -27,7 +27,6 @@
static const struct nvkm_falcon_func
mcp89_msvld = {
- .pmc_enable = 0x04008000,
.init = g98_msvld_init,
.sclass = {
{ -1, -1, IGT21A_MSVLD },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c
index f19fabef8d73..8616636ad7b4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c
@@ -863,5 +863,5 @@ nvkm_pm_ctor(const struct nvkm_pm_func *func, struct nvkm_device *device,
pm->func = func;
INIT_LIST_HEAD(&pm->domains);
INIT_LIST_HEAD(&pm->sources);
- return nvkm_engine_ctor(&nvkm_pm, device, index, 0, true, &pm->engine);
+ return nvkm_engine_ctor(&nvkm_pm, device, index, true, &pm->engine);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c b/drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c
index 995c2c5ec150..6d2a7f0afbb5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c
@@ -66,7 +66,6 @@ g98_sec = {
.code.size = sizeof(g98_sec_code),
.data.data = g98_sec_data,
.data.size = sizeof(g98_sec_data),
- .pmc_enable = 0x00004000,
.intr = g98_sec_intr,
.sclass = {
{ -1, -1, G98_SEC },
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sw/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/sw/base.c
index 53c1f7e75b54..7be3198e11de 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/sw/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/base.c
@@ -106,5 +106,5 @@ nvkm_sw_new_(const struct nvkm_sw_func *func, struct nvkm_device *device,
INIT_LIST_HEAD(&sw->chan);
sw->func = func;
- return nvkm_engine_ctor(&nvkm_sw, device, index, 0, true, &sw->engine);
+ return nvkm_engine_ctor(&nvkm_sw, device, index, true, &sw->engine);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/vp/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/vp/g84.c
index 4188c77ac927..7a96178786c4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/vp/g84.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/vp/g84.c
@@ -27,7 +27,6 @@
static const struct nvkm_xtensa_func
g84_vp = {
- .pmc_enable = 0x01020000,
.fifo_val = 0x111,
.unkd28 = 0x9c544,
.sclass = {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c b/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c
index a3d4f5bcec7a..06bdb67a0205 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c
@@ -187,6 +187,6 @@ nvkm_xtensa_new_(const struct nvkm_xtensa_func *func,
xtensa->addr = addr;
*pengine = &xtensa->engine;
- return nvkm_engine_ctor(&nvkm_xtensa, device, index, func->pmc_enable,
+ return nvkm_engine_ctor(&nvkm_xtensa, device, index,
enable, &xtensa->engine);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild
index 642d27dc99a3..3f5d38d74fba 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/Kbuild
@@ -19,4 +19,5 @@ include $(src)/nvkm/subdev/pmu/Kbuild
include $(src)/nvkm/subdev/secboot/Kbuild
include $(src)/nvkm/subdev/therm/Kbuild
include $(src)/nvkm/subdev/timer/Kbuild
+include $(src)/nvkm/subdev/top/Kbuild
include $(src)/nvkm/subdev/volt/Kbuild
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c
index a9433ad45b1e..c561d148cebc 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/base.c
@@ -77,7 +77,7 @@ void
nvkm_bar_ctor(const struct nvkm_bar_func *func, struct nvkm_device *device,
int index, struct nvkm_bar *bar)
{
- nvkm_subdev_ctor(&nvkm_bar, device, index, 0, &bar->subdev);
+ nvkm_subdev_ctor(&nvkm_bar, device, index, &bar->subdev);
bar->func = func;
spin_lock_init(&bar->lock);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c
index 79536897efaa..e15b9627b07e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c
@@ -105,7 +105,7 @@ nvkm_bios_new(struct nvkm_device *device, int index, struct nvkm_bios **pbios)
if (!(bios = *pbios = kzalloc(sizeof(*bios), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&nvkm_bios, device, index, 0, &bios->subdev);
+ nvkm_subdev_ctor(&nvkm_bios, device, index, &bios->subdev);
ret = nvbios_shadow(bios);
if (ret)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c
index 125ec2ed6c2e..91a7dc56e406 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c
@@ -81,9 +81,11 @@ static u16
pll_limits_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
struct bit_entry bit_C;
+ u16 data = 0x0000;
- if (!bit_entry(bios, 'C', &bit_C) && bit_C.length >= 10) {
- u16 data = nvbios_rd16(bios, bit_C.offset + 8);
+ if (!bit_entry(bios, 'C', &bit_C)) {
+ if (bit_C.version == 1 && bit_C.length >= 10)
+ data = nvbios_rd16(bios, bit_C.offset + 8);
if (data) {
*ver = nvbios_rd08(bios, data + 0);
*hdr = nvbios_rd08(bios, data + 1);
@@ -94,7 +96,7 @@ pll_limits_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
}
if (bmp_version(bios) >= 0x0524) {
- u16 data = nvbios_rd16(bios, bios->bmp_offset + 142);
+ data = nvbios_rd16(bios, bios->bmp_offset + 142);
if (data) {
*ver = nvbios_rd08(bios, data + 0);
*hdr = 1;
@@ -105,7 +107,7 @@ pll_limits_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
}
*ver = 0x00;
- return 0x0000;
+ return data;
}
static struct pll_mapping *
@@ -156,7 +158,7 @@ pll_map_reg(struct nvkm_bios *bios, u32 reg, u32 *type, u8 *ver, u8 *len)
}
map = pll_map(bios);
- while (map->reg) {
+ while (map && map->reg) {
if (map->reg == reg && *ver >= 0x20) {
u16 addr = (data += hdr);
*type = map->type;
@@ -198,7 +200,7 @@ pll_map_type(struct nvkm_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len)
}
map = pll_map(bios);
- while (map->reg) {
+ while (map && map->reg) {
if (map->type == type && *ver >= 0x20) {
u16 addr = (data += hdr);
*reg = map->reg;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/base.c
index dc5a10f18bdb..52ad73bce5fe 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/base.c
@@ -58,7 +58,7 @@ nvkm_bus_new_(const struct nvkm_bus_func *func, struct nvkm_device *device,
struct nvkm_bus *bus;
if (!(bus = *pbus = kzalloc(sizeof(*bus), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&nvkm_bus, device, index, 0, &bus->subdev);
+ nvkm_subdev_ctor(&nvkm_bus, device, index, &bus->subdev);
bus->func = func;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
index 889cce2eb727..7102c25320fc 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
@@ -564,7 +564,7 @@ nvkm_clk_ctor(const struct nvkm_clk_func *func, struct nvkm_device *device,
int ret, idx, arglen;
const char *mode;
- nvkm_subdev_ctor(&nvkm_clk, device, index, 0, &clk->subdev);
+ nvkm_subdev_ctor(&nvkm_clk, device, index, &clk->subdev);
clk->func = func;
INIT_LIST_HEAD(&clk->states);
clk->domains = func->domains;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c
index 5f25402f6b09..4756019ddf3f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/base.c
@@ -83,6 +83,12 @@ nvkm_devinit_preinit(struct nvkm_subdev *subdev)
if (init->func->preinit)
init->func->preinit(init);
+ /* Override the post flag during the first call if NvForcePost is set */
+ if (init->force_post) {
+ init->post = init->force_post;
+ init->force_post = false;
+ }
+
/* unlock the extended vga crtc regs */
nvkm_lockvgac(subdev->device, false);
return 0;
@@ -124,7 +130,7 @@ nvkm_devinit_ctor(const struct nvkm_devinit_func *func,
struct nvkm_device *device, int index,
struct nvkm_devinit *init)
{
- nvkm_subdev_ctor(&nvkm_devinit, device, index, 0, &init->subdev);
+ nvkm_subdev_ctor(&nvkm_devinit, device, index, &init->subdev);
init->func = func;
- init->post = nvkm_boolopt(device->cfgopt, "NvForcePost", false);
+ init->force_post = nvkm_boolopt(device->cfgopt, "NvForcePost", false);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c
index 2923598b5fe9..8b1b34c3ad26 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c
@@ -97,9 +97,11 @@ gf100_devinit_preinit(struct nvkm_devinit *base)
struct nvkm_subdev *subdev = &init->base.subdev;
struct nvkm_device *device = subdev->device;
- /* This bit is set by devinit, and flips back to 0 on suspend */
- if (!base->post)
- base->post = ((nvkm_rd32(device, 0x2240c) & BIT(1)) == 0);
+ /*
+ * This bit is set by devinit, and flips back to 0 on suspend. We
+ * can use it as a reliable way to know whether we should run devinit.
+ */
+ base->post = ((nvkm_rd32(device, 0x2240c) & BIT(1)) == 0);
}
static const struct nvkm_devinit_func
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild
index 08105701af7e..842d5de96d73 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild
@@ -23,6 +23,7 @@ nvkm-y += nvkm/subdev/fb/gf100.o
nvkm-y += nvkm/subdev/fb/gk104.o
nvkm-y += nvkm/subdev/fb/gk20a.o
nvkm-y += nvkm/subdev/fb/gm107.o
+nvkm-y += nvkm/subdev/fb/gm200.o
nvkm-y += nvkm/subdev/fb/ram.o
nvkm-y += nvkm/subdev/fb/ramnv04.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c
index a719b9becb73..ce90242b8cce 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c
@@ -24,6 +24,7 @@
#include "priv.h"
#include "ram.h"
+#include <core/memory.h>
#include <subdev/bios.h>
#include <subdev/bios/M0203.h>
#include <engine/gr.h>
@@ -98,6 +99,7 @@ static int
nvkm_fb_oneinit(struct nvkm_subdev *subdev)
{
struct nvkm_fb *fb = nvkm_fb(subdev);
+
if (fb->func->ram_new) {
int ret = fb->func->ram_new(fb, &fb->ram);
if (ret) {
@@ -105,6 +107,13 @@ nvkm_fb_oneinit(struct nvkm_subdev *subdev)
return ret;
}
}
+
+ if (fb->func->oneinit) {
+ int ret = fb->func->oneinit(fb);
+ if (ret)
+ return ret;
+ }
+
return 0;
}
@@ -134,6 +143,9 @@ nvkm_fb_dtor(struct nvkm_subdev *subdev)
struct nvkm_fb *fb = nvkm_fb(subdev);
int i;
+ nvkm_memory_del(&fb->mmu_wr);
+ nvkm_memory_del(&fb->mmu_rd);
+
for (i = 0; i < fb->tile.regions; i++)
fb->func->tile.fini(fb, i, &fb->tile.region[i]);
@@ -156,7 +168,7 @@ void
nvkm_fb_ctor(const struct nvkm_fb_func *func, struct nvkm_device *device,
int index, struct nvkm_fb *fb)
{
- nvkm_subdev_ctor(&nvkm_fb, device, index, 0, &fb->subdev);
+ nvkm_subdev_ctor(&nvkm_fb, device, index, &fb->subdev);
fb->func = func;
fb->tile.regions = fb->func->tile.regions;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
index 008bb9849f3b..e649ead5ccfc 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c
@@ -24,6 +24,9 @@
#include "gf100.h"
#include "ram.h"
+#include <core/memory.h>
+#include <core/option.h>
+
extern const u8 gf100_pte_storage_type_map[256];
bool
@@ -46,6 +49,28 @@ gf100_fb_intr(struct nvkm_fb *base)
nvkm_debug(subdev, "PBFB intr\n");
}
+int
+gf100_fb_oneinit(struct nvkm_fb *fb)
+{
+ struct nvkm_device *device = fb->subdev.device;
+ int ret, size = 0x1000;
+
+ size = nvkm_longopt(device->cfgopt, "MmuDebugBufferSize", size);
+ size = min(size, 0x1000);
+
+ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, size, 0x1000,
+ false, &fb->mmu_rd);
+ if (ret)
+ return ret;
+
+ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, size, 0x1000,
+ false, &fb->mmu_wr);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
void
gf100_fb_init(struct nvkm_fb *base)
{
@@ -98,6 +123,7 @@ gf100_fb_new_(const struct nvkm_fb_func *func, struct nvkm_device *device,
static const struct nvkm_fb_func
gf100_fb = {
.dtor = gf100_fb_dtor,
+ .oneinit = gf100_fb_oneinit,
.init = gf100_fb_init,
.intr = gf100_fb_intr,
.ram_new = gf100_ram_new,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c
index 0edb3c316f5c..b41f0f70038c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk104.c
@@ -27,6 +27,7 @@
static const struct nvkm_fb_func
gk104_fb = {
.dtor = gf100_fb_dtor,
+ .oneinit = gf100_fb_oneinit,
.init = gf100_fb_init,
.intr = gf100_fb_intr,
.ram_new = gk104_ram_new,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c
index 81447eb4c948..7306f7dfc3b9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c
@@ -21,15 +21,20 @@
*/
#include "priv.h"
+#include <core/memory.h>
+
static void
gk20a_fb_init(struct nvkm_fb *fb)
{
struct nvkm_device *device = fb->subdev.device;
nvkm_mask(device, 0x100c80, 0x00000001, 0x00000000); /* 128KiB lpg */
+ nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(fb->mmu_wr) >> 8);
+ nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(fb->mmu_rd) >> 8);
}
static const struct nvkm_fb_func
gk20a_fb = {
+ .oneinit = gf100_fb_oneinit,
.init = gk20a_fb_init,
.memtype_valid = gf100_fb_memtype_valid,
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c
index 2a91df8655dd..4869fdb753c9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm107.c
@@ -27,6 +27,7 @@
static const struct nvkm_fb_func
gm107_fb = {
.dtor = gf100_fb_dtor,
+ .oneinit = gf100_fb_oneinit,
.init = gf100_fb_init,
.intr = gf100_fb_intr,
.ram_new = gm107_ram_new,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c
new file mode 100644
index 000000000000..44f5716f64d8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include "gf100.h"
+#include "ram.h"
+
+#include <core/memory.h>
+
+static void
+gm200_fb_init(struct nvkm_fb *base)
+{
+ struct gf100_fb *fb = gf100_fb(base);
+ struct nvkm_device *device = fb->base.subdev.device;
+
+ if (fb->r100c10_page)
+ nvkm_wr32(device, 0x100c10, fb->r100c10 >> 8);
+
+ nvkm_mask(device, 0x100c80, 0x00000001, 0x00000000); /* 128KiB lpg */
+
+ nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(fb->base.mmu_wr) >> 8);
+ nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(fb->base.mmu_rd) >> 8);
+ nvkm_mask(device, 0x100cc4, 0x00060000,
+ min(nvkm_memory_size(fb->base.mmu_rd) >> 16, (u64)2) << 17);
+}
+
+static const struct nvkm_fb_func
+gm200_fb = {
+ .dtor = gf100_fb_dtor,
+ .oneinit = gf100_fb_oneinit,
+ .init = gm200_fb_init,
+ .intr = gf100_fb_intr,
+ .ram_new = gm107_ram_new,
+ .memtype_valid = gf100_fb_memtype_valid,
+};
+
+int
+gm200_fb_new(struct nvkm_device *device, int index, struct nvkm_fb **pfb)
+{
+ return gf100_fb_new_(&gm200_fb, device, index, pfb);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
index 62b9feb531dc..d97d640e60a0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/priv.h
@@ -6,6 +6,7 @@ struct nvkm_bios;
struct nvkm_fb_func {
void *(*dtor)(struct nvkm_fb *);
+ int (*oneinit)(struct nvkm_fb *);
void (*init)(struct nvkm_fb *);
void (*intr)(struct nvkm_fb *);
@@ -58,5 +59,6 @@ void nv44_fb_tile_prog(struct nvkm_fb *, int, struct nvkm_fb_tile *);
void nv46_fb_tile_init(struct nvkm_fb *, int i, u32 addr, u32 size,
u32 pitch, u32 flags, struct nvkm_fb_tile *);
+int gf100_fb_oneinit(struct nvkm_fb *);
bool gf100_fb_memtype_valid(struct nvkm_fb *, u32);
#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/base.c
index f4144979a79c..1c3c18ea8ced 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/base.c
@@ -47,7 +47,7 @@ nvkm_fuse_new_(const struct nvkm_fuse_func *func, struct nvkm_device *device,
struct nvkm_fuse *fuse;
if (!(fuse = *pfuse = kzalloc(sizeof(*fuse), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&nvkm_fuse, device, index, 0, &fuse->subdev);
+ nvkm_subdev_ctor(&nvkm_fuse, device, index, &fuse->subdev);
fuse->func = func;
spin_lock_init(&fuse->lock);
return 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c
index d45ec99f0e38..77c649723ad7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c
@@ -216,7 +216,7 @@ nvkm_gpio_new_(const struct nvkm_gpio_func *func, struct nvkm_device *device,
if (!(gpio = *pgpio = kzalloc(sizeof(*gpio), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&nvkm_gpio, device, index, 0, &gpio->subdev);
+ nvkm_subdev_ctor(&nvkm_gpio, device, index, &gpio->subdev);
gpio->func = func;
return nvkm_event_init(&nvkm_gpio_intr_func, 2, func->lines,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
index 243a71ff0a0d..4f197b15acf6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c
@@ -254,7 +254,7 @@ nvkm_i2c_new_(const struct nvkm_i2c_func *func, struct nvkm_device *device,
if (!(i2c = *pi2c = kzalloc(sizeof(*i2c), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&nvkm_i2c, device, index, 0, &i2c->subdev);
+ nvkm_subdev_ctor(&nvkm_i2c, device, index, &i2c->subdev);
i2c->func = func;
INIT_LIST_HEAD(&i2c->pad);
INIT_LIST_HEAD(&i2c->bus);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c
index 72d6330d243d..2c6b374f1420 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf100.c
@@ -117,6 +117,6 @@ gf100_ibus_new(struct nvkm_device *device, int index,
struct nvkm_subdev *ibus;
if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&gf100_ibus, device, index, 0, ibus);
+ nvkm_subdev_ctor(&gf100_ibus, device, index, ibus);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c
index f69f263c5906..3905a80da811 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gf117.c
@@ -46,6 +46,6 @@ gf117_ibus_new(struct nvkm_device *device, int index,
struct nvkm_subdev *ibus;
if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&gf117_ibus, device, index, 0, ibus);
+ nvkm_subdev_ctor(&gf117_ibus, device, index, ibus);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c
index b5cee3f89aaa..c673853f3213 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk104.c
@@ -120,6 +120,6 @@ gk104_ibus_new(struct nvkm_device *device, int index,
struct nvkm_subdev *ibus;
if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&gk104_ibus, device, index, 0, ibus);
+ nvkm_subdev_ctor(&gk104_ibus, device, index, ibus);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c
index 3484079e885a..b7159b338fac 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gk20a.c
@@ -84,6 +84,6 @@ gk20a_ibus_new(struct nvkm_device *device, int index,
struct nvkm_subdev *ibus;
if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&gk20a_ibus, device, index, 0, ibus);
+ nvkm_subdev_ctor(&gk20a_ibus, device, index, ibus);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c
index ef0b7f3b1128..c63328152bfa 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ibus/gm200.c
@@ -35,6 +35,6 @@ gm200_ibus_new(struct nvkm_device *device, int index,
struct nvkm_subdev *ibus;
if (!(ibus = *pibus = kzalloc(sizeof(*ibus), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&gm200_ibus, device, index, 0, ibus);
+ nvkm_subdev_ctor(&gm200_ibus, device, index, ibus);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c
index c44a85228074..323c79abe468 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c
@@ -30,15 +30,14 @@
static bool
nvkm_iccsense_validate_device(struct i2c_adapter *i2c, u8 addr,
- enum nvbios_extdev_type type, u8 rail)
+ enum nvbios_extdev_type type)
{
switch (type) {
case NVBIOS_EXTDEV_INA209:
case NVBIOS_EXTDEV_INA219:
- return rail == 0 && nv_rd16i2cr(i2c, addr, 0x0) >= 0;
+ return nv_rd16i2cr(i2c, addr, 0x0) >= 0;
case NVBIOS_EXTDEV_INA3221:
- return rail <= 3 &&
- nv_rd16i2cr(i2c, addr, 0xff) == 0x3220 &&
+ return nv_rd16i2cr(i2c, addr, 0xff) == 0x3220 &&
nv_rd16i2cr(i2c, addr, 0xfe) == 0x5449;
default:
return false;
@@ -67,8 +66,9 @@ nvkm_iccsense_ina2x9_read(struct nvkm_iccsense *iccsense,
struct nvkm_iccsense_rail *rail,
u8 shunt_reg, u8 bus_reg)
{
- return nvkm_iccsense_poll_lane(rail->i2c, rail->addr, shunt_reg, 0,
- bus_reg, 3, rail->mohm, 10 * 4);
+ return nvkm_iccsense_poll_lane(rail->sensor->i2c, rail->sensor->addr,
+ shunt_reg, 0, bus_reg, 3, rail->mohm,
+ 10 * 4);
}
static int
@@ -89,37 +89,87 @@ static int
nvkm_iccsense_ina3221_read(struct nvkm_iccsense *iccsense,
struct nvkm_iccsense_rail *rail)
{
- return nvkm_iccsense_poll_lane(rail->i2c, rail->addr,
- 1 + (rail->rail * 2), 3,
- 2 + (rail->rail * 2), 3, rail->mohm,
+ return nvkm_iccsense_poll_lane(rail->sensor->i2c, rail->sensor->addr,
+ 1 + (rail->idx * 2), 3,
+ 2 + (rail->idx * 2), 3, rail->mohm,
40 * 8);
}
-int
-nvkm_iccsense_read(struct nvkm_iccsense *iccsense, u8 idx)
+static void
+nvkm_iccsense_ina209_config(struct nvkm_iccsense *iccsense,
+ struct nvkm_iccsense_sensor *sensor)
{
- struct nvkm_iccsense_rail *rail;
-
- if (!iccsense || idx >= iccsense->rail_count)
- return -EINVAL;
+ struct nvkm_subdev *subdev = &iccsense->subdev;
+ /* configuration:
+ * 0x0007: 0x0007 shunt and bus continous
+ * 0x0078: 0x0078 128 samples shunt
+ * 0x0780: 0x0780 128 samples bus
+ * 0x1800: 0x0000 +-40 mV shunt range
+ * 0x2000: 0x0000 16V FSR
+ */
+ u16 value = 0x07ff;
+ nvkm_debug(subdev, "config for sensor id %i: 0x%x\n", sensor->id, value);
+ nv_wr16i2cr(sensor->i2c, sensor->addr, 0x00, value);
+}
- rail = &iccsense->rails[idx];
- if (!rail->read)
- return -ENODEV;
+static void
+nvkm_iccsense_ina3221_config(struct nvkm_iccsense *iccsense,
+ struct nvkm_iccsense_sensor *sensor)
+{
+ struct nvkm_subdev *subdev = &iccsense->subdev;
+ /* configuration:
+ * 0x0007: 0x0007 shunt and bus continous
+ * 0x0031: 0x0000 140 us conversion time shunt
+ * 0x01c0: 0x0000 140 us conversion time bus
+ * 0x0f00: 0x0f00 1024 samples
+ * 0x7000: 0x?000 channels
+ */
+ u16 value = 0x0e07;
+ if (sensor->rail_mask & 0x1)
+ value |= 0x1 << 14;
+ if (sensor->rail_mask & 0x2)
+ value |= 0x1 << 13;
+ if (sensor->rail_mask & 0x4)
+ value |= 0x1 << 12;
+ nvkm_debug(subdev, "config for sensor id %i: 0x%x\n", sensor->id, value);
+ nv_wr16i2cr(sensor->i2c, sensor->addr, 0x00, value);
+}
- return rail->read(iccsense, rail);
+static void
+nvkm_iccsense_sensor_config(struct nvkm_iccsense *iccsense,
+ struct nvkm_iccsense_sensor *sensor)
+{
+ switch (sensor->type) {
+ case NVBIOS_EXTDEV_INA209:
+ case NVBIOS_EXTDEV_INA219:
+ nvkm_iccsense_ina209_config(iccsense, sensor);
+ break;
+ case NVBIOS_EXTDEV_INA3221:
+ nvkm_iccsense_ina3221_config(iccsense, sensor);
+ break;
+ default:
+ break;
+ }
}
int
nvkm_iccsense_read_all(struct nvkm_iccsense *iccsense)
{
- int result = 0, i;
- for (i = 0; i < iccsense->rail_count; ++i) {
- int res = nvkm_iccsense_read(iccsense, i);
- if (res >= 0)
- result += res;
- else
+ int result = 0;
+ struct nvkm_iccsense_rail *rail;
+
+ if (!iccsense)
+ return -EINVAL;
+
+ list_for_each_entry(rail, &iccsense->rails, head) {
+ int res;
+ if (!rail->read)
+ return -ENODEV;
+
+ res = rail->read(iccsense, rail);
+ if (res < 0)
return res;
+ result += res;
}
return result;
}
@@ -128,89 +178,158 @@ static void *
nvkm_iccsense_dtor(struct nvkm_subdev *subdev)
{
struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev);
+ struct nvkm_iccsense_sensor *sensor, *tmps;
+ struct nvkm_iccsense_rail *rail, *tmpr;
- if (iccsense->rails)
- kfree(iccsense->rails);
+ list_for_each_entry_safe(sensor, tmps, &iccsense->sensors, head) {
+ list_del(&sensor->head);
+ kfree(sensor);
+ }
+ list_for_each_entry_safe(rail, tmpr, &iccsense->rails, head) {
+ list_del(&rail->head);
+ kfree(rail);
+ }
return iccsense;
}
+static struct nvkm_iccsense_sensor*
+nvkm_iccsense_create_sensor(struct nvkm_iccsense *iccsense, u8 id)
+{
+
+ struct nvkm_subdev *subdev = &iccsense->subdev;
+ struct nvkm_bios *bios = subdev->device->bios;
+ struct nvkm_i2c *i2c = subdev->device->i2c;
+ struct nvbios_extdev_func extdev;
+ struct nvkm_i2c_bus *i2c_bus;
+ struct nvkm_iccsense_sensor *sensor;
+ u8 addr;
+
+ if (!i2c || !bios || nvbios_extdev_parse(bios, id, &extdev))
+ return NULL;
+
+ if (extdev.type == 0xff)
+ return NULL;
+
+ if (extdev.type != NVBIOS_EXTDEV_INA209 &&
+ extdev.type != NVBIOS_EXTDEV_INA219 &&
+ extdev.type != NVBIOS_EXTDEV_INA3221) {
+ iccsense->data_valid = false;
+ nvkm_error(subdev, "Unknown sensor type %x, power reading "
+ "disabled\n", extdev.type);
+ return NULL;
+ }
+
+ if (extdev.bus)
+ i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_SEC);
+ else
+ i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_PRI);
+ if (!i2c_bus)
+ return NULL;
+
+ addr = extdev.addr >> 1;
+ if (!nvkm_iccsense_validate_device(&i2c_bus->i2c, addr,
+ extdev.type)) {
+ iccsense->data_valid = false;
+ nvkm_warn(subdev, "found invalid sensor id: %i, power reading"
+ "might be invalid\n", id);
+ return NULL;
+ }
+
+ sensor = kmalloc(sizeof(*sensor), GFP_KERNEL);
+ if (!sensor)
+ return NULL;
+
+ list_add_tail(&sensor->head, &iccsense->sensors);
+ sensor->id = id;
+ sensor->type = extdev.type;
+ sensor->i2c = &i2c_bus->i2c;
+ sensor->addr = addr;
+ sensor->rail_mask = 0x0;
+ return sensor;
+}
+
+static struct nvkm_iccsense_sensor*
+nvkm_iccsense_get_sensor(struct nvkm_iccsense *iccsense, u8 id)
+{
+ struct nvkm_iccsense_sensor *sensor;
+ list_for_each_entry(sensor, &iccsense->sensors, head) {
+ if (sensor->id == id)
+ return sensor;
+ }
+ return nvkm_iccsense_create_sensor(iccsense, id);
+}
+
static int
nvkm_iccsense_oneinit(struct nvkm_subdev *subdev)
{
struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev);
struct nvkm_bios *bios = subdev->device->bios;
- struct nvkm_i2c *i2c = subdev->device->i2c;
struct nvbios_iccsense stbl;
int i;
- if (!i2c || !bios || nvbios_iccsense_parse(bios, &stbl)
- || !stbl.nr_entry)
+ if (!bios || nvbios_iccsense_parse(bios, &stbl) || !stbl.nr_entry)
return 0;
- iccsense->rails = kmalloc(sizeof(*iccsense->rails) * stbl.nr_entry,
- GFP_KERNEL);
- if (!iccsense->rails)
- return -ENOMEM;
-
iccsense->data_valid = true;
for (i = 0; i < stbl.nr_entry; ++i) {
struct pwr_rail_t *r = &stbl.rail[i];
- struct nvbios_extdev_func extdev;
struct nvkm_iccsense_rail *rail;
- struct nvkm_i2c_bus *i2c_bus;
- u8 addr;
+ struct nvkm_iccsense_sensor *sensor;
if (!r->mode || r->resistor_mohm == 0)
continue;
- if (nvbios_extdev_parse(bios, r->extdev_id, &extdev))
+ sensor = nvkm_iccsense_get_sensor(iccsense, r->extdev_id);
+ if (!sensor)
continue;
- if (extdev.type == 0xff)
- continue;
+ rail = kmalloc(sizeof(*rail), GFP_KERNEL);
+ if (!rail)
+ return -ENOMEM;
- if (extdev.bus)
- i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_SEC);
- else
- i2c_bus = nvkm_i2c_bus_find(i2c, NVKM_I2C_BUS_PRI);
- if (!i2c_bus)
- continue;
-
- addr = extdev.addr >> 1;
- if (!nvkm_iccsense_validate_device(&i2c_bus->i2c, addr,
- extdev.type, r->rail)) {
- iccsense->data_valid = false;
- nvkm_warn(subdev, "found unknown or invalid rail entry"
- " type 0x%x rail %i, power reading might be"
- " invalid\n", extdev.type, r->rail);
- continue;
- }
-
- rail = &iccsense->rails[iccsense->rail_count];
- switch (extdev.type) {
+ switch (sensor->type) {
case NVBIOS_EXTDEV_INA209:
+ if (r->rail != 0)
+ continue;
rail->read = nvkm_iccsense_ina209_read;
break;
case NVBIOS_EXTDEV_INA219:
+ if (r->rail != 0)
+ continue;
rail->read = nvkm_iccsense_ina219_read;
break;
case NVBIOS_EXTDEV_INA3221:
+ if (r->rail >= 3)
+ continue;
rail->read = nvkm_iccsense_ina3221_read;
break;
+ default:
+ continue;
}
- rail->addr = addr;
- rail->rail = r->rail;
+ sensor->rail_mask |= 1 << r->rail;
+ rail->sensor = sensor;
+ rail->idx = r->rail;
rail->mohm = r->resistor_mohm;
- rail->i2c = &i2c_bus->i2c;
- ++iccsense->rail_count;
+ list_add_tail(&rail->head, &iccsense->rails);
}
return 0;
}
+static int
+nvkm_iccsense_init(struct nvkm_subdev *subdev)
+{
+ struct nvkm_iccsense *iccsense = nvkm_iccsense(subdev);
+ struct nvkm_iccsense_sensor *sensor;
+ list_for_each_entry(sensor, &iccsense->sensors, head)
+ nvkm_iccsense_sensor_config(iccsense, sensor);
+ return 0;
+}
+
struct nvkm_subdev_func iccsense_func = {
.oneinit = nvkm_iccsense_oneinit,
+ .init = nvkm_iccsense_init,
.dtor = nvkm_iccsense_dtor,
};
@@ -218,7 +337,7 @@ void
nvkm_iccsense_ctor(struct nvkm_device *device, int index,
struct nvkm_iccsense *iccsense)
{
- nvkm_subdev_ctor(&iccsense_func, device, index, 0, &iccsense->subdev);
+ nvkm_subdev_ctor(&iccsense_func, device, index, &iccsense->subdev);
}
int
@@ -227,6 +346,8 @@ nvkm_iccsense_new_(struct nvkm_device *device, int index,
{
if (!(*iccsense = kzalloc(sizeof(**iccsense), GFP_KERNEL)))
return -ENOMEM;
+ INIT_LIST_HEAD(&(*iccsense)->sensors);
+ INIT_LIST_HEAD(&(*iccsense)->rails);
nvkm_iccsense_ctor(device, index, *iccsense);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/priv.h
index ed398b81e86e..b72c31d2f908 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/priv.h
@@ -2,12 +2,22 @@
#define __NVKM_ICCSENSE_PRIV_H__
#define nvkm_iccsense(p) container_of((p), struct nvkm_iccsense, subdev)
#include <subdev/iccsense.h>
+#include <subdev/bios/extdev.h>
-struct nvkm_iccsense_rail {
- int (*read)(struct nvkm_iccsense *, struct nvkm_iccsense_rail *);
+struct nvkm_iccsense_sensor {
+ struct list_head head;
+ int id;
+ enum nvbios_extdev_type type;
struct i2c_adapter *i2c;
u8 addr;
- u8 rail;
+ u8 rail_mask;
+};
+
+struct nvkm_iccsense_rail {
+ struct list_head head;
+ int (*read)(struct nvkm_iccsense *, struct nvkm_iccsense_rail *);
+ struct nvkm_iccsense_sensor *sensor;
+ u8 idx;
u8 mohm;
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
index 1d7dd38292b3..8ed8f65ff664 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
@@ -311,7 +311,7 @@ nvkm_instmem_ctor(const struct nvkm_instmem_func *func,
struct nvkm_device *device, int index,
struct nvkm_instmem *imem)
{
- nvkm_subdev_ctor(&nvkm_instmem, device, index, 0, &imem->subdev);
+ nvkm_subdev_ctor(&nvkm_instmem, device, index, &imem->subdev);
imem->func = func;
spin_lock_init(&imem->lock);
INIT_LIST_HEAD(&imem->list);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c
index 85b1464c0194..39c2a38e54f7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c
@@ -138,7 +138,7 @@ nvkm_ltc_new_(const struct nvkm_ltc_func *func, struct nvkm_device *device,
if (!(ltc = *pltc = kzalloc(sizeof(*ltc), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&nvkm_ltc, device, index, 0, &ltc->subdev);
+ nvkm_subdev_ctor(&nvkm_ltc, device, index, &ltc->subdev);
ltc->func = func;
ltc->zbc_min = 1; /* reserve 0 for disabled */
ltc->zbc_max = min(func->zbc, NVKM_LTC_MAX_ZBC_CNT) - 1;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild
index bef325dcb4d0..49695ac7be2e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild
@@ -1,7 +1,12 @@
nvkm-y += nvkm/subdev/mc/base.o
nvkm-y += nvkm/subdev/mc/nv04.o
+nvkm-y += nvkm/subdev/mc/nv11.o
+nvkm-y += nvkm/subdev/mc/nv17.o
nvkm-y += nvkm/subdev/mc/nv44.o
nvkm-y += nvkm/subdev/mc/nv50.o
+nvkm-y += nvkm/subdev/mc/g84.o
nvkm-y += nvkm/subdev/mc/g98.o
+nvkm-y += nvkm/subdev/mc/gt215.o
nvkm-y += nvkm/subdev/mc/gf100.o
+nvkm-y += nvkm/subdev/mc/gk104.o
nvkm-y += nvkm/subdev/mc/gk20a.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c
index 954fbbe56c4b..350a8caa84c8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c
@@ -24,6 +24,7 @@
#include "priv.h"
#include <core/option.h>
+#include <subdev/top.h>
void
nvkm_mc_unk260(struct nvkm_mc *mc, u32 data)
@@ -58,10 +59,19 @@ nvkm_mc_intr(struct nvkm_mc *mc, bool *handled)
{
struct nvkm_device *device = mc->subdev.device;
struct nvkm_subdev *subdev;
- const struct nvkm_mc_intr *map = mc->func->intr;
- u32 stat, intr;
+ const struct nvkm_mc_map *map = mc->func->intr;
+ u32 stat, intr = nvkm_mc_intr_mask(mc);
+ u64 subdevs;
+
+ stat = nvkm_top_intr(device->top, intr, &subdevs);
+ while (subdevs) {
+ enum nvkm_devidx subidx = __ffs64(subdevs);
+ subdev = nvkm_device_subdev(device, subidx);
+ if (subdev)
+ nvkm_subdev_intr(subdev);
+ subdevs &= ~BIT_ULL(subidx);
+ }
- stat = intr = nvkm_mc_intr_mask(mc);
while (map->stat) {
if (intr & map->stat) {
subdev = nvkm_device_subdev(device, map->unit);
@@ -77,6 +87,36 @@ nvkm_mc_intr(struct nvkm_mc *mc, bool *handled)
*handled = intr != 0;
}
+static void
+nvkm_mc_reset_(struct nvkm_mc *mc, enum nvkm_devidx devidx)
+{
+ struct nvkm_device *device = mc->subdev.device;
+ const struct nvkm_mc_map *map;
+ u64 pmc_enable;
+
+ if (!(pmc_enable = nvkm_top_reset(device->top, devidx))) {
+ for (map = mc->func->reset; map && map->stat; map++) {
+ if (map->unit == devidx) {
+ pmc_enable = map->stat;
+ break;
+ }
+ }
+ }
+
+ if (pmc_enable) {
+ nvkm_mask(device, 0x000200, pmc_enable, 0x00000000);
+ nvkm_mask(device, 0x000200, pmc_enable, pmc_enable);
+ nvkm_rd32(device, 0x000200);
+ }
+}
+
+void
+nvkm_mc_reset(struct nvkm_mc *mc, enum nvkm_devidx devidx)
+{
+ if (likely(mc))
+ nvkm_mc_reset_(mc, devidx);
+}
+
static int
nvkm_mc_fini(struct nvkm_subdev *subdev, bool suspend)
{
@@ -117,7 +157,7 @@ nvkm_mc_new_(const struct nvkm_mc_func *func, struct nvkm_device *device,
if (!(mc = *pmc = kzalloc(sizeof(*mc), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&nvkm_mc, device, index, 0, &mc->subdev);
+ nvkm_subdev_ctor(&nvkm_mc, device, index, &mc->subdev);
mc->func = func;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g84.c
new file mode 100644
index 000000000000..5c85b47f071d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g84.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include "priv.h"
+
+static const struct nvkm_mc_map
+g84_mc_reset[] = {
+ { 0x04008000, NVKM_ENGINE_BSP },
+ { 0x02004000, NVKM_ENGINE_CIPHER },
+ { 0x01020000, NVKM_ENGINE_VP },
+ { 0x00400002, NVKM_ENGINE_MPEG },
+ { 0x00201000, NVKM_ENGINE_GR },
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ {}
+};
+
+const struct nvkm_mc_map
+g84_mc_intr[] = {
+ { 0x04000000, NVKM_ENGINE_DISP },
+ { 0x00020000, NVKM_ENGINE_VP },
+ { 0x00008000, NVKM_ENGINE_BSP },
+ { 0x00004000, NVKM_ENGINE_CIPHER },
+ { 0x00001000, NVKM_ENGINE_GR },
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ { 0x00000001, NVKM_ENGINE_MPEG },
+ { 0x0002d101, NVKM_SUBDEV_FB },
+ { 0x10000000, NVKM_SUBDEV_BUS },
+ { 0x00200000, NVKM_SUBDEV_GPIO },
+ { 0x00200000, NVKM_SUBDEV_I2C },
+ { 0x00100000, NVKM_SUBDEV_TIMER },
+ {},
+};
+
+static const struct nvkm_mc_func
+g84_mc = {
+ .init = nv50_mc_init,
+ .intr = g84_mc_intr,
+ .intr_unarm = nv04_mc_intr_unarm,
+ .intr_rearm = nv04_mc_intr_rearm,
+ .intr_mask = nv04_mc_intr_mask,
+ .reset = g84_mc_reset,
+};
+
+int
+g84_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
+{
+ return nvkm_mc_new_(&g84_mc, device, index, pmc);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c
index 7344ad659105..0280b43cc10c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c
@@ -23,24 +23,31 @@
*/
#include "priv.h"
-static const struct nvkm_mc_intr
-g98_mc_intr[] = {
- { 0x04000000, NVKM_ENGINE_DISP }, /* DISP first, so pageflip timestamps work */
- { 0x00000001, NVKM_ENGINE_MSPPP },
+static const struct nvkm_mc_map
+g98_mc_reset[] = {
+ { 0x04008000, NVKM_ENGINE_MSVLD },
+ { 0x02004000, NVKM_ENGINE_SEC },
+ { 0x01020000, NVKM_ENGINE_MSPDEC },
+ { 0x00400002, NVKM_ENGINE_MSPPP },
+ { 0x00201000, NVKM_ENGINE_GR },
{ 0x00000100, NVKM_ENGINE_FIFO },
- { 0x00001000, NVKM_ENGINE_GR },
- { 0x00004000, NVKM_ENGINE_SEC }, /* NV84:NVA3 */
- { 0x00008000, NVKM_ENGINE_MSVLD },
+ {}
+};
+
+static const struct nvkm_mc_map
+g98_mc_intr[] = {
+ { 0x04000000, NVKM_ENGINE_DISP },
{ 0x00020000, NVKM_ENGINE_MSPDEC },
- { 0x00040000, NVKM_SUBDEV_PMU }, /* NVA3:NVC0 */
- { 0x00080000, NVKM_SUBDEV_THERM }, /* NVA3:NVC0 */
- { 0x00100000, NVKM_SUBDEV_TIMER },
- { 0x00200000, NVKM_SUBDEV_GPIO }, /* PMGR->GPIO */
- { 0x00200000, NVKM_SUBDEV_I2C }, /* PMGR->I2C/AUX */
- { 0x00400000, NVKM_ENGINE_CE0 }, /* NVA3- */
+ { 0x00008000, NVKM_ENGINE_MSVLD },
+ { 0x00004000, NVKM_ENGINE_SEC },
+ { 0x00001000, NVKM_ENGINE_GR },
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ { 0x00000001, NVKM_ENGINE_MSPPP },
+ { 0x0002d101, NVKM_SUBDEV_FB },
{ 0x10000000, NVKM_SUBDEV_BUS },
- { 0x80000000, NVKM_ENGINE_SW },
- { 0x0042d101, NVKM_SUBDEV_FB },
+ { 0x00200000, NVKM_SUBDEV_GPIO },
+ { 0x00200000, NVKM_SUBDEV_I2C },
+ { 0x00100000, NVKM_SUBDEV_TIMER },
{},
};
@@ -51,6 +58,7 @@ g98_mc = {
.intr_unarm = nv04_mc_intr_unarm,
.intr_rearm = nv04_mc_intr_rearm,
.intr_mask = nv04_mc_intr_mask,
+ .reset = g98_mc_reset,
};
int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
index 122fe69e83e4..8397e223bd43 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
@@ -23,28 +23,38 @@
*/
#include "priv.h"
-const struct nvkm_mc_intr
-gf100_mc_intr[] = {
- { 0x04000000, NVKM_ENGINE_DISP }, /* DISP first, so pageflip timestamps work. */
- { 0x00000001, NVKM_ENGINE_MSPPP },
- { 0x00000020, NVKM_ENGINE_CE0 },
- { 0x00000040, NVKM_ENGINE_CE1 },
- { 0x00000080, NVKM_ENGINE_CE2 },
- { 0x00000100, NVKM_ENGINE_FIFO },
- { 0x00001000, NVKM_ENGINE_GR },
- { 0x00002000, NVKM_SUBDEV_FB },
+static const struct nvkm_mc_map
+gf100_mc_reset[] = {
+ { 0x00020000, NVKM_ENGINE_MSPDEC },
{ 0x00008000, NVKM_ENGINE_MSVLD },
- { 0x00040000, NVKM_SUBDEV_THERM },
+ { 0x00001000, NVKM_ENGINE_GR },
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ { 0x00000080, NVKM_ENGINE_CE1 },
+ { 0x00000040, NVKM_ENGINE_CE0 },
+ { 0x00000002, NVKM_ENGINE_MSPPP },
+ {}
+};
+
+static const struct nvkm_mc_map
+gf100_mc_intr[] = {
+ { 0x04000000, NVKM_ENGINE_DISP },
{ 0x00020000, NVKM_ENGINE_MSPDEC },
- { 0x00100000, NVKM_SUBDEV_TIMER },
- { 0x00200000, NVKM_SUBDEV_GPIO }, /* PMGR->GPIO */
- { 0x00200000, NVKM_SUBDEV_I2C }, /* PMGR->I2C/AUX */
- { 0x01000000, NVKM_SUBDEV_PMU },
- { 0x02000000, NVKM_SUBDEV_LTC },
- { 0x08000000, NVKM_SUBDEV_FB },
- { 0x10000000, NVKM_SUBDEV_BUS },
+ { 0x00008000, NVKM_ENGINE_MSVLD },
+ { 0x00001000, NVKM_ENGINE_GR },
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ { 0x00000040, NVKM_ENGINE_CE1 },
+ { 0x00000020, NVKM_ENGINE_CE0 },
+ { 0x00000001, NVKM_ENGINE_MSPPP },
{ 0x40000000, NVKM_SUBDEV_IBUS },
- { 0x80000000, NVKM_ENGINE_SW },
+ { 0x10000000, NVKM_SUBDEV_BUS },
+ { 0x08000000, NVKM_SUBDEV_FB },
+ { 0x02000000, NVKM_SUBDEV_LTC },
+ { 0x01000000, NVKM_SUBDEV_PMU },
+ { 0x00200000, NVKM_SUBDEV_GPIO },
+ { 0x00200000, NVKM_SUBDEV_I2C },
+ { 0x00100000, NVKM_SUBDEV_TIMER },
+ { 0x00040000, NVKM_SUBDEV_THERM },
+ { 0x00002000, NVKM_SUBDEV_FB },
{},
};
@@ -87,6 +97,7 @@ gf100_mc = {
.intr_unarm = gf100_mc_intr_unarm,
.intr_rearm = gf100_mc_intr_rearm,
.intr_mask = gf100_mc_intr_mask,
+ .reset = gf100_mc_reset,
.unk260 = gf100_mc_unk260,
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk104.c
new file mode 100644
index 000000000000..317464212c7d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk104.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2016 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include "priv.h"
+
+const struct nvkm_mc_map
+gk104_mc_reset[] = {
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ {}
+};
+
+const struct nvkm_mc_map
+gk104_mc_intr[] = {
+ { 0x04000000, NVKM_ENGINE_DISP },
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ { 0x40000000, NVKM_SUBDEV_IBUS },
+ { 0x10000000, NVKM_SUBDEV_BUS },
+ { 0x08000000, NVKM_SUBDEV_FB },
+ { 0x02000000, NVKM_SUBDEV_LTC },
+ { 0x01000000, NVKM_SUBDEV_PMU },
+ { 0x00200000, NVKM_SUBDEV_GPIO },
+ { 0x00200000, NVKM_SUBDEV_I2C },
+ { 0x00100000, NVKM_SUBDEV_TIMER },
+ { 0x00040000, NVKM_SUBDEV_THERM },
+ { 0x00002000, NVKM_SUBDEV_FB },
+ {},
+};
+
+static const struct nvkm_mc_func
+gk104_mc = {
+ .init = nv50_mc_init,
+ .intr = gk104_mc_intr,
+ .intr_unarm = gf100_mc_intr_unarm,
+ .intr_rearm = gf100_mc_intr_rearm,
+ .intr_mask = gf100_mc_intr_mask,
+ .reset = gk104_mc_reset,
+ .unk260 = gf100_mc_unk260,
+};
+
+int
+gk104_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
+{
+ return nvkm_mc_new_(&gk104_mc, device, index, pmc);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c
index d92efb33bcc3..60b044f517ed 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c
@@ -26,10 +26,11 @@
static const struct nvkm_mc_func
gk20a_mc = {
.init = nv50_mc_init,
- .intr = gf100_mc_intr,
+ .intr = gk104_mc_intr,
.intr_unarm = gf100_mc_intr_unarm,
.intr_rearm = gf100_mc_intr_rearm,
.intr_mask = gf100_mc_intr_mask,
+ .reset = gk104_mc_reset,
};
int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gt215.c
new file mode 100644
index 000000000000..aad0ba95bf18
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gt215.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2016 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+#include "priv.h"
+
+static const struct nvkm_mc_map
+gt215_mc_reset[] = {
+ { 0x04008000, NVKM_ENGINE_MSVLD },
+ { 0x01020000, NVKM_ENGINE_MSPDEC },
+ { 0x00802000, NVKM_ENGINE_CE0 },
+ { 0x00400002, NVKM_ENGINE_MSPPP },
+ { 0x00201000, NVKM_ENGINE_GR },
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ {}
+};
+
+static const struct nvkm_mc_map
+gt215_mc_intr[] = {
+ { 0x04000000, NVKM_ENGINE_DISP },
+ { 0x00400000, NVKM_ENGINE_CE0 },
+ { 0x00020000, NVKM_ENGINE_MSPDEC },
+ { 0x00008000, NVKM_ENGINE_MSVLD },
+ { 0x00001000, NVKM_ENGINE_GR },
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ { 0x00000001, NVKM_ENGINE_MSPPP },
+ { 0x00429101, NVKM_SUBDEV_FB },
+ { 0x10000000, NVKM_SUBDEV_BUS },
+ { 0x00200000, NVKM_SUBDEV_GPIO },
+ { 0x00200000, NVKM_SUBDEV_I2C },
+ { 0x00100000, NVKM_SUBDEV_TIMER },
+ { 0x00080000, NVKM_SUBDEV_THERM },
+ { 0x00040000, NVKM_SUBDEV_PMU },
+ {},
+};
+
+static const struct nvkm_mc_func
+gt215_mc = {
+ .init = nv50_mc_init,
+ .intr = gt215_mc_intr,
+ .intr_unarm = nv04_mc_intr_unarm,
+ .intr_rearm = nv04_mc_intr_rearm,
+ .intr_mask = nv04_mc_intr_mask,
+ .reset = gt215_mc_reset,
+};
+
+int
+gt215_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
+{
+ return nvkm_mc_new_(&gt215_mc, device, index, pmc);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c
index d282ec1555f8..a062624e906b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv04.c
@@ -23,18 +23,20 @@
*/
#include "priv.h"
-const struct nvkm_mc_intr
-nv04_mc_intr[] = {
- { 0x00000001, NVKM_ENGINE_MPEG }, /* NV17- MPEG/ME */
+const struct nvkm_mc_map
+nv04_mc_reset[] = {
+ { 0x00001000, NVKM_ENGINE_GR },
{ 0x00000100, NVKM_ENGINE_FIFO },
+ {}
+};
+
+static const struct nvkm_mc_map
+nv04_mc_intr[] = {
+ { 0x01010000, NVKM_ENGINE_DISP },
{ 0x00001000, NVKM_ENGINE_GR },
- { 0x00010000, NVKM_ENGINE_DISP },
- { 0x00020000, NVKM_ENGINE_VP }, /* NV40- */
- { 0x00100000, NVKM_SUBDEV_TIMER },
- { 0x01000000, NVKM_ENGINE_DISP }, /* NV04- PCRTC0 */
- { 0x02000000, NVKM_ENGINE_DISP }, /* NV11- PCRTC1 */
+ { 0x00000100, NVKM_ENGINE_FIFO },
{ 0x10000000, NVKM_SUBDEV_BUS },
- { 0x80000000, NVKM_ENGINE_SW },
+ { 0x00100000, NVKM_SUBDEV_TIMER },
{}
};
@@ -74,6 +76,7 @@ nv04_mc = {
.intr_unarm = nv04_mc_intr_unarm,
.intr_rearm = nv04_mc_intr_rearm,
.intr_mask = nv04_mc_intr_mask,
+ .reset = nv04_mc_reset,
};
int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv11.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv11.c
new file mode 100644
index 000000000000..55f0b9166b52
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv11.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2016 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+#include "priv.h"
+
+static const struct nvkm_mc_map
+nv11_mc_intr[] = {
+ { 0x03010000, NVKM_ENGINE_DISP },
+ { 0x00001000, NVKM_ENGINE_GR },
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ { 0x10000000, NVKM_SUBDEV_BUS },
+ { 0x00100000, NVKM_SUBDEV_TIMER },
+ {}
+};
+
+static const struct nvkm_mc_func
+nv11_mc = {
+ .init = nv04_mc_init,
+ .intr = nv11_mc_intr,
+ .intr_unarm = nv04_mc_intr_unarm,
+ .intr_rearm = nv04_mc_intr_rearm,
+ .intr_mask = nv04_mc_intr_mask,
+ .reset = nv04_mc_reset,
+};
+
+int
+nv11_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
+{
+ return nvkm_mc_new_(&nv11_mc, device, index, pmc);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv17.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv17.c
new file mode 100644
index 000000000000..c40fa67f79a5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv17.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2016 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+#include "priv.h"
+
+const struct nvkm_mc_map
+nv17_mc_reset[] = {
+ { 0x00001000, NVKM_ENGINE_GR },
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ { 0x00000002, NVKM_ENGINE_MPEG },
+ {}
+};
+
+const struct nvkm_mc_map
+nv17_mc_intr[] = {
+ { 0x03010000, NVKM_ENGINE_DISP },
+ { 0x00001000, NVKM_ENGINE_GR },
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ { 0x00000001, NVKM_ENGINE_MPEG },
+ { 0x10000000, NVKM_SUBDEV_BUS },
+ { 0x00100000, NVKM_SUBDEV_TIMER },
+ {}
+};
+
+static const struct nvkm_mc_func
+nv17_mc = {
+ .init = nv04_mc_init,
+ .intr = nv17_mc_intr,
+ .intr_unarm = nv04_mc_intr_unarm,
+ .intr_rearm = nv04_mc_intr_rearm,
+ .intr_mask = nv04_mc_intr_mask,
+ .reset = nv17_mc_reset,
+};
+
+int
+nv17_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
+{
+ return nvkm_mc_new_(&nv17_mc, device, index, pmc);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c
index 9a3ac9965be0..cc56271db564 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c
@@ -40,10 +40,11 @@ nv44_mc_init(struct nvkm_mc *mc)
static const struct nvkm_mc_func
nv44_mc = {
.init = nv44_mc_init,
- .intr = nv04_mc_intr,
+ .intr = nv17_mc_intr,
.intr_unarm = nv04_mc_intr_unarm,
.intr_rearm = nv04_mc_intr_rearm,
.intr_mask = nv04_mc_intr_mask,
+ .reset = nv17_mc_reset,
};
int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c
index 5f27d7b8fddd..343b6078580d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c
@@ -23,21 +23,17 @@
*/
#include "priv.h"
-const struct nvkm_mc_intr
+static const struct nvkm_mc_map
nv50_mc_intr[] = {
- { 0x04000000, NVKM_ENGINE_DISP }, /* DISP before FIFO, so pageflip-timestamping works! */
- { 0x00000001, NVKM_ENGINE_MPEG },
- { 0x00000100, NVKM_ENGINE_FIFO },
+ { 0x04000000, NVKM_ENGINE_DISP },
{ 0x00001000, NVKM_ENGINE_GR },
- { 0x00004000, NVKM_ENGINE_CIPHER }, /* NV84- */
- { 0x00008000, NVKM_ENGINE_BSP }, /* NV84- */
- { 0x00020000, NVKM_ENGINE_VP }, /* NV84- */
- { 0x00100000, NVKM_SUBDEV_TIMER },
- { 0x00200000, NVKM_SUBDEV_GPIO }, /* PMGR->GPIO */
- { 0x00200000, NVKM_SUBDEV_I2C }, /* PMGR->I2C/AUX */
+ { 0x00000100, NVKM_ENGINE_FIFO },
+ { 0x00000001, NVKM_ENGINE_MPEG },
+ { 0x00001101, NVKM_SUBDEV_FB },
{ 0x10000000, NVKM_SUBDEV_BUS },
- { 0x80000000, NVKM_ENGINE_SW },
- { 0x0002d101, NVKM_SUBDEV_FB },
+ { 0x00200000, NVKM_SUBDEV_GPIO },
+ { 0x00200000, NVKM_SUBDEV_I2C },
+ { 0x00100000, NVKM_SUBDEV_TIMER },
{},
};
@@ -55,6 +51,7 @@ nv50_mc = {
.intr_unarm = nv04_mc_intr_unarm,
.intr_rearm = nv04_mc_intr_rearm,
.intr_mask = nv04_mc_intr_mask,
+ .reset = nv17_mc_reset,
};
int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h
index 307f6c692287..a12038118512 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h
@@ -6,37 +6,42 @@
int nvkm_mc_new_(const struct nvkm_mc_func *, struct nvkm_device *,
int index, struct nvkm_mc **);
-struct nvkm_mc_intr {
+struct nvkm_mc_map {
u32 stat;
u32 unit;
};
struct nvkm_mc_func {
void (*init)(struct nvkm_mc *);
- const struct nvkm_mc_intr *intr;
+ const struct nvkm_mc_map *intr;
/* disable reporting of interrupts to host */
void (*intr_unarm)(struct nvkm_mc *);
/* enable reporting of interrupts to host */
void (*intr_rearm)(struct nvkm_mc *);
/* retrieve pending interrupt mask (NV_PMC_INTR) */
u32 (*intr_mask)(struct nvkm_mc *);
+ const struct nvkm_mc_map *reset;
void (*unk260)(struct nvkm_mc *, u32);
};
void nv04_mc_init(struct nvkm_mc *);
-extern const struct nvkm_mc_intr nv04_mc_intr[];
void nv04_mc_intr_unarm(struct nvkm_mc *);
void nv04_mc_intr_rearm(struct nvkm_mc *);
u32 nv04_mc_intr_mask(struct nvkm_mc *);
+extern const struct nvkm_mc_map nv04_mc_reset[];
+
+extern const struct nvkm_mc_map nv17_mc_intr[];
+extern const struct nvkm_mc_map nv17_mc_reset[];
void nv44_mc_init(struct nvkm_mc *);
void nv50_mc_init(struct nvkm_mc *);
-extern const struct nvkm_mc_intr nv50_mc_intr[];
-extern const struct nvkm_mc_intr gf100_mc_intr[];
void gf100_mc_intr_unarm(struct nvkm_mc *);
void gf100_mc_intr_rearm(struct nvkm_mc *);
u32 gf100_mc_intr_mask(struct nvkm_mc *);
void gf100_mc_unk260(struct nvkm_mc *, u32);
+
+extern const struct nvkm_mc_map gk104_mc_intr[];
+extern const struct nvkm_mc_map gk104_mc_reset[];
#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c
index e04a2296ecd0..5df9669ea39c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c
@@ -524,7 +524,7 @@ void
nvkm_mmu_ctor(const struct nvkm_mmu_func *func, struct nvkm_device *device,
int index, struct nvkm_mmu *mmu)
{
- nvkm_subdev_ctor(&nvkm_mmu, device, index, 0, &mmu->subdev);
+ nvkm_subdev_ctor(&nvkm_mmu, device, index, &mmu->subdev);
mmu->func = func;
mmu->limit = func->limit;
mmu->dma_bits = func->dma_bits;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c
index 9700a7625012..21b65ee254e4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c
@@ -241,7 +241,7 @@ nvkm_mxm_new_(struct nvkm_device *device, int index, struct nvkm_mxm **pmxm)
if (!(mxm = *pmxm = kzalloc(sizeof(*mxm), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&nvkm_mxm, device, index, 0, &mxm->subdev);
+ nvkm_subdev_ctor(&nvkm_mxm, device, index, &mxm->subdev);
data = mxm_table(bios, &ver, &len);
if (!data || !(ver = nvbios_rd08(bios, data))) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
index 65057c8310a2..6b0328bd7eed 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
@@ -168,7 +168,7 @@ nvkm_pci_new_(const struct nvkm_pci_func *func, struct nvkm_device *device,
if (!(pci = *ppci = kzalloc(sizeof(**ppci), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&nvkm_pci_func, device, index, 0, &pci->subdev);
+ nvkm_subdev_ctor(&nvkm_pci_func, device, index, &pci->subdev);
pci->func = func;
pci->pdev = device->func->pci(device)->pdev;
pci->irq = -1;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
index d95eb8659d1b..8dd164d13043 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c
@@ -40,21 +40,23 @@ nvkm_pmu_send(struct nvkm_pmu *pmu, u32 reply[2],
struct nvkm_device *device = subdev->device;
u32 addr;
+ mutex_lock(&subdev->mutex);
/* wait for a free slot in the fifo */
addr = nvkm_rd32(device, 0x10a4a0);
if (nvkm_msec(device, 2000,
u32 tmp = nvkm_rd32(device, 0x10a4b0);
if (tmp != (addr ^ 8))
break;
- ) < 0)
+ ) < 0) {
+ mutex_unlock(&subdev->mutex);
return -EBUSY;
+ }
/* we currently only support a single process at a time waiting
* on a synchronous reply, take the PMU mutex and tell the
* receive handler what we're waiting for
*/
if (reply) {
- mutex_lock(&subdev->mutex);
pmu->recv.message = message;
pmu->recv.process = process;
}
@@ -81,9 +83,9 @@ nvkm_pmu_send(struct nvkm_pmu *pmu, u32 reply[2],
wait_event(pmu->recv.wait, (pmu->recv.process == 0));
reply[0] = pmu->recv.data[0];
reply[1] = pmu->recv.data[1];
- mutex_unlock(&subdev->mutex);
}
+ mutex_unlock(&subdev->mutex);
return 0;
}
@@ -272,7 +274,7 @@ nvkm_pmu_new_(const struct nvkm_pmu_func *func, struct nvkm_device *device,
struct nvkm_pmu *pmu;
if (!(pmu = *ppmu = kzalloc(sizeof(*pmu), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&nvkm_pmu, device, index, 0, &pmu->subdev);
+ nvkm_subdev_ctor(&nvkm_pmu, device, index, &pmu->subdev);
pmu->func = func;
INIT_WORK(&pmu->recv.work, nvkm_pmu_recv);
init_waitqueue_head(&pmu->recv.wait);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c
index 6689d0290a7e..f996d90c9f0d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c
@@ -220,7 +220,7 @@ gk20a_pmu_new(struct nvkm_device *device, int index, struct nvkm_pmu **ppmu)
pmu->base.func = &func;
*ppmu = &pmu->base;
- nvkm_subdev_ctor(&gk20a_pmu, device, index, 0, &pmu->base.subdev);
+ nvkm_subdev_ctor(&gk20a_pmu, device, index, &pmu->base.subdev);
pmu->data = &gk20a_dvfs_data;
nvkm_alarm_init(&pmu->alarm, gk20a_pmu_dvfs_work);
return 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c
index 520facf9bc07..213fdba6cfa0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/base.c
@@ -264,7 +264,7 @@ nvkm_secboot_ctor(const struct nvkm_secboot_func *func,
{
unsigned long fid;
- nvkm_subdev_ctor(&nvkm_secboot, device, index, 0, &sb->subdev);
+ nvkm_subdev_ctor(&nvkm_secboot, device, index, &sb->subdev);
sb->func = func;
/* setup the performing falcon's base address and masks */
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
index 949dc6101a58..8894fee30cbc 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c
@@ -366,7 +366,7 @@ nvkm_therm_new_(const struct nvkm_therm_func *func, struct nvkm_device *device,
if (!(therm = *ptherm = kzalloc(sizeof(*therm), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&nvkm_therm, device, index, 0, &therm->subdev);
+ nvkm_subdev_ctor(&nvkm_therm, device, index, &therm->subdev);
therm->func = func;
nvkm_alarm_init(&therm->alarm, nvkm_therm_alarm);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c
index d4dae1f12d62..07dc82bfe346 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c
@@ -143,7 +143,7 @@ nvkm_timer_new_(const struct nvkm_timer_func *func, struct nvkm_device *device,
if (!(tmr = *ptmr = kzalloc(sizeof(*tmr), GFP_KERNEL)))
return -ENOMEM;
- nvkm_subdev_ctor(&nvkm_timer, device, index, 0, &tmr->subdev);
+ nvkm_subdev_ctor(&nvkm_timer, device, index, &tmr->subdev);
tmr->func = func;
INIT_LIST_HEAD(&tmr->alarms);
spin_lock_init(&tmr->lock);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/top/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/top/Kbuild
new file mode 100644
index 000000000000..1078401cdcea
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/top/Kbuild
@@ -0,0 +1,2 @@
+nvkm-y += nvkm/subdev/top/base.o
+nvkm-y += nvkm/subdev/top/gk104.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/top/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/top/base.c
new file mode 100644
index 000000000000..a1b264664aad
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/top/base.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2016 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+#include "priv.h"
+
+struct nvkm_top_device *
+nvkm_top_device_new(struct nvkm_top *top)
+{
+ struct nvkm_top_device *info = kmalloc(sizeof(*info), GFP_KERNEL);
+ if (info) {
+ info->index = NVKM_SUBDEV_NR;
+ info->addr = 0;
+ info->fault = -1;
+ info->engine = -1;
+ info->runlist = -1;
+ info->reset = -1;
+ info->intr = -1;
+ list_add_tail(&info->head, &top->device);
+ }
+ return info;
+}
+
+u32
+nvkm_top_reset(struct nvkm_top *top, enum nvkm_devidx index)
+{
+ struct nvkm_top_device *info;
+
+ if (top) {
+ list_for_each_entry(info, &top->device, head) {
+ if (info->index == index && info->reset >= 0)
+ return BIT(info->reset);
+ }
+ }
+
+ return 0;
+}
+
+u32
+nvkm_top_intr(struct nvkm_top *top, u32 intr, u64 *psubdevs)
+{
+ struct nvkm_top_device *info;
+ u64 subdevs = 0;
+ u32 handled = 0;
+
+ if (top) {
+ list_for_each_entry(info, &top->device, head) {
+ if (info->index != NVKM_SUBDEV_NR && info->intr >= 0) {
+ if (intr & BIT(info->intr)) {
+ subdevs |= BIT_ULL(info->index);
+ handled |= BIT(info->intr);
+ }
+ }
+ }
+ }
+
+ *psubdevs = subdevs;
+ return intr & ~handled;
+}
+
+enum nvkm_devidx
+nvkm_top_fault(struct nvkm_top *top, int fault)
+{
+ struct nvkm_top_device *info;
+
+ list_for_each_entry(info, &top->device, head) {
+ if (info->fault == fault)
+ return info->index;
+ }
+
+ return NVKM_SUBDEV_NR;
+}
+
+enum nvkm_devidx
+nvkm_top_engine(struct nvkm_top *top, int index, int *runl, int *engn)
+{
+ struct nvkm_top_device *info;
+ int n = 0;
+
+ list_for_each_entry(info, &top->device, head) {
+ if (info->engine >= 0 && info->runlist >= 0 && n++ == index) {
+ *runl = info->runlist;
+ *engn = info->engine;
+ return info->index;
+ }
+ }
+
+ return -ENODEV;
+}
+
+static int
+nvkm_top_oneinit(struct nvkm_subdev *subdev)
+{
+ struct nvkm_top *top = nvkm_top(subdev);
+ return top->func->oneinit(top);
+}
+
+static void *
+nvkm_top_dtor(struct nvkm_subdev *subdev)
+{
+ struct nvkm_top *top = nvkm_top(subdev);
+ struct nvkm_top_device *info, *temp;
+
+ list_for_each_entry_safe(info, temp, &top->device, head) {
+ list_del(&info->head);
+ kfree(info);
+ }
+
+ return top;
+}
+
+static const struct nvkm_subdev_func
+nvkm_top = {
+ .dtor = nvkm_top_dtor,
+ .oneinit = nvkm_top_oneinit,
+};
+
+int
+nvkm_top_new_(const struct nvkm_top_func *func, struct nvkm_device *device,
+ int index, struct nvkm_top **ptop)
+{
+ struct nvkm_top *top;
+ if (!(top = *ptop = kzalloc(sizeof(*top), GFP_KERNEL)))
+ return -ENOMEM;
+ nvkm_subdev_ctor(&nvkm_top, device, index, &top->subdev);
+ top->func = func;
+ INIT_LIST_HEAD(&top->device);
+ return 0;
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c
new file mode 100644
index 000000000000..e06acc340e99
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/top/gk104.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2016 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+#include "priv.h"
+
+static int
+gk104_top_oneinit(struct nvkm_top *top)
+{
+ struct nvkm_subdev *subdev = &top->subdev;
+ struct nvkm_device *device = subdev->device;
+ struct nvkm_top_device *info = NULL;
+ u32 data, type;
+ int i;
+
+ for (i = 0; i < 64; i++) {
+ if (!info) {
+ if (!(info = nvkm_top_device_new(top)))
+ return -ENOMEM;
+ type = ~0;
+ }
+
+ data = nvkm_rd32(device, 0x022700 + (i * 0x04));
+ nvkm_trace(subdev, "%02x: %08x\n", i, data);
+ switch (data & 0x00000003) {
+ case 0x00000000: /* NOT_VALID */
+ continue;
+ case 0x00000001: /* DATA */
+ info->addr = (data & 0x00fff000);
+ info->fault = (data & 0x000000f8) >> 3;
+ break;
+ case 0x00000002: /* ENUM */
+ if (data & 0x00000020)
+ info->engine = (data & 0x3c000000) >> 26;
+ if (data & 0x00000010)
+ info->runlist = (data & 0x01e00000) >> 21;
+ if (data & 0x00000008)
+ info->intr = (data & 0x000f8000) >> 15;
+ if (data & 0x00000004)
+ info->reset = (data & 0x00003e00) >> 9;
+ break;
+ case 0x00000003: /* ENGINE_TYPE */
+ type = (data & 0x7ffffffc) >> 2;
+ break;
+ }
+
+ if (data & 0x80000000)
+ continue;
+
+ /* Translate engine type to NVKM engine identifier. */
+ switch (type) {
+ case 0x00000000: info->index = NVKM_ENGINE_GR; break;
+ case 0x00000001: info->index = NVKM_ENGINE_CE0; break;
+ case 0x00000002: info->index = NVKM_ENGINE_CE1; break;
+ case 0x00000003: info->index = NVKM_ENGINE_CE2; break;
+ case 0x00000008: info->index = NVKM_ENGINE_MSPDEC; break;
+ case 0x00000009: info->index = NVKM_ENGINE_MSPPP; break;
+ case 0x0000000a: info->index = NVKM_ENGINE_MSVLD; break;
+ case 0x0000000b: info->index = NVKM_ENGINE_MSENC; break;
+ case 0x0000000c: info->index = NVKM_ENGINE_VIC; break;
+ case 0x0000000d: info->index = NVKM_ENGINE_SEC; break;
+ case 0x0000000e: info->index = NVKM_ENGINE_NVENC0; break;
+ case 0x0000000f: info->index = NVKM_ENGINE_NVENC1; break;
+ case 0x00000010: info->index = NVKM_ENGINE_NVDEC; break;
+ break;
+ default:
+ break;
+ }
+
+ nvkm_debug(subdev, "%02x (%8s): addr %06x fault %2d engine %2d "
+ "runlist %2d intr %2d reset %2d\n", type,
+ info->index == NVKM_SUBDEV_NR ? NULL :
+ nvkm_subdev_name[info->index],
+ info->addr, info->fault, info->engine, info->runlist,
+ info->intr, info->reset);
+ info = NULL;
+ }
+
+ return 0;
+}
+
+static const struct nvkm_top_func
+gk104_top = {
+ .oneinit = gk104_top_oneinit,
+};
+
+int
+gk104_top_new(struct nvkm_device *device, int index, struct nvkm_top **ptop)
+{
+ return nvkm_top_new_(&gk104_top, device, index, ptop);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/top/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/top/priv.h
new file mode 100644
index 000000000000..adb3ed03d937
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/top/priv.h
@@ -0,0 +1,25 @@
+#ifndef __NVKM_TOP_PRIV_H__
+#define __NVKM_TOP_PRIV_H__
+#define nvkm_top(p) container_of((p), struct nvkm_top, subdev)
+#include <subdev/top.h>
+
+struct nvkm_top_func {
+ int (*oneinit)(struct nvkm_top *);
+};
+
+int nvkm_top_new_(const struct nvkm_top_func *, struct nvkm_device *,
+ int, struct nvkm_top **);
+
+struct nvkm_top_device {
+ enum nvkm_devidx index;
+ u32 addr;
+ int fault;
+ int engine;
+ int runlist;
+ int reset;
+ int intr;
+ struct list_head head;
+};
+
+struct nvkm_top_device *nvkm_top_device_new(struct nvkm_top *);
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c
index 50b5649ad1a4..6b2d7531a7ff 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c
@@ -177,7 +177,7 @@ nvkm_volt_ctor(const struct nvkm_volt_func *func, struct nvkm_device *device,
struct nvkm_bios *bios = device->bios;
int i;
- nvkm_subdev_ctor(&nvkm_volt, device, index, 0, &volt->subdev);
+ nvkm_subdev_ctor(&nvkm_volt, device, index, &volt->subdev);
volt->func = func;
/* Assuming the non-bios device should build the voltage table later */
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c
index b735173a18ff..420bd84d8483 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c
@@ -56,7 +56,7 @@ gk104_volt_set(struct nvkm_volt *base, u32 uv)
/* the blob uses this crystal frequency, let's use it too. */
div = 27648000 / bios->pwm_freq;
- duty = (uv - bios->base) * div / bios->pwm_range;
+ duty = DIV_ROUND_UP((uv - bios->base) * div, bios->pwm_range);
nvkm_wr32(device, 0x20340, div);
nvkm_wr32(device, 0x20344, 0x80000000 | duty);