diff options
author | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-09-11 04:34:46 -0300 |
---|---|---|
committer | André Fabian Silva Delgado <emulatorman@parabola.nu> | 2016-09-11 04:34:46 -0300 |
commit | 863981e96738983919de841ec669e157e6bdaeb0 (patch) | |
tree | d6d89a12e7eb8017837c057935a2271290907f76 /drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | |
parent | 8dec7c70575785729a6a9e6719a955e9c545bcab (diff) |
Linux-libre 4.7.1-gnupck-4.7.1-gnu
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 395 |
1 files changed, 193 insertions, 202 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index 68acb36b3..743f3a189 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 |