17c4f87c9SBen Skeggs /* 27c4f87c9SBen Skeggs * Copyright 2016 Red Hat Inc. 37c4f87c9SBen Skeggs * 47c4f87c9SBen Skeggs * Permission is hereby granted, free of charge, to any person obtaining a 57c4f87c9SBen Skeggs * copy of this software and associated documentation files (the "Software"), 67c4f87c9SBen Skeggs * to deal in the Software without restriction, including without limitation 77c4f87c9SBen Skeggs * the rights to use, copy, modify, merge, publish, distribute, sublicense, 87c4f87c9SBen Skeggs * and/or sell copies of the Software, and to permit persons to whom the 97c4f87c9SBen Skeggs * Software is furnished to do so, subject to the following conditions: 107c4f87c9SBen Skeggs * 117c4f87c9SBen Skeggs * The above copyright notice and this permission notice shall be included in 127c4f87c9SBen Skeggs * all copies or substantial portions of the Software. 137c4f87c9SBen Skeggs * 147c4f87c9SBen Skeggs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 157c4f87c9SBen Skeggs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 167c4f87c9SBen Skeggs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 177c4f87c9SBen Skeggs * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 187c4f87c9SBen Skeggs * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 197c4f87c9SBen Skeggs * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 207c4f87c9SBen Skeggs * OTHER DEALINGS IN THE SOFTWARE. 217c4f87c9SBen Skeggs * 227c4f87c9SBen Skeggs * Authors: Ben Skeggs 237c4f87c9SBen Skeggs */ 24f5e45689SBen Skeggs #include "priv.h" 25f5e45689SBen Skeggs #include "chan.h" 267c4f87c9SBen Skeggs #include "gk104.h" 277c4f87c9SBen Skeggs #include "changk104.h" 287c4f87c9SBen Skeggs 29eda12417SBen Skeggs #include <core/gpuobj.h> 30cde54021SBen Skeggs #include <subdev/fault.h> 31eda12417SBen Skeggs 32f9360c3aSBen Skeggs #include <nvif/class.h> 33f9360c3aSBen Skeggs 34f5e45689SBen Skeggs const struct nvkm_chan_func 35f5e45689SBen Skeggs gm107_chan = { 36f5e45689SBen Skeggs }; 37f5e45689SBen Skeggs 38eda12417SBen Skeggs static void 39eda12417SBen Skeggs gm107_fifo_runlist_chan(struct gk104_fifo_chan *chan, 40eda12417SBen Skeggs struct nvkm_memory *memory, u32 offset) 41eda12417SBen Skeggs { 42eda12417SBen Skeggs nvkm_wo32(memory, offset + 0, chan->base.chid); 43eda12417SBen Skeggs nvkm_wo32(memory, offset + 4, chan->base.inst->addr >> 12); 44eda12417SBen Skeggs } 45eda12417SBen Skeggs 46eda12417SBen Skeggs const struct gk104_fifo_runlist_func 47eda12417SBen Skeggs gm107_fifo_runlist = { 48eda12417SBen Skeggs .size = 8, 49eda12417SBen Skeggs .cgrp = gk110_fifo_runlist_cgrp, 50eda12417SBen Skeggs .chan = gm107_fifo_runlist_chan, 51efa44c66SBen Skeggs .commit = gk104_fifo_runlist_commit, 52eda12417SBen Skeggs }; 53eda12417SBen Skeggs 540cdc3fdfSBen Skeggs const struct nvkm_enum 550cdc3fdfSBen Skeggs gm107_fifo_fault_engine[] = { 560cdc3fdfSBen Skeggs { 0x01, "DISPLAY" }, 570cdc3fdfSBen Skeggs { 0x02, "CAPTURE" }, 580cdc3fdfSBen Skeggs { 0x03, "IFB", NULL, NVKM_ENGINE_IFB }, 590cdc3fdfSBen Skeggs { 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR }, 600cdc3fdfSBen Skeggs { 0x05, "BAR2", NULL, NVKM_SUBDEV_INSTMEM }, 610cdc3fdfSBen Skeggs { 0x06, "SCHED" }, 62ec884f74SBen Skeggs { 0x07, "HOST0", NULL, NVKM_ENGINE_FIFO }, 63ec884f74SBen Skeggs { 0x08, "HOST1", NULL, NVKM_ENGINE_FIFO }, 64ec884f74SBen Skeggs { 0x09, "HOST2", NULL, NVKM_ENGINE_FIFO }, 65ec884f74SBen Skeggs { 0x0a, "HOST3", NULL, NVKM_ENGINE_FIFO }, 66ec884f74SBen Skeggs { 0x0b, "HOST4", NULL, NVKM_ENGINE_FIFO }, 67ec884f74SBen Skeggs { 0x0c, "HOST5", NULL, NVKM_ENGINE_FIFO }, 68ec884f74SBen Skeggs { 0x0d, "HOST6", NULL, NVKM_ENGINE_FIFO }, 69ec884f74SBen Skeggs { 0x0e, "HOST7", NULL, NVKM_ENGINE_FIFO }, 700cdc3fdfSBen Skeggs { 0x0f, "HOSTSR" }, 710cdc3fdfSBen Skeggs { 0x13, "PERF" }, 720cdc3fdfSBen Skeggs { 0x17, "PMU" }, 730cdc3fdfSBen Skeggs { 0x18, "PTP" }, 740cdc3fdfSBen Skeggs {} 750cdc3fdfSBen Skeggs }; 760cdc3fdfSBen Skeggs 779be9c606SBen Skeggs const struct nvkm_fifo_func_mmu_fault 789be9c606SBen Skeggs gm107_fifo_mmu_fault = { 799be9c606SBen Skeggs .recover = gk104_fifo_fault, 809be9c606SBen Skeggs }; 819be9c606SBen Skeggs 82cde54021SBen Skeggs void 839be9c606SBen Skeggs gm107_fifo_intr_mmu_fault_unit(struct nvkm_fifo *fifo, int unit) 84cde54021SBen Skeggs { 85cde54021SBen Skeggs struct nvkm_device *device = fifo->engine.subdev.device; 86cde54021SBen Skeggs u32 inst = nvkm_rd32(device, 0x002800 + (unit * 0x10)); 87cde54021SBen Skeggs u32 valo = nvkm_rd32(device, 0x002804 + (unit * 0x10)); 88cde54021SBen Skeggs u32 vahi = nvkm_rd32(device, 0x002808 + (unit * 0x10)); 89cde54021SBen Skeggs u32 type = nvkm_rd32(device, 0x00280c + (unit * 0x10)); 90cde54021SBen Skeggs struct nvkm_fault_data info; 91cde54021SBen Skeggs 92cde54021SBen Skeggs info.inst = (u64)inst << 12; 93cde54021SBen Skeggs info.addr = ((u64)vahi << 32) | valo; 94cde54021SBen Skeggs info.time = 0; 95cde54021SBen Skeggs info.engine = unit; 96cde54021SBen Skeggs info.valid = 1; 97cde54021SBen Skeggs info.gpc = (type & 0x1f000000) >> 24; 98cde54021SBen Skeggs info.client = (type & 0x00003f00) >> 8; 99cde54021SBen Skeggs info.access = (type & 0x00000080) >> 7; 100cde54021SBen Skeggs info.hub = (type & 0x00000040) >> 6; 101cde54021SBen Skeggs info.reason = (type & 0x0000000f); 102cde54021SBen Skeggs 103cde54021SBen Skeggs nvkm_fifo_fault(fifo, &info); 104cde54021SBen Skeggs } 105cde54021SBen Skeggs 1068c18138cSBen Skeggs static int 1078c18138cSBen Skeggs gm107_fifo_chid_nr(struct nvkm_fifo *fifo) 1088c18138cSBen Skeggs { 1098c18138cSBen Skeggs return 2048; 1108c18138cSBen Skeggs } 1118c18138cSBen Skeggs 1129be9c606SBen Skeggs static const struct nvkm_fifo_func 1137c4f87c9SBen Skeggs gm107_fifo = { 1149be9c606SBen Skeggs .dtor = gk104_fifo_dtor, 1159be9c606SBen Skeggs .oneinit = gk104_fifo_oneinit, 1168c18138cSBen Skeggs .chid_nr = gm107_fifo_chid_nr, 117800ac1f8SBen Skeggs .chid_ctor = gk110_fifo_chid_ctor, 118*1c488ba9SBen Skeggs .runq_nr = gf100_fifo_runq_nr, 1199be9c606SBen Skeggs .info = gk104_fifo_info, 1209be9c606SBen Skeggs .init = gk104_fifo_init, 1219be9c606SBen Skeggs .fini = gk104_fifo_fini, 1229be9c606SBen Skeggs .intr = gk104_fifo_intr, 1239be9c606SBen Skeggs .intr_mmu_fault_unit = gm107_fifo_intr_mmu_fault_unit, 1249be9c606SBen Skeggs .mmu_fault = &gm107_fifo_mmu_fault, 125ddc669e2SBen Skeggs .fault.access = gk104_fifo_fault_access, 1260cdc3fdfSBen Skeggs .fault.engine = gm107_fifo_fault_engine, 12791419acfSBen Skeggs .fault.reason = gk104_fifo_fault_reason, 12891419acfSBen Skeggs .fault.hubclient = gk104_fifo_fault_hubclient, 12991419acfSBen Skeggs .fault.gpcclient = gk104_fifo_fault_gpcclient, 1309be9c606SBen Skeggs .engine_id = gk104_fifo_engine_id, 1319be9c606SBen Skeggs .id_engine = gk104_fifo_id_engine, 1329be9c606SBen Skeggs .uevent_init = gk104_fifo_uevent_init, 1339be9c606SBen Skeggs .uevent_fini = gk104_fifo_uevent_fini, 1349be9c606SBen Skeggs .recover_chan = gk104_fifo_recover_chan, 135eda12417SBen Skeggs .runlist = &gm107_fifo_runlist, 1369be9c606SBen Skeggs .pbdma = &gk208_fifo_pbdma, 137*1c488ba9SBen Skeggs .runq = &gk208_runq, 138f5e45689SBen Skeggs .cgrp = {{ 0, 0, KEPLER_CHANNEL_GROUP_A }, &gk110_cgrp }, 139f5e45689SBen Skeggs .chan = {{ 0, 0, KEPLER_CHANNEL_GPFIFO_B }, &gm107_chan, .ctor = &gk104_fifo_gpfifo_new }, 1407c4f87c9SBen Skeggs }; 1417c4f87c9SBen Skeggs 1427c4f87c9SBen Skeggs int 143ab0db2bdSBen Skeggs gm107_fifo_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, 144ab0db2bdSBen Skeggs struct nvkm_fifo **pfifo) 1457c4f87c9SBen Skeggs { 1468c18138cSBen Skeggs return gk104_fifo_new_(&gm107_fifo, device, type, inst, 0, pfifo); 1477c4f87c9SBen Skeggs } 148