1 /* 2 * Copyright 2013 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 25 #include <subdev/timer.h> 26 27 #include "priv.h" 28 29 void 30 nouveau_pmu_pgob(struct nouveau_pmu *pmu, bool enable) 31 { 32 const struct nvkm_pmu_impl *impl = (void *)nv_oclass(pmu); 33 if (impl->pgob) 34 impl->pgob(pmu, enable); 35 } 36 37 static int 38 nouveau_pmu_send(struct nouveau_pmu *pmu, u32 reply[2], 39 u32 process, u32 message, u32 data0, u32 data1) 40 { 41 struct nouveau_subdev *subdev = nv_subdev(pmu); 42 u32 addr; 43 44 /* wait for a free slot in the fifo */ 45 addr = nv_rd32(pmu, 0x10a4a0); 46 if (!nv_wait_ne(pmu, 0x10a4b0, 0xffffffff, addr ^ 8)) 47 return -EBUSY; 48 49 /* we currently only support a single process at a time waiting 50 * on a synchronous reply, take the PMU mutex and tell the 51 * receive handler what we're waiting for 52 */ 53 if (reply) { 54 mutex_lock(&subdev->mutex); 55 pmu->recv.message = message; 56 pmu->recv.process = process; 57 } 58 59 /* acquire data segment access */ 60 do { 61 nv_wr32(pmu, 0x10a580, 0x00000001); 62 } while (nv_rd32(pmu, 0x10a580) != 0x00000001); 63 64 /* write the packet */ 65 nv_wr32(pmu, 0x10a1c0, 0x01000000 | (((addr & 0x07) << 4) + 66 pmu->send.base)); 67 nv_wr32(pmu, 0x10a1c4, process); 68 nv_wr32(pmu, 0x10a1c4, message); 69 nv_wr32(pmu, 0x10a1c4, data0); 70 nv_wr32(pmu, 0x10a1c4, data1); 71 nv_wr32(pmu, 0x10a4a0, (addr + 1) & 0x0f); 72 73 /* release data segment access */ 74 nv_wr32(pmu, 0x10a580, 0x00000000); 75 76 /* wait for reply, if requested */ 77 if (reply) { 78 wait_event(pmu->recv.wait, (pmu->recv.process == 0)); 79 reply[0] = pmu->recv.data[0]; 80 reply[1] = pmu->recv.data[1]; 81 mutex_unlock(&subdev->mutex); 82 } 83 84 return 0; 85 } 86 87 static void 88 nouveau_pmu_recv(struct work_struct *work) 89 { 90 struct nouveau_pmu *pmu = 91 container_of(work, struct nouveau_pmu, recv.work); 92 u32 process, message, data0, data1; 93 94 /* nothing to do if GET == PUT */ 95 u32 addr = nv_rd32(pmu, 0x10a4cc); 96 if (addr == nv_rd32(pmu, 0x10a4c8)) 97 return; 98 99 /* acquire data segment access */ 100 do { 101 nv_wr32(pmu, 0x10a580, 0x00000002); 102 } while (nv_rd32(pmu, 0x10a580) != 0x00000002); 103 104 /* read the packet */ 105 nv_wr32(pmu, 0x10a1c0, 0x02000000 | (((addr & 0x07) << 4) + 106 pmu->recv.base)); 107 process = nv_rd32(pmu, 0x10a1c4); 108 message = nv_rd32(pmu, 0x10a1c4); 109 data0 = nv_rd32(pmu, 0x10a1c4); 110 data1 = nv_rd32(pmu, 0x10a1c4); 111 nv_wr32(pmu, 0x10a4cc, (addr + 1) & 0x0f); 112 113 /* release data segment access */ 114 nv_wr32(pmu, 0x10a580, 0x00000000); 115 116 /* wake process if it's waiting on a synchronous reply */ 117 if (pmu->recv.process) { 118 if (process == pmu->recv.process && 119 message == pmu->recv.message) { 120 pmu->recv.data[0] = data0; 121 pmu->recv.data[1] = data1; 122 pmu->recv.process = 0; 123 wake_up(&pmu->recv.wait); 124 return; 125 } 126 } 127 128 /* right now there's no other expected responses from the engine, 129 * so assume that any unexpected message is an error. 130 */ 131 nv_warn(pmu, "%c%c%c%c 0x%08x 0x%08x 0x%08x 0x%08x\n", 132 (char)((process & 0x000000ff) >> 0), 133 (char)((process & 0x0000ff00) >> 8), 134 (char)((process & 0x00ff0000) >> 16), 135 (char)((process & 0xff000000) >> 24), 136 process, message, data0, data1); 137 } 138 139 static void 140 nouveau_pmu_intr(struct nouveau_subdev *subdev) 141 { 142 struct nouveau_pmu *pmu = (void *)subdev; 143 u32 disp = nv_rd32(pmu, 0x10a01c); 144 u32 intr = nv_rd32(pmu, 0x10a008) & disp & ~(disp >> 16); 145 146 if (intr & 0x00000020) { 147 u32 stat = nv_rd32(pmu, 0x10a16c); 148 if (stat & 0x80000000) { 149 nv_error(pmu, "UAS fault at 0x%06x addr 0x%08x\n", 150 stat & 0x00ffffff, nv_rd32(pmu, 0x10a168)); 151 nv_wr32(pmu, 0x10a16c, 0x00000000); 152 intr &= ~0x00000020; 153 } 154 } 155 156 if (intr & 0x00000040) { 157 schedule_work(&pmu->recv.work); 158 nv_wr32(pmu, 0x10a004, 0x00000040); 159 intr &= ~0x00000040; 160 } 161 162 if (intr & 0x00000080) { 163 nv_info(pmu, "wr32 0x%06x 0x%08x\n", nv_rd32(pmu, 0x10a7a0), 164 nv_rd32(pmu, 0x10a7a4)); 165 nv_wr32(pmu, 0x10a004, 0x00000080); 166 intr &= ~0x00000080; 167 } 168 169 if (intr) { 170 nv_error(pmu, "intr 0x%08x\n", intr); 171 nv_wr32(pmu, 0x10a004, intr); 172 } 173 } 174 175 int 176 _nouveau_pmu_fini(struct nouveau_object *object, bool suspend) 177 { 178 struct nouveau_pmu *pmu = (void *)object; 179 180 nv_wr32(pmu, 0x10a014, 0x00000060); 181 flush_work(&pmu->recv.work); 182 183 return nouveau_subdev_fini(&pmu->base, suspend); 184 } 185 186 int 187 _nouveau_pmu_init(struct nouveau_object *object) 188 { 189 const struct nvkm_pmu_impl *impl = (void *)object->oclass; 190 struct nouveau_pmu *pmu = (void *)object; 191 int ret, i; 192 193 ret = nouveau_subdev_init(&pmu->base); 194 if (ret) 195 return ret; 196 197 nv_subdev(pmu)->intr = nouveau_pmu_intr; 198 pmu->message = nouveau_pmu_send; 199 pmu->pgob = nouveau_pmu_pgob; 200 201 /* prevent previous ucode from running, wait for idle, reset */ 202 nv_wr32(pmu, 0x10a014, 0x0000ffff); /* INTR_EN_CLR = ALL */ 203 nv_wait(pmu, 0x10a04c, 0xffffffff, 0x00000000); 204 nv_mask(pmu, 0x000200, 0x00002000, 0x00000000); 205 nv_mask(pmu, 0x000200, 0x00002000, 0x00002000); 206 nv_rd32(pmu, 0x000200); 207 nv_wait(pmu, 0x10a10c, 0x00000006, 0x00000000); 208 209 /* upload data segment */ 210 nv_wr32(pmu, 0x10a1c0, 0x01000000); 211 for (i = 0; i < impl->data.size / 4; i++) 212 nv_wr32(pmu, 0x10a1c4, impl->data.data[i]); 213 214 /* upload code segment */ 215 nv_wr32(pmu, 0x10a180, 0x01000000); 216 for (i = 0; i < impl->code.size / 4; i++) { 217 if ((i & 0x3f) == 0) 218 nv_wr32(pmu, 0x10a188, i >> 6); 219 nv_wr32(pmu, 0x10a184, impl->code.data[i]); 220 } 221 222 /* start it running */ 223 nv_wr32(pmu, 0x10a10c, 0x00000000); 224 nv_wr32(pmu, 0x10a104, 0x00000000); 225 nv_wr32(pmu, 0x10a100, 0x00000002); 226 227 /* wait for valid host->pmu ring configuration */ 228 if (!nv_wait_ne(pmu, 0x10a4d0, 0xffffffff, 0x00000000)) 229 return -EBUSY; 230 pmu->send.base = nv_rd32(pmu, 0x10a4d0) & 0x0000ffff; 231 pmu->send.size = nv_rd32(pmu, 0x10a4d0) >> 16; 232 233 /* wait for valid pmu->host ring configuration */ 234 if (!nv_wait_ne(pmu, 0x10a4dc, 0xffffffff, 0x00000000)) 235 return -EBUSY; 236 pmu->recv.base = nv_rd32(pmu, 0x10a4dc) & 0x0000ffff; 237 pmu->recv.size = nv_rd32(pmu, 0x10a4dc) >> 16; 238 239 nv_wr32(pmu, 0x10a010, 0x000000e0); 240 return 0; 241 } 242 243 int 244 nouveau_pmu_create_(struct nouveau_object *parent, 245 struct nouveau_object *engine, 246 struct nouveau_oclass *oclass, int length, void **pobject) 247 { 248 struct nouveau_pmu *pmu; 249 int ret; 250 251 ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PMU", 252 "pmu", length, pobject); 253 pmu = *pobject; 254 if (ret) 255 return ret; 256 257 INIT_WORK(&pmu->recv.work, nouveau_pmu_recv); 258 init_waitqueue_head(&pmu->recv.wait); 259 return 0; 260 } 261 262 int 263 _nouveau_pmu_ctor(struct nouveau_object *parent, 264 struct nouveau_object *engine, 265 struct nouveau_oclass *oclass, void *data, u32 size, 266 struct nouveau_object **pobject) 267 { 268 struct nouveau_pmu *pmu; 269 int ret = nouveau_pmu_create(parent, engine, oclass, &pmu); 270 *pobject = nv_object(pmu); 271 return ret; 272 } 273