aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c')
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c116
1 files changed, 103 insertions, 13 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
index 9f5dfc85147a..1f81069edc58 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
@@ -34,6 +34,7 @@
#include <engine/fifo.h>
#include <nvif/class.h>
+#include <nvif/cl9097.h>
#include <nvif/unpack.h>
/*******************************************************************************
@@ -139,6 +140,12 @@ gf100_gr_zbc_depth_get(struct gf100_gr *gr, int format,
/*******************************************************************************
* Graphics object classes
******************************************************************************/
+#define gf100_gr_object(p) container_of((p), struct gf100_gr_object, object)
+
+struct gf100_gr_object {
+ struct nvkm_object object;
+ struct gf100_gr_chan *chan;
+};
static int
gf100_fermi_mthd_zbc_color(struct nvkm_object *object, void *data, u32 size)
@@ -147,9 +154,9 @@ gf100_fermi_mthd_zbc_color(struct nvkm_object *object, void *data, u32 size)
union {
struct fermi_a_zbc_color_v0 v0;
} *args = data;
- int ret;
+ int ret = -ENOSYS;
- if (nvif_unpack(args->v0, 0, 0, false)) {
+ if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
switch (args->v0.format) {
case FERMI_A_ZBC_COLOR_V0_FMT_ZERO:
case FERMI_A_ZBC_COLOR_V0_FMT_UNORM_ONE:
@@ -193,9 +200,9 @@ gf100_fermi_mthd_zbc_depth(struct nvkm_object *object, void *data, u32 size)
union {
struct fermi_a_zbc_depth_v0 v0;
} *args = data;
- int ret;
+ int ret = -ENOSYS;
- if (nvif_unpack(args->v0, 0, 0, false)) {
+ if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
switch (args->v0.format) {
case FERMI_A_ZBC_DEPTH_V0_FMT_FP32:
ret = gf100_gr_zbc_depth_get(gr, args->v0.format,
@@ -213,6 +220,7 @@ gf100_fermi_mthd_zbc_depth(struct nvkm_object *object, void *data, u32 size)
static int
gf100_fermi_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
+ nvif_ioctl(object, "fermi mthd %08x\n", mthd);
switch (mthd) {
case FERMI_A_ZBC_COLOR:
return gf100_fermi_mthd_zbc_color(object, data, size);
@@ -256,6 +264,27 @@ gf100_gr_mthd_sw(struct nvkm_device *device, u16 class, u32 mthd, u32 data)
return false;
}
+static const struct nvkm_object_func
+gf100_gr_object_func = {
+};
+
+static int
+gf100_gr_object_new(const struct nvkm_oclass *oclass, void *data, u32 size,
+ struct nvkm_object **pobject)
+{
+ struct gf100_gr_chan *chan = gf100_gr_chan(oclass->parent);
+ struct gf100_gr_object *object;
+
+ if (!(object = kzalloc(sizeof(*object), GFP_KERNEL)))
+ return -ENOMEM;
+ *pobject = &object->object;
+
+ nvkm_object_ctor(oclass->base.func ? oclass->base.func :
+ &gf100_gr_object_func, oclass, &object->object);
+ object->chan = chan;
+ return 0;
+}
+
static int
gf100_gr_object_get(struct nvkm_gr *base, int index, struct nvkm_sclass *sclass)
{
@@ -265,6 +294,7 @@ gf100_gr_object_get(struct nvkm_gr *base, int index, struct nvkm_sclass *sclass)
while (gr->func->sclass[c].oclass) {
if (c++ == index) {
*sclass = gr->func->sclass[index];
+ sclass->ctor = gf100_gr_object_new;
return index;
}
}
@@ -826,7 +856,41 @@ gf100_gr_units(struct nvkm_gr *base)
return cfg;
}
+static const struct nvkm_bitfield gf100_dispatch_error[] = {
+ { 0x00000001, "INJECTED_BUNDLE_ERROR" },
+ { 0x00000002, "CLASS_SUBCH_MISMATCH" },
+ { 0x00000004, "SUBCHSW_DURING_NOTIFY" },
+ {}
+};
+
+static const struct nvkm_bitfield gf100_m2mf_error[] = {
+ { 0x00000001, "PUSH_TOO_MUCH_DATA" },
+ { 0x00000002, "PUSH_NOT_ENOUGH_DATA" },
+ {}
+};
+
+static const struct nvkm_bitfield gf100_unk6_error[] = {
+ { 0x00000001, "TEMP_TOO_SMALL" },
+ {}
+};
+
+static const struct nvkm_bitfield gf100_ccache_error[] = {
+ { 0x00000001, "INTR" },
+ { 0x00000002, "LDCONST_OOB" },
+ {}
+};
+
+static const struct nvkm_bitfield gf100_macro_error[] = {
+ { 0x00000001, "TOO_FEW_PARAMS" },
+ { 0x00000002, "TOO_MANY_PARAMS" },
+ { 0x00000004, "ILLEGAL_OPCODE" },
+ { 0x00000008, "DOUBLE_BRANCH" },
+ { 0x00000010, "WATCHDOG" },
+ {}
+};
+
static const struct nvkm_bitfield gk104_sked_error[] = {
+ { 0x00000040, "CTA_RESUME" },
{ 0x00000080, "CONSTANT_BUFFER_SIZE" },
{ 0x00000200, "LOCAL_MEMORY_SIZE_POS" },
{ 0x00000400, "LOCAL_MEMORY_SIZE_NEG" },
@@ -836,6 +900,8 @@ static const struct nvkm_bitfield gk104_sked_error[] = {
{ 0x00040000, "TOTAL_THREADS" },
{ 0x00100000, "PROGRAM_OFFSET" },
{ 0x00200000, "SHARED_MEMORY_SIZE" },
+ { 0x00800000, "CTA_THREAD_DIMENSION_ZERO" },
+ { 0x01000000, "MEMORY_WINDOW_OVERLAP" },
{ 0x02000000, "SHARED_CONFIG_TOO_SMALL" },
{ 0x04000000, "TOTAL_REGISTER_COUNT" },
{}
@@ -1005,12 +1071,16 @@ gf100_gr_trap_intr(struct gf100_gr *gr)
{
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
struct nvkm_device *device = subdev->device;
+ char error[128];
u32 trap = nvkm_rd32(device, 0x400108);
int rop, gpc;
if (trap & 0x00000001) {
u32 stat = nvkm_rd32(device, 0x404000);
- nvkm_error(subdev, "DISPATCH %08x\n", stat);
+
+ nvkm_snprintbf(error, sizeof(error), gf100_dispatch_error,
+ stat & 0x3fffffff);
+ nvkm_error(subdev, "DISPATCH %08x [%s]\n", stat, error);
nvkm_wr32(device, 0x404000, 0xc0000000);
nvkm_wr32(device, 0x400108, 0x00000001);
trap &= ~0x00000001;
@@ -1018,7 +1088,11 @@ gf100_gr_trap_intr(struct gf100_gr *gr)
if (trap & 0x00000002) {
u32 stat = nvkm_rd32(device, 0x404600);
- nvkm_error(subdev, "M2MF %08x\n", stat);
+
+ nvkm_snprintbf(error, sizeof(error), gf100_m2mf_error,
+ stat & 0x3fffffff);
+ nvkm_error(subdev, "M2MF %08x [%s]\n", stat, error);
+
nvkm_wr32(device, 0x404600, 0xc0000000);
nvkm_wr32(device, 0x400108, 0x00000002);
trap &= ~0x00000002;
@@ -1026,7 +1100,10 @@ gf100_gr_trap_intr(struct gf100_gr *gr)
if (trap & 0x00000008) {
u32 stat = nvkm_rd32(device, 0x408030);
- nvkm_error(subdev, "CCACHE %08x\n", stat);
+
+ nvkm_snprintbf(error, sizeof(error), gf100_m2mf_error,
+ stat & 0x3fffffff);
+ nvkm_error(subdev, "CCACHE %08x [%s]\n", stat, error);
nvkm_wr32(device, 0x408030, 0xc0000000);
nvkm_wr32(device, 0x400108, 0x00000008);
trap &= ~0x00000008;
@@ -1034,7 +1111,8 @@ gf100_gr_trap_intr(struct gf100_gr *gr)
if (trap & 0x00000010) {
u32 stat = nvkm_rd32(device, 0x405840);
- nvkm_error(subdev, "SHADER %08x\n", stat);
+ nvkm_error(subdev, "SHADER %08x, sph: 0x%06x, stage: 0x%02x\n",
+ stat, stat & 0xffffff, (stat >> 24) & 0x3f);
nvkm_wr32(device, 0x405840, 0xc0000000);
nvkm_wr32(device, 0x400108, 0x00000010);
trap &= ~0x00000010;
@@ -1042,7 +1120,11 @@ gf100_gr_trap_intr(struct gf100_gr *gr)
if (trap & 0x00000040) {
u32 stat = nvkm_rd32(device, 0x40601c);
- nvkm_error(subdev, "UNK6 %08x\n", stat);
+
+ nvkm_snprintbf(error, sizeof(error), gf100_unk6_error,
+ stat & 0x3fffffff);
+ nvkm_error(subdev, "UNK6 %08x [%s]\n", stat, error);
+
nvkm_wr32(device, 0x40601c, 0xc0000000);
nvkm_wr32(device, 0x400108, 0x00000040);
trap &= ~0x00000040;
@@ -1050,7 +1132,16 @@ gf100_gr_trap_intr(struct gf100_gr *gr)
if (trap & 0x00000080) {
u32 stat = nvkm_rd32(device, 0x404490);
- nvkm_error(subdev, "MACRO %08x\n", stat);
+ u32 pc = nvkm_rd32(device, 0x404494);
+ u32 op = nvkm_rd32(device, 0x40449c);
+
+ nvkm_snprintbf(error, sizeof(error), gf100_macro_error,
+ stat & 0x1fffffff);
+ nvkm_error(subdev, "MACRO %08x [%s], pc: 0x%03x%s, op: 0x%08x\n",
+ stat, error, pc & 0x7ff,
+ (pc & 0x10000000) ? "" : " (invalid)",
+ op);
+
nvkm_wr32(device, 0x404490, 0xc0000000);
nvkm_wr32(device, 0x400108, 0x00000080);
trap &= ~0x00000080;
@@ -1058,10 +1149,9 @@ gf100_gr_trap_intr(struct gf100_gr *gr)
if (trap & 0x00000100) {
u32 stat = nvkm_rd32(device, 0x407020) & 0x3fffffff;
- char sked[128];
- nvkm_snprintbf(sked, sizeof(sked), gk104_sked_error, stat);
- nvkm_error(subdev, "SKED: %08x [%s]\n", stat, sked);
+ nvkm_snprintbf(error, sizeof(error), gk104_sked_error, stat);
+ nvkm_error(subdev, "SKED: %08x [%s]\n", stat, error);
if (stat)
nvkm_wr32(device, 0x407020, 0x40000000);