Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
nve0.c
Go to the documentation of this file.
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 
25 #include "nvc0.h"
26 #include "fuc/hubnve0.fuc.h"
27 #include "fuc/gpcnve0.fuc.h"
28 
29 /*******************************************************************************
30  * Graphics object classes
31  ******************************************************************************/
32 
33 static struct nouveau_oclass
34 nve0_graph_sclass[] = {
35  { 0x902d, &nouveau_object_ofuncs },
36  { 0xa040, &nouveau_object_ofuncs },
37  { 0xa097, &nouveau_object_ofuncs },
38  { 0xa0c0, &nouveau_object_ofuncs },
39  { 0xa0b5, &nouveau_object_ofuncs },
40  {}
41 };
42 
43 /*******************************************************************************
44  * PGRAPH context
45  ******************************************************************************/
46 
47 static struct nouveau_oclass
48 nve0_graph_cclass = {
49  .handle = NV_ENGCTX(GR, 0xe0),
50  .ofuncs = &(struct nouveau_ofuncs) {
57  },
58 };
59 
60 /*******************************************************************************
61  * PGRAPH engine/subdev functions
62  ******************************************************************************/
63 
64 static void
65 nve0_graph_ctxctl_isr(struct nvc0_graph_priv *priv)
66 {
67  u32 ustat = nv_rd32(priv, 0x409c18);
68 
69  if (ustat & 0x00000001)
70  nv_error(priv, "CTXCTRL ucode error\n");
71  if (ustat & 0x00080000)
72  nv_error(priv, "CTXCTRL watchdog timeout\n");
73  if (ustat & ~0x00080001)
74  nv_error(priv, "CTXCTRL 0x%08x\n", ustat);
75 
77  nv_wr32(priv, 0x409c20, ustat);
78 }
79 
80 static void
81 nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst)
82 {
83  u32 trap = nv_rd32(priv, 0x400108);
84  int rop;
85 
86  if (trap & 0x00000001) {
87  u32 stat = nv_rd32(priv, 0x404000);
88  nv_error(priv, "DISPATCH ch %d [0x%010llx] 0x%08x\n",
89  chid, inst, stat);
90  nv_wr32(priv, 0x404000, 0xc0000000);
91  nv_wr32(priv, 0x400108, 0x00000001);
92  trap &= ~0x00000001;
93  }
94 
95  if (trap & 0x00000010) {
96  u32 stat = nv_rd32(priv, 0x405840);
97  nv_error(priv, "SHADER ch %d [0x%010llx] 0x%08x\n",
98  chid, inst, stat);
99  nv_wr32(priv, 0x405840, 0xc0000000);
100  nv_wr32(priv, 0x400108, 0x00000010);
101  trap &= ~0x00000010;
102  }
103 
104  if (trap & 0x02000000) {
105  for (rop = 0; rop < priv->rop_nr; rop++) {
106  u32 statz = nv_rd32(priv, ROP_UNIT(rop, 0x070));
107  u32 statc = nv_rd32(priv, ROP_UNIT(rop, 0x144));
108  nv_error(priv, "ROP%d ch %d [0x%010llx] 0x%08x 0x%08x\n",
109  rop, chid, inst, statz, statc);
110  nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000);
111  nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000);
112  }
113  nv_wr32(priv, 0x400108, 0x02000000);
114  trap &= ~0x02000000;
115  }
116 
117  if (trap) {
118  nv_error(priv, "TRAP ch %d [0x%010llx] 0x%08x\n",
119  chid, inst, trap);
120  nv_wr32(priv, 0x400108, trap);
121  }
122 }
123 
124 static void
125 nve0_graph_intr(struct nouveau_subdev *subdev)
126 {
127  struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
128  struct nouveau_engine *engine = nv_engine(subdev);
129  struct nouveau_object *engctx;
130  struct nouveau_handle *handle;
131  struct nvc0_graph_priv *priv = (void *)subdev;
132  u64 inst = nv_rd32(priv, 0x409b00) & 0x0fffffff;
133  u32 stat = nv_rd32(priv, 0x400100);
134  u32 addr = nv_rd32(priv, 0x400704);
135  u32 mthd = (addr & 0x00003ffc);
136  u32 subc = (addr & 0x00070000) >> 16;
137  u32 data = nv_rd32(priv, 0x400708);
138  u32 code = nv_rd32(priv, 0x400110);
139  u32 class = nv_rd32(priv, 0x404200 + (subc * 4));
140  int chid;
141 
142  engctx = nouveau_engctx_get(engine, inst);
143  chid = pfifo->chid(pfifo, engctx);
144 
145  if (stat & 0x00000010) {
146  handle = nouveau_handle_get_class(engctx, class);
147  if (!handle || nv_call(handle->object, mthd, data)) {
148  nv_error(priv, "ILLEGAL_MTHD ch %d [0x%010llx] "
149  "subc %d class 0x%04x mthd 0x%04x "
150  "data 0x%08x\n",
151  chid, inst, subc, class, mthd, data);
152  }
153  nouveau_handle_put(handle);
154  nv_wr32(priv, 0x400100, 0x00000010);
155  stat &= ~0x00000010;
156  }
157 
158  if (stat & 0x00000020) {
159  nv_error(priv, "ILLEGAL_CLASS ch %d [0x%010llx] subc %d "
160  "class 0x%04x mthd 0x%04x data 0x%08x\n",
161  chid, inst, subc, class, mthd, data);
162  nv_wr32(priv, 0x400100, 0x00000020);
163  stat &= ~0x00000020;
164  }
165 
166  if (stat & 0x00100000) {
167  nv_error(priv, "DATA_ERROR [");
169  printk("] ch %d [0x%010llx] subc %d class 0x%04x "
170  "mthd 0x%04x data 0x%08x\n",
171  chid, inst, subc, class, mthd, data);
172  nv_wr32(priv, 0x400100, 0x00100000);
173  stat &= ~0x00100000;
174  }
175 
176  if (stat & 0x00200000) {
177  nve0_graph_trap_isr(priv, chid, inst);
178  nv_wr32(priv, 0x400100, 0x00200000);
179  stat &= ~0x00200000;
180  }
181 
182  if (stat & 0x00080000) {
183  nve0_graph_ctxctl_isr(priv);
184  nv_wr32(priv, 0x400100, 0x00080000);
185  stat &= ~0x00080000;
186  }
187 
188  if (stat) {
189  nv_error(priv, "unknown stat 0x%08x\n", stat);
190  nv_wr32(priv, 0x400100, stat);
191  }
192 
193  nv_wr32(priv, 0x400500, 0x00010001);
194  nouveau_engctx_put(engctx);
195 }
196 
197 static int
198 nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
199  struct nouveau_oclass *oclass, void *data, u32 size,
200  struct nouveau_object **pobject)
201 {
202  struct nouveau_device *device = nv_device(parent);
203  struct nvc0_graph_priv *priv;
204  int ret, i;
205 
206  ret = nouveau_graph_create(parent, engine, oclass, false, &priv);
207  *pobject = nv_object(priv);
208  if (ret)
209  return ret;
210 
211  nv_subdev(priv)->unit = 0x18001000;
212  nv_subdev(priv)->intr = nve0_graph_intr;
213  nv_engine(priv)->cclass = &nve0_graph_cclass;
214  nv_engine(priv)->sclass = nve0_graph_sclass;
215 
216  if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) {
217  nv_info(priv, "using external firmware\n");
218  if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
219  nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) ||
220  nvc0_graph_ctor_fw(priv, "fuc41ac", &priv->fuc41ac) ||
221  nvc0_graph_ctor_fw(priv, "fuc41ad", &priv->fuc41ad))
222  return -EINVAL;
223  priv->firmware = true;
224  }
225 
226  ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b4);
227  if (ret)
228  return ret;
229 
230  ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b8);
231  if (ret)
232  return ret;
233 
234  for (i = 0; i < 0x1000; i += 4) {
235  nv_wo32(priv->unk4188b4, i, 0x00000010);
236  nv_wo32(priv->unk4188b8, i, 0x00000010);
237  }
238 
239  priv->gpc_nr = nv_rd32(priv, 0x409604) & 0x0000001f;
240  priv->rop_nr = (nv_rd32(priv, 0x409604) & 0x001f0000) >> 16;
241  for (i = 0; i < priv->gpc_nr; i++) {
242  priv->tpc_nr[i] = nv_rd32(priv, GPC_UNIT(i, 0x2608));
243  priv->tpc_total += priv->tpc_nr[i];
244  }
245 
246  switch (nv_device(priv)->chipset) {
247  case 0xe4:
248  if (priv->tpc_total == 8)
249  priv->magic_not_rop_nr = 3;
250  else
251  if (priv->tpc_total == 7)
252  priv->magic_not_rop_nr = 1;
253  break;
254  case 0xe7:
255  priv->magic_not_rop_nr = 1;
256  break;
257  default:
258  break;
259  }
260 
261  return 0;
262 }
263 
264 static void
265 nve0_graph_init_obj418880(struct nvc0_graph_priv *priv)
266 {
267  int i;
268 
269  nv_wr32(priv, GPC_BCAST(0x0880), 0x00000000);
270  nv_wr32(priv, GPC_BCAST(0x08a4), 0x00000000);
271  for (i = 0; i < 4; i++)
272  nv_wr32(priv, GPC_BCAST(0x0888) + (i * 4), 0x00000000);
273  nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8);
274  nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8);
275 }
276 
277 static void
278 nve0_graph_init_regs(struct nvc0_graph_priv *priv)
279 {
280  nv_wr32(priv, 0x400080, 0x003083c2);
281  nv_wr32(priv, 0x400088, 0x0001ffe7);
282  nv_wr32(priv, 0x40008c, 0x00000000);
283  nv_wr32(priv, 0x400090, 0x00000030);
284  nv_wr32(priv, 0x40013c, 0x003901f7);
285  nv_wr32(priv, 0x400140, 0x00000100);
286  nv_wr32(priv, 0x400144, 0x00000000);
287  nv_wr32(priv, 0x400148, 0x00000110);
288  nv_wr32(priv, 0x400138, 0x00000000);
289  nv_wr32(priv, 0x400130, 0x00000000);
290  nv_wr32(priv, 0x400134, 0x00000000);
291  nv_wr32(priv, 0x400124, 0x00000002);
292 }
293 
294 static void
295 nve0_graph_init_units(struct nvc0_graph_priv *priv)
296 {
297  nv_wr32(priv, 0x409ffc, 0x00000000);
298  nv_wr32(priv, 0x409c14, 0x00003e3e);
299  nv_wr32(priv, 0x409c24, 0x000f0000);
300 
301  nv_wr32(priv, 0x404000, 0xc0000000);
302  nv_wr32(priv, 0x404600, 0xc0000000);
303  nv_wr32(priv, 0x408030, 0xc0000000);
304  nv_wr32(priv, 0x404490, 0xc0000000);
305  nv_wr32(priv, 0x406018, 0xc0000000);
306  nv_wr32(priv, 0x407020, 0xc0000000);
307  nv_wr32(priv, 0x405840, 0xc0000000);
308  nv_wr32(priv, 0x405844, 0x00ffffff);
309 
310  nv_mask(priv, 0x419cc0, 0x00000008, 0x00000008);
311  nv_mask(priv, 0x419eb4, 0x00001000, 0x00001000);
312 
313 }
314 
315 static void
316 nve0_graph_init_gpc_0(struct nvc0_graph_priv *priv)
317 {
318  const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total);
319  u32 data[TPC_MAX / 8];
320  u8 tpcnr[GPC_MAX];
321  int i, gpc, tpc;
322 
323  nv_wr32(priv, GPC_UNIT(0, 0x3018), 0x00000001);
324 
325  memset(data, 0x00, sizeof(data));
326  memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
327  for (i = 0, gpc = -1; i < priv->tpc_total; i++) {
328  do {
329  gpc = (gpc + 1) % priv->gpc_nr;
330  } while (!tpcnr[gpc]);
331  tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;
332 
333  data[i / 8] |= tpc << ((i % 8) * 4);
334  }
335 
336  nv_wr32(priv, GPC_BCAST(0x0980), data[0]);
337  nv_wr32(priv, GPC_BCAST(0x0984), data[1]);
338  nv_wr32(priv, GPC_BCAST(0x0988), data[2]);
339  nv_wr32(priv, GPC_BCAST(0x098c), data[3]);
340 
341  for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
342  nv_wr32(priv, GPC_UNIT(gpc, 0x0914), priv->magic_not_rop_nr << 8 |
343  priv->tpc_nr[gpc]);
344  nv_wr32(priv, GPC_UNIT(gpc, 0x0910), 0x00040000 | priv->tpc_total);
345  nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918);
346  }
347 
348  nv_wr32(priv, GPC_BCAST(0x1bd4), magicgpc918);
349  nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800));
350 }
351 
352 static void
353 nve0_graph_init_gpc_1(struct nvc0_graph_priv *priv)
354 {
355  int gpc, tpc;
356 
357  for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
358  nv_wr32(priv, GPC_UNIT(gpc, 0x3038), 0xc0000000);
359  nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000);
360  nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000);
361  nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000);
362  nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000);
363  for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
364  nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff);
365  nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff);
366  nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000);
367  nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000);
368  nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000);
369  nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x644), 0x001ffffe);
370  nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x64c), 0x0000000f);
371  }
372  nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0xffffffff);
373  nv_wr32(priv, GPC_UNIT(gpc, 0x2c94), 0xffffffff);
374  }
375 }
376 
377 static void
378 nve0_graph_init_rop(struct nvc0_graph_priv *priv)
379 {
380  int rop;
381 
382  for (rop = 0; rop < priv->rop_nr; rop++) {
383  nv_wr32(priv, ROP_UNIT(rop, 0x144), 0xc0000000);
384  nv_wr32(priv, ROP_UNIT(rop, 0x070), 0xc0000000);
385  nv_wr32(priv, ROP_UNIT(rop, 0x204), 0xffffffff);
386  nv_wr32(priv, ROP_UNIT(rop, 0x208), 0xffffffff);
387  }
388 }
389 
390 static int
391 nve0_graph_init_ctxctl(struct nvc0_graph_priv *priv)
392 {
393  u32 r000260;
394  int i;
395 
396  if (priv->firmware) {
397  /* load fuc microcode */
398  r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
399  nvc0_graph_init_fw(priv, 0x409000, &priv->fuc409c, &priv->fuc409d);
400  nvc0_graph_init_fw(priv, 0x41a000, &priv->fuc41ac, &priv->fuc41ad);
401  nv_wr32(priv, 0x000260, r000260);
402 
403  /* start both of them running */
404  nv_wr32(priv, 0x409840, 0xffffffff);
405  nv_wr32(priv, 0x41a10c, 0x00000000);
406  nv_wr32(priv, 0x40910c, 0x00000000);
407  nv_wr32(priv, 0x41a100, 0x00000002);
408  nv_wr32(priv, 0x409100, 0x00000002);
409  if (!nv_wait(priv, 0x409800, 0x00000001, 0x00000001))
410  nv_error(priv, "0x409800 wait failed\n");
411 
412  nv_wr32(priv, 0x409840, 0xffffffff);
413  nv_wr32(priv, 0x409500, 0x7fffffff);
414  nv_wr32(priv, 0x409504, 0x00000021);
415 
416  nv_wr32(priv, 0x409840, 0xffffffff);
417  nv_wr32(priv, 0x409500, 0x00000000);
418  nv_wr32(priv, 0x409504, 0x00000010);
419  if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
420  nv_error(priv, "fuc09 req 0x10 timeout\n");
421  return -EBUSY;
422  }
423  priv->size = nv_rd32(priv, 0x409800);
424 
425  nv_wr32(priv, 0x409840, 0xffffffff);
426  nv_wr32(priv, 0x409500, 0x00000000);
427  nv_wr32(priv, 0x409504, 0x00000016);
428  if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
429  nv_error(priv, "fuc09 req 0x16 timeout\n");
430  return -EBUSY;
431  }
432 
433  nv_wr32(priv, 0x409840, 0xffffffff);
434  nv_wr32(priv, 0x409500, 0x00000000);
435  nv_wr32(priv, 0x409504, 0x00000025);
436  if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
437  nv_error(priv, "fuc09 req 0x25 timeout\n");
438  return -EBUSY;
439  }
440 
441  nv_wr32(priv, 0x409800, 0x00000000);
442  nv_wr32(priv, 0x409500, 0x00000001);
443  nv_wr32(priv, 0x409504, 0x00000030);
444  if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
445  nv_error(priv, "fuc09 req 0x30 timeout\n");
446  return -EBUSY;
447  }
448 
449  nv_wr32(priv, 0x409810, 0xb00095c8);
450  nv_wr32(priv, 0x409800, 0x00000000);
451  nv_wr32(priv, 0x409500, 0x00000001);
452  nv_wr32(priv, 0x409504, 0x00000031);
453  if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
454  nv_error(priv, "fuc09 req 0x31 timeout\n");
455  return -EBUSY;
456  }
457 
458  nv_wr32(priv, 0x409810, 0x00080420);
459  nv_wr32(priv, 0x409800, 0x00000000);
460  nv_wr32(priv, 0x409500, 0x00000001);
461  nv_wr32(priv, 0x409504, 0x00000032);
462  if (!nv_wait_ne(priv, 0x409800, 0xffffffff, 0x00000000)) {
463  nv_error(priv, "fuc09 req 0x32 timeout\n");
464  return -EBUSY;
465  }
466 
467  nv_wr32(priv, 0x409614, 0x00000070);
468  nv_wr32(priv, 0x409614, 0x00000770);
469  nv_wr32(priv, 0x40802c, 0x00000001);
470 
471  if (priv->data == NULL) {
472  int ret = nve0_grctx_generate(priv);
473  if (ret) {
474  nv_error(priv, "failed to construct context\n");
475  return ret;
476  }
477  }
478 
479  return 0;
480  }
481 
482  /* load HUB microcode */
483  r000260 = nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
484  nv_wr32(priv, 0x4091c0, 0x01000000);
485  for (i = 0; i < sizeof(nve0_grhub_data) / 4; i++)
486  nv_wr32(priv, 0x4091c4, nve0_grhub_data[i]);
487 
488  nv_wr32(priv, 0x409180, 0x01000000);
489  for (i = 0; i < sizeof(nve0_grhub_code) / 4; i++) {
490  if ((i & 0x3f) == 0)
491  nv_wr32(priv, 0x409188, i >> 6);
492  nv_wr32(priv, 0x409184, nve0_grhub_code[i]);
493  }
494 
495  /* load GPC microcode */
496  nv_wr32(priv, 0x41a1c0, 0x01000000);
497  for (i = 0; i < sizeof(nve0_grgpc_data) / 4; i++)
498  nv_wr32(priv, 0x41a1c4, nve0_grgpc_data[i]);
499 
500  nv_wr32(priv, 0x41a180, 0x01000000);
501  for (i = 0; i < sizeof(nve0_grgpc_code) / 4; i++) {
502  if ((i & 0x3f) == 0)
503  nv_wr32(priv, 0x41a188, i >> 6);
504  nv_wr32(priv, 0x41a184, nve0_grgpc_code[i]);
505  }
506  nv_wr32(priv, 0x000260, r000260);
507 
508  /* start HUB ucode running, it'll init the GPCs */
509  nv_wr32(priv, 0x409800, nv_device(priv)->chipset);
510  nv_wr32(priv, 0x40910c, 0x00000000);
511  nv_wr32(priv, 0x409100, 0x00000002);
512  if (!nv_wait(priv, 0x409800, 0x80000000, 0x80000000)) {
513  nv_error(priv, "HUB_INIT timed out\n");
515  return -EBUSY;
516  }
517 
518  priv->size = nv_rd32(priv, 0x409804);
519  if (priv->data == NULL) {
520  int ret = nve0_grctx_generate(priv);
521  if (ret) {
522  nv_error(priv, "failed to construct context\n");
523  return ret;
524  }
525  }
526 
527  return 0;
528 }
529 
530 static int
531 nve0_graph_init(struct nouveau_object *object)
532 {
533  struct nvc0_graph_priv *priv = (void *)object;
534  int ret;
535 
536  ret = nouveau_graph_init(&priv->base);
537  if (ret)
538  return ret;
539 
540  nve0_graph_init_obj418880(priv);
541  nve0_graph_init_regs(priv);
542  nve0_graph_init_gpc_0(priv);
543 
544  nv_wr32(priv, 0x400500, 0x00010001);
545  nv_wr32(priv, 0x400100, 0xffffffff);
546  nv_wr32(priv, 0x40013c, 0xffffffff);
547 
548  nve0_graph_init_units(priv);
549  nve0_graph_init_gpc_1(priv);
550  nve0_graph_init_rop(priv);
551 
552  nv_wr32(priv, 0x400108, 0xffffffff);
553  nv_wr32(priv, 0x400138, 0xffffffff);
554  nv_wr32(priv, 0x400118, 0xffffffff);
555  nv_wr32(priv, 0x400130, 0xffffffff);
556  nv_wr32(priv, 0x40011c, 0xffffffff);
557  nv_wr32(priv, 0x400134, 0xffffffff);
558  nv_wr32(priv, 0x400054, 0x34ce3464);
559 
560  ret = nve0_graph_init_ctxctl(priv);
561  if (ret)
562  return ret;
563 
564  return 0;
565 }
566 
567 struct nouveau_oclass
569  .handle = NV_ENGINE(GR, 0xe0),
570  .ofuncs = &(struct nouveau_ofuncs) {
571  .ctor = nve0_graph_ctor,
572  .dtor = nvc0_graph_dtor,
573  .init = nve0_graph_init,
574  .fini = _nouveau_graph_fini,
575  },
576 };