1 /* 2 * Copyright 2012 Red Hat Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: Ben Skeggs 23 */ 24 #include <engine/ce.h> 25 #include <engine/fifo.h> 26 27 #include <nvif/class.h> 28 29 static void 30 gk104_ce_intr(struct nvkm_subdev *subdev) 31 { 32 struct nvkm_device *device = subdev->device; 33 const int idx = nv_subidx(subdev) - NVDEV_ENGINE_CE0; 34 u32 stat = nvkm_rd32(device, 0x104908 + (idx * 0x1000)); 35 36 if (stat) { 37 nvkm_warn(subdev, "intr %08x\n", stat); 38 nvkm_wr32(device, 0x104908 + (idx * 0x1000), stat); 39 } 40 } 41 42 static const struct nvkm_engine_func 43 gk104_ce = { 44 .sclass = { 45 { -1, -1, KEPLER_DMA_COPY_A }, 46 {} 47 } 48 }; 49 50 static int 51 gk104_ce0_ctor(struct nvkm_object *parent, struct nvkm_object *engine, 52 struct nvkm_oclass *oclass, void *data, u32 size, 53 struct nvkm_object **pobject) 54 { 55 struct nvkm_engine *ce; 56 int ret; 57 58 ret = nvkm_engine_create(parent, engine, oclass, true, 59 "PCE0", "ce0", &ce); 60 *pobject = nv_object(ce); 61 if (ret) 62 return ret; 63 64 ce->func = &gk104_ce; 65 nv_subdev(ce)->unit = 0x00000040; 66 nv_subdev(ce)->intr = gk104_ce_intr; 67 return 0; 68 } 69 70 static int 71 gk104_ce1_ctor(struct nvkm_object *parent, struct nvkm_object *engine, 72 struct nvkm_oclass *oclass, void *data, u32 size, 73 struct nvkm_object **pobject) 74 { 75 struct nvkm_engine *ce; 76 int ret; 77 78 ret = nvkm_engine_create(parent, engine, oclass, true, 79 "PCE1", "ce1", &ce); 80 *pobject = nv_object(ce); 81 if (ret) 82 return ret; 83 84 ce->func = &gk104_ce; 85 nv_subdev(ce)->unit = 0x00000080; 86 nv_subdev(ce)->intr = gk104_ce_intr; 87 return 0; 88 } 89 90 static int 91 gk104_ce2_ctor(struct nvkm_object *parent, struct nvkm_object *engine, 92 struct nvkm_oclass *oclass, void *data, u32 size, 93 struct nvkm_object **pobject) 94 { 95 struct nvkm_engine *ce; 96 int ret; 97 98 ret = nvkm_engine_create(parent, engine, oclass, true, 99 "PCE2", "ce2", &ce); 100 *pobject = nv_object(ce); 101 if (ret) 102 return ret; 103 104 ce->func = &gk104_ce; 105 nv_subdev(ce)->unit = 0x00200000; 106 nv_subdev(ce)->intr = gk104_ce_intr; 107 return 0; 108 } 109 110 struct nvkm_oclass 111 gk104_ce0_oclass = { 112 .handle = NV_ENGINE(CE0, 0xe0), 113 .ofuncs = &(struct nvkm_ofuncs) { 114 .ctor = gk104_ce0_ctor, 115 .dtor = _nvkm_engine_dtor, 116 .init = _nvkm_engine_init, 117 .fini = _nvkm_engine_fini, 118 }, 119 }; 120 121 struct nvkm_oclass 122 gk104_ce1_oclass = { 123 .handle = NV_ENGINE(CE1, 0xe0), 124 .ofuncs = &(struct nvkm_ofuncs) { 125 .ctor = gk104_ce1_ctor, 126 .dtor = _nvkm_engine_dtor, 127 .init = _nvkm_engine_init, 128 .fini = _nvkm_engine_fini, 129 }, 130 }; 131 132 struct nvkm_oclass 133 gk104_ce2_oclass = { 134 .handle = NV_ENGINE(CE2, 0xe0), 135 .ofuncs = &(struct nvkm_ofuncs) { 136 .ctor = gk104_ce2_ctor, 137 .dtor = _nvkm_engine_dtor, 138 .init = _nvkm_engine_init, 139 .fini = _nvkm_engine_fini, 140 }, 141 }; 142