Эх сурвалжийг харах

Merge branch 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next

- first stage of (ongoing) gpu fault recovery work
- initial support for maxwell (binary driver fw needed)
- various random fixes across the board

* 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: (87 commits)
  drm/nouveau: fix missing newline
  drm/nouveau/bios: fetch the vbios from PROM using only aligned 32-bit accesses
  drm/nouveau/therm: let the vbios decide on the automatic fan management mode
  drm/nvd7/therm: handle another kind of PWM fans
  drm/nouveau/pm/fan: drop the fan lock in fan_update() before rescheduling
  drm/nouveau: fix small thinko in vblank timestamping.
  drm/nouveau/therm: check for sensor presence with requested mode, not current
  drm/nouveau/disp/dp: allow 540MHz data rate
  drm/nouveau: recognise higher link rate for available dp bw calculations
  drm/nouveau/disp: limit dp capabilities as per dcb
  drm/nva3/fbram: restrict training pattern setup to GT218
  drm/nva3/devinit: restrict script access to some PFB regs
  drm/nouveau/devinit: add interface to check if a mmio access by scripts is ok
  drm/nouveau/bios: have strap reads show on devinit spam debug level
  drm/nv50/gpio: fixup reset for gpios >= 16
  drm/nv50/gpio: exclude sense value from mask when changing registers
  drm/gk104/gr: therm magic needed on some kepler boards
  drm/gm107/gr: initial support
  drm/gf100-/gf: fix a stupid typo, waiting on wrong signal for mmctx
  drm/nouveau/bios: parsing of some random table needed to bring up gr
  ...
Dave Airlie 11 жил өмнө
parent
commit
e954a2044e
100 өөрчлөгдсөн 9199 нэмэгдсэн , 4123 устгасан
  1. 13 3
      drivers/gpu/drm/nouveau/Makefile
  2. 1 1
      drivers/gpu/drm/nouveau/core/core/namedb.c
  3. 1 1
      drivers/gpu/drm/nouveau/core/core/parent.c
  4. 80 5
      drivers/gpu/drm/nouveau/core/engine/device/base.c
  5. 106 0
      drivers/gpu/drm/nouveau/core/engine/device/gm100.c
  6. 2 2
      drivers/gpu/drm/nouveau/core/engine/device/nv04.c
  7. 8 8
      drivers/gpu/drm/nouveau/core/engine/device/nv10.c
  8. 4 4
      drivers/gpu/drm/nouveau/core/engine/device/nv20.c
  9. 5 5
      drivers/gpu/drm/nouveau/core/engine/device/nv30.c
  10. 16 16
      drivers/gpu/drm/nouveau/core/engine/device/nv40.c
  11. 14 14
      drivers/gpu/drm/nouveau/core/engine/device/nv50.c
  12. 22 22
      drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
  13. 10 10
      drivers/gpu/drm/nouveau/core/engine/device/nve0.c
  14. 9 1
      drivers/gpu/drm/nouveau/core/engine/disp/dport.c
  15. 101 0
      drivers/gpu/drm/nouveau/core/engine/disp/gm107.c
  16. 6 6
      drivers/gpu/drm/nouveau/core/engine/disp/nv04.c
  17. 344 26
      drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
  18. 53 1
      drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
  19. 186 5
      drivers/gpu/drm/nouveau/core/engine/disp/nv84.c
  20. 45 5
      drivers/gpu/drm/nouveau/core/engine/disp/nv94.c
  21. 62 5
      drivers/gpu/drm/nouveau/core/engine/disp/nva0.c
  22. 17 5
      drivers/gpu/drm/nouveau/core/engine/disp/nva3.c
  23. 343 18
      drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
  24. 182 5
      drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
  25. 17 5
      drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c
  26. 10 0
      drivers/gpu/drm/nouveau/core/engine/disp/priv.h
  27. 3 0
      drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c
  28. 3 3
      drivers/gpu/drm/nouveau/core/engine/falcon.c
  29. 1 1
      drivers/gpu/drm/nouveau/core/engine/fifo/base.c
  30. 369 140
      drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
  31. 356 151
      drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
  32. 989 0
      drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c
  33. 115 926
      drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c
  34. 192 116
      drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c
  35. 170 0
      drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h
  36. 120 150
      drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c
  37. 41 37
      drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc4.c
  38. 64 80
      drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c
  39. 100 116
      drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c
  40. 142 136
      drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c
  41. 144 141
      drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c
  42. 670 112
      drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c
  43. 1 1
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/com.fuc
  44. 6 1
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc
  45. 42 0
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5
  46. 473 0
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5.h
  47. 177 177
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnv108.fuc5.h
  48. 168 168
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h
  49. 198 198
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc.h
  50. 198 198
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h
  51. 198 198
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc.h
  52. 40 0
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5
  53. 916 0
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5.h
  54. 1 1
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnv108.fuc5.h
  55. 1 1
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h
  56. 1 1
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc.h
  57. 1 1
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h
  58. 1 1
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc.h
  59. 1 0
      drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc
  60. 465 0
      drivers/gpu/drm/nouveau/core/engine/graph/gm107.c
  61. 60 73
      drivers/gpu/drm/nouveau/core/engine/graph/nv108.c
  62. 1 1
      drivers/gpu/drm/nouveau/core/engine/graph/nv20.c
  63. 1 1
      drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
  64. 31 14
      drivers/gpu/drm/nouveau/core/engine/graph/nv50.c
  65. 211 101
      drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
  66. 73 141
      drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
  67. 52 63
      drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c
  68. 52 34
      drivers/gpu/drm/nouveau/core/engine/graph/nvc4.c
  69. 39 65
      drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c
  70. 72 103
      drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c
  71. 90 64
      drivers/gpu/drm/nouveau/core/engine/graph/nvd9.c
  72. 99 93
      drivers/gpu/drm/nouveau/core/engine/graph/nve4.c
  73. 66 70
      drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c
  74. 1 1
      drivers/gpu/drm/nouveau/core/engine/xtensa.c
  75. 12 0
      drivers/gpu/drm/nouveau/core/include/core/class.h
  76. 31 0
      drivers/gpu/drm/nouveau/core/include/core/device.h
  77. 1 1
      drivers/gpu/drm/nouveau/core/include/core/namedb.h
  78. 14 4
      drivers/gpu/drm/nouveau/core/include/engine/device.h
  79. 10 9
      drivers/gpu/drm/nouveau/core/include/engine/disp.h
  80. 2 1
      drivers/gpu/drm/nouveau/core/include/engine/graph.h
  81. 23 0
      drivers/gpu/drm/nouveau/core/include/subdev/bios/P0260.h
  82. 1 0
      drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h
  83. 1 1
      drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h
  84. 7 0
      drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h
  85. 2 0
      drivers/gpu/drm/nouveau/core/include/subdev/devinit.h
  86. 1 0
      drivers/gpu/drm/nouveau/core/include/subdev/fb.h
  87. 2 1
      drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h
  88. 1 0
      drivers/gpu/drm/nouveau/core/include/subdev/mc.h
  89. 1 1
      drivers/gpu/drm/nouveau/core/include/subdev/therm.h
  90. 1 0
      drivers/gpu/drm/nouveau/core/include/subdev/timer.h
  91. 1 11
      drivers/gpu/drm/nouveau/core/os.h
  92. 2 2
      drivers/gpu/drm/nouveau/core/subdev/bar/base.c
  93. 5 3
      drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c
  94. 7 8
      drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
  95. 109 0
      drivers/gpu/drm/nouveau/core/subdev/bios/P0260.c
  96. 38 17
      drivers/gpu/drm/nouveau/core/subdev/bios/base.c
  97. 28 1
      drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
  98. 11 7
      drivers/gpu/drm/nouveau/core/subdev/bios/init.c
  99. 5 4
      drivers/gpu/drm/nouveau/core/subdev/bios/ramcfg.c
  100. 11 0
      drivers/gpu/drm/nouveau/core/subdev/bios/therm.c

+ 13 - 3
drivers/gpu/drm/nouveau/Makefile

@@ -48,6 +48,7 @@ nouveau-y += core/subdev/bios/therm.o
 nouveau-y += core/subdev/bios/vmap.o
 nouveau-y += core/subdev/bios/volt.o
 nouveau-y += core/subdev/bios/xpio.o
+nouveau-y += core/subdev/bios/P0260.o
 nouveau-y += core/subdev/bus/hwsq.o
 nouveau-y += core/subdev/bus/nv04.o
 nouveau-y += core/subdev/bus/nv31.o
@@ -77,6 +78,7 @@ nouveau-y += core/subdev/devinit/nv98.o
 nouveau-y += core/subdev/devinit/nva3.o
 nouveau-y += core/subdev/devinit/nvaf.o
 nouveau-y += core/subdev/devinit/nvc0.o
+nouveau-y += core/subdev/devinit/gm107.o
 nouveau-y += core/subdev/fb/base.o
 nouveau-y += core/subdev/fb/nv04.o
 nouveau-y += core/subdev/fb/nv10.o
@@ -100,6 +102,7 @@ nouveau-y += core/subdev/fb/nvaa.o
 nouveau-y += core/subdev/fb/nvaf.o
 nouveau-y += core/subdev/fb/nvc0.o
 nouveau-y += core/subdev/fb/nve0.o
+nouveau-y += core/subdev/fb/gm107.o
 nouveau-y += core/subdev/fb/ramnv04.o
 nouveau-y += core/subdev/fb/ramnv10.o
 nouveau-y += core/subdev/fb/ramnv1a.o
@@ -114,6 +117,7 @@ nouveau-y += core/subdev/fb/ramnva3.o
 nouveau-y += core/subdev/fb/ramnvaa.o
 nouveau-y += core/subdev/fb/ramnvc0.o
 nouveau-y += core/subdev/fb/ramnve0.o
+nouveau-y += core/subdev/fb/ramgm107.o
 nouveau-y += core/subdev/fb/sddr3.o
 nouveau-y += core/subdev/fb/gddr5.o
 nouveau-y += core/subdev/gpio/base.o
@@ -136,7 +140,8 @@ nouveau-y += core/subdev/instmem/base.o
 nouveau-y += core/subdev/instmem/nv04.o
 nouveau-y += core/subdev/instmem/nv40.o
 nouveau-y += core/subdev/instmem/nv50.o
-nouveau-y += core/subdev/ltcg/nvc0.o
+nouveau-y += core/subdev/ltcg/gf100.o
+nouveau-y += core/subdev/ltcg/gm107.o
 nouveau-y += core/subdev/mc/base.o
 nouveau-y += core/subdev/mc/nv04.o
 nouveau-y += core/subdev/mc/nv40.o
@@ -170,6 +175,7 @@ nouveau-y += core/subdev/therm/nva3.o
 nouveau-y += core/subdev/therm/nvd0.o
 nouveau-y += core/subdev/timer/base.o
 nouveau-y += core/subdev/timer/nv04.o
+nouveau-y += core/subdev/timer/gk20a.o
 nouveau-y += core/subdev/vm/base.o
 nouveau-y += core/subdev/vm/nv04.o
 nouveau-y += core/subdev/vm/nv41.o
@@ -206,6 +212,7 @@ nouveau-y += core/engine/device/nv40.o
 nouveau-y += core/engine/device/nv50.o
 nouveau-y += core/engine/device/nvc0.o
 nouveau-y += core/engine/device/nve0.o
+nouveau-y += core/engine/device/gm100.o
 nouveau-y += core/engine/disp/base.o
 nouveau-y += core/engine/disp/nv04.o
 nouveau-y += core/engine/disp/nv50.o
@@ -216,6 +223,7 @@ nouveau-y += core/engine/disp/nva3.o
 nouveau-y += core/engine/disp/nvd0.o
 nouveau-y += core/engine/disp/nve0.o
 nouveau-y += core/engine/disp/nvf0.o
+nouveau-y += core/engine/disp/gm107.o
 nouveau-y += core/engine/disp/dacnv50.o
 nouveau-y += core/engine/disp/dport.o
 nouveau-y += core/engine/disp/hdanva3.o
@@ -242,13 +250,14 @@ nouveau-y += core/engine/graph/ctxnv40.o
 nouveau-y += core/engine/graph/ctxnv50.o
 nouveau-y += core/engine/graph/ctxnvc0.o
 nouveau-y += core/engine/graph/ctxnvc1.o
-nouveau-y += core/engine/graph/ctxnvc3.o
+nouveau-y += core/engine/graph/ctxnvc4.o
 nouveau-y += core/engine/graph/ctxnvc8.o
 nouveau-y += core/engine/graph/ctxnvd7.o
 nouveau-y += core/engine/graph/ctxnvd9.o
 nouveau-y += core/engine/graph/ctxnve4.o
 nouveau-y += core/engine/graph/ctxnvf0.o
 nouveau-y += core/engine/graph/ctxnv108.o
+nouveau-y += core/engine/graph/ctxgm107.o
 nouveau-y += core/engine/graph/nv04.o
 nouveau-y += core/engine/graph/nv10.o
 nouveau-y += core/engine/graph/nv20.o
@@ -261,13 +270,14 @@ nouveau-y += core/engine/graph/nv40.o
 nouveau-y += core/engine/graph/nv50.o
 nouveau-y += core/engine/graph/nvc0.o
 nouveau-y += core/engine/graph/nvc1.o
-nouveau-y += core/engine/graph/nvc3.o
+nouveau-y += core/engine/graph/nvc4.o
 nouveau-y += core/engine/graph/nvc8.o
 nouveau-y += core/engine/graph/nvd7.o
 nouveau-y += core/engine/graph/nvd9.o
 nouveau-y += core/engine/graph/nve4.o
 nouveau-y += core/engine/graph/nvf0.o
 nouveau-y += core/engine/graph/nv108.o
+nouveau-y += core/engine/graph/gm107.o
 nouveau-y += core/engine/mpeg/nv31.o
 nouveau-y += core/engine/mpeg/nv40.o
 nouveau-y += core/engine/mpeg/nv44.o

+ 1 - 1
drivers/gpu/drm/nouveau/core/core/namedb.c

@@ -167,7 +167,7 @@ int
 nouveau_namedb_create_(struct nouveau_object *parent,
 		       struct nouveau_object *engine,
 		       struct nouveau_oclass *oclass, u32 pclass,
-		       struct nouveau_oclass *sclass, u32 engcls,
+		       struct nouveau_oclass *sclass, u64 engcls,
 		       int length, void **pobject)
 {
 	struct nouveau_namedb *namedb;

+ 1 - 1
drivers/gpu/drm/nouveau/core/core/parent.c

@@ -49,7 +49,7 @@ nouveau_parent_sclass(struct nouveau_object *parent, u16 handle,
 
 	mask = nv_parent(parent)->engine;
 	while (mask) {
-		int i = ffsll(mask) - 1;
+		int i = __ffs64(mask);
 
 		if (nv_iclass(parent, NV_CLIENT_CLASS))
 			engine = nv_engine(nv_client(parent)->device);

+ 80 - 5
drivers/gpu/drm/nouveau/core/engine/device/base.c

@@ -131,8 +131,8 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
 	if (ret)
 		return ret;
 
-	mmio_base = pci_resource_start(device->pdev, 0);
-	mmio_size = pci_resource_len(device->pdev, 0);
+	mmio_base = nv_device_resource_start(device, 0);
+	mmio_size = nv_device_resource_len(device, 0);
 
 	/* translate api disable mask into internal mapping */
 	disable = args->debug0;
@@ -185,6 +185,7 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
 			case 0x0e0:
 			case 0x0f0:
 			case 0x100: device->card_type = NV_E0; break;
+			case 0x110: device->card_type = GM100; break;
 			default:
 				break;
 			}
@@ -208,6 +209,7 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
 		case NV_C0:
 		case NV_D0: ret = nvc0_identify(device); break;
 		case NV_E0: ret = nve0_identify(device); break;
+		case GM100: ret = gm100_identify(device); break;
 		default:
 			ret = -EINVAL;
 			break;
@@ -446,6 +448,72 @@ nouveau_device_dtor(struct nouveau_object *object)
 	nouveau_engine_destroy(&device->base);
 }
 
+resource_size_t
+nv_device_resource_start(struct nouveau_device *device, unsigned int bar)
+{
+	if (nv_device_is_pci(device)) {
+		return pci_resource_start(device->pdev, bar);
+	} else {
+		struct resource *res;
+		res = platform_get_resource(device->platformdev,
+					    IORESOURCE_MEM, bar);
+		if (!res)
+			return 0;
+		return res->start;
+	}
+}
+
+resource_size_t
+nv_device_resource_len(struct nouveau_device *device, unsigned int bar)
+{
+	if (nv_device_is_pci(device)) {
+		return pci_resource_len(device->pdev, bar);
+	} else {
+		struct resource *res;
+		res = platform_get_resource(device->platformdev,
+					    IORESOURCE_MEM, bar);
+		if (!res)
+			return 0;
+		return resource_size(res);
+	}
+}
+
+dma_addr_t
+nv_device_map_page(struct nouveau_device *device, struct page *page)
+{
+	dma_addr_t ret;
+
+	if (nv_device_is_pci(device)) {
+		ret = pci_map_page(device->pdev, page, 0, PAGE_SIZE,
+				   PCI_DMA_BIDIRECTIONAL);
+		if (pci_dma_mapping_error(device->pdev, ret))
+			ret = 0;
+	} else {
+		ret = page_to_phys(page);
+	}
+
+	return ret;
+}
+
+void
+nv_device_unmap_page(struct nouveau_device *device, dma_addr_t addr)
+{
+	if (nv_device_is_pci(device))
+		pci_unmap_page(device->pdev, addr, PAGE_SIZE,
+			       PCI_DMA_BIDIRECTIONAL);
+}
+
+int
+nv_device_get_irq(struct nouveau_device *device, bool stall)
+{
+	if (nv_device_is_pci(device)) {
+		return device->pdev->irq;
+	} else {
+		return platform_get_irq_byname(device->platformdev,
+					       stall ? "stall" : "nonstall");
+	}
+}
+
 static struct nouveau_oclass
 nouveau_device_oclass = {
 	.handle = NV_ENGINE(DEVICE, 0x00),
@@ -457,8 +525,8 @@ nouveau_device_oclass = {
 };
 
 int
-nouveau_device_create_(struct pci_dev *pdev, u64 name, const char *sname,
-		       const char *cfg, const char *dbg,
+nouveau_device_create_(void *dev, enum nv_bus_type type, u64 name,
+		       const char *sname, const char *cfg, const char *dbg,
 		       int length, void **pobject)
 {
 	struct nouveau_device *device;
@@ -476,7 +544,14 @@ nouveau_device_create_(struct pci_dev *pdev, u64 name, const char *sname,
 	if (ret)
 		goto done;
 
-	device->pdev = pdev;
+	switch (type) {
+	case NOUVEAU_BUS_PCI:
+		device->pdev = dev;
+		break;
+	case NOUVEAU_BUS_PLATFORM:
+		device->platformdev = dev;
+		break;
+	}
 	device->handle = name;
 	device->cfgopt = cfg;
 	device->dbgopt = dbg;

+ 106 - 0
drivers/gpu/drm/nouveau/core/engine/device/gm100.c

@@ -0,0 +1,106 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/bios.h>
+#include <subdev/bus.h>
+#include <subdev/gpio.h>
+#include <subdev/i2c.h>
+#include <subdev/clock.h>
+#include <subdev/therm.h>
+#include <subdev/mxm.h>
+#include <subdev/devinit.h>
+#include <subdev/mc.h>
+#include <subdev/timer.h>
+#include <subdev/fb.h>
+#include <subdev/ltcg.h>
+#include <subdev/ibus.h>
+#include <subdev/instmem.h>
+#include <subdev/vm.h>
+#include <subdev/bar.h>
+#include <subdev/pwr.h>
+#include <subdev/volt.h>
+
+#include <engine/device.h>
+#include <engine/dmaobj.h>
+#include <engine/fifo.h>
+#include <engine/software.h>
+#include <engine/graph.h>
+#include <engine/disp.h>
+#include <engine/copy.h>
+#include <engine/bsp.h>
+#include <engine/vp.h>
+#include <engine/ppp.h>
+#include <engine/perfmon.h>
+
+int
+gm100_identify(struct nouveau_device *device)
+{
+	switch (device->chipset) {
+	case 0x117:
+		device->cname = "GM107";
+		device->oclass[NVDEV_SUBDEV_VBIOS  ] = &nouveau_bios_oclass;
+		device->oclass[NVDEV_SUBDEV_GPIO   ] = &nve0_gpio_oclass;
+		device->oclass[NVDEV_SUBDEV_I2C    ] = &nvd0_i2c_oclass;
+		device->oclass[NVDEV_SUBDEV_CLOCK  ] = &nve0_clock_oclass;
+#if 0
+		device->oclass[NVDEV_SUBDEV_THERM  ] = &nvd0_therm_oclass;
+#endif
+		device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
+		device->oclass[NVDEV_SUBDEV_DEVINIT] =  gm107_devinit_oclass;
+		device->oclass[NVDEV_SUBDEV_MC     ] =  nvc3_mc_oclass;
+		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass;
+		device->oclass[NVDEV_SUBDEV_TIMER  ] = &gk20a_timer_oclass;
+		device->oclass[NVDEV_SUBDEV_FB     ] =  gm107_fb_oclass;
+		device->oclass[NVDEV_SUBDEV_LTCG   ] =  gm107_ltcg_oclass;
+		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nve0_ibus_oclass;
+		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
+		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
+		device->oclass[NVDEV_SUBDEV_BAR    ] = &nvc0_bar_oclass;
+#if 0
+		device->oclass[NVDEV_SUBDEV_PWR    ] = &nv108_pwr_oclass;
+		device->oclass[NVDEV_SUBDEV_VOLT   ] = &nv40_volt_oclass;
+#endif
+		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
+		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv108_fifo_oclass;
+		device->oclass[NVDEV_ENGINE_SW     ] =  nvc0_software_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  gm107_graph_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  gm107_disp_oclass;
+		device->oclass[NVDEV_ENGINE_COPY0  ] = &nve0_copy0_oclass;
+#if 0
+		device->oclass[NVDEV_ENGINE_COPY1  ] = &nve0_copy1_oclass;
+#endif
+		device->oclass[NVDEV_ENGINE_COPY2  ] = &nve0_copy2_oclass;
+#if 0
+		device->oclass[NVDEV_ENGINE_BSP    ] = &nve0_bsp_oclass;
+		device->oclass[NVDEV_ENGINE_VP     ] = &nve0_vp_oclass;
+		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
+#endif
+		break;
+	default:
+		nv_fatal(device, "unknown Maxwell chipset\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}

+ 2 - 2
drivers/gpu/drm/nouveau/core/engine/device/nv04.c

@@ -60,7 +60,7 @@ nv04_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv04_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv04_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv04_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	case 0x05:
 		device->cname = "NV05";
@@ -78,7 +78,7 @@ nv04_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv04_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv04_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv04_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	default:
 		nv_fatal(device, "unknown RIVA chipset\n");

+ 8 - 8
drivers/gpu/drm/nouveau/core/engine/device/nv10.c

@@ -60,7 +60,7 @@ nv10_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nv04_vmmgr_oclass;
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv10_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	case 0x15:
 		device->cname = "NV15";
@@ -79,7 +79,7 @@ nv10_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv10_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv10_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	case 0x16:
 		device->cname = "NV16";
@@ -98,7 +98,7 @@ nv10_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv10_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv10_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	case 0x1a:
 		device->cname = "nForce";
@@ -117,7 +117,7 @@ nv10_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv10_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv10_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	case 0x11:
 		device->cname = "NV11";
@@ -136,7 +136,7 @@ nv10_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv10_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv10_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	case 0x17:
 		device->cname = "NV17";
@@ -155,7 +155,7 @@ nv10_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv10_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	case 0x1f:
 		device->cname = "nForce2";
@@ -174,7 +174,7 @@ nv10_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv10_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	case 0x18:
 		device->cname = "NV18";
@@ -193,7 +193,7 @@ nv10_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv10_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	default:
 		nv_fatal(device, "unknown Celsius chipset\n");

+ 4 - 4
drivers/gpu/drm/nouveau/core/engine/device/nv20.c

@@ -63,7 +63,7 @@ nv20_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv20_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	case 0x25:
 		device->cname = "NV25";
@@ -82,7 +82,7 @@ nv20_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv25_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	case 0x28:
 		device->cname = "NV28";
@@ -101,7 +101,7 @@ nv20_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv25_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	case 0x2a:
 		device->cname = "NV2A";
@@ -120,7 +120,7 @@ nv20_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv2a_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	default:
 		nv_fatal(device, "unknown Kelvin chipset\n");

+ 5 - 5
drivers/gpu/drm/nouveau/core/engine/device/nv30.c

@@ -63,7 +63,7 @@ nv30_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv30_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	case 0x35:
 		device->cname = "NV35";
@@ -82,7 +82,7 @@ nv30_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv17_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv35_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	case 0x31:
 		device->cname = "NV31";
@@ -102,7 +102,7 @@ nv30_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv30_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv31_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	case 0x36:
 		device->cname = "NV36";
@@ -122,7 +122,7 @@ nv30_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv35_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv31_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	case 0x34:
 		device->cname = "NV34";
@@ -142,7 +142,7 @@ nv30_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv34_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv31_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		break;
 	default:
 		nv_fatal(device, "unknown Rankine chipset\n");

+ 16 - 16
drivers/gpu/drm/nouveau/core/engine/device/nv40.c

@@ -70,7 +70,7 @@ nv40_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv40_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv40_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv40_perfmon_oclass;
 		break;
 	case 0x41:
@@ -93,7 +93,7 @@ nv40_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv40_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv40_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv40_perfmon_oclass;
 		break;
 	case 0x42:
@@ -116,7 +116,7 @@ nv40_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv40_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv40_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv40_perfmon_oclass;
 		break;
 	case 0x43:
@@ -139,7 +139,7 @@ nv40_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv40_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv40_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv40_perfmon_oclass;
 		break;
 	case 0x45:
@@ -162,7 +162,7 @@ nv40_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv40_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv44_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv40_perfmon_oclass;
 		break;
 	case 0x47:
@@ -185,7 +185,7 @@ nv40_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv40_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv44_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv40_perfmon_oclass;
 		break;
 	case 0x49:
@@ -208,7 +208,7 @@ nv40_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv40_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv44_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv40_perfmon_oclass;
 		break;
 	case 0x4b:
@@ -231,7 +231,7 @@ nv40_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv40_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv44_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv40_perfmon_oclass;
 		break;
 	case 0x44:
@@ -254,7 +254,7 @@ nv40_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv40_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv44_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv40_perfmon_oclass;
 		break;
 	case 0x46:
@@ -277,7 +277,7 @@ nv40_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv40_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv44_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv40_perfmon_oclass;
 		break;
 	case 0x4a:
@@ -300,7 +300,7 @@ nv40_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv40_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv44_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv40_perfmon_oclass;
 		break;
 	case 0x4c:
@@ -323,7 +323,7 @@ nv40_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv40_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv44_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv40_perfmon_oclass;
 		break;
 	case 0x4e:
@@ -346,7 +346,7 @@ nv40_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv40_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv44_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv40_perfmon_oclass;
 		break;
 	case 0x63:
@@ -369,7 +369,7 @@ nv40_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv40_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv44_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv40_perfmon_oclass;
 		break;
 	case 0x67:
@@ -392,7 +392,7 @@ nv40_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv40_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv44_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv40_perfmon_oclass;
 		break;
 	case 0x68:
@@ -415,7 +415,7 @@ nv40_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv10_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv40_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv44_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv04_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv04_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv40_perfmon_oclass;
 		break;
 	default:

+ 14 - 14
drivers/gpu/drm/nouveau/core/engine/device/nv50.c

@@ -79,7 +79,7 @@ nv50_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_SW     ] =  nv50_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] = &nv50_graph_oclass;
 		device->oclass[NVDEV_ENGINE_MPEG   ] = &nv50_mpeg_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv50_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv50_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv50_perfmon_oclass;
 		break;
 	case 0x84:
@@ -107,7 +107,7 @@ nv50_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_VP     ] = &nv84_vp_oclass;
 		device->oclass[NVDEV_ENGINE_CRYPT  ] = &nv84_crypt_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nv84_bsp_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv84_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv84_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv84_perfmon_oclass;
 		break;
 	case 0x86:
@@ -135,7 +135,7 @@ nv50_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_VP     ] = &nv84_vp_oclass;
 		device->oclass[NVDEV_ENGINE_CRYPT  ] = &nv84_crypt_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nv84_bsp_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv84_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv84_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv84_perfmon_oclass;
 		break;
 	case 0x92:
@@ -163,7 +163,7 @@ nv50_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_VP     ] = &nv84_vp_oclass;
 		device->oclass[NVDEV_ENGINE_CRYPT  ] = &nv84_crypt_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nv84_bsp_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv84_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv84_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv84_perfmon_oclass;
 		break;
 	case 0x94:
@@ -191,7 +191,7 @@ nv50_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_VP     ] = &nv84_vp_oclass;
 		device->oclass[NVDEV_ENGINE_CRYPT  ] = &nv84_crypt_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nv84_bsp_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv94_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv94_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv84_perfmon_oclass;
 		break;
 	case 0x96:
@@ -219,7 +219,7 @@ nv50_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_VP     ] = &nv84_vp_oclass;
 		device->oclass[NVDEV_ENGINE_CRYPT  ] = &nv84_crypt_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nv84_bsp_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv94_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv94_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv84_perfmon_oclass;
 		break;
 	case 0x98:
@@ -247,7 +247,7 @@ nv50_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_CRYPT  ] = &nv98_crypt_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nv98_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nv98_ppp_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv94_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv94_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv84_perfmon_oclass;
 		break;
 	case 0xa0:
@@ -275,7 +275,7 @@ nv50_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_VP     ] = &nv84_vp_oclass;
 		device->oclass[NVDEV_ENGINE_CRYPT  ] = &nv84_crypt_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nv84_bsp_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nva0_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nva0_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv84_perfmon_oclass;
 		break;
 	case 0xaa:
@@ -303,7 +303,7 @@ nv50_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_CRYPT  ] = &nv98_crypt_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nv98_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nv98_ppp_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv94_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv94_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv84_perfmon_oclass;
 		break;
 	case 0xac:
@@ -331,7 +331,7 @@ nv50_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_CRYPT  ] = &nv98_crypt_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nv98_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nv98_ppp_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nv94_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nv94_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nv84_perfmon_oclass;
 		break;
 	case 0xa3:
@@ -361,7 +361,7 @@ nv50_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nv98_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nv98_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nva3_copy_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nva3_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nva3_perfmon_oclass;
 		break;
 	case 0xa5:
@@ -390,7 +390,7 @@ nv50_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nv98_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nv98_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nva3_copy_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nva3_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nva3_perfmon_oclass;
 		break;
 	case 0xa8:
@@ -419,7 +419,7 @@ nv50_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nv98_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nv98_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nva3_copy_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nva3_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nva3_perfmon_oclass;
 		break;
 	case 0xaf:
@@ -448,7 +448,7 @@ nv50_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nv98_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nv98_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nva3_copy_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nva3_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] =  nva3_perfmon_oclass;
 		break;
 	default:

+ 22 - 22
drivers/gpu/drm/nouveau/core/engine/device/nvc0.c

@@ -70,7 +70,7 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_FB     ] =  nvc0_fb_oclass;
-		device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
+		device->oclass[NVDEV_SUBDEV_LTCG   ] =  gf100_ltcg_oclass;
 		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nvc0_ibus_oclass;
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
@@ -86,7 +86,7 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nvc0_copy0_oclass;
 		device->oclass[NVDEV_ENGINE_COPY1  ] = &nvc0_copy1_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nva3_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
 		break;
 	case 0xc4:
@@ -102,7 +102,7 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_FB     ] =  nvc0_fb_oclass;
-		device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
+		device->oclass[NVDEV_SUBDEV_LTCG   ] =  gf100_ltcg_oclass;
 		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nvc0_ibus_oclass;
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
@@ -112,13 +112,13 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nvc0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] =  nvc3_graph_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nvc4_graph_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nvc0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nvc0_copy0_oclass;
 		device->oclass[NVDEV_ENGINE_COPY1  ] = &nvc0_copy1_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nva3_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
 		break;
 	case 0xc3:
@@ -134,7 +134,7 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_FB     ] =  nvc0_fb_oclass;
-		device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
+		device->oclass[NVDEV_SUBDEV_LTCG   ] =  gf100_ltcg_oclass;
 		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nvc0_ibus_oclass;
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
@@ -144,12 +144,12 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nvc0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] =  nvc3_graph_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nvc4_graph_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nvc0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nvc0_copy0_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nva3_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
 		break;
 	case 0xce:
@@ -165,7 +165,7 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_FB     ] =  nvc0_fb_oclass;
-		device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
+		device->oclass[NVDEV_SUBDEV_LTCG   ] =  gf100_ltcg_oclass;
 		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nvc0_ibus_oclass;
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
@@ -175,13 +175,13 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nvc0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] =  nvc3_graph_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nvc4_graph_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nvc0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nvc0_copy0_oclass;
 		device->oclass[NVDEV_ENGINE_COPY1  ] = &nvc0_copy1_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nva3_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
 		break;
 	case 0xcf:
@@ -197,7 +197,7 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_FB     ] =  nvc0_fb_oclass;
-		device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
+		device->oclass[NVDEV_SUBDEV_LTCG   ] =  gf100_ltcg_oclass;
 		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nvc0_ibus_oclass;
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
@@ -207,13 +207,13 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nvc0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nvc0_software_oclass;
-		device->oclass[NVDEV_ENGINE_GR     ] =  nvc3_graph_oclass;
+		device->oclass[NVDEV_ENGINE_GR     ] =  nvc4_graph_oclass;
 		device->oclass[NVDEV_ENGINE_VP     ] = &nvc0_vp_oclass;
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nvc0_copy0_oclass;
 		device->oclass[NVDEV_ENGINE_COPY1  ] = &nvc0_copy1_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nva3_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
 		break;
 	case 0xc1:
@@ -229,7 +229,7 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_FB     ] =  nvc0_fb_oclass;
-		device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
+		device->oclass[NVDEV_SUBDEV_LTCG   ] =  gf100_ltcg_oclass;
 		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nvc0_ibus_oclass;
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
@@ -244,7 +244,7 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nvc0_copy0_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nva3_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
 		break;
 	case 0xc8:
@@ -260,7 +260,7 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_FB     ] =  nvc0_fb_oclass;
-		device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
+		device->oclass[NVDEV_SUBDEV_LTCG   ] =  gf100_ltcg_oclass;
 		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nvc0_ibus_oclass;
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
@@ -276,7 +276,7 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nvc0_copy0_oclass;
 		device->oclass[NVDEV_ENGINE_COPY1  ] = &nvc0_copy1_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nva3_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nva3_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
 		break;
 	case 0xd9:
@@ -292,7 +292,7 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_FB     ] =  nvc0_fb_oclass;
-		device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
+		device->oclass[NVDEV_SUBDEV_LTCG   ] =  gf100_ltcg_oclass;
 		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nvc0_ibus_oclass;
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
@@ -307,7 +307,7 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nvc0_copy0_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nvd0_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nvd0_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
 		break;
 	case 0xd7:
@@ -323,7 +323,7 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_FB     ] =  nvc0_fb_oclass;
-		device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
+		device->oclass[NVDEV_SUBDEV_LTCG   ] =  gf100_ltcg_oclass;
 		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nvc0_ibus_oclass;
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
@@ -336,7 +336,7 @@ nvc0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_BSP    ] = &nvc0_bsp_oclass;
 		device->oclass[NVDEV_ENGINE_PPP    ] = &nvc0_ppp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nvc0_copy0_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nvd0_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nvd0_disp_oclass;
 		device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass;
 		break;
 	default:

+ 10 - 10
drivers/gpu/drm/nouveau/core/engine/device/nve0.c

@@ -70,7 +70,7 @@ nve0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_FB     ] =  nve0_fb_oclass;
-		device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
+		device->oclass[NVDEV_SUBDEV_LTCG   ] =  gf100_ltcg_oclass;
 		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nve0_ibus_oclass;
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
@@ -81,7 +81,7 @@ nve0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nve0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nvc0_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] =  nve4_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nve0_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nve0_disp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nve0_copy0_oclass;
 		device->oclass[NVDEV_ENGINE_COPY1  ] = &nve0_copy1_oclass;
 		device->oclass[NVDEV_ENGINE_COPY2  ] = &nve0_copy2_oclass;
@@ -103,7 +103,7 @@ nve0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_FB     ] =  nve0_fb_oclass;
-		device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
+		device->oclass[NVDEV_SUBDEV_LTCG   ] =  gf100_ltcg_oclass;
 		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nve0_ibus_oclass;
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
@@ -114,7 +114,7 @@ nve0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nve0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nvc0_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] =  nve4_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nve0_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nve0_disp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nve0_copy0_oclass;
 		device->oclass[NVDEV_ENGINE_COPY1  ] = &nve0_copy1_oclass;
 		device->oclass[NVDEV_ENGINE_COPY2  ] = &nve0_copy2_oclass;
@@ -136,7 +136,7 @@ nve0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_FB     ] =  nve0_fb_oclass;
-		device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
+		device->oclass[NVDEV_SUBDEV_LTCG   ] =  gf100_ltcg_oclass;
 		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nve0_ibus_oclass;
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
@@ -147,7 +147,7 @@ nve0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nve0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nvc0_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] =  nve4_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nve0_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nve0_disp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nve0_copy0_oclass;
 		device->oclass[NVDEV_ENGINE_COPY1  ] = &nve0_copy1_oclass;
 		device->oclass[NVDEV_ENGINE_COPY2  ] = &nve0_copy2_oclass;
@@ -169,7 +169,7 @@ nve0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_FB     ] =  nve0_fb_oclass;
-		device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
+		device->oclass[NVDEV_SUBDEV_LTCG   ] =  gf100_ltcg_oclass;
 		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nve0_ibus_oclass;
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
@@ -180,7 +180,7 @@ nve0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nve0_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nvc0_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] =  nvf0_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nvf0_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nvf0_disp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nve0_copy0_oclass;
 		device->oclass[NVDEV_ENGINE_COPY1  ] = &nve0_copy1_oclass;
 		device->oclass[NVDEV_ENGINE_COPY2  ] = &nve0_copy2_oclass;
@@ -204,7 +204,7 @@ nve0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_SUBDEV_BUS    ] =  nvc0_bus_oclass;
 		device->oclass[NVDEV_SUBDEV_TIMER  ] = &nv04_timer_oclass;
 		device->oclass[NVDEV_SUBDEV_FB     ] =  nve0_fb_oclass;
-		device->oclass[NVDEV_SUBDEV_LTCG   ] = &nvc0_ltcg_oclass;
+		device->oclass[NVDEV_SUBDEV_LTCG   ] =  gf100_ltcg_oclass;
 		device->oclass[NVDEV_SUBDEV_IBUS   ] = &nve0_ibus_oclass;
 		device->oclass[NVDEV_SUBDEV_INSTMEM] =  nv50_instmem_oclass;
 		device->oclass[NVDEV_SUBDEV_VM     ] = &nvc0_vmmgr_oclass;
@@ -215,7 +215,7 @@ nve0_identify(struct nouveau_device *device)
 		device->oclass[NVDEV_ENGINE_FIFO   ] =  nv108_fifo_oclass;
 		device->oclass[NVDEV_ENGINE_SW     ] =  nvc0_software_oclass;
 		device->oclass[NVDEV_ENGINE_GR     ] =  nv108_graph_oclass;
-		device->oclass[NVDEV_ENGINE_DISP   ] = &nvf0_disp_oclass;
+		device->oclass[NVDEV_ENGINE_DISP   ] =  nvf0_disp_oclass;
 		device->oclass[NVDEV_ENGINE_COPY0  ] = &nve0_copy0_oclass;
 		device->oclass[NVDEV_ENGINE_COPY1  ] = &nve0_copy1_oclass;
 		device->oclass[NVDEV_ENGINE_COPY2  ] = &nve0_copy2_oclass;

+ 9 - 1
drivers/gpu/drm/nouveau/core/engine/disp/dport.c

@@ -273,7 +273,7 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func,
 		.outp = outp,
 		.head = head,
 	}, *dp = &_dp;
-	const u32 bw_list[] = { 270000, 162000, 0 };
+	const u32 bw_list[] = { 540000, 270000, 162000, 0 };
 	const u32 *link_bw = bw_list;
 	u8  hdr, cnt, len;
 	u32 data;
@@ -312,6 +312,14 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func,
 		ERR("failed to read DPCD\n");
 	}
 
+	/* bring capabilities within encoder limits */
+	if ((dp->dpcd[2] & 0x1f) > dp->outp->dpconf.link_nr) {
+		dp->dpcd[2] &= ~0x1f;
+		dp->dpcd[2] |= dp->outp->dpconf.link_nr;
+	}
+	if (dp->dpcd[1] > dp->outp->dpconf.link_bw)
+		dp->dpcd[1] = dp->outp->dpconf.link_bw;
+
 	/* adjust required bandwidth for 8B/10B coding overhead */
 	datarate = (datarate / 8) * 10;
 

+ 101 - 0
drivers/gpu/drm/nouveau/core/engine/disp/gm107.c

@@ -0,0 +1,101 @@
+/*
+ * Copyright 2012 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <engine/software.h>
+#include <engine/disp.h>
+
+#include <core/class.h>
+
+#include "nv50.h"
+
+/*******************************************************************************
+ * Base display object
+ ******************************************************************************/
+
+static struct nouveau_oclass
+gm107_disp_sclass[] = {
+	{ GM107_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs },
+	{ GM107_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs },
+	{ GM107_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs },
+	{ GM107_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs },
+	{ GM107_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs },
+	{}
+};
+
+static struct nouveau_oclass
+gm107_disp_base_oclass[] = {
+	{ GM107_DISP_CLASS, &nvd0_disp_base_ofuncs, nvd0_disp_base_omthds },
+	{}
+};
+
+/*******************************************************************************
+ * Display engine implementation
+ ******************************************************************************/
+
+static int
+gm107_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
+	       struct nouveau_oclass *oclass, void *data, u32 size,
+	       struct nouveau_object **pobject)
+{
+	struct nv50_disp_priv *priv;
+	int heads = nv_rd32(parent, 0x022448);
+	int ret;
+
+	ret = nouveau_disp_create(parent, engine, oclass, heads,
+				  "PDISP", "display", &priv);
+	*pobject = nv_object(priv);
+	if (ret)
+		return ret;
+
+	nv_engine(priv)->sclass = gm107_disp_base_oclass;
+	nv_engine(priv)->cclass = &nv50_disp_cclass;
+	nv_subdev(priv)->intr = nvd0_disp_intr;
+	INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor);
+	priv->sclass = gm107_disp_sclass;
+	priv->head.nr = heads;
+	priv->dac.nr = 3;
+	priv->sor.nr = 4;
+	priv->dac.power = nv50_dac_power;
+	priv->dac.sense = nv50_dac_sense;
+	priv->sor.power = nv50_sor_power;
+	priv->sor.hda_eld = nvd0_hda_eld;
+	priv->sor.hdmi = nvd0_hdmi_ctrl;
+	priv->sor.dp = &nvd0_sor_dp_func;
+	return 0;
+}
+
+struct nouveau_oclass *
+gm107_disp_oclass = &(struct nv50_disp_impl) {
+	.base.base.handle = NV_ENGINE(DISP, 0x07),
+	.base.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = gm107_disp_ctor,
+		.dtor = _nouveau_disp_dtor,
+		.init = _nouveau_disp_init,
+		.fini = _nouveau_disp_fini,
+	},
+	.mthd.core = &nve0_disp_mast_mthd_chan,
+	.mthd.base = &nvd0_disp_sync_mthd_chan,
+	.mthd.ovly = &nve0_disp_ovly_mthd_chan,
+	.mthd.prev = -0x020000,
+}.base.base;

+ 6 - 6
drivers/gpu/drm/nouveau/core/engine/disp/nv04.c

@@ -22,7 +22,7 @@
  * Authors: Ben Skeggs
  */
 
-#include <engine/disp.h>
+#include "priv.h"
 
 #include <core/event.h>
 #include <core/class.h>
@@ -138,13 +138,13 @@ nv04_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	return 0;
 }
 
-struct nouveau_oclass
-nv04_disp_oclass = {
-	.handle = NV_ENGINE(DISP, 0x04),
-	.ofuncs = &(struct nouveau_ofuncs) {
+struct nouveau_oclass *
+nv04_disp_oclass = &(struct nouveau_disp_impl) {
+	.base.handle = NV_ENGINE(DISP, 0x04),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nv04_disp_ctor,
 		.dtor = _nouveau_disp_dtor,
 		.init = _nouveau_disp_init,
 		.fini = _nouveau_disp_fini,
 	},
-};
+}.base;

+ 344 - 26
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c

@@ -26,8 +26,7 @@
 #include <core/parent.h>
 #include <core/handle.h>
 #include <core/class.h>
-
-#include <engine/disp.h>
+#include <core/enum.h>
 
 #include <subdev/bios.h>
 #include <subdev/bios/dcb.h>
@@ -227,6 +226,177 @@ nv50_disp_dmac_fini(struct nouveau_object *object, bool suspend)
  * EVO master channel object
  ******************************************************************************/
 
+static void
+nv50_disp_mthd_list(struct nv50_disp_priv *priv, int debug, u32 base, int c,
+		    const struct nv50_disp_mthd_list *list, int inst)
+{
+	struct nouveau_object *disp = nv_object(priv);
+	int i;
+
+	for (i = 0; list->data[i].mthd; i++) {
+		if (list->data[i].addr) {
+			u32 next = nv_rd32(priv, list->data[i].addr + base + 0);
+			u32 prev = nv_rd32(priv, list->data[i].addr + base + c);
+			u32 mthd = list->data[i].mthd + (list->mthd * inst);
+			const char *name = list->data[i].name;
+			char mods[16];
+
+			if (prev != next)
+				snprintf(mods, sizeof(mods), "-> 0x%08x", next);
+			else
+				snprintf(mods, sizeof(mods), "%13c", ' ');
+
+			nv_printk_(disp, debug, "\t0x%04x: 0x%08x %s%s%s\n",
+				   mthd, prev, mods, name ? " // " : "",
+				   name ? name : "");
+		}
+	}
+}
+
+void
+nv50_disp_mthd_chan(struct nv50_disp_priv *priv, int debug, int head,
+		    const struct nv50_disp_mthd_chan *chan)
+{
+	struct nouveau_object *disp = nv_object(priv);
+	const struct nv50_disp_impl *impl = (void *)disp->oclass;
+	const struct nv50_disp_mthd_list *list;
+	int i, j;
+
+	if (debug > nv_subdev(priv)->debug)
+		return;
+
+	for (i = 0; (list = chan->data[i].mthd) != NULL; i++) {
+		u32 base = head * chan->addr;
+		for (j = 0; j < chan->data[i].nr; j++, base += list->addr) {
+			const char *cname = chan->name;
+			const char *sname = "";
+			char cname_[16], sname_[16];
+
+			if (chan->addr) {
+				snprintf(cname_, sizeof(cname_), "%s %d",
+					 chan->name, head);
+				cname = cname_;
+			}
+
+			if (chan->data[i].nr > 1) {
+				snprintf(sname_, sizeof(sname_), " - %s %d",
+					 chan->data[i].name, j);
+				sname = sname_;
+			}
+
+			nv_printk_(disp, debug, "%s%s:\n", cname, sname);
+			nv50_disp_mthd_list(priv, debug, base, impl->mthd.prev,
+					    list, j);
+		}
+	}
+}
+
+const struct nv50_disp_mthd_list
+nv50_disp_mast_mthd_base = {
+	.mthd = 0x0000,
+	.addr = 0x000000,
+	.data = {
+		{ 0x0080, 0x000000 },
+		{ 0x0084, 0x610bb8 },
+		{ 0x0088, 0x610b9c },
+		{ 0x008c, 0x000000 },
+		{}
+	}
+};
+
+static const struct nv50_disp_mthd_list
+nv50_disp_mast_mthd_dac = {
+	.mthd = 0x0080,
+	.addr = 0x000008,
+	.data = {
+		{ 0x0400, 0x610b58 },
+		{ 0x0404, 0x610bdc },
+		{ 0x0420, 0x610828 },
+		{}
+	}
+};
+
+const struct nv50_disp_mthd_list
+nv50_disp_mast_mthd_sor = {
+	.mthd = 0x0040,
+	.addr = 0x000008,
+	.data = {
+		{ 0x0600, 0x610b70 },
+		{}
+	}
+};
+
+const struct nv50_disp_mthd_list
+nv50_disp_mast_mthd_pior = {
+	.mthd = 0x0040,
+	.addr = 0x000008,
+	.data = {
+		{ 0x0700, 0x610b80 },
+		{}
+	}
+};
+
+static const struct nv50_disp_mthd_list
+nv50_disp_mast_mthd_head = {
+	.mthd = 0x0400,
+	.addr = 0x000540,
+	.data = {
+		{ 0x0800, 0x610ad8 },
+		{ 0x0804, 0x610ad0 },
+		{ 0x0808, 0x610a48 },
+		{ 0x080c, 0x610a78 },
+		{ 0x0810, 0x610ac0 },
+		{ 0x0814, 0x610af8 },
+		{ 0x0818, 0x610b00 },
+		{ 0x081c, 0x610ae8 },
+		{ 0x0820, 0x610af0 },
+		{ 0x0824, 0x610b08 },
+		{ 0x0828, 0x610b10 },
+		{ 0x082c, 0x610a68 },
+		{ 0x0830, 0x610a60 },
+		{ 0x0834, 0x000000 },
+		{ 0x0838, 0x610a40 },
+		{ 0x0840, 0x610a24 },
+		{ 0x0844, 0x610a2c },
+		{ 0x0848, 0x610aa8 },
+		{ 0x084c, 0x610ab0 },
+		{ 0x0860, 0x610a84 },
+		{ 0x0864, 0x610a90 },
+		{ 0x0868, 0x610b18 },
+		{ 0x086c, 0x610b20 },
+		{ 0x0870, 0x610ac8 },
+		{ 0x0874, 0x610a38 },
+		{ 0x0880, 0x610a58 },
+		{ 0x0884, 0x610a9c },
+		{ 0x08a0, 0x610a70 },
+		{ 0x08a4, 0x610a50 },
+		{ 0x08a8, 0x610ae0 },
+		{ 0x08c0, 0x610b28 },
+		{ 0x08c4, 0x610b30 },
+		{ 0x08c8, 0x610b40 },
+		{ 0x08d4, 0x610b38 },
+		{ 0x08d8, 0x610b48 },
+		{ 0x08dc, 0x610b50 },
+		{ 0x0900, 0x610a18 },
+		{ 0x0904, 0x610ab8 },
+		{}
+	}
+};
+
+static const struct nv50_disp_mthd_chan
+nv50_disp_mast_mthd_chan = {
+	.name = "Core",
+	.addr = 0x000000,
+	.data = {
+		{ "Global", 1, &nv50_disp_mast_mthd_base },
+		{    "DAC", 3, &nv50_disp_mast_mthd_dac  },
+		{    "SOR", 2, &nv50_disp_mast_mthd_sor  },
+		{   "PIOR", 3, &nv50_disp_mast_mthd_pior },
+		{   "HEAD", 2, &nv50_disp_mast_mthd_head },
+		{}
+	}
+};
+
 static int
 nv50_disp_mast_ctor(struct nouveau_object *parent,
 		    struct nouveau_object *engine,
@@ -323,6 +493,56 @@ nv50_disp_mast_ofuncs = {
  * EVO sync channel objects
  ******************************************************************************/
 
+static const struct nv50_disp_mthd_list
+nv50_disp_sync_mthd_base = {
+	.mthd = 0x0000,
+	.addr = 0x000000,
+	.data = {
+		{ 0x0080, 0x000000 },
+		{ 0x0084, 0x0008c4 },
+		{ 0x0088, 0x0008d0 },
+		{ 0x008c, 0x0008dc },
+		{ 0x0090, 0x0008e4 },
+		{ 0x0094, 0x610884 },
+		{ 0x00a0, 0x6108a0 },
+		{ 0x00a4, 0x610878 },
+		{ 0x00c0, 0x61086c },
+		{ 0x00e0, 0x610858 },
+		{ 0x00e4, 0x610860 },
+		{ 0x00e8, 0x6108ac },
+		{ 0x00ec, 0x6108b4 },
+		{ 0x0100, 0x610894 },
+		{ 0x0110, 0x6108bc },
+		{ 0x0114, 0x61088c },
+		{}
+	}
+};
+
+const struct nv50_disp_mthd_list
+nv50_disp_sync_mthd_image = {
+	.mthd = 0x0400,
+	.addr = 0x000000,
+	.data = {
+		{ 0x0800, 0x6108f0 },
+		{ 0x0804, 0x6108fc },
+		{ 0x0808, 0x61090c },
+		{ 0x080c, 0x610914 },
+		{ 0x0810, 0x610904 },
+		{}
+	}
+};
+
+static const struct nv50_disp_mthd_chan
+nv50_disp_sync_mthd_chan = {
+	.name = "Base",
+	.addr = 0x000540,
+	.data = {
+		{ "Global", 1, &nv50_disp_sync_mthd_base },
+		{  "Image", 2, &nv50_disp_sync_mthd_image },
+		{}
+	}
+};
+
 static int
 nv50_disp_sync_ctor(struct nouveau_object *parent,
 		    struct nouveau_object *engine,
@@ -362,6 +582,44 @@ nv50_disp_sync_ofuncs = {
  * EVO overlay channel objects
  ******************************************************************************/
 
+const struct nv50_disp_mthd_list
+nv50_disp_ovly_mthd_base = {
+	.mthd = 0x0000,
+	.addr = 0x000000,
+	.data = {
+		{ 0x0080, 0x000000 },
+		{ 0x0084, 0x0009a0 },
+		{ 0x0088, 0x0009c0 },
+		{ 0x008c, 0x0009c8 },
+		{ 0x0090, 0x6109b4 },
+		{ 0x0094, 0x610970 },
+		{ 0x00a0, 0x610998 },
+		{ 0x00a4, 0x610964 },
+		{ 0x00c0, 0x610958 },
+		{ 0x00e0, 0x6109a8 },
+		{ 0x00e4, 0x6109d0 },
+		{ 0x00e8, 0x6109d8 },
+		{ 0x0100, 0x61094c },
+		{ 0x0104, 0x610984 },
+		{ 0x0108, 0x61098c },
+		{ 0x0800, 0x6109f8 },
+		{ 0x0808, 0x610a08 },
+		{ 0x080c, 0x610a10 },
+		{ 0x0810, 0x610a00 },
+		{}
+	}
+};
+
+static const struct nv50_disp_mthd_chan
+nv50_disp_ovly_mthd_chan = {
+	.name = "Overlay",
+	.addr = 0x000540,
+	.data = {
+		{ "Global", 1, &nv50_disp_ovly_mthd_base },
+		{}
+	}
+};
+
 static int
 nv50_disp_ovly_ctor(struct nouveau_object *parent,
 		    struct nouveau_object *engine,
@@ -782,25 +1040,78 @@ nv50_disp_cclass = {
  * Display engine implementation
  ******************************************************************************/
 
-static void
-nv50_disp_intr_error(struct nv50_disp_priv *priv)
-{
-	u32 channels = (nv_rd32(priv, 0x610020) & 0x001f0000) >> 16;
-	u32 addr, data;
-	int chid;
-
-	for (chid = 0; chid < 5; chid++) {
-		if (!(channels & (1 << chid)))
-			continue;
+static const struct nouveau_enum
+nv50_disp_intr_error_type[] = {
+	{ 3, "ILLEGAL_MTHD" },
+	{ 4, "INVALID_VALUE" },
+	{ 5, "INVALID_STATE" },
+	{ 7, "INVALID_HANDLE" },
+	{}
+};
 
-		nv_wr32(priv, 0x610020, 0x00010000 << chid);
-		addr = nv_rd32(priv, 0x610080 + (chid * 0x08));
-		data = nv_rd32(priv, 0x610084 + (chid * 0x08));
-		nv_wr32(priv, 0x610080 + (chid * 0x08), 0x90000000);
+static const struct nouveau_enum
+nv50_disp_intr_error_code[] = {
+	{ 0x00, "" },
+	{}
+};
 
-		nv_error(priv, "chid %d mthd 0x%04x data 0x%08x 0x%08x\n",
-			 chid, addr & 0xffc, data, addr);
+static void
+nv50_disp_intr_error(struct nv50_disp_priv *priv, int chid)
+{
+	struct nv50_disp_impl *impl = (void *)nv_object(priv)->oclass;
+	u32 data = nv_rd32(priv, 0x610084 + (chid * 0x08));
+	u32 addr = nv_rd32(priv, 0x610080 + (chid * 0x08));
+	u32 code = (addr & 0x00ff0000) >> 16;
+	u32 type = (addr & 0x00007000) >> 12;
+	u32 mthd = (addr & 0x00000ffc);
+	const struct nouveau_enum *ec, *et;
+	char ecunk[6], etunk[6];
+
+	et = nouveau_enum_find(nv50_disp_intr_error_type, type);
+	if (!et)
+		snprintf(etunk, sizeof(etunk), "UNK%02X", type);
+
+	ec = nouveau_enum_find(nv50_disp_intr_error_code, code);
+	if (!ec)
+		snprintf(ecunk, sizeof(ecunk), "UNK%02X", code);
+
+	nv_error(priv, "%s [%s] chid %d mthd 0x%04x data 0x%08x\n",
+		 et ? et->name : etunk, ec ? ec->name : ecunk,
+		 chid, mthd, data);
+
+	if (chid == 0) {
+		switch (mthd) {
+		case 0x0080:
+			nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 0,
+					    impl->mthd.core);
+			break;
+		default:
+			break;
+		}
+	} else
+	if (chid <= 2) {
+		switch (mthd) {
+		case 0x0080:
+			nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 1,
+					    impl->mthd.base);
+			break;
+		default:
+			break;
+		}
+	} else
+	if (chid <= 4) {
+		switch (mthd) {
+		case 0x0080:
+			nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 3,
+					    impl->mthd.ovly);
+			break;
+		default:
+			break;
+		}
 	}
+
+	nv_wr32(priv, 0x610020, 0x00010000 << chid);
+	nv_wr32(priv, 0x610080 + (chid * 0x08), 0x90000000);
 }
 
 static u16
@@ -1241,12 +1552,14 @@ nv50_disp_intr_supervisor(struct work_struct *work)
 {
 	struct nv50_disp_priv *priv =
 		container_of(work, struct nv50_disp_priv, supervisor);
+	struct nv50_disp_impl *impl = (void *)nv_object(priv)->oclass;
 	u32 super = nv_rd32(priv, 0x610030);
 	int head;
 
 	nv_debug(priv, "supervisor 0x%08x 0x%08x\n", priv->super, super);
 
 	if (priv->super & 0x00000010) {
+		nv50_disp_mthd_chan(priv, NV_DBG_DEBUG, 0, impl->mthd.core);
 		for (head = 0; head < priv->head.nr; head++) {
 			if (!(super & (0x00000020 << head)))
 				continue;
@@ -1290,9 +1603,10 @@ nv50_disp_intr(struct nouveau_subdev *subdev)
 	u32 intr0 = nv_rd32(priv, 0x610020);
 	u32 intr1 = nv_rd32(priv, 0x610024);
 
-	if (intr0 & 0x001f0000) {
-		nv50_disp_intr_error(priv);
-		intr0 &= ~0x001f0000;
+	while (intr0 & 0x001f0000) {
+		u32 chid = __ffs(intr0 & 0x001f0000) - 16;
+		nv50_disp_intr_error(priv, chid);
+		intr0 &= ~(0x00010000 << chid);
 	}
 
 	if (intr1 & 0x00000004) {
@@ -1346,13 +1660,17 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	return 0;
 }
 
-struct nouveau_oclass
-nv50_disp_oclass = {
-	.handle = NV_ENGINE(DISP, 0x50),
-	.ofuncs = &(struct nouveau_ofuncs) {
+struct nouveau_oclass *
+nv50_disp_oclass = &(struct nv50_disp_impl) {
+	.base.base.handle = NV_ENGINE(DISP, 0x50),
+	.base.base.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nv50_disp_ctor,
 		.dtor = _nouveau_disp_dtor,
 		.init = _nouveau_disp_init,
 		.fini = _nouveau_disp_fini,
 	},
-};
+	.mthd.core = &nv50_disp_mast_mthd_chan,
+	.mthd.base = &nv50_disp_sync_mthd_chan,
+	.mthd.ovly = &nv50_disp_ovly_mthd_chan,
+	.mthd.prev = 0x000004,
+}.base.base;

+ 53 - 1
drivers/gpu/drm/nouveau/core/engine/disp/nv50.h

@@ -8,9 +8,19 @@
 #include <core/event.h>
 
 #include <engine/dmaobj.h>
-#include <engine/disp.h>
 
 #include "dport.h"
+#include "priv.h"
+
+struct nv50_disp_impl {
+	struct nouveau_disp_impl base;
+	struct {
+		const struct nv50_disp_mthd_chan *core;
+		const struct nv50_disp_mthd_chan *base;
+		const struct nv50_disp_mthd_chan *ovly;
+		int prev;
+	} mthd;
+};
 
 struct nv50_disp_priv {
 	struct nouveau_disp base;
@@ -124,21 +134,60 @@ struct nv50_disp_pioc {
 	struct nv50_disp_chan base;
 };
 
+struct nv50_disp_mthd_list {
+	u32 mthd;
+	u32 addr;
+	struct {
+		u32 mthd;
+		u32 addr;
+		const char *name;
+	} data[];
+};
+
+struct nv50_disp_mthd_chan {
+	const char *name;
+	u32 addr;
+	struct {
+		const char *name;
+		int nr;
+		const struct nv50_disp_mthd_list *mthd;
+	} data[];
+};
+
 extern struct nouveau_ofuncs nv50_disp_mast_ofuncs;
+extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_base;
+extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_sor;
+extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_pior;
 extern struct nouveau_ofuncs nv50_disp_sync_ofuncs;
+extern const struct nv50_disp_mthd_list nv50_disp_sync_mthd_image;
 extern struct nouveau_ofuncs nv50_disp_ovly_ofuncs;
+extern const struct nv50_disp_mthd_list nv50_disp_ovly_mthd_base;
 extern struct nouveau_ofuncs nv50_disp_oimm_ofuncs;
 extern struct nouveau_ofuncs nv50_disp_curs_ofuncs;
 extern struct nouveau_ofuncs nv50_disp_base_ofuncs;
 extern struct nouveau_oclass nv50_disp_cclass;
+void nv50_disp_mthd_chan(struct nv50_disp_priv *, int debug, int head,
+			 const struct nv50_disp_mthd_chan *);
 void nv50_disp_intr_supervisor(struct work_struct *);
 void nv50_disp_intr(struct nouveau_subdev *);
 
+extern const struct nv50_disp_mthd_chan nv84_disp_mast_mthd_chan;
+extern const struct nv50_disp_mthd_list nv84_disp_mast_mthd_dac;
+extern const struct nv50_disp_mthd_list nv84_disp_mast_mthd_head;
+extern const struct nv50_disp_mthd_chan nv84_disp_sync_mthd_chan;
+extern const struct nv50_disp_mthd_chan nv84_disp_ovly_mthd_chan;
 extern struct nouveau_omthds nv84_disp_base_omthds[];
 
+extern const struct nv50_disp_mthd_chan nv94_disp_mast_mthd_chan;
+
 extern struct nouveau_ofuncs nvd0_disp_mast_ofuncs;
+extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_base;
+extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_dac;
+extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_sor;
+extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_pior;
 extern struct nouveau_ofuncs nvd0_disp_sync_ofuncs;
 extern struct nouveau_ofuncs nvd0_disp_ovly_ofuncs;
+extern const struct nv50_disp_mthd_chan nvd0_disp_sync_mthd_chan;
 extern struct nouveau_ofuncs nvd0_disp_oimm_ofuncs;
 extern struct nouveau_ofuncs nvd0_disp_curs_ofuncs;
 extern struct nouveau_omthds nvd0_disp_base_omthds[];
@@ -147,4 +196,7 @@ extern struct nouveau_oclass nvd0_disp_cclass;
 void nvd0_disp_intr_supervisor(struct work_struct *);
 void nvd0_disp_intr(struct nouveau_subdev *);
 
+extern const struct nv50_disp_mthd_chan nve0_disp_mast_mthd_chan;
+extern const struct nv50_disp_mthd_chan nve0_disp_ovly_mthd_chan;
+
 #endif

+ 186 - 5
drivers/gpu/drm/nouveau/core/engine/disp/nv84.c

@@ -29,6 +29,179 @@
 
 #include "nv50.h"
 
+/*******************************************************************************
+ * EVO master channel object
+ ******************************************************************************/
+
+const struct nv50_disp_mthd_list
+nv84_disp_mast_mthd_dac = {
+	.mthd = 0x0080,
+	.addr = 0x000008,
+	.data = {
+		{ 0x0400, 0x610b58 },
+		{ 0x0404, 0x610bdc },
+		{ 0x0420, 0x610bc4 },
+		{}
+	}
+};
+
+const struct nv50_disp_mthd_list
+nv84_disp_mast_mthd_head = {
+	.mthd = 0x0400,
+	.addr = 0x000540,
+	.data = {
+		{ 0x0800, 0x610ad8 },
+		{ 0x0804, 0x610ad0 },
+		{ 0x0808, 0x610a48 },
+		{ 0x080c, 0x610a78 },
+		{ 0x0810, 0x610ac0 },
+		{ 0x0814, 0x610af8 },
+		{ 0x0818, 0x610b00 },
+		{ 0x081c, 0x610ae8 },
+		{ 0x0820, 0x610af0 },
+		{ 0x0824, 0x610b08 },
+		{ 0x0828, 0x610b10 },
+		{ 0x082c, 0x610a68 },
+		{ 0x0830, 0x610a60 },
+		{ 0x0834, 0x000000 },
+		{ 0x0838, 0x610a40 },
+		{ 0x0840, 0x610a24 },
+		{ 0x0844, 0x610a2c },
+		{ 0x0848, 0x610aa8 },
+		{ 0x084c, 0x610ab0 },
+		{ 0x085c, 0x610c5c },
+		{ 0x0860, 0x610a84 },
+		{ 0x0864, 0x610a90 },
+		{ 0x0868, 0x610b18 },
+		{ 0x086c, 0x610b20 },
+		{ 0x0870, 0x610ac8 },
+		{ 0x0874, 0x610a38 },
+		{ 0x0878, 0x610c50 },
+		{ 0x0880, 0x610a58 },
+		{ 0x0884, 0x610a9c },
+		{ 0x089c, 0x610c68 },
+		{ 0x08a0, 0x610a70 },
+		{ 0x08a4, 0x610a50 },
+		{ 0x08a8, 0x610ae0 },
+		{ 0x08c0, 0x610b28 },
+		{ 0x08c4, 0x610b30 },
+		{ 0x08c8, 0x610b40 },
+		{ 0x08d4, 0x610b38 },
+		{ 0x08d8, 0x610b48 },
+		{ 0x08dc, 0x610b50 },
+		{ 0x0900, 0x610a18 },
+		{ 0x0904, 0x610ab8 },
+		{ 0x0910, 0x610c70 },
+		{ 0x0914, 0x610c78 },
+		{}
+	}
+};
+
+const struct nv50_disp_mthd_chan
+nv84_disp_mast_mthd_chan = {
+	.name = "Core",
+	.addr = 0x000000,
+	.data = {
+		{ "Global", 1, &nv50_disp_mast_mthd_base },
+		{    "DAC", 3, &nv84_disp_mast_mthd_dac  },
+		{    "SOR", 2, &nv50_disp_mast_mthd_sor  },
+		{   "PIOR", 3, &nv50_disp_mast_mthd_pior },
+		{   "HEAD", 2, &nv84_disp_mast_mthd_head },
+		{}
+	}
+};
+
+/*******************************************************************************
+ * EVO sync channel objects
+ ******************************************************************************/
+
+static const struct nv50_disp_mthd_list
+nv84_disp_sync_mthd_base = {
+	.mthd = 0x0000,
+	.addr = 0x000000,
+	.data = {
+		{ 0x0080, 0x000000 },
+		{ 0x0084, 0x0008c4 },
+		{ 0x0088, 0x0008d0 },
+		{ 0x008c, 0x0008dc },
+		{ 0x0090, 0x0008e4 },
+		{ 0x0094, 0x610884 },
+		{ 0x00a0, 0x6108a0 },
+		{ 0x00a4, 0x610878 },
+		{ 0x00c0, 0x61086c },
+		{ 0x00c4, 0x610800 },
+		{ 0x00c8, 0x61080c },
+		{ 0x00cc, 0x610818 },
+		{ 0x00e0, 0x610858 },
+		{ 0x00e4, 0x610860 },
+		{ 0x00e8, 0x6108ac },
+		{ 0x00ec, 0x6108b4 },
+		{ 0x00fc, 0x610824 },
+		{ 0x0100, 0x610894 },
+		{ 0x0104, 0x61082c },
+		{ 0x0110, 0x6108bc },
+		{ 0x0114, 0x61088c },
+		{}
+	}
+};
+
+const struct nv50_disp_mthd_chan
+nv84_disp_sync_mthd_chan = {
+	.name = "Base",
+	.addr = 0x000540,
+	.data = {
+		{ "Global", 1, &nv84_disp_sync_mthd_base },
+		{  "Image", 2, &nv50_disp_sync_mthd_image },
+		{}
+	}
+};
+
+/*******************************************************************************
+ * EVO overlay channel objects
+ ******************************************************************************/
+
+static const struct nv50_disp_mthd_list
+nv84_disp_ovly_mthd_base = {
+	.mthd = 0x0000,
+	.addr = 0x000000,
+	.data = {
+		{ 0x0080, 0x000000 },
+		{ 0x0084, 0x6109a0 },
+		{ 0x0088, 0x6109c0 },
+		{ 0x008c, 0x6109c8 },
+		{ 0x0090, 0x6109b4 },
+		{ 0x0094, 0x610970 },
+		{ 0x00a0, 0x610998 },
+		{ 0x00a4, 0x610964 },
+		{ 0x00c0, 0x610958 },
+		{ 0x00e0, 0x6109a8 },
+		{ 0x00e4, 0x6109d0 },
+		{ 0x00e8, 0x6109d8 },
+		{ 0x0100, 0x61094c },
+		{ 0x0104, 0x610984 },
+		{ 0x0108, 0x61098c },
+		{ 0x0800, 0x6109f8 },
+		{ 0x0808, 0x610a08 },
+		{ 0x080c, 0x610a10 },
+		{ 0x0810, 0x610a00 },
+		{}
+	}
+};
+
+const struct nv50_disp_mthd_chan
+nv84_disp_ovly_mthd_chan = {
+	.name = "Overlay",
+	.addr = 0x000540,
+	.data = {
+		{ "Global", 1, &nv84_disp_ovly_mthd_base },
+		{}
+	}
+};
+
+/*******************************************************************************
+ * Base display object
+ ******************************************************************************/
+
 static struct nouveau_oclass
 nv84_disp_sclass[] = {
 	{ NV84_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
@@ -59,6 +232,10 @@ nv84_disp_base_oclass[] = {
 	{}
 };
 
+/*******************************************************************************
+ * Display engine implementation
+ ******************************************************************************/
+
 static int
 nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	       struct nouveau_oclass *oclass, void *data, u32 size,
@@ -91,13 +268,17 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	return 0;
 }
 
-struct nouveau_oclass
-nv84_disp_oclass = {
-	.handle = NV_ENGINE(DISP, 0x82),
-	.ofuncs = &(struct nouveau_ofuncs) {
+struct nouveau_oclass *
+nv84_disp_oclass = &(struct nv50_disp_impl) {
+	.base.base.handle = NV_ENGINE(DISP, 0x82),
+	.base.base.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nv84_disp_ctor,
 		.dtor = _nouveau_disp_dtor,
 		.init = _nouveau_disp_init,
 		.fini = _nouveau_disp_fini,
 	},
-};
+	.mthd.core = &nv84_disp_mast_mthd_chan,
+	.mthd.base = &nv84_disp_sync_mthd_chan,
+	.mthd.ovly = &nv84_disp_ovly_mthd_chan,
+	.mthd.prev = 0x000004,
+}.base.base;

+ 45 - 5
drivers/gpu/drm/nouveau/core/engine/disp/nv94.c

@@ -29,6 +29,38 @@
 
 #include "nv50.h"
 
+/*******************************************************************************
+ * EVO master channel object
+ ******************************************************************************/
+
+const struct nv50_disp_mthd_list
+nv94_disp_mast_mthd_sor = {
+	.mthd = 0x0040,
+	.addr = 0x000008,
+	.data = {
+		{ 0x0600, 0x610794 },
+		{}
+	}
+};
+
+const struct nv50_disp_mthd_chan
+nv94_disp_mast_mthd_chan = {
+	.name = "Core",
+	.addr = 0x000000,
+	.data = {
+		{ "Global", 1, &nv50_disp_mast_mthd_base },
+		{    "DAC", 3, &nv84_disp_mast_mthd_dac  },
+		{    "SOR", 4, &nv94_disp_mast_mthd_sor  },
+		{   "PIOR", 3, &nv50_disp_mast_mthd_pior },
+		{   "HEAD", 2, &nv84_disp_mast_mthd_head },
+		{}
+	}
+};
+
+/*******************************************************************************
+ * Base display object
+ ******************************************************************************/
+
 static struct nouveau_oclass
 nv94_disp_sclass[] = {
 	{ NV94_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
@@ -59,6 +91,10 @@ nv94_disp_base_oclass[] = {
 	{}
 };
 
+/*******************************************************************************
+ * Display engine implementation
+ ******************************************************************************/
+
 static int
 nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	       struct nouveau_oclass *oclass, void *data, u32 size,
@@ -92,13 +128,17 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	return 0;
 }
 
-struct nouveau_oclass
-nv94_disp_oclass = {
-	.handle = NV_ENGINE(DISP, 0x88),
-	.ofuncs = &(struct nouveau_ofuncs) {
+struct nouveau_oclass *
+nv94_disp_oclass = &(struct nv50_disp_impl) {
+	.base.base.handle = NV_ENGINE(DISP, 0x88),
+	.base.base.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nv94_disp_ctor,
 		.dtor = _nouveau_disp_dtor,
 		.init = _nouveau_disp_init,
 		.fini = _nouveau_disp_fini,
 	},
-};
+	.mthd.core = &nv94_disp_mast_mthd_chan,
+	.mthd.base = &nv84_disp_sync_mthd_chan,
+	.mthd.ovly = &nv84_disp_ovly_mthd_chan,
+	.mthd.prev = 0x000004,
+}.base.base;

+ 62 - 5
drivers/gpu/drm/nouveau/core/engine/disp/nva0.c

@@ -29,6 +29,55 @@
 
 #include "nv50.h"
 
+/*******************************************************************************
+ * EVO overlay channel objects
+ ******************************************************************************/
+
+static const struct nv50_disp_mthd_list
+nva0_disp_ovly_mthd_base = {
+	.mthd = 0x0000,
+	.addr = 0x000000,
+	.data = {
+		{ 0x0080, 0x000000 },
+		{ 0x0084, 0x6109a0 },
+		{ 0x0088, 0x6109c0 },
+		{ 0x008c, 0x6109c8 },
+		{ 0x0090, 0x6109b4 },
+		{ 0x0094, 0x610970 },
+		{ 0x00a0, 0x610998 },
+		{ 0x00a4, 0x610964 },
+		{ 0x00b0, 0x610c98 },
+		{ 0x00b4, 0x610ca4 },
+		{ 0x00b8, 0x610cac },
+		{ 0x00c0, 0x610958 },
+		{ 0x00e0, 0x6109a8 },
+		{ 0x00e4, 0x6109d0 },
+		{ 0x00e8, 0x6109d8 },
+		{ 0x0100, 0x61094c },
+		{ 0x0104, 0x610984 },
+		{ 0x0108, 0x61098c },
+		{ 0x0800, 0x6109f8 },
+		{ 0x0808, 0x610a08 },
+		{ 0x080c, 0x610a10 },
+		{ 0x0810, 0x610a00 },
+		{}
+	}
+};
+
+static const struct nv50_disp_mthd_chan
+nva0_disp_ovly_mthd_chan = {
+	.name = "Overlay",
+	.addr = 0x000540,
+	.data = {
+		{ "Global", 1, &nva0_disp_ovly_mthd_base },
+		{}
+	}
+};
+
+/*******************************************************************************
+ * Base display object
+ ******************************************************************************/
+
 static struct nouveau_oclass
 nva0_disp_sclass[] = {
 	{ NVA0_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
@@ -45,6 +94,10 @@ nva0_disp_base_oclass[] = {
 	{}
 };
 
+/*******************************************************************************
+ * Display engine implementation
+ ******************************************************************************/
+
 static int
 nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	       struct nouveau_oclass *oclass, void *data, u32 size,
@@ -77,13 +130,17 @@ nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	return 0;
 }
 
-struct nouveau_oclass
-nva0_disp_oclass = {
-	.handle = NV_ENGINE(DISP, 0x83),
-	.ofuncs = &(struct nouveau_ofuncs) {
+struct nouveau_oclass *
+nva0_disp_oclass = &(struct nv50_disp_impl) {
+	.base.base.handle = NV_ENGINE(DISP, 0x83),
+	.base.base.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nva0_disp_ctor,
 		.dtor = _nouveau_disp_dtor,
 		.init = _nouveau_disp_init,
 		.fini = _nouveau_disp_fini,
 	},
-};
+	.mthd.core = &nv84_disp_mast_mthd_chan,
+	.mthd.base = &nv84_disp_sync_mthd_chan,
+	.mthd.ovly = &nva0_disp_ovly_mthd_chan,
+	.mthd.prev = 0x000004,
+}.base.base;

+ 17 - 5
drivers/gpu/drm/nouveau/core/engine/disp/nva3.c

@@ -29,6 +29,10 @@
 
 #include "nv50.h"
 
+/*******************************************************************************
+ * Base display object
+ ******************************************************************************/
+
 static struct nouveau_oclass
 nva3_disp_sclass[] = {
 	{ NVA3_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
@@ -60,6 +64,10 @@ nva3_disp_base_oclass[] = {
 	{}
 };
 
+/*******************************************************************************
+ * Display engine implementation
+ ******************************************************************************/
+
 static int
 nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	       struct nouveau_oclass *oclass, void *data, u32 size,
@@ -94,13 +102,17 @@ nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	return 0;
 }
 
-struct nouveau_oclass
-nva3_disp_oclass = {
-	.handle = NV_ENGINE(DISP, 0x85),
-	.ofuncs = &(struct nouveau_ofuncs) {
+struct nouveau_oclass *
+nva3_disp_oclass = &(struct nv50_disp_impl) {
+	.base.base.handle = NV_ENGINE(DISP, 0x85),
+	.base.base.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nva3_disp_ctor,
 		.dtor = _nouveau_disp_dtor,
 		.init = _nouveau_disp_init,
 		.fini = _nouveau_disp_fini,
 	},
-};
+	.mthd.core = &nv94_disp_mast_mthd_chan,
+	.mthd.base = &nv84_disp_sync_mthd_chan,
+	.mthd.ovly = &nv84_disp_ovly_mthd_chan,
+	.mthd.prev = 0x000004,
+}.base.base;

+ 343 - 18
drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c

@@ -124,6 +124,146 @@ nvd0_disp_dmac_fini(struct nouveau_object *object, bool suspend)
  * EVO master channel object
  ******************************************************************************/
 
+const struct nv50_disp_mthd_list
+nvd0_disp_mast_mthd_base = {
+	.mthd = 0x0000,
+	.addr = 0x000000,
+	.data = {
+		{ 0x0080, 0x660080 },
+		{ 0x0084, 0x660084 },
+		{ 0x0088, 0x660088 },
+		{ 0x008c, 0x000000 },
+		{}
+	}
+};
+
+const struct nv50_disp_mthd_list
+nvd0_disp_mast_mthd_dac = {
+	.mthd = 0x0020,
+	.addr = 0x000020,
+	.data = {
+		{ 0x0180, 0x660180 },
+		{ 0x0184, 0x660184 },
+		{ 0x0188, 0x660188 },
+		{ 0x0190, 0x660190 },
+		{}
+	}
+};
+
+const struct nv50_disp_mthd_list
+nvd0_disp_mast_mthd_sor = {
+	.mthd = 0x0020,
+	.addr = 0x000020,
+	.data = {
+		{ 0x0200, 0x660200 },
+		{ 0x0204, 0x660204 },
+		{ 0x0208, 0x660208 },
+		{ 0x0210, 0x660210 },
+		{}
+	}
+};
+
+const struct nv50_disp_mthd_list
+nvd0_disp_mast_mthd_pior = {
+	.mthd = 0x0020,
+	.addr = 0x000020,
+	.data = {
+		{ 0x0300, 0x660300 },
+		{ 0x0304, 0x660304 },
+		{ 0x0308, 0x660308 },
+		{ 0x0310, 0x660310 },
+		{}
+	}
+};
+
+static const struct nv50_disp_mthd_list
+nvd0_disp_mast_mthd_head = {
+	.mthd = 0x0300,
+	.addr = 0x000300,
+	.data = {
+		{ 0x0400, 0x660400 },
+		{ 0x0404, 0x660404 },
+		{ 0x0408, 0x660408 },
+		{ 0x040c, 0x66040c },
+		{ 0x0410, 0x660410 },
+		{ 0x0414, 0x660414 },
+		{ 0x0418, 0x660418 },
+		{ 0x041c, 0x66041c },
+		{ 0x0420, 0x660420 },
+		{ 0x0424, 0x660424 },
+		{ 0x0428, 0x660428 },
+		{ 0x042c, 0x66042c },
+		{ 0x0430, 0x660430 },
+		{ 0x0434, 0x660434 },
+		{ 0x0438, 0x660438 },
+		{ 0x0440, 0x660440 },
+		{ 0x0444, 0x660444 },
+		{ 0x0448, 0x660448 },
+		{ 0x044c, 0x66044c },
+		{ 0x0450, 0x660450 },
+		{ 0x0454, 0x660454 },
+		{ 0x0458, 0x660458 },
+		{ 0x045c, 0x66045c },
+		{ 0x0460, 0x660460 },
+		{ 0x0468, 0x660468 },
+		{ 0x046c, 0x66046c },
+		{ 0x0470, 0x660470 },
+		{ 0x0474, 0x660474 },
+		{ 0x0480, 0x660480 },
+		{ 0x0484, 0x660484 },
+		{ 0x048c, 0x66048c },
+		{ 0x0490, 0x660490 },
+		{ 0x0494, 0x660494 },
+		{ 0x0498, 0x660498 },
+		{ 0x04b0, 0x6604b0 },
+		{ 0x04b8, 0x6604b8 },
+		{ 0x04bc, 0x6604bc },
+		{ 0x04c0, 0x6604c0 },
+		{ 0x04c4, 0x6604c4 },
+		{ 0x04c8, 0x6604c8 },
+		{ 0x04d0, 0x6604d0 },
+		{ 0x04d4, 0x6604d4 },
+		{ 0x04e0, 0x6604e0 },
+		{ 0x04e4, 0x6604e4 },
+		{ 0x04e8, 0x6604e8 },
+		{ 0x04ec, 0x6604ec },
+		{ 0x04f0, 0x6604f0 },
+		{ 0x04f4, 0x6604f4 },
+		{ 0x04f8, 0x6604f8 },
+		{ 0x04fc, 0x6604fc },
+		{ 0x0500, 0x660500 },
+		{ 0x0504, 0x660504 },
+		{ 0x0508, 0x660508 },
+		{ 0x050c, 0x66050c },
+		{ 0x0510, 0x660510 },
+		{ 0x0514, 0x660514 },
+		{ 0x0518, 0x660518 },
+		{ 0x051c, 0x66051c },
+		{ 0x052c, 0x66052c },
+		{ 0x0530, 0x660530 },
+		{ 0x054c, 0x66054c },
+		{ 0x0550, 0x660550 },
+		{ 0x0554, 0x660554 },
+		{ 0x0558, 0x660558 },
+		{ 0x055c, 0x66055c },
+		{}
+	}
+};
+
+static const struct nv50_disp_mthd_chan
+nvd0_disp_mast_mthd_chan = {
+	.name = "Core",
+	.addr = 0x000000,
+	.data = {
+		{ "Global", 1, &nvd0_disp_mast_mthd_base },
+		{    "DAC", 3, &nvd0_disp_mast_mthd_dac  },
+		{    "SOR", 8, &nvd0_disp_mast_mthd_sor  },
+		{   "PIOR", 4, &nvd0_disp_mast_mthd_pior },
+		{   "HEAD", 4, &nvd0_disp_mast_mthd_head },
+		{}
+	}
+};
+
 static int
 nvd0_disp_mast_ctor(struct nouveau_object *parent,
 		    struct nouveau_object *engine,
@@ -216,6 +356,81 @@ nvd0_disp_mast_ofuncs = {
  * EVO sync channel objects
  ******************************************************************************/
 
+static const struct nv50_disp_mthd_list
+nvd0_disp_sync_mthd_base = {
+	.mthd = 0x0000,
+	.addr = 0x000000,
+	.data = {
+		{ 0x0080, 0x661080 },
+		{ 0x0084, 0x661084 },
+		{ 0x0088, 0x661088 },
+		{ 0x008c, 0x66108c },
+		{ 0x0090, 0x661090 },
+		{ 0x0094, 0x661094 },
+		{ 0x00a0, 0x6610a0 },
+		{ 0x00a4, 0x6610a4 },
+		{ 0x00c0, 0x6610c0 },
+		{ 0x00c4, 0x6610c4 },
+		{ 0x00c8, 0x6610c8 },
+		{ 0x00cc, 0x6610cc },
+		{ 0x00e0, 0x6610e0 },
+		{ 0x00e4, 0x6610e4 },
+		{ 0x00e8, 0x6610e8 },
+		{ 0x00ec, 0x6610ec },
+		{ 0x00fc, 0x6610fc },
+		{ 0x0100, 0x661100 },
+		{ 0x0104, 0x661104 },
+		{ 0x0108, 0x661108 },
+		{ 0x010c, 0x66110c },
+		{ 0x0110, 0x661110 },
+		{ 0x0114, 0x661114 },
+		{ 0x0118, 0x661118 },
+		{ 0x011c, 0x66111c },
+		{ 0x0130, 0x661130 },
+		{ 0x0134, 0x661134 },
+		{ 0x0138, 0x661138 },
+		{ 0x013c, 0x66113c },
+		{ 0x0140, 0x661140 },
+		{ 0x0144, 0x661144 },
+		{ 0x0148, 0x661148 },
+		{ 0x014c, 0x66114c },
+		{ 0x0150, 0x661150 },
+		{ 0x0154, 0x661154 },
+		{ 0x0158, 0x661158 },
+		{ 0x015c, 0x66115c },
+		{ 0x0160, 0x661160 },
+		{ 0x0164, 0x661164 },
+		{ 0x0168, 0x661168 },
+		{ 0x016c, 0x66116c },
+		{}
+	}
+};
+
+static const struct nv50_disp_mthd_list
+nvd0_disp_sync_mthd_image = {
+	.mthd = 0x0400,
+	.addr = 0x000400,
+	.data = {
+		{ 0x0400, 0x661400 },
+		{ 0x0404, 0x661404 },
+		{ 0x0408, 0x661408 },
+		{ 0x040c, 0x66140c },
+		{ 0x0410, 0x661410 },
+		{}
+	}
+};
+
+const struct nv50_disp_mthd_chan
+nvd0_disp_sync_mthd_chan = {
+	.name = "Base",
+	.addr = 0x001000,
+	.data = {
+		{ "Global", 1, &nvd0_disp_sync_mthd_base },
+		{  "Image", 2, &nvd0_disp_sync_mthd_image },
+		{}
+	}
+};
+
 static int
 nvd0_disp_sync_ctor(struct nouveau_object *parent,
 		    struct nouveau_object *engine,
@@ -256,6 +471,68 @@ nvd0_disp_sync_ofuncs = {
  * EVO overlay channel objects
  ******************************************************************************/
 
+static const struct nv50_disp_mthd_list
+nvd0_disp_ovly_mthd_base = {
+	.mthd = 0x0000,
+	.data = {
+		{ 0x0080, 0x665080 },
+		{ 0x0084, 0x665084 },
+		{ 0x0088, 0x665088 },
+		{ 0x008c, 0x66508c },
+		{ 0x0090, 0x665090 },
+		{ 0x0094, 0x665094 },
+		{ 0x00a0, 0x6650a0 },
+		{ 0x00a4, 0x6650a4 },
+		{ 0x00b0, 0x6650b0 },
+		{ 0x00b4, 0x6650b4 },
+		{ 0x00b8, 0x6650b8 },
+		{ 0x00c0, 0x6650c0 },
+		{ 0x00e0, 0x6650e0 },
+		{ 0x00e4, 0x6650e4 },
+		{ 0x00e8, 0x6650e8 },
+		{ 0x0100, 0x665100 },
+		{ 0x0104, 0x665104 },
+		{ 0x0108, 0x665108 },
+		{ 0x010c, 0x66510c },
+		{ 0x0110, 0x665110 },
+		{ 0x0118, 0x665118 },
+		{ 0x011c, 0x66511c },
+		{ 0x0120, 0x665120 },
+		{ 0x0124, 0x665124 },
+		{ 0x0130, 0x665130 },
+		{ 0x0134, 0x665134 },
+		{ 0x0138, 0x665138 },
+		{ 0x013c, 0x66513c },
+		{ 0x0140, 0x665140 },
+		{ 0x0144, 0x665144 },
+		{ 0x0148, 0x665148 },
+		{ 0x014c, 0x66514c },
+		{ 0x0150, 0x665150 },
+		{ 0x0154, 0x665154 },
+		{ 0x0158, 0x665158 },
+		{ 0x015c, 0x66515c },
+		{ 0x0160, 0x665160 },
+		{ 0x0164, 0x665164 },
+		{ 0x0168, 0x665168 },
+		{ 0x016c, 0x66516c },
+		{ 0x0400, 0x665400 },
+		{ 0x0408, 0x665408 },
+		{ 0x040c, 0x66540c },
+		{ 0x0410, 0x665410 },
+		{}
+	}
+};
+
+static const struct nv50_disp_mthd_chan
+nvd0_disp_ovly_mthd_chan = {
+	.name = "Overlay",
+	.addr = 0x001000,
+	.data = {
+		{ "Global", 1, &nvd0_disp_ovly_mthd_base },
+		{}
+	}
+};
+
 static int
 nvd0_disp_ovly_ctor(struct nouveau_object *parent,
 		    struct nouveau_object *engine,
@@ -897,19 +1174,22 @@ nvd0_disp_intr_supervisor(struct work_struct *work)
 {
 	struct nv50_disp_priv *priv =
 		container_of(work, struct nv50_disp_priv, supervisor);
+	struct nv50_disp_impl *impl = (void *)nv_object(priv)->oclass;
 	u32 mask[4];
 	int head;
 
-	nv_debug(priv, "supervisor %08x\n", priv->super);
+	nv_debug(priv, "supervisor %d\n", ffs(priv->super));
 	for (head = 0; head < priv->head.nr; head++) {
 		mask[head] = nv_rd32(priv, 0x6101d4 + (head * 0x800));
 		nv_debug(priv, "head %d: 0x%08x\n", head, mask[head]);
 	}
 
 	if (priv->super & 0x00000001) {
+		nv50_disp_mthd_chan(priv, NV_DBG_DEBUG, 0, impl->mthd.core);
 		for (head = 0; head < priv->head.nr; head++) {
 			if (!(mask[head] & 0x00001000))
 				continue;
+			nv_debug(priv, "supervisor 1.0 - head %d\n", head);
 			nvd0_disp_intr_unk1_0(priv, head);
 		}
 	} else
@@ -917,16 +1197,19 @@ nvd0_disp_intr_supervisor(struct work_struct *work)
 		for (head = 0; head < priv->head.nr; head++) {
 			if (!(mask[head] & 0x00001000))
 				continue;
+			nv_debug(priv, "supervisor 2.0 - head %d\n", head);
 			nvd0_disp_intr_unk2_0(priv, head);
 		}
 		for (head = 0; head < priv->head.nr; head++) {
 			if (!(mask[head] & 0x00010000))
 				continue;
+			nv_debug(priv, "supervisor 2.1 - head %d\n", head);
 			nvd0_disp_intr_unk2_1(priv, head);
 		}
 		for (head = 0; head < priv->head.nr; head++) {
 			if (!(mask[head] & 0x00001000))
 				continue;
+			nv_debug(priv, "supervisor 2.2 - head %d\n", head);
 			nvd0_disp_intr_unk2_2(priv, head);
 		}
 	} else
@@ -934,6 +1217,7 @@ nvd0_disp_intr_supervisor(struct work_struct *work)
 		for (head = 0; head < priv->head.nr; head++) {
 			if (!(mask[head] & 0x00001000))
 				continue;
+			nv_debug(priv, "supervisor 3.0 - head %d\n", head);
 			nvd0_disp_intr_unk4_0(priv, head);
 		}
 	}
@@ -943,6 +1227,53 @@ nvd0_disp_intr_supervisor(struct work_struct *work)
 	nv_wr32(priv, 0x6101d0, 0x80000000);
 }
 
+static void
+nvd0_disp_intr_error(struct nv50_disp_priv *priv, int chid)
+{
+	const struct nv50_disp_impl *impl = (void *)nv_object(priv)->oclass;
+	u32 mthd = nv_rd32(priv, 0x6101f0 + (chid * 12));
+	u32 data = nv_rd32(priv, 0x6101f4 + (chid * 12));
+	u32 unkn = nv_rd32(priv, 0x6101f8 + (chid * 12));
+
+	nv_error(priv, "chid %d mthd 0x%04x data 0x%08x "
+		       "0x%08x 0x%08x\n",
+		 chid, (mthd & 0x0000ffc), data, mthd, unkn);
+
+	if (chid == 0) {
+		switch (mthd) {
+		case 0x0080:
+			nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 0,
+					    impl->mthd.core);
+			break;
+		default:
+			break;
+		}
+	} else
+	if (chid <= 4) {
+		switch (mthd) {
+		case 0x0080:
+			nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 1,
+					    impl->mthd.base);
+			break;
+		default:
+			break;
+		}
+	} else
+	if (chid <= 8) {
+		switch (mthd) {
+		case 0x0080:
+			nv50_disp_mthd_chan(priv, NV_DBG_ERROR, chid - 5,
+					    impl->mthd.ovly);
+			break;
+		default:
+			break;
+		}
+	}
+
+	nv_wr32(priv, 0x61009c, (1 << chid));
+	nv_wr32(priv, 0x6101f0 + (chid * 12), 0x90000000);
+}
+
 void
 nvd0_disp_intr(struct nouveau_subdev *subdev)
 {
@@ -959,18 +1290,8 @@ nvd0_disp_intr(struct nouveau_subdev *subdev)
 	if (intr & 0x00000002) {
 		u32 stat = nv_rd32(priv, 0x61009c);
 		int chid = ffs(stat) - 1;
-		if (chid >= 0) {
-			u32 mthd = nv_rd32(priv, 0x6101f0 + (chid * 12));
-			u32 data = nv_rd32(priv, 0x6101f4 + (chid * 12));
-			u32 unkn = nv_rd32(priv, 0x6101f8 + (chid * 12));
-
-			nv_error(priv, "chid %d mthd 0x%04x data 0x%08x "
-				       "0x%08x 0x%08x\n",
-				 chid, (mthd & 0x0000ffc), data, mthd, unkn);
-			nv_wr32(priv, 0x61009c, (1 << chid));
-			nv_wr32(priv, 0x6101f0 + (chid * 12), 0x90000000);
-		}
-
+		if (chid >= 0)
+			nvd0_disp_intr_error(priv, chid);
 		intr &= ~0x00000002;
 	}
 
@@ -1035,13 +1356,17 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	return 0;
 }
 
-struct nouveau_oclass
-nvd0_disp_oclass = {
-	.handle = NV_ENGINE(DISP, 0x90),
-	.ofuncs = &(struct nouveau_ofuncs) {
+struct nouveau_oclass *
+nvd0_disp_oclass = &(struct nv50_disp_impl) {
+	.base.base.handle = NV_ENGINE(DISP, 0x90),
+	.base.base.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nvd0_disp_ctor,
 		.dtor = _nouveau_disp_dtor,
 		.init = _nouveau_disp_init,
 		.fini = _nouveau_disp_fini,
 	},
-};
+	.mthd.core = &nvd0_disp_mast_mthd_chan,
+	.mthd.base = &nvd0_disp_sync_mthd_chan,
+	.mthd.ovly = &nvd0_disp_ovly_mthd_chan,
+	.mthd.prev = -0x020000,
+}.base.base;

+ 182 - 5
drivers/gpu/drm/nouveau/core/engine/disp/nve0.c

@@ -29,6 +29,175 @@
 
 #include "nv50.h"
 
+/*******************************************************************************
+ * EVO master channel object
+ ******************************************************************************/
+
+static const struct nv50_disp_mthd_list
+nve0_disp_mast_mthd_head = {
+	.mthd = 0x0300,
+	.addr = 0x000300,
+	.data = {
+		{ 0x0400, 0x660400 },
+		{ 0x0404, 0x660404 },
+		{ 0x0408, 0x660408 },
+		{ 0x040c, 0x66040c },
+		{ 0x0410, 0x660410 },
+		{ 0x0414, 0x660414 },
+		{ 0x0418, 0x660418 },
+		{ 0x041c, 0x66041c },
+		{ 0x0420, 0x660420 },
+		{ 0x0424, 0x660424 },
+		{ 0x0428, 0x660428 },
+		{ 0x042c, 0x66042c },
+		{ 0x0430, 0x660430 },
+		{ 0x0434, 0x660434 },
+		{ 0x0438, 0x660438 },
+		{ 0x0440, 0x660440 },
+		{ 0x0444, 0x660444 },
+		{ 0x0448, 0x660448 },
+		{ 0x044c, 0x66044c },
+		{ 0x0450, 0x660450 },
+		{ 0x0454, 0x660454 },
+		{ 0x0458, 0x660458 },
+		{ 0x045c, 0x66045c },
+		{ 0x0460, 0x660460 },
+		{ 0x0468, 0x660468 },
+		{ 0x046c, 0x66046c },
+		{ 0x0470, 0x660470 },
+		{ 0x0474, 0x660474 },
+		{ 0x047c, 0x66047c },
+		{ 0x0480, 0x660480 },
+		{ 0x0484, 0x660484 },
+		{ 0x0488, 0x660488 },
+		{ 0x048c, 0x66048c },
+		{ 0x0490, 0x660490 },
+		{ 0x0494, 0x660494 },
+		{ 0x0498, 0x660498 },
+		{ 0x04a0, 0x6604a0 },
+		{ 0x04b0, 0x6604b0 },
+		{ 0x04b8, 0x6604b8 },
+		{ 0x04bc, 0x6604bc },
+		{ 0x04c0, 0x6604c0 },
+		{ 0x04c4, 0x6604c4 },
+		{ 0x04c8, 0x6604c8 },
+		{ 0x04d0, 0x6604d0 },
+		{ 0x04d4, 0x6604d4 },
+		{ 0x04e0, 0x6604e0 },
+		{ 0x04e4, 0x6604e4 },
+		{ 0x04e8, 0x6604e8 },
+		{ 0x04ec, 0x6604ec },
+		{ 0x04f0, 0x6604f0 },
+		{ 0x04f4, 0x6604f4 },
+		{ 0x04f8, 0x6604f8 },
+		{ 0x04fc, 0x6604fc },
+		{ 0x0500, 0x660500 },
+		{ 0x0504, 0x660504 },
+		{ 0x0508, 0x660508 },
+		{ 0x050c, 0x66050c },
+		{ 0x0510, 0x660510 },
+		{ 0x0514, 0x660514 },
+		{ 0x0518, 0x660518 },
+		{ 0x051c, 0x66051c },
+		{ 0x0520, 0x660520 },
+		{ 0x0524, 0x660524 },
+		{ 0x052c, 0x66052c },
+		{ 0x0530, 0x660530 },
+		{ 0x054c, 0x66054c },
+		{ 0x0550, 0x660550 },
+		{ 0x0554, 0x660554 },
+		{ 0x0558, 0x660558 },
+		{ 0x055c, 0x66055c },
+		{}
+	}
+};
+
+const struct nv50_disp_mthd_chan
+nve0_disp_mast_mthd_chan = {
+	.name = "Core",
+	.addr = 0x000000,
+	.data = {
+		{ "Global", 1, &nvd0_disp_mast_mthd_base },
+		{    "DAC", 3, &nvd0_disp_mast_mthd_dac  },
+		{    "SOR", 8, &nvd0_disp_mast_mthd_sor  },
+		{   "PIOR", 4, &nvd0_disp_mast_mthd_pior },
+		{   "HEAD", 4, &nve0_disp_mast_mthd_head },
+		{}
+	}
+};
+
+/*******************************************************************************
+ * EVO overlay channel objects
+ ******************************************************************************/
+
+static const struct nv50_disp_mthd_list
+nve0_disp_ovly_mthd_base = {
+	.mthd = 0x0000,
+	.data = {
+		{ 0x0080, 0x665080 },
+		{ 0x0084, 0x665084 },
+		{ 0x0088, 0x665088 },
+		{ 0x008c, 0x66508c },
+		{ 0x0090, 0x665090 },
+		{ 0x0094, 0x665094 },
+		{ 0x00a0, 0x6650a0 },
+		{ 0x00a4, 0x6650a4 },
+		{ 0x00b0, 0x6650b0 },
+		{ 0x00b4, 0x6650b4 },
+		{ 0x00b8, 0x6650b8 },
+		{ 0x00c0, 0x6650c0 },
+		{ 0x00c4, 0x6650c4 },
+		{ 0x00e0, 0x6650e0 },
+		{ 0x00e4, 0x6650e4 },
+		{ 0x00e8, 0x6650e8 },
+		{ 0x0100, 0x665100 },
+		{ 0x0104, 0x665104 },
+		{ 0x0108, 0x665108 },
+		{ 0x010c, 0x66510c },
+		{ 0x0110, 0x665110 },
+		{ 0x0118, 0x665118 },
+		{ 0x011c, 0x66511c },
+		{ 0x0120, 0x665120 },
+		{ 0x0124, 0x665124 },
+		{ 0x0130, 0x665130 },
+		{ 0x0134, 0x665134 },
+		{ 0x0138, 0x665138 },
+		{ 0x013c, 0x66513c },
+		{ 0x0140, 0x665140 },
+		{ 0x0144, 0x665144 },
+		{ 0x0148, 0x665148 },
+		{ 0x014c, 0x66514c },
+		{ 0x0150, 0x665150 },
+		{ 0x0154, 0x665154 },
+		{ 0x0158, 0x665158 },
+		{ 0x015c, 0x66515c },
+		{ 0x0160, 0x665160 },
+		{ 0x0164, 0x665164 },
+		{ 0x0168, 0x665168 },
+		{ 0x016c, 0x66516c },
+		{ 0x0400, 0x665400 },
+		{ 0x0404, 0x665404 },
+		{ 0x0408, 0x665408 },
+		{ 0x040c, 0x66540c },
+		{ 0x0410, 0x665410 },
+		{}
+	}
+};
+
+const struct nv50_disp_mthd_chan
+nve0_disp_ovly_mthd_chan = {
+	.name = "Overlay",
+	.addr = 0x001000,
+	.data = {
+		{ "Global", 1, &nve0_disp_ovly_mthd_base },
+		{}
+	}
+};
+
+/*******************************************************************************
+ * Base display object
+ ******************************************************************************/
+
 static struct nouveau_oclass
 nve0_disp_sclass[] = {
 	{ NVE0_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs },
@@ -45,6 +214,10 @@ nve0_disp_base_oclass[] = {
 	{}
 };
 
+/*******************************************************************************
+ * Display engine implementation
+ ******************************************************************************/
+
 static int
 nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	       struct nouveau_oclass *oclass, void *data, u32 size,
@@ -77,13 +250,17 @@ nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	return 0;
 }
 
-struct nouveau_oclass
-nve0_disp_oclass = {
-	.handle = NV_ENGINE(DISP, 0x91),
-	.ofuncs = &(struct nouveau_ofuncs) {
+struct nouveau_oclass *
+nve0_disp_oclass = &(struct nv50_disp_impl) {
+	.base.base.handle = NV_ENGINE(DISP, 0x91),
+	.base.base.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nve0_disp_ctor,
 		.dtor = _nouveau_disp_dtor,
 		.init = _nouveau_disp_init,
 		.fini = _nouveau_disp_fini,
 	},
-};
+	.mthd.core = &nve0_disp_mast_mthd_chan,
+	.mthd.base = &nvd0_disp_sync_mthd_chan,
+	.mthd.ovly = &nve0_disp_ovly_mthd_chan,
+	.mthd.prev = -0x020000,
+}.base.base;

+ 17 - 5
drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c

@@ -29,6 +29,10 @@
 
 #include "nv50.h"
 
+/*******************************************************************************
+ * Base display object
+ ******************************************************************************/
+
 static struct nouveau_oclass
 nvf0_disp_sclass[] = {
 	{ NVF0_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs },
@@ -45,6 +49,10 @@ nvf0_disp_base_oclass[] = {
 	{}
 };
 
+/*******************************************************************************
+ * Display engine implementation
+ ******************************************************************************/
+
 static int
 nvf0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	       struct nouveau_oclass *oclass, void *data, u32 size,
@@ -77,13 +85,17 @@ nvf0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	return 0;
 }
 
-struct nouveau_oclass
-nvf0_disp_oclass = {
-	.handle = NV_ENGINE(DISP, 0x92),
-	.ofuncs = &(struct nouveau_ofuncs) {
+struct nouveau_oclass *
+nvf0_disp_oclass = &(struct nv50_disp_impl) {
+	.base.base.handle = NV_ENGINE(DISP, 0x92),
+	.base.base.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nvf0_disp_ctor,
 		.dtor = _nouveau_disp_dtor,
 		.init = _nouveau_disp_init,
 		.fini = _nouveau_disp_fini,
 	},
-};
+	.mthd.core = &nve0_disp_mast_mthd_chan,
+	.mthd.base = &nvd0_disp_sync_mthd_chan,
+	.mthd.ovly = &nve0_disp_ovly_mthd_chan,
+	.mthd.prev = -0x020000,
+}.base.base;

+ 10 - 0
drivers/gpu/drm/nouveau/core/engine/disp/priv.h

@@ -0,0 +1,10 @@
+#ifndef __NVKM_DISP_PRIV_H__
+#define __NVKM_DISP_PRIV_H__
+
+#include <engine/disp.h>
+
+struct nouveau_disp_impl {
+	struct nouveau_oclass base;
+};
+
+#endif

+ 3 - 0
drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c

@@ -53,6 +53,9 @@ nvd0_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
 		case NVF0_DISP_MAST_CLASS:
 		case NVF0_DISP_SYNC_CLASS:
 		case NVF0_DISP_OVLY_CLASS:
+		case GM107_DISP_MAST_CLASS:
+		case GM107_DISP_SYNC_CLASS:
+		case GM107_DISP_OVLY_CLASS:
 			break;
 		default:
 			return -EINVAL;

+ 3 - 3
drivers/gpu/drm/nouveau/core/engine/falcon.c

@@ -119,7 +119,7 @@ _nouveau_falcon_init(struct nouveau_object *object)
 		snprintf(name, sizeof(name), "nouveau/nv%02x_fuc%03x",
 			 device->chipset, falcon->addr >> 12);
 
-		ret = request_firmware(&fw, name, &device->pdev->dev);
+		ret = request_firmware(&fw, name, nv_device_base(device));
 		if (ret == 0) {
 			falcon->code.data = vmemdup(fw->data, fw->size);
 			falcon->code.size = fw->size;
@@ -138,7 +138,7 @@ _nouveau_falcon_init(struct nouveau_object *object)
 		snprintf(name, sizeof(name), "nouveau/nv%02x_fuc%03xd",
 			 device->chipset, falcon->addr >> 12);
 
-		ret = request_firmware(&fw, name, &device->pdev->dev);
+		ret = request_firmware(&fw, name, nv_device_base(device));
 		if (ret) {
 			nv_error(falcon, "unable to load firmware data\n");
 			return ret;
@@ -153,7 +153,7 @@ _nouveau_falcon_init(struct nouveau_object *object)
 		snprintf(name, sizeof(name), "nouveau/nv%02x_fuc%03xc",
 			 device->chipset, falcon->addr >> 12);
 
-		ret = request_firmware(&fw, name, &device->pdev->dev);
+		ret = request_firmware(&fw, name, nv_device_base(device));
 		if (ret) {
 			nv_error(falcon, "unable to load firmware code\n");
 			return ret;

+ 1 - 1
drivers/gpu/drm/nouveau/core/engine/fifo/base.c

@@ -86,7 +86,7 @@ nouveau_fifo_channel_create_(struct nouveau_object *parent,
 	}
 
 	/* map fifo control registers */
-	chan->user = ioremap(pci_resource_start(device->pdev, bar) + addr +
+	chan->user = ioremap(nv_device_resource_start(device, bar) + addr +
 			     (chan->chid * size), size);
 	if (!chan->user)
 		return -EFAULT;

+ 369 - 140
drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c

@@ -41,8 +41,16 @@
 
 struct nvc0_fifo_priv {
 	struct nouveau_fifo base;
-	struct nouveau_gpuobj *playlist[2];
-	int cur_playlist;
+
+	struct work_struct fault;
+	u64 mask;
+
+	struct {
+		struct nouveau_gpuobj *mem[2];
+		int active;
+		wait_queue_head_t wait;
+	} runlist;
+
 	struct {
 		struct nouveau_gpuobj *mem;
 		struct nouveau_vma bar;
@@ -58,6 +66,11 @@ struct nvc0_fifo_base {
 
 struct nvc0_fifo_chan {
 	struct nouveau_fifo_chan base;
+	enum {
+		STOPPED,
+		RUNNING,
+		KILLED
+	} state;
 };
 
 /*******************************************************************************
@@ -65,29 +78,33 @@ struct nvc0_fifo_chan {
  ******************************************************************************/
 
 static void
-nvc0_fifo_playlist_update(struct nvc0_fifo_priv *priv)
+nvc0_fifo_runlist_update(struct nvc0_fifo_priv *priv)
 {
 	struct nouveau_bar *bar = nouveau_bar(priv);
 	struct nouveau_gpuobj *cur;
 	int i, p;
 
 	mutex_lock(&nv_subdev(priv)->mutex);
-	cur = priv->playlist[priv->cur_playlist];
-	priv->cur_playlist = !priv->cur_playlist;
+	cur = priv->runlist.mem[priv->runlist.active];
+	priv->runlist.active = !priv->runlist.active;
 
 	for (i = 0, p = 0; i < 128; i++) {
-		if (!(nv_rd32(priv, 0x003004 + (i * 8)) & 1))
-			continue;
-		nv_wo32(cur, p + 0, i);
-		nv_wo32(cur, p + 4, 0x00000004);
-		p += 8;
+		struct nvc0_fifo_chan *chan = (void *)priv->base.channel[i];
+		if (chan && chan->state == RUNNING) {
+			nv_wo32(cur, p + 0, i);
+			nv_wo32(cur, p + 4, 0x00000004);
+			p += 8;
+		}
 	}
 	bar->flush(bar);
 
 	nv_wr32(priv, 0x002270, cur->addr >> 12);
 	nv_wr32(priv, 0x002274, 0x01f00000 | (p >> 3));
-	if (!nv_wait(priv, 0x00227c, 0x00100000, 0x00000000))
-		nv_error(priv, "playlist update failed\n");
+
+	if (wait_event_timeout(priv->runlist.wait,
+			       !(nv_rd32(priv, 0x00227c) & 0x00100000),
+			       msecs_to_jiffies(2000)) == 0)
+		nv_error(priv, "runlist update timeout\n");
 	mutex_unlock(&nv_subdev(priv)->mutex);
 }
 
@@ -239,30 +256,32 @@ nvc0_fifo_chan_init(struct nouveau_object *object)
 		return ret;
 
 	nv_wr32(priv, 0x003000 + (chid * 8), 0xc0000000 | base->addr >> 12);
-	nv_wr32(priv, 0x003004 + (chid * 8), 0x001f0001);
-	nvc0_fifo_playlist_update(priv);
+
+	if (chan->state == STOPPED && (chan->state = RUNNING) == RUNNING) {
+		nv_wr32(priv, 0x003004 + (chid * 8), 0x001f0001);
+		nvc0_fifo_runlist_update(priv);
+	}
+
 	return 0;
 }
 
+static void nvc0_fifo_intr_engine(struct nvc0_fifo_priv *priv);
+
 static int
 nvc0_fifo_chan_fini(struct nouveau_object *object, bool suspend)
 {
 	struct nvc0_fifo_priv *priv = (void *)object->engine;
 	struct nvc0_fifo_chan *chan = (void *)object;
 	u32 chid = chan->base.chid;
-	u32 mask, engine;
 
-	nv_mask(priv, 0x003004 + (chid * 8), 0x00000001, 0x00000000);
-	nvc0_fifo_playlist_update(priv);
-	mask = nv_rd32(priv, 0x0025a4);
-	for (engine = 0; mask && engine < 16; engine++) {
-		if (!(mask & (1 << engine)))
-			continue;
-		nv_mask(priv, 0x0025a8 + (engine * 4), 0x00000000, 0x00000000);
-		mask &= ~(1 << engine);
+	if (chan->state == RUNNING && (chan->state = STOPPED) == STOPPED) {
+		nv_mask(priv, 0x003004 + (chid * 8), 0x00000001, 0x00000000);
+		nvc0_fifo_runlist_update(priv);
 	}
-	nv_wr32(priv, 0x003000 + (chid * 8), 0x00000000);
 
+	nvc0_fifo_intr_engine(priv);
+
+	nv_wr32(priv, 0x003000 + (chid * 8), 0x00000000);
 	return nouveau_fifo_channel_fini(&chan->base, suspend);
 }
 
@@ -345,11 +364,177 @@ nvc0_fifo_cclass = {
  * PFIFO engine
  ******************************************************************************/
 
-static const struct nouveau_enum nvc0_fifo_fault_unit[] = {
+static inline int
+nvc0_fifo_engidx(struct nvc0_fifo_priv *priv, u32 engn)
+{
+	switch (engn) {
+	case NVDEV_ENGINE_GR   : engn = 0; break;
+	case NVDEV_ENGINE_BSP  : engn = 1; break;
+	case NVDEV_ENGINE_PPP  : engn = 2; break;
+	case NVDEV_ENGINE_VP   : engn = 3; break;
+	case NVDEV_ENGINE_COPY0: engn = 4; break;
+	case NVDEV_ENGINE_COPY1: engn = 5; break;
+	default:
+		return -1;
+	}
+
+	return engn;
+}
+
+static inline struct nouveau_engine *
+nvc0_fifo_engine(struct nvc0_fifo_priv *priv, u32 engn)
+{
+	switch (engn) {
+	case 0: engn = NVDEV_ENGINE_GR; break;
+	case 1: engn = NVDEV_ENGINE_BSP; break;
+	case 2: engn = NVDEV_ENGINE_PPP; break;
+	case 3: engn = NVDEV_ENGINE_VP; break;
+	case 4: engn = NVDEV_ENGINE_COPY0; break;
+	case 5: engn = NVDEV_ENGINE_COPY1; break;
+	default:
+		return NULL;
+	}
+
+	return nouveau_engine(priv, engn);
+}
+
+static void
+nvc0_fifo_recover_work(struct work_struct *work)
+{
+	struct nvc0_fifo_priv *priv = container_of(work, typeof(*priv), fault);
+	struct nouveau_object *engine;
+	unsigned long flags;
+	u32 engn, engm = 0;
+	u64 mask, todo;
+
+	spin_lock_irqsave(&priv->base.lock, flags);
+	mask = priv->mask;
+	priv->mask = 0ULL;
+	spin_unlock_irqrestore(&priv->base.lock, flags);
+
+	for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn))
+		engm |= 1 << nvc0_fifo_engidx(priv, engn);
+	nv_mask(priv, 0x002630, engm, engm);
+
+	for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) {
+		if ((engine = (void *)nouveau_engine(priv, engn))) {
+			nv_ofuncs(engine)->fini(engine, false);
+			WARN_ON(nv_ofuncs(engine)->init(engine));
+		}
+	}
+
+	nvc0_fifo_runlist_update(priv);
+	nv_wr32(priv, 0x00262c, engm);
+	nv_mask(priv, 0x002630, engm, 0x00000000);
+}
+
+static void
+nvc0_fifo_recover(struct nvc0_fifo_priv *priv, struct nouveau_engine *engine,
+		  struct nvc0_fifo_chan *chan)
+{
+	struct nouveau_object *engobj = nv_object(engine);
+	u32 chid = chan->base.chid;
+	unsigned long flags;
+
+	nv_error(priv, "%s engine fault on channel %d, recovering...\n",
+		       nv_subdev(engine)->name, chid);
+
+	nv_mask(priv, 0x003004 + (chid * 0x08), 0x00000001, 0x00000000);
+	chan->state = KILLED;
+
+	spin_lock_irqsave(&priv->base.lock, flags);
+	priv->mask |= 1ULL << nv_engidx(engobj);
+	spin_unlock_irqrestore(&priv->base.lock, flags);
+	schedule_work(&priv->fault);
+}
+
+static int
+nvc0_fifo_swmthd(struct nvc0_fifo_priv *priv, u32 chid, u32 mthd, u32 data)
+{
+	struct nvc0_fifo_chan *chan = NULL;
+	struct nouveau_handle *bind;
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	spin_lock_irqsave(&priv->base.lock, flags);
+	if (likely(chid >= priv->base.min && chid <= priv->base.max))
+		chan = (void *)priv->base.channel[chid];
+	if (unlikely(!chan))
+		goto out;
+
+	bind = nouveau_namedb_get_class(nv_namedb(chan), 0x906e);
+	if (likely(bind)) {
+		if (!mthd || !nv_call(bind->object, mthd, data))
+			ret = 0;
+		nouveau_namedb_put(bind);
+	}
+
+out:
+	spin_unlock_irqrestore(&priv->base.lock, flags);
+	return ret;
+}
+
+static const struct nouveau_enum
+nvc0_fifo_sched_reason[] = {
+	{ 0x0a, "CTXSW_TIMEOUT" },
+	{}
+};
+
+static void
+nvc0_fifo_intr_sched_ctxsw(struct nvc0_fifo_priv *priv)
+{
+	struct nouveau_engine *engine;
+	struct nvc0_fifo_chan *chan;
+	u32 engn;
+
+	for (engn = 0; engn < 6; engn++) {
+		u32 stat = nv_rd32(priv, 0x002640 + (engn * 0x04));
+		u32 busy = (stat & 0x80000000);
+		u32 save = (stat & 0x00100000); /* maybe? */
+		u32 unk0 = (stat & 0x00040000);
+		u32 unk1 = (stat & 0x00001000);
+		u32 chid = (stat & 0x0000007f);
+		(void)save;
+
+		if (busy && unk0 && unk1) {
+			if (!(chan = (void *)priv->base.channel[chid]))
+				continue;
+			if (!(engine = nvc0_fifo_engine(priv, engn)))
+				continue;
+			nvc0_fifo_recover(priv, engine, chan);
+		}
+	}
+}
+
+static void
+nvc0_fifo_intr_sched(struct nvc0_fifo_priv *priv)
+{
+	u32 intr = nv_rd32(priv, 0x00254c);
+	u32 code = intr & 0x000000ff;
+	const struct nouveau_enum *en;
+	char enunk[6] = "";
+
+	en = nouveau_enum_find(nvc0_fifo_sched_reason, code);
+	if (!en)
+		snprintf(enunk, sizeof(enunk), "UNK%02x", code);
+
+	nv_error(priv, "SCHED_ERROR [ %s ]\n", en ? en->name : enunk);
+
+	switch (code) {
+	case 0x0a:
+		nvc0_fifo_intr_sched_ctxsw(priv);
+		break;
+	default:
+		break;
+	}
+}
+
+static const struct nouveau_enum
+nvc0_fifo_fault_engine[] = {
 	{ 0x00, "PGRAPH", NULL, NVDEV_ENGINE_GR },
-	{ 0x03, "PEEPHOLE" },
-	{ 0x04, "BAR1" },
-	{ 0x05, "BAR3" },
+	{ 0x03, "PEEPHOLE", NULL, NVDEV_ENGINE_IFB },
+	{ 0x04, "BAR1", NULL, NVDEV_SUBDEV_BAR },
+	{ 0x05, "BAR3", NULL, NVDEV_SUBDEV_INSTMEM },
 	{ 0x07, "PFIFO", NULL, NVDEV_ENGINE_FIFO },
 	{ 0x10, "PBSP", NULL, NVDEV_ENGINE_BSP },
 	{ 0x11, "PPPP", NULL, NVDEV_ENGINE_PPP },
@@ -361,7 +546,8 @@ static const struct nouveau_enum nvc0_fifo_fault_unit[] = {
 	{}
 };
 
-static const struct nouveau_enum nvc0_fifo_fault_reason[] = {
+static const struct nouveau_enum
+nvc0_fifo_fault_reason[] = {
 	{ 0x00, "PT_NOT_PRESENT" },
 	{ 0x01, "PT_TOO_SHORT" },
 	{ 0x02, "PAGE_NOT_PRESENT" },
@@ -374,7 +560,8 @@ static const struct nouveau_enum nvc0_fifo_fault_reason[] = {
 	{}
 };
 
-static const struct nouveau_enum nvc0_fifo_fault_hubclient[] = {
+static const struct nouveau_enum
+nvc0_fifo_fault_hubclient[] = {
 	{ 0x01, "PCOPY0" },
 	{ 0x02, "PCOPY1" },
 	{ 0x04, "DISPATCH" },
@@ -392,7 +579,8 @@ static const struct nouveau_enum nvc0_fifo_fault_hubclient[] = {
 	{}
 };
 
-static const struct nouveau_enum nvc0_fifo_fault_gpcclient[] = {
+static const struct nouveau_enum
+nvc0_fifo_fault_gpcclient[] = {
 	{ 0x01, "TEX" },
 	{ 0x0c, "ESETUP" },
 	{ 0x0e, "CTXCTL" },
@@ -400,92 +588,92 @@ static const struct nouveau_enum nvc0_fifo_fault_gpcclient[] = {
 	{}
 };
 
-static const struct nouveau_bitfield nvc0_fifo_subfifo_intr[] = {
-/*	{ 0x00008000, "" }	seen with null ib push */
-	{ 0x00200000, "ILLEGAL_MTHD" },
-	{ 0x00800000, "EMPTY_SUBC" },
-	{}
-};
-
 static void
-nvc0_fifo_isr_vm_fault(struct nvc0_fifo_priv *priv, int unit)
+nvc0_fifo_intr_fault(struct nvc0_fifo_priv *priv, int unit)
 {
 	u32 inst = nv_rd32(priv, 0x002800 + (unit * 0x10));
 	u32 valo = nv_rd32(priv, 0x002804 + (unit * 0x10));
 	u32 vahi = nv_rd32(priv, 0x002808 + (unit * 0x10));
 	u32 stat = nv_rd32(priv, 0x00280c + (unit * 0x10));
+	u32 gpc    = (stat & 0x1f000000) >> 24;
 	u32 client = (stat & 0x00001f00) >> 8;
-	const struct nouveau_enum *en;
-	struct nouveau_engine *engine;
-	struct nouveau_object *engctx = NULL;
-
-	switch (unit) {
-	case 3: /* PEEPHOLE */
-		nv_mask(priv, 0x001718, 0x00000000, 0x00000000);
-		break;
-	case 4: /* BAR1 */
-		nv_mask(priv, 0x001704, 0x00000000, 0x00000000);
-		break;
-	case 5: /* BAR3 */
-		nv_mask(priv, 0x001714, 0x00000000, 0x00000000);
-		break;
-	default:
-		break;
+	u32 write  = (stat & 0x00000080);
+	u32 hub    = (stat & 0x00000040);
+	u32 reason = (stat & 0x0000000f);
+	struct nouveau_object *engctx = NULL, *object;
+	struct nouveau_engine *engine = NULL;
+	const struct nouveau_enum *er, *eu, *ec;
+	char erunk[6] = "";
+	char euunk[6] = "";
+	char ecunk[6] = "";
+	char gpcid[3] = "";
+
+	er = nouveau_enum_find(nvc0_fifo_fault_reason, reason);
+	if (!er)
+		snprintf(erunk, sizeof(erunk), "UNK%02X", reason);
+
+	eu = nouveau_enum_find(nvc0_fifo_fault_engine, unit);
+	if (eu) {
+		switch (eu->data2) {
+		case NVDEV_SUBDEV_BAR:
+			nv_mask(priv, 0x001704, 0x00000000, 0x00000000);
+			break;
+		case NVDEV_SUBDEV_INSTMEM:
+			nv_mask(priv, 0x001714, 0x00000000, 0x00000000);
+			break;
+		case NVDEV_ENGINE_IFB:
+			nv_mask(priv, 0x001718, 0x00000000, 0x00000000);
+			break;
+		default:
+			engine = nouveau_engine(priv, eu->data2);
+			if (engine)
+				engctx = nouveau_engctx_get(engine, inst);
+			break;
+		}
+	} else {
+		snprintf(euunk, sizeof(euunk), "UNK%02x", unit);
 	}
 
-	nv_error(priv, "%s fault at 0x%010llx [", (stat & 0x00000080) ?
-		 "write" : "read", (u64)vahi << 32 | valo);
-	nouveau_enum_print(nvc0_fifo_fault_reason, stat & 0x0000000f);
-	pr_cont("] from ");
-	en = nouveau_enum_print(nvc0_fifo_fault_unit, unit);
-	if (stat & 0x00000040) {
-		pr_cont("/");
-		nouveau_enum_print(nvc0_fifo_fault_hubclient, client);
+	if (hub) {
+		ec = nouveau_enum_find(nvc0_fifo_fault_hubclient, client);
 	} else {
-		pr_cont("/GPC%d/", (stat & 0x1f000000) >> 24);
-		nouveau_enum_print(nvc0_fifo_fault_gpcclient, client);
+		ec = nouveau_enum_find(nvc0_fifo_fault_gpcclient, client);
+		snprintf(gpcid, sizeof(gpcid), "%d", gpc);
 	}
 
-	if (en && en->data2) {
-		engine = nouveau_engine(priv, en->data2);
-		if (engine)
-			engctx = nouveau_engctx_get(engine, inst);
-
+	if (!ec)
+		snprintf(ecunk, sizeof(ecunk), "UNK%02x", client);
+
+	nv_error(priv, "%s fault at 0x%010llx [%s] from %s/%s%s%s%s on "
+		       "channel 0x%010llx [%s]\n", write ? "write" : "read",
+		 (u64)vahi << 32 | valo, er ? er->name : erunk,
+		 eu ? eu->name : euunk, hub ? "" : "GPC", gpcid, hub ? "" : "/",
+		 ec ? ec->name : ecunk, (u64)inst << 12,
+		 nouveau_client_name(engctx));
+
+	object = engctx;
+	while (object) {
+		switch (nv_mclass(object)) {
+		case NVC0_CHANNEL_IND_CLASS:
+			nvc0_fifo_recover(priv, engine, (void *)object);
+			break;
+		}
+		object = object->parent;
 	}
-	pr_cont(" on channel 0x%010llx [%s]\n", (u64)inst << 12,
-			nouveau_client_name(engctx));
 
 	nouveau_engctx_put(engctx);
 }
 
-static int
-nvc0_fifo_swmthd(struct nvc0_fifo_priv *priv, u32 chid, u32 mthd, u32 data)
-{
-	struct nvc0_fifo_chan *chan = NULL;
-	struct nouveau_handle *bind;
-	unsigned long flags;
-	int ret = -EINVAL;
-
-	spin_lock_irqsave(&priv->base.lock, flags);
-	if (likely(chid >= priv->base.min && chid <= priv->base.max))
-		chan = (void *)priv->base.channel[chid];
-	if (unlikely(!chan))
-		goto out;
-
-	bind = nouveau_namedb_get_class(nv_namedb(chan), 0x906e);
-	if (likely(bind)) {
-		if (!mthd || !nv_call(bind->object, mthd, data))
-			ret = 0;
-		nouveau_namedb_put(bind);
-	}
-
-out:
-	spin_unlock_irqrestore(&priv->base.lock, flags);
-	return ret;
-}
+static const struct nouveau_bitfield
+nvc0_fifo_pbdma_intr[] = {
+/*	{ 0x00008000, "" }	seen with null ib push */
+	{ 0x00200000, "ILLEGAL_MTHD" },
+	{ 0x00800000, "EMPTY_SUBC" },
+	{}
+};
 
 static void
-nvc0_fifo_isr_subfifo_intr(struct nvc0_fifo_priv *priv, int unit)
+nvc0_fifo_intr_pbdma(struct nvc0_fifo_priv *priv, int unit)
 {
 	u32 stat = nv_rd32(priv, 0x040108 + (unit * 0x2000));
 	u32 addr = nv_rd32(priv, 0x0400c0 + (unit * 0x2000));
@@ -501,11 +689,11 @@ nvc0_fifo_isr_subfifo_intr(struct nvc0_fifo_priv *priv, int unit)
 	}
 
 	if (show) {
-		nv_error(priv, "SUBFIFO%d:", unit);
-		nouveau_bitfield_print(nvc0_fifo_subfifo_intr, show);
+		nv_error(priv, "PBDMA%d:", unit);
+		nouveau_bitfield_print(nvc0_fifo_pbdma_intr, show);
 		pr_cont("\n");
 		nv_error(priv,
-			 "SUBFIFO%d: ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n",
+			 "PBDMA%d: ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n",
 			 unit, chid,
 			 nouveau_client_name_for_fifo_chid(&priv->base, chid),
 			 subc, mthd, data);
@@ -515,6 +703,56 @@ nvc0_fifo_isr_subfifo_intr(struct nvc0_fifo_priv *priv, int unit)
 	nv_wr32(priv, 0x040108 + (unit * 0x2000), stat);
 }
 
+static void
+nvc0_fifo_intr_runlist(struct nvc0_fifo_priv *priv)
+{
+	u32 intr = nv_rd32(priv, 0x002a00);
+
+	if (intr & 0x10000000) {
+		wake_up(&priv->runlist.wait);
+		nv_wr32(priv, 0x002a00, 0x10000000);
+		intr &= ~0x10000000;
+	}
+
+	if (intr) {
+		nv_error(priv, "RUNLIST 0x%08x\n", intr);
+		nv_wr32(priv, 0x002a00, intr);
+	}
+}
+
+static void
+nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn)
+{
+	u32 intr = nv_rd32(priv, 0x0025a8 + (engn * 0x04));
+	u32 inte = nv_rd32(priv, 0x002628);
+	u32 unkn;
+
+	for (unkn = 0; unkn < 8; unkn++) {
+		u32 ints = (intr >> (unkn * 0x04)) & inte;
+		if (ints & 0x1) {
+			nouveau_event_trigger(priv->base.uevent, 0);
+			ints &= ~1;
+		}
+		if (ints) {
+			nv_error(priv, "ENGINE %d %d %01x", engn, unkn, ints);
+			nv_mask(priv, 0x002628, ints, 0);
+		}
+	}
+
+	nv_wr32(priv, 0x0025a8 + (engn * 0x04), intr);
+}
+
+static void
+nvc0_fifo_intr_engine(struct nvc0_fifo_priv *priv)
+{
+	u32 mask = nv_rd32(priv, 0x0025a4);
+	while (mask) {
+		u32 unit = __ffs(mask);
+		nvc0_fifo_intr_engine_unit(priv, unit);
+		mask &= ~(1 << unit);
+	}
+}
+
 static void
 nvc0_fifo_intr(struct nouveau_subdev *subdev)
 {
@@ -530,8 +768,7 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev)
 	}
 
 	if (stat & 0x00000100) {
-		u32 intr = nv_rd32(priv, 0x00254c);
-		nv_warn(priv, "INTR 0x00000100: 0x%08x\n", intr);
+		nvc0_fifo_intr_sched(priv);
 		nv_wr32(priv, 0x002100, 0x00000100);
 		stat &= ~0x00000100;
 	}
@@ -551,52 +788,41 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev)
 	}
 
 	if (stat & 0x10000000) {
-		u32 units = nv_rd32(priv, 0x00259c);
-		u32 u = units;
-
-		while (u) {
-			int i = ffs(u) - 1;
-			nvc0_fifo_isr_vm_fault(priv, i);
-			u &= ~(1 << i);
+		u32 mask = nv_rd32(priv, 0x00259c);
+		while (mask) {
+			u32 unit = __ffs(mask);
+			nvc0_fifo_intr_fault(priv, unit);
+			nv_wr32(priv, 0x00259c, (1 << unit));
+			mask &= ~(1 << unit);
 		}
-
-		nv_wr32(priv, 0x00259c, units);
 		stat &= ~0x10000000;
 	}
 
 	if (stat & 0x20000000) {
-		u32 units = nv_rd32(priv, 0x0025a0);
-		u32 u = units;
-
-		while (u) {
-			int i = ffs(u) - 1;
-			nvc0_fifo_isr_subfifo_intr(priv, i);
-			u &= ~(1 << i);
+		u32 mask = nv_rd32(priv, 0x0025a0);
+		while (mask) {
+			u32 unit = __ffs(mask);
+			nvc0_fifo_intr_pbdma(priv, unit);
+			nv_wr32(priv, 0x0025a0, (1 << unit));
+			mask &= ~(1 << unit);
 		}
-
-		nv_wr32(priv, 0x0025a0, units);
 		stat &= ~0x20000000;
 	}
 
 	if (stat & 0x40000000) {
-		u32 intr0 = nv_rd32(priv, 0x0025a4);
-		u32 intr1 = nv_mask(priv, 0x002a00, 0x00000000, 0x00000);
-		nv_debug(priv, "INTR 0x40000000: 0x%08x 0x%08x\n",
-			       intr0, intr1);
+		nvc0_fifo_intr_runlist(priv);
 		stat &= ~0x40000000;
 	}
 
 	if (stat & 0x80000000) {
-		u32 intr = nv_mask(priv, 0x0025a8, 0x00000000, 0x00000000);
-		nouveau_event_trigger(priv->base.uevent, 0);
-		nv_debug(priv, "INTR 0x80000000: 0x%08x\n", intr);
+		nvc0_fifo_intr_engine(priv);
 		stat &= ~0x80000000;
 	}
 
 	if (stat) {
-		nv_fatal(priv, "unhandled status 0x%08x\n", stat);
+		nv_error(priv, "INTR 0x%08x\n", stat);
+		nv_mask(priv, 0x002140, stat, 0x00000000);
 		nv_wr32(priv, 0x002100, stat);
-		nv_wr32(priv, 0x002140, 0);
 	}
 }
 
@@ -627,16 +853,20 @@ nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	if (ret)
 		return ret;
 
+	INIT_WORK(&priv->fault, nvc0_fifo_recover_work);
+
 	ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0x1000, 0,
-				&priv->playlist[0]);
+				&priv->runlist.mem[0]);
 	if (ret)
 		return ret;
 
 	ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0x1000, 0,
-				&priv->playlist[1]);
+				&priv->runlist.mem[1]);
 	if (ret)
 		return ret;
 
+	init_waitqueue_head(&priv->runlist.wait);
+
 	ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 0x1000, 0x1000, 0,
 				&priv->user.mem);
 	if (ret)
@@ -665,8 +895,8 @@ nvc0_fifo_dtor(struct nouveau_object *object)
 
 	nouveau_gpuobj_unmap(&priv->user.bar);
 	nouveau_gpuobj_ref(NULL, &priv->user.mem);
-	nouveau_gpuobj_ref(NULL, &priv->playlist[1]);
-	nouveau_gpuobj_ref(NULL, &priv->playlist[0]);
+	nouveau_gpuobj_ref(NULL, &priv->runlist.mem[0]);
+	nouveau_gpuobj_ref(NULL, &priv->runlist.mem[1]);
 
 	nouveau_fifo_destroy(&priv->base);
 }
@@ -685,9 +915,9 @@ nvc0_fifo_init(struct nouveau_object *object)
 	nv_wr32(priv, 0x002204, 0xffffffff);
 
 	priv->spoon_nr = hweight32(nv_rd32(priv, 0x002204));
-	nv_debug(priv, "%d subfifo(s)\n", priv->spoon_nr);
+	nv_debug(priv, "%d PBDMA unit(s)\n", priv->spoon_nr);
 
-	/* assign engines to subfifos */
+	/* assign engines to PBDMAs */
 	if (priv->spoon_nr >= 3) {
 		nv_wr32(priv, 0x002208, ~(1 << 0)); /* PGRAPH */
 		nv_wr32(priv, 0x00220c, ~(1 << 1)); /* PVP */
@@ -697,7 +927,7 @@ nvc0_fifo_init(struct nouveau_object *object)
 		nv_wr32(priv, 0x00221c, ~(1 << 1)); /* PCE1 */
 	}
 
-	/* PSUBFIFO[n] */
+	/* PBDMA[n] */
 	for (i = 0; i < priv->spoon_nr; i++) {
 		nv_mask(priv, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000);
 		nv_wr32(priv, 0x040108 + (i * 0x2000), 0xffffffff); /* INTR */
@@ -707,10 +937,9 @@ nvc0_fifo_init(struct nouveau_object *object)
 	nv_mask(priv, 0x002200, 0x00000001, 0x00000001);
 	nv_wr32(priv, 0x002254, 0x10000000 | priv->user.bar.offset >> 12);
 
-	nv_wr32(priv, 0x002a00, 0xffffffff); /* clears PFIFO.INTR bit 30 */
 	nv_wr32(priv, 0x002100, 0xffffffff);
-	nv_wr32(priv, 0x002140, 0x3fffffff);
-	nv_wr32(priv, 0x002628, 0x00000001); /* makes mthd 0x20 work */
+	nv_wr32(priv, 0x002140, 0x7fffffff);
+	nv_wr32(priv, 0x002628, 0x00000001); /* ENGINE_INTR_EN */
 	return 0;
 }
 

+ 356 - 151
drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c

@@ -60,10 +60,15 @@ static const struct {
 struct nve0_fifo_engn {
 	struct nouveau_gpuobj *runlist[2];
 	int cur_runlist;
+	wait_queue_head_t wait;
 };
 
 struct nve0_fifo_priv {
 	struct nouveau_fifo base;
+
+	struct work_struct fault;
+	u64 mask;
+
 	struct nve0_fifo_engn engine[FIFO_ENGINE_NR];
 	struct {
 		struct nouveau_gpuobj *mem;
@@ -81,6 +86,11 @@ struct nve0_fifo_base {
 struct nve0_fifo_chan {
 	struct nouveau_fifo_chan base;
 	u32 engine;
+	enum {
+		STOPPED,
+		RUNNING,
+		KILLED
+	} state;
 };
 
 /*******************************************************************************
@@ -93,7 +103,6 @@ nve0_fifo_runlist_update(struct nve0_fifo_priv *priv, u32 engine)
 	struct nouveau_bar *bar = nouveau_bar(priv);
 	struct nve0_fifo_engn *engn = &priv->engine[engine];
 	struct nouveau_gpuobj *cur;
-	u32 match = (engine << 16) | 0x00000001;
 	int i, p;
 
 	mutex_lock(&nv_subdev(priv)->mutex);
@@ -101,18 +110,21 @@ nve0_fifo_runlist_update(struct nve0_fifo_priv *priv, u32 engine)
 	engn->cur_runlist = !engn->cur_runlist;
 
 	for (i = 0, p = 0; i < priv->base.max; i++) {
-		u32 ctrl = nv_rd32(priv, 0x800004 + (i * 8)) & 0x001f0001;
-		if (ctrl != match)
-			continue;
-		nv_wo32(cur, p + 0, i);
-		nv_wo32(cur, p + 4, 0x00000000);
-		p += 8;
+		struct nve0_fifo_chan *chan = (void *)priv->base.channel[i];
+		if (chan && chan->state == RUNNING && chan->engine == engine) {
+			nv_wo32(cur, p + 0, i);
+			nv_wo32(cur, p + 4, 0x00000000);
+			p += 8;
+		}
 	}
 	bar->flush(bar);
 
 	nv_wr32(priv, 0x002270, cur->addr >> 12);
 	nv_wr32(priv, 0x002274, (engine << 20) | (p >> 3));
-	if (!nv_wait(priv, 0x002284 + (engine * 8), 0x00100000, 0x00000000))
+
+	if (wait_event_timeout(engn->wait, !(nv_rd32(priv, 0x002284 +
+			       (engine * 0x08)) & 0x00100000),
+				msecs_to_jiffies(2000)) == 0)
 		nv_error(priv, "runlist %d update timeout\n", engine);
 	mutex_unlock(&nv_subdev(priv)->mutex);
 }
@@ -129,9 +141,11 @@ nve0_fifo_context_attach(struct nouveau_object *parent,
 
 	switch (nv_engidx(object->engine)) {
 	case NVDEV_ENGINE_SW   :
+		return 0;
 	case NVDEV_ENGINE_COPY0:
 	case NVDEV_ENGINE_COPY1:
 	case NVDEV_ENGINE_COPY2:
+		nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12;
 		return 0;
 	case NVDEV_ENGINE_GR   : addr = 0x0210; break;
 	case NVDEV_ENGINE_BSP  : addr = 0x0270; break;
@@ -279,9 +293,13 @@ nve0_fifo_chan_init(struct nouveau_object *object)
 
 	nv_mask(priv, 0x800004 + (chid * 8), 0x000f0000, chan->engine << 16);
 	nv_wr32(priv, 0x800000 + (chid * 8), 0x80000000 | base->addr >> 12);
-	nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400);
-	nve0_fifo_runlist_update(priv, chan->engine);
-	nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400);
+
+	if (chan->state == STOPPED && (chan->state = RUNNING) == RUNNING) {
+		nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400);
+		nve0_fifo_runlist_update(priv, chan->engine);
+		nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400);
+	}
+
 	return 0;
 }
 
@@ -292,10 +310,12 @@ nve0_fifo_chan_fini(struct nouveau_object *object, bool suspend)
 	struct nve0_fifo_chan *chan = (void *)object;
 	u32 chid = chan->base.chid;
 
-	nv_mask(priv, 0x800004 + (chid * 8), 0x00000800, 0x00000800);
-	nve0_fifo_runlist_update(priv, chan->engine);
-	nv_wr32(priv, 0x800000 + (chid * 8), 0x00000000);
+	if (chan->state == RUNNING && (chan->state = STOPPED) == STOPPED) {
+		nv_mask(priv, 0x800004 + (chid * 8), 0x00000800, 0x00000800);
+		nve0_fifo_runlist_update(priv, chan->engine);
+	}
 
+	nv_wr32(priv, 0x800000 + (chid * 8), 0x00000000);
 	return nouveau_fifo_channel_fini(&chan->base, suspend);
 }
 
@@ -377,14 +397,211 @@ nve0_fifo_cclass = {
  * PFIFO engine
  ******************************************************************************/
 
-static const struct nouveau_enum nve0_fifo_sched_reason[] = {
+static inline int
+nve0_fifo_engidx(struct nve0_fifo_priv *priv, u32 engn)
+{
+	switch (engn) {
+	case NVDEV_ENGINE_GR   :
+	case NVDEV_ENGINE_COPY2: engn = 0; break;
+	case NVDEV_ENGINE_BSP  : engn = 1; break;
+	case NVDEV_ENGINE_PPP  : engn = 2; break;
+	case NVDEV_ENGINE_VP   : engn = 3; break;
+	case NVDEV_ENGINE_COPY0: engn = 4; break;
+	case NVDEV_ENGINE_COPY1: engn = 5; break;
+	case NVDEV_ENGINE_VENC : engn = 6; break;
+	default:
+		return -1;
+	}
+
+	return engn;
+}
+
+static inline struct nouveau_engine *
+nve0_fifo_engine(struct nve0_fifo_priv *priv, u32 engn)
+{
+	if (engn >= ARRAY_SIZE(fifo_engine))
+		return NULL;
+	return nouveau_engine(priv, fifo_engine[engn].subdev);
+}
+
+static void
+nve0_fifo_recover_work(struct work_struct *work)
+{
+	struct nve0_fifo_priv *priv = container_of(work, typeof(*priv), fault);
+	struct nouveau_object *engine;
+	unsigned long flags;
+	u32 engn, engm = 0;
+	u64 mask, todo;
+
+	spin_lock_irqsave(&priv->base.lock, flags);
+	mask = priv->mask;
+	priv->mask = 0ULL;
+	spin_unlock_irqrestore(&priv->base.lock, flags);
+
+	for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn))
+		engm |= 1 << nve0_fifo_engidx(priv, engn);
+	nv_mask(priv, 0x002630, engm, engm);
+
+	for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) {
+		if ((engine = (void *)nouveau_engine(priv, engn))) {
+			nv_ofuncs(engine)->fini(engine, false);
+			WARN_ON(nv_ofuncs(engine)->init(engine));
+		}
+		nve0_fifo_runlist_update(priv, nve0_fifo_engidx(priv, engn));
+	}
+
+	nv_wr32(priv, 0x00262c, engm);
+	nv_mask(priv, 0x002630, engm, 0x00000000);
+}
+
+static void
+nve0_fifo_recover(struct nve0_fifo_priv *priv, struct nouveau_engine *engine,
+		  struct nve0_fifo_chan *chan)
+{
+	struct nouveau_object *engobj = nv_object(engine);
+	u32 chid = chan->base.chid;
+	unsigned long flags;
+
+	nv_error(priv, "%s engine fault on channel %d, recovering...\n",
+		       nv_subdev(engine)->name, chid);
+
+	nv_mask(priv, 0x800004 + (chid * 0x08), 0x00000800, 0x00000800);
+	chan->state = KILLED;
+
+	spin_lock_irqsave(&priv->base.lock, flags);
+	priv->mask |= 1ULL << nv_engidx(engobj);
+	spin_unlock_irqrestore(&priv->base.lock, flags);
+	schedule_work(&priv->fault);
+}
+
+static int
+nve0_fifo_swmthd(struct nve0_fifo_priv *priv, u32 chid, u32 mthd, u32 data)
+{
+	struct nve0_fifo_chan *chan = NULL;
+	struct nouveau_handle *bind;
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	spin_lock_irqsave(&priv->base.lock, flags);
+	if (likely(chid >= priv->base.min && chid <= priv->base.max))
+		chan = (void *)priv->base.channel[chid];
+	if (unlikely(!chan))
+		goto out;
+
+	bind = nouveau_namedb_get_class(nv_namedb(chan), 0x906e);
+	if (likely(bind)) {
+		if (!mthd || !nv_call(bind->object, mthd, data))
+			ret = 0;
+		nouveau_namedb_put(bind);
+	}
+
+out:
+	spin_unlock_irqrestore(&priv->base.lock, flags);
+	return ret;
+}
+
+static const struct nouveau_enum
+nve0_fifo_bind_reason[] = {
+	{ 0x01, "BIND_NOT_UNBOUND" },
+	{ 0x02, "SNOOP_WITHOUT_BAR1" },
+	{ 0x03, "UNBIND_WHILE_RUNNING" },
+	{ 0x05, "INVALID_RUNLIST" },
+	{ 0x06, "INVALID_CTX_TGT" },
+	{ 0x0b, "UNBIND_WHILE_PARKED" },
+	{}
+};
+
+static void
+nve0_fifo_intr_bind(struct nve0_fifo_priv *priv)
+{
+	u32 intr = nv_rd32(priv, 0x00252c);
+	u32 code = intr & 0x000000ff;
+	const struct nouveau_enum *en;
+	char enunk[6] = "";
+
+	en = nouveau_enum_find(nve0_fifo_bind_reason, code);
+	if (!en)
+		snprintf(enunk, sizeof(enunk), "UNK%02x", code);
+
+	nv_error(priv, "BIND_ERROR [ %s ]\n", en ? en->name : enunk);
+}
+
+static const struct nouveau_enum
+nve0_fifo_sched_reason[] = {
 	{ 0x0a, "CTXSW_TIMEOUT" },
 	{}
 };
 
-static const struct nouveau_enum nve0_fifo_fault_engine[] = {
+static void
+nve0_fifo_intr_sched_ctxsw(struct nve0_fifo_priv *priv)
+{
+	struct nouveau_engine *engine;
+	struct nve0_fifo_chan *chan;
+	u32 engn;
+
+	for (engn = 0; engn < ARRAY_SIZE(fifo_engine); engn++) {
+		u32 stat = nv_rd32(priv, 0x002640 + (engn * 0x04));
+		u32 busy = (stat & 0x80000000);
+		u32 next = (stat & 0x07ff0000) >> 16;
+		u32 chsw = (stat & 0x00008000);
+		u32 save = (stat & 0x00004000);
+		u32 load = (stat & 0x00002000);
+		u32 prev = (stat & 0x000007ff);
+		u32 chid = load ? next : prev;
+		(void)save;
+
+		if (busy && chsw) {
+			if (!(chan = (void *)priv->base.channel[chid]))
+				continue;
+			if (!(engine = nve0_fifo_engine(priv, engn)))
+				continue;
+			nve0_fifo_recover(priv, engine, chan);
+		}
+	}
+}
+
+static void
+nve0_fifo_intr_sched(struct nve0_fifo_priv *priv)
+{
+	u32 intr = nv_rd32(priv, 0x00254c);
+	u32 code = intr & 0x000000ff;
+	const struct nouveau_enum *en;
+	char enunk[6] = "";
+
+	en = nouveau_enum_find(nve0_fifo_sched_reason, code);
+	if (!en)
+		snprintf(enunk, sizeof(enunk), "UNK%02x", code);
+
+	nv_error(priv, "SCHED_ERROR [ %s ]\n", en ? en->name : enunk);
+
+	switch (code) {
+	case 0x0a:
+		nve0_fifo_intr_sched_ctxsw(priv);
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+nve0_fifo_intr_chsw(struct nve0_fifo_priv *priv)
+{
+	u32 stat = nv_rd32(priv, 0x00256c);
+	nv_error(priv, "CHSW_ERROR 0x%08x\n", stat);
+	nv_wr32(priv, 0x00256c, stat);
+}
+
+static void
+nve0_fifo_intr_dropped_fault(struct nve0_fifo_priv *priv)
+{
+	u32 stat = nv_rd32(priv, 0x00259c);
+	nv_error(priv, "DROPPED_MMU_FAULT 0x%08x\n", stat);
+}
+
+static const struct nouveau_enum
+nve0_fifo_fault_engine[] = {
 	{ 0x00, "GR", NULL, NVDEV_ENGINE_GR },
-	{ 0x03, "IFB" },
+	{ 0x03, "IFB", NULL, NVDEV_ENGINE_IFB },
 	{ 0x04, "BAR1", NULL, NVDEV_SUBDEV_BAR },
 	{ 0x05, "BAR3", NULL, NVDEV_SUBDEV_INSTMEM },
 	{ 0x07, "PBDMA0", NULL, NVDEV_ENGINE_FIFO },
@@ -402,7 +619,8 @@ static const struct nouveau_enum nve0_fifo_fault_engine[] = {
 	{}
 };
 
-static const struct nouveau_enum nve0_fifo_fault_reason[] = {
+static const struct nouveau_enum
+nve0_fifo_fault_reason[] = {
 	{ 0x00, "PDE" },
 	{ 0x01, "PDE_SIZE" },
 	{ 0x02, "PTE" },
@@ -422,7 +640,8 @@ static const struct nouveau_enum nve0_fifo_fault_reason[] = {
 	{}
 };
 
-static const struct nouveau_enum nve0_fifo_fault_hubclient[] = {
+static const struct nouveau_enum
+nve0_fifo_fault_hubclient[] = {
 	{ 0x00, "VIP" },
 	{ 0x01, "CE0" },
 	{ 0x02, "CE1" },
@@ -458,7 +677,8 @@ static const struct nouveau_enum nve0_fifo_fault_hubclient[] = {
 	{}
 };
 
-static const struct nouveau_enum nve0_fifo_fault_gpcclient[] = {
+static const struct nouveau_enum
+nve0_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" },
@@ -483,6 +703,82 @@ static const struct nouveau_enum nve0_fifo_fault_gpcclient[] = {
 	{}
 };
 
+static void
+nve0_fifo_intr_fault(struct nve0_fifo_priv *priv, int unit)
+{
+	u32 inst = nv_rd32(priv, 0x002800 + (unit * 0x10));
+	u32 valo = nv_rd32(priv, 0x002804 + (unit * 0x10));
+	u32 vahi = nv_rd32(priv, 0x002808 + (unit * 0x10));
+	u32 stat = nv_rd32(priv, 0x00280c + (unit * 0x10));
+	u32 gpc    = (stat & 0x1f000000) >> 24;
+	u32 client = (stat & 0x00001f00) >> 8;
+	u32 write  = (stat & 0x00000080);
+	u32 hub    = (stat & 0x00000040);
+	u32 reason = (stat & 0x0000000f);
+	struct nouveau_object *engctx = NULL, *object;
+	struct nouveau_engine *engine = NULL;
+	const struct nouveau_enum *er, *eu, *ec;
+	char erunk[6] = "";
+	char euunk[6] = "";
+	char ecunk[6] = "";
+	char gpcid[3] = "";
+
+	er = nouveau_enum_find(nve0_fifo_fault_reason, reason);
+	if (!er)
+		snprintf(erunk, sizeof(erunk), "UNK%02X", reason);
+
+	eu = nouveau_enum_find(nve0_fifo_fault_engine, unit);
+	if (eu) {
+		switch (eu->data2) {
+		case NVDEV_SUBDEV_BAR:
+			nv_mask(priv, 0x001704, 0x00000000, 0x00000000);
+			break;
+		case NVDEV_SUBDEV_INSTMEM:
+			nv_mask(priv, 0x001714, 0x00000000, 0x00000000);
+			break;
+		case NVDEV_ENGINE_IFB:
+			nv_mask(priv, 0x001718, 0x00000000, 0x00000000);
+			break;
+		default:
+			engine = nouveau_engine(priv, eu->data2);
+			if (engine)
+				engctx = nouveau_engctx_get(engine, inst);
+			break;
+		}
+	} else {
+		snprintf(euunk, sizeof(euunk), "UNK%02x", unit);
+	}
+
+	if (hub) {
+		ec = nouveau_enum_find(nve0_fifo_fault_hubclient, client);
+	} else {
+		ec = nouveau_enum_find(nve0_fifo_fault_gpcclient, client);
+		snprintf(gpcid, sizeof(gpcid), "%d", gpc);
+	}
+
+	if (!ec)
+		snprintf(ecunk, sizeof(ecunk), "UNK%02x", client);
+
+	nv_error(priv, "%s fault at 0x%010llx [%s] from %s/%s%s%s%s on "
+		       "channel 0x%010llx [%s]\n", write ? "write" : "read",
+		 (u64)vahi << 32 | valo, er ? er->name : erunk,
+		 eu ? eu->name : euunk, hub ? "" : "GPC", gpcid, hub ? "" : "/",
+		 ec ? ec->name : ecunk, (u64)inst << 12,
+		 nouveau_client_name(engctx));
+
+	object = engctx;
+	while (object) {
+		switch (nv_mclass(object)) {
+		case NVE0_CHANNEL_IND_CLASS:
+			nve0_fifo_recover(priv, engine, (void *)object);
+			break;
+		}
+		object = object->parent;
+	}
+
+	nouveau_engctx_put(engctx);
+}
+
 static const struct nouveau_bitfield nve0_fifo_pbdma_intr[] = {
 	{ 0x00000001, "MEMREQ" },
 	{ 0x00000002, "MEMACK_TIMEOUT" },
@@ -517,104 +813,6 @@ static const struct nouveau_bitfield nve0_fifo_pbdma_intr[] = {
 	{}
 };
 
-static void
-nve0_fifo_intr_sched(struct nve0_fifo_priv *priv)
-{
-	u32 intr = nv_rd32(priv, 0x00254c);
-	u32 code = intr & 0x000000ff;
-	nv_error(priv, "SCHED_ERROR [");
-	nouveau_enum_print(nve0_fifo_sched_reason, code);
-	pr_cont("]\n");
-}
-
-static void
-nve0_fifo_intr_chsw(struct nve0_fifo_priv *priv)
-{
-	u32 stat = nv_rd32(priv, 0x00256c);
-	nv_error(priv, "CHSW_ERROR 0x%08x\n", stat);
-	nv_wr32(priv, 0x00256c, stat);
-}
-
-static void
-nve0_fifo_intr_dropped_fault(struct nve0_fifo_priv *priv)
-{
-	u32 stat = nv_rd32(priv, 0x00259c);
-	nv_error(priv, "DROPPED_MMU_FAULT 0x%08x\n", stat);
-}
-
-static void
-nve0_fifo_intr_fault(struct nve0_fifo_priv *priv, int unit)
-{
-	u32 inst = nv_rd32(priv, 0x2800 + (unit * 0x10));
-	u32 valo = nv_rd32(priv, 0x2804 + (unit * 0x10));
-	u32 vahi = nv_rd32(priv, 0x2808 + (unit * 0x10));
-	u32 stat = nv_rd32(priv, 0x280c + (unit * 0x10));
-	u32 client = (stat & 0x00001f00) >> 8;
-	struct nouveau_engine *engine = NULL;
-	struct nouveau_object *engctx = NULL;
-	const struct nouveau_enum *en;
-	const char *name = "unknown";
-
-	nv_error(priv, "PFIFO: %s fault at 0x%010llx [", (stat & 0x00000080) ?
-		       "write" : "read", (u64)vahi << 32 | valo);
-	nouveau_enum_print(nve0_fifo_fault_reason, stat & 0x0000000f);
-	pr_cont("] from ");
-	en = nouveau_enum_print(nve0_fifo_fault_engine, unit);
-	if (stat & 0x00000040) {
-		pr_cont("/");
-		nouveau_enum_print(nve0_fifo_fault_hubclient, client);
-	} else {
-		pr_cont("/GPC%d/", (stat & 0x1f000000) >> 24);
-		nouveau_enum_print(nve0_fifo_fault_gpcclient, client);
-	}
-
-	if (en && en->data2) {
-		if (en->data2 == NVDEV_SUBDEV_BAR) {
-			nv_mask(priv, 0x001704, 0x00000000, 0x00000000);
-			name = "BAR1";
-		} else
-		if (en->data2 == NVDEV_SUBDEV_INSTMEM) {
-			nv_mask(priv, 0x001714, 0x00000000, 0x00000000);
-			name = "BAR3";
-		} else {
-			engine = nouveau_engine(priv, en->data2);
-			if (engine) {
-				engctx = nouveau_engctx_get(engine, inst);
-				name   = nouveau_client_name(engctx);
-			}
-		}
-	}
-	pr_cont(" on channel 0x%010llx [%s]\n", (u64)inst << 12, name);
-
-	nouveau_engctx_put(engctx);
-}
-
-static int
-nve0_fifo_swmthd(struct nve0_fifo_priv *priv, u32 chid, u32 mthd, u32 data)
-{
-	struct nve0_fifo_chan *chan = NULL;
-	struct nouveau_handle *bind;
-	unsigned long flags;
-	int ret = -EINVAL;
-
-	spin_lock_irqsave(&priv->base.lock, flags);
-	if (likely(chid >= priv->base.min && chid <= priv->base.max))
-		chan = (void *)priv->base.channel[chid];
-	if (unlikely(!chan))
-		goto out;
-
-	bind = nouveau_namedb_get_class(nv_namedb(chan), 0x906e);
-	if (likely(bind)) {
-		if (!mthd || !nv_call(bind->object, mthd, data))
-			ret = 0;
-		nouveau_namedb_put(bind);
-	}
-
-out:
-	spin_unlock_irqrestore(&priv->base.lock, flags);
-	return ret;
-}
-
 static void
 nve0_fifo_intr_pbdma(struct nve0_fifo_priv *priv, int unit)
 {
@@ -646,6 +844,24 @@ nve0_fifo_intr_pbdma(struct nve0_fifo_priv *priv, int unit)
 	nv_wr32(priv, 0x040108 + (unit * 0x2000), stat);
 }
 
+static void
+nve0_fifo_intr_runlist(struct nve0_fifo_priv *priv)
+{
+	u32 mask = nv_rd32(priv, 0x002a00);
+	while (mask) {
+		u32 engn = __ffs(mask);
+		wake_up(&priv->engine[engn].wait);
+		nv_wr32(priv, 0x002a00, 1 << engn);
+		mask &= ~(1 << engn);
+	}
+}
+
+static void
+nve0_fifo_intr_engine(struct nve0_fifo_priv *priv)
+{
+	nouveau_event_trigger(priv->base.uevent, 0);
+}
+
 static void
 nve0_fifo_intr(struct nouveau_subdev *subdev)
 {
@@ -654,8 +870,7 @@ nve0_fifo_intr(struct nouveau_subdev *subdev)
 	u32 stat = nv_rd32(priv, 0x002100) & mask;
 
 	if (stat & 0x00000001) {
-		u32 stat = nv_rd32(priv, 0x00252c);
-		nv_error(priv, "BIND_ERROR 0x%08x\n", stat);
+		nve0_fifo_intr_bind(priv);
 		nv_wr32(priv, 0x002100, 0x00000001);
 		stat &= ~0x00000001;
 	}
@@ -697,55 +912,42 @@ nve0_fifo_intr(struct nouveau_subdev *subdev)
 	}
 
 	if (stat & 0x10000000) {
-		u32 units = nv_rd32(priv, 0x00259c);
-		u32 u = units;
-
-		while (u) {
-			int i = ffs(u) - 1;
-			nve0_fifo_intr_fault(priv, i);
-			u &= ~(1 << i);
+		u32 mask = nv_rd32(priv, 0x00259c);
+		while (mask) {
+			u32 unit = __ffs(mask);
+			nve0_fifo_intr_fault(priv, unit);
+			nv_wr32(priv, 0x00259c, (1 << unit));
+			mask &= ~(1 << unit);
 		}
-
-		nv_wr32(priv, 0x00259c, units);
 		stat &= ~0x10000000;
 	}
 
 	if (stat & 0x20000000) {
 		u32 mask = nv_rd32(priv, 0x0025a0);
-		u32 temp = mask;
-
-		while (temp) {
-			u32 unit = ffs(temp) - 1;
+		while (mask) {
+			u32 unit = __ffs(mask);
 			nve0_fifo_intr_pbdma(priv, unit);
-			temp &= ~(1 << unit);
+			nv_wr32(priv, 0x0025a0, (1 << unit));
+			mask &= ~(1 << unit);
 		}
-
-		nv_wr32(priv, 0x0025a0, mask);
 		stat &= ~0x20000000;
 	}
 
 	if (stat & 0x40000000) {
-		u32 mask = nv_mask(priv, 0x002a00, 0x00000000, 0x00000000);
-
-		while (mask) {
-			u32 engn = ffs(mask) - 1;
-			/* runlist event, not currently used */
-			mask &= ~(1 << engn);
-		}
-
+		nve0_fifo_intr_runlist(priv);
 		stat &= ~0x40000000;
 	}
 
 	if (stat & 0x80000000) {
-		nouveau_event_trigger(priv->base.uevent, 0);
+		nve0_fifo_intr_engine(priv);
 		nv_wr32(priv, 0x002100, 0x80000000);
 		stat &= ~0x80000000;
 	}
 
 	if (stat) {
-		nv_fatal(priv, "unhandled status 0x%08x\n", stat);
+		nv_error(priv, "INTR 0x%08x\n", stat);
+		nv_mask(priv, 0x002140, stat, 0x00000000);
 		nv_wr32(priv, 0x002100, stat);
-		nv_wr32(priv, 0x002140, 0);
 	}
 }
 
@@ -802,9 +1004,8 @@ nve0_fifo_init(struct nouveau_object *object)
 
 	nv_wr32(priv, 0x002254, 0x10000000 | priv->user.bar.offset >> 12);
 
-	nv_wr32(priv, 0x002a00, 0xffffffff);
 	nv_wr32(priv, 0x002100, 0xffffffff);
-	nv_wr32(priv, 0x002140, 0x3fffffff);
+	nv_wr32(priv, 0x002140, 0x7fffffff);
 	return 0;
 }
 
@@ -840,6 +1041,8 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	if (ret)
 		return ret;
 
+	INIT_WORK(&priv->fault, nve0_fifo_recover_work);
+
 	for (i = 0; i < FIFO_ENGINE_NR; i++) {
 		ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0x1000,
 					 0, &priv->engine[i].runlist[0]);
@@ -850,10 +1053,12 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 					 0, &priv->engine[i].runlist[1]);
 		if (ret)
 			return ret;
+
+		init_waitqueue_head(&priv->engine[i].wait);
 	}
 
-	ret = nouveau_gpuobj_new(nv_object(priv), NULL, 4096 * 0x200, 0x1000,
-				 NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem);
+	ret = nouveau_gpuobj_new(nv_object(priv), NULL, impl->channels * 0x200,
+				0x1000, NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem);
 	if (ret)
 		return ret;
 

+ 989 - 0
drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c

@@ -0,0 +1,989 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include "ctxnvc0.h"
+
+/*******************************************************************************
+ * PGRAPH context register lists
+ ******************************************************************************/
+
+static const struct nvc0_graph_init
+gm107_grctx_init_icmd_0[] = {
+	{ 0x001000,   1, 0x01, 0x00000004 },
+	{ 0x000039,   3, 0x01, 0x00000000 },
+	{ 0x0000a9,   1, 0x01, 0x0000ffff },
+	{ 0x000038,   1, 0x01, 0x0fac6881 },
+	{ 0x00003d,   1, 0x01, 0x00000001 },
+	{ 0x0000e8,   8, 0x01, 0x00000400 },
+	{ 0x000078,   8, 0x01, 0x00000300 },
+	{ 0x000050,   1, 0x01, 0x00000011 },
+	{ 0x000058,   8, 0x01, 0x00000008 },
+	{ 0x000208,   8, 0x01, 0x00000001 },
+	{ 0x000081,   1, 0x01, 0x00000001 },
+	{ 0x000085,   1, 0x01, 0x00000004 },
+	{ 0x000088,   1, 0x01, 0x00000400 },
+	{ 0x000090,   1, 0x01, 0x00000300 },
+	{ 0x000098,   1, 0x01, 0x00001001 },
+	{ 0x0000e3,   1, 0x01, 0x00000001 },
+	{ 0x0000da,   1, 0x01, 0x00000001 },
+	{ 0x0000f8,   1, 0x01, 0x00000003 },
+	{ 0x0000fa,   1, 0x01, 0x00000001 },
+	{ 0x0000b1,   2, 0x01, 0x00000001 },
+	{ 0x00009f,   4, 0x01, 0x0000ffff },
+	{ 0x0000a8,   1, 0x01, 0x0000ffff },
+	{ 0x0000ad,   1, 0x01, 0x0000013e },
+	{ 0x0000e1,   1, 0x01, 0x00000010 },
+	{ 0x000290,  16, 0x01, 0x00000000 },
+	{ 0x0003b0,  16, 0x01, 0x00000000 },
+	{ 0x0002a0,  16, 0x01, 0x00000000 },
+	{ 0x000420,  16, 0x01, 0x00000000 },
+	{ 0x0002b0,  16, 0x01, 0x00000000 },
+	{ 0x000430,  16, 0x01, 0x00000000 },
+	{ 0x0002c0,  16, 0x01, 0x00000000 },
+	{ 0x0004d0,  16, 0x01, 0x00000000 },
+	{ 0x000720,  16, 0x01, 0x00000000 },
+	{ 0x0008c0,  16, 0x01, 0x00000000 },
+	{ 0x000890,  16, 0x01, 0x00000000 },
+	{ 0x0008e0,  16, 0x01, 0x00000000 },
+	{ 0x0008a0,  16, 0x01, 0x00000000 },
+	{ 0x0008f0,  16, 0x01, 0x00000000 },
+	{ 0x00094c,   1, 0x01, 0x000000ff },
+	{ 0x00094d,   1, 0x01, 0xffffffff },
+	{ 0x00094e,   1, 0x01, 0x00000002 },
+	{ 0x0002f2,   2, 0x01, 0x00000001 },
+	{ 0x0002f5,   1, 0x01, 0x00000001 },
+	{ 0x0002f7,   1, 0x01, 0x00000001 },
+	{ 0x000303,   1, 0x01, 0x00000001 },
+	{ 0x0002e6,   1, 0x01, 0x00000001 },
+	{ 0x000466,   1, 0x01, 0x00000052 },
+	{ 0x000301,   1, 0x01, 0x3f800000 },
+	{ 0x000304,   1, 0x01, 0x30201000 },
+	{ 0x000305,   1, 0x01, 0x70605040 },
+	{ 0x000306,   1, 0x01, 0xb8a89888 },
+	{ 0x000307,   1, 0x01, 0xf8e8d8c8 },
+	{ 0x00030a,   1, 0x01, 0x00ffff00 },
+	{ 0x0000de,   1, 0x01, 0x00000001 },
+	{ 0x00030b,   1, 0x01, 0x0000001a },
+	{ 0x00030c,   1, 0x01, 0x00000001 },
+	{ 0x000318,   1, 0x01, 0x00000001 },
+	{ 0x000340,   1, 0x01, 0x00000000 },
+	{ 0x00037d,   1, 0x01, 0x00000006 },
+	{ 0x0003a0,   1, 0x01, 0x00000002 },
+	{ 0x0003aa,   1, 0x01, 0x00000001 },
+	{ 0x0003a9,   1, 0x01, 0x00000001 },
+	{ 0x000380,   1, 0x01, 0x00000001 },
+	{ 0x000383,   1, 0x01, 0x00000011 },
+	{ 0x000360,   1, 0x01, 0x00000040 },
+	{ 0x000366,   2, 0x01, 0x00000000 },
+	{ 0x000368,   1, 0x01, 0x00000fff },
+	{ 0x000370,   2, 0x01, 0x00000000 },
+	{ 0x000372,   1, 0x01, 0x000fffff },
+	{ 0x00037a,   1, 0x01, 0x00000012 },
+	{ 0x000619,   1, 0x01, 0x00000003 },
+	{ 0x000811,   1, 0x01, 0x00000003 },
+	{ 0x000812,   1, 0x01, 0x00000004 },
+	{ 0x000813,   1, 0x01, 0x00000006 },
+	{ 0x000814,   1, 0x01, 0x00000008 },
+	{ 0x000815,   1, 0x01, 0x0000000b },
+	{ 0x000800,   6, 0x01, 0x00000001 },
+	{ 0x000632,   1, 0x01, 0x00000001 },
+	{ 0x000633,   1, 0x01, 0x00000002 },
+	{ 0x000634,   1, 0x01, 0x00000003 },
+	{ 0x000635,   1, 0x01, 0x00000004 },
+	{ 0x000654,   1, 0x01, 0x3f800000 },
+	{ 0x000657,   1, 0x01, 0x3f800000 },
+	{ 0x000655,   2, 0x01, 0x3f800000 },
+	{ 0x0006cd,   1, 0x01, 0x3f800000 },
+	{ 0x0007f5,   1, 0x01, 0x3f800000 },
+	{ 0x0007dc,   1, 0x01, 0x39291909 },
+	{ 0x0007dd,   1, 0x01, 0x79695949 },
+	{ 0x0007de,   1, 0x01, 0xb9a99989 },
+	{ 0x0007df,   1, 0x01, 0xf9e9d9c9 },
+	{ 0x0007e8,   1, 0x01, 0x00003210 },
+	{ 0x0007e9,   1, 0x01, 0x00007654 },
+	{ 0x0007ea,   1, 0x01, 0x00000098 },
+	{ 0x0007ec,   1, 0x01, 0x39291909 },
+	{ 0x0007ed,   1, 0x01, 0x79695949 },
+	{ 0x0007ee,   1, 0x01, 0xb9a99989 },
+	{ 0x0007ef,   1, 0x01, 0xf9e9d9c9 },
+	{ 0x0007f0,   1, 0x01, 0x00003210 },
+	{ 0x0007f1,   1, 0x01, 0x00007654 },
+	{ 0x0007f2,   1, 0x01, 0x00000098 },
+	{ 0x0005a5,   1, 0x01, 0x00000001 },
+	{ 0x0005d0,   1, 0x01, 0x20181008 },
+	{ 0x0005d1,   1, 0x01, 0x40383028 },
+	{ 0x0005d2,   1, 0x01, 0x60585048 },
+	{ 0x0005d3,   1, 0x01, 0x80787068 },
+	{ 0x000980, 128, 0x01, 0x00000000 },
+	{ 0x000468,   1, 0x01, 0x00000004 },
+	{ 0x00046c,   1, 0x01, 0x00000001 },
+	{ 0x000470,  96, 0x01, 0x00000000 },
+	{ 0x000510,  16, 0x01, 0x3f800000 },
+	{ 0x000520,   1, 0x01, 0x000002b6 },
+	{ 0x000529,   1, 0x01, 0x00000001 },
+	{ 0x000530,  16, 0x01, 0xffff0000 },
+	{ 0x000550,  32, 0x01, 0xffff0000 },
+	{ 0x000585,   1, 0x01, 0x0000003f },
+	{ 0x000576,   1, 0x01, 0x00000003 },
+	{ 0x00057b,   1, 0x01, 0x00000059 },
+	{ 0x000586,   1, 0x01, 0x00000040 },
+	{ 0x000582,   2, 0x01, 0x00000080 },
+	{ 0x000595,   1, 0x01, 0x00400040 },
+	{ 0x000596,   1, 0x01, 0x00000492 },
+	{ 0x000597,   1, 0x01, 0x08080203 },
+	{ 0x0005ad,   1, 0x01, 0x00000008 },
+	{ 0x000598,   1, 0x01, 0x00020001 },
+	{ 0x0005c2,   1, 0x01, 0x00000001 },
+	{ 0x000638,   2, 0x01, 0x00000001 },
+	{ 0x00063a,   1, 0x01, 0x00000002 },
+	{ 0x00063b,   2, 0x01, 0x00000001 },
+	{ 0x00063d,   1, 0x01, 0x00000002 },
+	{ 0x00063e,   1, 0x01, 0x00000001 },
+	{ 0x0008b8,   8, 0x01, 0x00000001 },
+	{ 0x000900,   8, 0x01, 0x00000001 },
+	{ 0x000908,   8, 0x01, 0x00000002 },
+	{ 0x000910,  16, 0x01, 0x00000001 },
+	{ 0x000920,   8, 0x01, 0x00000002 },
+	{ 0x000928,   8, 0x01, 0x00000001 },
+	{ 0x000662,   1, 0x01, 0x00000001 },
+	{ 0x000648,   9, 0x01, 0x00000001 },
+	{ 0x000658,   1, 0x01, 0x0000000f },
+	{ 0x0007ff,   1, 0x01, 0x0000000a },
+	{ 0x00066a,   1, 0x01, 0x40000000 },
+	{ 0x00066b,   1, 0x01, 0x10000000 },
+	{ 0x00066c,   2, 0x01, 0xffff0000 },
+	{ 0x0007af,   2, 0x01, 0x00000008 },
+	{ 0x0007f6,   1, 0x01, 0x00000001 },
+	{ 0x0006b2,   1, 0x01, 0x00000055 },
+	{ 0x0007ad,   1, 0x01, 0x00000003 },
+	{ 0x000971,   1, 0x01, 0x00000008 },
+	{ 0x000972,   1, 0x01, 0x00000040 },
+	{ 0x000973,   1, 0x01, 0x0000012c },
+	{ 0x00097c,   1, 0x01, 0x00000040 },
+	{ 0x000975,   1, 0x01, 0x00000020 },
+	{ 0x000976,   1, 0x01, 0x00000001 },
+	{ 0x000977,   1, 0x01, 0x00000020 },
+	{ 0x000978,   1, 0x01, 0x00000001 },
+	{ 0x000957,   1, 0x01, 0x00000003 },
+	{ 0x00095e,   1, 0x01, 0x20164010 },
+	{ 0x00095f,   1, 0x01, 0x00000020 },
+	{ 0x000a0d,   1, 0x01, 0x00000006 },
+	{ 0x00097d,   1, 0x01, 0x0000000c },
+	{ 0x000683,   1, 0x01, 0x00000006 },
+	{ 0x000687,   1, 0x01, 0x003fffff },
+	{ 0x0006a0,   1, 0x01, 0x00000005 },
+	{ 0x000840,   1, 0x01, 0x00400008 },
+	{ 0x000841,   1, 0x01, 0x08000080 },
+	{ 0x000842,   1, 0x01, 0x00400008 },
+	{ 0x000843,   1, 0x01, 0x08000080 },
+	{ 0x000818,   8, 0x01, 0x00000000 },
+	{ 0x000848,  16, 0x01, 0x00000000 },
+	{ 0x000738,   1, 0x01, 0x00000000 },
+	{ 0x0006aa,   1, 0x01, 0x00000001 },
+	{ 0x0006ab,   1, 0x01, 0x00000002 },
+	{ 0x0006ac,   1, 0x01, 0x00000080 },
+	{ 0x0006ad,   2, 0x01, 0x00000100 },
+	{ 0x0006b1,   1, 0x01, 0x00000011 },
+	{ 0x0006bb,   1, 0x01, 0x000000cf },
+	{ 0x0006ce,   1, 0x01, 0x2a712488 },
+	{ 0x000739,   1, 0x01, 0x4085c000 },
+	{ 0x00073a,   1, 0x01, 0x00000080 },
+	{ 0x000786,   1, 0x01, 0x80000100 },
+	{ 0x00073c,   1, 0x01, 0x00010100 },
+	{ 0x00073d,   1, 0x01, 0x02800000 },
+	{ 0x000787,   1, 0x01, 0x000000cf },
+	{ 0x00078c,   1, 0x01, 0x00000008 },
+	{ 0x000792,   1, 0x01, 0x00000001 },
+	{ 0x000794,   3, 0x01, 0x00000001 },
+	{ 0x000797,   1, 0x01, 0x000000cf },
+	{ 0x000836,   1, 0x01, 0x00000001 },
+	{ 0x00079a,   1, 0x01, 0x00000002 },
+	{ 0x000833,   1, 0x01, 0x04444480 },
+	{ 0x0007a1,   1, 0x01, 0x00000001 },
+	{ 0x0007a3,   3, 0x01, 0x00000001 },
+	{ 0x000831,   1, 0x01, 0x00000004 },
+	{ 0x000b07,   1, 0x01, 0x00000002 },
+	{ 0x000b08,   2, 0x01, 0x00000100 },
+	{ 0x000b0a,   1, 0x01, 0x00000001 },
+	{ 0x000a04,   1, 0x01, 0x000000ff },
+	{ 0x000a0b,   1, 0x01, 0x00000040 },
+	{ 0x00097f,   1, 0x01, 0x00000100 },
+	{ 0x000a02,   1, 0x01, 0x00000001 },
+	{ 0x000809,   1, 0x01, 0x00000007 },
+	{ 0x00c221,   1, 0x01, 0x00000040 },
+	{ 0x00c1b0,   8, 0x01, 0x0000000f },
+	{ 0x00c1b8,   1, 0x01, 0x0fac6881 },
+	{ 0x00c1b9,   1, 0x01, 0x00fac688 },
+	{ 0x00c401,   1, 0x01, 0x00000001 },
+	{ 0x00c402,   1, 0x01, 0x00010001 },
+	{ 0x00c403,   2, 0x01, 0x00000001 },
+	{ 0x00c40e,   1, 0x01, 0x00000020 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000002 },
+	{ 0x0006aa,   1, 0x01, 0x00000001 },
+	{ 0x0006ad,   2, 0x01, 0x00000100 },
+	{ 0x0006b1,   1, 0x01, 0x00000011 },
+	{ 0x00078c,   1, 0x01, 0x00000008 },
+	{ 0x000792,   1, 0x01, 0x00000001 },
+	{ 0x000794,   3, 0x01, 0x00000001 },
+	{ 0x000797,   1, 0x01, 0x000000cf },
+	{ 0x00079a,   1, 0x01, 0x00000002 },
+	{ 0x0007a1,   1, 0x01, 0x00000001 },
+	{ 0x0007a3,   3, 0x01, 0x00000001 },
+	{ 0x000831,   1, 0x01, 0x00000004 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000008 },
+	{ 0x000039,   3, 0x01, 0x00000000 },
+	{ 0x000380,   1, 0x01, 0x00000001 },
+	{ 0x000366,   2, 0x01, 0x00000000 },
+	{ 0x000368,   1, 0x01, 0x00000fff },
+	{ 0x000370,   2, 0x01, 0x00000000 },
+	{ 0x000372,   1, 0x01, 0x000fffff },
+	{ 0x000813,   1, 0x01, 0x00000006 },
+	{ 0x000814,   1, 0x01, 0x00000008 },
+	{ 0x000818,   8, 0x01, 0x00000000 },
+	{ 0x000848,  16, 0x01, 0x00000000 },
+	{ 0x000738,   1, 0x01, 0x00000000 },
+	{ 0x000b07,   1, 0x01, 0x00000002 },
+	{ 0x000b08,   2, 0x01, 0x00000100 },
+	{ 0x000b0a,   1, 0x01, 0x00000001 },
+	{ 0x000a04,   1, 0x01, 0x000000ff },
+	{ 0x000a0b,   1, 0x01, 0x00000040 },
+	{ 0x00097f,   1, 0x01, 0x00000100 },
+	{ 0x000a02,   1, 0x01, 0x00000001 },
+	{ 0x000809,   1, 0x01, 0x00000007 },
+	{ 0x00c221,   1, 0x01, 0x00000040 },
+	{ 0x00c401,   1, 0x01, 0x00000001 },
+	{ 0x00c402,   1, 0x01, 0x00010001 },
+	{ 0x00c403,   2, 0x01, 0x00000001 },
+	{ 0x00c40e,   1, 0x01, 0x00000020 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000001 },
+	{ 0x000b07,   1, 0x01, 0x00000002 },
+	{ 0x000b08,   2, 0x01, 0x00000100 },
+	{ 0x000b0a,   1, 0x01, 0x00000001 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{}
+};
+
+static const struct nvc0_graph_pack
+gm107_grctx_pack_icmd[] = {
+	{ gm107_grctx_init_icmd_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_grctx_init_b097_0[] = {
+	{ 0x000800,   8, 0x40, 0x00000000 },
+	{ 0x000804,   8, 0x40, 0x00000000 },
+	{ 0x000808,   8, 0x40, 0x00000400 },
+	{ 0x00080c,   8, 0x40, 0x00000300 },
+	{ 0x000810,   1, 0x04, 0x000000cf },
+	{ 0x000850,   7, 0x40, 0x00000000 },
+	{ 0x000814,   8, 0x40, 0x00000040 },
+	{ 0x000818,   8, 0x40, 0x00000001 },
+	{ 0x00081c,   8, 0x40, 0x00000000 },
+	{ 0x000820,   8, 0x40, 0x00000000 },
+	{ 0x001c00,  16, 0x10, 0x00000000 },
+	{ 0x001c04,  16, 0x10, 0x00000000 },
+	{ 0x001c08,  16, 0x10, 0x00000000 },
+	{ 0x001c0c,  16, 0x10, 0x00000000 },
+	{ 0x001d00,  16, 0x10, 0x00000000 },
+	{ 0x001d04,  16, 0x10, 0x00000000 },
+	{ 0x001d08,  16, 0x10, 0x00000000 },
+	{ 0x001d0c,  16, 0x10, 0x00000000 },
+	{ 0x001f00,  16, 0x08, 0x00000000 },
+	{ 0x001f04,  16, 0x08, 0x00000000 },
+	{ 0x001f80,  16, 0x08, 0x00000000 },
+	{ 0x001f84,  16, 0x08, 0x00000000 },
+	{ 0x002000,   1, 0x04, 0x00000000 },
+	{ 0x002040,   1, 0x04, 0x00000011 },
+	{ 0x002080,   1, 0x04, 0x00000020 },
+	{ 0x0020c0,   1, 0x04, 0x00000030 },
+	{ 0x002100,   1, 0x04, 0x00000040 },
+	{ 0x002140,   1, 0x04, 0x00000051 },
+	{ 0x00200c,   6, 0x40, 0x00000001 },
+	{ 0x002010,   1, 0x04, 0x00000000 },
+	{ 0x002050,   1, 0x04, 0x00000000 },
+	{ 0x002090,   1, 0x04, 0x00000001 },
+	{ 0x0020d0,   1, 0x04, 0x00000002 },
+	{ 0x002110,   1, 0x04, 0x00000003 },
+	{ 0x002150,   1, 0x04, 0x00000004 },
+	{ 0x000380,   4, 0x20, 0x00000000 },
+	{ 0x000384,   4, 0x20, 0x00000000 },
+	{ 0x000388,   4, 0x20, 0x00000000 },
+	{ 0x00038c,   4, 0x20, 0x00000000 },
+	{ 0x000700,   4, 0x10, 0x00000000 },
+	{ 0x000704,   4, 0x10, 0x00000000 },
+	{ 0x000708,   4, 0x10, 0x00000000 },
+	{ 0x002800, 128, 0x04, 0x00000000 },
+	{ 0x000a00,  16, 0x20, 0x00000000 },
+	{ 0x000a04,  16, 0x20, 0x00000000 },
+	{ 0x000a08,  16, 0x20, 0x00000000 },
+	{ 0x000a0c,  16, 0x20, 0x00000000 },
+	{ 0x000a10,  16, 0x20, 0x00000000 },
+	{ 0x000a14,  16, 0x20, 0x00000000 },
+	{ 0x000c00,  16, 0x10, 0x00000000 },
+	{ 0x000c04,  16, 0x10, 0x00000000 },
+	{ 0x000c08,  16, 0x10, 0x00000000 },
+	{ 0x000c0c,  16, 0x10, 0x3f800000 },
+	{ 0x000d00,   8, 0x08, 0xffff0000 },
+	{ 0x000d04,   8, 0x08, 0xffff0000 },
+	{ 0x000e00,  16, 0x10, 0x00000000 },
+	{ 0x000e04,  16, 0x10, 0xffff0000 },
+	{ 0x000e08,  16, 0x10, 0xffff0000 },
+	{ 0x000d40,   4, 0x08, 0x00000000 },
+	{ 0x000d44,   4, 0x08, 0x00000000 },
+	{ 0x001e00,   8, 0x20, 0x00000001 },
+	{ 0x001e04,   8, 0x20, 0x00000001 },
+	{ 0x001e08,   8, 0x20, 0x00000002 },
+	{ 0x001e0c,   8, 0x20, 0x00000001 },
+	{ 0x001e10,   8, 0x20, 0x00000001 },
+	{ 0x001e14,   8, 0x20, 0x00000002 },
+	{ 0x001e18,   8, 0x20, 0x00000001 },
+	{ 0x001480,   8, 0x10, 0x00000000 },
+	{ 0x001484,   8, 0x10, 0x00000000 },
+	{ 0x001488,   8, 0x10, 0x00000000 },
+	{ 0x003400, 128, 0x04, 0x00000000 },
+	{ 0x00030c,   1, 0x04, 0x00000001 },
+	{ 0x001944,   1, 0x04, 0x00000000 },
+	{ 0x001514,   1, 0x04, 0x00000000 },
+	{ 0x000d68,   1, 0x04, 0x0000ffff },
+	{ 0x00121c,   1, 0x04, 0x0fac6881 },
+	{ 0x000fac,   1, 0x04, 0x00000001 },
+	{ 0x001538,   1, 0x04, 0x00000001 },
+	{ 0x000fe0,   2, 0x04, 0x00000000 },
+	{ 0x000fe8,   1, 0x04, 0x00000014 },
+	{ 0x000fec,   1, 0x04, 0x00000040 },
+	{ 0x000ff0,   1, 0x04, 0x00000000 },
+	{ 0x00179c,   1, 0x04, 0x00000000 },
+	{ 0x001228,   1, 0x04, 0x00000400 },
+	{ 0x00122c,   1, 0x04, 0x00000300 },
+	{ 0x001230,   1, 0x04, 0x00010001 },
+	{ 0x0007f8,   1, 0x04, 0x00000000 },
+	{ 0x0015b4,   1, 0x04, 0x00000001 },
+	{ 0x0015cc,   1, 0x04, 0x00000000 },
+	{ 0x001534,   1, 0x04, 0x00000000 },
+	{ 0x000754,   1, 0x04, 0x00000001 },
+	{ 0x000fb0,   1, 0x04, 0x00000000 },
+	{ 0x0015d0,   1, 0x04, 0x00000000 },
+	{ 0x00153c,   1, 0x04, 0x00000000 },
+	{ 0x0016b4,   1, 0x04, 0x00000003 },
+	{ 0x000fbc,   4, 0x04, 0x0000ffff },
+	{ 0x000df8,   2, 0x04, 0x00000000 },
+	{ 0x001948,   1, 0x04, 0x00000000 },
+	{ 0x001970,   1, 0x04, 0x00000001 },
+	{ 0x00161c,   1, 0x04, 0x000009f0 },
+	{ 0x000dcc,   1, 0x04, 0x00000010 },
+	{ 0x0015e4,   1, 0x04, 0x00000000 },
+	{ 0x001160,  32, 0x04, 0x25e00040 },
+	{ 0x001880,  32, 0x04, 0x00000000 },
+	{ 0x000f84,   2, 0x04, 0x00000000 },
+	{ 0x0017c8,   2, 0x04, 0x00000000 },
+	{ 0x0017d0,   1, 0x04, 0x000000ff },
+	{ 0x0017d4,   1, 0x04, 0xffffffff },
+	{ 0x0017d8,   1, 0x04, 0x00000002 },
+	{ 0x0017dc,   1, 0x04, 0x00000000 },
+	{ 0x0015f4,   2, 0x04, 0x00000000 },
+	{ 0x001434,   2, 0x04, 0x00000000 },
+	{ 0x000d74,   1, 0x04, 0x00000000 },
+	{ 0x0013a4,   1, 0x04, 0x00000000 },
+	{ 0x001318,   1, 0x04, 0x00000001 },
+	{ 0x001080,   2, 0x04, 0x00000000 },
+	{ 0x001088,   2, 0x04, 0x00000001 },
+	{ 0x001090,   1, 0x04, 0x00000000 },
+	{ 0x001094,   1, 0x04, 0x00000001 },
+	{ 0x001098,   1, 0x04, 0x00000000 },
+	{ 0x00109c,   1, 0x04, 0x00000001 },
+	{ 0x0010a0,   2, 0x04, 0x00000000 },
+	{ 0x001644,   1, 0x04, 0x00000000 },
+	{ 0x000748,   1, 0x04, 0x00000000 },
+	{ 0x000de8,   1, 0x04, 0x00000000 },
+	{ 0x001648,   1, 0x04, 0x00000000 },
+	{ 0x0012a4,   1, 0x04, 0x00000000 },
+	{ 0x001120,   4, 0x04, 0x00000000 },
+	{ 0x001118,   1, 0x04, 0x00000000 },
+	{ 0x00164c,   1, 0x04, 0x00000000 },
+	{ 0x001658,   1, 0x04, 0x00000000 },
+	{ 0x001910,   1, 0x04, 0x00000290 },
+	{ 0x001518,   1, 0x04, 0x00000000 },
+	{ 0x00165c,   1, 0x04, 0x00000001 },
+	{ 0x001520,   1, 0x04, 0x00000000 },
+	{ 0x001604,   1, 0x04, 0x00000000 },
+	{ 0x001570,   1, 0x04, 0x00000000 },
+	{ 0x0013b0,   2, 0x04, 0x3f800000 },
+	{ 0x00020c,   1, 0x04, 0x00000000 },
+	{ 0x001670,   1, 0x04, 0x30201000 },
+	{ 0x001674,   1, 0x04, 0x70605040 },
+	{ 0x001678,   1, 0x04, 0xb8a89888 },
+	{ 0x00167c,   1, 0x04, 0xf8e8d8c8 },
+	{ 0x00166c,   1, 0x04, 0x00000000 },
+	{ 0x001680,   1, 0x04, 0x00ffff00 },
+	{ 0x0012d0,   1, 0x04, 0x00000003 },
+	{ 0x0012d4,   1, 0x04, 0x00000002 },
+	{ 0x001684,   2, 0x04, 0x00000000 },
+	{ 0x000dac,   2, 0x04, 0x00001b02 },
+	{ 0x000db4,   1, 0x04, 0x00000000 },
+	{ 0x00168c,   1, 0x04, 0x00000000 },
+	{ 0x0015bc,   1, 0x04, 0x00000000 },
+	{ 0x00156c,   1, 0x04, 0x00000000 },
+	{ 0x00187c,   1, 0x04, 0x00000000 },
+	{ 0x001110,   1, 0x04, 0x00000001 },
+	{ 0x000dc0,   3, 0x04, 0x00000000 },
+	{ 0x000f40,   5, 0x04, 0x00000000 },
+	{ 0x001234,   1, 0x04, 0x00000000 },
+	{ 0x001690,   1, 0x04, 0x00000000 },
+	{ 0x000790,   5, 0x04, 0x00000000 },
+	{ 0x00077c,   1, 0x04, 0x00000000 },
+	{ 0x001000,   1, 0x04, 0x00000010 },
+	{ 0x0010fc,   1, 0x04, 0x00000000 },
+	{ 0x001290,   1, 0x04, 0x00000000 },
+	{ 0x000218,   1, 0x04, 0x00000010 },
+	{ 0x0012d8,   1, 0x04, 0x00000000 },
+	{ 0x0012dc,   1, 0x04, 0x00000010 },
+	{ 0x000d94,   1, 0x04, 0x00000001 },
+	{ 0x00155c,   2, 0x04, 0x00000000 },
+	{ 0x001564,   1, 0x04, 0x00000fff },
+	{ 0x001574,   2, 0x04, 0x00000000 },
+	{ 0x00157c,   1, 0x04, 0x000fffff },
+	{ 0x001354,   1, 0x04, 0x00000000 },
+	{ 0x001610,   1, 0x04, 0x00000012 },
+	{ 0x001608,   2, 0x04, 0x00000000 },
+	{ 0x00260c,   1, 0x04, 0x00000000 },
+	{ 0x0007ac,   1, 0x04, 0x00000000 },
+	{ 0x00162c,   1, 0x04, 0x00000003 },
+	{ 0x000210,   1, 0x04, 0x00000000 },
+	{ 0x000320,   1, 0x04, 0x00000000 },
+	{ 0x000324,   6, 0x04, 0x3f800000 },
+	{ 0x000750,   1, 0x04, 0x00000000 },
+	{ 0x000760,   1, 0x04, 0x39291909 },
+	{ 0x000764,   1, 0x04, 0x79695949 },
+	{ 0x000768,   1, 0x04, 0xb9a99989 },
+	{ 0x00076c,   1, 0x04, 0xf9e9d9c9 },
+	{ 0x000770,   1, 0x04, 0x30201000 },
+	{ 0x000774,   1, 0x04, 0x70605040 },
+	{ 0x000778,   1, 0x04, 0x00009080 },
+	{ 0x000780,   1, 0x04, 0x39291909 },
+	{ 0x000784,   1, 0x04, 0x79695949 },
+	{ 0x000788,   1, 0x04, 0xb9a99989 },
+	{ 0x00078c,   1, 0x04, 0xf9e9d9c9 },
+	{ 0x0007d0,   1, 0x04, 0x30201000 },
+	{ 0x0007d4,   1, 0x04, 0x70605040 },
+	{ 0x0007d8,   1, 0x04, 0x00009080 },
+	{ 0x00037c,   1, 0x04, 0x00000001 },
+	{ 0x000740,   2, 0x04, 0x00000000 },
+	{ 0x002600,   1, 0x04, 0x00000000 },
+	{ 0x001918,   1, 0x04, 0x00000000 },
+	{ 0x00191c,   1, 0x04, 0x00000900 },
+	{ 0x001920,   1, 0x04, 0x00000405 },
+	{ 0x001308,   1, 0x04, 0x00000001 },
+	{ 0x001924,   1, 0x04, 0x00000000 },
+	{ 0x0013ac,   1, 0x04, 0x00000000 },
+	{ 0x00192c,   1, 0x04, 0x00000001 },
+	{ 0x00193c,   1, 0x04, 0x00002c1c },
+	{ 0x000d7c,   1, 0x04, 0x00000000 },
+	{ 0x000f8c,   1, 0x04, 0x00000000 },
+	{ 0x0002c0,   1, 0x04, 0x00000001 },
+	{ 0x001510,   1, 0x04, 0x00000000 },
+	{ 0x001940,   1, 0x04, 0x00000000 },
+	{ 0x000ff4,   2, 0x04, 0x00000000 },
+	{ 0x00194c,   2, 0x04, 0x00000000 },
+	{ 0x001968,   1, 0x04, 0x00000000 },
+	{ 0x001590,   1, 0x04, 0x0000003f },
+	{ 0x0007e8,   4, 0x04, 0x00000000 },
+	{ 0x00196c,   1, 0x04, 0x00000011 },
+	{ 0x0002e4,   1, 0x04, 0x0000b001 },
+	{ 0x00036c,   2, 0x04, 0x00000000 },
+	{ 0x00197c,   1, 0x04, 0x00000000 },
+	{ 0x000fcc,   2, 0x04, 0x00000000 },
+	{ 0x0002d8,   1, 0x04, 0x00000040 },
+	{ 0x001980,   1, 0x04, 0x00000080 },
+	{ 0x001504,   1, 0x04, 0x00000080 },
+	{ 0x001984,   1, 0x04, 0x00000000 },
+	{ 0x000f60,   1, 0x04, 0x00000000 },
+	{ 0x000f64,   1, 0x04, 0x00400040 },
+	{ 0x000f68,   1, 0x04, 0x00002212 },
+	{ 0x000f6c,   1, 0x04, 0x08080203 },
+	{ 0x001108,   1, 0x04, 0x00000008 },
+	{ 0x000f70,   1, 0x04, 0x00080001 },
+	{ 0x000ffc,   1, 0x04, 0x00000000 },
+	{ 0x000300,   1, 0x04, 0x00000001 },
+	{ 0x0013a8,   1, 0x04, 0x00000000 },
+	{ 0x0012ec,   1, 0x04, 0x00000000 },
+	{ 0x001310,   1, 0x04, 0x00000000 },
+	{ 0x001314,   1, 0x04, 0x00000001 },
+	{ 0x001380,   1, 0x04, 0x00000000 },
+	{ 0x001384,   4, 0x04, 0x00000001 },
+	{ 0x001394,   1, 0x04, 0x00000000 },
+	{ 0x00139c,   1, 0x04, 0x00000000 },
+	{ 0x001398,   1, 0x04, 0x00000000 },
+	{ 0x001594,   1, 0x04, 0x00000000 },
+	{ 0x001598,   4, 0x04, 0x00000001 },
+	{ 0x000f54,   3, 0x04, 0x00000000 },
+	{ 0x0019bc,   1, 0x04, 0x00000000 },
+	{ 0x000f9c,   2, 0x04, 0x00000000 },
+	{ 0x0012cc,   1, 0x04, 0x00000000 },
+	{ 0x0012e8,   1, 0x04, 0x00000000 },
+	{ 0x00130c,   1, 0x04, 0x00000001 },
+	{ 0x001360,   8, 0x04, 0x00000000 },
+	{ 0x00133c,   2, 0x04, 0x00000001 },
+	{ 0x001344,   1, 0x04, 0x00000002 },
+	{ 0x001348,   2, 0x04, 0x00000001 },
+	{ 0x001350,   1, 0x04, 0x00000002 },
+	{ 0x001358,   1, 0x04, 0x00000001 },
+	{ 0x0012e4,   1, 0x04, 0x00000000 },
+	{ 0x00131c,   4, 0x04, 0x00000000 },
+	{ 0x0019c0,   1, 0x04, 0x00000000 },
+	{ 0x001140,   1, 0x04, 0x00000000 },
+	{ 0x000dd0,   1, 0x04, 0x00000000 },
+	{ 0x000dd4,   1, 0x04, 0x00000001 },
+	{ 0x0002f4,   1, 0x04, 0x00000000 },
+	{ 0x0019c4,   1, 0x04, 0x00000000 },
+	{ 0x0019c8,   1, 0x04, 0x00001500 },
+	{ 0x00135c,   1, 0x04, 0x00000000 },
+	{ 0x000f90,   1, 0x04, 0x00000000 },
+	{ 0x0019e0,   8, 0x04, 0x00000001 },
+	{ 0x0019cc,   1, 0x04, 0x00000001 },
+	{ 0x0015b8,   1, 0x04, 0x00000000 },
+	{ 0x001a00,   1, 0x04, 0x00001111 },
+	{ 0x001a04,   7, 0x04, 0x00000000 },
+	{ 0x000d6c,   2, 0x04, 0xffff0000 },
+	{ 0x0010f8,   1, 0x04, 0x00001010 },
+	{ 0x000d80,   5, 0x04, 0x00000000 },
+	{ 0x000da0,   1, 0x04, 0x00000000 },
+	{ 0x0007a4,   2, 0x04, 0x00000000 },
+	{ 0x001508,   1, 0x04, 0x80000000 },
+	{ 0x00150c,   1, 0x04, 0x40000000 },
+	{ 0x001668,   1, 0x04, 0x00000000 },
+	{ 0x000318,   2, 0x04, 0x00000008 },
+	{ 0x000d9c,   1, 0x04, 0x00000001 },
+	{ 0x000f14,   1, 0x04, 0x00000000 },
+	{ 0x000374,   1, 0x04, 0x00000000 },
+	{ 0x000378,   1, 0x04, 0x0000000c },
+	{ 0x0007dc,   1, 0x04, 0x00000000 },
+	{ 0x00074c,   1, 0x04, 0x00000055 },
+	{ 0x001420,   1, 0x04, 0x00000003 },
+	{ 0x001008,   1, 0x04, 0x00000008 },
+	{ 0x00100c,   1, 0x04, 0x00000040 },
+	{ 0x001010,   1, 0x04, 0x0000012c },
+	{ 0x000d60,   1, 0x04, 0x00000040 },
+	{ 0x001018,   1, 0x04, 0x00000020 },
+	{ 0x00101c,   1, 0x04, 0x00000001 },
+	{ 0x001020,   1, 0x04, 0x00000020 },
+	{ 0x001024,   1, 0x04, 0x00000001 },
+	{ 0x001444,   3, 0x04, 0x00000000 },
+	{ 0x000360,   1, 0x04, 0x20164010 },
+	{ 0x000364,   1, 0x04, 0x00000020 },
+	{ 0x000368,   1, 0x04, 0x00000000 },
+	{ 0x000da8,   1, 0x04, 0x00000030 },
+	{ 0x000de4,   1, 0x04, 0x00000000 },
+	{ 0x000204,   1, 0x04, 0x00000006 },
+	{ 0x0002d0,   1, 0x04, 0x003fffff },
+	{ 0x001220,   1, 0x04, 0x00000005 },
+	{ 0x000fdc,   1, 0x04, 0x00000000 },
+	{ 0x000f98,   1, 0x04, 0x00400008 },
+	{ 0x001284,   1, 0x04, 0x08000080 },
+	{ 0x001450,   1, 0x04, 0x00400008 },
+	{ 0x001454,   1, 0x04, 0x08000080 },
+	{ 0x000214,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_pack
+gm107_grctx_pack_mthd[] = {
+	{ gm107_grctx_init_b097_0, 0xb097 },
+	{ nvc0_grctx_init_902d_0, 0x902d },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_grctx_init_fe_0[] = {
+	{ 0x404004,   8, 0x04, 0x00000000 },
+	{ 0x404024,   1, 0x04, 0x0000e000 },
+	{ 0x404028,   8, 0x04, 0x00000000 },
+	{ 0x4040a8,   8, 0x04, 0x00000000 },
+	{ 0x4040c8,   1, 0x04, 0xf800008f },
+	{ 0x4040d0,   6, 0x04, 0x00000000 },
+	{ 0x4040f8,   1, 0x04, 0x00000000 },
+	{ 0x404100,  10, 0x04, 0x00000000 },
+	{ 0x404130,   2, 0x04, 0x00000000 },
+	{ 0x404150,   1, 0x04, 0x0000002e },
+	{ 0x404154,   1, 0x04, 0x00000400 },
+	{ 0x404158,   1, 0x04, 0x00000200 },
+	{ 0x404164,   1, 0x04, 0x00000045 },
+	{ 0x40417c,   2, 0x04, 0x00000000 },
+	{ 0x404194,   1, 0x04, 0x01000700 },
+	{ 0x4041a0,   4, 0x04, 0x00000000 },
+	{ 0x404200,   4, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_grctx_init_ds_0[] = {
+	{ 0x405800,   1, 0x04, 0x0f8001bf },
+	{ 0x405830,   1, 0x04, 0x0aa01000 },
+	{ 0x405834,   1, 0x04, 0x08000000 },
+	{ 0x405838,   1, 0x04, 0x00000000 },
+	{ 0x405854,   1, 0x04, 0x00000000 },
+	{ 0x405870,   4, 0x04, 0x00000001 },
+	{ 0x405a00,   2, 0x04, 0x00000000 },
+	{ 0x405a18,   1, 0x04, 0x00000000 },
+	{ 0x405a1c,   1, 0x04, 0x000000ff },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_grctx_init_pd_0[] = {
+	{ 0x406020,   1, 0x04, 0x07410001 },
+	{ 0x406028,   4, 0x04, 0x00000001 },
+	{ 0x4064a8,   1, 0x04, 0x00000000 },
+	{ 0x4064ac,   1, 0x04, 0x00003fff },
+	{ 0x4064b0,   3, 0x04, 0x00000000 },
+	{ 0x4064c0,   1, 0x04, 0x80400280 },
+	{ 0x4064c4,   1, 0x04, 0x0400ffff },
+	{ 0x4064c8,   1, 0x04, 0x018001ff },
+	{ 0x4064cc,   9, 0x04, 0x00000000 },
+	{ 0x4064fc,   1, 0x04, 0x0000022a },
+	{ 0x406500,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_grctx_init_be_0[] = {
+	{ 0x408800,   1, 0x04, 0x32802a3c },
+	{ 0x408804,   1, 0x04, 0x00000040 },
+	{ 0x408808,   1, 0x04, 0x1003e005 },
+	{ 0x408840,   1, 0x04, 0x0000000b },
+	{ 0x408900,   1, 0x04, 0xb080b801 },
+	{ 0x408904,   1, 0x04, 0x63038001 },
+	{ 0x408908,   1, 0x04, 0x02c8102f },
+	{ 0x408980,   1, 0x04, 0x0000011d },
+	{}
+};
+
+static const struct nvc0_graph_pack
+gm107_grctx_pack_hub[] = {
+	{ nvc0_grctx_init_main_0 },
+	{ gm107_grctx_init_fe_0 },
+	{ nvf0_grctx_init_pri_0 },
+	{ nve4_grctx_init_memfmt_0 },
+	{ gm107_grctx_init_ds_0 },
+	{ nvf0_grctx_init_cwd_0 },
+	{ gm107_grctx_init_pd_0 },
+	{ nv108_grctx_init_rstr2d_0 },
+	{ nve4_grctx_init_scc_0 },
+	{ gm107_grctx_init_be_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_grctx_init_gpc_unk_0[] = {
+	{ 0x418380,   1, 0x04, 0x00000056 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_grctx_init_gpc_unk_1[] = {
+	{ 0x418600,   1, 0x04, 0x0000007f },
+	{ 0x418684,   1, 0x04, 0x0000001f },
+	{ 0x418700,   1, 0x04, 0x00000002 },
+	{ 0x418704,   1, 0x04, 0x00000080 },
+	{ 0x418708,   1, 0x04, 0x40000000 },
+	{ 0x41870c,   2, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_grctx_init_setup_0[] = {
+	{ 0x418800,   1, 0x04, 0x7006863a },
+	{ 0x418810,   1, 0x04, 0x00000000 },
+	{ 0x418828,   1, 0x04, 0x00000044 },
+	{ 0x418830,   1, 0x04, 0x10000001 },
+	{ 0x4188d8,   1, 0x04, 0x00000008 },
+	{ 0x4188e0,   1, 0x04, 0x01000000 },
+	{ 0x4188e8,   5, 0x04, 0x00000000 },
+	{ 0x4188fc,   1, 0x04, 0x20100058 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_grctx_init_gpc_unk_2[] = {
+	{ 0x418d24,   1, 0x04, 0x00000000 },
+	{ 0x418e00,   1, 0x04, 0x90000000 },
+	{ 0x418e24,   1, 0x04, 0x00000000 },
+	{ 0x418e28,   1, 0x04, 0x00000030 },
+	{ 0x418e30,   1, 0x04, 0x00000000 },
+	{ 0x418e34,   1, 0x04, 0x00010000 },
+	{ 0x418e38,   1, 0x04, 0x00000000 },
+	{ 0x418e40,  22, 0x04, 0x00000000 },
+	{ 0x418ea0,   2, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_pack
+gm107_grctx_pack_gpc[] = {
+	{ gm107_grctx_init_gpc_unk_0 },
+	{ nv108_grctx_init_prop_0 },
+	{ gm107_grctx_init_gpc_unk_1 },
+	{ gm107_grctx_init_setup_0 },
+	{ nvc0_grctx_init_zcull_0 },
+	{ nv108_grctx_init_crstr_0 },
+	{ nve4_grctx_init_gpm_0 },
+	{ gm107_grctx_init_gpc_unk_2 },
+	{ nvc0_grctx_init_gcc_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_grctx_init_tex_0[] = {
+	{ 0x419a00,   1, 0x04, 0x000300f0 },
+	{ 0x419a04,   1, 0x04, 0x00000005 },
+	{ 0x419a08,   1, 0x04, 0x00000421 },
+	{ 0x419a0c,   1, 0x04, 0x00120000 },
+	{ 0x419a10,   1, 0x04, 0x00000000 },
+	{ 0x419a14,   1, 0x04, 0x00002200 },
+	{ 0x419a1c,   1, 0x04, 0x0000c000 },
+	{ 0x419a20,   1, 0x04, 0x20008a00 },
+	{ 0x419a30,   1, 0x04, 0x00000001 },
+	{ 0x419a3c,   1, 0x04, 0x00000002 },
+	{ 0x419ac4,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_grctx_init_mpc_0[] = {
+	{ 0x419c00,   1, 0x04, 0x0000001a },
+	{ 0x419c04,   1, 0x04, 0x80000006 },
+	{ 0x419c08,   1, 0x04, 0x00000002 },
+	{ 0x419c20,   1, 0x04, 0x00000000 },
+	{ 0x419c24,   1, 0x04, 0x00084210 },
+	{ 0x419c28,   1, 0x04, 0x3efbefbe },
+	{ 0x419c2c,   1, 0x04, 0x00000000 },
+	{ 0x419c34,   1, 0x04, 0x01ff1ff3 },
+	{ 0x419c3c,   1, 0x04, 0x00001919 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_grctx_init_l1c_0[] = {
+	{ 0x419c84,   1, 0x04, 0x00000020 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_grctx_init_sm_0[] = {
+	{ 0x419e04,   3, 0x04, 0x00000000 },
+	{ 0x419e10,   1, 0x04, 0x00001c02 },
+	{ 0x419e44,   1, 0x04, 0x00d3eff2 },
+	{ 0x419e48,   1, 0x04, 0x00000000 },
+	{ 0x419e4c,   1, 0x04, 0x0000007f },
+	{ 0x419e50,   1, 0x04, 0x00000000 },
+	{ 0x419e60,   4, 0x04, 0x00000000 },
+	{ 0x419e74,  10, 0x04, 0x00000000 },
+	{ 0x419eac,   1, 0x04, 0x0001cf8b },
+	{ 0x419eb0,   1, 0x04, 0x00030300 },
+	{ 0x419eb8,   1, 0x04, 0x00000000 },
+	{ 0x419ef0,  24, 0x04, 0x00000000 },
+	{ 0x419f68,   2, 0x04, 0x00000000 },
+	{ 0x419f70,   1, 0x04, 0x00000020 },
+	{ 0x419f78,   1, 0x04, 0x000003eb },
+	{ 0x419f7c,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_pack
+gm107_grctx_pack_tpc[] = {
+	{ nvd7_grctx_init_pe_0 },
+	{ gm107_grctx_init_tex_0 },
+	{ gm107_grctx_init_mpc_0 },
+	{ gm107_grctx_init_l1c_0 },
+	{ gm107_grctx_init_sm_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_grctx_init_cbm_0[] = {
+	{ 0x41bec0,   1, 0x04, 0x00000000 },
+	{ 0x41bec4,   1, 0x04, 0x01050000 },
+	{ 0x41bee4,   1, 0x04, 0x00000000 },
+	{ 0x41bef0,   1, 0x04, 0x000003ff },
+	{ 0x41bef4,   2, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_grctx_init_wwdx_0[] = {
+	{ 0x41bf00,   1, 0x04, 0x0a418820 },
+	{ 0x41bf04,   1, 0x04, 0x062080e6 },
+	{ 0x41bf08,   1, 0x04, 0x020398a4 },
+	{ 0x41bf0c,   1, 0x04, 0x0e629062 },
+	{ 0x41bf10,   1, 0x04, 0x0a418820 },
+	{ 0x41bf14,   1, 0x04, 0x000000e6 },
+	{ 0x41bfd0,   1, 0x04, 0x00900103 },
+	{ 0x41bfe0,   1, 0x04, 0x80000000 },
+	{ 0x41bfe4,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_pack
+gm107_grctx_pack_ppc[] = {
+	{ nve4_grctx_init_pes_0 },
+	{ gm107_grctx_init_cbm_0 },
+	{ gm107_grctx_init_wwdx_0 },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH context implementation
+ ******************************************************************************/
+
+static void
+gm107_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
+{
+	mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
+	mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS);
+	mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW);
+
+	mmio_list(0x40800c, 0x00000000,  8, 1);
+	mmio_list(0x408010, 0x80000000,  0, 0);
+	mmio_list(0x419004, 0x00000000,  8, 1);
+	mmio_list(0x419008, 0x00000000,  0, 0);
+	mmio_list(0x4064cc, 0x80000000,  0, 0);
+	mmio_list(0x418e30, 0x80000000,  0, 0);
+
+	mmio_list(0x408004, 0x00000000,  8, 0);
+	mmio_list(0x408008, 0x80000030,  0, 0);
+	mmio_list(0x418e24, 0x00000000,  8, 0);
+	mmio_list(0x418e28, 0x80000030,  0, 0);
+
+	mmio_list(0x418810, 0x80000000, 12, 2);
+	mmio_list(0x419848, 0x10000000, 12, 2);
+	mmio_list(0x419c2c, 0x10000000, 12, 2);
+
+	mmio_list(0x405830, 0x0aa01000,  0, 0);
+	mmio_list(0x4064c4, 0x0400ffff,  0, 0);
+
+	/*XXX*/
+	mmio_list(0x5030c0, 0x00001540,  0, 0);
+	mmio_list(0x5030f4, 0x00000000,  0, 0);
+	mmio_list(0x5030e4, 0x00002000,  0, 0);
+	mmio_list(0x5030f8, 0x00003fc0,  0, 0);
+	mmio_list(0x418ea0, 0x07151540,  0, 0);
+
+	mmio_list(0x5032c0, 0x00001540,  0, 0);
+	mmio_list(0x5032f4, 0x00001fe0,  0, 0);
+	mmio_list(0x5032e4, 0x00002000,  0, 0);
+	mmio_list(0x5032f8, 0x00006fc0,  0, 0);
+	mmio_list(0x418ea4, 0x07151540,  0, 0);
+}
+
+static void
+gm107_grctx_generate_tpcid(struct nvc0_graph_priv *priv)
+{
+	int gpc, tpc, id;
+
+	for (tpc = 0, id = 0; tpc < 4; tpc++) {
+		for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+			if (tpc < priv->tpc_nr[gpc]) {
+				nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x698), id);
+				nv_wr32(priv, GPC_UNIT(gpc, 0x0c10 + tpc * 4), id);
+				nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x088), id);
+				id++;
+			}
+
+			nv_wr32(priv, GPC_UNIT(gpc, 0x0c08), priv->tpc_nr[gpc]);
+			nv_wr32(priv, GPC_UNIT(gpc, 0x0c8c), priv->tpc_nr[gpc]);
+		}
+	}
+}
+
+static void
+gm107_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
+{
+	struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
+	int i;
+
+	nvc0_graph_mmio(priv, oclass->hub);
+	nvc0_graph_mmio(priv, oclass->gpc);
+	nvc0_graph_mmio(priv, oclass->zcull);
+	nvc0_graph_mmio(priv, oclass->tpc);
+	nvc0_graph_mmio(priv, oclass->ppc);
+
+	nv_wr32(priv, 0x404154, 0x00000000);
+
+	oclass->mods(priv, info);
+	oclass->unkn(priv);
+
+	gm107_grctx_generate_tpcid(priv);
+	nvc0_grctx_generate_r406028(priv);
+	nve4_grctx_generate_r418bb8(priv);
+	nvc0_grctx_generate_r406800(priv);
+
+	nv_wr32(priv, 0x4064d0, 0x00000001);
+	for (i = 1; i < 8; i++)
+		nv_wr32(priv, 0x4064d0 + (i * 0x04), 0x00000000);
+	nv_wr32(priv, 0x406500, 0x00000001);
+
+	nv_wr32(priv, 0x405b00, (priv->tpc_total << 8) | priv->gpc_nr);
+
+	if (priv->gpc_nr == 1) {
+		nv_mask(priv, 0x408850, 0x0000000f, priv->tpc_nr[0]);
+		nv_mask(priv, 0x408958, 0x0000000f, priv->tpc_nr[0]);
+	} else {
+		nv_mask(priv, 0x408850, 0x0000000f, priv->gpc_nr);
+		nv_mask(priv, 0x408958, 0x0000000f, priv->gpc_nr);
+	}
+
+	nvc0_graph_icmd(priv, oclass->icmd);
+	nv_wr32(priv, 0x404154, 0x00000400);
+	nvc0_graph_mthd(priv, oclass->mthd);
+
+	nv_mask(priv, 0x419e00, 0x00808080, 0x00808080);
+	nv_mask(priv, 0x419ccc, 0x80000000, 0x80000000);
+	nv_mask(priv, 0x419f80, 0x80000000, 0x80000000);
+	nv_mask(priv, 0x419f88, 0x80000000, 0x80000000);
+}
+
+struct nouveau_oclass *
+gm107_grctx_oclass = &(struct nvc0_grctx_oclass) {
+	.base.handle = NV_ENGCTX(GR, 0x08),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_context_ctor,
+		.dtor = nvc0_graph_context_dtor,
+		.init = _nouveau_graph_context_init,
+		.fini = _nouveau_graph_context_fini,
+		.rd32 = _nouveau_graph_context_rd32,
+		.wr32 = _nouveau_graph_context_wr32,
+	},
+	.main  = gm107_grctx_generate_main,
+	.mods  = gm107_grctx_generate_mods,
+	.unkn  = nve4_grctx_generate_unkn,
+	.hub   = gm107_grctx_pack_hub,
+	.gpc   = gm107_grctx_pack_gpc,
+	.zcull = nvc0_grctx_pack_zcull,
+	.tpc   = gm107_grctx_pack_tpc,
+	.ppc   = gm107_grctx_pack_ppc,
+	.icmd  = gm107_grctx_pack_icmd,
+	.mthd  = gm107_grctx_pack_mthd,
+}.base;

+ 115 - 926
drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c

@@ -22,10 +22,14 @@
  * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
 
-#include "nvc0.h"
+#include "ctxnvc0.h"
 
-static struct nvc0_graph_init
-nv108_grctx_init_icmd[] = {
+/*******************************************************************************
+ * PGRAPH context register lists
+ ******************************************************************************/
+
+static const struct nvc0_graph_init
+nv108_grctx_init_icmd_0[] = {
 	{ 0x001000,   1, 0x01, 0x00000004 },
 	{ 0x000039,   3, 0x01, 0x00000000 },
 	{ 0x0000a9,   1, 0x01, 0x0000ffff },
@@ -274,839 +278,14 @@ nv108_grctx_init_icmd[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nv108_grctx_init_a197[] = {
-	{ 0x000800,   1, 0x04, 0x00000000 },
-	{ 0x000840,   1, 0x04, 0x00000000 },
-	{ 0x000880,   1, 0x04, 0x00000000 },
-	{ 0x0008c0,   1, 0x04, 0x00000000 },
-	{ 0x000900,   1, 0x04, 0x00000000 },
-	{ 0x000940,   1, 0x04, 0x00000000 },
-	{ 0x000980,   1, 0x04, 0x00000000 },
-	{ 0x0009c0,   1, 0x04, 0x00000000 },
-	{ 0x000804,   1, 0x04, 0x00000000 },
-	{ 0x000844,   1, 0x04, 0x00000000 },
-	{ 0x000884,   1, 0x04, 0x00000000 },
-	{ 0x0008c4,   1, 0x04, 0x00000000 },
-	{ 0x000904,   1, 0x04, 0x00000000 },
-	{ 0x000944,   1, 0x04, 0x00000000 },
-	{ 0x000984,   1, 0x04, 0x00000000 },
-	{ 0x0009c4,   1, 0x04, 0x00000000 },
-	{ 0x000808,   1, 0x04, 0x00000400 },
-	{ 0x000848,   1, 0x04, 0x00000400 },
-	{ 0x000888,   1, 0x04, 0x00000400 },
-	{ 0x0008c8,   1, 0x04, 0x00000400 },
-	{ 0x000908,   1, 0x04, 0x00000400 },
-	{ 0x000948,   1, 0x04, 0x00000400 },
-	{ 0x000988,   1, 0x04, 0x00000400 },
-	{ 0x0009c8,   1, 0x04, 0x00000400 },
-	{ 0x00080c,   1, 0x04, 0x00000300 },
-	{ 0x00084c,   1, 0x04, 0x00000300 },
-	{ 0x00088c,   1, 0x04, 0x00000300 },
-	{ 0x0008cc,   1, 0x04, 0x00000300 },
-	{ 0x00090c,   1, 0x04, 0x00000300 },
-	{ 0x00094c,   1, 0x04, 0x00000300 },
-	{ 0x00098c,   1, 0x04, 0x00000300 },
-	{ 0x0009cc,   1, 0x04, 0x00000300 },
-	{ 0x000810,   1, 0x04, 0x000000cf },
-	{ 0x000850,   1, 0x04, 0x00000000 },
-	{ 0x000890,   1, 0x04, 0x00000000 },
-	{ 0x0008d0,   1, 0x04, 0x00000000 },
-	{ 0x000910,   1, 0x04, 0x00000000 },
-	{ 0x000950,   1, 0x04, 0x00000000 },
-	{ 0x000990,   1, 0x04, 0x00000000 },
-	{ 0x0009d0,   1, 0x04, 0x00000000 },
-	{ 0x000814,   1, 0x04, 0x00000040 },
-	{ 0x000854,   1, 0x04, 0x00000040 },
-	{ 0x000894,   1, 0x04, 0x00000040 },
-	{ 0x0008d4,   1, 0x04, 0x00000040 },
-	{ 0x000914,   1, 0x04, 0x00000040 },
-	{ 0x000954,   1, 0x04, 0x00000040 },
-	{ 0x000994,   1, 0x04, 0x00000040 },
-	{ 0x0009d4,   1, 0x04, 0x00000040 },
-	{ 0x000818,   1, 0x04, 0x00000001 },
-	{ 0x000858,   1, 0x04, 0x00000001 },
-	{ 0x000898,   1, 0x04, 0x00000001 },
-	{ 0x0008d8,   1, 0x04, 0x00000001 },
-	{ 0x000918,   1, 0x04, 0x00000001 },
-	{ 0x000958,   1, 0x04, 0x00000001 },
-	{ 0x000998,   1, 0x04, 0x00000001 },
-	{ 0x0009d8,   1, 0x04, 0x00000001 },
-	{ 0x00081c,   1, 0x04, 0x00000000 },
-	{ 0x00085c,   1, 0x04, 0x00000000 },
-	{ 0x00089c,   1, 0x04, 0x00000000 },
-	{ 0x0008dc,   1, 0x04, 0x00000000 },
-	{ 0x00091c,   1, 0x04, 0x00000000 },
-	{ 0x00095c,   1, 0x04, 0x00000000 },
-	{ 0x00099c,   1, 0x04, 0x00000000 },
-	{ 0x0009dc,   1, 0x04, 0x00000000 },
-	{ 0x000820,   1, 0x04, 0x00000000 },
-	{ 0x000860,   1, 0x04, 0x00000000 },
-	{ 0x0008a0,   1, 0x04, 0x00000000 },
-	{ 0x0008e0,   1, 0x04, 0x00000000 },
-	{ 0x000920,   1, 0x04, 0x00000000 },
-	{ 0x000960,   1, 0x04, 0x00000000 },
-	{ 0x0009a0,   1, 0x04, 0x00000000 },
-	{ 0x0009e0,   1, 0x04, 0x00000000 },
-	{ 0x001c00,   1, 0x04, 0x00000000 },
-	{ 0x001c10,   1, 0x04, 0x00000000 },
-	{ 0x001c20,   1, 0x04, 0x00000000 },
-	{ 0x001c30,   1, 0x04, 0x00000000 },
-	{ 0x001c40,   1, 0x04, 0x00000000 },
-	{ 0x001c50,   1, 0x04, 0x00000000 },
-	{ 0x001c60,   1, 0x04, 0x00000000 },
-	{ 0x001c70,   1, 0x04, 0x00000000 },
-	{ 0x001c80,   1, 0x04, 0x00000000 },
-	{ 0x001c90,   1, 0x04, 0x00000000 },
-	{ 0x001ca0,   1, 0x04, 0x00000000 },
-	{ 0x001cb0,   1, 0x04, 0x00000000 },
-	{ 0x001cc0,   1, 0x04, 0x00000000 },
-	{ 0x001cd0,   1, 0x04, 0x00000000 },
-	{ 0x001ce0,   1, 0x04, 0x00000000 },
-	{ 0x001cf0,   1, 0x04, 0x00000000 },
-	{ 0x001c04,   1, 0x04, 0x00000000 },
-	{ 0x001c14,   1, 0x04, 0x00000000 },
-	{ 0x001c24,   1, 0x04, 0x00000000 },
-	{ 0x001c34,   1, 0x04, 0x00000000 },
-	{ 0x001c44,   1, 0x04, 0x00000000 },
-	{ 0x001c54,   1, 0x04, 0x00000000 },
-	{ 0x001c64,   1, 0x04, 0x00000000 },
-	{ 0x001c74,   1, 0x04, 0x00000000 },
-	{ 0x001c84,   1, 0x04, 0x00000000 },
-	{ 0x001c94,   1, 0x04, 0x00000000 },
-	{ 0x001ca4,   1, 0x04, 0x00000000 },
-	{ 0x001cb4,   1, 0x04, 0x00000000 },
-	{ 0x001cc4,   1, 0x04, 0x00000000 },
-	{ 0x001cd4,   1, 0x04, 0x00000000 },
-	{ 0x001ce4,   1, 0x04, 0x00000000 },
-	{ 0x001cf4,   1, 0x04, 0x00000000 },
-	{ 0x001c08,   1, 0x04, 0x00000000 },
-	{ 0x001c18,   1, 0x04, 0x00000000 },
-	{ 0x001c28,   1, 0x04, 0x00000000 },
-	{ 0x001c38,   1, 0x04, 0x00000000 },
-	{ 0x001c48,   1, 0x04, 0x00000000 },
-	{ 0x001c58,   1, 0x04, 0x00000000 },
-	{ 0x001c68,   1, 0x04, 0x00000000 },
-	{ 0x001c78,   1, 0x04, 0x00000000 },
-	{ 0x001c88,   1, 0x04, 0x00000000 },
-	{ 0x001c98,   1, 0x04, 0x00000000 },
-	{ 0x001ca8,   1, 0x04, 0x00000000 },
-	{ 0x001cb8,   1, 0x04, 0x00000000 },
-	{ 0x001cc8,   1, 0x04, 0x00000000 },
-	{ 0x001cd8,   1, 0x04, 0x00000000 },
-	{ 0x001ce8,   1, 0x04, 0x00000000 },
-	{ 0x001cf8,   1, 0x04, 0x00000000 },
-	{ 0x001c0c,   1, 0x04, 0x00000000 },
-	{ 0x001c1c,   1, 0x04, 0x00000000 },
-	{ 0x001c2c,   1, 0x04, 0x00000000 },
-	{ 0x001c3c,   1, 0x04, 0x00000000 },
-	{ 0x001c4c,   1, 0x04, 0x00000000 },
-	{ 0x001c5c,   1, 0x04, 0x00000000 },
-	{ 0x001c6c,   1, 0x04, 0x00000000 },
-	{ 0x001c7c,   1, 0x04, 0x00000000 },
-	{ 0x001c8c,   1, 0x04, 0x00000000 },
-	{ 0x001c9c,   1, 0x04, 0x00000000 },
-	{ 0x001cac,   1, 0x04, 0x00000000 },
-	{ 0x001cbc,   1, 0x04, 0x00000000 },
-	{ 0x001ccc,   1, 0x04, 0x00000000 },
-	{ 0x001cdc,   1, 0x04, 0x00000000 },
-	{ 0x001cec,   1, 0x04, 0x00000000 },
-	{ 0x001cfc,   2, 0x04, 0x00000000 },
-	{ 0x001d10,   1, 0x04, 0x00000000 },
-	{ 0x001d20,   1, 0x04, 0x00000000 },
-	{ 0x001d30,   1, 0x04, 0x00000000 },
-	{ 0x001d40,   1, 0x04, 0x00000000 },
-	{ 0x001d50,   1, 0x04, 0x00000000 },
-	{ 0x001d60,   1, 0x04, 0x00000000 },
-	{ 0x001d70,   1, 0x04, 0x00000000 },
-	{ 0x001d80,   1, 0x04, 0x00000000 },
-	{ 0x001d90,   1, 0x04, 0x00000000 },
-	{ 0x001da0,   1, 0x04, 0x00000000 },
-	{ 0x001db0,   1, 0x04, 0x00000000 },
-	{ 0x001dc0,   1, 0x04, 0x00000000 },
-	{ 0x001dd0,   1, 0x04, 0x00000000 },
-	{ 0x001de0,   1, 0x04, 0x00000000 },
-	{ 0x001df0,   1, 0x04, 0x00000000 },
-	{ 0x001d04,   1, 0x04, 0x00000000 },
-	{ 0x001d14,   1, 0x04, 0x00000000 },
-	{ 0x001d24,   1, 0x04, 0x00000000 },
-	{ 0x001d34,   1, 0x04, 0x00000000 },
-	{ 0x001d44,   1, 0x04, 0x00000000 },
-	{ 0x001d54,   1, 0x04, 0x00000000 },
-	{ 0x001d64,   1, 0x04, 0x00000000 },
-	{ 0x001d74,   1, 0x04, 0x00000000 },
-	{ 0x001d84,   1, 0x04, 0x00000000 },
-	{ 0x001d94,   1, 0x04, 0x00000000 },
-	{ 0x001da4,   1, 0x04, 0x00000000 },
-	{ 0x001db4,   1, 0x04, 0x00000000 },
-	{ 0x001dc4,   1, 0x04, 0x00000000 },
-	{ 0x001dd4,   1, 0x04, 0x00000000 },
-	{ 0x001de4,   1, 0x04, 0x00000000 },
-	{ 0x001df4,   1, 0x04, 0x00000000 },
-	{ 0x001d08,   1, 0x04, 0x00000000 },
-	{ 0x001d18,   1, 0x04, 0x00000000 },
-	{ 0x001d28,   1, 0x04, 0x00000000 },
-	{ 0x001d38,   1, 0x04, 0x00000000 },
-	{ 0x001d48,   1, 0x04, 0x00000000 },
-	{ 0x001d58,   1, 0x04, 0x00000000 },
-	{ 0x001d68,   1, 0x04, 0x00000000 },
-	{ 0x001d78,   1, 0x04, 0x00000000 },
-	{ 0x001d88,   1, 0x04, 0x00000000 },
-	{ 0x001d98,   1, 0x04, 0x00000000 },
-	{ 0x001da8,   1, 0x04, 0x00000000 },
-	{ 0x001db8,   1, 0x04, 0x00000000 },
-	{ 0x001dc8,   1, 0x04, 0x00000000 },
-	{ 0x001dd8,   1, 0x04, 0x00000000 },
-	{ 0x001de8,   1, 0x04, 0x00000000 },
-	{ 0x001df8,   1, 0x04, 0x00000000 },
-	{ 0x001d0c,   1, 0x04, 0x00000000 },
-	{ 0x001d1c,   1, 0x04, 0x00000000 },
-	{ 0x001d2c,   1, 0x04, 0x00000000 },
-	{ 0x001d3c,   1, 0x04, 0x00000000 },
-	{ 0x001d4c,   1, 0x04, 0x00000000 },
-	{ 0x001d5c,   1, 0x04, 0x00000000 },
-	{ 0x001d6c,   1, 0x04, 0x00000000 },
-	{ 0x001d7c,   1, 0x04, 0x00000000 },
-	{ 0x001d8c,   1, 0x04, 0x00000000 },
-	{ 0x001d9c,   1, 0x04, 0x00000000 },
-	{ 0x001dac,   1, 0x04, 0x00000000 },
-	{ 0x001dbc,   1, 0x04, 0x00000000 },
-	{ 0x001dcc,   1, 0x04, 0x00000000 },
-	{ 0x001ddc,   1, 0x04, 0x00000000 },
-	{ 0x001dec,   1, 0x04, 0x00000000 },
-	{ 0x001dfc,   1, 0x04, 0x00000000 },
-	{ 0x001f00,   1, 0x04, 0x00000000 },
-	{ 0x001f08,   1, 0x04, 0x00000000 },
-	{ 0x001f10,   1, 0x04, 0x00000000 },
-	{ 0x001f18,   1, 0x04, 0x00000000 },
-	{ 0x001f20,   1, 0x04, 0x00000000 },
-	{ 0x001f28,   1, 0x04, 0x00000000 },
-	{ 0x001f30,   1, 0x04, 0x00000000 },
-	{ 0x001f38,   1, 0x04, 0x00000000 },
-	{ 0x001f40,   1, 0x04, 0x00000000 },
-	{ 0x001f48,   1, 0x04, 0x00000000 },
-	{ 0x001f50,   1, 0x04, 0x00000000 },
-	{ 0x001f58,   1, 0x04, 0x00000000 },
-	{ 0x001f60,   1, 0x04, 0x00000000 },
-	{ 0x001f68,   1, 0x04, 0x00000000 },
-	{ 0x001f70,   1, 0x04, 0x00000000 },
-	{ 0x001f78,   1, 0x04, 0x00000000 },
-	{ 0x001f04,   1, 0x04, 0x00000000 },
-	{ 0x001f0c,   1, 0x04, 0x00000000 },
-	{ 0x001f14,   1, 0x04, 0x00000000 },
-	{ 0x001f1c,   1, 0x04, 0x00000000 },
-	{ 0x001f24,   1, 0x04, 0x00000000 },
-	{ 0x001f2c,   1, 0x04, 0x00000000 },
-	{ 0x001f34,   1, 0x04, 0x00000000 },
-	{ 0x001f3c,   1, 0x04, 0x00000000 },
-	{ 0x001f44,   1, 0x04, 0x00000000 },
-	{ 0x001f4c,   1, 0x04, 0x00000000 },
-	{ 0x001f54,   1, 0x04, 0x00000000 },
-	{ 0x001f5c,   1, 0x04, 0x00000000 },
-	{ 0x001f64,   1, 0x04, 0x00000000 },
-	{ 0x001f6c,   1, 0x04, 0x00000000 },
-	{ 0x001f74,   1, 0x04, 0x00000000 },
-	{ 0x001f7c,   2, 0x04, 0x00000000 },
-	{ 0x001f88,   1, 0x04, 0x00000000 },
-	{ 0x001f90,   1, 0x04, 0x00000000 },
-	{ 0x001f98,   1, 0x04, 0x00000000 },
-	{ 0x001fa0,   1, 0x04, 0x00000000 },
-	{ 0x001fa8,   1, 0x04, 0x00000000 },
-	{ 0x001fb0,   1, 0x04, 0x00000000 },
-	{ 0x001fb8,   1, 0x04, 0x00000000 },
-	{ 0x001fc0,   1, 0x04, 0x00000000 },
-	{ 0x001fc8,   1, 0x04, 0x00000000 },
-	{ 0x001fd0,   1, 0x04, 0x00000000 },
-	{ 0x001fd8,   1, 0x04, 0x00000000 },
-	{ 0x001fe0,   1, 0x04, 0x00000000 },
-	{ 0x001fe8,   1, 0x04, 0x00000000 },
-	{ 0x001ff0,   1, 0x04, 0x00000000 },
-	{ 0x001ff8,   1, 0x04, 0x00000000 },
-	{ 0x001f84,   1, 0x04, 0x00000000 },
-	{ 0x001f8c,   1, 0x04, 0x00000000 },
-	{ 0x001f94,   1, 0x04, 0x00000000 },
-	{ 0x001f9c,   1, 0x04, 0x00000000 },
-	{ 0x001fa4,   1, 0x04, 0x00000000 },
-	{ 0x001fac,   1, 0x04, 0x00000000 },
-	{ 0x001fb4,   1, 0x04, 0x00000000 },
-	{ 0x001fbc,   1, 0x04, 0x00000000 },
-	{ 0x001fc4,   1, 0x04, 0x00000000 },
-	{ 0x001fcc,   1, 0x04, 0x00000000 },
-	{ 0x001fd4,   1, 0x04, 0x00000000 },
-	{ 0x001fdc,   1, 0x04, 0x00000000 },
-	{ 0x001fe4,   1, 0x04, 0x00000000 },
-	{ 0x001fec,   1, 0x04, 0x00000000 },
-	{ 0x001ff4,   1, 0x04, 0x00000000 },
-	{ 0x001ffc,   2, 0x04, 0x00000000 },
-	{ 0x002040,   1, 0x04, 0x00000011 },
-	{ 0x002080,   1, 0x04, 0x00000020 },
-	{ 0x0020c0,   1, 0x04, 0x00000030 },
-	{ 0x002100,   1, 0x04, 0x00000040 },
-	{ 0x002140,   1, 0x04, 0x00000051 },
-	{ 0x00200c,   1, 0x04, 0x00000001 },
-	{ 0x00204c,   1, 0x04, 0x00000001 },
-	{ 0x00208c,   1, 0x04, 0x00000001 },
-	{ 0x0020cc,   1, 0x04, 0x00000001 },
-	{ 0x00210c,   1, 0x04, 0x00000001 },
-	{ 0x00214c,   1, 0x04, 0x00000001 },
-	{ 0x002010,   1, 0x04, 0x00000000 },
-	{ 0x002050,   1, 0x04, 0x00000000 },
-	{ 0x002090,   1, 0x04, 0x00000001 },
-	{ 0x0020d0,   1, 0x04, 0x00000002 },
-	{ 0x002110,   1, 0x04, 0x00000003 },
-	{ 0x002150,   1, 0x04, 0x00000004 },
-	{ 0x000380,   1, 0x04, 0x00000000 },
-	{ 0x0003a0,   1, 0x04, 0x00000000 },
-	{ 0x0003c0,   1, 0x04, 0x00000000 },
-	{ 0x0003e0,   1, 0x04, 0x00000000 },
-	{ 0x000384,   1, 0x04, 0x00000000 },
-	{ 0x0003a4,   1, 0x04, 0x00000000 },
-	{ 0x0003c4,   1, 0x04, 0x00000000 },
-	{ 0x0003e4,   1, 0x04, 0x00000000 },
-	{ 0x000388,   1, 0x04, 0x00000000 },
-	{ 0x0003a8,   1, 0x04, 0x00000000 },
-	{ 0x0003c8,   1, 0x04, 0x00000000 },
-	{ 0x0003e8,   1, 0x04, 0x00000000 },
-	{ 0x00038c,   1, 0x04, 0x00000000 },
-	{ 0x0003ac,   1, 0x04, 0x00000000 },
-	{ 0x0003cc,   1, 0x04, 0x00000000 },
-	{ 0x0003ec,   1, 0x04, 0x00000000 },
-	{ 0x000700,   1, 0x04, 0x00000000 },
-	{ 0x000710,   1, 0x04, 0x00000000 },
-	{ 0x000720,   1, 0x04, 0x00000000 },
-	{ 0x000730,   1, 0x04, 0x00000000 },
-	{ 0x000704,   1, 0x04, 0x00000000 },
-	{ 0x000714,   1, 0x04, 0x00000000 },
-	{ 0x000724,   1, 0x04, 0x00000000 },
-	{ 0x000734,   1, 0x04, 0x00000000 },
-	{ 0x000708,   1, 0x04, 0x00000000 },
-	{ 0x000718,   1, 0x04, 0x00000000 },
-	{ 0x000728,   1, 0x04, 0x00000000 },
-	{ 0x000738,   1, 0x04, 0x00000000 },
-	{ 0x002800, 128, 0x04, 0x00000000 },
-	{ 0x000a00,   1, 0x04, 0x00000000 },
-	{ 0x000a20,   1, 0x04, 0x00000000 },
-	{ 0x000a40,   1, 0x04, 0x00000000 },
-	{ 0x000a60,   1, 0x04, 0x00000000 },
-	{ 0x000a80,   1, 0x04, 0x00000000 },
-	{ 0x000aa0,   1, 0x04, 0x00000000 },
-	{ 0x000ac0,   1, 0x04, 0x00000000 },
-	{ 0x000ae0,   1, 0x04, 0x00000000 },
-	{ 0x000b00,   1, 0x04, 0x00000000 },
-	{ 0x000b20,   1, 0x04, 0x00000000 },
-	{ 0x000b40,   1, 0x04, 0x00000000 },
-	{ 0x000b60,   1, 0x04, 0x00000000 },
-	{ 0x000b80,   1, 0x04, 0x00000000 },
-	{ 0x000ba0,   1, 0x04, 0x00000000 },
-	{ 0x000bc0,   1, 0x04, 0x00000000 },
-	{ 0x000be0,   1, 0x04, 0x00000000 },
-	{ 0x000a04,   1, 0x04, 0x00000000 },
-	{ 0x000a24,   1, 0x04, 0x00000000 },
-	{ 0x000a44,   1, 0x04, 0x00000000 },
-	{ 0x000a64,   1, 0x04, 0x00000000 },
-	{ 0x000a84,   1, 0x04, 0x00000000 },
-	{ 0x000aa4,   1, 0x04, 0x00000000 },
-	{ 0x000ac4,   1, 0x04, 0x00000000 },
-	{ 0x000ae4,   1, 0x04, 0x00000000 },
-	{ 0x000b04,   1, 0x04, 0x00000000 },
-	{ 0x000b24,   1, 0x04, 0x00000000 },
-	{ 0x000b44,   1, 0x04, 0x00000000 },
-	{ 0x000b64,   1, 0x04, 0x00000000 },
-	{ 0x000b84,   1, 0x04, 0x00000000 },
-	{ 0x000ba4,   1, 0x04, 0x00000000 },
-	{ 0x000bc4,   1, 0x04, 0x00000000 },
-	{ 0x000be4,   1, 0x04, 0x00000000 },
-	{ 0x000a08,   1, 0x04, 0x00000000 },
-	{ 0x000a28,   1, 0x04, 0x00000000 },
-	{ 0x000a48,   1, 0x04, 0x00000000 },
-	{ 0x000a68,   1, 0x04, 0x00000000 },
-	{ 0x000a88,   1, 0x04, 0x00000000 },
-	{ 0x000aa8,   1, 0x04, 0x00000000 },
-	{ 0x000ac8,   1, 0x04, 0x00000000 },
-	{ 0x000ae8,   1, 0x04, 0x00000000 },
-	{ 0x000b08,   1, 0x04, 0x00000000 },
-	{ 0x000b28,   1, 0x04, 0x00000000 },
-	{ 0x000b48,   1, 0x04, 0x00000000 },
-	{ 0x000b68,   1, 0x04, 0x00000000 },
-	{ 0x000b88,   1, 0x04, 0x00000000 },
-	{ 0x000ba8,   1, 0x04, 0x00000000 },
-	{ 0x000bc8,   1, 0x04, 0x00000000 },
-	{ 0x000be8,   1, 0x04, 0x00000000 },
-	{ 0x000a0c,   1, 0x04, 0x00000000 },
-	{ 0x000a2c,   1, 0x04, 0x00000000 },
-	{ 0x000a4c,   1, 0x04, 0x00000000 },
-	{ 0x000a6c,   1, 0x04, 0x00000000 },
-	{ 0x000a8c,   1, 0x04, 0x00000000 },
-	{ 0x000aac,   1, 0x04, 0x00000000 },
-	{ 0x000acc,   1, 0x04, 0x00000000 },
-	{ 0x000aec,   1, 0x04, 0x00000000 },
-	{ 0x000b0c,   1, 0x04, 0x00000000 },
-	{ 0x000b2c,   1, 0x04, 0x00000000 },
-	{ 0x000b4c,   1, 0x04, 0x00000000 },
-	{ 0x000b6c,   1, 0x04, 0x00000000 },
-	{ 0x000b8c,   1, 0x04, 0x00000000 },
-	{ 0x000bac,   1, 0x04, 0x00000000 },
-	{ 0x000bcc,   1, 0x04, 0x00000000 },
-	{ 0x000bec,   1, 0x04, 0x00000000 },
-	{ 0x000a10,   1, 0x04, 0x00000000 },
-	{ 0x000a30,   1, 0x04, 0x00000000 },
-	{ 0x000a50,   1, 0x04, 0x00000000 },
-	{ 0x000a70,   1, 0x04, 0x00000000 },
-	{ 0x000a90,   1, 0x04, 0x00000000 },
-	{ 0x000ab0,   1, 0x04, 0x00000000 },
-	{ 0x000ad0,   1, 0x04, 0x00000000 },
-	{ 0x000af0,   1, 0x04, 0x00000000 },
-	{ 0x000b10,   1, 0x04, 0x00000000 },
-	{ 0x000b30,   1, 0x04, 0x00000000 },
-	{ 0x000b50,   1, 0x04, 0x00000000 },
-	{ 0x000b70,   1, 0x04, 0x00000000 },
-	{ 0x000b90,   1, 0x04, 0x00000000 },
-	{ 0x000bb0,   1, 0x04, 0x00000000 },
-	{ 0x000bd0,   1, 0x04, 0x00000000 },
-	{ 0x000bf0,   1, 0x04, 0x00000000 },
-	{ 0x000a14,   1, 0x04, 0x00000000 },
-	{ 0x000a34,   1, 0x04, 0x00000000 },
-	{ 0x000a54,   1, 0x04, 0x00000000 },
-	{ 0x000a74,   1, 0x04, 0x00000000 },
-	{ 0x000a94,   1, 0x04, 0x00000000 },
-	{ 0x000ab4,   1, 0x04, 0x00000000 },
-	{ 0x000ad4,   1, 0x04, 0x00000000 },
-	{ 0x000af4,   1, 0x04, 0x00000000 },
-	{ 0x000b14,   1, 0x04, 0x00000000 },
-	{ 0x000b34,   1, 0x04, 0x00000000 },
-	{ 0x000b54,   1, 0x04, 0x00000000 },
-	{ 0x000b74,   1, 0x04, 0x00000000 },
-	{ 0x000b94,   1, 0x04, 0x00000000 },
-	{ 0x000bb4,   1, 0x04, 0x00000000 },
-	{ 0x000bd4,   1, 0x04, 0x00000000 },
-	{ 0x000bf4,   1, 0x04, 0x00000000 },
-	{ 0x000c00,   1, 0x04, 0x00000000 },
-	{ 0x000c10,   1, 0x04, 0x00000000 },
-	{ 0x000c20,   1, 0x04, 0x00000000 },
-	{ 0x000c30,   1, 0x04, 0x00000000 },
-	{ 0x000c40,   1, 0x04, 0x00000000 },
-	{ 0x000c50,   1, 0x04, 0x00000000 },
-	{ 0x000c60,   1, 0x04, 0x00000000 },
-	{ 0x000c70,   1, 0x04, 0x00000000 },
-	{ 0x000c80,   1, 0x04, 0x00000000 },
-	{ 0x000c90,   1, 0x04, 0x00000000 },
-	{ 0x000ca0,   1, 0x04, 0x00000000 },
-	{ 0x000cb0,   1, 0x04, 0x00000000 },
-	{ 0x000cc0,   1, 0x04, 0x00000000 },
-	{ 0x000cd0,   1, 0x04, 0x00000000 },
-	{ 0x000ce0,   1, 0x04, 0x00000000 },
-	{ 0x000cf0,   1, 0x04, 0x00000000 },
-	{ 0x000c04,   1, 0x04, 0x00000000 },
-	{ 0x000c14,   1, 0x04, 0x00000000 },
-	{ 0x000c24,   1, 0x04, 0x00000000 },
-	{ 0x000c34,   1, 0x04, 0x00000000 },
-	{ 0x000c44,   1, 0x04, 0x00000000 },
-	{ 0x000c54,   1, 0x04, 0x00000000 },
-	{ 0x000c64,   1, 0x04, 0x00000000 },
-	{ 0x000c74,   1, 0x04, 0x00000000 },
-	{ 0x000c84,   1, 0x04, 0x00000000 },
-	{ 0x000c94,   1, 0x04, 0x00000000 },
-	{ 0x000ca4,   1, 0x04, 0x00000000 },
-	{ 0x000cb4,   1, 0x04, 0x00000000 },
-	{ 0x000cc4,   1, 0x04, 0x00000000 },
-	{ 0x000cd4,   1, 0x04, 0x00000000 },
-	{ 0x000ce4,   1, 0x04, 0x00000000 },
-	{ 0x000cf4,   1, 0x04, 0x00000000 },
-	{ 0x000c08,   1, 0x04, 0x00000000 },
-	{ 0x000c18,   1, 0x04, 0x00000000 },
-	{ 0x000c28,   1, 0x04, 0x00000000 },
-	{ 0x000c38,   1, 0x04, 0x00000000 },
-	{ 0x000c48,   1, 0x04, 0x00000000 },
-	{ 0x000c58,   1, 0x04, 0x00000000 },
-	{ 0x000c68,   1, 0x04, 0x00000000 },
-	{ 0x000c78,   1, 0x04, 0x00000000 },
-	{ 0x000c88,   1, 0x04, 0x00000000 },
-	{ 0x000c98,   1, 0x04, 0x00000000 },
-	{ 0x000ca8,   1, 0x04, 0x00000000 },
-	{ 0x000cb8,   1, 0x04, 0x00000000 },
-	{ 0x000cc8,   1, 0x04, 0x00000000 },
-	{ 0x000cd8,   1, 0x04, 0x00000000 },
-	{ 0x000ce8,   1, 0x04, 0x00000000 },
-	{ 0x000cf8,   1, 0x04, 0x00000000 },
-	{ 0x000c0c,   1, 0x04, 0x3f800000 },
-	{ 0x000c1c,   1, 0x04, 0x3f800000 },
-	{ 0x000c2c,   1, 0x04, 0x3f800000 },
-	{ 0x000c3c,   1, 0x04, 0x3f800000 },
-	{ 0x000c4c,   1, 0x04, 0x3f800000 },
-	{ 0x000c5c,   1, 0x04, 0x3f800000 },
-	{ 0x000c6c,   1, 0x04, 0x3f800000 },
-	{ 0x000c7c,   1, 0x04, 0x3f800000 },
-	{ 0x000c8c,   1, 0x04, 0x3f800000 },
-	{ 0x000c9c,   1, 0x04, 0x3f800000 },
-	{ 0x000cac,   1, 0x04, 0x3f800000 },
-	{ 0x000cbc,   1, 0x04, 0x3f800000 },
-	{ 0x000ccc,   1, 0x04, 0x3f800000 },
-	{ 0x000cdc,   1, 0x04, 0x3f800000 },
-	{ 0x000cec,   1, 0x04, 0x3f800000 },
-	{ 0x000cfc,   1, 0x04, 0x3f800000 },
-	{ 0x000d00,   1, 0x04, 0xffff0000 },
-	{ 0x000d08,   1, 0x04, 0xffff0000 },
-	{ 0x000d10,   1, 0x04, 0xffff0000 },
-	{ 0x000d18,   1, 0x04, 0xffff0000 },
-	{ 0x000d20,   1, 0x04, 0xffff0000 },
-	{ 0x000d28,   1, 0x04, 0xffff0000 },
-	{ 0x000d30,   1, 0x04, 0xffff0000 },
-	{ 0x000d38,   1, 0x04, 0xffff0000 },
-	{ 0x000d04,   1, 0x04, 0xffff0000 },
-	{ 0x000d0c,   1, 0x04, 0xffff0000 },
-	{ 0x000d14,   1, 0x04, 0xffff0000 },
-	{ 0x000d1c,   1, 0x04, 0xffff0000 },
-	{ 0x000d24,   1, 0x04, 0xffff0000 },
-	{ 0x000d2c,   1, 0x04, 0xffff0000 },
-	{ 0x000d34,   1, 0x04, 0xffff0000 },
-	{ 0x000d3c,   1, 0x04, 0xffff0000 },
-	{ 0x000e00,   1, 0x04, 0x00000000 },
-	{ 0x000e10,   1, 0x04, 0x00000000 },
-	{ 0x000e20,   1, 0x04, 0x00000000 },
-	{ 0x000e30,   1, 0x04, 0x00000000 },
-	{ 0x000e40,   1, 0x04, 0x00000000 },
-	{ 0x000e50,   1, 0x04, 0x00000000 },
-	{ 0x000e60,   1, 0x04, 0x00000000 },
-	{ 0x000e70,   1, 0x04, 0x00000000 },
-	{ 0x000e80,   1, 0x04, 0x00000000 },
-	{ 0x000e90,   1, 0x04, 0x00000000 },
-	{ 0x000ea0,   1, 0x04, 0x00000000 },
-	{ 0x000eb0,   1, 0x04, 0x00000000 },
-	{ 0x000ec0,   1, 0x04, 0x00000000 },
-	{ 0x000ed0,   1, 0x04, 0x00000000 },
-	{ 0x000ee0,   1, 0x04, 0x00000000 },
-	{ 0x000ef0,   1, 0x04, 0x00000000 },
-	{ 0x000e04,   1, 0x04, 0xffff0000 },
-	{ 0x000e14,   1, 0x04, 0xffff0000 },
-	{ 0x000e24,   1, 0x04, 0xffff0000 },
-	{ 0x000e34,   1, 0x04, 0xffff0000 },
-	{ 0x000e44,   1, 0x04, 0xffff0000 },
-	{ 0x000e54,   1, 0x04, 0xffff0000 },
-	{ 0x000e64,   1, 0x04, 0xffff0000 },
-	{ 0x000e74,   1, 0x04, 0xffff0000 },
-	{ 0x000e84,   1, 0x04, 0xffff0000 },
-	{ 0x000e94,   1, 0x04, 0xffff0000 },
-	{ 0x000ea4,   1, 0x04, 0xffff0000 },
-	{ 0x000eb4,   1, 0x04, 0xffff0000 },
-	{ 0x000ec4,   1, 0x04, 0xffff0000 },
-	{ 0x000ed4,   1, 0x04, 0xffff0000 },
-	{ 0x000ee4,   1, 0x04, 0xffff0000 },
-	{ 0x000ef4,   1, 0x04, 0xffff0000 },
-	{ 0x000e08,   1, 0x04, 0xffff0000 },
-	{ 0x000e18,   1, 0x04, 0xffff0000 },
-	{ 0x000e28,   1, 0x04, 0xffff0000 },
-	{ 0x000e38,   1, 0x04, 0xffff0000 },
-	{ 0x000e48,   1, 0x04, 0xffff0000 },
-	{ 0x000e58,   1, 0x04, 0xffff0000 },
-	{ 0x000e68,   1, 0x04, 0xffff0000 },
-	{ 0x000e78,   1, 0x04, 0xffff0000 },
-	{ 0x000e88,   1, 0x04, 0xffff0000 },
-	{ 0x000e98,   1, 0x04, 0xffff0000 },
-	{ 0x000ea8,   1, 0x04, 0xffff0000 },
-	{ 0x000eb8,   1, 0x04, 0xffff0000 },
-	{ 0x000ec8,   1, 0x04, 0xffff0000 },
-	{ 0x000ed8,   1, 0x04, 0xffff0000 },
-	{ 0x000ee8,   1, 0x04, 0xffff0000 },
-	{ 0x000ef8,   1, 0x04, 0xffff0000 },
-	{ 0x000d40,   1, 0x04, 0x00000000 },
-	{ 0x000d48,   1, 0x04, 0x00000000 },
-	{ 0x000d50,   1, 0x04, 0x00000000 },
-	{ 0x000d58,   1, 0x04, 0x00000000 },
-	{ 0x000d44,   1, 0x04, 0x00000000 },
-	{ 0x000d4c,   1, 0x04, 0x00000000 },
-	{ 0x000d54,   1, 0x04, 0x00000000 },
-	{ 0x000d5c,   1, 0x04, 0x00000000 },
-	{ 0x001e00,   1, 0x04, 0x00000001 },
-	{ 0x001e20,   1, 0x04, 0x00000001 },
-	{ 0x001e40,   1, 0x04, 0x00000001 },
-	{ 0x001e60,   1, 0x04, 0x00000001 },
-	{ 0x001e80,   1, 0x04, 0x00000001 },
-	{ 0x001ea0,   1, 0x04, 0x00000001 },
-	{ 0x001ec0,   1, 0x04, 0x00000001 },
-	{ 0x001ee0,   1, 0x04, 0x00000001 },
-	{ 0x001e04,   1, 0x04, 0x00000001 },
-	{ 0x001e24,   1, 0x04, 0x00000001 },
-	{ 0x001e44,   1, 0x04, 0x00000001 },
-	{ 0x001e64,   1, 0x04, 0x00000001 },
-	{ 0x001e84,   1, 0x04, 0x00000001 },
-	{ 0x001ea4,   1, 0x04, 0x00000001 },
-	{ 0x001ec4,   1, 0x04, 0x00000001 },
-	{ 0x001ee4,   1, 0x04, 0x00000001 },
-	{ 0x001e08,   1, 0x04, 0x00000002 },
-	{ 0x001e28,   1, 0x04, 0x00000002 },
-	{ 0x001e48,   1, 0x04, 0x00000002 },
-	{ 0x001e68,   1, 0x04, 0x00000002 },
-	{ 0x001e88,   1, 0x04, 0x00000002 },
-	{ 0x001ea8,   1, 0x04, 0x00000002 },
-	{ 0x001ec8,   1, 0x04, 0x00000002 },
-	{ 0x001ee8,   1, 0x04, 0x00000002 },
-	{ 0x001e0c,   1, 0x04, 0x00000001 },
-	{ 0x001e2c,   1, 0x04, 0x00000001 },
-	{ 0x001e4c,   1, 0x04, 0x00000001 },
-	{ 0x001e6c,   1, 0x04, 0x00000001 },
-	{ 0x001e8c,   1, 0x04, 0x00000001 },
-	{ 0x001eac,   1, 0x04, 0x00000001 },
-	{ 0x001ecc,   1, 0x04, 0x00000001 },
-	{ 0x001eec,   1, 0x04, 0x00000001 },
-	{ 0x001e10,   1, 0x04, 0x00000001 },
-	{ 0x001e30,   1, 0x04, 0x00000001 },
-	{ 0x001e50,   1, 0x04, 0x00000001 },
-	{ 0x001e70,   1, 0x04, 0x00000001 },
-	{ 0x001e90,   1, 0x04, 0x00000001 },
-	{ 0x001eb0,   1, 0x04, 0x00000001 },
-	{ 0x001ed0,   1, 0x04, 0x00000001 },
-	{ 0x001ef0,   1, 0x04, 0x00000001 },
-	{ 0x001e14,   1, 0x04, 0x00000002 },
-	{ 0x001e34,   1, 0x04, 0x00000002 },
-	{ 0x001e54,   1, 0x04, 0x00000002 },
-	{ 0x001e74,   1, 0x04, 0x00000002 },
-	{ 0x001e94,   1, 0x04, 0x00000002 },
-	{ 0x001eb4,   1, 0x04, 0x00000002 },
-	{ 0x001ed4,   1, 0x04, 0x00000002 },
-	{ 0x001ef4,   1, 0x04, 0x00000002 },
-	{ 0x001e18,   1, 0x04, 0x00000001 },
-	{ 0x001e38,   1, 0x04, 0x00000001 },
-	{ 0x001e58,   1, 0x04, 0x00000001 },
-	{ 0x001e78,   1, 0x04, 0x00000001 },
-	{ 0x001e98,   1, 0x04, 0x00000001 },
-	{ 0x001eb8,   1, 0x04, 0x00000001 },
-	{ 0x001ed8,   1, 0x04, 0x00000001 },
-	{ 0x001ef8,   1, 0x04, 0x00000001 },
-	{ 0x003400, 128, 0x04, 0x00000000 },
-	{ 0x00030c,   1, 0x04, 0x00000001 },
-	{ 0x001944,   1, 0x04, 0x00000000 },
-	{ 0x001514,   1, 0x04, 0x00000000 },
-	{ 0x000d68,   1, 0x04, 0x0000ffff },
-	{ 0x00121c,   1, 0x04, 0x0fac6881 },
-	{ 0x000fac,   1, 0x04, 0x00000001 },
-	{ 0x001538,   1, 0x04, 0x00000001 },
-	{ 0x000fe0,   2, 0x04, 0x00000000 },
-	{ 0x000fe8,   1, 0x04, 0x00000014 },
-	{ 0x000fec,   1, 0x04, 0x00000040 },
-	{ 0x000ff0,   1, 0x04, 0x00000000 },
-	{ 0x00179c,   1, 0x04, 0x00000000 },
-	{ 0x001228,   1, 0x04, 0x00000400 },
-	{ 0x00122c,   1, 0x04, 0x00000300 },
-	{ 0x001230,   1, 0x04, 0x00010001 },
-	{ 0x0007f8,   1, 0x04, 0x00000000 },
-	{ 0x0015b4,   1, 0x04, 0x00000001 },
-	{ 0x0015cc,   1, 0x04, 0x00000000 },
-	{ 0x001534,   1, 0x04, 0x00000000 },
-	{ 0x000fb0,   1, 0x04, 0x00000000 },
-	{ 0x0015d0,   1, 0x04, 0x00000000 },
-	{ 0x00153c,   1, 0x04, 0x00000000 },
-	{ 0x0016b4,   1, 0x04, 0x00000003 },
-	{ 0x000fbc,   4, 0x04, 0x0000ffff },
-	{ 0x000df8,   2, 0x04, 0x00000000 },
-	{ 0x001948,   1, 0x04, 0x00000000 },
-	{ 0x001970,   1, 0x04, 0x00000001 },
-	{ 0x00161c,   1, 0x04, 0x000009f0 },
-	{ 0x000dcc,   1, 0x04, 0x00000010 },
-	{ 0x00163c,   1, 0x04, 0x00000000 },
-	{ 0x0015e4,   1, 0x04, 0x00000000 },
-	{ 0x001160,  32, 0x04, 0x25e00040 },
-	{ 0x001880,  32, 0x04, 0x00000000 },
-	{ 0x000f84,   2, 0x04, 0x00000000 },
-	{ 0x0017c8,   2, 0x04, 0x00000000 },
-	{ 0x0017d0,   1, 0x04, 0x000000ff },
-	{ 0x0017d4,   1, 0x04, 0xffffffff },
-	{ 0x0017d8,   1, 0x04, 0x00000002 },
-	{ 0x0017dc,   1, 0x04, 0x00000000 },
-	{ 0x0015f4,   2, 0x04, 0x00000000 },
-	{ 0x001434,   2, 0x04, 0x00000000 },
-	{ 0x000d74,   1, 0x04, 0x00000000 },
-	{ 0x000dec,   1, 0x04, 0x00000001 },
-	{ 0x0013a4,   1, 0x04, 0x00000000 },
-	{ 0x001318,   1, 0x04, 0x00000001 },
-	{ 0x001644,   1, 0x04, 0x00000000 },
-	{ 0x000748,   1, 0x04, 0x00000000 },
-	{ 0x000de8,   1, 0x04, 0x00000000 },
-	{ 0x001648,   1, 0x04, 0x00000000 },
-	{ 0x0012a4,   1, 0x04, 0x00000000 },
-	{ 0x001120,   4, 0x04, 0x00000000 },
-	{ 0x001118,   1, 0x04, 0x00000000 },
-	{ 0x00164c,   1, 0x04, 0x00000000 },
-	{ 0x001658,   1, 0x04, 0x00000000 },
-	{ 0x001910,   1, 0x04, 0x00000290 },
-	{ 0x001518,   1, 0x04, 0x00000000 },
-	{ 0x00165c,   1, 0x04, 0x00000001 },
-	{ 0x001520,   1, 0x04, 0x00000000 },
-	{ 0x001604,   1, 0x04, 0x00000000 },
-	{ 0x001570,   1, 0x04, 0x00000000 },
-	{ 0x0013b0,   2, 0x04, 0x3f800000 },
-	{ 0x00020c,   1, 0x04, 0x00000000 },
-	{ 0x001670,   1, 0x04, 0x30201000 },
-	{ 0x001674,   1, 0x04, 0x70605040 },
-	{ 0x001678,   1, 0x04, 0xb8a89888 },
-	{ 0x00167c,   1, 0x04, 0xf8e8d8c8 },
-	{ 0x00166c,   1, 0x04, 0x00000000 },
-	{ 0x001680,   1, 0x04, 0x00ffff00 },
-	{ 0x0012d0,   1, 0x04, 0x00000003 },
-	{ 0x0012d4,   1, 0x04, 0x00000002 },
-	{ 0x001684,   2, 0x04, 0x00000000 },
-	{ 0x000dac,   2, 0x04, 0x00001b02 },
-	{ 0x000db4,   1, 0x04, 0x00000000 },
-	{ 0x00168c,   1, 0x04, 0x00000000 },
-	{ 0x0015bc,   1, 0x04, 0x00000000 },
-	{ 0x00156c,   1, 0x04, 0x00000000 },
-	{ 0x00187c,   1, 0x04, 0x00000000 },
-	{ 0x001110,   1, 0x04, 0x00000001 },
-	{ 0x000dc0,   3, 0x04, 0x00000000 },
-	{ 0x001234,   1, 0x04, 0x00000000 },
-	{ 0x001690,   1, 0x04, 0x00000000 },
-	{ 0x0012ac,   1, 0x04, 0x00000001 },
-	{ 0x0002c4,   1, 0x04, 0x00000000 },
-	{ 0x000790,   5, 0x04, 0x00000000 },
-	{ 0x00077c,   1, 0x04, 0x00000000 },
-	{ 0x001000,   1, 0x04, 0x00000010 },
-	{ 0x0010fc,   1, 0x04, 0x00000000 },
-	{ 0x001290,   1, 0x04, 0x00000000 },
-	{ 0x000218,   1, 0x04, 0x00000010 },
-	{ 0x0012d8,   1, 0x04, 0x00000000 },
-	{ 0x0012dc,   1, 0x04, 0x00000010 },
-	{ 0x000d94,   1, 0x04, 0x00000001 },
-	{ 0x00155c,   2, 0x04, 0x00000000 },
-	{ 0x001564,   1, 0x04, 0x00000fff },
-	{ 0x001574,   2, 0x04, 0x00000000 },
-	{ 0x00157c,   1, 0x04, 0x000fffff },
-	{ 0x001354,   1, 0x04, 0x00000000 },
-	{ 0x001610,   1, 0x04, 0x00000012 },
-	{ 0x001608,   2, 0x04, 0x00000000 },
-	{ 0x00260c,   1, 0x04, 0x00000000 },
-	{ 0x0007ac,   1, 0x04, 0x00000000 },
-	{ 0x00162c,   1, 0x04, 0x00000003 },
-	{ 0x000210,   1, 0x04, 0x00000000 },
-	{ 0x000320,   1, 0x04, 0x00000000 },
-	{ 0x000324,   6, 0x04, 0x3f800000 },
-	{ 0x000750,   1, 0x04, 0x00000000 },
-	{ 0x000760,   1, 0x04, 0x39291909 },
-	{ 0x000764,   1, 0x04, 0x79695949 },
-	{ 0x000768,   1, 0x04, 0xb9a99989 },
-	{ 0x00076c,   1, 0x04, 0xf9e9d9c9 },
-	{ 0x000770,   1, 0x04, 0x30201000 },
-	{ 0x000774,   1, 0x04, 0x70605040 },
-	{ 0x000778,   1, 0x04, 0x00009080 },
-	{ 0x000780,   1, 0x04, 0x39291909 },
-	{ 0x000784,   1, 0x04, 0x79695949 },
-	{ 0x000788,   1, 0x04, 0xb9a99989 },
-	{ 0x00078c,   1, 0x04, 0xf9e9d9c9 },
-	{ 0x0007d0,   1, 0x04, 0x30201000 },
-	{ 0x0007d4,   1, 0x04, 0x70605040 },
-	{ 0x0007d8,   1, 0x04, 0x00009080 },
-	{ 0x00037c,   1, 0x04, 0x00000001 },
-	{ 0x000740,   2, 0x04, 0x00000000 },
-	{ 0x002600,   1, 0x04, 0x00000000 },
-	{ 0x001918,   1, 0x04, 0x00000000 },
-	{ 0x00191c,   1, 0x04, 0x00000900 },
-	{ 0x001920,   1, 0x04, 0x00000405 },
-	{ 0x001308,   1, 0x04, 0x00000001 },
-	{ 0x001924,   1, 0x04, 0x00000000 },
-	{ 0x0013ac,   1, 0x04, 0x00000000 },
-	{ 0x00192c,   1, 0x04, 0x00000001 },
-	{ 0x00193c,   1, 0x04, 0x00002c1c },
-	{ 0x000d7c,   1, 0x04, 0x00000000 },
-	{ 0x000f8c,   1, 0x04, 0x00000000 },
-	{ 0x0002c0,   1, 0x04, 0x00000001 },
-	{ 0x001510,   1, 0x04, 0x00000000 },
-	{ 0x001940,   1, 0x04, 0x00000000 },
-	{ 0x000ff4,   2, 0x04, 0x00000000 },
-	{ 0x00194c,   2, 0x04, 0x00000000 },
-	{ 0x001968,   1, 0x04, 0x00000000 },
-	{ 0x001590,   1, 0x04, 0x0000003f },
-	{ 0x0007e8,   4, 0x04, 0x00000000 },
-	{ 0x00196c,   1, 0x04, 0x00000011 },
-	{ 0x0002e4,   1, 0x04, 0x0000b001 },
-	{ 0x00036c,   2, 0x04, 0x00000000 },
-	{ 0x00197c,   1, 0x04, 0x00000000 },
-	{ 0x000fcc,   2, 0x04, 0x00000000 },
-	{ 0x0002d8,   1, 0x04, 0x00000040 },
-	{ 0x001980,   1, 0x04, 0x00000080 },
-	{ 0x001504,   1, 0x04, 0x00000080 },
-	{ 0x001984,   1, 0x04, 0x00000000 },
-	{ 0x000300,   1, 0x04, 0x00000001 },
-	{ 0x0013a8,   1, 0x04, 0x00000000 },
-	{ 0x0012ec,   1, 0x04, 0x00000000 },
-	{ 0x001310,   1, 0x04, 0x00000000 },
-	{ 0x001314,   1, 0x04, 0x00000001 },
-	{ 0x001380,   1, 0x04, 0x00000000 },
-	{ 0x001384,   4, 0x04, 0x00000001 },
-	{ 0x001394,   1, 0x04, 0x00000000 },
-	{ 0x00139c,   1, 0x04, 0x00000000 },
-	{ 0x001398,   1, 0x04, 0x00000000 },
-	{ 0x001594,   1, 0x04, 0x00000000 },
-	{ 0x001598,   4, 0x04, 0x00000001 },
-	{ 0x000f54,   3, 0x04, 0x00000000 },
-	{ 0x0019bc,   1, 0x04, 0x00000000 },
-	{ 0x000f9c,   2, 0x04, 0x00000000 },
-	{ 0x0012cc,   1, 0x04, 0x00000000 },
-	{ 0x0012e8,   1, 0x04, 0x00000000 },
-	{ 0x00130c,   1, 0x04, 0x00000001 },
-	{ 0x001360,   8, 0x04, 0x00000000 },
-	{ 0x00133c,   2, 0x04, 0x00000001 },
-	{ 0x001344,   1, 0x04, 0x00000002 },
-	{ 0x001348,   2, 0x04, 0x00000001 },
-	{ 0x001350,   1, 0x04, 0x00000002 },
-	{ 0x001358,   1, 0x04, 0x00000001 },
-	{ 0x0012e4,   1, 0x04, 0x00000000 },
-	{ 0x00131c,   4, 0x04, 0x00000000 },
-	{ 0x0019c0,   1, 0x04, 0x00000000 },
-	{ 0x001140,   1, 0x04, 0x00000000 },
-	{ 0x0019c4,   1, 0x04, 0x00000000 },
-	{ 0x0019c8,   1, 0x04, 0x00001500 },
-	{ 0x00135c,   1, 0x04, 0x00000000 },
-	{ 0x000f90,   1, 0x04, 0x00000000 },
-	{ 0x0019e0,   8, 0x04, 0x00000001 },
-	{ 0x0019cc,   1, 0x04, 0x00000001 },
-	{ 0x0015b8,   1, 0x04, 0x00000000 },
-	{ 0x001a00,   1, 0x04, 0x00001111 },
-	{ 0x001a04,   7, 0x04, 0x00000000 },
-	{ 0x000d6c,   2, 0x04, 0xffff0000 },
-	{ 0x0010f8,   1, 0x04, 0x00001010 },
-	{ 0x000d80,   5, 0x04, 0x00000000 },
-	{ 0x000da0,   1, 0x04, 0x00000000 },
-	{ 0x0007a4,   2, 0x04, 0x00000000 },
-	{ 0x001508,   1, 0x04, 0x80000000 },
-	{ 0x00150c,   1, 0x04, 0x40000000 },
-	{ 0x001668,   1, 0x04, 0x00000000 },
-	{ 0x000318,   2, 0x04, 0x00000008 },
-	{ 0x000d9c,   1, 0x04, 0x00000001 },
-	{ 0x000ddc,   1, 0x04, 0x00000002 },
-	{ 0x000374,   1, 0x04, 0x00000000 },
-	{ 0x000378,   1, 0x04, 0x00000020 },
-	{ 0x0007dc,   1, 0x04, 0x00000000 },
-	{ 0x00074c,   1, 0x04, 0x00000055 },
-	{ 0x001420,   1, 0x04, 0x00000003 },
-	{ 0x0017bc,   2, 0x04, 0x00000000 },
-	{ 0x0017c4,   1, 0x04, 0x00000001 },
-	{ 0x001008,   1, 0x04, 0x00000008 },
-	{ 0x00100c,   1, 0x04, 0x00000040 },
-	{ 0x001010,   1, 0x04, 0x0000012c },
-	{ 0x000d60,   1, 0x04, 0x00000040 },
-	{ 0x00075c,   1, 0x04, 0x00000003 },
-	{ 0x001018,   1, 0x04, 0x00000020 },
-	{ 0x00101c,   1, 0x04, 0x00000001 },
-	{ 0x001020,   1, 0x04, 0x00000020 },
-	{ 0x001024,   1, 0x04, 0x00000001 },
-	{ 0x001444,   3, 0x04, 0x00000000 },
-	{ 0x000360,   1, 0x04, 0x20164010 },
-	{ 0x000364,   1, 0x04, 0x00000020 },
-	{ 0x000368,   1, 0x04, 0x00000000 },
-	{ 0x000de4,   1, 0x04, 0x00000000 },
-	{ 0x000204,   1, 0x04, 0x00000006 },
-	{ 0x000208,   1, 0x04, 0x00000000 },
-	{ 0x0002cc,   2, 0x04, 0x003fffff },
-	{ 0x001220,   1, 0x04, 0x00000005 },
-	{ 0x000fdc,   1, 0x04, 0x00000000 },
-	{ 0x000f98,   1, 0x04, 0x00400008 },
-	{ 0x001284,   1, 0x04, 0x08000080 },
-	{ 0x001450,   1, 0x04, 0x00400008 },
-	{ 0x001454,   1, 0x04, 0x08000080 },
-	{ 0x000214,   1, 0x04, 0x00000000 },
+static const struct nvc0_graph_pack
+nv108_grctx_pack_icmd[] = {
+	{ nv108_grctx_init_icmd_0 },
 	{}
 };
 
-static struct nvc0_graph_init
-nv108_grctx_init_unk40xx[] = {
+static const struct nvc0_graph_init
+nv108_grctx_init_fe_0[] = {
 	{ 0x404004,   8, 0x04, 0x00000000 },
 	{ 0x404024,   1, 0x04, 0x0000e000 },
 	{ 0x404028,   8, 0x04, 0x00000000 },
@@ -1132,8 +311,8 @@ nv108_grctx_init_unk40xx[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nv108_grctx_init_unk58xx[] = {
+static const struct nvc0_graph_init
+nv108_grctx_init_ds_0[] = {
 	{ 0x405800,   1, 0x04, 0x0f8000bf },
 	{ 0x405830,   1, 0x04, 0x02180648 },
 	{ 0x405834,   1, 0x04, 0x08000000 },
@@ -1146,8 +325,10 @@ nv108_grctx_init_unk58xx[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nv108_grctx_init_unk64xx[] = {
+static const struct nvc0_graph_init
+nv108_grctx_init_pd_0[] = {
+	{ 0x406020,   1, 0x04, 0x034103c1 },
+	{ 0x406028,   4, 0x04, 0x00000001 },
 	{ 0x4064a8,   1, 0x04, 0x00000000 },
 	{ 0x4064ac,   1, 0x04, 0x00003fff },
 	{ 0x4064b0,   3, 0x04, 0x00000000 },
@@ -1159,8 +340,8 @@ nv108_grctx_init_unk64xx[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nv108_grctx_init_unk78xx[] = {
+const struct nvc0_graph_init
+nv108_grctx_init_rstr2d_0[] = {
 	{ 0x407804,   1, 0x04, 0x00000063 },
 	{ 0x40780c,   1, 0x04, 0x0a418820 },
 	{ 0x407810,   1, 0x04, 0x062080e6 },
@@ -1172,8 +353,8 @@ nv108_grctx_init_unk78xx[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nv108_grctx_init_unk88xx[] = {
+static const struct nvc0_graph_init
+nv108_grctx_init_be_0[] = {
 	{ 0x408800,   1, 0x04, 0x32802a3c },
 	{ 0x408804,   1, 0x04, 0x00000040 },
 	{ 0x408808,   1, 0x04, 0x1003e005 },
@@ -1185,9 +366,23 @@ nv108_grctx_init_unk88xx[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nv108_grctx_init_gpc_0[] = {
-	{ 0x418380,   1, 0x04, 0x00000016 },
+static const struct nvc0_graph_pack
+nv108_grctx_pack_hub[] = {
+	{ nvc0_grctx_init_main_0 },
+	{ nv108_grctx_init_fe_0 },
+	{ nvf0_grctx_init_pri_0 },
+	{ nve4_grctx_init_memfmt_0 },
+	{ nv108_grctx_init_ds_0 },
+	{ nvf0_grctx_init_cwd_0 },
+	{ nv108_grctx_init_pd_0 },
+	{ nv108_grctx_init_rstr2d_0 },
+	{ nve4_grctx_init_scc_0 },
+	{ nv108_grctx_init_be_0 },
+	{}
+};
+
+const struct nvc0_graph_init
+nv108_grctx_init_prop_0[] = {
 	{ 0x418400,   1, 0x04, 0x38005e00 },
 	{ 0x418404,   1, 0x04, 0x71e0ffff },
 	{ 0x41840c,   1, 0x04, 0x00001008 },
@@ -1196,11 +391,21 @@ nv108_grctx_init_gpc_0[] = {
 	{ 0x418450,   6, 0x04, 0x00000000 },
 	{ 0x418468,   1, 0x04, 0x00000001 },
 	{ 0x41846c,   2, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nv108_grctx_init_gpc_unk_1[] = {
 	{ 0x418600,   1, 0x04, 0x0000007f },
 	{ 0x418684,   1, 0x04, 0x0000001f },
 	{ 0x418700,   1, 0x04, 0x00000002 },
 	{ 0x418704,   2, 0x04, 0x00000080 },
 	{ 0x41870c,   2, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nv108_grctx_init_setup_0[] = {
 	{ 0x418800,   1, 0x04, 0x7006863a },
 	{ 0x418808,   1, 0x04, 0x00000000 },
 	{ 0x41880c,   1, 0x04, 0x00000030 },
@@ -1211,10 +416,11 @@ nv108_grctx_init_gpc_0[] = {
 	{ 0x4188e0,   1, 0x04, 0x01000000 },
 	{ 0x4188e8,   5, 0x04, 0x00000000 },
 	{ 0x4188fc,   1, 0x04, 0x20100058 },
-	{ 0x41891c,   1, 0x04, 0x00ff00ff },
-	{ 0x418924,   1, 0x04, 0x00000000 },
-	{ 0x418928,   1, 0x04, 0x00ffff00 },
-	{ 0x41892c,   1, 0x04, 0x0000ff00 },
+	{}
+};
+
+const struct nvc0_graph_init
+nv108_grctx_init_crstr_0[] = {
 	{ 0x418b00,   1, 0x04, 0x0000001e },
 	{ 0x418b08,   1, 0x04, 0x0a418820 },
 	{ 0x418b0c,   1, 0x04, 0x062080e6 },
@@ -1223,24 +429,36 @@ nv108_grctx_init_gpc_0[] = {
 	{ 0x418b18,   1, 0x04, 0x0a418820 },
 	{ 0x418b1c,   1, 0x04, 0x000000e6 },
 	{ 0x418bb8,   1, 0x04, 0x00000103 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nv108_grctx_init_gpm_0[] = {
 	{ 0x418c08,   1, 0x04, 0x00000001 },
 	{ 0x418c10,   8, 0x04, 0x00000000 },
 	{ 0x418c40,   1, 0x04, 0xffffffff },
 	{ 0x418c6c,   1, 0x04, 0x00000001 },
 	{ 0x418c80,   1, 0x04, 0x2020000c },
 	{ 0x418c8c,   1, 0x04, 0x00000001 },
-	{ 0x418d24,   1, 0x04, 0x00000000 },
-	{ 0x419000,   1, 0x04, 0x00000780 },
-	{ 0x419004,   2, 0x04, 0x00000000 },
-	{ 0x419014,   1, 0x04, 0x00000004 },
 	{}
 };
 
-static struct nvc0_graph_init
-nv108_grctx_init_tpc[] = {
-	{ 0x419848,   1, 0x04, 0x00000000 },
-	{ 0x419864,   1, 0x04, 0x00000129 },
-	{ 0x419888,   1, 0x04, 0x00000000 },
+static const struct nvc0_graph_pack
+nv108_grctx_pack_gpc[] = {
+	{ nvc0_grctx_init_gpc_unk_0 },
+	{ nv108_grctx_init_prop_0 },
+	{ nv108_grctx_init_gpc_unk_1 },
+	{ nv108_grctx_init_setup_0 },
+	{ nvc0_grctx_init_zcull_0 },
+	{ nv108_grctx_init_crstr_0 },
+	{ nv108_grctx_init_gpm_0 },
+	{ nvf0_grctx_init_gpc_unk_2 },
+	{ nvc0_grctx_init_gcc_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nv108_grctx_init_tex_0[] = {
 	{ 0x419a00,   1, 0x04, 0x000100f0 },
 	{ 0x419a04,   1, 0x04, 0x00000001 },
 	{ 0x419a08,   1, 0x04, 0x00000421 },
@@ -1251,14 +469,11 @@ nv108_grctx_init_tpc[] = {
 	{ 0x419a20,   1, 0x04, 0x00000800 },
 	{ 0x419a30,   1, 0x04, 0x00000001 },
 	{ 0x419ac4,   1, 0x04, 0x0037f440 },
-	{ 0x419c00,   1, 0x04, 0x0000001a },
-	{ 0x419c04,   1, 0x04, 0x80000006 },
-	{ 0x419c08,   1, 0x04, 0x00000002 },
-	{ 0x419c20,   1, 0x04, 0x00000000 },
-	{ 0x419c24,   1, 0x04, 0x00084210 },
-	{ 0x419c28,   1, 0x04, 0x3efbefbe },
-	{ 0x419ce8,   1, 0x04, 0x00000000 },
-	{ 0x419cf4,   1, 0x04, 0x00000203 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nv108_grctx_init_sm_0[] = {
 	{ 0x419e04,   1, 0x04, 0x00000000 },
 	{ 0x419e08,   1, 0x04, 0x0000001d },
 	{ 0x419e0c,   1, 0x04, 0x00000000 },
@@ -1272,7 +487,7 @@ nv108_grctx_init_tpc[] = {
 	{ 0x419e68,   1, 0x04, 0x00000002 },
 	{ 0x419e6c,  12, 0x04, 0x00000000 },
 	{ 0x419eac,   1, 0x04, 0x00001f8f },
-	{ 0x419eb0,   1, 0x04, 0x0db00da0 },
+	{ 0x419eb0,   1, 0x04, 0x0db00d2f },
 	{ 0x419eb8,   1, 0x04, 0x00000000 },
 	{ 0x419ec8,   1, 0x04, 0x0001304f },
 	{ 0x419f30,   4, 0x04, 0x00000000 },
@@ -1285,25 +500,37 @@ nv108_grctx_init_tpc[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nv108_grctx_init_unk[] = {
-	{ 0x41be24,   1, 0x04, 0x00000006 },
+static const struct nvc0_graph_pack
+nv108_grctx_pack_tpc[] = {
+	{ nvd7_grctx_init_pe_0 },
+	{ nv108_grctx_init_tex_0 },
+	{ nvf0_grctx_init_mpc_0 },
+	{ nvf0_grctx_init_l1c_0 },
+	{ nv108_grctx_init_sm_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nv108_grctx_init_cbm_0[] = {
 	{ 0x41bec0,   1, 0x04, 0x10000000 },
 	{ 0x41bec4,   1, 0x04, 0x00037f7f },
 	{ 0x41bee4,   1, 0x04, 0x00000000 },
 	{ 0x41bef0,   1, 0x04, 0x000003ff },
-	{ 0x41bf00,   1, 0x04, 0x0a418820 },
-	{ 0x41bf04,   1, 0x04, 0x062080e6 },
-	{ 0x41bf08,   1, 0x04, 0x020398a4 },
-	{ 0x41bf0c,   1, 0x04, 0x0e629062 },
-	{ 0x41bf10,   1, 0x04, 0x0a418820 },
-	{ 0x41bf14,   1, 0x04, 0x000000e6 },
-	{ 0x41bfd0,   1, 0x04, 0x00900103 },
-	{ 0x41bfe0,   1, 0x04, 0x00400001 },
-	{ 0x41bfe4,   1, 0x04, 0x00000000 },
 	{}
 };
 
+static const struct nvc0_graph_pack
+nv108_grctx_pack_ppc[] = {
+	{ nve4_grctx_init_pes_0 },
+	{ nv108_grctx_init_cbm_0 },
+	{ nvd7_grctx_init_wwdx_0 },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH context implementation
+ ******************************************************************************/
+
 static void
 nv108_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
 {
@@ -1346,47 +573,6 @@ nv108_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
 	mmio_list(0x17e920, 0x00090d08, 0, 0);
 }
 
-static struct nvc0_graph_init *
-nv108_grctx_init_hub[] = {
-	nvc0_grctx_init_base,
-	nv108_grctx_init_unk40xx,
-	nvf0_grctx_init_unk44xx,
-	nve4_grctx_init_unk46xx,
-	nve4_grctx_init_unk47xx,
-	nv108_grctx_init_unk58xx,
-	nvf0_grctx_init_unk5bxx,
-	nvf0_grctx_init_unk60xx,
-	nv108_grctx_init_unk64xx,
-	nv108_grctx_init_unk78xx,
-	nve4_grctx_init_unk80xx,
-	nv108_grctx_init_unk88xx,
-	NULL
-};
-
-struct nvc0_graph_init *
-nv108_grctx_init_gpc[] = {
-	nv108_grctx_init_gpc_0,
-	nvc0_grctx_init_gpc_1,
-	nv108_grctx_init_tpc,
-	nv108_grctx_init_unk,
-	NULL
-};
-
-struct nvc0_graph_init
-nv108_grctx_init_mthd_magic[] = {
-	{ 0x3410, 1, 0x04, 0x8e0e2006 },
-	{ 0x3414, 1, 0x04, 0x00000038 },
-	{}
-};
-
-static struct nvc0_graph_mthd
-nv108_grctx_init_mthd[] = {
-	{ 0xa197, nv108_grctx_init_a197, },
-	{ 0x902d, nvc0_grctx_init_902d, },
-	{ 0x902d, nv108_grctx_init_mthd_magic, },
-	{}
-};
-
 struct nouveau_oclass *
 nv108_grctx_oclass = &(struct nvc0_grctx_oclass) {
 	.base.handle = NV_ENGCTX(GR, 0x08),
@@ -1398,11 +584,14 @@ nv108_grctx_oclass = &(struct nvc0_grctx_oclass) {
 		.rd32 = _nouveau_graph_context_rd32,
 		.wr32 = _nouveau_graph_context_wr32,
 	},
-	.main = nve4_grctx_generate_main,
-	.mods = nv108_grctx_generate_mods,
-	.unkn = nve4_grctx_generate_unkn,
-	.hub  = nv108_grctx_init_hub,
-	.gpc  = nv108_grctx_init_gpc,
-	.icmd = nv108_grctx_init_icmd,
-	.mthd = nv108_grctx_init_mthd,
+	.main  = nve4_grctx_generate_main,
+	.mods  = nv108_grctx_generate_mods,
+	.unkn  = nve4_grctx_generate_unkn,
+	.hub   = nv108_grctx_pack_hub,
+	.gpc   = nv108_grctx_pack_gpc,
+	.zcull = nvc0_grctx_pack_zcull,
+	.tpc   = nv108_grctx_pack_tpc,
+	.ppc   = nv108_grctx_pack_ppc,
+	.icmd  = nv108_grctx_pack_icmd,
+	.mthd  = nvf0_grctx_pack_mthd,
 }.base;

+ 192 - 116
drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c

@@ -22,10 +22,14 @@
  * Authors: Ben Skeggs
  */
 
-#include "nvc0.h"
+#include "ctxnvc0.h"
 
-struct nvc0_graph_init
-nvc0_grctx_init_icmd[] = {
+/*******************************************************************************
+ * PGRAPH context register lists
+ ******************************************************************************/
+
+static const struct nvc0_graph_init
+nvc0_grctx_init_icmd_0[] = {
 	{ 0x001000,   1, 0x01, 0x00000004 },
 	{ 0x0000a9,   1, 0x01, 0x0000ffff },
 	{ 0x000038,   1, 0x01, 0x0fac6881 },
@@ -140,8 +144,7 @@ nvc0_grctx_init_icmd[] = {
 	{ 0x000586,   1, 0x01, 0x00000040 },
 	{ 0x000582,   2, 0x01, 0x00000080 },
 	{ 0x0005c2,   1, 0x01, 0x00000001 },
-	{ 0x000638,   1, 0x01, 0x00000001 },
-	{ 0x000639,   1, 0x01, 0x00000001 },
+	{ 0x000638,   2, 0x01, 0x00000001 },
 	{ 0x00063a,   1, 0x01, 0x00000002 },
 	{ 0x00063b,   2, 0x01, 0x00000001 },
 	{ 0x00063d,   1, 0x01, 0x00000002 },
@@ -201,15 +204,13 @@ nvc0_grctx_init_icmd[] = {
 	{ 0x000787,   1, 0x01, 0x000000cf },
 	{ 0x00078c,   1, 0x01, 0x00000008 },
 	{ 0x000792,   1, 0x01, 0x00000001 },
-	{ 0x000794,   1, 0x01, 0x00000001 },
-	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000794,   3, 0x01, 0x00000001 },
 	{ 0x000797,   1, 0x01, 0x000000cf },
 	{ 0x000836,   1, 0x01, 0x00000001 },
 	{ 0x00079a,   1, 0x01, 0x00000002 },
 	{ 0x000833,   1, 0x01, 0x04444480 },
 	{ 0x0007a1,   1, 0x01, 0x00000001 },
-	{ 0x0007a3,   1, 0x01, 0x00000001 },
-	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x0007a3,   3, 0x01, 0x00000001 },
 	{ 0x000831,   1, 0x01, 0x00000004 },
 	{ 0x00080c,   1, 0x01, 0x00000002 },
 	{ 0x00080d,   2, 0x01, 0x00000100 },
@@ -235,14 +236,12 @@ nvc0_grctx_init_icmd[] = {
 	{ 0x0006b1,   1, 0x01, 0x00000011 },
 	{ 0x00078c,   1, 0x01, 0x00000008 },
 	{ 0x000792,   1, 0x01, 0x00000001 },
-	{ 0x000794,   1, 0x01, 0x00000001 },
-	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000794,   3, 0x01, 0x00000001 },
 	{ 0x000797,   1, 0x01, 0x000000cf },
 	{ 0x00079a,   1, 0x01, 0x00000002 },
 	{ 0x000833,   1, 0x01, 0x04444480 },
 	{ 0x0007a1,   1, 0x01, 0x00000001 },
-	{ 0x0007a3,   1, 0x01, 0x00000001 },
-	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x0007a3,   3, 0x01, 0x00000001 },
 	{ 0x000831,   1, 0x01, 0x00000004 },
 	{ 0x01e100,   1, 0x01, 0x00000001 },
 	{ 0x001000,   1, 0x01, 0x00000014 },
@@ -267,8 +266,14 @@ nvc0_grctx_init_icmd[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_grctx_init_9097[] = {
+const struct nvc0_graph_pack
+nvc0_grctx_pack_icmd[] = {
+	{ nvc0_grctx_init_icmd_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvc0_grctx_init_9097_0[] = {
 	{ 0x000800,   8, 0x40, 0x00000000 },
 	{ 0x000804,   8, 0x40, 0x00000000 },
 	{ 0x000808,   8, 0x40, 0x00000400 },
@@ -516,8 +521,7 @@ nvc0_grctx_init_9097[] = {
 	{ 0x001350,   1, 0x04, 0x00000002 },
 	{ 0x001358,   1, 0x04, 0x00000001 },
 	{ 0x0012e4,   1, 0x04, 0x00000000 },
-	{ 0x00131c,   1, 0x04, 0x00000000 },
-	{ 0x001320,   3, 0x04, 0x00000000 },
+	{ 0x00131c,   4, 0x04, 0x00000000 },
 	{ 0x0019c0,   1, 0x04, 0x00000000 },
 	{ 0x001140,   1, 0x04, 0x00000000 },
 	{ 0x0019c4,   1, 0x04, 0x00000000 },
@@ -571,8 +575,8 @@ nvc0_grctx_init_9097[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_grctx_init_902d[] = {
+const struct nvc0_graph_init
+nvc0_grctx_init_902d_0[] = {
 	{ 0x000200,   1, 0x04, 0x000000cf },
 	{ 0x000204,   1, 0x04, 0x00000001 },
 	{ 0x000208,   1, 0x04, 0x00000020 },
@@ -590,8 +594,8 @@ nvc0_grctx_init_902d[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_grctx_init_9039[] = {
+const struct nvc0_graph_init
+nvc0_grctx_init_9039_0[] = {
 	{ 0x00030c,   3, 0x04, 0x00000000 },
 	{ 0x000320,   1, 0x04, 0x00000000 },
 	{ 0x000238,   2, 0x04, 0x00000000 },
@@ -599,8 +603,8 @@ nvc0_grctx_init_9039[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_grctx_init_90c0[] = {
+const struct nvc0_graph_init
+nvc0_grctx_init_90c0_0[] = {
 	{ 0x00270c,   8, 0x20, 0x00000000 },
 	{ 0x00030c,   1, 0x04, 0x00000001 },
 	{ 0x001944,   1, 0x04, 0x00000000 },
@@ -617,38 +621,44 @@ nvc0_grctx_init_90c0[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_grctx_init_base[] = {
+const struct nvc0_graph_pack
+nvc0_grctx_pack_mthd[] = {
+	{ nvc0_grctx_init_9097_0, 0x9097 },
+	{ nvc0_grctx_init_902d_0, 0x902d },
+	{ nvc0_grctx_init_9039_0, 0x9039 },
+	{ nvc0_grctx_init_90c0_0, 0x90c0 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_grctx_init_main_0[] = {
 	{ 0x400204,   2, 0x04, 0x00000000 },
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_grctx_init_unk40xx[] = {
-	{ 0x404004,  10, 0x04, 0x00000000 },
+const struct nvc0_graph_init
+nvc0_grctx_init_fe_0[] = {
+	{ 0x404004,  11, 0x04, 0x00000000 },
 	{ 0x404044,   1, 0x04, 0x00000000 },
-	{ 0x404094,   1, 0x04, 0x00000000 },
-	{ 0x404098,  12, 0x04, 0x00000000 },
+	{ 0x404094,  13, 0x04, 0x00000000 },
 	{ 0x4040c8,   1, 0x04, 0xf0000087 },
 	{ 0x4040d0,   6, 0x04, 0x00000000 },
 	{ 0x4040e8,   1, 0x04, 0x00001000 },
 	{ 0x4040f8,   1, 0x04, 0x00000000 },
-	{ 0x404130,   1, 0x04, 0x00000000 },
-	{ 0x404134,   1, 0x04, 0x00000000 },
+	{ 0x404130,   2, 0x04, 0x00000000 },
 	{ 0x404138,   1, 0x04, 0x20000040 },
 	{ 0x404150,   1, 0x04, 0x0000002e },
 	{ 0x404154,   1, 0x04, 0x00000400 },
 	{ 0x404158,   1, 0x04, 0x00000200 },
 	{ 0x404164,   1, 0x04, 0x00000055 },
 	{ 0x404168,   1, 0x04, 0x00000000 },
-	{ 0x404174,   1, 0x04, 0x00000000 },
-	{ 0x404178,   2, 0x04, 0x00000000 },
+	{ 0x404174,   3, 0x04, 0x00000000 },
 	{ 0x404200,   8, 0x04, 0x00000000 },
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_grctx_init_unk44xx[] = {
+const struct nvc0_graph_init
+nvc0_grctx_init_pri_0[] = {
 	{ 0x404404,  14, 0x04, 0x00000000 },
 	{ 0x404460,   2, 0x04, 0x00000000 },
 	{ 0x404468,   1, 0x04, 0x00ffffff },
@@ -658,8 +668,8 @@ nvc0_grctx_init_unk44xx[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_grctx_init_unk46xx[] = {
+const struct nvc0_graph_init
+nvc0_grctx_init_memfmt_0[] = {
 	{ 0x404604,   1, 0x04, 0x00000015 },
 	{ 0x404608,   1, 0x04, 0x00000000 },
 	{ 0x40460c,   1, 0x04, 0x00002e00 },
@@ -674,19 +684,14 @@ nvc0_grctx_init_unk46xx[] = {
 	{ 0x4046a0,   1, 0x04, 0x007f0080 },
 	{ 0x4046a4,  18, 0x04, 0x00000000 },
 	{ 0x4046f0,   2, 0x04, 0x00000000 },
-	{}
-};
-
-struct nvc0_graph_init
-nvc0_grctx_init_unk47xx[] = {
 	{ 0x404700,  13, 0x04, 0x00000000 },
 	{ 0x404734,   1, 0x04, 0x00000100 },
 	{ 0x404738,   8, 0x04, 0x00000000 },
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_grctx_init_unk58xx[] = {
+static const struct nvc0_graph_init
+nvc0_grctx_init_ds_0[] = {
 	{ 0x405800,   1, 0x04, 0x078000bf },
 	{ 0x405830,   1, 0x04, 0x02180000 },
 	{ 0x405834,   2, 0x04, 0x00000000 },
@@ -697,23 +702,18 @@ nvc0_grctx_init_unk58xx[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_grctx_init_unk60xx[] = {
+static const struct nvc0_graph_init
+nvc0_grctx_init_pd_0[] = {
 	{ 0x406020,   1, 0x04, 0x000103c1 },
 	{ 0x406028,   4, 0x04, 0x00000001 },
-	{}
-};
-
-struct nvc0_graph_init
-nvc0_grctx_init_unk64xx[] = {
 	{ 0x4064a8,   1, 0x04, 0x00000000 },
 	{ 0x4064ac,   1, 0x04, 0x00003fff },
 	{ 0x4064b4,   2, 0x04, 0x00000000 },
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_grctx_init_unk78xx[] = {
+const struct nvc0_graph_init
+nvc0_grctx_init_rstr2d_0[] = {
 	{ 0x407804,   1, 0x04, 0x00000023 },
 	{ 0x40780c,   1, 0x04, 0x0a418820 },
 	{ 0x407810,   1, 0x04, 0x062080e6 },
@@ -725,8 +725,8 @@ nvc0_grctx_init_unk78xx[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_grctx_init_unk80xx[] = {
+const struct nvc0_graph_init
+nvc0_grctx_init_scc_0[] = {
 	{ 0x408000,   2, 0x04, 0x00000000 },
 	{ 0x408008,   1, 0x04, 0x00000018 },
 	{ 0x40800c,   2, 0x04, 0x00000000 },
@@ -736,8 +736,8 @@ nvc0_grctx_init_unk80xx[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_grctx_init_rop[] = {
+static const struct nvc0_graph_init
+nvc0_grctx_init_be_0[] = {
 	{ 0x408800,   1, 0x04, 0x02802a3c },
 	{ 0x408804,   1, 0x04, 0x00000040 },
 	{ 0x408808,   1, 0x04, 0x0003e00d },
@@ -748,9 +748,28 @@ nvc0_grctx_init_rop[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_grctx_init_gpc_0[] = {
+const struct nvc0_graph_pack
+nvc0_grctx_pack_hub[] = {
+	{ nvc0_grctx_init_main_0 },
+	{ nvc0_grctx_init_fe_0 },
+	{ nvc0_grctx_init_pri_0 },
+	{ nvc0_grctx_init_memfmt_0 },
+	{ nvc0_grctx_init_ds_0 },
+	{ nvc0_grctx_init_pd_0 },
+	{ nvc0_grctx_init_rstr2d_0 },
+	{ nvc0_grctx_init_scc_0 },
+	{ nvc0_grctx_init_be_0 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_grctx_init_gpc_unk_0[] = {
 	{ 0x418380,   1, 0x04, 0x00000016 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_grctx_init_prop_0[] = {
 	{ 0x418400,   1, 0x04, 0x38004e00 },
 	{ 0x418404,   1, 0x04, 0x71e0ffff },
 	{ 0x418408,   1, 0x04, 0x00000000 },
@@ -760,6 +779,11 @@ nvc0_grctx_init_gpc_0[] = {
 	{ 0x418450,   6, 0x04, 0x00000000 },
 	{ 0x418468,   1, 0x04, 0x00000001 },
 	{ 0x41846c,   2, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_grctx_init_gpc_unk_1[] = {
 	{ 0x418600,   1, 0x04, 0x0000001f },
 	{ 0x418684,   1, 0x04, 0x0000000f },
 	{ 0x418700,   1, 0x04, 0x00000002 },
@@ -767,6 +791,11 @@ nvc0_grctx_init_gpc_0[] = {
 	{ 0x418708,   1, 0x04, 0x00000000 },
 	{ 0x41870c,   1, 0x04, 0x07c80000 },
 	{ 0x418710,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvc0_grctx_init_setup_0[] = {
 	{ 0x418800,   1, 0x04, 0x0006860a },
 	{ 0x418808,   3, 0x04, 0x00000000 },
 	{ 0x418828,   1, 0x04, 0x00008442 },
@@ -775,10 +804,20 @@ nvc0_grctx_init_gpc_0[] = {
 	{ 0x4188e0,   1, 0x04, 0x01000000 },
 	{ 0x4188e8,   5, 0x04, 0x00000000 },
 	{ 0x4188fc,   1, 0x04, 0x00100000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_grctx_init_zcull_0[] = {
 	{ 0x41891c,   1, 0x04, 0x00ff00ff },
 	{ 0x418924,   1, 0x04, 0x00000000 },
 	{ 0x418928,   1, 0x04, 0x00ffff00 },
 	{ 0x41892c,   1, 0x04, 0x0000ff00 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_grctx_init_crstr_0[] = {
 	{ 0x418b00,   1, 0x04, 0x00000000 },
 	{ 0x418b08,   1, 0x04, 0x0a418820 },
 	{ 0x418b0c,   1, 0x04, 0x062080e6 },
@@ -787,18 +826,41 @@ nvc0_grctx_init_gpc_0[] = {
 	{ 0x418b18,   1, 0x04, 0x0a418820 },
 	{ 0x418b1c,   1, 0x04, 0x000000e6 },
 	{ 0x418bb8,   1, 0x04, 0x00000103 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_grctx_init_gpm_0[] = {
 	{ 0x418c08,   1, 0x04, 0x00000001 },
 	{ 0x418c10,   8, 0x04, 0x00000000 },
 	{ 0x418c80,   1, 0x04, 0x20200004 },
 	{ 0x418c8c,   1, 0x04, 0x00000001 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_grctx_init_gcc_0[] = {
 	{ 0x419000,   1, 0x04, 0x00000780 },
 	{ 0x419004,   2, 0x04, 0x00000000 },
 	{ 0x419014,   1, 0x04, 0x00000004 },
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_grctx_init_gpc_1[] = {
+const struct nvc0_graph_pack
+nvc0_grctx_pack_gpc[] = {
+	{ nvc0_grctx_init_gpc_unk_0 },
+	{ nvc0_grctx_init_prop_0 },
+	{ nvc0_grctx_init_gpc_unk_1 },
+	{ nvc0_grctx_init_setup_0 },
+	{ nvc0_grctx_init_zcull_0 },
+	{ nvc0_grctx_init_crstr_0 },
+	{ nvc0_grctx_init_gpm_0 },
+	{ nvc0_grctx_init_gcc_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvc0_grctx_init_zcullr_0[] = {
 	{ 0x418a00,   3, 0x04, 0x00000000 },
 	{ 0x418a0c,   1, 0x04, 0x00010000 },
 	{ 0x418a10,   3, 0x04, 0x00000000 },
@@ -826,19 +888,35 @@ nvc0_grctx_init_gpc_1[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_grctx_init_tpc[] = {
+const struct nvc0_graph_pack
+nvc0_grctx_pack_zcull[] = {
+	{ nvc0_grctx_init_zcullr_0 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_grctx_init_pe_0[] = {
 	{ 0x419818,   1, 0x04, 0x00000000 },
 	{ 0x41983c,   1, 0x04, 0x00038bc7 },
 	{ 0x419848,   1, 0x04, 0x00000000 },
 	{ 0x419864,   1, 0x04, 0x0000012a },
 	{ 0x419888,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvc0_grctx_init_tex_0[] = {
 	{ 0x419a00,   1, 0x04, 0x000001f0 },
 	{ 0x419a04,   1, 0x04, 0x00000001 },
 	{ 0x419a08,   1, 0x04, 0x00000023 },
 	{ 0x419a0c,   1, 0x04, 0x00020000 },
 	{ 0x419a10,   1, 0x04, 0x00000000 },
 	{ 0x419a14,   1, 0x04, 0x00000200 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_grctx_init_wwdx_0[] = {
 	{ 0x419b00,   1, 0x04, 0x0a418820 },
 	{ 0x419b04,   1, 0x04, 0x062080e6 },
 	{ 0x419b08,   1, 0x04, 0x020398a4 },
@@ -848,15 +926,35 @@ nvc0_grctx_init_tpc[] = {
 	{ 0x419bd0,   1, 0x04, 0x00900103 },
 	{ 0x419be0,   1, 0x04, 0x00000001 },
 	{ 0x419be4,   1, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_grctx_init_mpc_0[] = {
 	{ 0x419c00,   1, 0x04, 0x00000002 },
 	{ 0x419c04,   1, 0x04, 0x00000006 },
 	{ 0x419c08,   1, 0x04, 0x00000002 },
 	{ 0x419c20,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvc0_grctx_init_l1c_0[] = {
 	{ 0x419cb0,   1, 0x04, 0x00060048 },
 	{ 0x419ce8,   1, 0x04, 0x00000000 },
 	{ 0x419cf4,   1, 0x04, 0x00000183 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_grctx_init_tpccs_0[] = {
 	{ 0x419d20,   1, 0x04, 0x02180000 },
 	{ 0x419d24,   1, 0x04, 0x00001fff },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvc0_grctx_init_sm_0[] = {
 	{ 0x419e04,   3, 0x04, 0x00000000 },
 	{ 0x419e10,   1, 0x04, 0x00000002 },
 	{ 0x419e44,   1, 0x04, 0x001beff2 },
@@ -868,6 +966,22 @@ nvc0_grctx_init_tpc[] = {
 	{}
 };
 
+const struct nvc0_graph_pack
+nvc0_grctx_pack_tpc[] = {
+	{ nvc0_grctx_init_pe_0 },
+	{ nvc0_grctx_init_tex_0 },
+	{ nvc0_grctx_init_wwdx_0 },
+	{ nvc0_grctx_init_mpc_0 },
+	{ nvc0_grctx_init_l1c_0 },
+	{ nvc0_grctx_init_tpccs_0 },
+	{ nvc0_grctx_init_sm_0 },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH context implementation
+ ******************************************************************************/
+
 void
 nvc0_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
 {
@@ -1055,14 +1169,14 @@ void
 nvc0_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
 {
 	struct nvc0_grctx_oclass *oclass = (void *)nv_engine(priv)->cclass;
-	int i;
 
 	nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
 
-	for (i = 0; oclass->hub[i]; i++)
-		nvc0_graph_mmio(priv, oclass->hub[i]);
-	for (i = 0; oclass->gpc[i]; i++)
-		nvc0_graph_mmio(priv, oclass->gpc[i]);
+	nvc0_graph_mmio(priv, oclass->hub);
+	nvc0_graph_mmio(priv, oclass->gpc);
+	nvc0_graph_mmio(priv, oclass->zcull);
+	nvc0_graph_mmio(priv, oclass->tpc);
+	nvc0_graph_mmio(priv, oclass->ppc);
 
 	nv_wr32(priv, 0x404154, 0x00000000);
 
@@ -1182,46 +1296,6 @@ done:
 	return ret;
 }
 
-struct nvc0_graph_init *
-nvc0_grctx_init_hub[] = {
-	nvc0_grctx_init_base,
-	nvc0_grctx_init_unk40xx,
-	nvc0_grctx_init_unk44xx,
-	nvc0_grctx_init_unk46xx,
-	nvc0_grctx_init_unk47xx,
-	nvc0_grctx_init_unk58xx,
-	nvc0_grctx_init_unk60xx,
-	nvc0_grctx_init_unk64xx,
-	nvc0_grctx_init_unk78xx,
-	nvc0_grctx_init_unk80xx,
-	nvc0_grctx_init_rop,
-	NULL
-};
-
-static struct nvc0_graph_init *
-nvc0_grctx_init_gpc[] = {
-	nvc0_grctx_init_gpc_0,
-	nvc0_grctx_init_gpc_1,
-	nvc0_grctx_init_tpc,
-	NULL
-};
-
-struct nvc0_graph_init
-nvc0_grctx_init_mthd_magic[] = {
-	{ 0x3410, 1, 0x04, 0x00000000 },
-	{}
-};
-
-struct nvc0_graph_mthd
-nvc0_grctx_init_mthd[] = {
-	{ 0x9097, nvc0_grctx_init_9097, },
-	{ 0x902d, nvc0_grctx_init_902d, },
-	{ 0x9039, nvc0_grctx_init_9039, },
-	{ 0x90c0, nvc0_grctx_init_90c0, },
-	{ 0x902d, nvc0_grctx_init_mthd_magic, },
-	{}
-};
-
 struct nouveau_oclass *
 nvc0_grctx_oclass = &(struct nvc0_grctx_oclass) {
 	.base.handle = NV_ENGCTX(GR, 0xc0),
@@ -1233,11 +1307,13 @@ nvc0_grctx_oclass = &(struct nvc0_grctx_oclass) {
 		.rd32 = _nouveau_graph_context_rd32,
 		.wr32 = _nouveau_graph_context_wr32,
 	},
-	.main = nvc0_grctx_generate_main,
-	.mods = nvc0_grctx_generate_mods,
-	.unkn = nvc0_grctx_generate_unkn,
-	.hub  = nvc0_grctx_init_hub,
-	.gpc  = nvc0_grctx_init_gpc,
-	.icmd = nvc0_grctx_init_icmd,
-	.mthd = nvc0_grctx_init_mthd,
+	.main  = nvc0_grctx_generate_main,
+	.mods  = nvc0_grctx_generate_mods,
+	.unkn  = nvc0_grctx_generate_unkn,
+	.hub   = nvc0_grctx_pack_hub,
+	.gpc   = nvc0_grctx_pack_gpc,
+	.zcull = nvc0_grctx_pack_zcull,
+	.tpc   = nvc0_grctx_pack_tpc,
+	.icmd  = nvc0_grctx_pack_icmd,
+	.mthd  = nvc0_grctx_pack_mthd,
 }.base;

+ 170 - 0
drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h

@@ -0,0 +1,170 @@
+#ifndef __NVKM_GRCTX_NVC0_H__
+#define __NVKM_GRCTX_NVC0_H__
+
+#include "nvc0.h"
+
+struct nvc0_grctx {
+	struct nvc0_graph_priv *priv;
+	struct nvc0_graph_data *data;
+	struct nvc0_graph_mmio *mmio;
+	int buffer_nr;
+	u64 buffer[4];
+	u64 addr;
+};
+
+struct nvc0_grctx_oclass {
+	struct nouveau_oclass base;
+	/* main context generation function */
+	void  (*main)(struct nvc0_graph_priv *, struct nvc0_grctx *);
+	/* context-specific modify-on-first-load list generation function */
+	void  (*mods)(struct nvc0_graph_priv *, struct nvc0_grctx *);
+	void  (*unkn)(struct nvc0_graph_priv *);
+	/* mmio context data */
+	const struct nvc0_graph_pack *hub;
+	const struct nvc0_graph_pack *gpc;
+	const struct nvc0_graph_pack *zcull;
+	const struct nvc0_graph_pack *tpc;
+	const struct nvc0_graph_pack *ppc;
+	/* indirect context data, generated with icmds/mthds */
+	const struct nvc0_graph_pack *icmd;
+	const struct nvc0_graph_pack *mthd;
+};
+
+#define mmio_data(s,a,p) do {                                                  \
+	info->buffer[info->buffer_nr] = round_up(info->addr, (a));             \
+	info->addr = info->buffer[info->buffer_nr++] + (s);                    \
+	info->data->size = (s);                                                \
+	info->data->align = (a);                                               \
+	info->data->access = (p);                                              \
+	info->data++;                                                          \
+} while(0)
+
+#define mmio_list(r,d,s,b) do {                                                \
+	info->mmio->addr = (r);                                                \
+	info->mmio->data = (d);                                                \
+	info->mmio->shift = (s);                                               \
+	info->mmio->buffer = (b);                                              \
+	info->mmio++;                                                          \
+	nv_wr32(priv, (r), (d) | ((s) ? (info->buffer[(b)] >> (s)) : 0));      \
+} while(0)
+
+extern struct nouveau_oclass *nvc0_grctx_oclass;
+int  nvc0_grctx_generate(struct nvc0_graph_priv *);
+void nvc0_grctx_generate_main(struct nvc0_graph_priv *, struct nvc0_grctx *);
+void nvc0_grctx_generate_mods(struct nvc0_graph_priv *, struct nvc0_grctx *);
+void nvc0_grctx_generate_unkn(struct nvc0_graph_priv *);
+void nvc0_grctx_generate_tpcid(struct nvc0_graph_priv *);
+void nvc0_grctx_generate_r406028(struct nvc0_graph_priv *);
+void nvc0_grctx_generate_r4060a8(struct nvc0_graph_priv *);
+void nvc0_grctx_generate_r418bb8(struct nvc0_graph_priv *);
+void nvc0_grctx_generate_r406800(struct nvc0_graph_priv *);
+
+extern struct nouveau_oclass *nvc1_grctx_oclass;
+void nvc1_grctx_generate_mods(struct nvc0_graph_priv *, struct nvc0_grctx *);
+void nvc1_grctx_generate_unkn(struct nvc0_graph_priv *);
+
+extern struct nouveau_oclass *nvc4_grctx_oclass;
+extern struct nouveau_oclass *nvc8_grctx_oclass;
+extern struct nouveau_oclass *nvd7_grctx_oclass;
+extern struct nouveau_oclass *nvd9_grctx_oclass;
+
+extern struct nouveau_oclass *nve4_grctx_oclass;
+void nve4_grctx_generate_main(struct nvc0_graph_priv *, struct nvc0_grctx *);
+void nve4_grctx_generate_unkn(struct nvc0_graph_priv *);
+void nve4_grctx_generate_r418bb8(struct nvc0_graph_priv *);
+
+extern struct nouveau_oclass *nvf0_grctx_oclass;
+extern struct nouveau_oclass *nv108_grctx_oclass;
+extern struct nouveau_oclass *gm107_grctx_oclass;
+
+/* context init value lists */
+
+extern const struct nvc0_graph_pack nvc0_grctx_pack_icmd[];
+
+extern const struct nvc0_graph_pack nvc0_grctx_pack_mthd[];
+extern const struct nvc0_graph_init nvc0_grctx_init_902d_0[];
+extern const struct nvc0_graph_init nvc0_grctx_init_9039_0[];
+extern const struct nvc0_graph_init nvc0_grctx_init_90c0_0[];
+
+extern const struct nvc0_graph_pack nvc0_grctx_pack_hub[];
+extern const struct nvc0_graph_init nvc0_grctx_init_main_0[];
+extern const struct nvc0_graph_init nvc0_grctx_init_fe_0[];
+extern const struct nvc0_graph_init nvc0_grctx_init_pri_0[];
+extern const struct nvc0_graph_init nvc0_grctx_init_memfmt_0[];
+extern const struct nvc0_graph_init nvc0_grctx_init_rstr2d_0[];
+extern const struct nvc0_graph_init nvc0_grctx_init_scc_0[];
+
+extern const struct nvc0_graph_pack nvc0_grctx_pack_gpc[];
+extern const struct nvc0_graph_init nvc0_grctx_init_gpc_unk_0[];
+extern const struct nvc0_graph_init nvc0_grctx_init_prop_0[];
+extern const struct nvc0_graph_init nvc0_grctx_init_gpc_unk_1[];
+extern const struct nvc0_graph_init nvc0_grctx_init_zcull_0[];
+extern const struct nvc0_graph_init nvc0_grctx_init_crstr_0[];
+extern const struct nvc0_graph_init nvc0_grctx_init_gpm_0[];
+extern const struct nvc0_graph_init nvc0_grctx_init_gcc_0[];
+
+extern const struct nvc0_graph_pack nvc0_grctx_pack_zcull[];
+
+extern const struct nvc0_graph_pack nvc0_grctx_pack_tpc[];
+extern const struct nvc0_graph_init nvc0_grctx_init_pe_0[];
+extern const struct nvc0_graph_init nvc0_grctx_init_wwdx_0[];
+extern const struct nvc0_graph_init nvc0_grctx_init_mpc_0[];
+extern const struct nvc0_graph_init nvc0_grctx_init_tpccs_0[];
+
+extern const struct nvc0_graph_init nvc4_grctx_init_tex_0[];
+extern const struct nvc0_graph_init nvc4_grctx_init_l1c_0[];
+extern const struct nvc0_graph_init nvc4_grctx_init_sm_0[];
+
+extern const struct nvc0_graph_init nvc1_grctx_init_9097_0[];
+
+extern const struct nvc0_graph_init nvc1_grctx_init_gpm_0[];
+
+extern const struct nvc0_graph_init nvc1_grctx_init_pe_0[];
+extern const struct nvc0_graph_init nvc1_grctx_init_wwdx_0[];
+extern const struct nvc0_graph_init nvc1_grctx_init_tpccs_0[];
+
+extern const struct nvc0_graph_init nvc8_grctx_init_9197_0[];
+extern const struct nvc0_graph_init nvc8_grctx_init_9297_0[];
+
+extern const struct nvc0_graph_pack nvd9_grctx_pack_icmd[];
+
+extern const struct nvc0_graph_pack nvd9_grctx_pack_mthd[];
+
+extern const struct nvc0_graph_init nvd9_grctx_init_fe_0[];
+extern const struct nvc0_graph_init nvd9_grctx_init_be_0[];
+
+extern const struct nvc0_graph_init nvd9_grctx_init_prop_0[];
+extern const struct nvc0_graph_init nvd9_grctx_init_gpc_unk_1[];
+extern const struct nvc0_graph_init nvd9_grctx_init_crstr_0[];
+
+extern const struct nvc0_graph_init nvd9_grctx_init_sm_0[];
+
+extern const struct nvc0_graph_init nvd7_grctx_init_pe_0[];
+
+extern const struct nvc0_graph_init nvd7_grctx_init_wwdx_0[];
+
+extern const struct nvc0_graph_init nve4_grctx_init_memfmt_0[];
+extern const struct nvc0_graph_init nve4_grctx_init_ds_0[];
+extern const struct nvc0_graph_init nve4_grctx_init_scc_0[];
+
+extern const struct nvc0_graph_init nve4_grctx_init_gpm_0[];
+
+extern const struct nvc0_graph_init nve4_grctx_init_pes_0[];
+
+extern const struct nvc0_graph_pack nvf0_grctx_pack_mthd[];
+
+extern const struct nvc0_graph_init nvf0_grctx_init_pri_0[];
+extern const struct nvc0_graph_init nvf0_grctx_init_cwd_0[];
+
+extern const struct nvc0_graph_init nvf0_grctx_init_gpc_unk_2[];
+
+extern const struct nvc0_graph_init nvf0_grctx_init_mpc_0[];
+extern const struct nvc0_graph_init nvf0_grctx_init_l1c_0[];
+
+extern const struct nvc0_graph_init nv108_grctx_init_rstr2d_0[];
+
+extern const struct nvc0_graph_init nv108_grctx_init_prop_0[];
+extern const struct nvc0_graph_init nv108_grctx_init_crstr_0[];
+
+
+#endif

+ 120 - 150
drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c

@@ -22,10 +22,14 @@
  * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
 
-#include "nvc0.h"
+#include "ctxnvc0.h"
 
-static struct nvc0_graph_init
-nvc1_grctx_init_icmd[] = {
+/*******************************************************************************
+ * PGRAPH context register lists
+ ******************************************************************************/
+
+static const struct nvc0_graph_init
+nvc1_grctx_init_icmd_0[] = {
 	{ 0x001000,   1, 0x01, 0x00000004 },
 	{ 0x0000a9,   1, 0x01, 0x0000ffff },
 	{ 0x000038,   1, 0x01, 0x0fac6881 },
@@ -141,8 +145,7 @@ nvc1_grctx_init_icmd[] = {
 	{ 0x000586,   1, 0x01, 0x00000040 },
 	{ 0x000582,   2, 0x01, 0x00000080 },
 	{ 0x0005c2,   1, 0x01, 0x00000001 },
-	{ 0x000638,   1, 0x01, 0x00000001 },
-	{ 0x000639,   1, 0x01, 0x00000001 },
+	{ 0x000638,   2, 0x01, 0x00000001 },
 	{ 0x00063a,   1, 0x01, 0x00000002 },
 	{ 0x00063b,   2, 0x01, 0x00000001 },
 	{ 0x00063d,   1, 0x01, 0x00000002 },
@@ -202,15 +205,13 @@ nvc1_grctx_init_icmd[] = {
 	{ 0x000787,   1, 0x01, 0x000000cf },
 	{ 0x00078c,   1, 0x01, 0x00000008 },
 	{ 0x000792,   1, 0x01, 0x00000001 },
-	{ 0x000794,   1, 0x01, 0x00000001 },
-	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000794,   3, 0x01, 0x00000001 },
 	{ 0x000797,   1, 0x01, 0x000000cf },
 	{ 0x000836,   1, 0x01, 0x00000001 },
 	{ 0x00079a,   1, 0x01, 0x00000002 },
 	{ 0x000833,   1, 0x01, 0x04444480 },
 	{ 0x0007a1,   1, 0x01, 0x00000001 },
-	{ 0x0007a3,   1, 0x01, 0x00000001 },
-	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x0007a3,   3, 0x01, 0x00000001 },
 	{ 0x000831,   1, 0x01, 0x00000004 },
 	{ 0x00080c,   1, 0x01, 0x00000002 },
 	{ 0x00080d,   2, 0x01, 0x00000100 },
@@ -236,14 +237,12 @@ nvc1_grctx_init_icmd[] = {
 	{ 0x0006b1,   1, 0x01, 0x00000011 },
 	{ 0x00078c,   1, 0x01, 0x00000008 },
 	{ 0x000792,   1, 0x01, 0x00000001 },
-	{ 0x000794,   1, 0x01, 0x00000001 },
-	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000794,   3, 0x01, 0x00000001 },
 	{ 0x000797,   1, 0x01, 0x000000cf },
 	{ 0x00079a,   1, 0x01, 0x00000002 },
 	{ 0x000833,   1, 0x01, 0x04444480 },
 	{ 0x0007a1,   1, 0x01, 0x00000001 },
-	{ 0x0007a3,   1, 0x01, 0x00000001 },
-	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x0007a3,   3, 0x01, 0x00000001 },
 	{ 0x000831,   1, 0x01, 0x00000004 },
 	{ 0x01e100,   1, 0x01, 0x00000001 },
 	{ 0x001000,   1, 0x01, 0x00000014 },
@@ -268,8 +267,14 @@ nvc1_grctx_init_icmd[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvc1_grctx_init_9097[] = {
+static const struct nvc0_graph_pack
+nvc1_grctx_pack_icmd[] = {
+	{ nvc1_grctx_init_icmd_0 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc1_grctx_init_9097_0[] = {
 	{ 0x000800,   8, 0x40, 0x00000000 },
 	{ 0x000804,   8, 0x40, 0x00000000 },
 	{ 0x000808,   8, 0x40, 0x00000400 },
@@ -516,8 +521,7 @@ nvc1_grctx_init_9097[] = {
 	{ 0x001350,   1, 0x04, 0x00000002 },
 	{ 0x001358,   1, 0x04, 0x00000001 },
 	{ 0x0012e4,   1, 0x04, 0x00000000 },
-	{ 0x00131c,   1, 0x04, 0x00000000 },
-	{ 0x001320,   3, 0x04, 0x00000000 },
+	{ 0x00131c,   4, 0x04, 0x00000000 },
 	{ 0x0019c0,   1, 0x04, 0x00000000 },
 	{ 0x001140,   1, 0x04, 0x00000000 },
 	{ 0x0019c4,   1, 0x04, 0x00000000 },
@@ -571,15 +575,25 @@ nvc1_grctx_init_9097[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nvc1_grctx_init_9197[] = {
+static const struct nvc0_graph_init
+nvc1_grctx_init_9197_0[] = {
 	{ 0x003400, 128, 0x04, 0x00000000 },
 	{ 0x0002e4,   1, 0x04, 0x0000b001 },
 	{}
 };
 
-static struct nvc0_graph_init
-nvc1_grctx_init_unk58xx[] = {
+static const struct nvc0_graph_pack
+nvc1_grctx_pack_mthd[] = {
+	{ nvc1_grctx_init_9097_0, 0x9097 },
+	{ nvc1_grctx_init_9197_0, 0x9197 },
+	{ nvc0_grctx_init_902d_0, 0x902d },
+	{ nvc0_grctx_init_9039_0, 0x9039 },
+	{ nvc0_grctx_init_90c0_0, 0x90c0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvc1_grctx_init_ds_0[] = {
 	{ 0x405800,   1, 0x04, 0x0f8000bf },
 	{ 0x405830,   1, 0x04, 0x02180218 },
 	{ 0x405834,   2, 0x04, 0x00000000 },
@@ -590,8 +604,20 @@ nvc1_grctx_init_unk58xx[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nvc1_grctx_init_rop[] = {
+static const struct nvc0_graph_init
+nvc1_grctx_init_pd_0[] = {
+	{ 0x406020,   1, 0x04, 0x000103c1 },
+	{ 0x406028,   4, 0x04, 0x00000001 },
+	{ 0x4064a8,   1, 0x04, 0x00000000 },
+	{ 0x4064ac,   1, 0x04, 0x00003fff },
+	{ 0x4064b4,   2, 0x04, 0x00000000 },
+	{ 0x4064c0,   1, 0x04, 0x80140078 },
+	{ 0x4064c4,   1, 0x04, 0x0086ffff },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvc1_grctx_init_be_0[] = {
 	{ 0x408800,   1, 0x04, 0x02802a3c },
 	{ 0x408804,   1, 0x04, 0x00000040 },
 	{ 0x408808,   1, 0x04, 0x1003e005 },
@@ -602,25 +628,22 @@ nvc1_grctx_init_rop[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nvc1_grctx_init_gpc_0[] = {
-	{ 0x418380,   1, 0x04, 0x00000016 },
-	{ 0x418400,   1, 0x04, 0x38004e00 },
-	{ 0x418404,   1, 0x04, 0x71e0ffff },
-	{ 0x418408,   1, 0x04, 0x00000000 },
-	{ 0x41840c,   1, 0x04, 0x00001008 },
-	{ 0x418410,   1, 0x04, 0x0fff0fff },
-	{ 0x418414,   1, 0x04, 0x00200fff },
-	{ 0x418450,   6, 0x04, 0x00000000 },
-	{ 0x418468,   1, 0x04, 0x00000001 },
-	{ 0x41846c,   2, 0x04, 0x00000000 },
-	{ 0x418600,   1, 0x04, 0x0000001f },
-	{ 0x418684,   1, 0x04, 0x0000000f },
-	{ 0x418700,   1, 0x04, 0x00000002 },
-	{ 0x418704,   1, 0x04, 0x00000080 },
-	{ 0x418708,   1, 0x04, 0x00000000 },
-	{ 0x41870c,   1, 0x04, 0x07c80000 },
-	{ 0x418710,   1, 0x04, 0x00000000 },
+static const struct nvc0_graph_pack
+nvc1_grctx_pack_hub[] = {
+	{ nvc0_grctx_init_main_0 },
+	{ nvc0_grctx_init_fe_0 },
+	{ nvc0_grctx_init_pri_0 },
+	{ nvc0_grctx_init_memfmt_0 },
+	{ nvc1_grctx_init_ds_0 },
+	{ nvc1_grctx_init_pd_0 },
+	{ nvc0_grctx_init_rstr2d_0 },
+	{ nvc0_grctx_init_scc_0 },
+	{ nvc1_grctx_init_be_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvc1_grctx_init_setup_0[] = {
 	{ 0x418800,   1, 0x04, 0x0006860a },
 	{ 0x418808,   3, 0x04, 0x00000000 },
 	{ 0x418828,   1, 0x04, 0x00008442 },
@@ -629,69 +652,44 @@ nvc1_grctx_init_gpc_0[] = {
 	{ 0x4188e0,   1, 0x04, 0x01000000 },
 	{ 0x4188e8,   5, 0x04, 0x00000000 },
 	{ 0x4188fc,   1, 0x04, 0x00100018 },
-	{ 0x41891c,   1, 0x04, 0x00ff00ff },
-	{ 0x418924,   1, 0x04, 0x00000000 },
-	{ 0x418928,   1, 0x04, 0x00ffff00 },
-	{ 0x41892c,   1, 0x04, 0x0000ff00 },
-	{ 0x418a00,   3, 0x04, 0x00000000 },
-	{ 0x418a0c,   1, 0x04, 0x00010000 },
-	{ 0x418a10,   3, 0x04, 0x00000000 },
-	{ 0x418a20,   3, 0x04, 0x00000000 },
-	{ 0x418a2c,   1, 0x04, 0x00010000 },
-	{ 0x418a30,   3, 0x04, 0x00000000 },
-	{ 0x418a40,   3, 0x04, 0x00000000 },
-	{ 0x418a4c,   1, 0x04, 0x00010000 },
-	{ 0x418a50,   3, 0x04, 0x00000000 },
-	{ 0x418a60,   3, 0x04, 0x00000000 },
-	{ 0x418a6c,   1, 0x04, 0x00010000 },
-	{ 0x418a70,   3, 0x04, 0x00000000 },
-	{ 0x418a80,   3, 0x04, 0x00000000 },
-	{ 0x418a8c,   1, 0x04, 0x00010000 },
-	{ 0x418a90,   3, 0x04, 0x00000000 },
-	{ 0x418aa0,   3, 0x04, 0x00000000 },
-	{ 0x418aac,   1, 0x04, 0x00010000 },
-	{ 0x418ab0,   3, 0x04, 0x00000000 },
-	{ 0x418ac0,   3, 0x04, 0x00000000 },
-	{ 0x418acc,   1, 0x04, 0x00010000 },
-	{ 0x418ad0,   3, 0x04, 0x00000000 },
-	{ 0x418ae0,   3, 0x04, 0x00000000 },
-	{ 0x418aec,   1, 0x04, 0x00010000 },
-	{ 0x418af0,   3, 0x04, 0x00000000 },
-	{ 0x418b00,   1, 0x04, 0x00000000 },
-	{ 0x418b08,   1, 0x04, 0x0a418820 },
-	{ 0x418b0c,   1, 0x04, 0x062080e6 },
-	{ 0x418b10,   1, 0x04, 0x020398a4 },
-	{ 0x418b14,   1, 0x04, 0x0e629062 },
-	{ 0x418b18,   1, 0x04, 0x0a418820 },
-	{ 0x418b1c,   1, 0x04, 0x000000e6 },
-	{ 0x418bb8,   1, 0x04, 0x00000103 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc1_grctx_init_gpm_0[] = {
 	{ 0x418c08,   1, 0x04, 0x00000001 },
 	{ 0x418c10,   8, 0x04, 0x00000000 },
 	{ 0x418c6c,   1, 0x04, 0x00000001 },
 	{ 0x418c80,   1, 0x04, 0x20200004 },
 	{ 0x418c8c,   1, 0x04, 0x00000001 },
-	{ 0x419000,   1, 0x04, 0x00000780 },
-	{ 0x419004,   2, 0x04, 0x00000000 },
-	{ 0x419014,   1, 0x04, 0x00000004 },
 	{}
 };
 
-static struct nvc0_graph_init
-nvc1_grctx_init_tpc[] = {
+static const struct nvc0_graph_pack
+nvc1_grctx_pack_gpc[] = {
+	{ nvc0_grctx_init_gpc_unk_0 },
+	{ nvc0_grctx_init_prop_0 },
+	{ nvc0_grctx_init_gpc_unk_1 },
+	{ nvc1_grctx_init_setup_0 },
+	{ nvc0_grctx_init_zcull_0 },
+	{ nvc0_grctx_init_crstr_0 },
+	{ nvc1_grctx_init_gpm_0 },
+	{ nvc0_grctx_init_gcc_0 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc1_grctx_init_pe_0[] = {
 	{ 0x419818,   1, 0x04, 0x00000000 },
 	{ 0x41983c,   1, 0x04, 0x00038bc7 },
 	{ 0x419848,   1, 0x04, 0x00000000 },
 	{ 0x419864,   1, 0x04, 0x00000129 },
 	{ 0x419888,   1, 0x04, 0x00000000 },
-	{ 0x419a00,   1, 0x04, 0x000001f0 },
-	{ 0x419a04,   1, 0x04, 0x00000001 },
-	{ 0x419a08,   1, 0x04, 0x00000023 },
-	{ 0x419a0c,   1, 0x04, 0x00020000 },
-	{ 0x419a10,   1, 0x04, 0x00000000 },
-	{ 0x419a14,   1, 0x04, 0x00000200 },
-	{ 0x419a1c,   1, 0x04, 0x00000000 },
-	{ 0x419a20,   1, 0x04, 0x00000800 },
-	{ 0x419ac4,   1, 0x04, 0x0007f440 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc1_grctx_init_wwdx_0[] = {
 	{ 0x419b00,   1, 0x04, 0x0a418820 },
 	{ 0x419b04,   1, 0x04, 0x062080e6 },
 	{ 0x419b08,   1, 0x04, 0x020398a4 },
@@ -701,28 +699,33 @@ nvc1_grctx_init_tpc[] = {
 	{ 0x419bd0,   1, 0x04, 0x00900103 },
 	{ 0x419be0,   1, 0x04, 0x00400001 },
 	{ 0x419be4,   1, 0x04, 0x00000000 },
-	{ 0x419c00,   1, 0x04, 0x00000002 },
-	{ 0x419c04,   1, 0x04, 0x00000006 },
-	{ 0x419c08,   1, 0x04, 0x00000002 },
-	{ 0x419c20,   1, 0x04, 0x00000000 },
-	{ 0x419cb0,   1, 0x04, 0x00020048 },
-	{ 0x419ce8,   1, 0x04, 0x00000000 },
-	{ 0x419cf4,   1, 0x04, 0x00000183 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc1_grctx_init_tpccs_0[] = {
 	{ 0x419d20,   1, 0x04, 0x12180000 },
 	{ 0x419d24,   1, 0x04, 0x00001fff },
 	{ 0x419d44,   1, 0x04, 0x02180218 },
-	{ 0x419e04,   3, 0x04, 0x00000000 },
-	{ 0x419e10,   1, 0x04, 0x00000002 },
-	{ 0x419e44,   1, 0x04, 0x001beff2 },
-	{ 0x419e48,   1, 0x04, 0x00000000 },
-	{ 0x419e4c,   1, 0x04, 0x0000000f },
-	{ 0x419e50,  17, 0x04, 0x00000000 },
-	{ 0x419e98,   1, 0x04, 0x00000000 },
-	{ 0x419ee0,   1, 0x04, 0x00011110 },
-	{ 0x419f30,  11, 0x04, 0x00000000 },
 	{}
 };
 
+static const struct nvc0_graph_pack
+nvc1_grctx_pack_tpc[] = {
+	{ nvc1_grctx_init_pe_0 },
+	{ nvc4_grctx_init_tex_0 },
+	{ nvc1_grctx_init_wwdx_0 },
+	{ nvc0_grctx_init_mpc_0 },
+	{ nvc4_grctx_init_l1c_0 },
+	{ nvc1_grctx_init_tpccs_0 },
+	{ nvc4_grctx_init_sm_0 },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH context implementation
+ ******************************************************************************/
+
 void
 nvc1_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
 {
@@ -771,41 +774,6 @@ nvc1_grctx_generate_unkn(struct nvc0_graph_priv *priv)
 	nv_mask(priv, 0x419c00, 0x00000008, 0x00000008);
 }
 
-static struct nvc0_graph_init *
-nvc1_grctx_init_hub[] = {
-	nvc0_grctx_init_base,
-	nvc0_grctx_init_unk40xx,
-	nvc0_grctx_init_unk44xx,
-	nvc0_grctx_init_unk46xx,
-	nvc0_grctx_init_unk47xx,
-	nvc1_grctx_init_unk58xx,
-	nvc0_grctx_init_unk60xx,
-	nvc0_grctx_init_unk64xx,
-	nvc0_grctx_init_unk78xx,
-	nvc0_grctx_init_unk80xx,
-	nvc1_grctx_init_rop,
-	NULL
-};
-
-struct nvc0_graph_init *
-nvc1_grctx_init_gpc[] = {
-	nvc1_grctx_init_gpc_0,
-	nvc0_grctx_init_gpc_1,
-	nvc1_grctx_init_tpc,
-	NULL
-};
-
-static struct nvc0_graph_mthd
-nvc1_grctx_init_mthd[] = {
-	{ 0x9097, nvc1_grctx_init_9097, },
-	{ 0x9197, nvc1_grctx_init_9197, },
-	{ 0x902d, nvc0_grctx_init_902d, },
-	{ 0x9039, nvc0_grctx_init_9039, },
-	{ 0x90c0, nvc0_grctx_init_90c0, },
-	{ 0x902d, nvc0_grctx_init_mthd_magic, },
-	{}
-};
-
 struct nouveau_oclass *
 nvc1_grctx_oclass = &(struct nvc0_grctx_oclass) {
 	.base.handle = NV_ENGCTX(GR, 0xc1),
@@ -817,11 +785,13 @@ nvc1_grctx_oclass = &(struct nvc0_grctx_oclass) {
 		.rd32 = _nouveau_graph_context_rd32,
 		.wr32 = _nouveau_graph_context_wr32,
 	},
-	.main = nvc0_grctx_generate_main,
-	.mods = nvc1_grctx_generate_mods,
-	.unkn = nvc1_grctx_generate_unkn,
-	.hub  = nvc1_grctx_init_hub,
-	.gpc  = nvc1_grctx_init_gpc,
-	.icmd = nvc1_grctx_init_icmd,
-	.mthd = nvc1_grctx_init_mthd,
+	.main  = nvc0_grctx_generate_main,
+	.mods  = nvc1_grctx_generate_mods,
+	.unkn  = nvc1_grctx_generate_unkn,
+	.hub   = nvc1_grctx_pack_hub,
+	.gpc   = nvc1_grctx_pack_gpc,
+	.zcull = nvc0_grctx_pack_zcull,
+	.tpc   = nvc1_grctx_pack_tpc,
+	.icmd  = nvc1_grctx_pack_icmd,
+	.mthd  = nvc1_grctx_pack_mthd,
 }.base;

+ 41 - 37
drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc3.c → drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc4.c

@@ -22,15 +22,14 @@
  * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
 
-#include "nvc0.h"
+#include "ctxnvc0.h"
 
-static struct nvc0_graph_init
-nvc3_grctx_init_tpc[] = {
-	{ 0x419818,   1, 0x04, 0x00000000 },
-	{ 0x41983c,   1, 0x04, 0x00038bc7 },
-	{ 0x419848,   1, 0x04, 0x00000000 },
-	{ 0x419864,   1, 0x04, 0x0000012a },
-	{ 0x419888,   1, 0x04, 0x00000000 },
+/*******************************************************************************
+ * PGRAPH context register lists
+ ******************************************************************************/
+
+const struct nvc0_graph_init
+nvc4_grctx_init_tex_0[] = {
 	{ 0x419a00,   1, 0x04, 0x000001f0 },
 	{ 0x419a04,   1, 0x04, 0x00000001 },
 	{ 0x419a08,   1, 0x04, 0x00000023 },
@@ -40,24 +39,19 @@ nvc3_grctx_init_tpc[] = {
 	{ 0x419a1c,   1, 0x04, 0x00000000 },
 	{ 0x419a20,   1, 0x04, 0x00000800 },
 	{ 0x419ac4,   1, 0x04, 0x0007f440 },
-	{ 0x419b00,   1, 0x04, 0x0a418820 },
-	{ 0x419b04,   1, 0x04, 0x062080e6 },
-	{ 0x419b08,   1, 0x04, 0x020398a4 },
-	{ 0x419b0c,   1, 0x04, 0x0e629062 },
-	{ 0x419b10,   1, 0x04, 0x0a418820 },
-	{ 0x419b14,   1, 0x04, 0x000000e6 },
-	{ 0x419bd0,   1, 0x04, 0x00900103 },
-	{ 0x419be0,   1, 0x04, 0x00000001 },
-	{ 0x419be4,   1, 0x04, 0x00000000 },
-	{ 0x419c00,   1, 0x04, 0x00000002 },
-	{ 0x419c04,   1, 0x04, 0x00000006 },
-	{ 0x419c08,   1, 0x04, 0x00000002 },
-	{ 0x419c20,   1, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc4_grctx_init_l1c_0[] = {
 	{ 0x419cb0,   1, 0x04, 0x00020048 },
 	{ 0x419ce8,   1, 0x04, 0x00000000 },
 	{ 0x419cf4,   1, 0x04, 0x00000183 },
-	{ 0x419d20,   1, 0x04, 0x02180000 },
-	{ 0x419d24,   1, 0x04, 0x00001fff },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc4_grctx_init_sm_0[] = {
 	{ 0x419e04,   3, 0x04, 0x00000000 },
 	{ 0x419e10,   1, 0x04, 0x00000002 },
 	{ 0x419e44,   1, 0x04, 0x001beff2 },
@@ -70,16 +64,24 @@ nvc3_grctx_init_tpc[] = {
 	{}
 };
 
-struct nvc0_graph_init *
-nvc3_grctx_init_gpc[] = {
-	nvc0_grctx_init_gpc_0,
-	nvc0_grctx_init_gpc_1,
-	nvc3_grctx_init_tpc,
-	NULL
+static const struct nvc0_graph_pack
+nvc4_grctx_pack_tpc[] = {
+	{ nvc0_grctx_init_pe_0 },
+	{ nvc4_grctx_init_tex_0 },
+	{ nvc0_grctx_init_wwdx_0 },
+	{ nvc0_grctx_init_mpc_0 },
+	{ nvc4_grctx_init_l1c_0 },
+	{ nvc0_grctx_init_tpccs_0 },
+	{ nvc4_grctx_init_sm_0 },
+	{}
 };
 
+/*******************************************************************************
+ * PGRAPH context implementation
+ ******************************************************************************/
+
 struct nouveau_oclass *
-nvc3_grctx_oclass = &(struct nvc0_grctx_oclass) {
+nvc4_grctx_oclass = &(struct nvc0_grctx_oclass) {
 	.base.handle = NV_ENGCTX(GR, 0xc3),
 	.base.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nvc0_graph_context_ctor,
@@ -89,11 +91,13 @@ nvc3_grctx_oclass = &(struct nvc0_grctx_oclass) {
 		.rd32 = _nouveau_graph_context_rd32,
 		.wr32 = _nouveau_graph_context_wr32,
 	},
-	.main = nvc0_grctx_generate_main,
-	.mods = nvc0_grctx_generate_mods,
-	.unkn = nvc0_grctx_generate_unkn,
-	.hub  = nvc0_grctx_init_hub,
-	.gpc  = nvc3_grctx_init_gpc,
-	.icmd = nvc0_grctx_init_icmd,
-	.mthd = nvc0_grctx_init_mthd,
+	.main  = nvc0_grctx_generate_main,
+	.mods  = nvc0_grctx_generate_mods,
+	.unkn  = nvc0_grctx_generate_unkn,
+	.hub   = nvc0_grctx_pack_hub,
+	.gpc   = nvc0_grctx_pack_gpc,
+	.zcull = nvc0_grctx_pack_zcull,
+	.tpc   = nvc4_grctx_pack_tpc,
+	.icmd  = nvc0_grctx_pack_icmd,
+	.mthd  = nvc0_grctx_pack_mthd,
 }.base;

+ 64 - 80
drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c

@@ -22,10 +22,14 @@
  * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
 
-#include "nvc0.h"
+#include "ctxnvc0.h"
 
-static struct nvc0_graph_init
-nvc8_grctx_init_icmd[] = {
+/*******************************************************************************
+ * PGRAPH context register lists
+ ******************************************************************************/
+
+static const struct nvc0_graph_init
+nvc8_grctx_init_icmd_0[] = {
 	{ 0x001000,   1, 0x01, 0x00000004 },
 	{ 0x0000a9,   1, 0x01, 0x0000ffff },
 	{ 0x000038,   1, 0x01, 0x0fac6881 },
@@ -141,8 +145,7 @@ nvc8_grctx_init_icmd[] = {
 	{ 0x000586,   1, 0x01, 0x00000040 },
 	{ 0x000582,   2, 0x01, 0x00000080 },
 	{ 0x0005c2,   1, 0x01, 0x00000001 },
-	{ 0x000638,   1, 0x01, 0x00000001 },
-	{ 0x000639,   1, 0x01, 0x00000001 },
+	{ 0x000638,   2, 0x01, 0x00000001 },
 	{ 0x00063a,   1, 0x01, 0x00000002 },
 	{ 0x00063b,   2, 0x01, 0x00000001 },
 	{ 0x00063d,   1, 0x01, 0x00000002 },
@@ -203,15 +206,13 @@ nvc8_grctx_init_icmd[] = {
 	{ 0x000787,   1, 0x01, 0x000000cf },
 	{ 0x00078c,   1, 0x01, 0x00000008 },
 	{ 0x000792,   1, 0x01, 0x00000001 },
-	{ 0x000794,   1, 0x01, 0x00000001 },
-	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000794,   3, 0x01, 0x00000001 },
 	{ 0x000797,   1, 0x01, 0x000000cf },
 	{ 0x000836,   1, 0x01, 0x00000001 },
 	{ 0x00079a,   1, 0x01, 0x00000002 },
 	{ 0x000833,   1, 0x01, 0x04444480 },
 	{ 0x0007a1,   1, 0x01, 0x00000001 },
-	{ 0x0007a3,   1, 0x01, 0x00000001 },
-	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x0007a3,   3, 0x01, 0x00000001 },
 	{ 0x000831,   1, 0x01, 0x00000004 },
 	{ 0x00080c,   1, 0x01, 0x00000002 },
 	{ 0x00080d,   2, 0x01, 0x00000100 },
@@ -237,14 +238,12 @@ nvc8_grctx_init_icmd[] = {
 	{ 0x0006b1,   1, 0x01, 0x00000011 },
 	{ 0x00078c,   1, 0x01, 0x00000008 },
 	{ 0x000792,   1, 0x01, 0x00000001 },
-	{ 0x000794,   1, 0x01, 0x00000001 },
-	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000794,   3, 0x01, 0x00000001 },
 	{ 0x000797,   1, 0x01, 0x000000cf },
 	{ 0x00079a,   1, 0x01, 0x00000002 },
 	{ 0x000833,   1, 0x01, 0x04444480 },
 	{ 0x0007a1,   1, 0x01, 0x00000001 },
-	{ 0x0007a3,   1, 0x01, 0x00000001 },
-	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x0007a3,   3, 0x01, 0x00000001 },
 	{ 0x000831,   1, 0x01, 0x00000004 },
 	{ 0x01e100,   1, 0x01, 0x00000001 },
 	{ 0x001000,   1, 0x01, 0x00000014 },
@@ -269,58 +268,20 @@ nvc8_grctx_init_icmd[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nvc8_grctx_init_tpc[] = {
-	{ 0x419818,   1, 0x04, 0x00000000 },
-	{ 0x41983c,   1, 0x04, 0x00038bc7 },
-	{ 0x419848,   1, 0x04, 0x00000000 },
-	{ 0x419864,   1, 0x04, 0x0000012a },
-	{ 0x419888,   1, 0x04, 0x00000000 },
-	{ 0x419a00,   1, 0x04, 0x000001f0 },
-	{ 0x419a04,   1, 0x04, 0x00000001 },
-	{ 0x419a08,   1, 0x04, 0x00000023 },
-	{ 0x419a0c,   1, 0x04, 0x00020000 },
-	{ 0x419a10,   1, 0x04, 0x00000000 },
-	{ 0x419a14,   1, 0x04, 0x00000200 },
-	{ 0x419a1c,   1, 0x04, 0x00000000 },
-	{ 0x419a20,   1, 0x04, 0x00000800 },
-	{ 0x419b00,   1, 0x04, 0x0a418820 },
-	{ 0x419b04,   1, 0x04, 0x062080e6 },
-	{ 0x419b08,   1, 0x04, 0x020398a4 },
-	{ 0x419b0c,   1, 0x04, 0x0e629062 },
-	{ 0x419b10,   1, 0x04, 0x0a418820 },
-	{ 0x419b14,   1, 0x04, 0x000000e6 },
-	{ 0x419bd0,   1, 0x04, 0x00900103 },
-	{ 0x419be0,   1, 0x04, 0x00000001 },
-	{ 0x419be4,   1, 0x04, 0x00000000 },
-	{ 0x419c00,   1, 0x04, 0x00000002 },
-	{ 0x419c04,   1, 0x04, 0x00000006 },
-	{ 0x419c08,   1, 0x04, 0x00000002 },
-	{ 0x419c20,   1, 0x04, 0x00000000 },
-	{ 0x419cb0,   1, 0x04, 0x00060048 },
-	{ 0x419ce8,   1, 0x04, 0x00000000 },
-	{ 0x419cf4,   1, 0x04, 0x00000183 },
-	{ 0x419d20,   1, 0x04, 0x02180000 },
-	{ 0x419d24,   1, 0x04, 0x00001fff },
-	{ 0x419e04,   3, 0x04, 0x00000000 },
-	{ 0x419e10,   1, 0x04, 0x00000002 },
-	{ 0x419e44,   1, 0x04, 0x001beff2 },
-	{ 0x419e48,   1, 0x04, 0x00000000 },
-	{ 0x419e4c,   1, 0x04, 0x0000000f },
-	{ 0x419e50,  17, 0x04, 0x00000000 },
-	{ 0x419e98,   1, 0x04, 0x00000000 },
-	{ 0x419f50,   2, 0x04, 0x00000000 },
+static const struct nvc0_graph_pack
+nvc8_grctx_pack_icmd[] = {
+	{ nvc8_grctx_init_icmd_0 },
 	{}
 };
 
-struct nvc0_graph_init
-nvc8_grctx_init_9197[] = {
+const struct nvc0_graph_init
+nvc8_grctx_init_9197_0[] = {
 	{ 0x0002e4,   1, 0x04, 0x0000b001 },
 	{}
 };
 
-struct nvc0_graph_init
-nvc8_grctx_init_9297[] = {
+const struct nvc0_graph_init
+nvc8_grctx_init_9297_0[] = {
 	{ 0x003400, 128, 0x04, 0x00000000 },
 	{ 0x00036c,   2, 0x04, 0x00000000 },
 	{ 0x0007a4,   2, 0x04, 0x00000000 },
@@ -329,26 +290,47 @@ nvc8_grctx_init_9297[] = {
 	{}
 };
 
-static struct nvc0_graph_mthd
-nvc8_grctx_init_mthd[] = {
-	{ 0x9097, nvc1_grctx_init_9097, },
-	{ 0x9197, nvc8_grctx_init_9197, },
-	{ 0x9297, nvc8_grctx_init_9297, },
-	{ 0x902d, nvc0_grctx_init_902d, },
-	{ 0x9039, nvc0_grctx_init_9039, },
-	{ 0x90c0, nvc0_grctx_init_90c0, },
-	{ 0x902d, nvc0_grctx_init_mthd_magic, },
+static const struct nvc0_graph_pack
+nvc8_grctx_pack_mthd[] = {
+	{ nvc1_grctx_init_9097_0, 0x9097 },
+	{ nvc8_grctx_init_9197_0, 0x9197 },
+	{ nvc8_grctx_init_9297_0, 0x9297 },
+	{ nvc0_grctx_init_902d_0, 0x902d },
+	{ nvc0_grctx_init_9039_0, 0x9039 },
+	{ nvc0_grctx_init_90c0_0, 0x90c0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvc8_grctx_init_setup_0[] = {
+	{ 0x418800,   1, 0x04, 0x0006860a },
+	{ 0x418808,   3, 0x04, 0x00000000 },
+	{ 0x418828,   1, 0x04, 0x00008442 },
+	{ 0x418830,   1, 0x04, 0x00000001 },
+	{ 0x4188d8,   1, 0x04, 0x00000008 },
+	{ 0x4188e0,   1, 0x04, 0x01000000 },
+	{ 0x4188e8,   5, 0x04, 0x00000000 },
+	{ 0x4188fc,   1, 0x04, 0x20100000 },
 	{}
 };
 
-static struct nvc0_graph_init *
-nvc8_grctx_init_gpc[] = {
-	nvc0_grctx_init_gpc_0,
-	nvc0_grctx_init_gpc_1,
-	nvc8_grctx_init_tpc,
-	NULL
+static const struct nvc0_graph_pack
+nvc8_grctx_pack_gpc[] = {
+	{ nvc0_grctx_init_gpc_unk_0 },
+	{ nvc0_grctx_init_prop_0 },
+	{ nvc0_grctx_init_gpc_unk_1 },
+	{ nvc8_grctx_init_setup_0 },
+	{ nvc0_grctx_init_zcull_0 },
+	{ nvc0_grctx_init_crstr_0 },
+	{ nvc0_grctx_init_gpm_0 },
+	{ nvc0_grctx_init_gcc_0 },
+	{}
 };
 
+/*******************************************************************************
+ * PGRAPH context implementation
+ ******************************************************************************/
+
 struct nouveau_oclass *
 nvc8_grctx_oclass = &(struct nvc0_grctx_oclass) {
 	.base.handle = NV_ENGCTX(GR, 0xc8),
@@ -360,11 +342,13 @@ nvc8_grctx_oclass = &(struct nvc0_grctx_oclass) {
 		.rd32 = _nouveau_graph_context_rd32,
 		.wr32 = _nouveau_graph_context_wr32,
 	},
-	.main = nvc0_grctx_generate_main,
-	.mods = nvc0_grctx_generate_mods,
-	.unkn = nvc0_grctx_generate_unkn,
-	.hub  = nvc0_grctx_init_hub,
-	.gpc  = nvc8_grctx_init_gpc,
-	.icmd = nvc8_grctx_init_icmd,
-	.mthd = nvc8_grctx_init_mthd,
+	.main  = nvc0_grctx_generate_main,
+	.mods  = nvc0_grctx_generate_mods,
+	.unkn  = nvc0_grctx_generate_unkn,
+	.hub   = nvc0_grctx_pack_hub,
+	.gpc   = nvc8_grctx_pack_gpc,
+	.zcull = nvc0_grctx_pack_zcull,
+	.tpc   = nvc0_grctx_pack_tpc,
+	.icmd  = nvc8_grctx_pack_icmd,
+	.mthd  = nvc8_grctx_pack_mthd,
 }.base;

+ 100 - 116
drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c

@@ -22,33 +22,14 @@
  * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
 
-#include "nvc0.h"
+#include "ctxnvc0.h"
 
-struct nvc0_graph_init
-nvd7_grctx_init_unk40xx[] = {
-	{ 0x404004,  10, 0x04, 0x00000000 },
-	{ 0x404044,   1, 0x04, 0x00000000 },
-	{ 0x404094,   1, 0x04, 0x00000000 },
-	{ 0x404098,  12, 0x04, 0x00000000 },
-	{ 0x4040c8,   1, 0x04, 0xf0000087 },
-	{ 0x4040d0,   6, 0x04, 0x00000000 },
-	{ 0x4040e8,   1, 0x04, 0x00001000 },
-	{ 0x4040f8,   1, 0x04, 0x00000000 },
-	{ 0x404130,   1, 0x04, 0x00000000 },
-	{ 0x404134,   1, 0x04, 0x00000000 },
-	{ 0x404138,   1, 0x04, 0x20000040 },
-	{ 0x404150,   1, 0x04, 0x0000002e },
-	{ 0x404154,   1, 0x04, 0x00000400 },
-	{ 0x404158,   1, 0x04, 0x00000200 },
-	{ 0x404164,   1, 0x04, 0x00000055 },
-	{ 0x404168,   1, 0x04, 0x00000000 },
-	{ 0x404178,   2, 0x04, 0x00000000 },
-	{ 0x404200,   8, 0x04, 0x00000000 },
-	{}
-};
+/*******************************************************************************
+ * PGRAPH context register lists
+ ******************************************************************************/
 
-static struct nvc0_graph_init
-nvd7_grctx_init_unk58xx[] = {
+static const struct nvc0_graph_init
+nvd7_grctx_init_ds_0[] = {
 	{ 0x405800,   1, 0x04, 0x0f8000bf },
 	{ 0x405830,   1, 0x04, 0x02180324 },
 	{ 0x405834,   1, 0x04, 0x08000000 },
@@ -60,8 +41,10 @@ nvd7_grctx_init_unk58xx[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nvd7_grctx_init_unk64xx[] = {
+static const struct nvc0_graph_init
+nvd7_grctx_init_pd_0[] = {
+	{ 0x406020,   1, 0x04, 0x000103c1 },
+	{ 0x406028,   4, 0x04, 0x00000001 },
 	{ 0x4064a8,   1, 0x04, 0x00000000 },
 	{ 0x4064ac,   1, 0x04, 0x00003fff },
 	{ 0x4064b4,   3, 0x04, 0x00000000 },
@@ -71,22 +54,22 @@ nvd7_grctx_init_unk64xx[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nvd7_grctx_init_gpc_0[] = {
-	{ 0x418380,   1, 0x04, 0x00000016 },
-	{ 0x418400,   1, 0x04, 0x38004e00 },
-	{ 0x418404,   1, 0x04, 0x71e0ffff },
-	{ 0x41840c,   1, 0x04, 0x00001008 },
-	{ 0x418410,   1, 0x04, 0x0fff0fff },
-	{ 0x418414,   1, 0x04, 0x02200fff },
-	{ 0x418450,   6, 0x04, 0x00000000 },
-	{ 0x418468,   1, 0x04, 0x00000001 },
-	{ 0x41846c,   2, 0x04, 0x00000000 },
-	{ 0x418600,   1, 0x04, 0x0000001f },
-	{ 0x418684,   1, 0x04, 0x0000000f },
-	{ 0x418700,   1, 0x04, 0x00000002 },
-	{ 0x418704,   1, 0x04, 0x00000080 },
-	{ 0x418708,   3, 0x04, 0x00000000 },
+static const struct nvc0_graph_pack
+nvd7_grctx_pack_hub[] = {
+	{ nvc0_grctx_init_main_0 },
+	{ nvd9_grctx_init_fe_0 },
+	{ nvc0_grctx_init_pri_0 },
+	{ nvc0_grctx_init_memfmt_0 },
+	{ nvd7_grctx_init_ds_0 },
+	{ nvd7_grctx_init_pd_0 },
+	{ nvc0_grctx_init_rstr2d_0 },
+	{ nvc0_grctx_init_scc_0 },
+	{ nvd9_grctx_init_be_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvd7_grctx_init_setup_0[] = {
 	{ 0x418800,   1, 0x04, 0x7006860a },
 	{ 0x418808,   3, 0x04, 0x00000000 },
 	{ 0x418828,   1, 0x04, 0x00008442 },
@@ -95,34 +78,32 @@ nvd7_grctx_init_gpc_0[] = {
 	{ 0x4188e0,   1, 0x04, 0x01000000 },
 	{ 0x4188e8,   5, 0x04, 0x00000000 },
 	{ 0x4188fc,   1, 0x04, 0x20100018 },
-	{ 0x41891c,   1, 0x04, 0x00ff00ff },
-	{ 0x418924,   1, 0x04, 0x00000000 },
-	{ 0x418928,   1, 0x04, 0x00ffff00 },
-	{ 0x41892c,   1, 0x04, 0x0000ff00 },
-	{ 0x418b00,   1, 0x04, 0x00000006 },
-	{ 0x418b08,   1, 0x04, 0x0a418820 },
-	{ 0x418b0c,   1, 0x04, 0x062080e6 },
-	{ 0x418b10,   1, 0x04, 0x020398a4 },
-	{ 0x418b14,   1, 0x04, 0x0e629062 },
-	{ 0x418b18,   1, 0x04, 0x0a418820 },
-	{ 0x418b1c,   1, 0x04, 0x000000e6 },
-	{ 0x418bb8,   1, 0x04, 0x00000103 },
-	{ 0x418c08,   1, 0x04, 0x00000001 },
-	{ 0x418c10,   8, 0x04, 0x00000000 },
-	{ 0x418c6c,   1, 0x04, 0x00000001 },
-	{ 0x418c80,   1, 0x04, 0x20200004 },
-	{ 0x418c8c,   1, 0x04, 0x00000001 },
-	{ 0x419000,   1, 0x04, 0x00000780 },
-	{ 0x419004,   2, 0x04, 0x00000000 },
-	{ 0x419014,   1, 0x04, 0x00000004 },
 	{}
 };
 
-static struct nvc0_graph_init
-nvd7_grctx_init_tpc[] = {
+static const struct nvc0_graph_pack
+nvd7_grctx_pack_gpc[] = {
+	{ nvc0_grctx_init_gpc_unk_0 },
+	{ nvd9_grctx_init_prop_0 },
+	{ nvd9_grctx_init_gpc_unk_1 },
+	{ nvd7_grctx_init_setup_0 },
+	{ nvc0_grctx_init_zcull_0 },
+	{ nvd9_grctx_init_crstr_0 },
+	{ nvc1_grctx_init_gpm_0 },
+	{ nvc0_grctx_init_gcc_0 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvd7_grctx_init_pe_0[] = {
 	{ 0x419848,   1, 0x04, 0x00000000 },
 	{ 0x419864,   1, 0x04, 0x00000129 },
 	{ 0x419888,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvd7_grctx_init_tex_0[] = {
 	{ 0x419a00,   1, 0x04, 0x000001f0 },
 	{ 0x419a04,   1, 0x04, 0x00000001 },
 	{ 0x419a08,   1, 0x04, 0x00000023 },
@@ -132,33 +113,46 @@ nvd7_grctx_init_tpc[] = {
 	{ 0x419a1c,   1, 0x04, 0x00008000 },
 	{ 0x419a20,   1, 0x04, 0x00000800 },
 	{ 0x419ac4,   1, 0x04, 0x0017f440 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvd7_grctx_init_mpc_0[] = {
 	{ 0x419c00,   1, 0x04, 0x0000000a },
 	{ 0x419c04,   1, 0x04, 0x00000006 },
 	{ 0x419c08,   1, 0x04, 0x00000002 },
 	{ 0x419c20,   1, 0x04, 0x00000000 },
 	{ 0x419c24,   1, 0x04, 0x00084210 },
 	{ 0x419c28,   1, 0x04, 0x3efbefbe },
-	{ 0x419cb0,   1, 0x04, 0x00020048 },
-	{ 0x419ce8,   1, 0x04, 0x00000000 },
-	{ 0x419cf4,   1, 0x04, 0x00000183 },
-	{ 0x419e04,   3, 0x04, 0x00000000 },
-	{ 0x419e10,   1, 0x04, 0x00000002 },
-	{ 0x419e44,   1, 0x04, 0x001beff2 },
-	{ 0x419e48,   1, 0x04, 0x00000000 },
-	{ 0x419e4c,   1, 0x04, 0x0000000f },
-	{ 0x419e50,  17, 0x04, 0x00000000 },
-	{ 0x419e98,   1, 0x04, 0x00000000 },
-	{ 0x419ee0,   1, 0x04, 0x00010110 },
-	{ 0x419f30,  11, 0x04, 0x00000000 },
 	{}
 };
 
-static struct nvc0_graph_init
-nvd7_grctx_init_unk[] = {
+static const struct nvc0_graph_pack
+nvd7_grctx_pack_tpc[] = {
+	{ nvd7_grctx_init_pe_0 },
+	{ nvd7_grctx_init_tex_0 },
+	{ nvd7_grctx_init_mpc_0 },
+	{ nvc4_grctx_init_l1c_0 },
+	{ nvd9_grctx_init_sm_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvd7_grctx_init_pes_0[] = {
 	{ 0x41be24,   1, 0x04, 0x00000002 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvd7_grctx_init_cbm_0[] = {
 	{ 0x41bec0,   1, 0x04, 0x12180000 },
 	{ 0x41bec4,   1, 0x04, 0x00003fff },
 	{ 0x41bee4,   1, 0x04, 0x03240218 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvd7_grctx_init_wwdx_0[] = {
 	{ 0x41bf00,   1, 0x04, 0x0a418820 },
 	{ 0x41bf04,   1, 0x04, 0x062080e6 },
 	{ 0x41bf08,   1, 0x04, 0x020398a4 },
@@ -171,6 +165,18 @@ nvd7_grctx_init_unk[] = {
 	{}
 };
 
+static const struct nvc0_graph_pack
+nvd7_grctx_pack_ppc[] = {
+	{ nvd7_grctx_init_pes_0 },
+	{ nvd7_grctx_init_cbm_0 },
+	{ nvd7_grctx_init_wwdx_0 },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH context implementation
+ ******************************************************************************/
+
 static void
 nvd7_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
 {
@@ -219,10 +225,11 @@ nvd7_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
 
 	nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
 
-	for (i = 0; oclass->hub[i]; i++)
-		nvc0_graph_mmio(priv, oclass->hub[i]);
-	for (i = 0; oclass->gpc[i]; i++)
-		nvc0_graph_mmio(priv, oclass->gpc[i]);
+	nvc0_graph_mmio(priv, oclass->hub);
+	nvc0_graph_mmio(priv, oclass->gpc);
+	nvc0_graph_mmio(priv, oclass->zcull);
+	nvc0_graph_mmio(priv, oclass->tpc);
+	nvc0_graph_mmio(priv, oclass->ppc);
 
 	nv_wr32(priv, 0x404154, 0x00000000);
 
@@ -244,32 +251,6 @@ nvd7_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
 	nv_mask(priv, 0x000260, 0x00000001, 0x00000001);
 }
 
-
-static struct nvc0_graph_init *
-nvd7_grctx_init_hub[] = {
-	nvc0_grctx_init_base,
-	nvd7_grctx_init_unk40xx,
-	nvc0_grctx_init_unk44xx,
-	nvc0_grctx_init_unk46xx,
-	nvc0_grctx_init_unk47xx,
-	nvd7_grctx_init_unk58xx,
-	nvc0_grctx_init_unk60xx,
-	nvd7_grctx_init_unk64xx,
-	nvc0_grctx_init_unk78xx,
-	nvc0_grctx_init_unk80xx,
-	nvd9_grctx_init_rop,
-	NULL
-};
-
-struct nvc0_graph_init *
-nvd7_grctx_init_gpc[] = {
-	nvd7_grctx_init_gpc_0,
-	nvc0_grctx_init_gpc_1,
-	nvd7_grctx_init_tpc,
-	nvd7_grctx_init_unk,
-	NULL
-};
-
 struct nouveau_oclass *
 nvd7_grctx_oclass = &(struct nvc0_grctx_oclass) {
 	.base.handle = NV_ENGCTX(GR, 0xd7),
@@ -281,11 +262,14 @@ nvd7_grctx_oclass = &(struct nvc0_grctx_oclass) {
 		.rd32 = _nouveau_graph_context_rd32,
 		.wr32 = _nouveau_graph_context_wr32,
 	},
-	.main = nvd7_grctx_generate_main,
-	.mods = nvd7_grctx_generate_mods,
-	.unkn = nve4_grctx_generate_unkn,
-	.hub  = nvd7_grctx_init_hub,
-	.gpc  = nvd7_grctx_init_gpc,
-	.icmd = nvd9_grctx_init_icmd,
-	.mthd = nvd9_grctx_init_mthd,
+	.main  = nvd7_grctx_generate_main,
+	.mods  = nvd7_grctx_generate_mods,
+	.unkn  = nve4_grctx_generate_unkn,
+	.hub   = nvd7_grctx_pack_hub,
+	.gpc   = nvd7_grctx_pack_gpc,
+	.zcull = nvc0_grctx_pack_zcull,
+	.tpc   = nvd7_grctx_pack_tpc,
+	.ppc   = nvd7_grctx_pack_ppc,
+	.icmd  = nvd9_grctx_pack_icmd,
+	.mthd  = nvd9_grctx_pack_mthd,
 }.base;

+ 142 - 136
drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c

@@ -22,38 +22,14 @@
  * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
 
-#include "nvc0.h"
+#include "ctxnvc0.h"
 
-struct nvc0_graph_init
-nvd9_grctx_init_90c0[] = {
-	{ 0x002700,   4, 0x40, 0x00000000 },
-	{ 0x002720,   4, 0x40, 0x00000000 },
-	{ 0x002704,   4, 0x40, 0x00000000 },
-	{ 0x002724,   4, 0x40, 0x00000000 },
-	{ 0x002708,   4, 0x40, 0x00000000 },
-	{ 0x002728,   4, 0x40, 0x00000000 },
-	{ 0x00270c,   8, 0x20, 0x00000000 },
-	{ 0x002710,   4, 0x40, 0x00014000 },
-	{ 0x002730,   4, 0x40, 0x00014000 },
-	{ 0x002714,   4, 0x40, 0x00000040 },
-	{ 0x002734,   4, 0x40, 0x00000040 },
-	{ 0x00030c,   1, 0x04, 0x00000001 },
-	{ 0x001944,   1, 0x04, 0x00000000 },
-	{ 0x000758,   1, 0x04, 0x00000100 },
-	{ 0x0002c4,   1, 0x04, 0x00000000 },
-	{ 0x000790,   5, 0x04, 0x00000000 },
-	{ 0x00077c,   1, 0x04, 0x00000000 },
-	{ 0x000204,   3, 0x04, 0x00000000 },
-	{ 0x000214,   1, 0x04, 0x00000000 },
-	{ 0x00024c,   1, 0x04, 0x00000000 },
-	{ 0x000d94,   1, 0x04, 0x00000001 },
-	{ 0x001608,   2, 0x04, 0x00000000 },
-	{ 0x001664,   1, 0x04, 0x00000000 },
-	{}
-};
+/*******************************************************************************
+ * PGRAPH context register lists
+ ******************************************************************************/
 
-struct nvc0_graph_init
-nvd9_grctx_init_icmd[] = {
+static const struct nvc0_graph_init
+nvd9_grctx_init_icmd_0[] = {
 	{ 0x001000,   1, 0x01, 0x00000004 },
 	{ 0x0000a9,   1, 0x01, 0x0000ffff },
 	{ 0x000038,   1, 0x01, 0x0fac6881 },
@@ -171,8 +147,7 @@ nvd9_grctx_init_icmd[] = {
 	{ 0x000586,   1, 0x01, 0x00000040 },
 	{ 0x000582,   2, 0x01, 0x00000080 },
 	{ 0x0005c2,   1, 0x01, 0x00000001 },
-	{ 0x000638,   1, 0x01, 0x00000001 },
-	{ 0x000639,   1, 0x01, 0x00000001 },
+	{ 0x000638,   2, 0x01, 0x00000001 },
 	{ 0x00063a,   1, 0x01, 0x00000002 },
 	{ 0x00063b,   2, 0x01, 0x00000001 },
 	{ 0x00063d,   1, 0x01, 0x00000002 },
@@ -233,15 +208,13 @@ nvd9_grctx_init_icmd[] = {
 	{ 0x000787,   1, 0x01, 0x000000cf },
 	{ 0x00078c,   1, 0x01, 0x00000008 },
 	{ 0x000792,   1, 0x01, 0x00000001 },
-	{ 0x000794,   1, 0x01, 0x00000001 },
-	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000794,   3, 0x01, 0x00000001 },
 	{ 0x000797,   1, 0x01, 0x000000cf },
 	{ 0x000836,   1, 0x01, 0x00000001 },
 	{ 0x00079a,   1, 0x01, 0x00000002 },
 	{ 0x000833,   1, 0x01, 0x04444480 },
 	{ 0x0007a1,   1, 0x01, 0x00000001 },
-	{ 0x0007a3,   1, 0x01, 0x00000001 },
-	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x0007a3,   3, 0x01, 0x00000001 },
 	{ 0x000831,   1, 0x01, 0x00000004 },
 	{ 0x00080c,   1, 0x01, 0x00000002 },
 	{ 0x00080d,   2, 0x01, 0x00000100 },
@@ -267,14 +240,12 @@ nvd9_grctx_init_icmd[] = {
 	{ 0x0006b1,   1, 0x01, 0x00000011 },
 	{ 0x00078c,   1, 0x01, 0x00000008 },
 	{ 0x000792,   1, 0x01, 0x00000001 },
-	{ 0x000794,   1, 0x01, 0x00000001 },
-	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000794,   3, 0x01, 0x00000001 },
 	{ 0x000797,   1, 0x01, 0x000000cf },
 	{ 0x00079a,   1, 0x01, 0x00000002 },
 	{ 0x000833,   1, 0x01, 0x04444480 },
 	{ 0x0007a1,   1, 0x01, 0x00000001 },
-	{ 0x0007a3,   1, 0x01, 0x00000001 },
-	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x0007a3,   3, 0x01, 0x00000001 },
 	{ 0x000831,   1, 0x01, 0x00000004 },
 	{ 0x01e100,   1, 0x01, 0x00000001 },
 	{ 0x001000,   1, 0x01, 0x00000014 },
@@ -299,18 +270,56 @@ nvd9_grctx_init_icmd[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvd9_grctx_init_unk40xx[] = {
-	{ 0x404004,  11, 0x04, 0x00000000 },
+const struct nvc0_graph_pack
+nvd9_grctx_pack_icmd[] = {
+	{ nvd9_grctx_init_icmd_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvd9_grctx_init_90c0_0[] = {
+	{ 0x002700,   8, 0x20, 0x00000000 },
+	{ 0x002704,   8, 0x20, 0x00000000 },
+	{ 0x002708,   8, 0x20, 0x00000000 },
+	{ 0x00270c,   8, 0x20, 0x00000000 },
+	{ 0x002710,   8, 0x20, 0x00014000 },
+	{ 0x002714,   8, 0x20, 0x00000040 },
+	{ 0x00030c,   1, 0x04, 0x00000001 },
+	{ 0x001944,   1, 0x04, 0x00000000 },
+	{ 0x000758,   1, 0x04, 0x00000100 },
+	{ 0x0002c4,   1, 0x04, 0x00000000 },
+	{ 0x000790,   5, 0x04, 0x00000000 },
+	{ 0x00077c,   1, 0x04, 0x00000000 },
+	{ 0x000204,   3, 0x04, 0x00000000 },
+	{ 0x000214,   1, 0x04, 0x00000000 },
+	{ 0x00024c,   1, 0x04, 0x00000000 },
+	{ 0x000d94,   1, 0x04, 0x00000001 },
+	{ 0x001608,   2, 0x04, 0x00000000 },
+	{ 0x001664,   1, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_pack
+nvd9_grctx_pack_mthd[] = {
+	{ nvc1_grctx_init_9097_0, 0x9097 },
+	{ nvc8_grctx_init_9197_0, 0x9197 },
+	{ nvc8_grctx_init_9297_0, 0x9297 },
+	{ nvc0_grctx_init_902d_0, 0x902d },
+	{ nvc0_grctx_init_9039_0, 0x9039 },
+	{ nvd9_grctx_init_90c0_0, 0x90c0 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvd9_grctx_init_fe_0[] = {
+	{ 0x404004,  10, 0x04, 0x00000000 },
 	{ 0x404044,   1, 0x04, 0x00000000 },
-	{ 0x404094,   1, 0x04, 0x00000000 },
-	{ 0x404098,  12, 0x04, 0x00000000 },
+	{ 0x404094,  13, 0x04, 0x00000000 },
 	{ 0x4040c8,   1, 0x04, 0xf0000087 },
 	{ 0x4040d0,   6, 0x04, 0x00000000 },
 	{ 0x4040e8,   1, 0x04, 0x00001000 },
 	{ 0x4040f8,   1, 0x04, 0x00000000 },
-	{ 0x404130,   1, 0x04, 0x00000000 },
-	{ 0x404134,   1, 0x04, 0x00000000 },
+	{ 0x404130,   2, 0x04, 0x00000000 },
 	{ 0x404138,   1, 0x04, 0x20000040 },
 	{ 0x404150,   1, 0x04, 0x0000002e },
 	{ 0x404154,   1, 0x04, 0x00000400 },
@@ -322,8 +331,8 @@ nvd9_grctx_init_unk40xx[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nvd9_grctx_init_unk58xx[] = {
+static const struct nvc0_graph_init
+nvd9_grctx_init_ds_0[] = {
 	{ 0x405800,   1, 0x04, 0x0f8000bf },
 	{ 0x405830,   1, 0x04, 0x02180218 },
 	{ 0x405834,   1, 0x04, 0x08000000 },
@@ -335,8 +344,10 @@ nvd9_grctx_init_unk58xx[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nvd9_grctx_init_unk64xx[] = {
+static const struct nvc0_graph_init
+nvd9_grctx_init_pd_0[] = {
+	{ 0x406020,   1, 0x04, 0x000103c1 },
+	{ 0x406028,   4, 0x04, 0x00000001 },
 	{ 0x4064a8,   1, 0x04, 0x00000000 },
 	{ 0x4064ac,   1, 0x04, 0x00003fff },
 	{ 0x4064b4,   3, 0x04, 0x00000000 },
@@ -345,21 +356,34 @@ nvd9_grctx_init_unk64xx[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvd9_grctx_init_rop[] = {
+const struct nvc0_graph_init
+nvd9_grctx_init_be_0[] = {
 	{ 0x408800,   1, 0x04, 0x02802a3c },
 	{ 0x408804,   1, 0x04, 0x00000040 },
 	{ 0x408808,   1, 0x04, 0x1043e005 },
 	{ 0x408900,   1, 0x04, 0x3080b801 },
-	{ 0x408904,   1, 0x04, 0x1043e005 },
+	{ 0x408904,   1, 0x04, 0x62000001 },
 	{ 0x408908,   1, 0x04, 0x00c8102f },
 	{ 0x408980,   1, 0x04, 0x0000011d },
 	{}
 };
 
-static struct nvc0_graph_init
-nvd9_grctx_init_gpc_0[] = {
-	{ 0x418380,   1, 0x04, 0x00000016 },
+static const struct nvc0_graph_pack
+nvd9_grctx_pack_hub[] = {
+	{ nvc0_grctx_init_main_0 },
+	{ nvd9_grctx_init_fe_0 },
+	{ nvc0_grctx_init_pri_0 },
+	{ nvc0_grctx_init_memfmt_0 },
+	{ nvd9_grctx_init_ds_0 },
+	{ nvd9_grctx_init_pd_0 },
+	{ nvc0_grctx_init_rstr2d_0 },
+	{ nvc0_grctx_init_scc_0 },
+	{ nvd9_grctx_init_be_0 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvd9_grctx_init_prop_0[] = {
 	{ 0x418400,   1, 0x04, 0x38004e00 },
 	{ 0x418404,   1, 0x04, 0x71e0ffff },
 	{ 0x41840c,   1, 0x04, 0x00001008 },
@@ -368,11 +392,21 @@ nvd9_grctx_init_gpc_0[] = {
 	{ 0x418450,   6, 0x04, 0x00000000 },
 	{ 0x418468,   1, 0x04, 0x00000001 },
 	{ 0x41846c,   2, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvd9_grctx_init_gpc_unk_1[] = {
 	{ 0x418600,   1, 0x04, 0x0000001f },
 	{ 0x418684,   1, 0x04, 0x0000000f },
 	{ 0x418700,   1, 0x04, 0x00000002 },
 	{ 0x418704,   1, 0x04, 0x00000080 },
 	{ 0x418708,   3, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvd9_grctx_init_setup_0[] = {
 	{ 0x418800,   1, 0x04, 0x7006860a },
 	{ 0x418808,   3, 0x04, 0x00000000 },
 	{ 0x418828,   1, 0x04, 0x00008442 },
@@ -381,10 +415,11 @@ nvd9_grctx_init_gpc_0[] = {
 	{ 0x4188e0,   1, 0x04, 0x01000000 },
 	{ 0x4188e8,   5, 0x04, 0x00000000 },
 	{ 0x4188fc,   1, 0x04, 0x20100008 },
-	{ 0x41891c,   1, 0x04, 0x00ff00ff },
-	{ 0x418924,   1, 0x04, 0x00000000 },
-	{ 0x418928,   1, 0x04, 0x00ffff00 },
-	{ 0x41892c,   1, 0x04, 0x0000ff00 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvd9_grctx_init_crstr_0[] = {
 	{ 0x418b00,   1, 0x04, 0x00000006 },
 	{ 0x418b08,   1, 0x04, 0x0a418820 },
 	{ 0x418b0c,   1, 0x04, 0x062080e6 },
@@ -393,24 +428,24 @@ nvd9_grctx_init_gpc_0[] = {
 	{ 0x418b18,   1, 0x04, 0x0a418820 },
 	{ 0x418b1c,   1, 0x04, 0x000000e6 },
 	{ 0x418bb8,   1, 0x04, 0x00000103 },
-	{ 0x418c08,   1, 0x04, 0x00000001 },
-	{ 0x418c10,   8, 0x04, 0x00000000 },
-	{ 0x418c6c,   1, 0x04, 0x00000001 },
-	{ 0x418c80,   1, 0x04, 0x20200004 },
-	{ 0x418c8c,   1, 0x04, 0x00000001 },
-	{ 0x419000,   1, 0x04, 0x00000780 },
-	{ 0x419004,   2, 0x04, 0x00000000 },
-	{ 0x419014,   1, 0x04, 0x00000004 },
 	{}
 };
 
-static struct nvc0_graph_init
-nvd9_grctx_init_tpc[] = {
-	{ 0x419818,   1, 0x04, 0x00000000 },
-	{ 0x41983c,   1, 0x04, 0x00038bc7 },
-	{ 0x419848,   1, 0x04, 0x00000000 },
-	{ 0x419864,   1, 0x04, 0x00000129 },
-	{ 0x419888,   1, 0x04, 0x00000000 },
+static const struct nvc0_graph_pack
+nvd9_grctx_pack_gpc[] = {
+	{ nvc0_grctx_init_gpc_unk_0 },
+	{ nvd9_grctx_init_prop_0 },
+	{ nvd9_grctx_init_gpc_unk_1 },
+	{ nvd9_grctx_init_setup_0 },
+	{ nvc0_grctx_init_zcull_0 },
+	{ nvd9_grctx_init_crstr_0 },
+	{ nvc1_grctx_init_gpm_0 },
+	{ nvc0_grctx_init_gcc_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvd9_grctx_init_tex_0[] = {
 	{ 0x419a00,   1, 0x04, 0x000001f0 },
 	{ 0x419a04,   1, 0x04, 0x00000001 },
 	{ 0x419a08,   1, 0x04, 0x00000023 },
@@ -420,27 +455,22 @@ nvd9_grctx_init_tpc[] = {
 	{ 0x419a1c,   1, 0x04, 0x00000000 },
 	{ 0x419a20,   1, 0x04, 0x00000800 },
 	{ 0x419ac4,   1, 0x04, 0x0017f440 },
-	{ 0x419b00,   1, 0x04, 0x0a418820 },
-	{ 0x419b04,   1, 0x04, 0x062080e6 },
-	{ 0x419b08,   1, 0x04, 0x020398a4 },
-	{ 0x419b0c,   1, 0x04, 0x0e629062 },
-	{ 0x419b10,   1, 0x04, 0x0a418820 },
-	{ 0x419b14,   1, 0x04, 0x000000e6 },
-	{ 0x419bd0,   1, 0x04, 0x00900103 },
-	{ 0x419be0,   1, 0x04, 0x00400001 },
-	{ 0x419be4,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvd9_grctx_init_mpc_0[] = {
 	{ 0x419c00,   1, 0x04, 0x0000000a },
 	{ 0x419c04,   1, 0x04, 0x00000006 },
 	{ 0x419c08,   1, 0x04, 0x00000002 },
 	{ 0x419c20,   1, 0x04, 0x00000000 },
 	{ 0x419c24,   1, 0x04, 0x00084210 },
 	{ 0x419c28,   1, 0x04, 0x3cf3cf3c },
-	{ 0x419cb0,   1, 0x04, 0x00020048 },
-	{ 0x419ce8,   1, 0x04, 0x00000000 },
-	{ 0x419cf4,   1, 0x04, 0x00000183 },
-	{ 0x419d20,   1, 0x04, 0x12180000 },
-	{ 0x419d24,   1, 0x04, 0x00001fff },
-	{ 0x419d44,   1, 0x04, 0x02180218 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvd9_grctx_init_sm_0[] = {
 	{ 0x419e04,   3, 0x04, 0x00000000 },
 	{ 0x419e10,   1, 0x04, 0x00000002 },
 	{ 0x419e44,   1, 0x04, 0x001beff2 },
@@ -453,47 +483,21 @@ nvd9_grctx_init_tpc[] = {
 	{}
 };
 
-static struct nvc0_graph_init *
-nvd9_grctx_init_hub[] = {
-	nvc0_grctx_init_base,
-	nvd9_grctx_init_unk40xx,
-	nvc0_grctx_init_unk44xx,
-	nvc0_grctx_init_unk46xx,
-	nvc0_grctx_init_unk47xx,
-	nvd9_grctx_init_unk58xx,
-	nvc0_grctx_init_unk60xx,
-	nvd9_grctx_init_unk64xx,
-	nvc0_grctx_init_unk78xx,
-	nvc0_grctx_init_unk80xx,
-	nvd9_grctx_init_rop,
-	NULL
-};
-
-struct nvc0_graph_init *
-nvd9_grctx_init_gpc[] = {
-	nvd9_grctx_init_gpc_0,
-	nvc0_grctx_init_gpc_1,
-	nvd9_grctx_init_tpc,
-	NULL
-};
-
-struct nvc0_graph_init
-nvd9_grctx_init_mthd_magic[] = {
-	{ 0x3410, 1, 0x04, 0x80002006 },
+static const struct nvc0_graph_pack
+nvd9_grctx_pack_tpc[] = {
+	{ nvc1_grctx_init_pe_0 },
+	{ nvd9_grctx_init_tex_0 },
+	{ nvc1_grctx_init_wwdx_0 },
+	{ nvd9_grctx_init_mpc_0 },
+	{ nvc4_grctx_init_l1c_0 },
+	{ nvc1_grctx_init_tpccs_0 },
+	{ nvd9_grctx_init_sm_0 },
 	{}
 };
 
-struct nvc0_graph_mthd
-nvd9_grctx_init_mthd[] = {
-	{ 0x9097, nvc1_grctx_init_9097, },
-	{ 0x9197, nvc8_grctx_init_9197, },
-	{ 0x9297, nvc8_grctx_init_9297, },
-	{ 0x902d, nvc0_grctx_init_902d, },
-	{ 0x9039, nvc0_grctx_init_9039, },
-	{ 0x90c0, nvd9_grctx_init_90c0, },
-	{ 0x902d, nvd9_grctx_init_mthd_magic, },
-	{}
-};
+/*******************************************************************************
+ * PGRAPH context implementation
+ ******************************************************************************/
 
 struct nouveau_oclass *
 nvd9_grctx_oclass = &(struct nvc0_grctx_oclass) {
@@ -506,11 +510,13 @@ nvd9_grctx_oclass = &(struct nvc0_grctx_oclass) {
 		.rd32 = _nouveau_graph_context_rd32,
 		.wr32 = _nouveau_graph_context_wr32,
 	},
-	.main = nvc0_grctx_generate_main,
-	.mods = nvc1_grctx_generate_mods,
-	.unkn = nvc1_grctx_generate_unkn,
-	.hub  = nvd9_grctx_init_hub,
-	.gpc  = nvd9_grctx_init_gpc,
-	.icmd = nvd9_grctx_init_icmd,
-	.mthd = nvd9_grctx_init_mthd,
+	.main  = nvc0_grctx_generate_main,
+	.mods  = nvc1_grctx_generate_mods,
+	.unkn  = nvc1_grctx_generate_unkn,
+	.hub   = nvd9_grctx_pack_hub,
+	.gpc   = nvd9_grctx_pack_gpc,
+	.zcull = nvc0_grctx_pack_zcull,
+	.tpc   = nvd9_grctx_pack_tpc,
+	.icmd  = nvd9_grctx_pack_icmd,
+	.mthd  = nvd9_grctx_pack_mthd,
 }.base;

+ 144 - 141
drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c

@@ -22,10 +22,14 @@
  * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
 
-#include "nvc0.h"
+#include "ctxnvc0.h"
 
-struct nvc0_graph_init
-nve4_grctx_init_icmd[] = {
+/*******************************************************************************
+ * PGRAPH context register lists
+ ******************************************************************************/
+
+static const struct nvc0_graph_init
+nve4_grctx_init_icmd_0[] = {
 	{ 0x001000,   1, 0x01, 0x00000004 },
 	{ 0x000039,   3, 0x01, 0x00000000 },
 	{ 0x0000a9,   1, 0x01, 0x0000ffff },
@@ -138,8 +142,7 @@ nve4_grctx_init_icmd[] = {
 	{ 0x000586,   1, 0x01, 0x00000040 },
 	{ 0x000582,   2, 0x01, 0x00000080 },
 	{ 0x0005c2,   1, 0x01, 0x00000001 },
-	{ 0x000638,   1, 0x01, 0x00000001 },
-	{ 0x000639,   1, 0x01, 0x00000001 },
+	{ 0x000638,   2, 0x01, 0x00000001 },
 	{ 0x00063a,   1, 0x01, 0x00000002 },
 	{ 0x00063b,   2, 0x01, 0x00000001 },
 	{ 0x00063d,   1, 0x01, 0x00000002 },
@@ -197,15 +200,13 @@ nve4_grctx_init_icmd[] = {
 	{ 0x000787,   1, 0x01, 0x000000cf },
 	{ 0x00078c,   1, 0x01, 0x00000008 },
 	{ 0x000792,   1, 0x01, 0x00000001 },
-	{ 0x000794,   1, 0x01, 0x00000001 },
-	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000794,   3, 0x01, 0x00000001 },
 	{ 0x000797,   1, 0x01, 0x000000cf },
 	{ 0x000836,   1, 0x01, 0x00000001 },
 	{ 0x00079a,   1, 0x01, 0x00000002 },
 	{ 0x000833,   1, 0x01, 0x04444480 },
 	{ 0x0007a1,   1, 0x01, 0x00000001 },
-	{ 0x0007a3,   1, 0x01, 0x00000001 },
-	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x0007a3,   3, 0x01, 0x00000001 },
 	{ 0x000831,   1, 0x01, 0x00000004 },
 	{ 0x000b07,   1, 0x01, 0x00000002 },
 	{ 0x000b08,   2, 0x01, 0x00000100 },
@@ -231,14 +232,12 @@ nve4_grctx_init_icmd[] = {
 	{ 0x0006b1,   1, 0x01, 0x00000011 },
 	{ 0x00078c,   1, 0x01, 0x00000008 },
 	{ 0x000792,   1, 0x01, 0x00000001 },
-	{ 0x000794,   1, 0x01, 0x00000001 },
-	{ 0x000795,   2, 0x01, 0x00000001 },
+	{ 0x000794,   3, 0x01, 0x00000001 },
 	{ 0x000797,   1, 0x01, 0x000000cf },
 	{ 0x00079a,   1, 0x01, 0x00000002 },
 	{ 0x000833,   1, 0x01, 0x04444480 },
 	{ 0x0007a1,   1, 0x01, 0x00000001 },
-	{ 0x0007a3,   1, 0x01, 0x00000001 },
-	{ 0x0007a4,   2, 0x01, 0x00000001 },
+	{ 0x0007a3,   3, 0x01, 0x00000001 },
 	{ 0x000831,   1, 0x01, 0x00000004 },
 	{ 0x01e100,   1, 0x01, 0x00000001 },
 	{ 0x001000,   1, 0x01, 0x00000008 },
@@ -273,8 +272,14 @@ nve4_grctx_init_icmd[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nve4_grctx_init_a097[] = {
+static const struct nvc0_graph_pack
+nve4_grctx_pack_icmd[] = {
+	{ nve4_grctx_init_icmd_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nve4_grctx_init_a097_0[] = {
 	{ 0x000800,   8, 0x40, 0x00000000 },
 	{ 0x000804,   8, 0x40, 0x00000000 },
 	{ 0x000808,   8, 0x40, 0x00000400 },
@@ -517,8 +522,7 @@ nve4_grctx_init_a097[] = {
 	{ 0x001350,   1, 0x04, 0x00000002 },
 	{ 0x001358,   1, 0x04, 0x00000001 },
 	{ 0x0012e4,   1, 0x04, 0x00000000 },
-	{ 0x00131c,   1, 0x04, 0x00000000 },
-	{ 0x001320,   3, 0x04, 0x00000000 },
+	{ 0x00131c,   4, 0x04, 0x00000000 },
 	{ 0x0019c0,   1, 0x04, 0x00000000 },
 	{ 0x001140,   1, 0x04, 0x00000000 },
 	{ 0x0019c4,   1, 0x04, 0x00000000 },
@@ -574,19 +578,24 @@ nve4_grctx_init_a097[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nve4_grctx_init_unk40xx[] = {
+static const struct nvc0_graph_pack
+nve4_grctx_pack_mthd[] = {
+	{ nve4_grctx_init_a097_0, 0xa097 },
+	{ nvc0_grctx_init_902d_0, 0x902d },
+	{}
+};
+
+static const struct nvc0_graph_init
+nve4_grctx_init_fe_0[] = {
 	{ 0x404010,   5, 0x04, 0x00000000 },
 	{ 0x404024,   1, 0x04, 0x0000e000 },
 	{ 0x404028,   1, 0x04, 0x00000000 },
-	{ 0x4040a8,   1, 0x04, 0x00000000 },
-	{ 0x4040ac,   7, 0x04, 0x00000000 },
+	{ 0x4040a8,   8, 0x04, 0x00000000 },
 	{ 0x4040c8,   1, 0x04, 0xf800008f },
 	{ 0x4040d0,   6, 0x04, 0x00000000 },
 	{ 0x4040e8,   1, 0x04, 0x00001000 },
 	{ 0x4040f8,   1, 0x04, 0x00000000 },
-	{ 0x404130,   1, 0x04, 0x00000000 },
-	{ 0x404134,   1, 0x04, 0x00000000 },
+	{ 0x404130,   2, 0x04, 0x00000000 },
 	{ 0x404138,   1, 0x04, 0x20000040 },
 	{ 0x404150,   1, 0x04, 0x0000002e },
 	{ 0x404154,   1, 0x04, 0x00000400 },
@@ -597,8 +606,8 @@ nve4_grctx_init_unk40xx[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nve4_grctx_init_unk46xx[] = {
+const struct nvc0_graph_init
+nve4_grctx_init_memfmt_0[] = {
 	{ 0x404604,   1, 0x04, 0x00000014 },
 	{ 0x404608,   1, 0x04, 0x00000000 },
 	{ 0x40460c,   1, 0x04, 0x00003fff },
@@ -614,11 +623,6 @@ nve4_grctx_init_unk46xx[] = {
 	{ 0x4046a0,   1, 0x04, 0x007f0080 },
 	{ 0x4046a4,   8, 0x04, 0x00000000 },
 	{ 0x4046c8,   3, 0x04, 0x00000000 },
-	{}
-};
-
-struct nvc0_graph_init
-nve4_grctx_init_unk47xx[] = {
 	{ 0x404700,   3, 0x04, 0x00000000 },
 	{ 0x404718,   7, 0x04, 0x00000000 },
 	{ 0x404734,   1, 0x04, 0x00000100 },
@@ -628,8 +632,8 @@ nve4_grctx_init_unk47xx[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nve4_grctx_init_unk58xx[] = {
+const struct nvc0_graph_init
+nve4_grctx_init_ds_0[] = {
 	{ 0x405800,   1, 0x04, 0x0f8000bf },
 	{ 0x405830,   1, 0x04, 0x02180648 },
 	{ 0x405834,   1, 0x04, 0x08000000 },
@@ -641,22 +645,17 @@ nve4_grctx_init_unk58xx[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nve4_grctx_init_unk5bxx[] = {
+static const struct nvc0_graph_init
+nve4_grctx_init_cwd_0[] = {
 	{ 0x405b00,   1, 0x04, 0x00000000 },
 	{ 0x405b10,   1, 0x04, 0x00001000 },
 	{}
 };
 
-static struct nvc0_graph_init
-nve4_grctx_init_unk60xx[] = {
+static const struct nvc0_graph_init
+nve4_grctx_init_pd_0[] = {
 	{ 0x406020,   1, 0x04, 0x004103c1 },
 	{ 0x406028,   4, 0x04, 0x00000001 },
-	{}
-};
-
-static struct nvc0_graph_init
-nve4_grctx_init_unk64xx[] = {
 	{ 0x4064a8,   1, 0x04, 0x00000000 },
 	{ 0x4064ac,   1, 0x04, 0x00003fff },
 	{ 0x4064b4,   2, 0x04, 0x00000000 },
@@ -668,14 +667,14 @@ nve4_grctx_init_unk64xx[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nve4_grctx_init_unk70xx[] = {
+static const struct nvc0_graph_init
+nve4_grctx_init_sked_0[] = {
 	{ 0x407040,   1, 0x04, 0x00000000 },
 	{}
 };
 
-struct nvc0_graph_init
-nve4_grctx_init_unk80xx[] = {
+const struct nvc0_graph_init
+nve4_grctx_init_scc_0[] = {
 	{ 0x408000,   2, 0x04, 0x00000000 },
 	{ 0x408008,   1, 0x04, 0x00000030 },
 	{ 0x40800c,   2, 0x04, 0x00000000 },
@@ -685,8 +684,8 @@ nve4_grctx_init_unk80xx[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nve4_grctx_init_rop[] = {
+static const struct nvc0_graph_init
+nve4_grctx_init_be_0[] = {
 	{ 0x408800,   1, 0x04, 0x02802a3c },
 	{ 0x408804,   1, 0x04, 0x00000040 },
 	{ 0x408808,   1, 0x04, 0x1043e005 },
@@ -698,22 +697,24 @@ nve4_grctx_init_rop[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nve4_grctx_init_gpc_0[] = {
-	{ 0x418380,   1, 0x04, 0x00000016 },
-	{ 0x418400,   1, 0x04, 0x38004e00 },
-	{ 0x418404,   1, 0x04, 0x71e0ffff },
-	{ 0x41840c,   1, 0x04, 0x00001008 },
-	{ 0x418410,   1, 0x04, 0x0fff0fff },
-	{ 0x418414,   1, 0x04, 0x02200fff },
-	{ 0x418450,   6, 0x04, 0x00000000 },
-	{ 0x418468,   1, 0x04, 0x00000001 },
-	{ 0x41846c,   2, 0x04, 0x00000000 },
-	{ 0x418600,   1, 0x04, 0x0000001f },
-	{ 0x418684,   1, 0x04, 0x0000000f },
-	{ 0x418700,   1, 0x04, 0x00000002 },
-	{ 0x418704,   1, 0x04, 0x00000080 },
-	{ 0x418708,   3, 0x04, 0x00000000 },
+static const struct nvc0_graph_pack
+nve4_grctx_pack_hub[] = {
+	{ nvc0_grctx_init_main_0 },
+	{ nve4_grctx_init_fe_0 },
+	{ nvc0_grctx_init_pri_0 },
+	{ nve4_grctx_init_memfmt_0 },
+	{ nve4_grctx_init_ds_0 },
+	{ nve4_grctx_init_cwd_0 },
+	{ nve4_grctx_init_pd_0 },
+	{ nve4_grctx_init_sked_0 },
+	{ nvc0_grctx_init_rstr2d_0 },
+	{ nve4_grctx_init_scc_0 },
+	{ nve4_grctx_init_be_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nve4_grctx_init_setup_0[] = {
 	{ 0x418800,   1, 0x04, 0x7006860a },
 	{ 0x418808,   3, 0x04, 0x00000000 },
 	{ 0x418828,   1, 0x04, 0x00000044 },
@@ -722,35 +723,35 @@ nve4_grctx_init_gpc_0[] = {
 	{ 0x4188e0,   1, 0x04, 0x01000000 },
 	{ 0x4188e8,   5, 0x04, 0x00000000 },
 	{ 0x4188fc,   1, 0x04, 0x20100018 },
-	{ 0x41891c,   1, 0x04, 0x00ff00ff },
-	{ 0x418924,   1, 0x04, 0x00000000 },
-	{ 0x418928,   1, 0x04, 0x00ffff00 },
-	{ 0x41892c,   1, 0x04, 0x0000ff00 },
-	{ 0x418b00,   1, 0x04, 0x00000006 },
-	{ 0x418b08,   1, 0x04, 0x0a418820 },
-	{ 0x418b0c,   1, 0x04, 0x062080e6 },
-	{ 0x418b10,   1, 0x04, 0x020398a4 },
-	{ 0x418b14,   1, 0x04, 0x0e629062 },
-	{ 0x418b18,   1, 0x04, 0x0a418820 },
-	{ 0x418b1c,   1, 0x04, 0x000000e6 },
-	{ 0x418bb8,   1, 0x04, 0x00000103 },
+	{}
+};
+
+const struct nvc0_graph_init
+nve4_grctx_init_gpm_0[] = {
 	{ 0x418c08,   1, 0x04, 0x00000001 },
 	{ 0x418c10,   8, 0x04, 0x00000000 },
 	{ 0x418c40,   1, 0x04, 0xffffffff },
 	{ 0x418c6c,   1, 0x04, 0x00000001 },
 	{ 0x418c80,   1, 0x04, 0x20200004 },
 	{ 0x418c8c,   1, 0x04, 0x00000001 },
-	{ 0x419000,   1, 0x04, 0x00000780 },
-	{ 0x419004,   2, 0x04, 0x00000000 },
-	{ 0x419014,   1, 0x04, 0x00000004 },
 	{}
 };
 
-static struct nvc0_graph_init
-nve4_grctx_init_tpc[] = {
-	{ 0x419848,   1, 0x04, 0x00000000 },
-	{ 0x419864,   1, 0x04, 0x00000129 },
-	{ 0x419888,   1, 0x04, 0x00000000 },
+static const struct nvc0_graph_pack
+nve4_grctx_pack_gpc[] = {
+	{ nvc0_grctx_init_gpc_unk_0 },
+	{ nvd9_grctx_init_prop_0 },
+	{ nvd9_grctx_init_gpc_unk_1 },
+	{ nve4_grctx_init_setup_0 },
+	{ nvc0_grctx_init_zcull_0 },
+	{ nvd9_grctx_init_crstr_0 },
+	{ nve4_grctx_init_gpm_0 },
+	{ nvc0_grctx_init_gcc_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nve4_grctx_init_tex_0[] = {
 	{ 0x419a00,   1, 0x04, 0x000000f0 },
 	{ 0x419a04,   1, 0x04, 0x00000001 },
 	{ 0x419a08,   1, 0x04, 0x00000021 },
@@ -761,14 +762,29 @@ nve4_grctx_init_tpc[] = {
 	{ 0x419a20,   1, 0x04, 0x00000800 },
 	{ 0x419a30,   1, 0x04, 0x00000001 },
 	{ 0x419ac4,   1, 0x04, 0x0037f440 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nve4_grctx_init_mpc_0[] = {
 	{ 0x419c00,   1, 0x04, 0x0000000a },
 	{ 0x419c04,   1, 0x04, 0x80000006 },
 	{ 0x419c08,   1, 0x04, 0x00000002 },
 	{ 0x419c20,   1, 0x04, 0x00000000 },
 	{ 0x419c24,   1, 0x04, 0x00084210 },
 	{ 0x419c28,   1, 0x04, 0x3efbefbe },
+	{}
+};
+
+static const struct nvc0_graph_init
+nve4_grctx_init_l1c_0[] = {
 	{ 0x419ce8,   1, 0x04, 0x00000000 },
 	{ 0x419cf4,   1, 0x04, 0x00003203 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nve4_grctx_init_sm_0[] = {
 	{ 0x419e04,   3, 0x04, 0x00000000 },
 	{ 0x419e10,   1, 0x04, 0x00000402 },
 	{ 0x419e44,   1, 0x04, 0x0013eff2 },
@@ -782,28 +798,46 @@ nve4_grctx_init_tpc[] = {
 	{ 0x419f58,   1, 0x04, 0x00000000 },
 	{ 0x419f70,   1, 0x04, 0x00000000 },
 	{ 0x419f78,   1, 0x04, 0x0000000b },
-	{ 0x419f7c,   1, 0x04, 0x0000027a },
+	{ 0x419f7c,   1, 0x04, 0x0000027c },
+	{}
+};
+
+static const struct nvc0_graph_pack
+nve4_grctx_pack_tpc[] = {
+	{ nvd7_grctx_init_pe_0 },
+	{ nve4_grctx_init_tex_0 },
+	{ nve4_grctx_init_mpc_0 },
+	{ nve4_grctx_init_l1c_0 },
+	{ nve4_grctx_init_sm_0 },
 	{}
 };
 
-static struct nvc0_graph_init
-nve4_grctx_init_unk[] = {
+const struct nvc0_graph_init
+nve4_grctx_init_pes_0[] = {
 	{ 0x41be24,   1, 0x04, 0x00000006 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nve4_grctx_init_cbm_0[] = {
 	{ 0x41bec0,   1, 0x04, 0x12180000 },
 	{ 0x41bec4,   1, 0x04, 0x00037f7f },
 	{ 0x41bee4,   1, 0x04, 0x06480430 },
-	{ 0x41bf00,   1, 0x04, 0x0a418820 },
-	{ 0x41bf04,   1, 0x04, 0x062080e6 },
-	{ 0x41bf08,   1, 0x04, 0x020398a4 },
-	{ 0x41bf0c,   1, 0x04, 0x0e629062 },
-	{ 0x41bf10,   1, 0x04, 0x0a418820 },
-	{ 0x41bf14,   1, 0x04, 0x000000e6 },
-	{ 0x41bfd0,   1, 0x04, 0x00900103 },
-	{ 0x41bfe0,   1, 0x04, 0x00400001 },
-	{ 0x41bfe4,   1, 0x04, 0x00000000 },
 	{}
 };
 
+static const struct nvc0_graph_pack
+nve4_grctx_pack_ppc[] = {
+	{ nve4_grctx_init_pes_0 },
+	{ nve4_grctx_init_cbm_0 },
+	{ nvd7_grctx_init_wwdx_0 },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH context implementation
+ ******************************************************************************/
+
 static void
 nve4_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
 {
@@ -925,10 +959,11 @@ nve4_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
 
 	nv_mask(priv, 0x000260, 0x00000001, 0x00000000);
 
-	for (i = 0; oclass->hub[i]; i++)
-		nvc0_graph_mmio(priv, oclass->hub[i]);
-	for (i = 0; oclass->gpc[i]; i++)
-		nvc0_graph_mmio(priv, oclass->gpc[i]);
+	nvc0_graph_mmio(priv, oclass->hub);
+	nvc0_graph_mmio(priv, oclass->gpc);
+	nvc0_graph_mmio(priv, oclass->zcull);
+	nvc0_graph_mmio(priv, oclass->tpc);
+	nvc0_graph_mmio(priv, oclass->ppc);
 
 	nv_wr32(priv, 0x404154, 0x00000000);
 
@@ -962,41 +997,6 @@ nve4_grctx_generate_main(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
 	nv_mask(priv, 0x41be10, 0x00800000, 0x00800000);
 }
 
-static struct nvc0_graph_init *
-nve4_grctx_init_hub[] = {
-	nvc0_grctx_init_base,
-	nve4_grctx_init_unk40xx,
-	nvc0_grctx_init_unk44xx,
-	nve4_grctx_init_unk46xx,
-	nve4_grctx_init_unk47xx,
-	nve4_grctx_init_unk58xx,
-	nve4_grctx_init_unk5bxx,
-	nve4_grctx_init_unk60xx,
-	nve4_grctx_init_unk64xx,
-	nve4_grctx_init_unk70xx,
-	nvc0_grctx_init_unk78xx,
-	nve4_grctx_init_unk80xx,
-	nve4_grctx_init_rop,
-	NULL
-};
-
-struct nvc0_graph_init *
-nve4_grctx_init_gpc[] = {
-	nve4_grctx_init_gpc_0,
-	nvc0_grctx_init_gpc_1,
-	nve4_grctx_init_tpc,
-	nve4_grctx_init_unk,
-	NULL
-};
-
-static struct nvc0_graph_mthd
-nve4_grctx_init_mthd[] = {
-	{ 0xa097, nve4_grctx_init_a097, },
-	{ 0x902d, nvc0_grctx_init_902d, },
-	{ 0x902d, nvc0_grctx_init_mthd_magic, },
-	{}
-};
-
 struct nouveau_oclass *
 nve4_grctx_oclass = &(struct nvc0_grctx_oclass) {
 	.base.handle = NV_ENGCTX(GR, 0xe4),
@@ -1008,11 +1008,14 @@ nve4_grctx_oclass = &(struct nvc0_grctx_oclass) {
 		.rd32 = _nouveau_graph_context_rd32,
 		.wr32 = _nouveau_graph_context_wr32,
 	},
-	.main = nve4_grctx_generate_main,
-	.mods = nve4_grctx_generate_mods,
-	.unkn = nve4_grctx_generate_unkn,
-	.hub  = nve4_grctx_init_hub,
-	.gpc  = nve4_grctx_init_gpc,
-	.icmd = nve4_grctx_init_icmd,
-	.mthd = nve4_grctx_init_mthd,
+	.main  = nve4_grctx_generate_main,
+	.mods  = nve4_grctx_generate_mods,
+	.unkn  = nve4_grctx_generate_unkn,
+	.hub   = nve4_grctx_pack_hub,
+	.gpc   = nve4_grctx_pack_gpc,
+	.zcull = nvc0_grctx_pack_zcull,
+	.tpc   = nve4_grctx_pack_tpc,
+	.ppc   = nve4_grctx_pack_ppc,
+	.icmd  = nve4_grctx_pack_icmd,
+	.mthd  = nve4_grctx_pack_mthd,
 }.base;

+ 670 - 112
drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c

@@ -22,10 +22,580 @@
  * Authors: Ben Skeggs <bskeggs@redhat.com>
  */
 
-#include "nvc0.h"
+#include "ctxnvc0.h"
 
-static struct nvc0_graph_init
-nvf0_grctx_init_unk40xx[] = {
+/*******************************************************************************
+ * PGRAPH context register lists
+ ******************************************************************************/
+
+static const struct nvc0_graph_init
+nvf0_grctx_init_icmd_0[] = {
+	{ 0x001000,   1, 0x01, 0x00000004 },
+	{ 0x000039,   3, 0x01, 0x00000000 },
+	{ 0x0000a9,   1, 0x01, 0x0000ffff },
+	{ 0x000038,   1, 0x01, 0x0fac6881 },
+	{ 0x00003d,   1, 0x01, 0x00000001 },
+	{ 0x0000e8,   8, 0x01, 0x00000400 },
+	{ 0x000078,   8, 0x01, 0x00000300 },
+	{ 0x000050,   1, 0x01, 0x00000011 },
+	{ 0x000058,   8, 0x01, 0x00000008 },
+	{ 0x000208,   8, 0x01, 0x00000001 },
+	{ 0x000081,   1, 0x01, 0x00000001 },
+	{ 0x000085,   1, 0x01, 0x00000004 },
+	{ 0x000088,   1, 0x01, 0x00000400 },
+	{ 0x000090,   1, 0x01, 0x00000300 },
+	{ 0x000098,   1, 0x01, 0x00001001 },
+	{ 0x0000e3,   1, 0x01, 0x00000001 },
+	{ 0x0000da,   1, 0x01, 0x00000001 },
+	{ 0x0000f8,   1, 0x01, 0x00000003 },
+	{ 0x0000fa,   1, 0x01, 0x00000001 },
+	{ 0x00009f,   4, 0x01, 0x0000ffff },
+	{ 0x0000b1,   1, 0x01, 0x00000001 },
+	{ 0x0000ad,   1, 0x01, 0x0000013e },
+	{ 0x0000e1,   1, 0x01, 0x00000010 },
+	{ 0x000290,  16, 0x01, 0x00000000 },
+	{ 0x0003b0,  16, 0x01, 0x00000000 },
+	{ 0x0002a0,  16, 0x01, 0x00000000 },
+	{ 0x000420,  16, 0x01, 0x00000000 },
+	{ 0x0002b0,  16, 0x01, 0x00000000 },
+	{ 0x000430,  16, 0x01, 0x00000000 },
+	{ 0x0002c0,  16, 0x01, 0x00000000 },
+	{ 0x0004d0,  16, 0x01, 0x00000000 },
+	{ 0x000720,  16, 0x01, 0x00000000 },
+	{ 0x0008c0,  16, 0x01, 0x00000000 },
+	{ 0x000890,  16, 0x01, 0x00000000 },
+	{ 0x0008e0,  16, 0x01, 0x00000000 },
+	{ 0x0008a0,  16, 0x01, 0x00000000 },
+	{ 0x0008f0,  16, 0x01, 0x00000000 },
+	{ 0x00094c,   1, 0x01, 0x000000ff },
+	{ 0x00094d,   1, 0x01, 0xffffffff },
+	{ 0x00094e,   1, 0x01, 0x00000002 },
+	{ 0x0002ec,   1, 0x01, 0x00000001 },
+	{ 0x0002f2,   2, 0x01, 0x00000001 },
+	{ 0x0002f5,   1, 0x01, 0x00000001 },
+	{ 0x0002f7,   1, 0x01, 0x00000001 },
+	{ 0x000303,   1, 0x01, 0x00000001 },
+	{ 0x0002e6,   1, 0x01, 0x00000001 },
+	{ 0x000466,   1, 0x01, 0x00000052 },
+	{ 0x000301,   1, 0x01, 0x3f800000 },
+	{ 0x000304,   1, 0x01, 0x30201000 },
+	{ 0x000305,   1, 0x01, 0x70605040 },
+	{ 0x000306,   1, 0x01, 0xb8a89888 },
+	{ 0x000307,   1, 0x01, 0xf8e8d8c8 },
+	{ 0x00030a,   1, 0x01, 0x00ffff00 },
+	{ 0x00030b,   1, 0x01, 0x0000001a },
+	{ 0x00030c,   1, 0x01, 0x00000001 },
+	{ 0x000318,   1, 0x01, 0x00000001 },
+	{ 0x000340,   1, 0x01, 0x00000000 },
+	{ 0x000375,   1, 0x01, 0x00000001 },
+	{ 0x00037d,   1, 0x01, 0x00000006 },
+	{ 0x0003a0,   1, 0x01, 0x00000002 },
+	{ 0x0003aa,   1, 0x01, 0x00000001 },
+	{ 0x0003a9,   1, 0x01, 0x00000001 },
+	{ 0x000380,   1, 0x01, 0x00000001 },
+	{ 0x000383,   1, 0x01, 0x00000011 },
+	{ 0x000360,   1, 0x01, 0x00000040 },
+	{ 0x000366,   2, 0x01, 0x00000000 },
+	{ 0x000368,   1, 0x01, 0x00000fff },
+	{ 0x000370,   2, 0x01, 0x00000000 },
+	{ 0x000372,   1, 0x01, 0x000fffff },
+	{ 0x00037a,   1, 0x01, 0x00000012 },
+	{ 0x000619,   1, 0x01, 0x00000003 },
+	{ 0x000811,   1, 0x01, 0x00000003 },
+	{ 0x000812,   1, 0x01, 0x00000004 },
+	{ 0x000813,   1, 0x01, 0x00000006 },
+	{ 0x000814,   1, 0x01, 0x00000008 },
+	{ 0x000815,   1, 0x01, 0x0000000b },
+	{ 0x000800,   6, 0x01, 0x00000001 },
+	{ 0x000632,   1, 0x01, 0x00000001 },
+	{ 0x000633,   1, 0x01, 0x00000002 },
+	{ 0x000634,   1, 0x01, 0x00000003 },
+	{ 0x000635,   1, 0x01, 0x00000004 },
+	{ 0x000654,   1, 0x01, 0x3f800000 },
+	{ 0x000657,   1, 0x01, 0x3f800000 },
+	{ 0x000655,   2, 0x01, 0x3f800000 },
+	{ 0x0006cd,   1, 0x01, 0x3f800000 },
+	{ 0x0007f5,   1, 0x01, 0x3f800000 },
+	{ 0x0007dc,   1, 0x01, 0x39291909 },
+	{ 0x0007dd,   1, 0x01, 0x79695949 },
+	{ 0x0007de,   1, 0x01, 0xb9a99989 },
+	{ 0x0007df,   1, 0x01, 0xf9e9d9c9 },
+	{ 0x0007e8,   1, 0x01, 0x00003210 },
+	{ 0x0007e9,   1, 0x01, 0x00007654 },
+	{ 0x0007ea,   1, 0x01, 0x00000098 },
+	{ 0x0007ec,   1, 0x01, 0x39291909 },
+	{ 0x0007ed,   1, 0x01, 0x79695949 },
+	{ 0x0007ee,   1, 0x01, 0xb9a99989 },
+	{ 0x0007ef,   1, 0x01, 0xf9e9d9c9 },
+	{ 0x0007f0,   1, 0x01, 0x00003210 },
+	{ 0x0007f1,   1, 0x01, 0x00007654 },
+	{ 0x0007f2,   1, 0x01, 0x00000098 },
+	{ 0x0005a5,   1, 0x01, 0x00000001 },
+	{ 0x000980, 128, 0x01, 0x00000000 },
+	{ 0x000468,   1, 0x01, 0x00000004 },
+	{ 0x00046c,   1, 0x01, 0x00000001 },
+	{ 0x000470,  96, 0x01, 0x00000000 },
+	{ 0x000510,  16, 0x01, 0x3f800000 },
+	{ 0x000520,   1, 0x01, 0x000002b6 },
+	{ 0x000529,   1, 0x01, 0x00000001 },
+	{ 0x000530,  16, 0x01, 0xffff0000 },
+	{ 0x000585,   1, 0x01, 0x0000003f },
+	{ 0x000576,   1, 0x01, 0x00000003 },
+	{ 0x00057b,   1, 0x01, 0x00000059 },
+	{ 0x000586,   1, 0x01, 0x00000040 },
+	{ 0x000582,   2, 0x01, 0x00000080 },
+	{ 0x0005c2,   1, 0x01, 0x00000001 },
+	{ 0x000638,   2, 0x01, 0x00000001 },
+	{ 0x00063a,   1, 0x01, 0x00000002 },
+	{ 0x00063b,   2, 0x01, 0x00000001 },
+	{ 0x00063d,   1, 0x01, 0x00000002 },
+	{ 0x00063e,   1, 0x01, 0x00000001 },
+	{ 0x0008b8,   8, 0x01, 0x00000001 },
+	{ 0x000900,   8, 0x01, 0x00000001 },
+	{ 0x000908,   8, 0x01, 0x00000002 },
+	{ 0x000910,  16, 0x01, 0x00000001 },
+	{ 0x000920,   8, 0x01, 0x00000002 },
+	{ 0x000928,   8, 0x01, 0x00000001 },
+	{ 0x000662,   1, 0x01, 0x00000001 },
+	{ 0x000648,   9, 0x01, 0x00000001 },
+	{ 0x000658,   1, 0x01, 0x0000000f },
+	{ 0x0007ff,   1, 0x01, 0x0000000a },
+	{ 0x00066a,   1, 0x01, 0x40000000 },
+	{ 0x00066b,   1, 0x01, 0x10000000 },
+	{ 0x00066c,   2, 0x01, 0xffff0000 },
+	{ 0x0007af,   2, 0x01, 0x00000008 },
+	{ 0x0007f6,   1, 0x01, 0x00000001 },
+	{ 0x00080b,   1, 0x01, 0x00000002 },
+	{ 0x0006b2,   1, 0x01, 0x00000055 },
+	{ 0x0007ad,   1, 0x01, 0x00000003 },
+	{ 0x000937,   1, 0x01, 0x00000001 },
+	{ 0x000971,   1, 0x01, 0x00000008 },
+	{ 0x000972,   1, 0x01, 0x00000040 },
+	{ 0x000973,   1, 0x01, 0x0000012c },
+	{ 0x00097c,   1, 0x01, 0x00000040 },
+	{ 0x000979,   1, 0x01, 0x00000003 },
+	{ 0x000975,   1, 0x01, 0x00000020 },
+	{ 0x000976,   1, 0x01, 0x00000001 },
+	{ 0x000977,   1, 0x01, 0x00000020 },
+	{ 0x000978,   1, 0x01, 0x00000001 },
+	{ 0x000957,   1, 0x01, 0x00000003 },
+	{ 0x00095e,   1, 0x01, 0x20164010 },
+	{ 0x00095f,   1, 0x01, 0x00000020 },
+	{ 0x000a0d,   1, 0x01, 0x00000006 },
+	{ 0x00097d,   1, 0x01, 0x00000020 },
+	{ 0x000683,   1, 0x01, 0x00000006 },
+	{ 0x000685,   1, 0x01, 0x003fffff },
+	{ 0x000687,   1, 0x01, 0x003fffff },
+	{ 0x0006a0,   1, 0x01, 0x00000005 },
+	{ 0x000840,   1, 0x01, 0x00400008 },
+	{ 0x000841,   1, 0x01, 0x08000080 },
+	{ 0x000842,   1, 0x01, 0x00400008 },
+	{ 0x000843,   1, 0x01, 0x08000080 },
+	{ 0x0006aa,   1, 0x01, 0x00000001 },
+	{ 0x0006ab,   1, 0x01, 0x00000002 },
+	{ 0x0006ac,   1, 0x01, 0x00000080 },
+	{ 0x0006ad,   2, 0x01, 0x00000100 },
+	{ 0x0006b1,   1, 0x01, 0x00000011 },
+	{ 0x0006bb,   1, 0x01, 0x000000cf },
+	{ 0x0006ce,   1, 0x01, 0x2a712488 },
+	{ 0x000739,   1, 0x01, 0x4085c000 },
+	{ 0x00073a,   1, 0x01, 0x00000080 },
+	{ 0x000786,   1, 0x01, 0x80000100 },
+	{ 0x00073c,   1, 0x01, 0x00010100 },
+	{ 0x00073d,   1, 0x01, 0x02800000 },
+	{ 0x000787,   1, 0x01, 0x000000cf },
+	{ 0x00078c,   1, 0x01, 0x00000008 },
+	{ 0x000792,   1, 0x01, 0x00000001 },
+	{ 0x000794,   3, 0x01, 0x00000001 },
+	{ 0x000797,   1, 0x01, 0x000000cf },
+	{ 0x000836,   1, 0x01, 0x00000001 },
+	{ 0x00079a,   1, 0x01, 0x00000002 },
+	{ 0x000833,   1, 0x01, 0x04444480 },
+	{ 0x0007a1,   1, 0x01, 0x00000001 },
+	{ 0x0007a3,   3, 0x01, 0x00000001 },
+	{ 0x000831,   1, 0x01, 0x00000004 },
+	{ 0x000b07,   1, 0x01, 0x00000002 },
+	{ 0x000b08,   2, 0x01, 0x00000100 },
+	{ 0x000b0a,   1, 0x01, 0x00000001 },
+	{ 0x000a04,   1, 0x01, 0x000000ff },
+	{ 0x000a0b,   1, 0x01, 0x00000040 },
+	{ 0x00097f,   1, 0x01, 0x00000100 },
+	{ 0x000a02,   1, 0x01, 0x00000001 },
+	{ 0x000809,   1, 0x01, 0x00000007 },
+	{ 0x00c221,   1, 0x01, 0x00000040 },
+	{ 0x00c1b0,   8, 0x01, 0x0000000f },
+	{ 0x00c1b8,   1, 0x01, 0x0fac6881 },
+	{ 0x00c1b9,   1, 0x01, 0x00fac688 },
+	{ 0x00c401,   1, 0x01, 0x00000001 },
+	{ 0x00c402,   1, 0x01, 0x00010001 },
+	{ 0x00c403,   2, 0x01, 0x00000001 },
+	{ 0x00c40e,   1, 0x01, 0x00000020 },
+	{ 0x00c500,   1, 0x01, 0x00000003 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000002 },
+	{ 0x0006aa,   1, 0x01, 0x00000001 },
+	{ 0x0006ad,   2, 0x01, 0x00000100 },
+	{ 0x0006b1,   1, 0x01, 0x00000011 },
+	{ 0x00078c,   1, 0x01, 0x00000008 },
+	{ 0x000792,   1, 0x01, 0x00000001 },
+	{ 0x000794,   3, 0x01, 0x00000001 },
+	{ 0x000797,   1, 0x01, 0x000000cf },
+	{ 0x00079a,   1, 0x01, 0x00000002 },
+	{ 0x000833,   1, 0x01, 0x04444480 },
+	{ 0x0007a1,   1, 0x01, 0x00000001 },
+	{ 0x0007a3,   3, 0x01, 0x00000001 },
+	{ 0x000831,   1, 0x01, 0x00000004 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000008 },
+	{ 0x000039,   3, 0x01, 0x00000000 },
+	{ 0x000380,   1, 0x01, 0x00000001 },
+	{ 0x000366,   2, 0x01, 0x00000000 },
+	{ 0x000368,   1, 0x01, 0x00000fff },
+	{ 0x000370,   2, 0x01, 0x00000000 },
+	{ 0x000372,   1, 0x01, 0x000fffff },
+	{ 0x000813,   1, 0x01, 0x00000006 },
+	{ 0x000814,   1, 0x01, 0x00000008 },
+	{ 0x000957,   1, 0x01, 0x00000003 },
+	{ 0x000b07,   1, 0x01, 0x00000002 },
+	{ 0x000b08,   2, 0x01, 0x00000100 },
+	{ 0x000b0a,   1, 0x01, 0x00000001 },
+	{ 0x000a04,   1, 0x01, 0x000000ff },
+	{ 0x000a0b,   1, 0x01, 0x00000040 },
+	{ 0x00097f,   1, 0x01, 0x00000100 },
+	{ 0x000a02,   1, 0x01, 0x00000001 },
+	{ 0x000809,   1, 0x01, 0x00000007 },
+	{ 0x00c221,   1, 0x01, 0x00000040 },
+	{ 0x00c401,   1, 0x01, 0x00000001 },
+	{ 0x00c402,   1, 0x01, 0x00010001 },
+	{ 0x00c403,   2, 0x01, 0x00000001 },
+	{ 0x00c40e,   1, 0x01, 0x00000020 },
+	{ 0x00c500,   1, 0x01, 0x00000003 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{ 0x001000,   1, 0x01, 0x00000001 },
+	{ 0x000b07,   1, 0x01, 0x00000002 },
+	{ 0x000b08,   2, 0x01, 0x00000100 },
+	{ 0x000b0a,   1, 0x01, 0x00000001 },
+	{ 0x01e100,   1, 0x01, 0x00000001 },
+	{}
+};
+
+static const struct nvc0_graph_pack
+nvf0_grctx_pack_icmd[] = {
+	{ nvf0_grctx_init_icmd_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvf0_grctx_init_a197_0[] = {
+	{ 0x000800,   8, 0x40, 0x00000000 },
+	{ 0x000804,   8, 0x40, 0x00000000 },
+	{ 0x000808,   8, 0x40, 0x00000400 },
+	{ 0x00080c,   8, 0x40, 0x00000300 },
+	{ 0x000810,   1, 0x04, 0x000000cf },
+	{ 0x000850,   7, 0x40, 0x00000000 },
+	{ 0x000814,   8, 0x40, 0x00000040 },
+	{ 0x000818,   8, 0x40, 0x00000001 },
+	{ 0x00081c,   8, 0x40, 0x00000000 },
+	{ 0x000820,   8, 0x40, 0x00000000 },
+	{ 0x001c00,  16, 0x10, 0x00000000 },
+	{ 0x001c04,  16, 0x10, 0x00000000 },
+	{ 0x001c08,  16, 0x10, 0x00000000 },
+	{ 0x001c0c,  16, 0x10, 0x00000000 },
+	{ 0x001d00,  16, 0x10, 0x00000000 },
+	{ 0x001d04,  16, 0x10, 0x00000000 },
+	{ 0x001d08,  16, 0x10, 0x00000000 },
+	{ 0x001d0c,  16, 0x10, 0x00000000 },
+	{ 0x001f00,  16, 0x08, 0x00000000 },
+	{ 0x001f04,  16, 0x08, 0x00000000 },
+	{ 0x001f80,  16, 0x08, 0x00000000 },
+	{ 0x001f84,  16, 0x08, 0x00000000 },
+	{ 0x002000,   1, 0x04, 0x00000000 },
+	{ 0x002040,   1, 0x04, 0x00000011 },
+	{ 0x002080,   1, 0x04, 0x00000020 },
+	{ 0x0020c0,   1, 0x04, 0x00000030 },
+	{ 0x002100,   1, 0x04, 0x00000040 },
+	{ 0x002140,   1, 0x04, 0x00000051 },
+	{ 0x00200c,   6, 0x40, 0x00000001 },
+	{ 0x002010,   1, 0x04, 0x00000000 },
+	{ 0x002050,   1, 0x04, 0x00000000 },
+	{ 0x002090,   1, 0x04, 0x00000001 },
+	{ 0x0020d0,   1, 0x04, 0x00000002 },
+	{ 0x002110,   1, 0x04, 0x00000003 },
+	{ 0x002150,   1, 0x04, 0x00000004 },
+	{ 0x000380,   4, 0x20, 0x00000000 },
+	{ 0x000384,   4, 0x20, 0x00000000 },
+	{ 0x000388,   4, 0x20, 0x00000000 },
+	{ 0x00038c,   4, 0x20, 0x00000000 },
+	{ 0x000700,   4, 0x10, 0x00000000 },
+	{ 0x000704,   4, 0x10, 0x00000000 },
+	{ 0x000708,   4, 0x10, 0x00000000 },
+	{ 0x002800, 128, 0x04, 0x00000000 },
+	{ 0x000a00,  16, 0x20, 0x00000000 },
+	{ 0x000a04,  16, 0x20, 0x00000000 },
+	{ 0x000a08,  16, 0x20, 0x00000000 },
+	{ 0x000a0c,  16, 0x20, 0x00000000 },
+	{ 0x000a10,  16, 0x20, 0x00000000 },
+	{ 0x000a14,  16, 0x20, 0x00000000 },
+	{ 0x000c00,  16, 0x10, 0x00000000 },
+	{ 0x000c04,  16, 0x10, 0x00000000 },
+	{ 0x000c08,  16, 0x10, 0x00000000 },
+	{ 0x000c0c,  16, 0x10, 0x3f800000 },
+	{ 0x000d00,   8, 0x08, 0xffff0000 },
+	{ 0x000d04,   8, 0x08, 0xffff0000 },
+	{ 0x000e00,  16, 0x10, 0x00000000 },
+	{ 0x000e04,  16, 0x10, 0xffff0000 },
+	{ 0x000e08,  16, 0x10, 0xffff0000 },
+	{ 0x000d40,   4, 0x08, 0x00000000 },
+	{ 0x000d44,   4, 0x08, 0x00000000 },
+	{ 0x001e00,   8, 0x20, 0x00000001 },
+	{ 0x001e04,   8, 0x20, 0x00000001 },
+	{ 0x001e08,   8, 0x20, 0x00000002 },
+	{ 0x001e0c,   8, 0x20, 0x00000001 },
+	{ 0x001e10,   8, 0x20, 0x00000001 },
+	{ 0x001e14,   8, 0x20, 0x00000002 },
+	{ 0x001e18,   8, 0x20, 0x00000001 },
+	{ 0x003400, 128, 0x04, 0x00000000 },
+	{ 0x00030c,   1, 0x04, 0x00000001 },
+	{ 0x001944,   1, 0x04, 0x00000000 },
+	{ 0x001514,   1, 0x04, 0x00000000 },
+	{ 0x000d68,   1, 0x04, 0x0000ffff },
+	{ 0x00121c,   1, 0x04, 0x0fac6881 },
+	{ 0x000fac,   1, 0x04, 0x00000001 },
+	{ 0x001538,   1, 0x04, 0x00000001 },
+	{ 0x000fe0,   2, 0x04, 0x00000000 },
+	{ 0x000fe8,   1, 0x04, 0x00000014 },
+	{ 0x000fec,   1, 0x04, 0x00000040 },
+	{ 0x000ff0,   1, 0x04, 0x00000000 },
+	{ 0x00179c,   1, 0x04, 0x00000000 },
+	{ 0x001228,   1, 0x04, 0x00000400 },
+	{ 0x00122c,   1, 0x04, 0x00000300 },
+	{ 0x001230,   1, 0x04, 0x00010001 },
+	{ 0x0007f8,   1, 0x04, 0x00000000 },
+	{ 0x0015b4,   1, 0x04, 0x00000001 },
+	{ 0x0015cc,   1, 0x04, 0x00000000 },
+	{ 0x001534,   1, 0x04, 0x00000000 },
+	{ 0x000fb0,   1, 0x04, 0x00000000 },
+	{ 0x0015d0,   1, 0x04, 0x00000000 },
+	{ 0x00153c,   1, 0x04, 0x00000000 },
+	{ 0x0016b4,   1, 0x04, 0x00000003 },
+	{ 0x000fbc,   4, 0x04, 0x0000ffff },
+	{ 0x000df8,   2, 0x04, 0x00000000 },
+	{ 0x001948,   1, 0x04, 0x00000000 },
+	{ 0x001970,   1, 0x04, 0x00000001 },
+	{ 0x00161c,   1, 0x04, 0x000009f0 },
+	{ 0x000dcc,   1, 0x04, 0x00000010 },
+	{ 0x00163c,   1, 0x04, 0x00000000 },
+	{ 0x0015e4,   1, 0x04, 0x00000000 },
+	{ 0x001160,  32, 0x04, 0x25e00040 },
+	{ 0x001880,  32, 0x04, 0x00000000 },
+	{ 0x000f84,   2, 0x04, 0x00000000 },
+	{ 0x0017c8,   2, 0x04, 0x00000000 },
+	{ 0x0017d0,   1, 0x04, 0x000000ff },
+	{ 0x0017d4,   1, 0x04, 0xffffffff },
+	{ 0x0017d8,   1, 0x04, 0x00000002 },
+	{ 0x0017dc,   1, 0x04, 0x00000000 },
+	{ 0x0015f4,   2, 0x04, 0x00000000 },
+	{ 0x001434,   2, 0x04, 0x00000000 },
+	{ 0x000d74,   1, 0x04, 0x00000000 },
+	{ 0x000dec,   1, 0x04, 0x00000001 },
+	{ 0x0013a4,   1, 0x04, 0x00000000 },
+	{ 0x001318,   1, 0x04, 0x00000001 },
+	{ 0x001644,   1, 0x04, 0x00000000 },
+	{ 0x000748,   1, 0x04, 0x00000000 },
+	{ 0x000de8,   1, 0x04, 0x00000000 },
+	{ 0x001648,   1, 0x04, 0x00000000 },
+	{ 0x0012a4,   1, 0x04, 0x00000000 },
+	{ 0x001120,   4, 0x04, 0x00000000 },
+	{ 0x001118,   1, 0x04, 0x00000000 },
+	{ 0x00164c,   1, 0x04, 0x00000000 },
+	{ 0x001658,   1, 0x04, 0x00000000 },
+	{ 0x001910,   1, 0x04, 0x00000290 },
+	{ 0x001518,   1, 0x04, 0x00000000 },
+	{ 0x00165c,   1, 0x04, 0x00000001 },
+	{ 0x001520,   1, 0x04, 0x00000000 },
+	{ 0x001604,   1, 0x04, 0x00000000 },
+	{ 0x001570,   1, 0x04, 0x00000000 },
+	{ 0x0013b0,   2, 0x04, 0x3f800000 },
+	{ 0x00020c,   1, 0x04, 0x00000000 },
+	{ 0x001670,   1, 0x04, 0x30201000 },
+	{ 0x001674,   1, 0x04, 0x70605040 },
+	{ 0x001678,   1, 0x04, 0xb8a89888 },
+	{ 0x00167c,   1, 0x04, 0xf8e8d8c8 },
+	{ 0x00166c,   1, 0x04, 0x00000000 },
+	{ 0x001680,   1, 0x04, 0x00ffff00 },
+	{ 0x0012d0,   1, 0x04, 0x00000003 },
+	{ 0x0012d4,   1, 0x04, 0x00000002 },
+	{ 0x001684,   2, 0x04, 0x00000000 },
+	{ 0x000dac,   2, 0x04, 0x00001b02 },
+	{ 0x000db4,   1, 0x04, 0x00000000 },
+	{ 0x00168c,   1, 0x04, 0x00000000 },
+	{ 0x0015bc,   1, 0x04, 0x00000000 },
+	{ 0x00156c,   1, 0x04, 0x00000000 },
+	{ 0x00187c,   1, 0x04, 0x00000000 },
+	{ 0x001110,   1, 0x04, 0x00000001 },
+	{ 0x000dc0,   3, 0x04, 0x00000000 },
+	{ 0x001234,   1, 0x04, 0x00000000 },
+	{ 0x001690,   1, 0x04, 0x00000000 },
+	{ 0x0012ac,   1, 0x04, 0x00000001 },
+	{ 0x0002c4,   1, 0x04, 0x00000000 },
+	{ 0x000790,   5, 0x04, 0x00000000 },
+	{ 0x00077c,   1, 0x04, 0x00000000 },
+	{ 0x001000,   1, 0x04, 0x00000010 },
+	{ 0x0010fc,   1, 0x04, 0x00000000 },
+	{ 0x001290,   1, 0x04, 0x00000000 },
+	{ 0x000218,   1, 0x04, 0x00000010 },
+	{ 0x0012d8,   1, 0x04, 0x00000000 },
+	{ 0x0012dc,   1, 0x04, 0x00000010 },
+	{ 0x000d94,   1, 0x04, 0x00000001 },
+	{ 0x00155c,   2, 0x04, 0x00000000 },
+	{ 0x001564,   1, 0x04, 0x00000fff },
+	{ 0x001574,   2, 0x04, 0x00000000 },
+	{ 0x00157c,   1, 0x04, 0x000fffff },
+	{ 0x001354,   1, 0x04, 0x00000000 },
+	{ 0x001610,   1, 0x04, 0x00000012 },
+	{ 0x001608,   2, 0x04, 0x00000000 },
+	{ 0x00260c,   1, 0x04, 0x00000000 },
+	{ 0x0007ac,   1, 0x04, 0x00000000 },
+	{ 0x00162c,   1, 0x04, 0x00000003 },
+	{ 0x000210,   1, 0x04, 0x00000000 },
+	{ 0x000320,   1, 0x04, 0x00000000 },
+	{ 0x000324,   6, 0x04, 0x3f800000 },
+	{ 0x000750,   1, 0x04, 0x00000000 },
+	{ 0x000760,   1, 0x04, 0x39291909 },
+	{ 0x000764,   1, 0x04, 0x79695949 },
+	{ 0x000768,   1, 0x04, 0xb9a99989 },
+	{ 0x00076c,   1, 0x04, 0xf9e9d9c9 },
+	{ 0x000770,   1, 0x04, 0x30201000 },
+	{ 0x000774,   1, 0x04, 0x70605040 },
+	{ 0x000778,   1, 0x04, 0x00009080 },
+	{ 0x000780,   1, 0x04, 0x39291909 },
+	{ 0x000784,   1, 0x04, 0x79695949 },
+	{ 0x000788,   1, 0x04, 0xb9a99989 },
+	{ 0x00078c,   1, 0x04, 0xf9e9d9c9 },
+	{ 0x0007d0,   1, 0x04, 0x30201000 },
+	{ 0x0007d4,   1, 0x04, 0x70605040 },
+	{ 0x0007d8,   1, 0x04, 0x00009080 },
+	{ 0x00037c,   1, 0x04, 0x00000001 },
+	{ 0x000740,   2, 0x04, 0x00000000 },
+	{ 0x002600,   1, 0x04, 0x00000000 },
+	{ 0x001918,   1, 0x04, 0x00000000 },
+	{ 0x00191c,   1, 0x04, 0x00000900 },
+	{ 0x001920,   1, 0x04, 0x00000405 },
+	{ 0x001308,   1, 0x04, 0x00000001 },
+	{ 0x001924,   1, 0x04, 0x00000000 },
+	{ 0x0013ac,   1, 0x04, 0x00000000 },
+	{ 0x00192c,   1, 0x04, 0x00000001 },
+	{ 0x00193c,   1, 0x04, 0x00002c1c },
+	{ 0x000d7c,   1, 0x04, 0x00000000 },
+	{ 0x000f8c,   1, 0x04, 0x00000000 },
+	{ 0x0002c0,   1, 0x04, 0x00000001 },
+	{ 0x001510,   1, 0x04, 0x00000000 },
+	{ 0x001940,   1, 0x04, 0x00000000 },
+	{ 0x000ff4,   2, 0x04, 0x00000000 },
+	{ 0x00194c,   2, 0x04, 0x00000000 },
+	{ 0x001968,   1, 0x04, 0x00000000 },
+	{ 0x001590,   1, 0x04, 0x0000003f },
+	{ 0x0007e8,   4, 0x04, 0x00000000 },
+	{ 0x00196c,   1, 0x04, 0x00000011 },
+	{ 0x0002e4,   1, 0x04, 0x0000b001 },
+	{ 0x00036c,   2, 0x04, 0x00000000 },
+	{ 0x00197c,   1, 0x04, 0x00000000 },
+	{ 0x000fcc,   2, 0x04, 0x00000000 },
+	{ 0x0002d8,   1, 0x04, 0x00000040 },
+	{ 0x001980,   1, 0x04, 0x00000080 },
+	{ 0x001504,   1, 0x04, 0x00000080 },
+	{ 0x001984,   1, 0x04, 0x00000000 },
+	{ 0x000300,   1, 0x04, 0x00000001 },
+	{ 0x0013a8,   1, 0x04, 0x00000000 },
+	{ 0x0012ec,   1, 0x04, 0x00000000 },
+	{ 0x001310,   1, 0x04, 0x00000000 },
+	{ 0x001314,   1, 0x04, 0x00000001 },
+	{ 0x001380,   1, 0x04, 0x00000000 },
+	{ 0x001384,   4, 0x04, 0x00000001 },
+	{ 0x001394,   1, 0x04, 0x00000000 },
+	{ 0x00139c,   1, 0x04, 0x00000000 },
+	{ 0x001398,   1, 0x04, 0x00000000 },
+	{ 0x001594,   1, 0x04, 0x00000000 },
+	{ 0x001598,   4, 0x04, 0x00000001 },
+	{ 0x000f54,   3, 0x04, 0x00000000 },
+	{ 0x0019bc,   1, 0x04, 0x00000000 },
+	{ 0x000f9c,   2, 0x04, 0x00000000 },
+	{ 0x0012cc,   1, 0x04, 0x00000000 },
+	{ 0x0012e8,   1, 0x04, 0x00000000 },
+	{ 0x00130c,   1, 0x04, 0x00000001 },
+	{ 0x001360,   8, 0x04, 0x00000000 },
+	{ 0x00133c,   2, 0x04, 0x00000001 },
+	{ 0x001344,   1, 0x04, 0x00000002 },
+	{ 0x001348,   2, 0x04, 0x00000001 },
+	{ 0x001350,   1, 0x04, 0x00000002 },
+	{ 0x001358,   1, 0x04, 0x00000001 },
+	{ 0x0012e4,   1, 0x04, 0x00000000 },
+	{ 0x00131c,   4, 0x04, 0x00000000 },
+	{ 0x0019c0,   1, 0x04, 0x00000000 },
+	{ 0x001140,   1, 0x04, 0x00000000 },
+	{ 0x0019c4,   1, 0x04, 0x00000000 },
+	{ 0x0019c8,   1, 0x04, 0x00001500 },
+	{ 0x00135c,   1, 0x04, 0x00000000 },
+	{ 0x000f90,   1, 0x04, 0x00000000 },
+	{ 0x0019e0,   8, 0x04, 0x00000001 },
+	{ 0x0019cc,   1, 0x04, 0x00000001 },
+	{ 0x0015b8,   1, 0x04, 0x00000000 },
+	{ 0x001a00,   1, 0x04, 0x00001111 },
+	{ 0x001a04,   7, 0x04, 0x00000000 },
+	{ 0x000d6c,   2, 0x04, 0xffff0000 },
+	{ 0x0010f8,   1, 0x04, 0x00001010 },
+	{ 0x000d80,   5, 0x04, 0x00000000 },
+	{ 0x000da0,   1, 0x04, 0x00000000 },
+	{ 0x0007a4,   2, 0x04, 0x00000000 },
+	{ 0x001508,   1, 0x04, 0x80000000 },
+	{ 0x00150c,   1, 0x04, 0x40000000 },
+	{ 0x001668,   1, 0x04, 0x00000000 },
+	{ 0x000318,   2, 0x04, 0x00000008 },
+	{ 0x000d9c,   1, 0x04, 0x00000001 },
+	{ 0x000ddc,   1, 0x04, 0x00000002 },
+	{ 0x000374,   1, 0x04, 0x00000000 },
+	{ 0x000378,   1, 0x04, 0x00000020 },
+	{ 0x0007dc,   1, 0x04, 0x00000000 },
+	{ 0x00074c,   1, 0x04, 0x00000055 },
+	{ 0x001420,   1, 0x04, 0x00000003 },
+	{ 0x0017bc,   2, 0x04, 0x00000000 },
+	{ 0x0017c4,   1, 0x04, 0x00000001 },
+	{ 0x001008,   1, 0x04, 0x00000008 },
+	{ 0x00100c,   1, 0x04, 0x00000040 },
+	{ 0x001010,   1, 0x04, 0x0000012c },
+	{ 0x000d60,   1, 0x04, 0x00000040 },
+	{ 0x00075c,   1, 0x04, 0x00000003 },
+	{ 0x001018,   1, 0x04, 0x00000020 },
+	{ 0x00101c,   1, 0x04, 0x00000001 },
+	{ 0x001020,   1, 0x04, 0x00000020 },
+	{ 0x001024,   1, 0x04, 0x00000001 },
+	{ 0x001444,   3, 0x04, 0x00000000 },
+	{ 0x000360,   1, 0x04, 0x20164010 },
+	{ 0x000364,   1, 0x04, 0x00000020 },
+	{ 0x000368,   1, 0x04, 0x00000000 },
+	{ 0x000de4,   1, 0x04, 0x00000000 },
+	{ 0x000204,   1, 0x04, 0x00000006 },
+	{ 0x000208,   1, 0x04, 0x00000000 },
+	{ 0x0002cc,   2, 0x04, 0x003fffff },
+	{ 0x001220,   1, 0x04, 0x00000005 },
+	{ 0x000fdc,   1, 0x04, 0x00000000 },
+	{ 0x000f98,   1, 0x04, 0x00400008 },
+	{ 0x001284,   1, 0x04, 0x08000080 },
+	{ 0x001450,   1, 0x04, 0x00400008 },
+	{ 0x001454,   1, 0x04, 0x08000080 },
+	{ 0x000214,   1, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_pack
+nvf0_grctx_pack_mthd[] = {
+	{ nvf0_grctx_init_a197_0, 0xa197 },
+	{ nvc0_grctx_init_902d_0, 0x902d },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvf0_grctx_init_fe_0[] = {
 	{ 0x404004,   8, 0x04, 0x00000000 },
 	{ 0x404024,   1, 0x04, 0x0000e000 },
 	{ 0x404028,   8, 0x04, 0x00000000 },
@@ -50,8 +620,8 @@ nvf0_grctx_init_unk40xx[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvf0_grctx_init_unk44xx[] = {
+const struct nvc0_graph_init
+nvf0_grctx_init_pri_0[] = {
 	{ 0x404404,  12, 0x04, 0x00000000 },
 	{ 0x404438,   1, 0x04, 0x00000000 },
 	{ 0x404460,   2, 0x04, 0x00000000 },
@@ -62,23 +632,18 @@ nvf0_grctx_init_unk44xx[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvf0_grctx_init_unk5bxx[] = {
+const struct nvc0_graph_init
+nvf0_grctx_init_cwd_0[] = {
 	{ 0x405b00,   1, 0x04, 0x00000000 },
 	{ 0x405b10,   1, 0x04, 0x00001000 },
 	{ 0x405b20,   1, 0x04, 0x04000000 },
 	{}
 };
 
-struct nvc0_graph_init
-nvf0_grctx_init_unk60xx[] = {
+static const struct nvc0_graph_init
+nvf0_grctx_init_pd_0[] = {
 	{ 0x406020,   1, 0x04, 0x034103c1 },
 	{ 0x406028,   4, 0x04, 0x00000001 },
-	{}
-};
-
-static struct nvc0_graph_init
-nvf0_grctx_init_unk64xx[] = {
 	{ 0x4064a8,   1, 0x04, 0x00000000 },
 	{ 0x4064ac,   1, 0x04, 0x00003fff },
 	{ 0x4064b0,   3, 0x04, 0x00000000 },
@@ -90,8 +655,8 @@ nvf0_grctx_init_unk64xx[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nvf0_grctx_init_unk88xx[] = {
+static const struct nvc0_graph_init
+nvf0_grctx_init_be_0[] = {
 	{ 0x408800,   1, 0x04, 0x12802a3c },
 	{ 0x408804,   1, 0x04, 0x00000040 },
 	{ 0x408808,   1, 0x04, 0x1003e005 },
@@ -103,22 +668,23 @@ nvf0_grctx_init_unk88xx[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nvf0_grctx_init_gpc_0[] = {
-	{ 0x418380,   1, 0x04, 0x00000016 },
-	{ 0x418400,   1, 0x04, 0x38004e00 },
-	{ 0x418404,   1, 0x04, 0x71e0ffff },
-	{ 0x41840c,   1, 0x04, 0x00001008 },
-	{ 0x418410,   1, 0x04, 0x0fff0fff },
-	{ 0x418414,   1, 0x04, 0x02200fff },
-	{ 0x418450,   6, 0x04, 0x00000000 },
-	{ 0x418468,   1, 0x04, 0x00000001 },
-	{ 0x41846c,   2, 0x04, 0x00000000 },
-	{ 0x418600,   1, 0x04, 0x0000001f },
-	{ 0x418684,   1, 0x04, 0x0000000f },
-	{ 0x418700,   1, 0x04, 0x00000002 },
-	{ 0x418704,   1, 0x04, 0x00000080 },
-	{ 0x418708,   3, 0x04, 0x00000000 },
+static const struct nvc0_graph_pack
+nvf0_grctx_pack_hub[] = {
+	{ nvc0_grctx_init_main_0 },
+	{ nvf0_grctx_init_fe_0 },
+	{ nvf0_grctx_init_pri_0 },
+	{ nve4_grctx_init_memfmt_0 },
+	{ nve4_grctx_init_ds_0 },
+	{ nvf0_grctx_init_cwd_0 },
+	{ nvf0_grctx_init_pd_0 },
+	{ nvc0_grctx_init_rstr2d_0 },
+	{ nve4_grctx_init_scc_0 },
+	{ nvf0_grctx_init_be_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvf0_grctx_init_setup_0[] = {
 	{ 0x418800,   1, 0x04, 0x7006860a },
 	{ 0x418808,   1, 0x04, 0x00000000 },
 	{ 0x41880c,   1, 0x04, 0x00000030 },
@@ -129,36 +695,31 @@ nvf0_grctx_init_gpc_0[] = {
 	{ 0x4188e0,   1, 0x04, 0x01000000 },
 	{ 0x4188e8,   5, 0x04, 0x00000000 },
 	{ 0x4188fc,   1, 0x04, 0x20100018 },
-	{ 0x41891c,   1, 0x04, 0x00ff00ff },
-	{ 0x418924,   1, 0x04, 0x00000000 },
-	{ 0x418928,   1, 0x04, 0x00ffff00 },
-	{ 0x41892c,   1, 0x04, 0x0000ff00 },
-	{ 0x418b00,   1, 0x04, 0x00000006 },
-	{ 0x418b08,   1, 0x04, 0x0a418820 },
-	{ 0x418b0c,   1, 0x04, 0x062080e6 },
-	{ 0x418b10,   1, 0x04, 0x020398a4 },
-	{ 0x418b14,   1, 0x04, 0x0e629062 },
-	{ 0x418b18,   1, 0x04, 0x0a418820 },
-	{ 0x418b1c,   1, 0x04, 0x000000e6 },
-	{ 0x418bb8,   1, 0x04, 0x00000103 },
-	{ 0x418c08,   1, 0x04, 0x00000001 },
-	{ 0x418c10,   8, 0x04, 0x00000000 },
-	{ 0x418c40,   1, 0x04, 0xffffffff },
-	{ 0x418c6c,   1, 0x04, 0x00000001 },
-	{ 0x418c80,   1, 0x04, 0x20200004 },
-	{ 0x418c8c,   1, 0x04, 0x00000001 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvf0_grctx_init_gpc_unk_2[] = {
 	{ 0x418d24,   1, 0x04, 0x00000000 },
-	{ 0x419000,   1, 0x04, 0x00000780 },
-	{ 0x419004,   2, 0x04, 0x00000000 },
-	{ 0x419014,   1, 0x04, 0x00000004 },
 	{}
 };
 
-static struct nvc0_graph_init
-nvf0_grctx_init_tpc[] = {
-	{ 0x419848,   1, 0x04, 0x00000000 },
-	{ 0x419864,   1, 0x04, 0x00000129 },
-	{ 0x419888,   1, 0x04, 0x00000000 },
+static const struct nvc0_graph_pack
+nvf0_grctx_pack_gpc[] = {
+	{ nvc0_grctx_init_gpc_unk_0 },
+	{ nvd9_grctx_init_prop_0 },
+	{ nvd9_grctx_init_gpc_unk_1 },
+	{ nvf0_grctx_init_setup_0 },
+	{ nvc0_grctx_init_zcull_0 },
+	{ nvd9_grctx_init_crstr_0 },
+	{ nve4_grctx_init_gpm_0 },
+	{ nvf0_grctx_init_gpc_unk_2 },
+	{ nvc0_grctx_init_gcc_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvf0_grctx_init_tex_0[] = {
 	{ 0x419a00,   1, 0x04, 0x000000f0 },
 	{ 0x419a04,   1, 0x04, 0x00000001 },
 	{ 0x419a08,   1, 0x04, 0x00000021 },
@@ -169,14 +730,29 @@ nvf0_grctx_init_tpc[] = {
 	{ 0x419a20,   1, 0x04, 0x00020800 },
 	{ 0x419a30,   1, 0x04, 0x00000001 },
 	{ 0x419ac4,   1, 0x04, 0x0037f440 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvf0_grctx_init_mpc_0[] = {
 	{ 0x419c00,   1, 0x04, 0x0000001a },
 	{ 0x419c04,   1, 0x04, 0x80000006 },
 	{ 0x419c08,   1, 0x04, 0x00000002 },
 	{ 0x419c20,   1, 0x04, 0x00000000 },
 	{ 0x419c24,   1, 0x04, 0x00084210 },
 	{ 0x419c28,   1, 0x04, 0x3efbefbe },
+	{}
+};
+
+const struct nvc0_graph_init
+nvf0_grctx_init_l1c_0[] = {
 	{ 0x419ce8,   1, 0x04, 0x00000000 },
 	{ 0x419cf4,   1, 0x04, 0x00000203 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvf0_grctx_init_sm_0[] = {
 	{ 0x419e04,   1, 0x04, 0x00000000 },
 	{ 0x419e08,   1, 0x04, 0x0000001d },
 	{ 0x419e0c,   1, 0x04, 0x00000000 },
@@ -189,8 +765,8 @@ nvf0_grctx_init_tpc[] = {
 	{ 0x419e5c,   3, 0x04, 0x00000000 },
 	{ 0x419e68,   1, 0x04, 0x00000002 },
 	{ 0x419e6c,  12, 0x04, 0x00000000 },
-	{ 0x419eac,   1, 0x04, 0x00001fcf },
-	{ 0x419eb0,   1, 0x04, 0x0db00da0 },
+	{ 0x419eac,   1, 0x04, 0x00001f8f },
+	{ 0x419eb0,   1, 0x04, 0x0db00d2f },
 	{ 0x419eb8,   1, 0x04, 0x00000000 },
 	{ 0x419ec8,   1, 0x04, 0x0001304f },
 	{ 0x419f30,   4, 0x04, 0x00000000 },
@@ -203,24 +779,36 @@ nvf0_grctx_init_tpc[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nvf0_grctx_init_unk[] = {
-	{ 0x41be24,   1, 0x04, 0x00000006 },
+static const struct nvc0_graph_pack
+nvf0_grctx_pack_tpc[] = {
+	{ nvd7_grctx_init_pe_0 },
+	{ nvf0_grctx_init_tex_0 },
+	{ nvf0_grctx_init_mpc_0 },
+	{ nvf0_grctx_init_l1c_0 },
+	{ nvf0_grctx_init_sm_0 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvf0_grctx_init_cbm_0[] = {
 	{ 0x41bec0,   1, 0x04, 0x10000000 },
 	{ 0x41bec4,   1, 0x04, 0x00037f7f },
 	{ 0x41bee4,   1, 0x04, 0x00000000 },
-	{ 0x41bf00,   1, 0x04, 0x0a418820 },
-	{ 0x41bf04,   1, 0x04, 0x062080e6 },
-	{ 0x41bf08,   1, 0x04, 0x020398a4 },
-	{ 0x41bf0c,   1, 0x04, 0x0e629062 },
-	{ 0x41bf10,   1, 0x04, 0x0a418820 },
-	{ 0x41bf14,   1, 0x04, 0x000000e6 },
-	{ 0x41bfd0,   1, 0x04, 0x00900103 },
-	{ 0x41bfe0,   1, 0x04, 0x00400001 },
-	{ 0x41bfe4,   1, 0x04, 0x00000000 },
 	{}
 };
 
+static const struct nvc0_graph_pack
+nvf0_grctx_pack_ppc[] = {
+	{ nve4_grctx_init_pes_0 },
+	{ nvf0_grctx_init_cbm_0 },
+	{ nvd7_grctx_init_wwdx_0 },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH context implementation
+ ******************************************************************************/
+
 static void
 nvf0_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
 {
@@ -273,39 +861,6 @@ nvf0_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
 	mmio_list(0x17e920, 0x00090a05, 0, 0);
 }
 
-static struct nvc0_graph_init *
-nvf0_grctx_init_hub[] = {
-	nvc0_grctx_init_base,
-	nvf0_grctx_init_unk40xx,
-	nvf0_grctx_init_unk44xx,
-	nve4_grctx_init_unk46xx,
-	nve4_grctx_init_unk47xx,
-	nve4_grctx_init_unk58xx,
-	nvf0_grctx_init_unk5bxx,
-	nvf0_grctx_init_unk60xx,
-	nvf0_grctx_init_unk64xx,
-	nve4_grctx_init_unk80xx,
-	nvf0_grctx_init_unk88xx,
-	NULL
-};
-
-struct nvc0_graph_init *
-nvf0_grctx_init_gpc[] = {
-	nvf0_grctx_init_gpc_0,
-	nvc0_grctx_init_gpc_1,
-	nvf0_grctx_init_tpc,
-	nvf0_grctx_init_unk,
-	NULL
-};
-
-static struct nvc0_graph_mthd
-nvf0_grctx_init_mthd[] = {
-	{ 0xa197, nvc1_grctx_init_9097, },
-	{ 0x902d, nvc0_grctx_init_902d, },
-	{ 0x902d, nvc0_grctx_init_mthd_magic, },
-	{}
-};
-
 struct nouveau_oclass *
 nvf0_grctx_oclass = &(struct nvc0_grctx_oclass) {
 	.base.handle = NV_ENGCTX(GR, 0xf0),
@@ -317,11 +872,14 @@ nvf0_grctx_oclass = &(struct nvc0_grctx_oclass) {
 		.rd32 = _nouveau_graph_context_rd32,
 		.wr32 = _nouveau_graph_context_wr32,
 	},
-	.main = nve4_grctx_generate_main,
-	.mods = nvf0_grctx_generate_mods,
-	.unkn = nve4_grctx_generate_unkn,
-	.hub  = nvf0_grctx_init_hub,
-	.gpc  = nvf0_grctx_init_gpc,
-	.icmd = nvc0_grctx_init_icmd,
-	.mthd = nvf0_grctx_init_mthd,
+	.main  = nve4_grctx_generate_main,
+	.mods  = nvf0_grctx_generate_mods,
+	.unkn  = nve4_grctx_generate_unkn,
+	.hub   = nvf0_grctx_pack_hub,
+	.gpc   = nvf0_grctx_pack_gpc,
+	.zcull = nvc0_grctx_pack_zcull,
+	.tpc   = nvf0_grctx_pack_tpc,
+	.ppc   = nvf0_grctx_pack_ppc,
+	.icmd  = nvf0_grctx_pack_icmd,
+	.mthd  = nvf0_grctx_pack_mthd,
 }.base;

+ 1 - 1
drivers/gpu/drm/nouveau/core/engine/graph/fuc/com.fuc

@@ -228,7 +228,7 @@ mmctx_xfer:
 			and $r11 0x1f
 			cmpu b32 $r11 0x10
 			bra ne #mmctx_fini_wait
-		mov $r10 2				// DONE_MMCTX
+		mov $r10 5			// DONE_MMCTX
 		call(wait_donez)
 		bra #mmctx_done
 	mmctx_stop:

+ 6 - 1
drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpc.fuc

@@ -78,7 +78,12 @@ error:
 //
 init:
 	clear b32 $r0
-	mov $sp $r0
+
+	// setup stack
+	nv_iord($r1, NV_PGRAPH_GPCX_GPCCS_CAPS, 0)
+	extr $r1 $r1 9:17
+	shl b32 $r1 8
+	mov $sp $r1
 
 	// enable fifo access
 	mov $r2 NV_PGRAPH_GPCX_GPCCS_ACCESS_FIFO

+ 42 - 0
drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5

@@ -0,0 +1,42 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#define NV_PGRAPH_GPCX_UNK__SIZE                                     0x00000002
+
+#define CHIPSET GK208
+#include "macros.fuc"
+
+.section #gm107_grgpc_data
+#define INCLUDE_DATA
+#include "com.fuc"
+#include "gpc.fuc"
+#undef INCLUDE_DATA
+
+.section #gm107_grgpc_code
+#define INCLUDE_CODE
+bra #init
+#include "com.fuc"
+#include "gpc.fuc"
+.align 256
+#undef INCLUDE_CODE

+ 473 - 0
drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5.h

@@ -0,0 +1,473 @@
+uint32_t gm107_grgpc_data[] = {
+/* 0x0000: gpc_mmio_list_head */
+	0x0000006c,
+/* 0x0004: gpc_mmio_list_tail */
+/* 0x0004: tpc_mmio_list_head */
+	0x0000006c,
+/* 0x0008: tpc_mmio_list_tail */
+/* 0x0008: unk_mmio_list_head */
+	0x0000006c,
+/* 0x000c: unk_mmio_list_tail */
+	0x0000006c,
+/* 0x0010: gpc_id */
+	0x00000000,
+/* 0x0014: tpc_count */
+	0x00000000,
+/* 0x0018: tpc_mask */
+	0x00000000,
+/* 0x001c: unk_count */
+	0x00000000,
+/* 0x0020: unk_mask */
+	0x00000000,
+/* 0x0024: cmd_queue */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+};
+
+uint32_t gm107_grgpc_code[] = {
+	0x03140ef5,
+/* 0x0004: queue_put */
+	0x9800d898,
+	0x86f001d9,
+	0xf489a408,
+	0x020f0b1b,
+	0x0002f87e,
+/* 0x001a: queue_put_next */
+	0x98c400f8,
+	0x0384b607,
+	0xb6008dbb,
+	0x8eb50880,
+	0x018fb500,
+	0xf00190b6,
+	0xd9b50f94,
+/* 0x0037: queue_get */
+	0xf400f801,
+	0xd8980131,
+	0x01d99800,
+	0x0bf489a4,
+	0x0789c421,
+	0xbb0394b6,
+	0x90b6009d,
+	0x009e9808,
+	0xb6019f98,
+	0x84f00180,
+	0x00d8b50f,
+/* 0x0063: queue_get_done */
+	0xf80132f4,
+/* 0x0065: nv_rd32 */
+	0xf0ecb200,
+	0x00801fc9,
+	0x0cf601ca,
+/* 0x0073: nv_rd32_wait */
+	0x8c04bd00,
+	0xcf01ca00,
+	0xccc800cc,
+	0xf61bf41f,
+	0xec7e060a,
+	0x008f0000,
+	0xffcf01cb,
+/* 0x008f: nv_wr32 */
+	0x8000f800,
+	0xf601cc00,
+	0x04bd000f,
+	0xc9f0ecb2,
+	0x1ec9f01f,
+	0x01ca0080,
+	0xbd000cf6,
+/* 0x00a9: nv_wr32_wait */
+	0xca008c04,
+	0x00cccf01,
+	0xf41fccc8,
+	0x00f8f61b,
+/* 0x00b8: wait_donez */
+	0x99f094bd,
+	0x37008000,
+	0x0009f602,
+	0x008004bd,
+	0x0af60206,
+/* 0x00cf: wait_donez_ne */
+	0x8804bd00,
+	0xcf010000,
+	0x8aff0088,
+	0xf61bf488,
+	0x99f094bd,
+	0x17008000,
+	0x0009f602,
+	0x00f804bd,
+/* 0x00ec: wait_doneo */
+	0x99f094bd,
+	0x37008000,
+	0x0009f602,
+	0x008004bd,
+	0x0af60206,
+/* 0x0103: wait_doneo_e */
+	0x8804bd00,
+	0xcf010000,
+	0x8aff0088,
+	0xf60bf488,
+	0x99f094bd,
+	0x17008000,
+	0x0009f602,
+	0x00f804bd,
+/* 0x0120: mmctx_size */
+/* 0x0122: nv_mmctx_size_loop */
+	0xe89894bd,
+	0x1a85b600,
+	0xb60180b6,
+	0x98bb0284,
+	0x04e0b600,
+	0x1bf4efa4,
+	0xf89fb2ec,
+/* 0x013d: mmctx_xfer */
+	0xf094bd00,
+	0x00800199,
+	0x09f60237,
+	0xbd04bd00,
+	0x05bbfd94,
+	0x800f0bf4,
+	0xf601c400,
+	0x04bd000b,
+/* 0x015f: mmctx_base_disabled */
+	0xfd0099f0,
+	0x0bf405ee,
+	0xc6008018,
+	0x000ef601,
+	0x008004bd,
+	0x0ff601c7,
+	0xf004bd00,
+/* 0x017a: mmctx_multi_disabled */
+	0xabc80199,
+	0x10b4b600,
+	0xc80cb9f0,
+	0xe4b601ae,
+	0x05befd11,
+	0x01c50080,
+	0xbd000bf6,
+/* 0x0195: mmctx_exec_loop */
+/* 0x0195: mmctx_wait_free */
+	0xc5008e04,
+	0x00eecf01,
+	0xf41fe4f0,
+	0xce98f60b,
+	0x05e9fd00,
+	0x01c80080,
+	0xbd000ef6,
+	0x04c0b604,
+	0x1bf4cda4,
+	0x02abc8df,
+/* 0x01bf: mmctx_fini_wait */
+	0x8b1c1bf4,
+	0xcf01c500,
+	0xb4f000bb,
+	0x10b4b01f,
+	0x0af31bf4,
+	0x00b87e05,
+	0x250ef400,
+/* 0x01d8: mmctx_stop */
+	0xb600abc8,
+	0xb9f010b4,
+	0x12b9f00c,
+	0x01c50080,
+	0xbd000bf6,
+/* 0x01ed: mmctx_stop_wait */
+	0xc5008b04,
+	0x00bbcf01,
+	0xf412bbc8,
+/* 0x01fa: mmctx_done */
+	0x94bdf61b,
+	0x800199f0,
+	0xf6021700,
+	0x04bd0009,
+/* 0x020a: strand_wait */
+	0xa0f900f8,
+	0xb87e020a,
+	0xa0fc0000,
+/* 0x0216: strand_pre */
+	0x0c0900f8,
+	0x024afc80,
+	0xbd0009f6,
+	0x020a7e04,
+/* 0x0227: strand_post */
+	0x0900f800,
+	0x4afc800d,
+	0x0009f602,
+	0x0a7e04bd,
+	0x00f80002,
+/* 0x0238: strand_set */
+	0xfc800f0c,
+	0x0cf6024f,
+	0x0c04bd00,
+	0x4afc800b,
+	0x000cf602,
+	0xfc8004bd,
+	0x0ef6024f,
+	0x0c04bd00,
+	0x4afc800a,
+	0x000cf602,
+	0x0a7e04bd,
+	0x00f80002,
+/* 0x0268: strand_ctx_init */
+	0x99f094bd,
+	0x37008003,
+	0x0009f602,
+	0x167e04bd,
+	0x030e0002,
+	0x0002387e,
+	0xfc80c4bd,
+	0x0cf60247,
+	0x0c04bd00,
+	0x4afc8001,
+	0x000cf602,
+	0x0a7e04bd,
+	0x0c920002,
+	0x46fc8001,
+	0x000cf602,
+	0x020c04bd,
+	0x024afc80,
+	0xbd000cf6,
+	0x020a7e04,
+	0x02277e00,
+	0x42008800,
+	0x20008902,
+	0x0099cf02,
+/* 0x02c7: ctx_init_strand_loop */
+	0xf608fe95,
+	0x8ef6008e,
+	0x808acf40,
+	0xb606a5b6,
+	0xeabb01a0,
+	0x0480b600,
+	0xf40192b6,
+	0xe4b6e81b,
+	0xf2efbc08,
+	0x99f094bd,
+	0x17008003,
+	0x0009f602,
+	0x00f804bd,
+/* 0x02f8: error */
+	0xffb2e0f9,
+	0x4098148e,
+	0x00008f7e,
+	0xffb2010f,
+	0x409c1c8e,
+	0x00008f7e,
+	0x00f8e0fc,
+/* 0x0314: init */
+	0x004104bd,
+	0x0011cf42,
+	0x010911e7,
+	0xfe0814b6,
+	0x02020014,
+	0xf6120040,
+	0x04bd0002,
+	0xfe047241,
+	0x00400010,
+	0x0000f607,
+	0x040204bd,
+	0xf6040040,
+	0x04bd0002,
+	0x821031f4,
+	0xcf018200,
+	0x01030022,
+	0xbb1f24f0,
+	0x32b60432,
+	0x0502b501,
+	0x820603b5,
+	0xcf018600,
+	0x02b50022,
+	0x0c308e04,
+	0xbd24bd50,
+/* 0x0377: init_unk_loop */
+	0x7e44bd34,
+	0xb0000065,
+	0x0bf400f6,
+	0xbb010f0e,
+	0x4ffd04f2,
+	0x0130b605,
+/* 0x038c: init_unk_next */
+	0xb60120b6,
+	0x26b004e0,
+	0xe21bf402,
+/* 0x0398: init_unk_done */
+	0xb50703b5,
+	0x00820804,
+	0x22cf0201,
+	0x9534bd00,
+	0x00800825,
+	0x05f601c0,
+	0x8004bd00,
+	0xf601c100,
+	0x04bd0005,
+	0x98000e98,
+	0x207e010f,
+	0x2fbb0001,
+	0x003fbb00,
+	0x98010e98,
+	0x207e020f,
+	0x0e980001,
+	0x00effd05,
+	0xbb002ebb,
+	0x0e98003e,
+	0x030f9802,
+	0x0001207e,
+	0xfd070e98,
+	0x2ebb00ef,
+	0x003ebb00,
+	0x800235b6,
+	0xf601d300,
+	0x04bd0003,
+	0xb60825b6,
+	0x20b60635,
+	0x0130b601,
+	0xb60824b6,
+	0x2fb20834,
+	0x0002687e,
+	0x80003fbb,
+	0xf6020100,
+	0x04bd0003,
+	0x29f024bd,
+	0x3000801f,
+	0x0002f602,
+/* 0x0436: main */
+	0x31f404bd,
+	0x0028f400,
+	0x377e240d,
+	0x01f40000,
+	0x04e4b0f4,
+	0xfe1d18f4,
+	0x06020181,
+	0x12fd20bd,
+	0x01e4b604,
+	0xfe051efd,
+	0x097e0018,
+	0x0ef40005,
+/* 0x0465: main_not_ctx_xfer */
+	0x10ef94d4,
+	0x7e01f5f0,
+	0xf40002f8,
+/* 0x0472: ih */
+	0x80f9c70e,
+	0xf90188fe,
+	0xf990f980,
+	0xf9b0f9a0,
+	0xf9e0f9d0,
+	0x4a04bdf0,
+	0xaacf0200,
+	0x04abc400,
+	0x0d1f0bf4,
+	0x1a004e24,
+	0x4f00eecf,
+	0xffcf1900,
+	0x00047e00,
+	0x40010e00,
+	0x0ef61d00,
+/* 0x04af: ih_no_fifo */
+	0x4004bd00,
+	0x0af60100,
+	0xfc04bd00,
+	0xfce0fcf0,
+	0xfcb0fcd0,
+	0xfc90fca0,
+	0x0088fe80,
+	0x32f480fc,
+/* 0x04cf: hub_barrier_done */
+	0x0f01f800,
+	0x040e9801,
+	0xb204febb,
+	0x94188eff,
+	0x008f7e40,
+/* 0x04e3: ctx_redswitch */
+	0x0f00f800,
+	0x85008020,
+	0x000ff601,
+	0x080e04bd,
+/* 0x04f0: ctx_redswitch_delay */
+	0xf401e2b6,
+	0xf5f1fd1b,
+	0xf5f10800,
+	0x00800200,
+	0x0ff60185,
+	0xf804bd00,
+/* 0x0509: ctx_xfer */
+	0x81008000,
+	0x000ff602,
+	0x11f404bd,
+	0x04e37e07,
+/* 0x0519: ctx_xfer_not_load */
+	0x02167e00,
+	0x8024bd00,
+	0xf60247fc,
+	0x04bd0002,
+	0xb6012cf0,
+	0xfc800320,
+	0x02f6024a,
+	0xf004bd00,
+	0xa5f001ac,
+	0x00008b02,
+	0x040c9850,
+	0xbb0fc4b6,
+	0x0c9800bc,
+	0x010d9800,
+	0x3d7e000e,
+	0xacf00001,
+	0x40008b01,
+	0x040c9850,
+	0xbb0fc4b6,
+	0x0c9800bc,
+	0x020d9801,
+	0x4e060f98,
+	0x3d7e0800,
+	0xacf00001,
+	0x04a5f001,
+	0x5030008b,
+	0xb6040c98,
+	0xbcbb0fc4,
+	0x020c9800,
+	0x98030d98,
+	0x004e080f,
+	0x013d7e02,
+	0x020a7e00,
+	0x0601f400,
+/* 0x05a3: ctx_xfer_post */
+	0x7e0712f4,
+/* 0x05a7: ctx_xfer_done */
+	0x7e000227,
+	0xf80004cf,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+};

+ 177 - 177
drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnv108.fuc5.h

@@ -177,7 +177,7 @@ uint32_t nv108_grgpc_code[] = {
 	0xb4f000bb,
 	0x10b4b01f,
 	0x0af31bf4,
-	0x00b87e02,
+	0x00b87e05,
 	0x250ef400,
 /* 0x01d8: mmctx_stop */
 	0xb600abc8,
@@ -269,186 +269,186 @@ uint32_t nv108_grgpc_code[] = {
 	0x00008f7e,
 	0x00f8e0fc,
 /* 0x0314: init */
-	0x04fe04bd,
-	0x40020200,
-	0x02f61200,
-	0x4104bd00,
-	0x10fe0465,
-	0x07004000,
-	0xbd0000f6,
-	0x40040204,
-	0x02f60400,
-	0xf404bd00,
-	0x00821031,
-	0x22cf0182,
-	0xf0010300,
-	0x32bb1f24,
-	0x0132b604,
-	0xb50502b5,
-	0x00820603,
-	0x22cf0186,
-	0x0402b500,
-	0x500c308e,
-	0x34bd24bd,
-/* 0x036a: init_unk_loop */
-	0x657e44bd,
-	0xf6b00000,
-	0x0e0bf400,
-	0xf2bb010f,
-	0x054ffd04,
-/* 0x037f: init_unk_next */
-	0xb60130b6,
-	0xe0b60120,
-	0x0126b004,
-/* 0x038b: init_unk_done */
-	0xb5e21bf4,
-	0x04b50703,
-	0x01008208,
-	0x0022cf02,
-	0x259534bd,
-	0xc0008008,
-	0x0005f601,
-	0x008004bd,
-	0x05f601c1,
-	0x9804bd00,
-	0x0f98000e,
-	0x01207e01,
-	0x002fbb00,
-	0x98003fbb,
-	0x0f98010e,
-	0x01207e02,
-	0x050e9800,
-	0xbb00effd,
-	0x3ebb002e,
-	0x020e9800,
-	0x7e030f98,
-	0x98000120,
-	0xeffd070e,
-	0x002ebb00,
-	0xb6003ebb,
-	0x00800235,
-	0x03f601d3,
-	0xb604bd00,
-	0x35b60825,
-	0x0120b606,
-	0xb60130b6,
-	0x34b60824,
-	0x7e2fb208,
-	0xbb000268,
-	0x0080003f,
-	0x03f60201,
-	0xbd04bd00,
-	0x1f29f024,
-	0x02300080,
-	0xbd0002f6,
-/* 0x0429: main */
-	0x0031f404,
-	0x0d0028f4,
-	0x00377e24,
-	0xf401f400,
-	0xf404e4b0,
-	0x81fe1d18,
-	0xbd060201,
-	0x0412fd20,
-	0xfd01e4b6,
-	0x18fe051e,
-	0x04fc7e00,
-	0xd40ef400,
-/* 0x0458: main_not_ctx_xfer */
-	0xf010ef94,
-	0xf87e01f5,
-	0x0ef40002,
-/* 0x0465: ih */
-	0xfe80f9c7,
-	0x80f90188,
-	0xa0f990f9,
-	0xd0f9b0f9,
-	0xf0f9e0f9,
-	0x004a04bd,
-	0x00aacf02,
-	0xf404abc4,
-	0x240d1f0b,
-	0xcf1a004e,
-	0x004f00ee,
-	0x00ffcf19,
-	0x0000047e,
-	0x0040010e,
-	0x000ef61d,
-/* 0x04a2: ih_no_fifo */
-	0x004004bd,
-	0x000af601,
-	0xf0fc04bd,
-	0xd0fce0fc,
-	0xa0fcb0fc,
-	0x80fc90fc,
-	0xfc0088fe,
-	0x0032f480,
-/* 0x04c2: hub_barrier_done */
-	0x010f01f8,
-	0xbb040e98,
-	0xffb204fe,
-	0x4094188e,
-	0x00008f7e,
-/* 0x04d6: ctx_redswitch */
-	0x200f00f8,
-	0x01850080,
-	0xbd000ff6,
-/* 0x04e3: ctx_redswitch_delay */
-	0xb6080e04,
-	0x1bf401e2,
-	0x00f5f1fd,
-	0x00f5f108,
-	0x85008002,
+	0x004104bd,
+	0x0011cf42,
+	0x010911e7,
+	0xfe0814b6,
+	0x02020014,
+	0xf6120040,
+	0x04bd0002,
+	0xfe047241,
+	0x00400010,
+	0x0000f607,
+	0x040204bd,
+	0xf6040040,
+	0x04bd0002,
+	0x821031f4,
+	0xcf018200,
+	0x01030022,
+	0xbb1f24f0,
+	0x32b60432,
+	0x0502b501,
+	0x820603b5,
+	0xcf018600,
+	0x02b50022,
+	0x0c308e04,
+	0xbd24bd50,
+/* 0x0377: init_unk_loop */
+	0x7e44bd34,
+	0xb0000065,
+	0x0bf400f6,
+	0xbb010f0e,
+	0x4ffd04f2,
+	0x0130b605,
+/* 0x038c: init_unk_next */
+	0xb60120b6,
+	0x26b004e0,
+	0xe21bf401,
+/* 0x0398: init_unk_done */
+	0xb50703b5,
+	0x00820804,
+	0x22cf0201,
+	0x9534bd00,
+	0x00800825,
+	0x05f601c0,
+	0x8004bd00,
+	0xf601c100,
+	0x04bd0005,
+	0x98000e98,
+	0x207e010f,
+	0x2fbb0001,
+	0x003fbb00,
+	0x98010e98,
+	0x207e020f,
+	0x0e980001,
+	0x00effd05,
+	0xbb002ebb,
+	0x0e98003e,
+	0x030f9802,
+	0x0001207e,
+	0xfd070e98,
+	0x2ebb00ef,
+	0x003ebb00,
+	0x800235b6,
+	0xf601d300,
+	0x04bd0003,
+	0xb60825b6,
+	0x20b60635,
+	0x0130b601,
+	0xb60824b6,
+	0x2fb20834,
+	0x0002687e,
+	0x80003fbb,
+	0xf6020100,
+	0x04bd0003,
+	0x29f024bd,
+	0x3000801f,
+	0x0002f602,
+/* 0x0436: main */
+	0x31f404bd,
+	0x0028f400,
+	0x377e240d,
+	0x01f40000,
+	0x04e4b0f4,
+	0xfe1d18f4,
+	0x06020181,
+	0x12fd20bd,
+	0x01e4b604,
+	0xfe051efd,
+	0x097e0018,
+	0x0ef40005,
+/* 0x0465: main_not_ctx_xfer */
+	0x10ef94d4,
+	0x7e01f5f0,
+	0xf40002f8,
+/* 0x0472: ih */
+	0x80f9c70e,
+	0xf90188fe,
+	0xf990f980,
+	0xf9b0f9a0,
+	0xf9e0f9d0,
+	0x4a04bdf0,
+	0xaacf0200,
+	0x04abc400,
+	0x0d1f0bf4,
+	0x1a004e24,
+	0x4f00eecf,
+	0xffcf1900,
+	0x00047e00,
+	0x40010e00,
+	0x0ef61d00,
+/* 0x04af: ih_no_fifo */
+	0x4004bd00,
+	0x0af60100,
+	0xfc04bd00,
+	0xfce0fcf0,
+	0xfcb0fcd0,
+	0xfc90fca0,
+	0x0088fe80,
+	0x32f480fc,
+/* 0x04cf: hub_barrier_done */
+	0x0f01f800,
+	0x040e9801,
+	0xb204febb,
+	0x94188eff,
+	0x008f7e40,
+/* 0x04e3: ctx_redswitch */
+	0x0f00f800,
+	0x85008020,
 	0x000ff601,
-	0x00f804bd,
-/* 0x04fc: ctx_xfer */
-	0x02810080,
-	0xbd000ff6,
-	0x0711f404,
-	0x0004d67e,
-/* 0x050c: ctx_xfer_not_load */
-	0x0002167e,
-	0xfc8024bd,
-	0x02f60247,
+	0x080e04bd,
+/* 0x04f0: ctx_redswitch_delay */
+	0xf401e2b6,
+	0xf5f1fd1b,
+	0xf5f10800,
+	0x00800200,
+	0x0ff60185,
+	0xf804bd00,
+/* 0x0509: ctx_xfer */
+	0x81008000,
+	0x000ff602,
+	0x11f404bd,
+	0x04e37e07,
+/* 0x0519: ctx_xfer_not_load */
+	0x02167e00,
+	0x8024bd00,
+	0xf60247fc,
+	0x04bd0002,
+	0xb6012cf0,
+	0xfc800320,
+	0x02f6024a,
 	0xf004bd00,
-	0x20b6012c,
-	0x4afc8003,
-	0x0002f602,
-	0xacf004bd,
-	0x02a5f001,
-	0x5000008b,
+	0xa5f001ac,
+	0x00008b02,
+	0x040c9850,
+	0xbb0fc4b6,
+	0x0c9800bc,
+	0x010d9800,
+	0x3d7e000e,
+	0xacf00001,
+	0x40008b01,
+	0x040c9850,
+	0xbb0fc4b6,
+	0x0c9800bc,
+	0x020d9801,
+	0x4e060f98,
+	0x3d7e0800,
+	0xacf00001,
+	0x04a5f001,
+	0x5030008b,
 	0xb6040c98,
 	0xbcbb0fc4,
-	0x000c9800,
-	0x0e010d98,
-	0x013d7e00,
-	0x01acf000,
-	0x5040008b,
-	0xb6040c98,
-	0xbcbb0fc4,
-	0x010c9800,
-	0x98020d98,
-	0x004e060f,
-	0x013d7e08,
-	0x01acf000,
-	0x8b04a5f0,
-	0x98503000,
-	0xc4b6040c,
-	0x00bcbb0f,
-	0x98020c98,
-	0x0f98030d,
-	0x02004e08,
-	0x00013d7e,
-	0x00020a7e,
-	0xf40601f4,
-/* 0x0596: ctx_xfer_post */
-	0x277e0712,
-/* 0x059a: ctx_xfer_done */
-	0xc27e0002,
-	0x00f80004,
-	0x00000000,
-	0x00000000,
-	0x00000000,
+	0x020c9800,
+	0x98030d98,
+	0x004e080f,
+	0x013d7e02,
+	0x020a7e00,
+	0x0601f400,
+/* 0x05a3: ctx_xfer_post */
+	0x7e0712f4,
+/* 0x05a7: ctx_xfer_done */
+	0x7e000227,
+	0xf80004cf,
 	0x00000000,
 	0x00000000,
 	0x00000000,

+ 168 - 168
drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc.h

@@ -192,7 +192,7 @@ uint32_t nvc0_grgpc_code[] = {
 	0x1fb4f000,
 	0xf410b4b0,
 	0xa7f0f01b,
-	0xd021f402,
+	0xd021f405,
 /* 0x0223: mmctx_stop */
 	0xc82b0ef4,
 	0xb4b600ab,
@@ -300,182 +300,182 @@ uint32_t nvc0_grgpc_code[] = {
 	0x21f440e3,
 	0xf8e0fc9d,
 /* 0x03a1: init */
-	0xfe04bd00,
-	0x27f00004,
-	0x0007f102,
-	0x0003f012,
-	0xbd0002d0,
-	0xd517f104,
-	0x0010fe04,
-	0x070007f1,
+	0xf104bd00,
+	0xf0420017,
+	0x11cf0013,
+	0x0911e700,
+	0x0814b601,
+	0xf00014fe,
+	0x07f10227,
+	0x03f01200,
+	0x0002d000,
+	0x17f104bd,
+	0x10fe04e6,
+	0x0007f100,
+	0x0003f007,
+	0xbd0000d0,
+	0x0427f004,
+	0x040007f1,
 	0xd00003f0,
-	0x04bd0000,
-	0xf10427f0,
-	0xf0040007,
-	0x02d00003,
-	0xf404bd00,
-	0x27f11031,
-	0x23f08200,
-	0x0022cf01,
-	0xf00137f0,
-	0x32bb1f24,
-	0x0132b604,
-	0x80050280,
-	0x27f10603,
-	0x23f08600,
-	0x0022cf01,
-	0xf1040280,
-	0xf0010027,
-	0x22cf0223,
-	0x9534bd00,
-	0x07f10825,
-	0x03f0c000,
-	0x0005d001,
-	0x07f104bd,
-	0x03f0c100,
-	0x0005d001,
-	0x0e9804bd,
-	0x010f9800,
-	0x015021f5,
-	0xbb002fbb,
-	0x0e98003f,
-	0x020f9801,
-	0x015021f5,
-	0xfd050e98,
-	0x2ebb00ef,
-	0x003ebb00,
-	0xf10235b6,
-	0xf0d30007,
-	0x03d00103,
-	0xb604bd00,
-	0x35b60825,
-	0x0120b606,
-	0xb60130b6,
-	0x34b60824,
-	0x022fb908,
-	0x02d321f5,
-	0xf1003fbb,
-	0xf0010007,
-	0x03d00203,
-	0xbd04bd00,
-	0x1f29f024,
-	0x080007f1,
-	0xd00203f0,
 	0x04bd0002,
-/* 0x0498: main */
-	0xf40031f4,
-	0xd7f00028,
-	0x3921f41c,
-	0xb0f401f4,
-	0x18f404e4,
-	0x0181fe1e,
-	0xbd0627f0,
-	0x0412fd20,
-	0xfd01e4b6,
-	0x18fe051e,
-	0x8d21f500,
-	0xd30ef405,
-/* 0x04c8: main_not_ctx_xfer */
-	0xf010ef94,
-	0x21f501f5,
-	0x0ef4037e,
-/* 0x04d5: ih */
-	0xfe80f9c6,
-	0x80f90188,
-	0xa0f990f9,
-	0xd0f9b0f9,
-	0xf0f9e0f9,
-	0xa7f104bd,
-	0xa3f00200,
-	0x00aacf00,
-	0xf404abc4,
-	0xd7f02c0b,
-	0x00e7f11c,
-	0x00e3f01a,
-	0xf100eecf,
-	0xf01900f7,
-	0xffcf00f3,
-	0x0421f400,
-	0xf101e7f0,
-	0xf01d0007,
-	0x0ed00003,
-/* 0x0523: ih_no_fifo */
+	0xf11031f4,
+	0xf0820027,
+	0x22cf0123,
+	0x0137f000,
+	0xbb1f24f0,
+	0x32b60432,
+	0x05028001,
+	0xf1060380,
+	0xf0860027,
+	0x22cf0123,
+	0x04028000,
+	0x010027f1,
+	0xcf0223f0,
+	0x34bd0022,
+	0xf1082595,
+	0xf0c00007,
+	0x05d00103,
 	0xf104bd00,
-	0xf0010007,
-	0x0ad00003,
-	0xfc04bd00,
-	0xfce0fcf0,
-	0xfcb0fcd0,
-	0xfc90fca0,
-	0x0088fe80,
-	0x32f480fc,
-/* 0x0547: hub_barrier_done */
-	0xf001f800,
-	0x0e9801f7,
-	0x04febb04,
-	0xf102ffb9,
-	0xf09418e7,
-	0x21f440e3,
-/* 0x055f: ctx_redswitch */
-	0xf000f89d,
-	0x07f120f7,
-	0x03f08500,
-	0x000fd001,
-	0xe7f004bd,
-/* 0x0571: ctx_redswitch_delay */
-	0x01e2b608,
-	0xf1fd1bf4,
-	0xf10800f5,
-	0xf10200f5,
+	0xf0c10007,
+	0x05d00103,
+	0x9804bd00,
+	0x0f98000e,
+	0x5021f501,
+	0x002fbb01,
+	0x98003fbb,
+	0x0f98010e,
+	0x5021f502,
+	0x050e9801,
+	0xbb00effd,
+	0x3ebb002e,
+	0x0235b600,
+	0xd30007f1,
+	0xd00103f0,
+	0x04bd0003,
+	0xb60825b6,
+	0x20b60635,
+	0x0130b601,
+	0xb60824b6,
+	0x2fb90834,
+	0xd321f502,
+	0x003fbb02,
+	0x010007f1,
+	0xd00203f0,
+	0x04bd0003,
+	0x29f024bd,
+	0x0007f11f,
+	0x0203f008,
+	0xbd0002d0,
+/* 0x04a9: main */
+	0x0031f404,
+	0xf00028f4,
+	0x21f41cd7,
+	0xf401f439,
+	0xf404e4b0,
+	0x81fe1e18,
+	0x0627f001,
+	0x12fd20bd,
+	0x01e4b604,
+	0xfe051efd,
+	0x21f50018,
+	0x0ef4059e,
+/* 0x04d9: main_not_ctx_xfer */
+	0x10ef94d3,
+	0xf501f5f0,
+	0xf4037e21,
+/* 0x04e6: ih */
+	0x80f9c60e,
+	0xf90188fe,
+	0xf990f980,
+	0xf9b0f9a0,
+	0xf9e0f9d0,
+	0xf104bdf0,
+	0xf00200a7,
+	0xaacf00a3,
+	0x04abc400,
+	0xf02c0bf4,
+	0xe7f11cd7,
+	0xe3f01a00,
+	0x00eecf00,
+	0x1900f7f1,
+	0xcf00f3f0,
+	0x21f400ff,
+	0x01e7f004,
+	0x1d0007f1,
+	0xd00003f0,
+	0x04bd000e,
+/* 0x0534: ih_no_fifo */
+	0x010007f1,
+	0xd00003f0,
+	0x04bd000a,
+	0xe0fcf0fc,
+	0xb0fcd0fc,
+	0x90fca0fc,
+	0x88fe80fc,
+	0xf480fc00,
+	0x01f80032,
+/* 0x0558: hub_barrier_done */
+	0x9801f7f0,
+	0xfebb040e,
+	0x02ffb904,
+	0x9418e7f1,
+	0xf440e3f0,
+	0x00f89d21,
+/* 0x0570: ctx_redswitch */
+	0xf120f7f0,
 	0xf0850007,
 	0x0fd00103,
-	0xf804bd00,
-/* 0x058d: ctx_xfer */
-	0x0007f100,
-	0x0203f081,
-	0xbd000fd0,
-	0x0711f404,
-	0x055f21f5,
-/* 0x05a0: ctx_xfer_not_load */
-	0x026a21f5,
-	0x07f124bd,
-	0x03f047fc,
-	0x0002d002,
-	0x2cf004bd,
-	0x0320b601,
-	0x4afc07f1,
-	0xd00203f0,
-	0x04bd0002,
+	0xf004bd00,
+/* 0x0582: ctx_redswitch_delay */
+	0xe2b608e7,
+	0xfd1bf401,
+	0x0800f5f1,
+	0x0200f5f1,
+	0x850007f1,
+	0xd00103f0,
+	0x04bd000f,
+/* 0x059e: ctx_xfer */
+	0x07f100f8,
+	0x03f08100,
+	0x000fd002,
+	0x11f404bd,
+	0x7021f507,
+/* 0x05b1: ctx_xfer_not_load */
+	0x6a21f505,
+	0xf124bd02,
+	0xf047fc07,
+	0x02d00203,
+	0xf004bd00,
+	0x20b6012c,
+	0xfc07f103,
+	0x0203f04a,
+	0xbd0002d0,
+	0x01acf004,
+	0xf102a5f0,
+	0xf00000b7,
+	0x0c9850b3,
+	0x0fc4b604,
+	0x9800bcbb,
+	0x0d98000c,
+	0x00e7f001,
+	0x016f21f5,
 	0xf001acf0,
-	0xb7f102a5,
-	0xb3f00000,
+	0xb7f104a5,
+	0xb3f04000,
 	0x040c9850,
 	0xbb0fc4b6,
 	0x0c9800bc,
-	0x010d9800,
-	0xf500e7f0,
-	0xf0016f21,
-	0xa5f001ac,
-	0x00b7f104,
-	0x50b3f040,
-	0xb6040c98,
-	0xbcbb0fc4,
-	0x010c9800,
-	0x98020d98,
-	0xe7f1060f,
-	0x21f50800,
-	0x21f5016f,
-	0x01f4025e,
-	0x0712f406,
-/* 0x0618: ctx_xfer_post */
-	0x027f21f5,
-/* 0x061c: ctx_xfer_done */
-	0x054721f5,
-	0x000000f8,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
+	0x020d9801,
+	0xf1060f98,
+	0xf50800e7,
+	0xf5016f21,
+	0xf4025e21,
+	0x12f40601,
+/* 0x0629: ctx_xfer_post */
+	0x7f21f507,
+/* 0x062d: ctx_xfer_done */
+	0x5821f502,
+	0x0000f805,
 	0x00000000,
 	0x00000000,
 	0x00000000,

+ 198 - 198
drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvd7.fuc.h

@@ -196,7 +196,7 @@ uint32_t nvd7_grgpc_code[] = {
 	0x1fb4f000,
 	0xf410b4b0,
 	0xa7f0f01b,
-	0xd021f402,
+	0xd021f405,
 /* 0x0223: mmctx_stop */
 	0xc82b0ef4,
 	0xb4b600ab,
@@ -304,212 +304,212 @@ uint32_t nvd7_grgpc_code[] = {
 	0x21f440e3,
 	0xf8e0fc9d,
 /* 0x03a1: init */
-	0xfe04bd00,
-	0x27f00004,
-	0x0007f102,
-	0x0003f012,
-	0xbd0002d0,
-	0x1f17f104,
-	0x0010fe05,
-	0x070007f1,
+	0xf104bd00,
+	0xf0420017,
+	0x11cf0013,
+	0x0911e700,
+	0x0814b601,
+	0xf00014fe,
+	0x07f10227,
+	0x03f01200,
+	0x0002d000,
+	0x17f104bd,
+	0x10fe0530,
+	0x0007f100,
+	0x0003f007,
+	0xbd0000d0,
+	0x0427f004,
+	0x040007f1,
 	0xd00003f0,
-	0x04bd0000,
-	0xf10427f0,
-	0xf0040007,
-	0x02d00003,
+	0x04bd0002,
+	0xf11031f4,
+	0xf0820027,
+	0x22cf0123,
+	0x0137f000,
+	0xbb1f24f0,
+	0x32b60432,
+	0x05028001,
+	0xf1060380,
+	0xf0860027,
+	0x22cf0123,
+	0x04028000,
+	0x0c30e7f1,
+	0xbd50e3f0,
+	0xbd34bd24,
+/* 0x0421: init_unk_loop */
+	0x6821f444,
+	0xf400f6b0,
+	0xf7f00f0b,
+	0x04f2bb01,
+	0xb6054ffd,
+/* 0x0436: init_unk_next */
+	0x20b60130,
+	0x04e0b601,
+	0xf40126b0,
+/* 0x0442: init_unk_done */
+	0x0380e21b,
+	0x08048007,
+	0x010027f1,
+	0xcf0223f0,
+	0x34bd0022,
+	0xf1082595,
+	0xf0c00007,
+	0x05d00103,
+	0xf104bd00,
+	0xf0c10007,
+	0x05d00103,
+	0x9804bd00,
+	0x0f98000e,
+	0x5021f501,
+	0x002fbb01,
+	0x98003fbb,
+	0x0f98010e,
+	0x5021f502,
+	0x050e9801,
+	0xbb00effd,
+	0x3ebb002e,
+	0x020e9800,
+	0xf5030f98,
+	0x98015021,
+	0xeffd070e,
+	0x002ebb00,
+	0xb6003ebb,
+	0x07f10235,
+	0x03f0d300,
+	0x0003d001,
+	0x25b604bd,
+	0x0635b608,
+	0xb60120b6,
+	0x24b60130,
+	0x0834b608,
+	0xf5022fb9,
+	0xbb02d321,
+	0x07f1003f,
+	0x03f00100,
+	0x0003d002,
+	0x24bd04bd,
+	0xf11f29f0,
+	0xf0080007,
+	0x02d00203,
+/* 0x04f3: main */
 	0xf404bd00,
-	0x27f11031,
-	0x23f08200,
-	0x0022cf01,
-	0xf00137f0,
-	0x32bb1f24,
-	0x0132b604,
-	0x80050280,
-	0x27f10603,
-	0x23f08600,
-	0x0022cf01,
-	0xf1040280,
-	0xf00c30e7,
-	0x24bd50e3,
-	0x44bd34bd,
-/* 0x0410: init_unk_loop */
-	0xb06821f4,
-	0x0bf400f6,
-	0x01f7f00f,
-	0xfd04f2bb,
-	0x30b6054f,
-/* 0x0425: init_unk_next */
-	0x0120b601,
-	0xb004e0b6,
-	0x1bf40126,
-/* 0x0431: init_unk_done */
-	0x070380e2,
-	0xf1080480,
-	0xf0010027,
-	0x22cf0223,
-	0x9534bd00,
-	0x07f10825,
-	0x03f0c000,
-	0x0005d001,
+	0x28f40031,
+	0x24d7f000,
+	0xf43921f4,
+	0xe4b0f401,
+	0x1e18f404,
+	0xf00181fe,
+	0x20bd0627,
+	0xb60412fd,
+	0x1efd01e4,
+	0x0018fe05,
+	0x05e821f5,
+/* 0x0523: main_not_ctx_xfer */
+	0x94d30ef4,
+	0xf5f010ef,
+	0x7e21f501,
+	0xc60ef403,
+/* 0x0530: ih */
+	0x88fe80f9,
+	0xf980f901,
+	0xf9a0f990,
+	0xf9d0f9b0,
+	0xbdf0f9e0,
+	0x00a7f104,
+	0x00a3f002,
+	0xc400aacf,
+	0x0bf404ab,
+	0x24d7f02c,
+	0x1a00e7f1,
+	0xcf00e3f0,
+	0xf7f100ee,
+	0xf3f01900,
+	0x00ffcf00,
+	0xf00421f4,
+	0x07f101e7,
+	0x03f01d00,
+	0x000ed000,
+/* 0x057e: ih_no_fifo */
 	0x07f104bd,
-	0x03f0c100,
-	0x0005d001,
-	0x0e9804bd,
-	0x010f9800,
-	0x015021f5,
-	0xbb002fbb,
-	0x0e98003f,
-	0x020f9801,
-	0x015021f5,
-	0xfd050e98,
-	0x2ebb00ef,
-	0x003ebb00,
-	0x98020e98,
-	0x21f5030f,
-	0x0e980150,
-	0x00effd07,
-	0xbb002ebb,
-	0x35b6003e,
-	0x0007f102,
-	0x0103f0d3,
-	0xbd0003d0,
-	0x0825b604,
-	0xb60635b6,
-	0x30b60120,
-	0x0824b601,
-	0xb90834b6,
-	0x21f5022f,
-	0x3fbb02d3,
-	0x0007f100,
-	0x0203f001,
-	0xbd0003d0,
-	0xf024bd04,
-	0x07f11f29,
-	0x03f00800,
-	0x0002d002,
-/* 0x04e2: main */
-	0x31f404bd,
-	0x0028f400,
-	0xf424d7f0,
-	0x01f43921,
-	0x04e4b0f4,
-	0xfe1e18f4,
-	0x27f00181,
-	0xfd20bd06,
-	0xe4b60412,
-	0x051efd01,
-	0xf50018fe,
-	0xf405d721,
-/* 0x0512: main_not_ctx_xfer */
-	0xef94d30e,
-	0x01f5f010,
-	0x037e21f5,
-/* 0x051f: ih */
-	0xf9c60ef4,
-	0x0188fe80,
-	0x90f980f9,
-	0xb0f9a0f9,
-	0xe0f9d0f9,
-	0x04bdf0f9,
-	0x0200a7f1,
-	0xcf00a3f0,
-	0xabc400aa,
-	0x2c0bf404,
-	0xf124d7f0,
-	0xf01a00e7,
-	0xeecf00e3,
-	0x00f7f100,
-	0x00f3f019,
-	0xf400ffcf,
-	0xe7f00421,
-	0x0007f101,
-	0x0003f01d,
-	0xbd000ed0,
-/* 0x056d: ih_no_fifo */
-	0x0007f104,
-	0x0003f001,
-	0xbd000ad0,
-	0xfcf0fc04,
-	0xfcd0fce0,
-	0xfca0fcb0,
-	0xfe80fc90,
-	0x80fc0088,
-	0xf80032f4,
-/* 0x0591: hub_barrier_done */
-	0x01f7f001,
-	0xbb040e98,
-	0xffb904fe,
-	0x18e7f102,
-	0x40e3f094,
-	0xf89d21f4,
-/* 0x05a9: ctx_redswitch */
-	0x20f7f000,
-	0x850007f1,
-	0xd00103f0,
-	0x04bd000f,
-/* 0x05bb: ctx_redswitch_delay */
-	0xb608e7f0,
-	0x1bf401e2,
-	0x00f5f1fd,
-	0x00f5f108,
-	0x0007f102,
+	0x03f00100,
+	0x000ad000,
+	0xf0fc04bd,
+	0xd0fce0fc,
+	0xa0fcb0fc,
+	0x80fc90fc,
+	0xfc0088fe,
+	0x0032f480,
+/* 0x05a2: hub_barrier_done */
+	0xf7f001f8,
+	0x040e9801,
+	0xb904febb,
+	0xe7f102ff,
+	0xe3f09418,
+	0x9d21f440,
+/* 0x05ba: ctx_redswitch */
+	0xf7f000f8,
+	0x0007f120,
 	0x0103f085,
 	0xbd000fd0,
-/* 0x05d7: ctx_xfer */
-	0xf100f804,
-	0xf0810007,
-	0x0fd00203,
-	0xf404bd00,
-	0x21f50711,
-/* 0x05ea: ctx_xfer_not_load */
-	0x21f505a9,
-	0x24bd026a,
-	0x47fc07f1,
+	0x08e7f004,
+/* 0x05cc: ctx_redswitch_delay */
+	0xf401e2b6,
+	0xf5f1fd1b,
+	0xf5f10800,
+	0x07f10200,
+	0x03f08500,
+	0x000fd001,
+	0x00f804bd,
+/* 0x05e8: ctx_xfer */
+	0x810007f1,
 	0xd00203f0,
-	0x04bd0002,
-	0xb6012cf0,
-	0x07f10320,
-	0x03f04afc,
-	0x0002d002,
-	0xacf004bd,
-	0x02a5f001,
-	0x0000b7f1,
-	0x9850b3f0,
-	0xc4b6040c,
-	0x00bcbb0f,
-	0x98000c98,
-	0xe7f0010d,
-	0x6f21f500,
-	0x01acf001,
-	0x4000b7f1,
+	0x04bd000f,
+	0xf50711f4,
+/* 0x05fb: ctx_xfer_not_load */
+	0xf505ba21,
+	0xbd026a21,
+	0xfc07f124,
+	0x0203f047,
+	0xbd0002d0,
+	0x012cf004,
+	0xf10320b6,
+	0xf04afc07,
+	0x02d00203,
+	0xf004bd00,
+	0xa5f001ac,
+	0x00b7f102,
+	0x50b3f000,
+	0xb6040c98,
+	0xbcbb0fc4,
+	0x000c9800,
+	0xf0010d98,
+	0x21f500e7,
+	0xacf0016f,
+	0x00b7f101,
+	0x50b3f040,
+	0xb6040c98,
+	0xbcbb0fc4,
+	0x010c9800,
+	0x98020d98,
+	0xe7f1060f,
+	0x21f50800,
+	0xacf0016f,
+	0x04a5f001,
+	0x3000b7f1,
 	0x9850b3f0,
 	0xc4b6040c,
 	0x00bcbb0f,
-	0x98010c98,
-	0x0f98020d,
-	0x00e7f106,
-	0x6f21f508,
-	0x01acf001,
-	0xf104a5f0,
-	0xf03000b7,
-	0x0c9850b3,
-	0x0fc4b604,
-	0x9800bcbb,
-	0x0d98020c,
-	0x080f9803,
-	0x0200e7f1,
-	0x016f21f5,
-	0x025e21f5,
-	0xf40601f4,
-/* 0x0686: ctx_xfer_post */
-	0x21f50712,
-/* 0x068a: ctx_xfer_done */
-	0x21f5027f,
-	0x00f80591,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
+	0x98020c98,
+	0x0f98030d,
+	0x00e7f108,
+	0x6f21f502,
+	0x5e21f501,
+	0x0601f402,
+/* 0x0697: ctx_xfer_post */
+	0xf50712f4,
+/* 0x069b: ctx_xfer_done */
+	0xf5027f21,
+	0xf805a221,
 	0x00000000,
 	0x00000000,
 	0x00000000,

+ 198 - 198
drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc.h

@@ -196,7 +196,7 @@ uint32_t nve0_grgpc_code[] = {
 	0x1fb4f000,
 	0xf410b4b0,
 	0xa7f0f01b,
-	0xd021f402,
+	0xd021f405,
 /* 0x0223: mmctx_stop */
 	0xc82b0ef4,
 	0xb4b600ab,
@@ -304,212 +304,212 @@ uint32_t nve0_grgpc_code[] = {
 	0x21f440e3,
 	0xf8e0fc9d,
 /* 0x03a1: init */
-	0xfe04bd00,
-	0x27f00004,
-	0x0007f102,
-	0x0003f012,
-	0xbd0002d0,
-	0x1f17f104,
-	0x0010fe05,
-	0x070007f1,
+	0xf104bd00,
+	0xf0420017,
+	0x11cf0013,
+	0x0911e700,
+	0x0814b601,
+	0xf00014fe,
+	0x07f10227,
+	0x03f01200,
+	0x0002d000,
+	0x17f104bd,
+	0x10fe0530,
+	0x0007f100,
+	0x0003f007,
+	0xbd0000d0,
+	0x0427f004,
+	0x040007f1,
 	0xd00003f0,
-	0x04bd0000,
-	0xf10427f0,
-	0xf0040007,
-	0x02d00003,
+	0x04bd0002,
+	0xf11031f4,
+	0xf0820027,
+	0x22cf0123,
+	0x0137f000,
+	0xbb1f24f0,
+	0x32b60432,
+	0x05028001,
+	0xf1060380,
+	0xf0860027,
+	0x22cf0123,
+	0x04028000,
+	0x0c30e7f1,
+	0xbd50e3f0,
+	0xbd34bd24,
+/* 0x0421: init_unk_loop */
+	0x6821f444,
+	0xf400f6b0,
+	0xf7f00f0b,
+	0x04f2bb01,
+	0xb6054ffd,
+/* 0x0436: init_unk_next */
+	0x20b60130,
+	0x04e0b601,
+	0xf40126b0,
+/* 0x0442: init_unk_done */
+	0x0380e21b,
+	0x08048007,
+	0x010027f1,
+	0xcf0223f0,
+	0x34bd0022,
+	0xf1082595,
+	0xf0c00007,
+	0x05d00103,
+	0xf104bd00,
+	0xf0c10007,
+	0x05d00103,
+	0x9804bd00,
+	0x0f98000e,
+	0x5021f501,
+	0x002fbb01,
+	0x98003fbb,
+	0x0f98010e,
+	0x5021f502,
+	0x050e9801,
+	0xbb00effd,
+	0x3ebb002e,
+	0x020e9800,
+	0xf5030f98,
+	0x98015021,
+	0xeffd070e,
+	0x002ebb00,
+	0xb6003ebb,
+	0x07f10235,
+	0x03f0d300,
+	0x0003d001,
+	0x25b604bd,
+	0x0635b608,
+	0xb60120b6,
+	0x24b60130,
+	0x0834b608,
+	0xf5022fb9,
+	0xbb02d321,
+	0x07f1003f,
+	0x03f00100,
+	0x0003d002,
+	0x24bd04bd,
+	0xf11f29f0,
+	0xf0080007,
+	0x02d00203,
+/* 0x04f3: main */
 	0xf404bd00,
-	0x27f11031,
-	0x23f08200,
-	0x0022cf01,
-	0xf00137f0,
-	0x32bb1f24,
-	0x0132b604,
-	0x80050280,
-	0x27f10603,
-	0x23f08600,
-	0x0022cf01,
-	0xf1040280,
-	0xf00c30e7,
-	0x24bd50e3,
-	0x44bd34bd,
-/* 0x0410: init_unk_loop */
-	0xb06821f4,
-	0x0bf400f6,
-	0x01f7f00f,
-	0xfd04f2bb,
-	0x30b6054f,
-/* 0x0425: init_unk_next */
-	0x0120b601,
-	0xb004e0b6,
-	0x1bf40126,
-/* 0x0431: init_unk_done */
-	0x070380e2,
-	0xf1080480,
-	0xf0010027,
-	0x22cf0223,
-	0x9534bd00,
-	0x07f10825,
-	0x03f0c000,
-	0x0005d001,
+	0x28f40031,
+	0x24d7f000,
+	0xf43921f4,
+	0xe4b0f401,
+	0x1e18f404,
+	0xf00181fe,
+	0x20bd0627,
+	0xb60412fd,
+	0x1efd01e4,
+	0x0018fe05,
+	0x05e821f5,
+/* 0x0523: main_not_ctx_xfer */
+	0x94d30ef4,
+	0xf5f010ef,
+	0x7e21f501,
+	0xc60ef403,
+/* 0x0530: ih */
+	0x88fe80f9,
+	0xf980f901,
+	0xf9a0f990,
+	0xf9d0f9b0,
+	0xbdf0f9e0,
+	0x00a7f104,
+	0x00a3f002,
+	0xc400aacf,
+	0x0bf404ab,
+	0x24d7f02c,
+	0x1a00e7f1,
+	0xcf00e3f0,
+	0xf7f100ee,
+	0xf3f01900,
+	0x00ffcf00,
+	0xf00421f4,
+	0x07f101e7,
+	0x03f01d00,
+	0x000ed000,
+/* 0x057e: ih_no_fifo */
 	0x07f104bd,
-	0x03f0c100,
-	0x0005d001,
-	0x0e9804bd,
-	0x010f9800,
-	0x015021f5,
-	0xbb002fbb,
-	0x0e98003f,
-	0x020f9801,
-	0x015021f5,
-	0xfd050e98,
-	0x2ebb00ef,
-	0x003ebb00,
-	0x98020e98,
-	0x21f5030f,
-	0x0e980150,
-	0x00effd07,
-	0xbb002ebb,
-	0x35b6003e,
-	0x0007f102,
-	0x0103f0d3,
-	0xbd0003d0,
-	0x0825b604,
-	0xb60635b6,
-	0x30b60120,
-	0x0824b601,
-	0xb90834b6,
-	0x21f5022f,
-	0x3fbb02d3,
-	0x0007f100,
-	0x0203f001,
-	0xbd0003d0,
-	0xf024bd04,
-	0x07f11f29,
-	0x03f00800,
-	0x0002d002,
-/* 0x04e2: main */
-	0x31f404bd,
-	0x0028f400,
-	0xf424d7f0,
-	0x01f43921,
-	0x04e4b0f4,
-	0xfe1e18f4,
-	0x27f00181,
-	0xfd20bd06,
-	0xe4b60412,
-	0x051efd01,
-	0xf50018fe,
-	0xf405d721,
-/* 0x0512: main_not_ctx_xfer */
-	0xef94d30e,
-	0x01f5f010,
-	0x037e21f5,
-/* 0x051f: ih */
-	0xf9c60ef4,
-	0x0188fe80,
-	0x90f980f9,
-	0xb0f9a0f9,
-	0xe0f9d0f9,
-	0x04bdf0f9,
-	0x0200a7f1,
-	0xcf00a3f0,
-	0xabc400aa,
-	0x2c0bf404,
-	0xf124d7f0,
-	0xf01a00e7,
-	0xeecf00e3,
-	0x00f7f100,
-	0x00f3f019,
-	0xf400ffcf,
-	0xe7f00421,
-	0x0007f101,
-	0x0003f01d,
-	0xbd000ed0,
-/* 0x056d: ih_no_fifo */
-	0x0007f104,
-	0x0003f001,
-	0xbd000ad0,
-	0xfcf0fc04,
-	0xfcd0fce0,
-	0xfca0fcb0,
-	0xfe80fc90,
-	0x80fc0088,
-	0xf80032f4,
-/* 0x0591: hub_barrier_done */
-	0x01f7f001,
-	0xbb040e98,
-	0xffb904fe,
-	0x18e7f102,
-	0x40e3f094,
-	0xf89d21f4,
-/* 0x05a9: ctx_redswitch */
-	0x20f7f000,
-	0x850007f1,
-	0xd00103f0,
-	0x04bd000f,
-/* 0x05bb: ctx_redswitch_delay */
-	0xb608e7f0,
-	0x1bf401e2,
-	0x00f5f1fd,
-	0x00f5f108,
-	0x0007f102,
+	0x03f00100,
+	0x000ad000,
+	0xf0fc04bd,
+	0xd0fce0fc,
+	0xa0fcb0fc,
+	0x80fc90fc,
+	0xfc0088fe,
+	0x0032f480,
+/* 0x05a2: hub_barrier_done */
+	0xf7f001f8,
+	0x040e9801,
+	0xb904febb,
+	0xe7f102ff,
+	0xe3f09418,
+	0x9d21f440,
+/* 0x05ba: ctx_redswitch */
+	0xf7f000f8,
+	0x0007f120,
 	0x0103f085,
 	0xbd000fd0,
-/* 0x05d7: ctx_xfer */
-	0xf100f804,
-	0xf0810007,
-	0x0fd00203,
-	0xf404bd00,
-	0x21f50711,
-/* 0x05ea: ctx_xfer_not_load */
-	0x21f505a9,
-	0x24bd026a,
-	0x47fc07f1,
+	0x08e7f004,
+/* 0x05cc: ctx_redswitch_delay */
+	0xf401e2b6,
+	0xf5f1fd1b,
+	0xf5f10800,
+	0x07f10200,
+	0x03f08500,
+	0x000fd001,
+	0x00f804bd,
+/* 0x05e8: ctx_xfer */
+	0x810007f1,
 	0xd00203f0,
-	0x04bd0002,
-	0xb6012cf0,
-	0x07f10320,
-	0x03f04afc,
-	0x0002d002,
-	0xacf004bd,
-	0x02a5f001,
-	0x0000b7f1,
-	0x9850b3f0,
-	0xc4b6040c,
-	0x00bcbb0f,
-	0x98000c98,
-	0xe7f0010d,
-	0x6f21f500,
-	0x01acf001,
-	0x4000b7f1,
+	0x04bd000f,
+	0xf50711f4,
+/* 0x05fb: ctx_xfer_not_load */
+	0xf505ba21,
+	0xbd026a21,
+	0xfc07f124,
+	0x0203f047,
+	0xbd0002d0,
+	0x012cf004,
+	0xf10320b6,
+	0xf04afc07,
+	0x02d00203,
+	0xf004bd00,
+	0xa5f001ac,
+	0x00b7f102,
+	0x50b3f000,
+	0xb6040c98,
+	0xbcbb0fc4,
+	0x000c9800,
+	0xf0010d98,
+	0x21f500e7,
+	0xacf0016f,
+	0x00b7f101,
+	0x50b3f040,
+	0xb6040c98,
+	0xbcbb0fc4,
+	0x010c9800,
+	0x98020d98,
+	0xe7f1060f,
+	0x21f50800,
+	0xacf0016f,
+	0x04a5f001,
+	0x3000b7f1,
 	0x9850b3f0,
 	0xc4b6040c,
 	0x00bcbb0f,
-	0x98010c98,
-	0x0f98020d,
-	0x00e7f106,
-	0x6f21f508,
-	0x01acf001,
-	0xf104a5f0,
-	0xf03000b7,
-	0x0c9850b3,
-	0x0fc4b604,
-	0x9800bcbb,
-	0x0d98020c,
-	0x080f9803,
-	0x0200e7f1,
-	0x016f21f5,
-	0x025e21f5,
-	0xf40601f4,
-/* 0x0686: ctx_xfer_post */
-	0x21f50712,
-/* 0x068a: ctx_xfer_done */
-	0x21f5027f,
-	0x00f80591,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
+	0x98020c98,
+	0x0f98030d,
+	0x00e7f108,
+	0x6f21f502,
+	0x5e21f501,
+	0x0601f402,
+/* 0x0697: ctx_xfer_post */
+	0xf50712f4,
+/* 0x069b: ctx_xfer_done */
+	0xf5027f21,
+	0xf805a221,
 	0x00000000,
 	0x00000000,
 	0x00000000,

+ 198 - 198
drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc.h

@@ -196,7 +196,7 @@ uint32_t nvf0_grgpc_code[] = {
 	0x1fb4f000,
 	0xf410b4b0,
 	0xa7f0f01b,
-	0xd021f402,
+	0xd021f405,
 /* 0x0223: mmctx_stop */
 	0xc82b0ef4,
 	0xb4b600ab,
@@ -304,212 +304,212 @@ uint32_t nvf0_grgpc_code[] = {
 	0x21f440e3,
 	0xf8e0fc9d,
 /* 0x03a1: init */
-	0xfe04bd00,
-	0x27f00004,
-	0x0007f102,
-	0x0003f012,
-	0xbd0002d0,
-	0x1f17f104,
-	0x0010fe05,
-	0x070007f1,
+	0xf104bd00,
+	0xf0420017,
+	0x11cf0013,
+	0x0911e700,
+	0x0814b601,
+	0xf00014fe,
+	0x07f10227,
+	0x03f01200,
+	0x0002d000,
+	0x17f104bd,
+	0x10fe0530,
+	0x0007f100,
+	0x0003f007,
+	0xbd0000d0,
+	0x0427f004,
+	0x040007f1,
 	0xd00003f0,
-	0x04bd0000,
-	0xf10427f0,
-	0xf0040007,
-	0x02d00003,
+	0x04bd0002,
+	0xf11031f4,
+	0xf0820027,
+	0x22cf0123,
+	0x0137f000,
+	0xbb1f24f0,
+	0x32b60432,
+	0x05028001,
+	0xf1060380,
+	0xf0860027,
+	0x22cf0123,
+	0x04028000,
+	0x0c30e7f1,
+	0xbd50e3f0,
+	0xbd34bd24,
+/* 0x0421: init_unk_loop */
+	0x6821f444,
+	0xf400f6b0,
+	0xf7f00f0b,
+	0x04f2bb01,
+	0xb6054ffd,
+/* 0x0436: init_unk_next */
+	0x20b60130,
+	0x04e0b601,
+	0xf40226b0,
+/* 0x0442: init_unk_done */
+	0x0380e21b,
+	0x08048007,
+	0x010027f1,
+	0xcf0223f0,
+	0x34bd0022,
+	0xf1082595,
+	0xf0c00007,
+	0x05d00103,
+	0xf104bd00,
+	0xf0c10007,
+	0x05d00103,
+	0x9804bd00,
+	0x0f98000e,
+	0x5021f501,
+	0x002fbb01,
+	0x98003fbb,
+	0x0f98010e,
+	0x5021f502,
+	0x050e9801,
+	0xbb00effd,
+	0x3ebb002e,
+	0x020e9800,
+	0xf5030f98,
+	0x98015021,
+	0xeffd070e,
+	0x002ebb00,
+	0xb6003ebb,
+	0x07f10235,
+	0x03f0d300,
+	0x0003d001,
+	0x25b604bd,
+	0x0635b608,
+	0xb60120b6,
+	0x24b60130,
+	0x0834b608,
+	0xf5022fb9,
+	0xbb02d321,
+	0x07f1003f,
+	0x03f00100,
+	0x0003d002,
+	0x24bd04bd,
+	0xf11f29f0,
+	0xf0300007,
+	0x02d00203,
+/* 0x04f3: main */
 	0xf404bd00,
-	0x27f11031,
-	0x23f08200,
-	0x0022cf01,
-	0xf00137f0,
-	0x32bb1f24,
-	0x0132b604,
-	0x80050280,
-	0x27f10603,
-	0x23f08600,
-	0x0022cf01,
-	0xf1040280,
-	0xf00c30e7,
-	0x24bd50e3,
-	0x44bd34bd,
-/* 0x0410: init_unk_loop */
-	0xb06821f4,
-	0x0bf400f6,
-	0x01f7f00f,
-	0xfd04f2bb,
-	0x30b6054f,
-/* 0x0425: init_unk_next */
-	0x0120b601,
-	0xb004e0b6,
-	0x1bf40226,
-/* 0x0431: init_unk_done */
-	0x070380e2,
-	0xf1080480,
-	0xf0010027,
-	0x22cf0223,
-	0x9534bd00,
-	0x07f10825,
-	0x03f0c000,
-	0x0005d001,
+	0x28f40031,
+	0x24d7f000,
+	0xf43921f4,
+	0xe4b0f401,
+	0x1e18f404,
+	0xf00181fe,
+	0x20bd0627,
+	0xb60412fd,
+	0x1efd01e4,
+	0x0018fe05,
+	0x05e821f5,
+/* 0x0523: main_not_ctx_xfer */
+	0x94d30ef4,
+	0xf5f010ef,
+	0x7e21f501,
+	0xc60ef403,
+/* 0x0530: ih */
+	0x88fe80f9,
+	0xf980f901,
+	0xf9a0f990,
+	0xf9d0f9b0,
+	0xbdf0f9e0,
+	0x00a7f104,
+	0x00a3f002,
+	0xc400aacf,
+	0x0bf404ab,
+	0x24d7f02c,
+	0x1a00e7f1,
+	0xcf00e3f0,
+	0xf7f100ee,
+	0xf3f01900,
+	0x00ffcf00,
+	0xf00421f4,
+	0x07f101e7,
+	0x03f01d00,
+	0x000ed000,
+/* 0x057e: ih_no_fifo */
 	0x07f104bd,
-	0x03f0c100,
-	0x0005d001,
-	0x0e9804bd,
-	0x010f9800,
-	0x015021f5,
-	0xbb002fbb,
-	0x0e98003f,
-	0x020f9801,
-	0x015021f5,
-	0xfd050e98,
-	0x2ebb00ef,
-	0x003ebb00,
-	0x98020e98,
-	0x21f5030f,
-	0x0e980150,
-	0x00effd07,
-	0xbb002ebb,
-	0x35b6003e,
-	0x0007f102,
-	0x0103f0d3,
-	0xbd0003d0,
-	0x0825b604,
-	0xb60635b6,
-	0x30b60120,
-	0x0824b601,
-	0xb90834b6,
-	0x21f5022f,
-	0x3fbb02d3,
-	0x0007f100,
-	0x0203f001,
-	0xbd0003d0,
-	0xf024bd04,
-	0x07f11f29,
-	0x03f03000,
-	0x0002d002,
-/* 0x04e2: main */
-	0x31f404bd,
-	0x0028f400,
-	0xf424d7f0,
-	0x01f43921,
-	0x04e4b0f4,
-	0xfe1e18f4,
-	0x27f00181,
-	0xfd20bd06,
-	0xe4b60412,
-	0x051efd01,
-	0xf50018fe,
-	0xf405d721,
-/* 0x0512: main_not_ctx_xfer */
-	0xef94d30e,
-	0x01f5f010,
-	0x037e21f5,
-/* 0x051f: ih */
-	0xf9c60ef4,
-	0x0188fe80,
-	0x90f980f9,
-	0xb0f9a0f9,
-	0xe0f9d0f9,
-	0x04bdf0f9,
-	0x0200a7f1,
-	0xcf00a3f0,
-	0xabc400aa,
-	0x2c0bf404,
-	0xf124d7f0,
-	0xf01a00e7,
-	0xeecf00e3,
-	0x00f7f100,
-	0x00f3f019,
-	0xf400ffcf,
-	0xe7f00421,
-	0x0007f101,
-	0x0003f01d,
-	0xbd000ed0,
-/* 0x056d: ih_no_fifo */
-	0x0007f104,
-	0x0003f001,
-	0xbd000ad0,
-	0xfcf0fc04,
-	0xfcd0fce0,
-	0xfca0fcb0,
-	0xfe80fc90,
-	0x80fc0088,
-	0xf80032f4,
-/* 0x0591: hub_barrier_done */
-	0x01f7f001,
-	0xbb040e98,
-	0xffb904fe,
-	0x18e7f102,
-	0x40e3f094,
-	0xf89d21f4,
-/* 0x05a9: ctx_redswitch */
-	0x20f7f000,
-	0x850007f1,
-	0xd00103f0,
-	0x04bd000f,
-/* 0x05bb: ctx_redswitch_delay */
-	0xb608e7f0,
-	0x1bf401e2,
-	0x00f5f1fd,
-	0x00f5f108,
-	0x0007f102,
+	0x03f00100,
+	0x000ad000,
+	0xf0fc04bd,
+	0xd0fce0fc,
+	0xa0fcb0fc,
+	0x80fc90fc,
+	0xfc0088fe,
+	0x0032f480,
+/* 0x05a2: hub_barrier_done */
+	0xf7f001f8,
+	0x040e9801,
+	0xb904febb,
+	0xe7f102ff,
+	0xe3f09418,
+	0x9d21f440,
+/* 0x05ba: ctx_redswitch */
+	0xf7f000f8,
+	0x0007f120,
 	0x0103f085,
 	0xbd000fd0,
-/* 0x05d7: ctx_xfer */
-	0xf100f804,
-	0xf0810007,
-	0x0fd00203,
-	0xf404bd00,
-	0x21f50711,
-/* 0x05ea: ctx_xfer_not_load */
-	0x21f505a9,
-	0x24bd026a,
-	0x47fc07f1,
+	0x08e7f004,
+/* 0x05cc: ctx_redswitch_delay */
+	0xf401e2b6,
+	0xf5f1fd1b,
+	0xf5f10800,
+	0x07f10200,
+	0x03f08500,
+	0x000fd001,
+	0x00f804bd,
+/* 0x05e8: ctx_xfer */
+	0x810007f1,
 	0xd00203f0,
-	0x04bd0002,
-	0xb6012cf0,
-	0x07f10320,
-	0x03f04afc,
-	0x0002d002,
-	0xacf004bd,
-	0x02a5f001,
-	0x0000b7f1,
-	0x9850b3f0,
-	0xc4b6040c,
-	0x00bcbb0f,
-	0x98000c98,
-	0xe7f0010d,
-	0x6f21f500,
-	0x01acf001,
-	0x4000b7f1,
+	0x04bd000f,
+	0xf50711f4,
+/* 0x05fb: ctx_xfer_not_load */
+	0xf505ba21,
+	0xbd026a21,
+	0xfc07f124,
+	0x0203f047,
+	0xbd0002d0,
+	0x012cf004,
+	0xf10320b6,
+	0xf04afc07,
+	0x02d00203,
+	0xf004bd00,
+	0xa5f001ac,
+	0x00b7f102,
+	0x50b3f000,
+	0xb6040c98,
+	0xbcbb0fc4,
+	0x000c9800,
+	0xf0010d98,
+	0x21f500e7,
+	0xacf0016f,
+	0x00b7f101,
+	0x50b3f040,
+	0xb6040c98,
+	0xbcbb0fc4,
+	0x010c9800,
+	0x98020d98,
+	0xe7f1060f,
+	0x21f50800,
+	0xacf0016f,
+	0x04a5f001,
+	0x3000b7f1,
 	0x9850b3f0,
 	0xc4b6040c,
 	0x00bcbb0f,
-	0x98010c98,
-	0x0f98020d,
-	0x00e7f106,
-	0x6f21f508,
-	0x01acf001,
-	0xf104a5f0,
-	0xf03000b7,
-	0x0c9850b3,
-	0x0fc4b604,
-	0x9800bcbb,
-	0x0d98020c,
-	0x080f9803,
-	0x0200e7f1,
-	0x016f21f5,
-	0x025e21f5,
-	0xf40601f4,
-/* 0x0686: ctx_xfer_post */
-	0x21f50712,
-/* 0x068a: ctx_xfer_done */
-	0x21f5027f,
-	0x00f80591,
-	0x00000000,
-	0x00000000,
-	0x00000000,
-	0x00000000,
+	0x98020c98,
+	0x0f98030d,
+	0x00e7f108,
+	0x6f21f502,
+	0x5e21f501,
+	0x0601f402,
+/* 0x0697: ctx_xfer_post */
+	0xf50712f4,
+/* 0x069b: ctx_xfer_done */
+	0xf5027f21,
+	0xf805a221,
 	0x00000000,
 	0x00000000,
 	0x00000000,

+ 40 - 0
drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5

@@ -0,0 +1,40 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#define CHIPSET GK208
+#include "macros.fuc"
+
+.section #gm107_grhub_data
+#define INCLUDE_DATA
+#include "com.fuc"
+#include "hub.fuc"
+#undef INCLUDE_DATA
+
+.section #gm107_grhub_code
+#define INCLUDE_CODE
+bra #init
+#include "com.fuc"
+#include "hub.fuc"
+.align 256
+#undef INCLUDE_CODE

+ 916 - 0
drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5.h

@@ -0,0 +1,916 @@
+uint32_t gm107_grhub_data[] = {
+/* 0x0000: hub_mmio_list_head */
+	0x00000300,
+/* 0x0004: hub_mmio_list_tail */
+	0x00000304,
+/* 0x0008: gpc_count */
+	0x00000000,
+/* 0x000c: rop_count */
+	0x00000000,
+/* 0x0010: cmd_queue */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+/* 0x0058: ctx_current */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+/* 0x0100: chan_data */
+/* 0x0100: chan_mmio_count */
+	0x00000000,
+/* 0x0104: chan_mmio_address */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+/* 0x0200: xfer_data */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+/* 0x0300: hub_mmio_list_base */
+	0x0417e91c,
+};
+
+uint32_t gm107_grhub_code[] = {
+	0x030e0ef5,
+/* 0x0004: queue_put */
+	0x9800d898,
+	0x86f001d9,
+	0xf489a408,
+	0x020f0b1b,
+	0x0002f87e,
+/* 0x001a: queue_put_next */
+	0x98c400f8,
+	0x0384b607,
+	0xb6008dbb,
+	0x8eb50880,
+	0x018fb500,
+	0xf00190b6,
+	0xd9b50f94,
+/* 0x0037: queue_get */
+	0xf400f801,
+	0xd8980131,
+	0x01d99800,
+	0x0bf489a4,
+	0x0789c421,
+	0xbb0394b6,
+	0x90b6009d,
+	0x009e9808,
+	0xb6019f98,
+	0x84f00180,
+	0x00d8b50f,
+/* 0x0063: queue_get_done */
+	0xf80132f4,
+/* 0x0065: nv_rd32 */
+	0xf0ecb200,
+	0x00801fc9,
+	0x0cf601ca,
+/* 0x0073: nv_rd32_wait */
+	0x8c04bd00,
+	0xcf01ca00,
+	0xccc800cc,
+	0xf61bf41f,
+	0xec7e060a,
+	0x008f0000,
+	0xffcf01cb,
+/* 0x008f: nv_wr32 */
+	0x8000f800,
+	0xf601cc00,
+	0x04bd000f,
+	0xc9f0ecb2,
+	0x1ec9f01f,
+	0x01ca0080,
+	0xbd000cf6,
+/* 0x00a9: nv_wr32_wait */
+	0xca008c04,
+	0x00cccf01,
+	0xf41fccc8,
+	0x00f8f61b,
+/* 0x00b8: wait_donez */
+	0x99f094bd,
+	0x37008000,
+	0x0009f602,
+	0x008004bd,
+	0x0af60206,
+/* 0x00cf: wait_donez_ne */
+	0x8804bd00,
+	0xcf010000,
+	0x8aff0088,
+	0xf61bf488,
+	0x99f094bd,
+	0x17008000,
+	0x0009f602,
+	0x00f804bd,
+/* 0x00ec: wait_doneo */
+	0x99f094bd,
+	0x37008000,
+	0x0009f602,
+	0x008004bd,
+	0x0af60206,
+/* 0x0103: wait_doneo_e */
+	0x8804bd00,
+	0xcf010000,
+	0x8aff0088,
+	0xf60bf488,
+	0x99f094bd,
+	0x17008000,
+	0x0009f602,
+	0x00f804bd,
+/* 0x0120: mmctx_size */
+/* 0x0122: nv_mmctx_size_loop */
+	0xe89894bd,
+	0x1a85b600,
+	0xb60180b6,
+	0x98bb0284,
+	0x04e0b600,
+	0x1bf4efa4,
+	0xf89fb2ec,
+/* 0x013d: mmctx_xfer */
+	0xf094bd00,
+	0x00800199,
+	0x09f60237,
+	0xbd04bd00,
+	0x05bbfd94,
+	0x800f0bf4,
+	0xf601c400,
+	0x04bd000b,
+/* 0x015f: mmctx_base_disabled */
+	0xfd0099f0,
+	0x0bf405ee,
+	0xc6008018,
+	0x000ef601,
+	0x008004bd,
+	0x0ff601c7,
+	0xf004bd00,
+/* 0x017a: mmctx_multi_disabled */
+	0xabc80199,
+	0x10b4b600,
+	0xc80cb9f0,
+	0xe4b601ae,
+	0x05befd11,
+	0x01c50080,
+	0xbd000bf6,
+/* 0x0195: mmctx_exec_loop */
+/* 0x0195: mmctx_wait_free */
+	0xc5008e04,
+	0x00eecf01,
+	0xf41fe4f0,
+	0xce98f60b,
+	0x05e9fd00,
+	0x01c80080,
+	0xbd000ef6,
+	0x04c0b604,
+	0x1bf4cda4,
+	0x02abc8df,
+/* 0x01bf: mmctx_fini_wait */
+	0x8b1c1bf4,
+	0xcf01c500,
+	0xb4f000bb,
+	0x10b4b01f,
+	0x0af31bf4,
+	0x00b87e05,
+	0x250ef400,
+/* 0x01d8: mmctx_stop */
+	0xb600abc8,
+	0xb9f010b4,
+	0x12b9f00c,
+	0x01c50080,
+	0xbd000bf6,
+/* 0x01ed: mmctx_stop_wait */
+	0xc5008b04,
+	0x00bbcf01,
+	0xf412bbc8,
+/* 0x01fa: mmctx_done */
+	0x94bdf61b,
+	0x800199f0,
+	0xf6021700,
+	0x04bd0009,
+/* 0x020a: strand_wait */
+	0xa0f900f8,
+	0xb87e020a,
+	0xa0fc0000,
+/* 0x0216: strand_pre */
+	0x0c0900f8,
+	0x024afc80,
+	0xbd0009f6,
+	0x020a7e04,
+/* 0x0227: strand_post */
+	0x0900f800,
+	0x4afc800d,
+	0x0009f602,
+	0x0a7e04bd,
+	0x00f80002,
+/* 0x0238: strand_set */
+	0xfc800f0c,
+	0x0cf6024f,
+	0x0c04bd00,
+	0x4afc800b,
+	0x000cf602,
+	0xfc8004bd,
+	0x0ef6024f,
+	0x0c04bd00,
+	0x4afc800a,
+	0x000cf602,
+	0x0a7e04bd,
+	0x00f80002,
+/* 0x0268: strand_ctx_init */
+	0x99f094bd,
+	0x37008003,
+	0x0009f602,
+	0x167e04bd,
+	0x030e0002,
+	0x0002387e,
+	0xfc80c4bd,
+	0x0cf60247,
+	0x0c04bd00,
+	0x4afc8001,
+	0x000cf602,
+	0x0a7e04bd,
+	0x0c920002,
+	0x46fc8001,
+	0x000cf602,
+	0x020c04bd,
+	0x024afc80,
+	0xbd000cf6,
+	0x020a7e04,
+	0x02277e00,
+	0x42008800,
+	0x20008902,
+	0x0099cf02,
+/* 0x02c7: ctx_init_strand_loop */
+	0xf608fe95,
+	0x8ef6008e,
+	0x808acf40,
+	0xb606a5b6,
+	0xeabb01a0,
+	0x0480b600,
+	0xf40192b6,
+	0xe4b6e81b,
+	0xf2efbc08,
+	0x99f094bd,
+	0x17008003,
+	0x0009f602,
+	0x00f804bd,
+/* 0x02f8: error */
+	0x02050080,
+	0xbd000ff6,
+	0x80010f04,
+	0xf6030700,
+	0x04bd000f,
+/* 0x030e: init */
+	0x04bd00f8,
+	0x410007fe,
+	0x11cf4200,
+	0x0911e700,
+	0x0814b601,
+	0x020014fe,
+	0x12004002,
+	0xbd0002f6,
+	0x05c94104,
+	0xbd0010fe,
+	0x07004024,
+	0xbd0002f6,
+	0x20034204,
+	0x01010080,
+	0xbd0002f6,
+	0x20044204,
+	0x01010480,
+	0xbd0002f6,
+	0x200b4204,
+	0x01010880,
+	0xbd0002f6,
+	0x200c4204,
+	0x01011c80,
+	0xbd0002f6,
+	0x01039204,
+	0x03090080,
+	0xbd0003f6,
+	0x87044204,
+	0xf6040040,
+	0x04bd0002,
+	0x00400402,
+	0x0002f603,
+	0x31f404bd,
+	0x96048e10,
+	0x00657e40,
+	0xc7feb200,
+	0x01b590f1,
+	0x1ff4f003,
+	0x01020fb5,
+	0x041fbb01,
+	0x800112b6,
+	0xf6010300,
+	0x04bd0001,
+	0x01040080,
+	0xbd0001f6,
+	0x01004104,
+	0x627e020f,
+	0x717e0006,
+	0x100f0006,
+	0x0006b37e,
+	0x98000e98,
+	0x207e010f,
+	0x14950001,
+	0xc0008008,
+	0x0004f601,
+	0x008004bd,
+	0x04f601c1,
+	0xb704bd00,
+	0xbb130030,
+	0xf5b6001f,
+	0xd3008002,
+	0x000ff601,
+	0x15b604bd,
+	0x0110b608,
+	0xb20814b6,
+	0x02687e1f,
+	0x001fbb00,
+	0x84020398,
+/* 0x041f: init_gpc */
+	0xb8502000,
+	0x0008044e,
+	0x8f7e1fb2,
+	0x4eb80000,
+	0xbd00010c,
+	0x008f7ef4,
+	0x044eb800,
+	0x8f7e0001,
+	0x4eb80000,
+	0x0f000100,
+	0x008f7e02,
+	0x004eb800,
+/* 0x044e: init_gpc_wait */
+	0x657e0008,
+	0xffc80000,
+	0xf90bf41f,
+	0x08044eb8,
+	0x00657e00,
+	0x001fbb00,
+	0x800040b7,
+	0xf40132b6,
+	0x000fb41b,
+	0x0006b37e,
+	0x627e000f,
+	0x00800006,
+	0x01f60201,
+	0xbd04bd00,
+	0x1f19f014,
+	0x02300080,
+	0xbd0001f6,
+/* 0x0491: main */
+	0x0031f404,
+	0x0d0028f4,
+	0x00377e10,
+	0xf401f400,
+	0x4001e4b1,
+	0x00c71bf5,
+	0x99f094bd,
+	0x37008004,
+	0x0009f602,
+	0x008104bd,
+	0x11cf02c0,
+	0xc1008200,
+	0x0022cf02,
+	0xf41f13c8,
+	0x23c8770b,
+	0x550bf41f,
+	0x12b220f9,
+	0x99f094bd,
+	0x37008007,
+	0x0009f602,
+	0x32f404bd,
+	0x0231f401,
+	0x0008367e,
+	0x99f094bd,
+	0x17008007,
+	0x0009f602,
+	0x20fc04bd,
+	0x99f094bd,
+	0x37008006,
+	0x0009f602,
+	0x31f404bd,
+	0x08367e01,
+	0xf094bd00,
+	0x00800699,
+	0x09f60217,
+	0xf404bd00,
+/* 0x0522: chsw_prev_no_next */
+	0x20f92f0e,
+	0x32f412b2,
+	0x0232f401,
+	0x0008367e,
+	0x008020fc,
+	0x02f602c0,
+	0xf404bd00,
+/* 0x053e: chsw_no_prev */
+	0x23c8130e,
+	0x0d0bf41f,
+	0xf40131f4,
+	0x367e0232,
+/* 0x054e: chsw_done */
+	0x01020008,
+	0x02c30080,
+	0xbd0002f6,
+	0xf094bd04,
+	0x00800499,
+	0x09f60217,
+	0xf504bd00,
+/* 0x056b: main_not_ctx_switch */
+	0xb0ff2a0e,
+	0x1bf401e4,
+	0x7ef2b20c,
+	0xf40007d6,
+/* 0x057a: main_not_ctx_chan */
+	0xe4b0400e,
+	0x2c1bf402,
+	0x99f094bd,
+	0x37008007,
+	0x0009f602,
+	0x32f404bd,
+	0x0232f401,
+	0x0008367e,
+	0x99f094bd,
+	0x17008007,
+	0x0009f602,
+	0x0ef404bd,
+/* 0x05a9: main_not_ctx_save */
+	0x10ef9411,
+	0x7e01f5f0,
+	0xf50002f8,
+/* 0x05b7: main_done */
+	0xbdfede0e,
+	0x1f29f024,
+	0x02300080,
+	0xbd0002f6,
+	0xcc0ef504,
+/* 0x05c9: ih */
+	0xfe80f9fe,
+	0x80f90188,
+	0xa0f990f9,
+	0xd0f9b0f9,
+	0xf0f9e0f9,
+	0x004a04bd,
+	0x00aacf02,
+	0xf404abc4,
+	0x100d230b,
+	0xcf1a004e,
+	0x004f00ee,
+	0x00ffcf19,
+	0x0000047e,
+	0x0400b0b7,
+	0x0040010e,
+	0x000ef61d,
+/* 0x060a: ih_no_fifo */
+	0xabe404bd,
+	0x0bf40100,
+	0x4e100d0c,
+	0x047e4001,
+/* 0x061a: ih_no_ctxsw */
+	0xabe40000,
+	0x0bf40400,
+	0x01004b10,
+	0x448ebfb2,
+	0x8f7e4001,
+/* 0x062e: ih_no_fwmthd */
+	0x044b0000,
+	0xffb0bd01,
+	0x0bf4b4ab,
+	0x0700800c,
+	0x000bf603,
+/* 0x0642: ih_no_other */
+	0x004004bd,
+	0x000af601,
+	0xf0fc04bd,
+	0xd0fce0fc,
+	0xa0fcb0fc,
+	0x80fc90fc,
+	0xfc0088fe,
+	0x0032f480,
+/* 0x0662: ctx_4170s */
+	0xf5f001f8,
+	0x8effb210,
+	0x7e404170,
+	0xf800008f,
+/* 0x0671: ctx_4170w */
+	0x41708e00,
+	0x00657e40,
+	0xf0ffb200,
+	0x1bf410f4,
+/* 0x0683: ctx_redswitch */
+	0x4e00f8f3,
+	0xe5f00200,
+	0x20e5f040,
+	0x8010e5f0,
+	0xf6018500,
+	0x04bd000e,
+/* 0x069a: ctx_redswitch_delay */
+	0xf2b6080f,
+	0xfd1bf401,
+	0x0400e5f1,
+	0x0100e5f1,
+	0x01850080,
+	0xbd000ef6,
+/* 0x06b3: ctx_86c */
+	0x8000f804,
+	0xf6022300,
+	0x04bd000f,
+	0x148effb2,
+	0x8f7e408a,
+	0xffb20000,
+	0x41a88c8e,
+	0x00008f7e,
+/* 0x06d2: ctx_mem */
+	0x008000f8,
+	0x0ff60284,
+/* 0x06db: ctx_mem_wait */
+	0x8f04bd00,
+	0xcf028400,
+	0xfffd00ff,
+	0xf61bf405,
+/* 0x06ea: ctx_load */
+	0x94bd00f8,
+	0x800599f0,
+	0xf6023700,
+	0x04bd0009,
+	0xb87e0c0a,
+	0xf4bd0000,
+	0x02890080,
+	0xbd000ff6,
+	0xc1008004,
+	0x0002f602,
+	0x008004bd,
+	0x02f60283,
+	0x0f04bd00,
+	0x06d27e07,
+	0xc0008000,
+	0x0002f602,
+	0x0bfe04bd,
+	0x1f2af000,
+	0xb60424b6,
+	0x94bd0220,
+	0x800899f0,
+	0xf6023700,
+	0x04bd0009,
+	0x02810080,
+	0xbd0002f6,
+	0x0000d204,
+	0x25f08000,
+	0x88008002,
+	0x0002f602,
+	0x100104bd,
+	0xf0020042,
+	0x12fa0223,
+	0xbd03f805,
+	0x0899f094,
+	0x02170080,
+	0xbd0009f6,
+	0x81019804,
+	0x981814b6,
+	0x25b68002,
+	0x0512fd08,
+	0xbd1601b5,
+	0x0999f094,
+	0x02370080,
+	0xbd0009f6,
+	0x81008004,
+	0x0001f602,
+	0x010204bd,
+	0x02880080,
+	0xbd0002f6,
+	0x01004104,
+	0xfa0613f0,
+	0x03f80501,
+	0x99f094bd,
+	0x17008009,
+	0x0009f602,
+	0x94bd04bd,
+	0x800599f0,
+	0xf6021700,
+	0x04bd0009,
+/* 0x07d6: ctx_chan */
+	0xea7e00f8,
+	0x0c0a0006,
+	0x0000b87e,
+	0xd27e050f,
+	0x00f80006,
+/* 0x07e8: ctx_mmio_exec */
+	0x80410398,
+	0xf6028100,
+	0x04bd0003,
+/* 0x07f6: ctx_mmio_loop */
+	0x34c434bd,
+	0x0e1bf4ff,
+	0xf0020045,
+	0x35fa0653,
+/* 0x0807: ctx_mmio_pull */
+	0x9803f805,
+	0x4f98804e,
+	0x008f7e81,
+	0x0830b600,
+	0xf40112b6,
+/* 0x081a: ctx_mmio_done */
+	0x0398df1b,
+	0x81008016,
+	0x0003f602,
+	0x00b504bd,
+	0x01004140,
+	0xfa0613f0,
+	0x03f80601,
+/* 0x0836: ctx_xfer */
+	0x040e00f8,
+	0x03020080,
+	0xbd000ef6,
+/* 0x0841: ctx_xfer_idle */
+	0x00008e04,
+	0x00eecf03,
+	0x2000e4f1,
+	0xf4f51bf4,
+	0x02f40611,
+/* 0x0855: ctx_xfer_pre */
+	0x7e100f0c,
+	0xf40006b3,
+/* 0x085e: ctx_xfer_pre_load */
+	0x020f1b11,
+	0x0006627e,
+	0x0006717e,
+	0x0006837e,
+	0x627ef4bd,
+	0xea7e0006,
+/* 0x0876: ctx_xfer_exec */
+	0x01980006,
+	0x8024bd16,
+	0xf6010500,
+	0x04bd0002,
+	0x008e1fb2,
+	0x8f7e41a5,
+	0xfcf00000,
+	0x022cf001,
+	0xfd0124b6,
+	0xffb205f2,
+	0x41a5048e,
+	0x00008f7e,
+	0x0002167e,
+	0xfc8024bd,
+	0x02f60247,
+	0xf004bd00,
+	0x20b6012c,
+	0x4afc8003,
+	0x0002f602,
+	0xacf004bd,
+	0x06a5f001,
+	0x0c98000b,
+	0x010d9800,
+	0x3d7e000e,
+	0x080a0001,
+	0x0000ec7e,
+	0x00020a7e,
+	0x0a1201f4,
+	0x00b87e0c,
+	0x7e050f00,
+	0xf40006d2,
+/* 0x08f2: ctx_xfer_post */
+	0x020f2d02,
+	0x0006627e,
+	0xb37ef4bd,
+	0x277e0006,
+	0x717e0002,
+	0xf4bd0006,
+	0x0006627e,
+	0x981011f4,
+	0x11fd4001,
+	0x070bf405,
+	0x0007e87e,
+/* 0x091c: ctx_xfer_no_post_mmio */
+/* 0x091c: ctx_xfer_done */
+	0x000000f8,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+};

+ 1 - 1
drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnv108.fuc5.h

@@ -342,7 +342,7 @@ uint32_t nv108_grhub_code[] = {
 	0xb4f000bb,
 	0x10b4b01f,
 	0x0af31bf4,
-	0x00b87e02,
+	0x00b87e05,
 	0x250ef400,
 /* 0x01d8: mmctx_stop */
 	0xb600abc8,

+ 1 - 1
drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h

@@ -361,7 +361,7 @@ uint32_t nvc0_grhub_code[] = {
 	0x1fb4f000,
 	0xf410b4b0,
 	0xa7f0f01b,
-	0xd021f402,
+	0xd021f405,
 /* 0x0223: mmctx_stop */
 	0xc82b0ef4,
 	0xb4b600ab,

+ 1 - 1
drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvd7.fuc.h

@@ -361,7 +361,7 @@ uint32_t nvd7_grhub_code[] = {
 	0x1fb4f000,
 	0xf410b4b0,
 	0xa7f0f01b,
-	0xd021f402,
+	0xd021f405,
 /* 0x0223: mmctx_stop */
 	0xc82b0ef4,
 	0xb4b600ab,

+ 1 - 1
drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc.h

@@ -361,7 +361,7 @@ uint32_t nve0_grhub_code[] = {
 	0x1fb4f000,
 	0xf410b4b0,
 	0xa7f0f01b,
-	0xd021f402,
+	0xd021f405,
 /* 0x0223: mmctx_stop */
 	0xc82b0ef4,
 	0xb4b600ab,

+ 1 - 1
drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc.h

@@ -361,7 +361,7 @@ uint32_t nvf0_grhub_code[] = {
 	0x1fb4f000,
 	0xf410b4b0,
 	0xa7f0f01b,
-	0xd021f402,
+	0xd021f405,
 /* 0x0223: mmctx_stop */
 	0xc82b0ef4,
 	0xb4b600ab,

+ 1 - 0
drivers/gpu/drm/nouveau/core/engine/graph/fuc/macros.fuc

@@ -132,6 +132,7 @@
 #define NV_PGRAPH_GPCX_GPCCS_FIFO_CMD                                  0x41a068
 #define NV_PGRAPH_GPCX_GPCCS_FIFO_ACK                                  0x41a074
 #define NV_PGRAPH_GPCX_GPCCS_UNITS                                     0x41a608
+#define NV_PGRAPH_GPCX_GPCCS_CAPS                                      0x41a108
 #define NV_PGRAPH_GPCX_GPCCS_RED_SWITCH                                0x41a614
 #define NV_PGRAPH_GPCX_GPCCS_RED_SWITCH_UNK11                        0x00000800
 #define NV_PGRAPH_GPCX_GPCCS_RED_SWITCH_ENABLE                       0x00000200

+ 465 - 0
drivers/gpu/drm/nouveau/core/engine/graph/gm107.c

@@ -0,0 +1,465 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs <bskeggs@redhat.com>
+ */
+
+#include <subdev/bios.h>
+#include <subdev/bios/P0260.h>
+
+#include "nvc0.h"
+#include "ctxnvc0.h"
+
+/*******************************************************************************
+ * Graphics object classes
+ ******************************************************************************/
+
+static struct nouveau_oclass
+gm107_graph_sclass[] = {
+	{ 0x902d, &nouveau_object_ofuncs },
+	{ 0xa140, &nouveau_object_ofuncs },
+	{ 0xb097, &nouveau_object_ofuncs },
+	{ 0xb0c0, &nouveau_object_ofuncs },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH register lists
+ ******************************************************************************/
+
+static const struct nvc0_graph_init
+gm107_graph_init_main_0[] = {
+	{ 0x400080,   1, 0x04, 0x003003c2 },
+	{ 0x400088,   1, 0x04, 0x0001bfe7 },
+	{ 0x40008c,   1, 0x04, 0x00060000 },
+	{ 0x400090,   1, 0x04, 0x00000030 },
+	{ 0x40013c,   1, 0x04, 0x003901f3 },
+	{ 0x400140,   1, 0x04, 0x00000100 },
+	{ 0x400144,   1, 0x04, 0x00000000 },
+	{ 0x400148,   1, 0x04, 0x00000110 },
+	{ 0x400138,   1, 0x04, 0x00000000 },
+	{ 0x400130,   2, 0x04, 0x00000000 },
+	{ 0x400124,   1, 0x04, 0x00000002 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_ds_0[] = {
+	{ 0x405844,   1, 0x04, 0x00ffffff },
+	{ 0x405850,   1, 0x04, 0x00000000 },
+	{ 0x405900,   1, 0x04, 0x00000000 },
+	{ 0x405908,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_scc_0[] = {
+	{ 0x40803c,   1, 0x04, 0x00000010 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_sked_0[] = {
+	{ 0x407010,   1, 0x04, 0x00000000 },
+	{ 0x407040,   1, 0x04, 0x40440424 },
+	{ 0x407048,   1, 0x04, 0x0000000a },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_prop_0[] = {
+	{ 0x418408,   1, 0x04, 0x00000000 },
+	{ 0x4184a0,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_setup_1[] = {
+	{ 0x4188c8,   2, 0x04, 0x00000000 },
+	{ 0x4188d0,   1, 0x04, 0x00010000 },
+	{ 0x4188d4,   1, 0x04, 0x00010201 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_zcull_0[] = {
+	{ 0x418910,   1, 0x04, 0x00010001 },
+	{ 0x418914,   1, 0x04, 0x00000301 },
+	{ 0x418918,   1, 0x04, 0x00800000 },
+	{ 0x418930,   2, 0x04, 0x00000000 },
+	{ 0x418980,   1, 0x04, 0x77777770 },
+	{ 0x418984,   3, 0x04, 0x77777777 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_gpc_unk_1[] = {
+	{ 0x418d00,   1, 0x04, 0x00000000 },
+	{ 0x418f00,   1, 0x04, 0x00000400 },
+	{ 0x418f08,   1, 0x04, 0x00000000 },
+	{ 0x418e08,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_tpccs_0[] = {
+	{ 0x419dc4,   1, 0x04, 0x00000000 },
+	{ 0x419dc8,   1, 0x04, 0x00000501 },
+	{ 0x419dd0,   1, 0x04, 0x00000000 },
+	{ 0x419dd4,   1, 0x04, 0x00000100 },
+	{ 0x419dd8,   1, 0x04, 0x00000001 },
+	{ 0x419ddc,   1, 0x04, 0x00000002 },
+	{ 0x419de0,   1, 0x04, 0x00000001 },
+	{ 0x419d0c,   1, 0x04, 0x00000000 },
+	{ 0x419d10,   1, 0x04, 0x00000014 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_tex_0[] = {
+	{ 0x419ab0,   1, 0x04, 0x00000000 },
+	{ 0x419ab8,   1, 0x04, 0x000000e7 },
+	{ 0x419abc,   1, 0x04, 0x00000000 },
+	{ 0x419acc,   1, 0x04, 0x000000ff },
+	{ 0x419ac0,   1, 0x04, 0x00000000 },
+	{ 0x419aa8,   2, 0x04, 0x00000000 },
+	{ 0x419ad0,   2, 0x04, 0x00000000 },
+	{ 0x419ae0,   2, 0x04, 0x00000000 },
+	{ 0x419af0,   4, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_pe_0[] = {
+	{ 0x419900,   1, 0x04, 0x000000ff },
+	{ 0x41980c,   1, 0x04, 0x00000010 },
+	{ 0x419844,   1, 0x04, 0x00000000 },
+	{ 0x419838,   1, 0x04, 0x000000ff },
+	{ 0x419850,   1, 0x04, 0x00000004 },
+	{ 0x419854,   2, 0x04, 0x00000000 },
+	{ 0x419894,   3, 0x04, 0x00100401 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_l1c_0[] = {
+	{ 0x419c98,   1, 0x04, 0x00000000 },
+	{ 0x419cc0,   2, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_sm_0[] = {
+	{ 0x419e30,   1, 0x04, 0x000000ff },
+	{ 0x419e00,   1, 0x04, 0x00000000 },
+	{ 0x419ea0,   1, 0x04, 0x00000000 },
+	{ 0x419ee4,   1, 0x04, 0x00000000 },
+	{ 0x419ea4,   1, 0x04, 0x00000100 },
+	{ 0x419ea8,   1, 0x04, 0x01000000 },
+	{ 0x419ee8,   1, 0x04, 0x00000091 },
+	{ 0x419eb4,   1, 0x04, 0x00000000 },
+	{ 0x419ebc,   2, 0x04, 0x00000000 },
+	{ 0x419edc,   1, 0x04, 0x000c1810 },
+	{ 0x419ed8,   1, 0x04, 0x00000000 },
+	{ 0x419ee0,   1, 0x04, 0x00000000 },
+	{ 0x419f74,   1, 0x04, 0x00005155 },
+	{ 0x419f80,   4, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_l1c_1[] = {
+	{ 0x419ccc,   2, 0x04, 0x00000000 },
+	{ 0x419c80,   1, 0x04, 0x3f006022 },
+	{ 0x419c88,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_pes_0[] = {
+	{ 0x41be50,   1, 0x04, 0x000000ff },
+	{ 0x41be04,   1, 0x04, 0x00000000 },
+	{ 0x41be08,   1, 0x04, 0x00000004 },
+	{ 0x41be0c,   1, 0x04, 0x00000008 },
+	{ 0x41be10,   1, 0x04, 0x0e3b8bc7 },
+	{ 0x41be14,   2, 0x04, 0x00000000 },
+	{ 0x41be3c,   5, 0x04, 0x00100401 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_wwdx_0[] = {
+	{ 0x41bfd4,   1, 0x04, 0x00800000 },
+	{ 0x41bfdc,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_cbm_0[] = {
+	{ 0x41becc,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_be_0[] = {
+	{ 0x408890,   1, 0x04, 0x000000ff },
+	{ 0x40880c,   1, 0x04, 0x00000000 },
+	{ 0x408850,   1, 0x04, 0x00000004 },
+	{ 0x408878,   1, 0x04, 0x00c81603 },
+	{ 0x40887c,   1, 0x04, 0x80543432 },
+	{ 0x408880,   1, 0x04, 0x0010581e },
+	{ 0x408884,   1, 0x04, 0x00001205 },
+	{ 0x408974,   1, 0x04, 0x000000ff },
+	{ 0x408910,   9, 0x04, 0x00000000 },
+	{ 0x408950,   1, 0x04, 0x00000000 },
+	{ 0x408954,   1, 0x04, 0x0000ffff },
+	{ 0x408958,   1, 0x04, 0x00000034 },
+	{ 0x40895c,   1, 0x04, 0x8531a003 },
+	{ 0x408960,   1, 0x04, 0x0561985a },
+	{ 0x408964,   1, 0x04, 0x04e15c4f },
+	{ 0x408968,   1, 0x04, 0x02808833 },
+	{ 0x40896c,   1, 0x04, 0x01f02438 },
+	{ 0x408970,   1, 0x04, 0x00012c00 },
+	{ 0x408984,   1, 0x04, 0x00000000 },
+	{ 0x408988,   1, 0x04, 0x08040201 },
+	{ 0x40898c,   1, 0x04, 0x80402010 },
+	{}
+};
+
+static const struct nvc0_graph_init
+gm107_graph_init_sm_1[] = {
+	{ 0x419e5c,   1, 0x04, 0x00000000 },
+	{ 0x419e58,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_pack
+gm107_graph_pack_mmio[] = {
+	{ gm107_graph_init_main_0 },
+	{ nvf0_graph_init_fe_0 },
+	{ nvc0_graph_init_pri_0 },
+	{ nvc0_graph_init_rstr2d_0 },
+	{ nvc0_graph_init_pd_0 },
+	{ gm107_graph_init_ds_0 },
+	{ gm107_graph_init_scc_0 },
+	{ gm107_graph_init_sked_0 },
+	{ nvf0_graph_init_cwd_0 },
+	{ gm107_graph_init_prop_0 },
+	{ nv108_graph_init_gpc_unk_0 },
+	{ nvc0_graph_init_setup_0 },
+	{ nvc0_graph_init_crstr_0 },
+	{ gm107_graph_init_setup_1 },
+	{ gm107_graph_init_zcull_0 },
+	{ nvc0_graph_init_gpm_0 },
+	{ gm107_graph_init_gpc_unk_1 },
+	{ nvc0_graph_init_gcc_0 },
+	{ gm107_graph_init_tpccs_0 },
+	{ gm107_graph_init_tex_0 },
+	{ gm107_graph_init_pe_0 },
+	{ gm107_graph_init_l1c_0 },
+	{ nvc0_graph_init_mpc_0 },
+	{ gm107_graph_init_sm_0 },
+	{ gm107_graph_init_l1c_1 },
+	{ gm107_graph_init_pes_0 },
+	{ gm107_graph_init_wwdx_0 },
+	{ gm107_graph_init_cbm_0 },
+	{ gm107_graph_init_be_0 },
+	{ gm107_graph_init_sm_1 },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+static void
+gm107_graph_init_bios(struct nvc0_graph_priv *priv)
+{
+	static const struct {
+		u32 ctrl;
+		u32 data;
+	} regs[] = {
+		{ 0x419ed8, 0x419ee0 },
+		{ 0x419ad0, 0x419ad4 },
+		{ 0x419ae0, 0x419ae4 },
+		{ 0x419af0, 0x419af4 },
+		{ 0x419af8, 0x419afc },
+	};
+	struct nouveau_bios *bios = nouveau_bios(priv);
+	struct nvbios_P0260E infoE;
+	struct nvbios_P0260X infoX;
+	int E = -1, X;
+	u8 ver, hdr;
+
+	while (nvbios_P0260Ep(bios, ++E, &ver, &hdr, &infoE)) {
+		if (X = -1, E < ARRAY_SIZE(regs)) {
+			nv_wr32(priv, regs[E].ctrl, infoE.data);
+			while (nvbios_P0260Xp(bios, ++X, &ver, &hdr, &infoX))
+				nv_wr32(priv, regs[E].data, infoX.data);
+		}
+	}
+}
+
+int
+gm107_graph_init(struct nouveau_object *object)
+{
+	struct nvc0_graph_oclass *oclass = (void *)object->oclass;
+	struct nvc0_graph_priv *priv = (void *)object;
+	const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, priv->tpc_total);
+	u32 data[TPC_MAX / 8] = {};
+	u8  tpcnr[GPC_MAX];
+	int gpc, tpc, ppc, rop;
+	int ret, i;
+
+	ret = nouveau_graph_init(&priv->base);
+	if (ret)
+		return ret;
+
+	nv_wr32(priv, GPC_BCAST(0x0880), 0x00000000);
+	nv_wr32(priv, GPC_BCAST(0x0890), 0x00000000);
+	nv_wr32(priv, GPC_BCAST(0x0894), 0x00000000);
+	nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8);
+	nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8);
+
+	nvc0_graph_mmio(priv, oclass->mmio);
+
+	gm107_graph_init_bios(priv);
+
+	nv_wr32(priv, GPC_UNIT(0, 0x3018), 0x00000001);
+
+	memset(data, 0x00, sizeof(data));
+	memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
+	for (i = 0, gpc = -1; i < priv->tpc_total; i++) {
+		do {
+			gpc = (gpc + 1) % priv->gpc_nr;
+		} while (!tpcnr[gpc]);
+		tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--;
+
+		data[i / 8] |= tpc << ((i % 8) * 4);
+	}
+
+	nv_wr32(priv, GPC_BCAST(0x0980), data[0]);
+	nv_wr32(priv, GPC_BCAST(0x0984), data[1]);
+	nv_wr32(priv, GPC_BCAST(0x0988), data[2]);
+	nv_wr32(priv, GPC_BCAST(0x098c), data[3]);
+
+	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0914),
+			priv->magic_not_rop_nr << 8 | priv->tpc_nr[gpc]);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0910), 0x00040000 |
+			priv->tpc_total);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918);
+	}
+
+	nv_wr32(priv, GPC_BCAST(0x3fd4), magicgpc918);
+	nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800));
+
+	nv_wr32(priv, 0x400500, 0x00010001);
+
+	nv_wr32(priv, 0x400100, 0xffffffff);
+	nv_wr32(priv, 0x40013c, 0xffffffff);
+	nv_wr32(priv, 0x400124, 0x00000002);
+	nv_wr32(priv, 0x409c24, 0x000e0000);
+
+	nv_wr32(priv, 0x404000, 0xc0000000);
+	nv_wr32(priv, 0x404600, 0xc0000000);
+	nv_wr32(priv, 0x408030, 0xc0000000);
+	nv_wr32(priv, 0x404490, 0xc0000000);
+	nv_wr32(priv, 0x406018, 0xc0000000);
+	nv_wr32(priv, 0x407020, 0x40000000);
+	nv_wr32(priv, 0x405840, 0xc0000000);
+	nv_wr32(priv, 0x405844, 0x00ffffff);
+	nv_mask(priv, 0x419cc0, 0x00000008, 0x00000008);
+
+	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+		for (ppc = 0; ppc < 2 /* priv->ppc_nr[gpc] */; ppc++)
+			nv_wr32(priv, PPC_UNIT(gpc, ppc, 0x038), 0xc0000000);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000);
+		for (tpc = 0; tpc < priv->tpc_nr[gpc]; tpc++) {
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x430), 0xc0000000);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe);
+			nv_wr32(priv, TPC_UNIT(gpc, tpc, 0x64c), 0x00000005);
+		}
+		nv_wr32(priv, GPC_UNIT(gpc, 0x2c90), 0xffffffff);
+		nv_wr32(priv, GPC_UNIT(gpc, 0x2c94), 0xffffffff);
+	}
+
+	for (rop = 0; rop < priv->rop_nr; rop++) {
+		nv_wr32(priv, ROP_UNIT(rop, 0x144), 0x40000000);
+		nv_wr32(priv, ROP_UNIT(rop, 0x070), 0x40000000);
+		nv_wr32(priv, ROP_UNIT(rop, 0x204), 0xffffffff);
+		nv_wr32(priv, ROP_UNIT(rop, 0x208), 0xffffffff);
+	}
+
+	nv_wr32(priv, 0x400108, 0xffffffff);
+	nv_wr32(priv, 0x400138, 0xffffffff);
+	nv_wr32(priv, 0x400118, 0xffffffff);
+	nv_wr32(priv, 0x400130, 0xffffffff);
+	nv_wr32(priv, 0x40011c, 0xffffffff);
+	nv_wr32(priv, 0x400134, 0xffffffff);
+
+	nv_wr32(priv, 0x400054, 0x2c350f63);
+	return nvc0_graph_init_ctxctl(priv);
+}
+
+#include "fuc/hubgm107.fuc5.h"
+
+static struct nvc0_graph_ucode
+gm107_graph_fecs_ucode = {
+	.code.data = gm107_grhub_code,
+	.code.size = sizeof(gm107_grhub_code),
+	.data.data = gm107_grhub_data,
+	.data.size = sizeof(gm107_grhub_data),
+};
+
+#include "fuc/gpcgm107.fuc5.h"
+
+static struct nvc0_graph_ucode
+gm107_graph_gpccs_ucode = {
+	.code.data = gm107_grgpc_code,
+	.code.size = sizeof(gm107_grgpc_code),
+	.data.data = gm107_grgpc_data,
+	.data.size = sizeof(gm107_grgpc_data),
+};
+
+struct nouveau_oclass *
+gm107_graph_oclass = &(struct nvc0_graph_oclass) {
+	.base.handle = NV_ENGINE(GR, 0x07),
+	.base.ofuncs = &(struct nouveau_ofuncs) {
+		.ctor = nvc0_graph_ctor,
+		.dtor = nvc0_graph_dtor,
+		.init = gm107_graph_init,
+		.fini = _nouveau_graph_fini,
+	},
+	.cclass = &gm107_grctx_oclass,
+	.sclass =  gm107_graph_sclass,
+	.mmio = gm107_graph_pack_mmio,
+	.fecs.ucode = 0 ? &gm107_graph_fecs_ucode : NULL,
+	.gpccs.ucode = &gm107_graph_gpccs_ucode,
+}.base;

+ 60 - 73
drivers/gpu/drm/nouveau/core/engine/graph/nv108.c

@@ -23,6 +23,7 @@
  */
 
 #include "nvc0.h"
+#include "ctxnvc0.h"
 
 /*******************************************************************************
  * Graphics object classes
@@ -38,11 +39,11 @@ nv108_graph_sclass[] = {
 };
 
 /*******************************************************************************
- * PGRAPH engine/subdev functions
+ * PGRAPH register lists
  ******************************************************************************/
 
-static struct nvc0_graph_init
-nv108_graph_init_regs[] = {
+static const struct nvc0_graph_init
+nv108_graph_init_main_0[] = {
 	{ 0x400080,   1, 0x04, 0x003083c2 },
 	{ 0x400088,   1, 0x04, 0x0001bfe7 },
 	{ 0x40008c,   1, 0x04, 0x00000000 },
@@ -57,66 +58,46 @@ nv108_graph_init_regs[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nv108_graph_init_unk58xx[] = {
+static const struct nvc0_graph_init
+nv108_graph_init_ds_0[] = {
 	{ 0x405844,   1, 0x04, 0x00ffffff },
 	{ 0x405850,   1, 0x04, 0x00000000 },
 	{ 0x405900,   1, 0x04, 0x00000000 },
 	{ 0x405908,   1, 0x04, 0x00000000 },
-	{ 0x405928,   1, 0x04, 0x00000000 },
-	{ 0x40592c,   1, 0x04, 0x00000000 },
+	{ 0x405928,   2, 0x04, 0x00000000 },
 	{}
 };
 
-static struct nvc0_graph_init
-nv108_graph_init_gpc[] = {
-	{ 0x418408,   1, 0x04, 0x00000000 },
-	{ 0x4184a0,   3, 0x04, 0x00000000 },
+const struct nvc0_graph_init
+nv108_graph_init_gpc_unk_0[] = {
 	{ 0x418604,   1, 0x04, 0x00000000 },
 	{ 0x418680,   1, 0x04, 0x00000000 },
 	{ 0x418714,   1, 0x04, 0x00000000 },
 	{ 0x418384,   2, 0x04, 0x00000000 },
-	{ 0x418814,   3, 0x04, 0x00000000 },
-	{ 0x418b04,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nv108_graph_init_setup_1[] = {
 	{ 0x4188c8,   2, 0x04, 0x00000000 },
 	{ 0x4188d0,   1, 0x04, 0x00010000 },
 	{ 0x4188d4,   1, 0x04, 0x00000201 },
-	{ 0x418910,   1, 0x04, 0x00010001 },
-	{ 0x418914,   1, 0x04, 0x00000301 },
-	{ 0x418918,   1, 0x04, 0x00800000 },
-	{ 0x418980,   1, 0x04, 0x77777770 },
-	{ 0x418984,   3, 0x04, 0x77777777 },
-	{ 0x418c04,   1, 0x04, 0x00000000 },
-	{ 0x418c64,   2, 0x04, 0x00000000 },
-	{ 0x418c88,   1, 0x04, 0x00000000 },
-	{ 0x418cb4,   2, 0x04, 0x00000000 },
-	{ 0x418d00,   1, 0x04, 0x00000000 },
-	{ 0x418d28,   2, 0x04, 0x00000000 },
-	{ 0x418f00,   1, 0x04, 0x00000400 },
-	{ 0x418f08,   1, 0x04, 0x00000000 },
-	{ 0x418f20,   2, 0x04, 0x00000000 },
-	{ 0x418e00,   1, 0x04, 0x00000000 },
-	{ 0x418e08,   1, 0x04, 0x00000000 },
-	{ 0x418e1c,   2, 0x04, 0x00000000 },
-	{ 0x41900c,   1, 0x04, 0x00000000 },
-	{ 0x419018,   1, 0x04, 0x00000000 },
 	{}
 };
 
-static struct nvc0_graph_init
-nv108_graph_init_tpc[] = {
-	{ 0x419d0c,   1, 0x04, 0x00000000 },
-	{ 0x419d10,   1, 0x04, 0x00000014 },
+static const struct nvc0_graph_init
+nv108_graph_init_tex_0[] = {
 	{ 0x419ab0,   1, 0x04, 0x00000000 },
 	{ 0x419ac8,   1, 0x04, 0x00000000 },
 	{ 0x419ab8,   1, 0x04, 0x000000e7 },
 	{ 0x419abc,   2, 0x04, 0x00000000 },
 	{ 0x419ab4,   1, 0x04, 0x00000000 },
 	{ 0x419aa8,   2, 0x04, 0x00000000 },
-	{ 0x41980c,   1, 0x04, 0x00000010 },
-	{ 0x419844,   1, 0x04, 0x00000000 },
-	{ 0x419850,   1, 0x04, 0x00000004 },
-	{ 0x419854,   2, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nv108_graph_init_l1c_0[] = {
 	{ 0x419c98,   1, 0x04, 0x00000000 },
 	{ 0x419ca8,   1, 0x04, 0x00000000 },
 	{ 0x419cb0,   1, 0x04, 0x01000000 },
@@ -127,22 +108,47 @@ nv108_graph_init_tpc[] = {
 	{ 0x419cc0,   2, 0x04, 0x00000000 },
 	{ 0x419c80,   1, 0x04, 0x00000230 },
 	{ 0x419ccc,   2, 0x04, 0x00000000 },
-	{ 0x419c0c,   1, 0x04, 0x00000000 },
-	{ 0x419e00,   1, 0x04, 0x00000080 },
-	{ 0x419ea0,   1, 0x04, 0x00000000 },
-	{ 0x419ee4,   1, 0x04, 0x00000000 },
-	{ 0x419ea4,   1, 0x04, 0x00000100 },
-	{ 0x419ea8,   1, 0x04, 0x00000000 },
-	{ 0x419eb4,   1, 0x04, 0x00000000 },
-	{ 0x419ebc,   2, 0x04, 0x00000000 },
-	{ 0x419edc,   1, 0x04, 0x00000000 },
-	{ 0x419f00,   1, 0x04, 0x00000000 },
-	{ 0x419ed0,   1, 0x04, 0x00003234 },
-	{ 0x419f74,   1, 0x04, 0x00015555 },
-	{ 0x419f80,   4, 0x04, 0x00000000 },
 	{}
 };
 
+static const struct nvc0_graph_pack
+nv108_graph_pack_mmio[] = {
+	{ nv108_graph_init_main_0 },
+	{ nvf0_graph_init_fe_0 },
+	{ nvc0_graph_init_pri_0 },
+	{ nvc0_graph_init_rstr2d_0 },
+	{ nvd9_graph_init_pd_0 },
+	{ nv108_graph_init_ds_0 },
+	{ nvc0_graph_init_scc_0 },
+	{ nvf0_graph_init_sked_0 },
+	{ nvf0_graph_init_cwd_0 },
+	{ nvd9_graph_init_prop_0 },
+	{ nv108_graph_init_gpc_unk_0 },
+	{ nvc0_graph_init_setup_0 },
+	{ nvc0_graph_init_crstr_0 },
+	{ nv108_graph_init_setup_1 },
+	{ nvc0_graph_init_zcull_0 },
+	{ nvd9_graph_init_gpm_0 },
+	{ nvf0_graph_init_gpc_unk_1 },
+	{ nvc0_graph_init_gcc_0 },
+	{ nve4_graph_init_tpccs_0 },
+	{ nv108_graph_init_tex_0 },
+	{ nve4_graph_init_pe_0 },
+	{ nv108_graph_init_l1c_0 },
+	{ nvc0_graph_init_mpc_0 },
+	{ nvf0_graph_init_sm_0 },
+	{ nvd7_graph_init_pes_0 },
+	{ nvd7_graph_init_wwdx_0 },
+	{ nvd7_graph_init_cbm_0 },
+	{ nve4_graph_init_be_0 },
+	{ nvc0_graph_init_fe_1 },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
 static int
 nv108_graph_fini(struct nouveau_object *object, bool suspend)
 {
@@ -180,25 +186,6 @@ nv108_graph_fini(struct nouveau_object *object, bool suspend)
 	return nouveau_graph_fini(&priv->base, suspend);
 }
 
-static struct nvc0_graph_init *
-nv108_graph_init_mmio[] = {
-	nv108_graph_init_regs,
-	nvf0_graph_init_unk40xx,
-	nvc0_graph_init_unk44xx,
-	nvc0_graph_init_unk78xx,
-	nvc0_graph_init_unk60xx,
-	nvd9_graph_init_unk64xx,
-	nv108_graph_init_unk58xx,
-	nvc0_graph_init_unk80xx,
-	nvf0_graph_init_unk70xx,
-	nvf0_graph_init_unk5bxx,
-	nv108_graph_init_gpc,
-	nv108_graph_init_tpc,
-	nve4_graph_init_unk,
-	nve4_graph_init_unk88xx,
-	NULL
-};
-
 #include "fuc/hubnv108.fuc5.h"
 
 static struct nvc0_graph_ucode
@@ -230,7 +217,7 @@ nv108_graph_oclass = &(struct nvc0_graph_oclass) {
 	},
 	.cclass = &nv108_grctx_oclass,
 	.sclass =  nv108_graph_sclass,
-	.mmio = nv108_graph_init_mmio,
+	.mmio = nv108_graph_pack_mmio,
 	.fecs.ucode = &nv108_graph_fecs_ucode,
 	.gpccs.ucode = &nv108_graph_gpccs_ucode,
 }.base;

+ 1 - 1
drivers/gpu/drm/nouveau/core/engine/graph/nv20.c

@@ -349,7 +349,7 @@ nv20_graph_init(struct nouveau_object *object)
 	nv_wr32(priv, NV10_PGRAPH_SURFACE, tmp);
 
 	/* begin RAM config */
-	vramsz = pci_resource_len(nv_device(priv)->pdev, 0) - 1;
+	vramsz = nv_device_resource_len(nv_device(priv), 0) - 1;
 	nv_wr32(priv, 0x4009A4, nv_rd32(priv, 0x100200));
 	nv_wr32(priv, 0x4009A8, nv_rd32(priv, 0x100204));
 	nv_wr32(priv, NV10_PGRAPH_RDI_INDEX, 0x00EA0000);

+ 1 - 1
drivers/gpu/drm/nouveau/core/engine/graph/nv40.c

@@ -484,7 +484,7 @@ nv40_graph_init(struct nouveau_object *object)
 		engine->tile_prog(engine, i);
 
 	/* begin RAM config */
-	vramsz = pci_resource_len(nv_device(priv)->pdev, 0) - 1;
+	vramsz = nv_device_resource_len(nv_device(priv), 0) - 1;
 	switch (nv_device(priv)->chipset) {
 	case 0x40:
 		nv_wr32(priv, 0x4009A4, nv_rd32(priv, 0x100200));

+ 31 - 14
drivers/gpu/drm/nouveau/core/engine/graph/nv50.c

@@ -197,34 +197,35 @@ static const struct nouveau_bitfield nv50_pgraph_status[] = {
 	{ 0x00000080, "UNK7" },
 	{ 0x00000100, "CTXPROG" },
 	{ 0x00000200, "VFETCH" },
-	{ 0x00000400, "CCACHE_UNK4" },
-	{ 0x00000800, "STRMOUT_GSCHED_UNK5" },
-	{ 0x00001000, "UNK14XX" },
-	{ 0x00002000, "UNK24XX_CSCHED" },
-	{ 0x00004000, "UNK1CXX" },
+	{ 0x00000400, "CCACHE_PREGEOM" },
+	{ 0x00000800, "STRMOUT_VATTR_POSTGEOM" },
+	{ 0x00001000, "VCLIP" },
+	{ 0x00002000, "RATTR_APLANE" },
+	{ 0x00004000, "TRAST" },
 	{ 0x00008000, "CLIPID" },
 	{ 0x00010000, "ZCULL" },
 	{ 0x00020000, "ENG2D" },
-	{ 0x00040000, "UNK34XX" },
-	{ 0x00080000, "TPRAST" },
-	{ 0x00100000, "TPROP" },
-	{ 0x00200000, "TEX" },
-	{ 0x00400000, "TPVP" },
-	{ 0x00800000, "MP" },
+	{ 0x00040000, "RMASK" },
+	{ 0x00080000, "TPC_RAST" },
+	{ 0x00100000, "TPC_PROP" },
+	{ 0x00200000, "TPC_TEX" },
+	{ 0x00400000, "TPC_GEOM" },
+	{ 0x00800000, "TPC_MP" },
 	{ 0x01000000, "ROP" },
 	{}
 };
 
 static const char *const nv50_pgraph_vstatus_0[] = {
-	"VFETCH", "CCACHE", "UNK4", "UNK5", "GSCHED", "STRMOUT", "UNK14XX", NULL
+	"VFETCH", "CCACHE", "PREGEOM", "POSTGEOM", "VATTR", "STRMOUT", "VCLIP",
+	NULL
 };
 
 static const char *const nv50_pgraph_vstatus_1[] = {
-	"TPRAST", "TPROP", "TEXTURE", "TPVP", "MP", NULL
+	"TPC_RAST", "TPC_PROP", "TPC_TEX", "TPC_GEOM", "TPC_MP", NULL
 };
 
 static const char *const nv50_pgraph_vstatus_2[] = {
-	"UNK24XX", "CSCHED", "UNK1CXX", "CLIPID", "ZCULL", "ENG2D", "UNK34XX",
+	"RATTR", "APLANE", "TRAST", "CLIPID", "ZCULL", "ENG2D", "RMASK",
 	"ROP", NULL
 };
 
@@ -329,6 +330,15 @@ static const struct nouveau_bitfield nv50_mpc_traps[] = {
 	{}
 };
 
+static const struct nouveau_bitfield nv50_tex_traps[] = {
+	{ 0x00000001, "" }, /* any bit set? */
+	{ 0x00000002, "FAULT" },
+	{ 0x00000004, "STORAGE_TYPE_MISMATCH" },
+	{ 0x00000008, "LINEAR_MISMATCH" },
+	{ 0x00000020, "WRONG_MEMTYPE" },
+	{}
+};
+
 static const struct nouveau_bitfield nv50_graph_trap_m2mf[] = {
 	{ 0x00000001, "NOTIFY" },
 	{ 0x00000002, "IN" },
@@ -531,6 +541,13 @@ nv50_priv_tp_trap(struct nv50_graph_priv *priv, int type, u32 ustatus_old,
 				for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4)
 					nv_error(priv, "\t0x%08x: 0x%08x\n", r,
 						nv_rd32(priv, r));
+				if (ustatus) {
+					nv_error(priv, "%s - TP%d:", name, i);
+					nouveau_bitfield_print(nv50_tex_traps,
+							       ustatus);
+					pr_cont("\n");
+					ustatus = 0;
+				}
 			}
 			break;
 		case 7: /* MP error */

+ 211 - 101
drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c

@@ -23,6 +23,7 @@
  */
 
 #include "nvc0.h"
+#include "ctxnvc0.h"
 
 /*******************************************************************************
  * Graphics object classes
@@ -146,11 +147,11 @@ nvc0_graph_context_dtor(struct nouveau_object *object)
 }
 
 /*******************************************************************************
- * PGRAPH engine/subdev functions
+ * PGRAPH register lists
  ******************************************************************************/
 
-struct nvc0_graph_init
-nvc0_graph_init_regs[] = {
+const struct nvc0_graph_init
+nvc0_graph_init_main_0[] = {
 	{ 0x400080,   1, 0x04, 0x003083c2 },
 	{ 0x400088,   1, 0x04, 0x00006fe7 },
 	{ 0x40008c,   1, 0x04, 0x00000000 },
@@ -165,95 +166,170 @@ nvc0_graph_init_regs[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_graph_init_unk40xx[] = {
+const struct nvc0_graph_init
+nvc0_graph_init_fe_0[] = {
 	{ 0x40415c,   1, 0x04, 0x00000000 },
 	{ 0x404170,   1, 0x04, 0x00000000 },
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_graph_init_unk44xx[] = {
+const struct nvc0_graph_init
+nvc0_graph_init_pri_0[] = {
 	{ 0x404488,   2, 0x04, 0x00000000 },
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_graph_init_unk78xx[] = {
+const struct nvc0_graph_init
+nvc0_graph_init_rstr2d_0[] = {
 	{ 0x407808,   1, 0x04, 0x00000000 },
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_graph_init_unk60xx[] = {
+const struct nvc0_graph_init
+nvc0_graph_init_pd_0[] = {
 	{ 0x406024,   1, 0x04, 0x00000000 },
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_graph_init_unk58xx[] = {
+const struct nvc0_graph_init
+nvc0_graph_init_ds_0[] = {
 	{ 0x405844,   1, 0x04, 0x00ffffff },
 	{ 0x405850,   1, 0x04, 0x00000000 },
 	{ 0x405908,   1, 0x04, 0x00000000 },
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_graph_init_unk80xx[] = {
+const struct nvc0_graph_init
+nvc0_graph_init_scc_0[] = {
 	{ 0x40803c,   1, 0x04, 0x00000000 },
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_graph_init_gpc[] = {
+const struct nvc0_graph_init
+nvc0_graph_init_prop_0[] = {
 	{ 0x4184a0,   1, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_graph_init_gpc_unk_0[] = {
 	{ 0x418604,   1, 0x04, 0x00000000 },
 	{ 0x418680,   1, 0x04, 0x00000000 },
 	{ 0x418714,   1, 0x04, 0x80000000 },
 	{ 0x418384,   1, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_graph_init_setup_0[] = {
 	{ 0x418814,   3, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_graph_init_crstr_0[] = {
 	{ 0x418b04,   1, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_graph_init_setup_1[] = {
 	{ 0x4188c8,   1, 0x04, 0x80000000 },
 	{ 0x4188cc,   1, 0x04, 0x00000000 },
 	{ 0x4188d0,   1, 0x04, 0x00010000 },
 	{ 0x4188d4,   1, 0x04, 0x00000001 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_graph_init_zcull_0[] = {
 	{ 0x418910,   1, 0x04, 0x00010001 },
 	{ 0x418914,   1, 0x04, 0x00000301 },
 	{ 0x418918,   1, 0x04, 0x00800000 },
 	{ 0x418980,   1, 0x04, 0x77777770 },
 	{ 0x418984,   3, 0x04, 0x77777777 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_graph_init_gpm_0[] = {
 	{ 0x418c04,   1, 0x04, 0x00000000 },
 	{ 0x418c88,   1, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_graph_init_gpc_unk_1[] = {
 	{ 0x418d00,   1, 0x04, 0x00000000 },
 	{ 0x418f08,   1, 0x04, 0x00000000 },
 	{ 0x418e00,   1, 0x04, 0x00000050 },
 	{ 0x418e08,   1, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_graph_init_gcc_0[] = {
 	{ 0x41900c,   1, 0x04, 0x00000000 },
 	{ 0x419018,   1, 0x04, 0x00000000 },
 	{}
 };
 
-static struct nvc0_graph_init
-nvc0_graph_init_tpc[] = {
+const struct nvc0_graph_init
+nvc0_graph_init_tpccs_0[] = {
 	{ 0x419d08,   2, 0x04, 0x00000000 },
 	{ 0x419d10,   1, 0x04, 0x00000014 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_graph_init_tex_0[] = {
 	{ 0x419ab0,   1, 0x04, 0x00000000 },
 	{ 0x419ab8,   1, 0x04, 0x000000e7 },
 	{ 0x419abc,   2, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_graph_init_pe_0[] = {
 	{ 0x41980c,   3, 0x04, 0x00000000 },
 	{ 0x419844,   1, 0x04, 0x00000000 },
 	{ 0x41984c,   1, 0x04, 0x00005bc5 },
 	{ 0x419850,   4, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_graph_init_l1c_0[] = {
 	{ 0x419c98,   1, 0x04, 0x00000000 },
 	{ 0x419ca8,   1, 0x04, 0x80000000 },
 	{ 0x419cb4,   1, 0x04, 0x00000000 },
 	{ 0x419cb8,   1, 0x04, 0x00008bf4 },
 	{ 0x419cbc,   1, 0x04, 0x28137606 },
 	{ 0x419cc0,   2, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_graph_init_wwdx_0[] = {
 	{ 0x419bd4,   1, 0x04, 0x00800000 },
 	{ 0x419bdc,   1, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_graph_init_tpccs_1[] = {
 	{ 0x419d2c,   1, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc0_graph_init_mpc_0[] = {
 	{ 0x419c0c,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvc0_graph_init_sm_0[] = {
 	{ 0x419e00,   1, 0x04, 0x00000000 },
 	{ 0x419ea0,   1, 0x04, 0x00000000 },
 	{ 0x419ea4,   1, 0x04, 0x00000100 },
@@ -270,8 +346,8 @@ nvc0_graph_init_tpc[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_graph_init_unk88xx[] = {
+const struct nvc0_graph_init
+nvc0_graph_init_be_0[] = {
 	{ 0x40880c,   1, 0x04, 0x00000000 },
 	{ 0x408910,   9, 0x04, 0x00000000 },
 	{ 0x408950,   1, 0x04, 0x00000000 },
@@ -282,18 +358,64 @@ nvc0_graph_init_unk88xx[] = {
 	{}
 };
 
-struct nvc0_graph_init
-nvc0_graph_tpc_0[] = {
-	{ 0x50405c,   1, 0x04, 0x00000001 },
+const struct nvc0_graph_init
+nvc0_graph_init_fe_1[] = {
+	{ 0x4040f0,   1, 0x04, 0x00000000 },
 	{}
 };
 
+const struct nvc0_graph_init
+nvc0_graph_init_pe_1[] = {
+	{ 0x419880,   1, 0x04, 0x00000002 },
+	{}
+};
+
+static const struct nvc0_graph_pack
+nvc0_graph_pack_mmio[] = {
+	{ nvc0_graph_init_main_0 },
+	{ nvc0_graph_init_fe_0 },
+	{ nvc0_graph_init_pri_0 },
+	{ nvc0_graph_init_rstr2d_0 },
+	{ nvc0_graph_init_pd_0 },
+	{ nvc0_graph_init_ds_0 },
+	{ nvc0_graph_init_scc_0 },
+	{ nvc0_graph_init_prop_0 },
+	{ nvc0_graph_init_gpc_unk_0 },
+	{ nvc0_graph_init_setup_0 },
+	{ nvc0_graph_init_crstr_0 },
+	{ nvc0_graph_init_setup_1 },
+	{ nvc0_graph_init_zcull_0 },
+	{ nvc0_graph_init_gpm_0 },
+	{ nvc0_graph_init_gpc_unk_1 },
+	{ nvc0_graph_init_gcc_0 },
+	{ nvc0_graph_init_tpccs_0 },
+	{ nvc0_graph_init_tex_0 },
+	{ nvc0_graph_init_pe_0 },
+	{ nvc0_graph_init_l1c_0 },
+	{ nvc0_graph_init_wwdx_0 },
+	{ nvc0_graph_init_tpccs_1 },
+	{ nvc0_graph_init_mpc_0 },
+	{ nvc0_graph_init_sm_0 },
+	{ nvc0_graph_init_be_0 },
+	{ nvc0_graph_init_fe_1 },
+	{ nvc0_graph_init_pe_1 },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
 void
-nvc0_graph_mmio(struct nvc0_graph_priv *priv, struct nvc0_graph_init *init)
+nvc0_graph_mmio(struct nvc0_graph_priv *priv, const struct nvc0_graph_pack *p)
 {
-	for (; init && init->count; init++) {
-		u32 addr = init->addr, i;
-		for (i = 0; i < init->count; i++) {
+	const struct nvc0_graph_pack *pack;
+	const struct nvc0_graph_init *init;
+
+	pack_for_each_init(init, pack, p) {
+		u32 next = init->addr + init->count * init->pitch;
+		u32 addr = init->addr;
+		while (addr < next) {
 			nv_wr32(priv, addr, init->data);
 			addr += init->pitch;
 		}
@@ -301,49 +423,53 @@ nvc0_graph_mmio(struct nvc0_graph_priv *priv, struct nvc0_graph_init *init)
 }
 
 void
-nvc0_graph_icmd(struct nvc0_graph_priv *priv, struct nvc0_graph_init *init)
+nvc0_graph_icmd(struct nvc0_graph_priv *priv, const struct nvc0_graph_pack *p)
 {
-	u32 addr, data;
-	int i, j;
+	const struct nvc0_graph_pack *pack;
+	const struct nvc0_graph_init *init;
+	u32 data = 0;
 
 	nv_wr32(priv, 0x400208, 0x80000000);
-	for (i = 0; init->count; init++, i++) {
-		if (!i || data != init->data) {
+
+	pack_for_each_init(init, pack, p) {
+		u32 next = init->addr + init->count * init->pitch;
+		u32 addr = init->addr;
+
+		if ((pack == p && init == p->init) || data != init->data) {
 			nv_wr32(priv, 0x400204, init->data);
 			data = init->data;
 		}
 
-		addr = init->addr;
-		for (j = 0; j < init->count; j++) {
+		while (addr < next) {
 			nv_wr32(priv, 0x400200, addr);
+			nv_wait(priv, 0x400700, 0x00000002, 0x00000000);
 			addr += init->pitch;
-			while (nv_rd32(priv, 0x400700) & 0x00000002) {}
 		}
 	}
+
 	nv_wr32(priv, 0x400208, 0x00000000);
 }
 
 void
-nvc0_graph_mthd(struct nvc0_graph_priv *priv, struct nvc0_graph_mthd *mthds)
+nvc0_graph_mthd(struct nvc0_graph_priv *priv, const struct nvc0_graph_pack *p)
 {
-	struct nvc0_graph_mthd *mthd;
-	struct nvc0_graph_init *init;
-	int i = 0, j;
-	u32 data;
-
-	while ((mthd = &mthds[i++]) && (init = mthd->init)) {
-		u32  addr = 0x80000000 | mthd->oclass;
-		for (data = 0; init->count; init++) {
-			if (init == mthd->init || data != init->data) {
-				nv_wr32(priv, 0x40448c, init->data);
-				data = init->data;
-			}
+	const struct nvc0_graph_pack *pack;
+	const struct nvc0_graph_init *init;
+	u32 data = 0;
 
-			addr = (addr & 0x8000ffff) | (init->addr << 14);
-			for (j = 0; j < init->count; j++) {
-				nv_wr32(priv, 0x404488, addr);
-				addr += init->pitch << 14;
-			}
+	pack_for_each_init(init, pack, p) {
+		u32 ctrl = 0x80000000 | pack->type;
+		u32 next = init->addr + init->count * init->pitch;
+		u32 addr = init->addr;
+
+		if ((pack == p && init == p->init) || data != init->data) {
+			nv_wr32(priv, 0x40448c, init->data);
+			data = init->data;
+		}
+
+		while (addr < next) {
+			nv_wr32(priv, 0x404488, ctrl | (addr << 14));
+			addr += init->pitch;
 		}
 	}
 }
@@ -772,11 +898,12 @@ nvc0_graph_init_fw(struct nvc0_graph_priv *priv, u32 fuc_base,
 
 static void
 nvc0_graph_init_csdata(struct nvc0_graph_priv *priv,
-		       struct nvc0_graph_init *init,
+		       const struct nvc0_graph_pack *pack,
 		       u32 falcon, u32 starstar, u32 base)
 {
-	u32 addr = init->addr;
-	u32 next = addr;
+	const struct nvc0_graph_pack *iter;
+	const struct nvc0_graph_init *init;
+	u32 addr = ~0, prev = ~0, xfer = 0;
 	u32 star, temp;
 
 	nv_wr32(priv, falcon + 0x01c0, 0x02000000 + starstar);
@@ -786,22 +913,28 @@ nvc0_graph_init_csdata(struct nvc0_graph_priv *priv,
 		star = temp;
 	nv_wr32(priv, falcon + 0x01c0, 0x01000000 + star);
 
-	do {
-		if (init->addr != next) {
-			while (addr < next) {
-				u32 nr = min((int)(next - addr) / 4, 32);
-				nv_wr32(priv, falcon + 0x01c4,
-					((nr - 1) << 26) | (addr - base));
-				addr += nr * 4;
-				star += 4;
+	pack_for_each_init(init, iter, pack) {
+		u32 head = init->addr - base;
+		u32 tail = head + init->count * init->pitch;
+		while (head < tail) {
+			if (head != prev + 4 || xfer >= 32) {
+				if (xfer) {
+					u32 data = ((--xfer << 26) | addr);
+					nv_wr32(priv, falcon + 0x01c4, data);
+					star += 4;
+				}
+				addr = head;
+				xfer = 0;
 			}
-			addr = next = init->addr;
+			prev = head;
+			xfer = xfer + 1;
+			head = head + init->pitch;
 		}
-		next += init->count * 4;
-	} while ((init++)->count);
+	}
 
+	nv_wr32(priv, falcon + 0x01c4, (--xfer << 26) | addr);
 	nv_wr32(priv, falcon + 0x01c0, 0x01000004 + starstar);
-	nv_wr32(priv, falcon + 0x01c4, star);
+	nv_wr32(priv, falcon + 0x01c4, star + 4);
 }
 
 int
@@ -809,7 +942,6 @@ nvc0_graph_init_ctxctl(struct nvc0_graph_priv *priv)
 {
 	struct nvc0_graph_oclass *oclass = (void *)nv_object(priv)->oclass;
 	struct nvc0_grctx_oclass *cclass = (void *)nv_engine(priv)->cclass;
-	struct nvc0_graph_init *init;
 	u32 r000260;
 	int i;
 
@@ -919,10 +1051,6 @@ nvc0_graph_init_ctxctl(struct nvc0_graph_priv *priv)
 		nv_wr32(priv, 0x409184, oclass->fecs.ucode->code.data[i]);
 	}
 
-	for (i = 0; (init = cclass->hub[i]); i++) {
-		nvc0_graph_init_csdata(priv, init, 0x409000, 0x000, 0x000000);
-	}
-
 	/* load GPC microcode */
 	nv_wr32(priv, 0x41a1c0, 0x01000000);
 	for (i = 0; i < oclass->gpccs.ucode->data.size / 4; i++)
@@ -936,12 +1064,11 @@ nvc0_graph_init_ctxctl(struct nvc0_graph_priv *priv)
 	}
 	nv_wr32(priv, 0x000260, r000260);
 
-	if ((init = cclass->gpc[0]))
-		nvc0_graph_init_csdata(priv, init, 0x41a000, 0x000, 0x418000);
-	if ((init = cclass->gpc[2]))
-		nvc0_graph_init_csdata(priv, init, 0x41a000, 0x004, 0x419800);
-	if ((init = cclass->gpc[3]))
-		nvc0_graph_init_csdata(priv, init, 0x41a000, 0x008, 0x41be00);
+	/* load register lists */
+	nvc0_graph_init_csdata(priv, cclass->hub, 0x409000, 0x000, 0x000000);
+	nvc0_graph_init_csdata(priv, cclass->gpc, 0x41a000, 0x000, 0x418000);
+	nvc0_graph_init_csdata(priv, cclass->tpc, 0x41a000, 0x004, 0x419800);
+	nvc0_graph_init_csdata(priv, cclass->ppc, 0x41a000, 0x008, 0x41be00);
 
 	/* start HUB ucode running, it'll init the GPCs */
 	nv_wr32(priv, 0x40910c, 0x00000000);
@@ -988,8 +1115,7 @@ nvc0_graph_init(struct nouveau_object *object)
 	nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8);
 	nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8);
 
-	for (i = 0; oclass->mmio[i]; i++)
-		nvc0_graph_mmio(priv, oclass->mmio[i]);
+	nvc0_graph_mmio(priv, oclass->mmio);
 
 	memcpy(tpcnr, priv->tpc_nr, sizeof(priv->tpc_nr));
 	for (i = 0, gpc = -1; i < priv->tpc_total; i++) {
@@ -1091,10 +1217,10 @@ nvc0_graph_ctor_fw(struct nvc0_graph_priv *priv, const char *fwname,
 	int ret;
 
 	snprintf(f, sizeof(f), "nouveau/nv%02x_%s", device->chipset, fwname);
-	ret = request_firmware(&fw, f, &device->pdev->dev);
+	ret = request_firmware(&fw, f, nv_device_base(device));
 	if (ret) {
 		snprintf(f, sizeof(f), "nouveau/%s", fwname);
-		ret = request_firmware(&fw, f, &device->pdev->dev);
+		ret = request_firmware(&fw, f, nv_device_base(device));
 		if (ret) {
 			nv_error(priv, "failed to load %s\n", fwname);
 			return ret;
@@ -1220,22 +1346,6 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	return 0;
 }
 
-struct nvc0_graph_init *
-nvc0_graph_init_mmio[] = {
-	nvc0_graph_init_regs,
-	nvc0_graph_init_unk40xx,
-	nvc0_graph_init_unk44xx,
-	nvc0_graph_init_unk78xx,
-	nvc0_graph_init_unk60xx,
-	nvc0_graph_init_unk58xx,
-	nvc0_graph_init_unk80xx,
-	nvc0_graph_init_gpc,
-	nvc0_graph_init_tpc,
-	nvc0_graph_init_unk88xx,
-	nvc0_graph_tpc_0,
-	NULL
-};
-
 #include "fuc/hubnvc0.fuc.h"
 
 struct nvc0_graph_ucode
@@ -1267,7 +1377,7 @@ nvc0_graph_oclass = &(struct nvc0_graph_oclass) {
 	},
 	.cclass = &nvc0_grctx_oclass,
 	.sclass =  nvc0_graph_sclass,
-	.mmio = nvc0_graph_init_mmio,
+	.mmio = nvc0_graph_pack_mmio,
 	.fecs.ucode = &nvc0_graph_fecs_ucode,
 	.gpccs.ucode = &nvc0_graph_gpccs_ucode,
 }.base;

+ 73 - 141
drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h

@@ -45,6 +45,7 @@
 #define ROP_UNIT(u, r)    (0x410000 + (u) * 0x400 + (r))
 #define GPC_BCAST(r)      (0x418000 + (r))
 #define GPC_UNIT(t, r)    (0x500000 + (t) * 0x8000 + (r))
+#define PPC_UNIT(t, m, r) (0x503000 + (t) * 0x8000 + (m) * 0x200 + (r))
 #define TPC_UNIT(t, m, r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r))
 
 struct nvc0_graph_data {
@@ -102,8 +103,6 @@ struct nvc0_graph_chan {
 	} data[4];
 };
 
-int  nvc0_grctx_generate(struct nvc0_graph_priv *);
-
 int  nvc0_graph_context_ctor(struct nouveau_object *, struct nouveau_object *,
 			     struct nouveau_oclass *, void *, u32,
 			     struct nouveau_object **);
@@ -130,34 +129,14 @@ struct nvc0_graph_init {
 	u32 data;
 };
 
-struct nvc0_graph_mthd {
-	u16 oclass;
-	struct nvc0_graph_init *init;
-};
-
-struct nvc0_grctx {
-	struct nvc0_graph_priv *priv;
-	struct nvc0_graph_data *data;
-	struct nvc0_graph_mmio *mmio;
-	int buffer_nr;
-	u64 buffer[4];
-	u64 addr;
+struct nvc0_graph_pack {
+	const struct nvc0_graph_init *init;
+	u32 type;
 };
 
-struct nvc0_grctx_oclass {
-	struct nouveau_oclass base;
-	/* main context generation function */
-	void  (*main)(struct nvc0_graph_priv *, struct nvc0_grctx *);
-	/* context-specific modify-on-first-load list generation function */
-	void  (*mods)(struct nvc0_graph_priv *, struct nvc0_grctx *);
-	void  (*unkn)(struct nvc0_graph_priv *);
-	/* mmio context data */
-	struct nvc0_graph_init **hub;
-	struct nvc0_graph_init **gpc;
-	/* indirect context data, generated with icmds/mthds */
-	struct nvc0_graph_init *icmd;
-	struct nvc0_graph_mthd *mthd;
-};
+#define pack_for_each_init(init, pack, head)                                   \
+	for (pack = head; pack && pack->init; pack++)                          \
+		  for (init = pack->init; init && init->count; init++)
 
 struct nvc0_graph_ucode {
 	struct nvc0_graph_fuc code;
@@ -171,7 +150,7 @@ struct nvc0_graph_oclass {
 	struct nouveau_oclass base;
 	struct nouveau_oclass **cclass;
 	struct nouveau_oclass *sclass;
-	struct nvc0_graph_init **mmio;
+	const struct nvc0_graph_pack *mmio;
 	struct {
 		struct nvc0_graph_ucode *ucode;
 	} fecs;
@@ -180,119 +159,72 @@ struct nvc0_graph_oclass {
 	} gpccs;
 };
 
-void nvc0_graph_mmio(struct nvc0_graph_priv *, struct nvc0_graph_init *);
-void nvc0_graph_icmd(struct nvc0_graph_priv *, struct nvc0_graph_init *);
-void nvc0_graph_mthd(struct nvc0_graph_priv *, struct nvc0_graph_mthd *);
+void nvc0_graph_mmio(struct nvc0_graph_priv *, const struct nvc0_graph_pack *);
+void nvc0_graph_icmd(struct nvc0_graph_priv *, const struct nvc0_graph_pack *);
+void nvc0_graph_mthd(struct nvc0_graph_priv *, const struct nvc0_graph_pack *);
 int  nvc0_graph_init_ctxctl(struct nvc0_graph_priv *);
 
-extern struct nvc0_graph_init nvc0_graph_init_regs[];
-extern struct nvc0_graph_init nvc0_graph_init_unk40xx[];
-extern struct nvc0_graph_init nvc0_graph_init_unk44xx[];
-extern struct nvc0_graph_init nvc0_graph_init_unk78xx[];
-extern struct nvc0_graph_init nvc0_graph_init_unk60xx[];
-extern struct nvc0_graph_init nvc0_graph_init_unk58xx[];
-extern struct nvc0_graph_init nvc0_graph_init_unk80xx[];
-extern struct nvc0_graph_init nvc0_graph_init_gpc[];
-extern struct nvc0_graph_init nvc0_graph_init_unk88xx[];
-extern struct nvc0_graph_init nvc0_graph_tpc_0[];
-
-extern struct nvc0_graph_init nvc3_graph_init_unk58xx[];
-
-extern struct nvc0_graph_init nvd9_graph_init_unk58xx[];
-extern struct nvc0_graph_init nvd9_graph_init_unk64xx[];
-
-extern struct nvc0_graph_init nve4_graph_init_regs[];
-extern struct nvc0_graph_init nve4_graph_init_unk[];
-extern struct nvc0_graph_init nve4_graph_init_unk88xx[];
-
-extern struct nvc0_graph_init nvf0_graph_init_unk40xx[];
-extern struct nvc0_graph_init nvf0_graph_init_unk70xx[];
-extern struct nvc0_graph_init nvf0_graph_init_unk5bxx[];
-extern struct nvc0_graph_init nvf0_graph_init_tpc[];
-
-int  nvc0_grctx_generate(struct nvc0_graph_priv *);
-void nvc0_grctx_generate_main(struct nvc0_graph_priv *, struct nvc0_grctx *);
-void nvc0_grctx_generate_mods(struct nvc0_graph_priv *, struct nvc0_grctx *);
-void nvc0_grctx_generate_unkn(struct nvc0_graph_priv *);
-void nvc0_grctx_generate_tpcid(struct nvc0_graph_priv *);
-void nvc0_grctx_generate_r406028(struct nvc0_graph_priv *);
-void nvc0_grctx_generate_r4060a8(struct nvc0_graph_priv *);
-void nvc0_grctx_generate_r418bb8(struct nvc0_graph_priv *);
-void nve4_grctx_generate_r418bb8(struct nvc0_graph_priv *);
-void nvc0_grctx_generate_r406800(struct nvc0_graph_priv *);
-
-extern struct nouveau_oclass *nvc0_grctx_oclass;
-extern struct nvc0_graph_init *nvc0_grctx_init_hub[];
-extern struct nvc0_graph_init nvc0_grctx_init_base[];
-extern struct nvc0_graph_init nvc0_grctx_init_unk40xx[];
-extern struct nvc0_graph_init nvc0_grctx_init_unk44xx[];
-extern struct nvc0_graph_init nvc0_grctx_init_unk46xx[];
-extern struct nvc0_graph_init nvc0_grctx_init_unk47xx[];
-extern struct nvc0_graph_init nvc0_grctx_init_unk60xx[];
-extern struct nvc0_graph_init nvc0_grctx_init_unk64xx[];
-extern struct nvc0_graph_init nvc0_grctx_init_unk78xx[];
-extern struct nvc0_graph_init nvc0_grctx_init_unk80xx[];
-extern struct nvc0_graph_init nvc0_grctx_init_gpc_0[];
-extern struct nvc0_graph_init nvc0_grctx_init_gpc_1[];
-extern struct nvc0_graph_init nvc0_grctx_init_tpc[];
-extern struct nvc0_graph_init nvc0_grctx_init_icmd[];
-extern struct nvc0_graph_init nvd9_grctx_init_icmd[]; //
-
-extern struct nvc0_graph_mthd nvc0_grctx_init_mthd[];
-extern struct nvc0_graph_init nvc0_grctx_init_902d[];
-extern struct nvc0_graph_init nvc0_grctx_init_9039[];
-extern struct nvc0_graph_init nvc0_grctx_init_90c0[];
-extern struct nvc0_graph_init nvc0_grctx_init_mthd_magic[];
-
-void nvc1_grctx_generate_mods(struct nvc0_graph_priv *, struct nvc0_grctx *);
-void nvc1_grctx_generate_unkn(struct nvc0_graph_priv *);
-extern struct nouveau_oclass *nvc1_grctx_oclass;
-extern struct nvc0_graph_init nvc1_grctx_init_9097[];
-
-extern struct nouveau_oclass *nvc3_grctx_oclass;
-
-extern struct nouveau_oclass *nvc8_grctx_oclass;
-extern struct nvc0_graph_init nvc8_grctx_init_9197[];
-extern struct nvc0_graph_init nvc8_grctx_init_9297[];
-
-extern struct nouveau_oclass *nvd7_grctx_oclass;
-
-extern struct nouveau_oclass *nvd9_grctx_oclass;
-extern struct nvc0_graph_init nvd9_grctx_init_rop[];
-extern struct nvc0_graph_mthd nvd9_grctx_init_mthd[];
-
-void nve4_grctx_generate_main(struct nvc0_graph_priv *, struct nvc0_grctx *);
-void nve4_grctx_generate_unkn(struct nvc0_graph_priv *);
-extern struct nouveau_oclass *nve4_grctx_oclass;
-extern struct nvc0_graph_init nve4_grctx_init_unk46xx[];
-extern struct nvc0_graph_init nve4_grctx_init_unk47xx[];
-extern struct nvc0_graph_init nve4_grctx_init_unk58xx[];
-extern struct nvc0_graph_init nve4_grctx_init_unk80xx[];
-extern struct nvc0_graph_init nve4_grctx_init_unk90xx[];
-
-extern struct nouveau_oclass *nvf0_grctx_oclass;
-extern struct nvc0_graph_init nvf0_grctx_init_unk44xx[];
-extern struct nvc0_graph_init nvf0_grctx_init_unk5bxx[];
-extern struct nvc0_graph_init nvf0_grctx_init_unk60xx[];
-
-extern struct nouveau_oclass *nv108_grctx_oclass;
-
-#define mmio_data(s,a,p) do {                                                  \
-	info->buffer[info->buffer_nr] = round_up(info->addr, (a));             \
-	info->addr = info->buffer[info->buffer_nr++] + (s);                    \
-	info->data->size = (s);                                                \
-	info->data->align = (a);                                               \
-	info->data->access = (p);                                              \
-	info->data++;                                                          \
-} while(0)
-
-#define mmio_list(r,d,s,b) do {                                                \
-	info->mmio->addr = (r);                                                \
-	info->mmio->data = (d);                                                \
-	info->mmio->shift = (s);                                               \
-	info->mmio->buffer = (b);                                              \
-	info->mmio++;                                                          \
-	nv_wr32(priv, (r), (d) | ((s) ? (info->buffer[(b)] >> (s)) : 0));      \
-} while(0)
+/* register init value lists */
+
+extern const struct nvc0_graph_init nvc0_graph_init_main_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_fe_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_pri_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_rstr2d_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_pd_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_ds_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_scc_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_prop_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_gpc_unk_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_setup_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_crstr_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_setup_1[];
+extern const struct nvc0_graph_init nvc0_graph_init_zcull_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_gpm_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_gpc_unk_1[];
+extern const struct nvc0_graph_init nvc0_graph_init_gcc_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_tpccs_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_tex_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_pe_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_l1c_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_wwdx_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_tpccs_1[];
+extern const struct nvc0_graph_init nvc0_graph_init_mpc_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_be_0[];
+extern const struct nvc0_graph_init nvc0_graph_init_fe_1[];
+extern const struct nvc0_graph_init nvc0_graph_init_pe_1[];
+
+extern const struct nvc0_graph_init nvc4_graph_init_ds_0[];
+extern const struct nvc0_graph_init nvc4_graph_init_tex_0[];
+extern const struct nvc0_graph_init nvc4_graph_init_sm_0[];
+
+extern const struct nvc0_graph_init nvc1_graph_init_gpc_unk_0[];
+extern const struct nvc0_graph_init nvc1_graph_init_setup_1[];
+
+extern const struct nvc0_graph_init nvd9_graph_init_pd_0[];
+extern const struct nvc0_graph_init nvd9_graph_init_ds_0[];
+extern const struct nvc0_graph_init nvd9_graph_init_prop_0[];
+extern const struct nvc0_graph_init nvd9_graph_init_gpm_0[];
+extern const struct nvc0_graph_init nvd9_graph_init_gpc_unk_1[];
+extern const struct nvc0_graph_init nvd9_graph_init_tex_0[];
+extern const struct nvc0_graph_init nvd9_graph_init_sm_0[];
+extern const struct nvc0_graph_init nvd9_graph_init_fe_1[];
+
+extern const struct nvc0_graph_init nvd7_graph_init_pes_0[];
+extern const struct nvc0_graph_init nvd7_graph_init_wwdx_0[];
+extern const struct nvc0_graph_init nvd7_graph_init_cbm_0[];
+
+extern const struct nvc0_graph_init nve4_graph_init_main_0[];
+extern const struct nvc0_graph_init nve4_graph_init_tpccs_0[];
+extern const struct nvc0_graph_init nve4_graph_init_pe_0[];
+extern const struct nvc0_graph_init nve4_graph_init_be_0[];
+
+extern const struct nvc0_graph_init nvf0_graph_init_fe_0[];
+extern const struct nvc0_graph_init nvf0_graph_init_sked_0[];
+extern const struct nvc0_graph_init nvf0_graph_init_cwd_0[];
+extern const struct nvc0_graph_init nvf0_graph_init_gpc_unk_1[];
+extern const struct nvc0_graph_init nvf0_graph_init_sm_0[];
+
+extern const struct nvc0_graph_init nv108_graph_init_gpc_unk_0[];
+
 
 #endif

+ 52 - 63
drivers/gpu/drm/nouveau/core/engine/graph/nvc1.c

@@ -23,6 +23,7 @@
  */
 
 #include "nvc0.h"
+#include "ctxnvc0.h"
 
 /*******************************************************************************
  * Graphics object classes
@@ -39,94 +40,82 @@ nvc1_graph_sclass[] = {
 };
 
 /*******************************************************************************
- * PGRAPH engine/subdev functions
+ * PGRAPH register lists
  ******************************************************************************/
 
-static struct nvc0_graph_init
-nvc1_graph_init_gpc[] = {
-	{ 0x4184a0,   1, 0x04, 0x00000000 },
+const struct nvc0_graph_init
+nvc1_graph_init_gpc_unk_0[] = {
 	{ 0x418604,   1, 0x04, 0x00000000 },
 	{ 0x418680,   1, 0x04, 0x00000000 },
 	{ 0x418714,   1, 0x04, 0x00000000 },
 	{ 0x418384,   1, 0x04, 0x00000000 },
-	{ 0x418814,   3, 0x04, 0x00000000 },
-	{ 0x418b04,   1, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc1_graph_init_setup_1[] = {
 	{ 0x4188c8,   2, 0x04, 0x00000000 },
 	{ 0x4188d0,   1, 0x04, 0x00010000 },
 	{ 0x4188d4,   1, 0x04, 0x00000001 },
-	{ 0x418910,   1, 0x04, 0x00010001 },
-	{ 0x418914,   1, 0x04, 0x00000301 },
-	{ 0x418918,   1, 0x04, 0x00800000 },
-	{ 0x418980,   1, 0x04, 0x77777770 },
-	{ 0x418984,   3, 0x04, 0x77777777 },
-	{ 0x418c04,   1, 0x04, 0x00000000 },
-	{ 0x418c88,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvc1_graph_init_gpc_unk_1[] = {
 	{ 0x418d00,   1, 0x04, 0x00000000 },
 	{ 0x418f08,   1, 0x04, 0x00000000 },
 	{ 0x418e00,   1, 0x04, 0x00000003 },
 	{ 0x418e08,   1, 0x04, 0x00000000 },
-	{ 0x41900c,   1, 0x04, 0x00000000 },
-	{ 0x419018,   1, 0x04, 0x00000000 },
 	{}
 };
 
-static struct nvc0_graph_init
-nvc1_graph_init_tpc[] = {
-	{ 0x419d08,   2, 0x04, 0x00000000 },
-	{ 0x419d10,   1, 0x04, 0x00000014 },
-	{ 0x419ab0,   1, 0x04, 0x00000000 },
-	{ 0x419ac8,   1, 0x04, 0x00000000 },
-	{ 0x419ab8,   1, 0x04, 0x000000e7 },
-	{ 0x419abc,   2, 0x04, 0x00000000 },
-	{ 0x41980c,   2, 0x04, 0x00000000 },
+static const struct nvc0_graph_init
+nvc1_graph_init_pe_0[] = {
+	{ 0x41980c,   1, 0x04, 0x00000010 },
+	{ 0x419810,   1, 0x04, 0x00000000 },
 	{ 0x419814,   1, 0x04, 0x00000004 },
 	{ 0x419844,   1, 0x04, 0x00000000 },
 	{ 0x41984c,   1, 0x04, 0x00005bc5 },
 	{ 0x419850,   4, 0x04, 0x00000000 },
 	{ 0x419880,   1, 0x04, 0x00000002 },
-	{ 0x419c98,   1, 0x04, 0x00000000 },
-	{ 0x419ca8,   1, 0x04, 0x80000000 },
-	{ 0x419cb4,   1, 0x04, 0x00000000 },
-	{ 0x419cb8,   1, 0x04, 0x00008bf4 },
-	{ 0x419cbc,   1, 0x04, 0x28137606 },
-	{ 0x419cc0,   2, 0x04, 0x00000000 },
-	{ 0x419bd4,   1, 0x04, 0x00800000 },
-	{ 0x419bdc,   1, 0x04, 0x00000000 },
-	{ 0x419d2c,   1, 0x04, 0x00000000 },
-	{ 0x419c0c,   1, 0x04, 0x00000000 },
-	{ 0x419e00,   1, 0x04, 0x00000000 },
-	{ 0x419ea0,   1, 0x04, 0x00000000 },
-	{ 0x419ea4,   1, 0x04, 0x00000100 },
-	{ 0x419ea8,   1, 0x04, 0x00001100 },
-	{ 0x419eac,   1, 0x04, 0x11100702 },
-	{ 0x419eb0,   1, 0x04, 0x00000003 },
-	{ 0x419eb4,   4, 0x04, 0x00000000 },
-	{ 0x419ec8,   1, 0x04, 0x0e063818 },
-	{ 0x419ecc,   1, 0x04, 0x0e060e06 },
-	{ 0x419ed0,   1, 0x04, 0x00003818 },
-	{ 0x419ed4,   1, 0x04, 0x011104f1 },
-	{ 0x419edc,   1, 0x04, 0x00000000 },
-	{ 0x419f00,   1, 0x04, 0x00000000 },
-	{ 0x419f2c,   1, 0x04, 0x00000000 },
 	{}
 };
 
-struct nvc0_graph_init *
-nvc1_graph_init_mmio[] = {
-	nvc0_graph_init_regs,
-	nvc0_graph_init_unk40xx,
-	nvc0_graph_init_unk44xx,
-	nvc0_graph_init_unk78xx,
-	nvc0_graph_init_unk60xx,
-	nvc3_graph_init_unk58xx,
-	nvc0_graph_init_unk80xx,
-	nvc1_graph_init_gpc,
-	nvc1_graph_init_tpc,
-	nvc0_graph_init_unk88xx,
-	nvc0_graph_tpc_0,
-	NULL
+static const struct nvc0_graph_pack
+nvc1_graph_pack_mmio[] = {
+	{ nvc0_graph_init_main_0 },
+	{ nvc0_graph_init_fe_0 },
+	{ nvc0_graph_init_pri_0 },
+	{ nvc0_graph_init_rstr2d_0 },
+	{ nvc0_graph_init_pd_0 },
+	{ nvc4_graph_init_ds_0 },
+	{ nvc0_graph_init_scc_0 },
+	{ nvc0_graph_init_prop_0 },
+	{ nvc1_graph_init_gpc_unk_0 },
+	{ nvc0_graph_init_setup_0 },
+	{ nvc0_graph_init_crstr_0 },
+	{ nvc1_graph_init_setup_1 },
+	{ nvc0_graph_init_zcull_0 },
+	{ nvc0_graph_init_gpm_0 },
+	{ nvc1_graph_init_gpc_unk_1 },
+	{ nvc0_graph_init_gcc_0 },
+	{ nvc0_graph_init_tpccs_0 },
+	{ nvc4_graph_init_tex_0 },
+	{ nvc1_graph_init_pe_0 },
+	{ nvc0_graph_init_l1c_0 },
+	{ nvc0_graph_init_wwdx_0 },
+	{ nvc0_graph_init_tpccs_1 },
+	{ nvc0_graph_init_mpc_0 },
+	{ nvc4_graph_init_sm_0 },
+	{ nvc0_graph_init_be_0 },
+	{ nvc0_graph_init_fe_1 },
+	{}
 };
 
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
 struct nouveau_oclass *
 nvc1_graph_oclass = &(struct nvc0_graph_oclass) {
 	.base.handle = NV_ENGINE(GR, 0xc1),
@@ -138,7 +127,7 @@ nvc1_graph_oclass = &(struct nvc0_graph_oclass) {
 	},
 	.cclass = &nvc1_grctx_oclass,
 	.sclass = nvc1_graph_sclass,
-	.mmio = nvc1_graph_init_mmio,
+	.mmio = nvc1_graph_pack_mmio,
 	.fecs.ucode = &nvc0_graph_fecs_ucode,
 	.gpccs.ucode = &nvc0_graph_gpccs_ucode,
 }.base;

+ 52 - 34
drivers/gpu/drm/nouveau/core/engine/graph/nvc3.c → drivers/gpu/drm/nouveau/core/engine/graph/nvc4.c

@@ -23,13 +23,14 @@
  */
 
 #include "nvc0.h"
+#include "ctxnvc0.h"
 
 /*******************************************************************************
- * PGRAPH engine/subdev functions
+ * PGRAPH register lists
  ******************************************************************************/
 
-struct nvc0_graph_init
-nvc3_graph_init_unk58xx[] = {
+const struct nvc0_graph_init
+nvc4_graph_init_ds_0[] = {
 	{ 0x405844,   1, 0x04, 0x00ffffff },
 	{ 0x405850,   1, 0x04, 0x00000000 },
 	{ 0x405900,   1, 0x04, 0x00002834 },
@@ -37,29 +38,27 @@ nvc3_graph_init_unk58xx[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nvc3_graph_init_tpc[] = {
-	{ 0x419d08,   2, 0x04, 0x00000000 },
-	{ 0x419d10,   1, 0x04, 0x00000014 },
+const struct nvc0_graph_init
+nvc4_graph_init_tex_0[] = {
 	{ 0x419ab0,   1, 0x04, 0x00000000 },
 	{ 0x419ac8,   1, 0x04, 0x00000000 },
 	{ 0x419ab8,   1, 0x04, 0x000000e7 },
 	{ 0x419abc,   2, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvc4_graph_init_pe_0[] = {
 	{ 0x41980c,   3, 0x04, 0x00000000 },
 	{ 0x419844,   1, 0x04, 0x00000000 },
 	{ 0x41984c,   1, 0x04, 0x00005bc5 },
 	{ 0x419850,   4, 0x04, 0x00000000 },
 	{ 0x419880,   1, 0x04, 0x00000002 },
-	{ 0x419c98,   1, 0x04, 0x00000000 },
-	{ 0x419ca8,   1, 0x04, 0x80000000 },
-	{ 0x419cb4,   1, 0x04, 0x00000000 },
-	{ 0x419cb8,   1, 0x04, 0x00008bf4 },
-	{ 0x419cbc,   1, 0x04, 0x28137606 },
-	{ 0x419cc0,   2, 0x04, 0x00000000 },
-	{ 0x419bd4,   1, 0x04, 0x00800000 },
-	{ 0x419bdc,   1, 0x04, 0x00000000 },
-	{ 0x419d2c,   1, 0x04, 0x00000000 },
-	{ 0x419c0c,   1, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvc4_graph_init_sm_0[] = {
 	{ 0x419e00,   1, 0x04, 0x00000000 },
 	{ 0x419ea0,   1, 0x04, 0x00000000 },
 	{ 0x419ea4,   1, 0x04, 0x00000100 },
@@ -77,24 +76,43 @@ nvc3_graph_init_tpc[] = {
 	{}
 };
 
-static struct nvc0_graph_init *
-nvc3_graph_init_mmio[] = {
-	nvc0_graph_init_regs,
-	nvc0_graph_init_unk40xx,
-	nvc0_graph_init_unk44xx,
-	nvc0_graph_init_unk78xx,
-	nvc0_graph_init_unk60xx,
-	nvc3_graph_init_unk58xx,
-	nvc0_graph_init_unk80xx,
-	nvc0_graph_init_gpc,
-	nvc3_graph_init_tpc,
-	nvc0_graph_init_unk88xx,
-	nvc0_graph_tpc_0,
-	NULL
+static const struct nvc0_graph_pack
+nvc4_graph_pack_mmio[] = {
+	{ nvc0_graph_init_main_0 },
+	{ nvc0_graph_init_fe_0 },
+	{ nvc0_graph_init_pri_0 },
+	{ nvc0_graph_init_rstr2d_0 },
+	{ nvc0_graph_init_pd_0 },
+	{ nvc4_graph_init_ds_0 },
+	{ nvc0_graph_init_scc_0 },
+	{ nvc0_graph_init_prop_0 },
+	{ nvc0_graph_init_gpc_unk_0 },
+	{ nvc0_graph_init_setup_0 },
+	{ nvc0_graph_init_crstr_0 },
+	{ nvc0_graph_init_setup_1 },
+	{ nvc0_graph_init_zcull_0 },
+	{ nvc0_graph_init_gpm_0 },
+	{ nvc0_graph_init_gpc_unk_1 },
+	{ nvc0_graph_init_gcc_0 },
+	{ nvc0_graph_init_tpccs_0 },
+	{ nvc4_graph_init_tex_0 },
+	{ nvc4_graph_init_pe_0 },
+	{ nvc0_graph_init_l1c_0 },
+	{ nvc0_graph_init_wwdx_0 },
+	{ nvc0_graph_init_tpccs_1 },
+	{ nvc0_graph_init_mpc_0 },
+	{ nvc4_graph_init_sm_0 },
+	{ nvc0_graph_init_be_0 },
+	{ nvc0_graph_init_fe_1 },
+	{}
 };
 
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
 struct nouveau_oclass *
-nvc3_graph_oclass = &(struct nvc0_graph_oclass) {
+nvc4_graph_oclass = &(struct nvc0_graph_oclass) {
 	.base.handle = NV_ENGINE(GR, 0xc3),
 	.base.ofuncs = &(struct nouveau_ofuncs) {
 		.ctor = nvc0_graph_ctor,
@@ -102,9 +120,9 @@ nvc3_graph_oclass = &(struct nvc0_graph_oclass) {
 		.init = nvc0_graph_init,
 		.fini = _nouveau_graph_fini,
 	},
-	.cclass = &nvc3_grctx_oclass,
+	.cclass = &nvc4_grctx_oclass,
 	.sclass = nvc0_graph_sclass,
-	.mmio = nvc3_graph_init_mmio,
+	.mmio = nvc4_graph_pack_mmio,
 	.fecs.ucode = &nvc0_graph_fecs_ucode,
 	.gpccs.ucode = &nvc0_graph_gpccs_ucode,
 }.base;

+ 39 - 65
drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c

@@ -23,6 +23,7 @@
  */
 
 #include "nvc0.h"
+#include "ctxnvc0.h"
 
 /*******************************************************************************
  * Graphics object classes
@@ -40,58 +41,11 @@ nvc8_graph_sclass[] = {
 };
 
 /*******************************************************************************
- * PGRAPH engine/subdev functions
+ * PGRAPH register lists
  ******************************************************************************/
 
-static struct nvc0_graph_init
-nvc8_graph_init_gpc[] = {
-	{ 0x4184a0,   1, 0x04, 0x00000000 },
-	{ 0x418604,   1, 0x04, 0x00000000 },
-	{ 0x418680,   1, 0x04, 0x00000000 },
-	{ 0x418714,   1, 0x04, 0x80000000 },
-	{ 0x418384,   1, 0x04, 0x00000000 },
-	{ 0x418814,   3, 0x04, 0x00000000 },
-	{ 0x418b04,   1, 0x04, 0x00000000 },
-	{ 0x4188c8,   2, 0x04, 0x00000000 },
-	{ 0x4188d0,   1, 0x04, 0x00010000 },
-	{ 0x4188d4,   1, 0x04, 0x00000001 },
-	{ 0x418910,   1, 0x04, 0x00010001 },
-	{ 0x418914,   1, 0x04, 0x00000301 },
-	{ 0x418918,   1, 0x04, 0x00800000 },
-	{ 0x418980,   1, 0x04, 0x77777770 },
-	{ 0x418984,   3, 0x04, 0x77777777 },
-	{ 0x418c04,   1, 0x04, 0x00000000 },
-	{ 0x418c88,   1, 0x04, 0x00000000 },
-	{ 0x418d00,   1, 0x04, 0x00000000 },
-	{ 0x418f08,   1, 0x04, 0x00000000 },
-	{ 0x418e00,   1, 0x04, 0x00000050 },
-	{ 0x418e08,   1, 0x04, 0x00000000 },
-	{ 0x41900c,   1, 0x04, 0x00000000 },
-	{ 0x419018,   1, 0x04, 0x00000000 },
-	{}
-};
-
-static struct nvc0_graph_init
-nvc8_graph_init_tpc[] = {
-	{ 0x419d08,   2, 0x04, 0x00000000 },
-	{ 0x419d10,   1, 0x04, 0x00000014 },
-	{ 0x419ab0,   1, 0x04, 0x00000000 },
-	{ 0x419ab8,   1, 0x04, 0x000000e7 },
-	{ 0x419abc,   2, 0x04, 0x00000000 },
-	{ 0x41980c,   3, 0x04, 0x00000000 },
-	{ 0x419844,   1, 0x04, 0x00000000 },
-	{ 0x41984c,   1, 0x04, 0x00005bc5 },
-	{ 0x419850,   4, 0x04, 0x00000000 },
-	{ 0x419c98,   1, 0x04, 0x00000000 },
-	{ 0x419ca8,   1, 0x04, 0x80000000 },
-	{ 0x419cb4,   1, 0x04, 0x00000000 },
-	{ 0x419cb8,   1, 0x04, 0x00008bf4 },
-	{ 0x419cbc,   1, 0x04, 0x28137606 },
-	{ 0x419cc0,   2, 0x04, 0x00000000 },
-	{ 0x419bd4,   1, 0x04, 0x00800000 },
-	{ 0x419bdc,   1, 0x04, 0x00000000 },
-	{ 0x419d2c,   1, 0x04, 0x00000000 },
-	{ 0x419c0c,   1, 0x04, 0x00000000 },
+static const struct nvc0_graph_init
+nvc8_graph_init_sm_0[] = {
 	{ 0x419e00,   1, 0x04, 0x00000000 },
 	{ 0x419ea0,   1, 0x04, 0x00000000 },
 	{ 0x419ea4,   1, 0x04, 0x00000100 },
@@ -108,22 +62,42 @@ nvc8_graph_init_tpc[] = {
 	{}
 };
 
-static struct nvc0_graph_init *
-nvc8_graph_init_mmio[] = {
-	nvc0_graph_init_regs,
-	nvc0_graph_init_unk40xx,
-	nvc0_graph_init_unk44xx,
-	nvc0_graph_init_unk78xx,
-	nvc0_graph_init_unk60xx,
-	nvc0_graph_init_unk58xx,
-	nvc0_graph_init_unk80xx,
-	nvc8_graph_init_gpc,
-	nvc8_graph_init_tpc,
-	nvc0_graph_init_unk88xx,
-	nvc0_graph_tpc_0,
-	NULL
+static const struct nvc0_graph_pack
+nvc8_graph_pack_mmio[] = {
+	{ nvc0_graph_init_main_0 },
+	{ nvc0_graph_init_fe_0 },
+	{ nvc0_graph_init_pri_0 },
+	{ nvc0_graph_init_rstr2d_0 },
+	{ nvc0_graph_init_pd_0 },
+	{ nvc0_graph_init_ds_0 },
+	{ nvc0_graph_init_scc_0 },
+	{ nvc0_graph_init_prop_0 },
+	{ nvc0_graph_init_gpc_unk_0 },
+	{ nvc0_graph_init_setup_0 },
+	{ nvc0_graph_init_crstr_0 },
+	{ nvc1_graph_init_setup_1 },
+	{ nvc0_graph_init_zcull_0 },
+	{ nvc0_graph_init_gpm_0 },
+	{ nvc0_graph_init_gpc_unk_1 },
+	{ nvc0_graph_init_gcc_0 },
+	{ nvc0_graph_init_tpccs_0 },
+	{ nvc0_graph_init_tex_0 },
+	{ nvc0_graph_init_pe_0 },
+	{ nvc0_graph_init_l1c_0 },
+	{ nvc0_graph_init_wwdx_0 },
+	{ nvc0_graph_init_tpccs_1 },
+	{ nvc0_graph_init_mpc_0 },
+	{ nvc8_graph_init_sm_0 },
+	{ nvc0_graph_init_be_0 },
+	{ nvc0_graph_init_fe_1 },
+	{ nvc0_graph_init_pe_1 },
+	{}
 };
 
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
 struct nouveau_oclass *
 nvc8_graph_oclass = &(struct nvc0_graph_oclass) {
 	.base.handle = NV_ENGINE(GR, 0xc8),
@@ -135,7 +109,7 @@ nvc8_graph_oclass = &(struct nvc0_graph_oclass) {
 	},
 	.cclass = &nvc8_grctx_oclass,
 	.sclass = nvc8_graph_sclass,
-	.mmio = nvc8_graph_init_mmio,
+	.mmio = nvc8_graph_pack_mmio,
 	.fecs.ucode = &nvc0_graph_fecs_ucode,
 	.gpccs.ucode = &nvc0_graph_gpccs_ucode,
 }.base;

+ 72 - 103
drivers/gpu/drm/nouveau/core/engine/graph/nvd7.c

@@ -23,6 +23,77 @@
  */
 
 #include "nvc0.h"
+#include "ctxnvc0.h"
+
+/*******************************************************************************
+ * PGRAPH register lists
+ ******************************************************************************/
+
+static const struct nvc0_graph_init
+nvd7_graph_init_pe_0[] = {
+	{ 0x41980c,   1, 0x04, 0x00000010 },
+	{ 0x419844,   1, 0x04, 0x00000000 },
+	{ 0x41984c,   1, 0x04, 0x00005bc8 },
+	{ 0x419850,   3, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvd7_graph_init_pes_0[] = {
+	{ 0x41be04,   1, 0x04, 0x00000000 },
+	{ 0x41be08,   1, 0x04, 0x00000004 },
+	{ 0x41be0c,   1, 0x04, 0x00000000 },
+	{ 0x41be10,   1, 0x04, 0x003b8bc7 },
+	{ 0x41be14,   2, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvd7_graph_init_wwdx_0[] = {
+	{ 0x41bfd4,   1, 0x04, 0x00800000 },
+	{ 0x41bfdc,   1, 0x04, 0x00000000 },
+	{ 0x41bff8,   2, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvd7_graph_init_cbm_0[] = {
+	{ 0x41becc,   1, 0x04, 0x00000000 },
+	{ 0x41bee8,   2, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_pack
+nvd7_graph_pack_mmio[] = {
+	{ nvc0_graph_init_main_0 },
+	{ nvc0_graph_init_fe_0 },
+	{ nvc0_graph_init_pri_0 },
+	{ nvc0_graph_init_rstr2d_0 },
+	{ nvd9_graph_init_pd_0 },
+	{ nvd9_graph_init_ds_0 },
+	{ nvc0_graph_init_scc_0 },
+	{ nvd9_graph_init_prop_0 },
+	{ nvc1_graph_init_gpc_unk_0 },
+	{ nvc0_graph_init_setup_0 },
+	{ nvc0_graph_init_crstr_0 },
+	{ nvc1_graph_init_setup_1 },
+	{ nvc0_graph_init_zcull_0 },
+	{ nvd9_graph_init_gpm_0 },
+	{ nvd9_graph_init_gpc_unk_1 },
+	{ nvc0_graph_init_gcc_0 },
+	{ nvc0_graph_init_tpccs_0 },
+	{ nvd9_graph_init_tex_0 },
+	{ nvd7_graph_init_pe_0 },
+	{ nvc0_graph_init_l1c_0 },
+	{ nvc0_graph_init_mpc_0 },
+	{ nvd9_graph_init_sm_0 },
+	{ nvd7_graph_init_pes_0 },
+	{ nvd7_graph_init_wwdx_0 },
+	{ nvd7_graph_init_cbm_0 },
+	{ nvc0_graph_init_be_0 },
+	{ nvd9_graph_init_fe_1 },
+	{}
+};
 
 /*******************************************************************************
  * PGRAPH engine/subdev functions
@@ -48,108 +119,6 @@ nvd7_graph_gpccs_ucode = {
 	.data.size = sizeof(nvd7_grgpc_data),
 };
 
-static struct nvc0_graph_init
-nvd7_graph_init_gpc[] = {
-	{ 0x418408,   1, 0x04, 0x00000000 },
-	{ 0x4184a0,   1, 0x04, 0x00000000 },
-	{ 0x4184a4,   2, 0x04, 0x00000000 },
-	{ 0x418604,   1, 0x04, 0x00000000 },
-	{ 0x418680,   1, 0x04, 0x00000000 },
-	{ 0x418714,   1, 0x04, 0x00000000 },
-	{ 0x418384,   1, 0x04, 0x00000000 },
-	{ 0x418814,   3, 0x04, 0x00000000 },
-	{ 0x418b04,   1, 0x04, 0x00000000 },
-	{ 0x4188c8,   2, 0x04, 0x00000000 },
-	{ 0x4188d0,   1, 0x04, 0x00010000 },
-	{ 0x4188d4,   1, 0x04, 0x00000001 },
-	{ 0x418910,   1, 0x04, 0x00010001 },
-	{ 0x418914,   1, 0x04, 0x00000301 },
-	{ 0x418918,   1, 0x04, 0x00800000 },
-	{ 0x418980,   1, 0x04, 0x77777770 },
-	{ 0x418984,   3, 0x04, 0x77777777 },
-	{ 0x418c04,   1, 0x04, 0x00000000 },
-	{ 0x418c64,   1, 0x04, 0x00000000 },
-	{ 0x418c68,   1, 0x04, 0x00000000 },
-	{ 0x418c88,   1, 0x04, 0x00000000 },
-	{ 0x418cb4,   2, 0x04, 0x00000000 },
-	{ 0x418d00,   1, 0x04, 0x00000000 },
-	{ 0x418d28,   1, 0x04, 0x00000000 },
-	{ 0x418f00,   1, 0x04, 0x00000000 },
-	{ 0x418f08,   1, 0x04, 0x00000000 },
-	{ 0x418f20,   2, 0x04, 0x00000000 },
-	{ 0x418e00,   1, 0x04, 0x00000003 },
-	{ 0x418e08,   1, 0x04, 0x00000000 },
-	{ 0x418e1c,   1, 0x04, 0x00000000 },
-	{ 0x418e20,   1, 0x04, 0x00000000 },
-	{ 0x41900c,   1, 0x04, 0x00000000 },
-	{ 0x419018,   1, 0x04, 0x00000000 },
-	{}
-};
-
-static struct nvc0_graph_init
-nvd7_graph_init_tpc[] = {
-	{ 0x419d08,   2, 0x04, 0x00000000 },
-	{ 0x419d10,   1, 0x04, 0x00000014 },
-	{ 0x419ab0,   1, 0x04, 0x00000000 },
-	{ 0x419ac8,   1, 0x04, 0x00000000 },
-	{ 0x419ab8,   1, 0x04, 0x000000e7 },
-	{ 0x419abc,   2, 0x04, 0x00000000 },
-	{ 0x419ab4,   1, 0x04, 0x00000000 },
-	{ 0x41980c,   1, 0x04, 0x00000010 },
-	{ 0x419844,   1, 0x04, 0x00000000 },
-	{ 0x41984c,   1, 0x04, 0x00005bc8 },
-	{ 0x419850,   2, 0x04, 0x00000000 },
-	{ 0x419c98,   1, 0x04, 0x00000000 },
-	{ 0x419ca8,   1, 0x04, 0x80000000 },
-	{ 0x419cb4,   1, 0x04, 0x00000000 },
-	{ 0x419cb8,   1, 0x04, 0x00008bf4 },
-	{ 0x419cbc,   1, 0x04, 0x28137606 },
-	{ 0x419cc0,   2, 0x04, 0x00000000 },
-	{ 0x419c0c,   1, 0x04, 0x00000000 },
-	{ 0x419e00,   1, 0x04, 0x00000000 },
-	{ 0x419ea0,   1, 0x04, 0x00000000 },
-	{ 0x419ea4,   1, 0x04, 0x00000100 },
-	{ 0x419ea8,   1, 0x04, 0x02001100 },
-	{ 0x419eac,   1, 0x04, 0x11100702 },
-	{ 0x419eb0,   1, 0x04, 0x00000003 },
-	{ 0x419eb4,   4, 0x04, 0x00000000 },
-	{ 0x419ec8,   1, 0x04, 0x0e063818 },
-	{ 0x419ecc,   1, 0x04, 0x0e060e06 },
-	{ 0x419ed0,   1, 0x04, 0x00003818 },
-	{ 0x419ed4,   1, 0x04, 0x011104f1 },
-	{ 0x419edc,   1, 0x04, 0x00000000 },
-	{ 0x419f00,   1, 0x04, 0x00000000 },
-	{ 0x419f2c,   1, 0x04, 0x00000000 },
-	{}
-};
-
-static struct nvc0_graph_init
-nvd7_graph_init_tpc_0[] = {
-	{ 0x40402c,   1, 0x04, 0x00000000 },
-	{ 0x4040f0,   1, 0x04, 0x00000000 },
-	{ 0x404174,   1, 0x04, 0x00000000 },
-	{ 0x503018,   1, 0x04, 0x00000001 },
-	{}
-};
-
-static struct nvc0_graph_init *
-nvd7_graph_init_mmio[] = {
-	nvc0_graph_init_regs,
-	nvc0_graph_init_unk40xx,
-	nvc0_graph_init_unk44xx,
-	nvc0_graph_init_unk78xx,
-	nvc0_graph_init_unk60xx,
-	nvd9_graph_init_unk64xx,
-	nvd9_graph_init_unk58xx,
-	nvc0_graph_init_unk80xx,
-	nvd7_graph_init_gpc,
-	nvd7_graph_init_tpc,
-	nve4_graph_init_unk,
-	nvc0_graph_init_unk88xx,
-	nvd7_graph_init_tpc_0,
-	NULL
-};
-
 struct nouveau_oclass *
 nvd7_graph_oclass = &(struct nvc0_graph_oclass) {
 	.base.handle = NV_ENGINE(GR, 0xd7),
@@ -161,7 +130,7 @@ nvd7_graph_oclass = &(struct nvc0_graph_oclass) {
 	},
 	.cclass = &nvd7_grctx_oclass,
 	.sclass = nvc8_graph_sclass,
-	.mmio = nvd7_graph_init_mmio,
+	.mmio = nvd7_graph_pack_mmio,
 	.fecs.ucode = &nvd7_graph_fecs_ucode,
 	.gpccs.ucode = &nvd7_graph_gpccs_ucode,
 }.base;

+ 90 - 64
drivers/gpu/drm/nouveau/core/engine/graph/nvd9.c

@@ -23,76 +23,70 @@
  */
 
 #include "nvc0.h"
+#include "ctxnvc0.h"
 
 /*******************************************************************************
- * PGRAPH engine/subdev functions
+ * PGRAPH register lists
  ******************************************************************************/
 
-struct nvc0_graph_init
-nvd9_graph_init_unk64xx[] = {
+const struct nvc0_graph_init
+nvd9_graph_init_pd_0[] = {
+	{ 0x406024,   1, 0x04, 0x00000000 },
 	{ 0x4064f0,   3, 0x04, 0x00000000 },
 	{}
 };
 
-struct nvc0_graph_init
-nvd9_graph_init_unk58xx[] = {
+const struct nvc0_graph_init
+nvd9_graph_init_ds_0[] = {
 	{ 0x405844,   1, 0x04, 0x00ffffff },
 	{ 0x405850,   1, 0x04, 0x00000000 },
 	{ 0x405900,   1, 0x04, 0x00002834 },
 	{ 0x405908,   1, 0x04, 0x00000000 },
-	{ 0x405928,   1, 0x04, 0x00000000 },
-	{ 0x40592c,   1, 0x04, 0x00000000 },
+	{ 0x405928,   2, 0x04, 0x00000000 },
 	{}
 };
 
-static struct nvc0_graph_init
-nvd9_graph_init_gpc[] = {
+const struct nvc0_graph_init
+nvd9_graph_init_prop_0[] = {
 	{ 0x418408,   1, 0x04, 0x00000000 },
-	{ 0x4184a0,   1, 0x04, 0x00000000 },
-	{ 0x4184a4,   2, 0x04, 0x00000000 },
-	{ 0x418604,   1, 0x04, 0x00000000 },
-	{ 0x418680,   1, 0x04, 0x00000000 },
-	{ 0x418714,   1, 0x04, 0x00000000 },
-	{ 0x418384,   1, 0x04, 0x00000000 },
-	{ 0x418814,   3, 0x04, 0x00000000 },
-	{ 0x418b04,   1, 0x04, 0x00000000 },
-	{ 0x4188c8,   2, 0x04, 0x00000000 },
-	{ 0x4188d0,   1, 0x04, 0x00010000 },
-	{ 0x4188d4,   1, 0x04, 0x00000001 },
-	{ 0x418910,   1, 0x04, 0x00010001 },
-	{ 0x418914,   1, 0x04, 0x00000301 },
-	{ 0x418918,   1, 0x04, 0x00800000 },
-	{ 0x418980,   1, 0x04, 0x77777770 },
-	{ 0x418984,   3, 0x04, 0x77777777 },
+	{ 0x4184a0,   3, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvd9_graph_init_gpm_0[] = {
 	{ 0x418c04,   1, 0x04, 0x00000000 },
-	{ 0x418c64,   1, 0x04, 0x00000000 },
-	{ 0x418c68,   1, 0x04, 0x00000000 },
+	{ 0x418c64,   2, 0x04, 0x00000000 },
 	{ 0x418c88,   1, 0x04, 0x00000000 },
 	{ 0x418cb4,   2, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvd9_graph_init_gpc_unk_1[] = {
 	{ 0x418d00,   1, 0x04, 0x00000000 },
-	{ 0x418d28,   1, 0x04, 0x00000000 },
-	{ 0x418d2c,   1, 0x04, 0x00000000 },
+	{ 0x418d28,   2, 0x04, 0x00000000 },
 	{ 0x418f00,   1, 0x04, 0x00000000 },
 	{ 0x418f08,   1, 0x04, 0x00000000 },
 	{ 0x418f20,   2, 0x04, 0x00000000 },
 	{ 0x418e00,   1, 0x04, 0x00000003 },
 	{ 0x418e08,   1, 0x04, 0x00000000 },
-	{ 0x418e1c,   1, 0x04, 0x00000000 },
-	{ 0x418e20,   1, 0x04, 0x00000000 },
-	{ 0x41900c,   1, 0x04, 0x00000000 },
-	{ 0x419018,   1, 0x04, 0x00000000 },
+	{ 0x418e1c,   2, 0x04, 0x00000000 },
 	{}
 };
 
-static struct nvc0_graph_init
-nvd9_graph_init_tpc[] = {
-	{ 0x419d08,   2, 0x04, 0x00000000 },
-	{ 0x419d10,   1, 0x04, 0x00000014 },
+const struct nvc0_graph_init
+nvd9_graph_init_tex_0[] = {
 	{ 0x419ab0,   1, 0x04, 0x00000000 },
 	{ 0x419ac8,   1, 0x04, 0x00000000 },
 	{ 0x419ab8,   1, 0x04, 0x000000e7 },
 	{ 0x419abc,   2, 0x04, 0x00000000 },
 	{ 0x419ab4,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvd9_graph_init_pe_0[] = {
 	{ 0x41980c,   1, 0x04, 0x00000010 },
 	{ 0x419810,   1, 0x04, 0x00000000 },
 	{ 0x419814,   1, 0x04, 0x00000004 },
@@ -100,20 +94,26 @@ nvd9_graph_init_tpc[] = {
 	{ 0x41984c,   1, 0x04, 0x0000a918 },
 	{ 0x419850,   4, 0x04, 0x00000000 },
 	{ 0x419880,   1, 0x04, 0x00000002 },
-	{ 0x419c98,   1, 0x04, 0x00000000 },
-	{ 0x419ca8,   1, 0x04, 0x80000000 },
-	{ 0x419cb4,   1, 0x04, 0x00000000 },
-	{ 0x419cb8,   1, 0x04, 0x00008bf4 },
-	{ 0x419cbc,   1, 0x04, 0x28137606 },
-	{ 0x419cc0,   2, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvd9_graph_init_wwdx_0[] = {
 	{ 0x419bd4,   1, 0x04, 0x00800000 },
 	{ 0x419bdc,   1, 0x04, 0x00000000 },
-	{ 0x419bf8,   1, 0x04, 0x00000000 },
-	{ 0x419bfc,   1, 0x04, 0x00000000 },
+	{ 0x419bf8,   2, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvd9_graph_init_tpccs_1[] = {
 	{ 0x419d2c,   1, 0x04, 0x00000000 },
-	{ 0x419d48,   1, 0x04, 0x00000000 },
-	{ 0x419d4c,   1, 0x04, 0x00000000 },
-	{ 0x419c0c,   1, 0x04, 0x00000000 },
+	{ 0x419d48,   2, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvd9_graph_init_sm_0[] = {
 	{ 0x419e00,   1, 0x04, 0x00000000 },
 	{ 0x419ea0,   1, 0x04, 0x00000000 },
 	{ 0x419ea4,   1, 0x04, 0x00000100 },
@@ -131,23 +131,49 @@ nvd9_graph_init_tpc[] = {
 	{}
 };
 
-static struct nvc0_graph_init *
-nvd9_graph_init_mmio[] = {
-	nvc0_graph_init_regs,
-	nvc0_graph_init_unk40xx,
-	nvc0_graph_init_unk44xx,
-	nvc0_graph_init_unk78xx,
-	nvc0_graph_init_unk60xx,
-	nvd9_graph_init_unk64xx,
-	nvd9_graph_init_unk58xx,
-	nvc0_graph_init_unk80xx,
-	nvd9_graph_init_gpc,
-	nvd9_graph_init_tpc,
-	nvc0_graph_init_unk88xx,
-	nvc0_graph_tpc_0,
-	NULL
+const struct nvc0_graph_init
+nvd9_graph_init_fe_1[] = {
+	{ 0x40402c,   1, 0x04, 0x00000000 },
+	{ 0x4040f0,   1, 0x04, 0x00000000 },
+	{ 0x404174,   1, 0x04, 0x00000000 },
+	{}
 };
 
+static const struct nvc0_graph_pack
+nvd9_graph_pack_mmio[] = {
+	{ nvc0_graph_init_main_0 },
+	{ nvc0_graph_init_fe_0 },
+	{ nvc0_graph_init_pri_0 },
+	{ nvc0_graph_init_rstr2d_0 },
+	{ nvd9_graph_init_pd_0 },
+	{ nvd9_graph_init_ds_0 },
+	{ nvc0_graph_init_scc_0 },
+	{ nvd9_graph_init_prop_0 },
+	{ nvc1_graph_init_gpc_unk_0 },
+	{ nvc0_graph_init_setup_0 },
+	{ nvc0_graph_init_crstr_0 },
+	{ nvc1_graph_init_setup_1 },
+	{ nvc0_graph_init_zcull_0 },
+	{ nvd9_graph_init_gpm_0 },
+	{ nvd9_graph_init_gpc_unk_1 },
+	{ nvc0_graph_init_gcc_0 },
+	{ nvc0_graph_init_tpccs_0 },
+	{ nvd9_graph_init_tex_0 },
+	{ nvd9_graph_init_pe_0 },
+	{ nvc0_graph_init_l1c_0 },
+	{ nvd9_graph_init_wwdx_0 },
+	{ nvd9_graph_init_tpccs_1 },
+	{ nvc0_graph_init_mpc_0 },
+	{ nvd9_graph_init_sm_0 },
+	{ nvc0_graph_init_be_0 },
+	{ nvd9_graph_init_fe_1 },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
 struct nouveau_oclass *
 nvd9_graph_oclass = &(struct nvc0_graph_oclass) {
 	.base.handle = NV_ENGINE(GR, 0xd9),
@@ -159,7 +185,7 @@ nvd9_graph_oclass = &(struct nvc0_graph_oclass) {
 	},
 	.cclass = &nvd9_grctx_oclass,
 	.sclass = nvc8_graph_sclass,
-	.mmio = nvd9_graph_init_mmio,
+	.mmio = nvd9_graph_pack_mmio,
 	.fecs.ucode = &nvc0_graph_fecs_ucode,
 	.gpccs.ucode = &nvc0_graph_gpccs_ucode,
 }.base;

+ 99 - 93
drivers/gpu/drm/nouveau/core/engine/graph/nve4.c

@@ -23,6 +23,7 @@
  */
 
 #include "nvc0.h"
+#include "ctxnvc0.h"
 
 /*******************************************************************************
  * Graphics object classes
@@ -38,11 +39,11 @@ nve4_graph_sclass[] = {
 };
 
 /*******************************************************************************
- * PGRAPH engine/subdev functions
+ * PGRAPH register lists
  ******************************************************************************/
 
-struct nvc0_graph_init
-nve4_graph_init_regs[] = {
+const struct nvc0_graph_init
+nve4_graph_init_main_0[] = {
 	{ 0x400080,   1, 0x04, 0x003083c2 },
 	{ 0x400088,   1, 0x04, 0x0001ffe7 },
 	{ 0x40008c,   1, 0x04, 0x00000000 },
@@ -57,81 +58,59 @@ nve4_graph_init_regs[] = {
 	{}
 };
 
-static struct nvc0_graph_init
-nve4_graph_init_unk58xx[] = {
+static const struct nvc0_graph_init
+nve4_graph_init_ds_0[] = {
 	{ 0x405844,   1, 0x04, 0x00ffffff },
 	{ 0x405850,   1, 0x04, 0x00000000 },
 	{ 0x405900,   1, 0x04, 0x0000ff34 },
 	{ 0x405908,   1, 0x04, 0x00000000 },
-	{ 0x405928,   1, 0x04, 0x00000000 },
-	{ 0x40592c,   1, 0x04, 0x00000000 },
+	{ 0x405928,   2, 0x04, 0x00000000 },
 	{}
 };
 
-static struct nvc0_graph_init
-nve4_graph_init_unk70xx[] = {
+static const struct nvc0_graph_init
+nve4_graph_init_sked_0[] = {
 	{ 0x407010,   1, 0x04, 0x00000000 },
 	{}
 };
 
-struct nvc0_graph_init
-nve4_graph_init_unk5bxx[] = {
+static const struct nvc0_graph_init
+nve4_graph_init_cwd_0[] = {
 	{ 0x405b50,   1, 0x04, 0x00000000 },
 	{}
 };
 
-static struct nvc0_graph_init
-nve4_graph_init_gpc[] = {
-	{ 0x418408,   1, 0x04, 0x00000000 },
-	{ 0x4184a0,   1, 0x04, 0x00000000 },
-	{ 0x4184a4,   2, 0x04, 0x00000000 },
-	{ 0x418604,   1, 0x04, 0x00000000 },
-	{ 0x418680,   1, 0x04, 0x00000000 },
-	{ 0x418714,   1, 0x04, 0x00000000 },
-	{ 0x418384,   1, 0x04, 0x00000000 },
-	{ 0x418814,   3, 0x04, 0x00000000 },
-	{ 0x418b04,   1, 0x04, 0x00000000 },
-	{ 0x4188c8,   2, 0x04, 0x00000000 },
-	{ 0x4188d0,   1, 0x04, 0x00010000 },
-	{ 0x4188d4,   1, 0x04, 0x00000001 },
-	{ 0x418910,   1, 0x04, 0x00010001 },
-	{ 0x418914,   1, 0x04, 0x00000301 },
-	{ 0x418918,   1, 0x04, 0x00800000 },
-	{ 0x418980,   1, 0x04, 0x77777770 },
-	{ 0x418984,   3, 0x04, 0x77777777 },
-	{ 0x418c04,   1, 0x04, 0x00000000 },
-	{ 0x418c64,   1, 0x04, 0x00000000 },
-	{ 0x418c68,   1, 0x04, 0x00000000 },
-	{ 0x418c88,   1, 0x04, 0x00000000 },
-	{ 0x418cb4,   2, 0x04, 0x00000000 },
+static const struct nvc0_graph_init
+nve4_graph_init_gpc_unk_1[] = {
 	{ 0x418d00,   1, 0x04, 0x00000000 },
-	{ 0x418d28,   1, 0x04, 0x00000000 },
-	{ 0x418d2c,   1, 0x04, 0x00000000 },
+	{ 0x418d28,   2, 0x04, 0x00000000 },
 	{ 0x418f00,   1, 0x04, 0x00000000 },
 	{ 0x418f08,   1, 0x04, 0x00000000 },
 	{ 0x418f20,   2, 0x04, 0x00000000 },
 	{ 0x418e00,   1, 0x04, 0x00000060 },
 	{ 0x418e08,   1, 0x04, 0x00000000 },
-	{ 0x418e1c,   1, 0x04, 0x00000000 },
-	{ 0x418e20,   1, 0x04, 0x00000000 },
-	{ 0x41900c,   1, 0x04, 0x00000000 },
-	{ 0x419018,   1, 0x04, 0x00000000 },
+	{ 0x418e1c,   2, 0x04, 0x00000000 },
 	{}
 };
 
-static struct nvc0_graph_init
-nve4_graph_init_tpc[] = {
+const struct nvc0_graph_init
+nve4_graph_init_tpccs_0[] = {
 	{ 0x419d0c,   1, 0x04, 0x00000000 },
 	{ 0x419d10,   1, 0x04, 0x00000014 },
-	{ 0x419ab0,   1, 0x04, 0x00000000 },
-	{ 0x419ac8,   1, 0x04, 0x00000000 },
-	{ 0x419ab8,   1, 0x04, 0x000000e7 },
-	{ 0x419abc,   2, 0x04, 0x00000000 },
-	{ 0x419ab4,   1, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nve4_graph_init_pe_0[] = {
 	{ 0x41980c,   1, 0x04, 0x00000010 },
 	{ 0x419844,   1, 0x04, 0x00000000 },
 	{ 0x419850,   1, 0x04, 0x00000004 },
 	{ 0x419854,   2, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nve4_graph_init_l1c_0[] = {
 	{ 0x419c98,   1, 0x04, 0x00000000 },
 	{ 0x419ca8,   1, 0x04, 0x00000000 },
 	{ 0x419cb0,   1, 0x04, 0x01000000 },
@@ -141,39 +120,25 @@ nve4_graph_init_tpc[] = {
 	{ 0x419cbc,   1, 0x04, 0x28137646 },
 	{ 0x419cc0,   2, 0x04, 0x00000000 },
 	{ 0x419c80,   1, 0x04, 0x00020232 },
-	{ 0x419c0c,   1, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nve4_graph_init_sm_0[] = {
 	{ 0x419e00,   1, 0x04, 0x00000000 },
 	{ 0x419ea0,   1, 0x04, 0x00000000 },
 	{ 0x419ee4,   1, 0x04, 0x00000000 },
 	{ 0x419ea4,   1, 0x04, 0x00000100 },
 	{ 0x419ea8,   1, 0x04, 0x00000000 },
-	{ 0x419eb4,   1, 0x04, 0x00000000 },
-	{ 0x419eb8,   3, 0x04, 0x00000000 },
+	{ 0x419eb4,   4, 0x04, 0x00000000 },
 	{ 0x419edc,   1, 0x04, 0x00000000 },
 	{ 0x419f00,   1, 0x04, 0x00000000 },
 	{ 0x419f74,   1, 0x04, 0x00000555 },
 	{}
 };
 
-struct nvc0_graph_init
-nve4_graph_init_unk[] = {
-	{ 0x41be04,   1, 0x04, 0x00000000 },
-	{ 0x41be08,   1, 0x04, 0x00000004 },
-	{ 0x41be0c,   1, 0x04, 0x00000000 },
-	{ 0x41be10,   1, 0x04, 0x003b8bc7 },
-	{ 0x41be14,   2, 0x04, 0x00000000 },
-	{ 0x41bfd4,   1, 0x04, 0x00800000 },
-	{ 0x41bfdc,   1, 0x04, 0x00000000 },
-	{ 0x41bff8,   1, 0x04, 0x00000000 },
-	{ 0x41bffc,   1, 0x04, 0x00000000 },
-	{ 0x41becc,   1, 0x04, 0x00000000 },
-	{ 0x41bee8,   1, 0x04, 0x00000000 },
-	{ 0x41beec,   1, 0x04, 0x00000000 },
-	{}
-};
-
-struct nvc0_graph_init
-nve4_graph_init_unk88xx[] = {
+const struct nvc0_graph_init
+nve4_graph_init_be_0[] = {
 	{ 0x40880c,   1, 0x04, 0x00000000 },
 	{ 0x408850,   1, 0x04, 0x00000004 },
 	{ 0x408910,   9, 0x04, 0x00000000 },
@@ -186,6 +151,67 @@ nve4_graph_init_unk88xx[] = {
 	{}
 };
 
+static const struct nvc0_graph_pack
+nve4_graph_pack_mmio[] = {
+	{ nve4_graph_init_main_0 },
+	{ nvc0_graph_init_fe_0 },
+	{ nvc0_graph_init_pri_0 },
+	{ nvc0_graph_init_rstr2d_0 },
+	{ nvd9_graph_init_pd_0 },
+	{ nve4_graph_init_ds_0 },
+	{ nvc0_graph_init_scc_0 },
+	{ nve4_graph_init_sked_0 },
+	{ nve4_graph_init_cwd_0 },
+	{ nvd9_graph_init_prop_0 },
+	{ nvc1_graph_init_gpc_unk_0 },
+	{ nvc0_graph_init_setup_0 },
+	{ nvc0_graph_init_crstr_0 },
+	{ nvc1_graph_init_setup_1 },
+	{ nvc0_graph_init_zcull_0 },
+	{ nvd9_graph_init_gpm_0 },
+	{ nve4_graph_init_gpc_unk_1 },
+	{ nvc0_graph_init_gcc_0 },
+	{ nve4_graph_init_tpccs_0 },
+	{ nvd9_graph_init_tex_0 },
+	{ nve4_graph_init_pe_0 },
+	{ nve4_graph_init_l1c_0 },
+	{ nvc0_graph_init_mpc_0 },
+	{ nve4_graph_init_sm_0 },
+	{ nvd7_graph_init_pes_0 },
+	{ nvd7_graph_init_wwdx_0 },
+	{ nvd7_graph_init_cbm_0 },
+	{ nve4_graph_init_be_0 },
+	{ nvc0_graph_init_fe_1 },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
+static int
+nve4_graph_fini(struct nouveau_object *object, bool suspend)
+{
+	struct nvc0_graph_priv *priv = (void *)object;
+
+	/*XXX: this is a nasty hack to power on gr on certain boards
+	 *     where it's disabled by therm, somehow.  ideally it'd
+	 *     be nice to know when we should be doing this, and why,
+	 *     but, it's yet to be determined.  for now we test for
+	 *     the particular mmio error that occurs in the situation,
+	 *     and then bash therm in the way nvidia do.
+	 */
+	nv_mask(priv, 0x000200, 0x08001000, 0x08001000);
+	nv_rd32(priv, 0x000200);
+	if (nv_rd32(priv, 0x400700) == 0xbadf1000) {
+		nv_mask(priv, 0x000200, 0x08001000, 0x00000000);
+		nv_rd32(priv, 0x000200);
+		nv_mask(priv, 0x020004, 0xc0000000, 0x40000000);
+	}
+
+	return nouveau_graph_fini(&priv->base, suspend);
+}
+
 int
 nve4_graph_init(struct nouveau_object *object)
 {
@@ -210,8 +236,7 @@ nve4_graph_init(struct nouveau_object *object)
 	nv_wr32(priv, GPC_BCAST(0x08b4), priv->unk4188b4->addr >> 8);
 	nv_wr32(priv, GPC_BCAST(0x08b8), priv->unk4188b8->addr >> 8);
 
-	for (i = 0; oclass->mmio[i]; i++)
-		nvc0_graph_mmio(priv, oclass->mmio[i]);
+	nvc0_graph_mmio(priv, oclass->mmio);
 
 	nv_wr32(priv, GPC_UNIT(0, 0x3018), 0x00000001);
 
@@ -298,25 +323,6 @@ nve4_graph_init(struct nouveau_object *object)
 	return nvc0_graph_init_ctxctl(priv);
 }
 
-static struct nvc0_graph_init *
-nve4_graph_init_mmio[] = {
-	nve4_graph_init_regs,
-	nvc0_graph_init_unk40xx,
-	nvc0_graph_init_unk44xx,
-	nvc0_graph_init_unk78xx,
-	nvc0_graph_init_unk60xx,
-	nvd9_graph_init_unk64xx,
-	nve4_graph_init_unk58xx,
-	nvc0_graph_init_unk80xx,
-	nve4_graph_init_unk70xx,
-	nve4_graph_init_unk5bxx,
-	nve4_graph_init_gpc,
-	nve4_graph_init_tpc,
-	nve4_graph_init_unk,
-	nve4_graph_init_unk88xx,
-	NULL
-};
-
 #include "fuc/hubnve0.fuc.h"
 
 static struct nvc0_graph_ucode
@@ -344,11 +350,11 @@ nve4_graph_oclass = &(struct nvc0_graph_oclass) {
 		.ctor = nvc0_graph_ctor,
 		.dtor = nvc0_graph_dtor,
 		.init = nve4_graph_init,
-		.fini = _nouveau_graph_fini,
+		.fini = nve4_graph_fini,
 	},
 	.cclass = &nve4_grctx_oclass,
 	.sclass = nve4_graph_sclass,
-	.mmio = nve4_graph_init_mmio,
+	.mmio = nve4_graph_pack_mmio,
 	.fecs.ucode = &nve4_graph_fecs_ucode,
 	.gpccs.ucode = &nve4_graph_gpccs_ucode,
 }.base;

+ 66 - 70
drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c

@@ -23,6 +23,7 @@
  */
 
 #include "nvc0.h"
+#include "ctxnvc0.h"
 
 /*******************************************************************************
  * Graphics object classes
@@ -38,86 +39,57 @@ nvf0_graph_sclass[] = {
 };
 
 /*******************************************************************************
- * PGRAPH engine/subdev functions
+ * PGRAPH register lists
  ******************************************************************************/
 
-struct nvc0_graph_init
-nvf0_graph_init_unk40xx[] = {
+const struct nvc0_graph_init
+nvf0_graph_init_fe_0[] = {
 	{ 0x40415c,   1, 0x04, 0x00000000 },
 	{ 0x404170,   1, 0x04, 0x00000000 },
 	{ 0x4041b4,   1, 0x04, 0x00000000 },
 	{}
 };
 
-static struct nvc0_graph_init
-nvf0_graph_init_unk58xx[] = {
+static const struct nvc0_graph_init
+nvf0_graph_init_ds_0[] = {
 	{ 0x405844,   1, 0x04, 0x00ffffff },
 	{ 0x405850,   1, 0x04, 0x00000000 },
 	{ 0x405900,   1, 0x04, 0x0000ff00 },
 	{ 0x405908,   1, 0x04, 0x00000000 },
-	{ 0x405928,   1, 0x04, 0x00000000 },
-	{ 0x40592c,   1, 0x04, 0x00000000 },
+	{ 0x405928,   2, 0x04, 0x00000000 },
 	{}
 };
 
-struct nvc0_graph_init
-nvf0_graph_init_unk70xx[] = {
+const struct nvc0_graph_init
+nvf0_graph_init_sked_0[] = {
 	{ 0x407010,   1, 0x04, 0x00000000 },
 	{ 0x407040,   1, 0x04, 0x80440424 },
 	{ 0x407048,   1, 0x04, 0x0000000a },
 	{}
 };
 
-struct nvc0_graph_init
-nvf0_graph_init_unk5bxx[] = {
+const struct nvc0_graph_init
+nvf0_graph_init_cwd_0[] = {
 	{ 0x405b44,   1, 0x04, 0x00000000 },
 	{ 0x405b50,   1, 0x04, 0x00000000 },
 	{}
 };
 
-static struct nvc0_graph_init
-nvf0_graph_init_gpc[] = {
-	{ 0x418408,   1, 0x04, 0x00000000 },
-	{ 0x4184a0,   1, 0x04, 0x00000000 },
-	{ 0x4184a4,   2, 0x04, 0x00000000 },
-	{ 0x418604,   1, 0x04, 0x00000000 },
-	{ 0x418680,   1, 0x04, 0x00000000 },
-	{ 0x418714,   1, 0x04, 0x00000000 },
-	{ 0x418384,   1, 0x04, 0x00000000 },
-	{ 0x418814,   3, 0x04, 0x00000000 },
-	{ 0x418b04,   1, 0x04, 0x00000000 },
-	{ 0x4188c8,   2, 0x04, 0x00000000 },
-	{ 0x4188d0,   1, 0x04, 0x00010000 },
-	{ 0x4188d4,   1, 0x04, 0x00000001 },
-	{ 0x418910,   1, 0x04, 0x00010001 },
-	{ 0x418914,   1, 0x04, 0x00000301 },
-	{ 0x418918,   1, 0x04, 0x00800000 },
-	{ 0x418980,   1, 0x04, 0x77777770 },
-	{ 0x418984,   3, 0x04, 0x77777777 },
-	{ 0x418c04,   1, 0x04, 0x00000000 },
-	{ 0x418c64,   1, 0x04, 0x00000000 },
-	{ 0x418c68,   1, 0x04, 0x00000000 },
-	{ 0x418c88,   1, 0x04, 0x00000000 },
-	{ 0x418cb4,   2, 0x04, 0x00000000 },
+const struct nvc0_graph_init
+nvf0_graph_init_gpc_unk_1[] = {
 	{ 0x418d00,   1, 0x04, 0x00000000 },
-	{ 0x418d28,   1, 0x04, 0x00000000 },
-	{ 0x418d2c,   1, 0x04, 0x00000000 },
+	{ 0x418d28,   2, 0x04, 0x00000000 },
 	{ 0x418f00,   1, 0x04, 0x00000400 },
 	{ 0x418f08,   1, 0x04, 0x00000000 },
-	{ 0x418f20,   1, 0x04, 0x00000000 },
-	{ 0x418f24,   1, 0x04, 0x00000000 },
+	{ 0x418f20,   2, 0x04, 0x00000000 },
 	{ 0x418e00,   1, 0x04, 0x00000000 },
 	{ 0x418e08,   1, 0x04, 0x00000000 },
 	{ 0x418e1c,   2, 0x04, 0x00000000 },
-	{ 0x41900c,   1, 0x04, 0x00000000 },
-	{ 0x419018,   1, 0x04, 0x00000000 },
 	{}
 };
 
-struct nvc0_graph_init
-nvf0_graph_init_tpc[] = {
-	{ 0x419d0c,   1, 0x04, 0x00000000 },
-	{ 0x419d10,   1, 0x04, 0x00000014 },
+static const struct nvc0_graph_init
+nvf0_graph_init_tex_0[] = {
 	{ 0x419ab0,   1, 0x04, 0x00000000 },
 	{ 0x419ac8,   1, 0x04, 0x00000000 },
 	{ 0x419ab8,   1, 0x04, 0x000000e7 },
@@ -125,10 +97,11 @@ nvf0_graph_init_tpc[] = {
 	{ 0x419abc,   2, 0x04, 0x00000000 },
 	{ 0x419ab4,   1, 0x04, 0x00000000 },
 	{ 0x419aa8,   2, 0x04, 0x00000000 },
-	{ 0x41980c,   1, 0x04, 0x00000010 },
-	{ 0x419844,   1, 0x04, 0x00000000 },
-	{ 0x419850,   1, 0x04, 0x00000004 },
-	{ 0x419854,   2, 0x04, 0x00000000 },
+	{}
+};
+
+static const struct nvc0_graph_init
+nvf0_graph_init_l1c_0[] = {
 	{ 0x419c98,   1, 0x04, 0x00000000 },
 	{ 0x419ca8,   1, 0x04, 0x00000000 },
 	{ 0x419cb0,   1, 0x04, 0x01000000 },
@@ -139,7 +112,11 @@ nvf0_graph_init_tpc[] = {
 	{ 0x419cc0,   2, 0x04, 0x00000000 },
 	{ 0x419c80,   1, 0x04, 0x00020230 },
 	{ 0x419ccc,   2, 0x04, 0x00000000 },
-	{ 0x419c0c,   1, 0x04, 0x00000000 },
+	{}
+};
+
+const struct nvc0_graph_init
+nvf0_graph_init_sm_0[] = {
 	{ 0x419e00,   1, 0x04, 0x00000080 },
 	{ 0x419ea0,   1, 0x04, 0x00000000 },
 	{ 0x419ee4,   1, 0x04, 0x00000000 },
@@ -155,6 +132,44 @@ nvf0_graph_init_tpc[] = {
 	{}
 };
 
+static const struct nvc0_graph_pack
+nvf0_graph_pack_mmio[] = {
+	{ nve4_graph_init_main_0 },
+	{ nvf0_graph_init_fe_0 },
+	{ nvc0_graph_init_pri_0 },
+	{ nvc0_graph_init_rstr2d_0 },
+	{ nvd9_graph_init_pd_0 },
+	{ nvf0_graph_init_ds_0 },
+	{ nvc0_graph_init_scc_0 },
+	{ nvf0_graph_init_sked_0 },
+	{ nvf0_graph_init_cwd_0 },
+	{ nvd9_graph_init_prop_0 },
+	{ nvc1_graph_init_gpc_unk_0 },
+	{ nvc0_graph_init_setup_0 },
+	{ nvc0_graph_init_crstr_0 },
+	{ nvc1_graph_init_setup_1 },
+	{ nvc0_graph_init_zcull_0 },
+	{ nvd9_graph_init_gpm_0 },
+	{ nvf0_graph_init_gpc_unk_1 },
+	{ nvc0_graph_init_gcc_0 },
+	{ nve4_graph_init_tpccs_0 },
+	{ nvf0_graph_init_tex_0 },
+	{ nve4_graph_init_pe_0 },
+	{ nvf0_graph_init_l1c_0 },
+	{ nvc0_graph_init_mpc_0 },
+	{ nvf0_graph_init_sm_0 },
+	{ nvd7_graph_init_pes_0 },
+	{ nvd7_graph_init_wwdx_0 },
+	{ nvd7_graph_init_cbm_0 },
+	{ nve4_graph_init_be_0 },
+	{ nvc0_graph_init_fe_1 },
+	{}
+};
+
+/*******************************************************************************
+ * PGRAPH engine/subdev functions
+ ******************************************************************************/
+
 static int
 nvf0_graph_fini(struct nouveau_object *object, bool suspend)
 {
@@ -192,25 +207,6 @@ nvf0_graph_fini(struct nouveau_object *object, bool suspend)
 	return nouveau_graph_fini(&priv->base, suspend);
 }
 
-static struct nvc0_graph_init *
-nvf0_graph_init_mmio[] = {
-	nve4_graph_init_regs,
-	nvf0_graph_init_unk40xx,
-	nvc0_graph_init_unk44xx,
-	nvc0_graph_init_unk78xx,
-	nvc0_graph_init_unk60xx,
-	nvd9_graph_init_unk64xx,
-	nvf0_graph_init_unk58xx,
-	nvc0_graph_init_unk80xx,
-	nvf0_graph_init_unk70xx,
-	nvf0_graph_init_unk5bxx,
-	nvf0_graph_init_gpc,
-	nvf0_graph_init_tpc,
-	nve4_graph_init_unk,
-	nve4_graph_init_unk88xx,
-	NULL
-};
-
 #include "fuc/hubnvf0.fuc.h"
 
 static struct nvc0_graph_ucode
@@ -242,7 +238,7 @@ nvf0_graph_oclass = &(struct nvc0_graph_oclass) {
 	},
 	.cclass = &nvf0_grctx_oclass,
 	.sclass =  nvf0_graph_sclass,
-	.mmio = nvf0_graph_init_mmio,
+	.mmio = nvf0_graph_pack_mmio,
 	.fecs.ucode = &nvf0_graph_fecs_ucode,
 	.gpccs.ucode = &nvf0_graph_gpccs_ucode,
 }.base;

+ 1 - 1
drivers/gpu/drm/nouveau/core/engine/xtensa.c

@@ -112,7 +112,7 @@ _nouveau_xtensa_init(struct nouveau_object *object)
 		snprintf(name, sizeof(name), "nouveau/nv84_xuc%03x",
 			 xtensa->addr >> 12);
 
-		ret = request_firmware(&fw, name, &device->pdev->dev);
+		ret = request_firmware(&fw, name, nv_device_base(device));
 		if (ret) {
 			nv_warn(xtensa, "unable to load firmware %s\n", name);
 			return ret;

+ 12 - 0
drivers/gpu/drm/nouveau/core/include/core/class.h

@@ -258,6 +258,7 @@ struct nv04_display_scanoutpos {
  * 9070: NVD0_DISP
  * 9170: NVE0_DISP
  * 9270: NVF0_DISP
+ * 9470: GM107_DISP
  */
 
 #define NV50_DISP_CLASS                                              0x00005070
@@ -268,6 +269,7 @@ struct nv04_display_scanoutpos {
 #define NVD0_DISP_CLASS                                              0x00009070
 #define NVE0_DISP_CLASS                                              0x00009170
 #define NVF0_DISP_CLASS                                              0x00009270
+#define GM107_DISP_CLASS                                             0x00009470
 
 #define NV50_DISP_MTHD                                               0x00000000
 #define NV50_DISP_MTHD_HEAD                                          0x00000003
@@ -342,6 +344,7 @@ struct nv50_display_class {
  * 907a: NVD0_DISP_CURS
  * 917a: NVE0_DISP_CURS
  * 927a: NVF0_DISP_CURS
+ * 947a: GM107_DISP_CURS
  */
 
 #define NV50_DISP_CURS_CLASS                                         0x0000507a
@@ -352,6 +355,7 @@ struct nv50_display_class {
 #define NVD0_DISP_CURS_CLASS                                         0x0000907a
 #define NVE0_DISP_CURS_CLASS                                         0x0000917a
 #define NVF0_DISP_CURS_CLASS                                         0x0000927a
+#define GM107_DISP_CURS_CLASS                                        0x0000947a
 
 struct nv50_display_curs_class {
 	u32 head;
@@ -365,6 +369,7 @@ struct nv50_display_curs_class {
  * 907b: NVD0_DISP_OIMM
  * 917b: NVE0_DISP_OIMM
  * 927b: NVE0_DISP_OIMM
+ * 947b: GM107_DISP_OIMM
  */
 
 #define NV50_DISP_OIMM_CLASS                                         0x0000507b
@@ -375,6 +380,7 @@ struct nv50_display_curs_class {
 #define NVD0_DISP_OIMM_CLASS                                         0x0000907b
 #define NVE0_DISP_OIMM_CLASS                                         0x0000917b
 #define NVF0_DISP_OIMM_CLASS                                         0x0000927b
+#define GM107_DISP_OIMM_CLASS                                        0x0000947b
 
 struct nv50_display_oimm_class {
 	u32 head;
@@ -388,6 +394,7 @@ struct nv50_display_oimm_class {
  * 907c: NVD0_DISP_SYNC
  * 917c: NVE0_DISP_SYNC
  * 927c: NVF0_DISP_SYNC
+ * 947c: GM107_DISP_SYNC
  */
 
 #define NV50_DISP_SYNC_CLASS                                         0x0000507c
@@ -398,6 +405,7 @@ struct nv50_display_oimm_class {
 #define NVD0_DISP_SYNC_CLASS                                         0x0000907c
 #define NVE0_DISP_SYNC_CLASS                                         0x0000917c
 #define NVF0_DISP_SYNC_CLASS                                         0x0000927c
+#define GM107_DISP_SYNC_CLASS                                        0x0000947c
 
 struct nv50_display_sync_class {
 	u32 pushbuf;
@@ -412,6 +420,7 @@ struct nv50_display_sync_class {
  * 907d: NVD0_DISP_MAST
  * 917d: NVE0_DISP_MAST
  * 927d: NVF0_DISP_MAST
+ * 947d: GM107_DISP_MAST
  */
 
 #define NV50_DISP_MAST_CLASS                                         0x0000507d
@@ -422,6 +431,7 @@ struct nv50_display_sync_class {
 #define NVD0_DISP_MAST_CLASS                                         0x0000907d
 #define NVE0_DISP_MAST_CLASS                                         0x0000917d
 #define NVF0_DISP_MAST_CLASS                                         0x0000927d
+#define GM107_DISP_MAST_CLASS                                        0x0000947d
 
 struct nv50_display_mast_class {
 	u32 pushbuf;
@@ -435,6 +445,7 @@ struct nv50_display_mast_class {
  * 907e: NVD0_DISP_OVLY
  * 917e: NVE0_DISP_OVLY
  * 927e: NVF0_DISP_OVLY
+ * 947e: GM107_DISP_OVLY
  */
 
 #define NV50_DISP_OVLY_CLASS                                         0x0000507e
@@ -445,6 +456,7 @@ struct nv50_display_mast_class {
 #define NVD0_DISP_OVLY_CLASS                                         0x0000907e
 #define NVE0_DISP_OVLY_CLASS                                         0x0000917e
 #define NVF0_DISP_OVLY_CLASS                                         0x0000927e
+#define GM107_DISP_OVLY_CLASS                                        0x0000947e
 
 struct nv50_display_ovly_class {
 	u32 pushbuf;

+ 31 - 0
drivers/gpu/drm/nouveau/core/include/core/device.h

@@ -40,6 +40,7 @@ enum nv_subdev_type {
 
 	NVDEV_ENGINE_FIRST,
 	NVDEV_ENGINE_DMAOBJ = NVDEV_ENGINE_FIRST,
+	NVDEV_ENGINE_IFB,
 	NVDEV_ENGINE_FIFO,
 	NVDEV_ENGINE_SW,
 	NVDEV_ENGINE_GR,
@@ -65,6 +66,7 @@ struct nouveau_device {
 	struct list_head head;
 
 	struct pci_dev *pdev;
+	struct platform_device *platformdev;
 	u64 handle;
 
 	const char *cfgopt;
@@ -84,6 +86,7 @@ struct nouveau_device {
 		NV_C0    = 0xc0,
 		NV_D0    = 0xd0,
 		NV_E0    = 0xe0,
+		GM100    = 0x110,
 	} card_type;
 	u32 chipset;
 	u32 crystal;
@@ -140,4 +143,32 @@ nv_device_match(struct nouveau_object *object, u16 dev, u16 ven, u16 sub)
 	       device->pdev->subsystem_device == sub;
 }
 
+static inline bool
+nv_device_is_pci(struct nouveau_device *device)
+{
+	return device->pdev != NULL;
+}
+
+static inline struct device *
+nv_device_base(struct nouveau_device *device)
+{
+	return nv_device_is_pci(device) ? &device->pdev->dev :
+					  &device->platformdev->dev;
+}
+
+resource_size_t
+nv_device_resource_start(struct nouveau_device *device, unsigned int bar);
+
+resource_size_t
+nv_device_resource_len(struct nouveau_device *device, unsigned int bar);
+
+dma_addr_t
+nv_device_map_page(struct nouveau_device *device, struct page *page);
+
+void
+nv_device_unmap_page(struct nouveau_device *device, dma_addr_t addr);
+
+int
+nv_device_get_irq(struct nouveau_device *device, bool stall);
+
 #endif

+ 1 - 1
drivers/gpu/drm/nouveau/core/include/core/namedb.h

@@ -33,7 +33,7 @@ nv_namedb(void *obj)
 
 int  nouveau_namedb_create_(struct nouveau_object *, struct nouveau_object *,
 			    struct nouveau_oclass *, u32 pclass,
-			    struct nouveau_oclass *, u32 engcls,
+			    struct nouveau_oclass *, u64 engcls,
 			    int size, void **);
 
 int  _nouveau_namedb_ctor(struct nouveau_object *, struct nouveau_object *,

+ 14 - 4
drivers/gpu/drm/nouveau/core/include/engine/device.h

@@ -3,11 +3,20 @@
 
 #include <core/device.h>
 
-#define nouveau_device_create(p,n,s,c,d,u)                                     \
-	nouveau_device_create_((p), (n), (s), (c), (d), sizeof(**u), (void **)u)
+struct platform_device;
 
-int  nouveau_device_create_(struct pci_dev *, u64 name, const char *sname,
-			    const char *cfg, const char *dbg, int, void **);
+enum nv_bus_type {
+	NOUVEAU_BUS_PCI,
+	NOUVEAU_BUS_PLATFORM,
+};
+
+#define nouveau_device_create(p,t,n,s,c,d,u)                                   \
+	nouveau_device_create_((void *)(p), (t), (n), (s), (c), (d),           \
+			       sizeof(**u), (void **)u)
+
+int  nouveau_device_create_(void *, enum nv_bus_type type, u64 name,
+			    const char *sname, const char *cfg, const char *dbg,
+			    int, void **);
 
 int nv04_identify(struct nouveau_device *);
 int nv10_identify(struct nouveau_device *);
@@ -17,6 +26,7 @@ int nv40_identify(struct nouveau_device *);
 int nv50_identify(struct nouveau_device *);
 int nvc0_identify(struct nouveau_device *);
 int nve0_identify(struct nouveau_device *);
+int gm100_identify(struct nouveau_device *);
 
 struct nouveau_device *nouveau_device_find(u64 name);
 

+ 10 - 9
drivers/gpu/drm/nouveau/core/include/engine/disp.h

@@ -36,14 +36,15 @@ void _nouveau_disp_dtor(struct nouveau_object *);
 #define _nouveau_disp_init _nouveau_engine_init
 #define _nouveau_disp_fini _nouveau_engine_fini
 
-extern struct nouveau_oclass nv04_disp_oclass;
-extern struct nouveau_oclass nv50_disp_oclass;
-extern struct nouveau_oclass nv84_disp_oclass;
-extern struct nouveau_oclass nva0_disp_oclass;
-extern struct nouveau_oclass nv94_disp_oclass;
-extern struct nouveau_oclass nva3_disp_oclass;
-extern struct nouveau_oclass nvd0_disp_oclass;
-extern struct nouveau_oclass nve0_disp_oclass;
-extern struct nouveau_oclass nvf0_disp_oclass;
+extern struct nouveau_oclass *nv04_disp_oclass;
+extern struct nouveau_oclass *nv50_disp_oclass;
+extern struct nouveau_oclass *nv84_disp_oclass;
+extern struct nouveau_oclass *nva0_disp_oclass;
+extern struct nouveau_oclass *nv94_disp_oclass;
+extern struct nouveau_oclass *nva3_disp_oclass;
+extern struct nouveau_oclass *nvd0_disp_oclass;
+extern struct nouveau_oclass *nve0_disp_oclass;
+extern struct nouveau_oclass *nvf0_disp_oclass;
+extern struct nouveau_oclass *gm107_disp_oclass;
 
 #endif

+ 2 - 1
drivers/gpu/drm/nouveau/core/include/engine/graph.h

@@ -63,13 +63,14 @@ extern struct nouveau_oclass nv40_graph_oclass;
 extern struct nouveau_oclass nv50_graph_oclass;
 extern struct nouveau_oclass *nvc0_graph_oclass;
 extern struct nouveau_oclass *nvc1_graph_oclass;
-extern struct nouveau_oclass *nvc3_graph_oclass;
+extern struct nouveau_oclass *nvc4_graph_oclass;
 extern struct nouveau_oclass *nvc8_graph_oclass;
 extern struct nouveau_oclass *nvd7_graph_oclass;
 extern struct nouveau_oclass *nvd9_graph_oclass;
 extern struct nouveau_oclass *nve4_graph_oclass;
 extern struct nouveau_oclass *nvf0_graph_oclass;
 extern struct nouveau_oclass *nv108_graph_oclass;
+extern struct nouveau_oclass *gm107_graph_oclass;
 
 extern const struct nouveau_bitfield nv04_graph_nsource[];
 extern struct nouveau_ofuncs nv04_graph_ofuncs;

+ 23 - 0
drivers/gpu/drm/nouveau/core/include/subdev/bios/P0260.h

@@ -0,0 +1,23 @@
+#ifndef __NVBIOS_P0260_H__
+#define __NVBIOS_P0260_H__
+
+u32 nvbios_P0260Te(struct nouveau_bios *,
+		   u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz);
+
+struct nvbios_P0260E {
+	u32 data;
+};
+
+u32 nvbios_P0260Ee(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr);
+u32 nvbios_P0260Ep(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr,
+		   struct nvbios_P0260E *);
+
+struct nvbios_P0260X {
+	u32 data;
+};
+
+u32 nvbios_P0260Xe(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr);
+u32 nvbios_P0260Xp(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr,
+		   struct nvbios_P0260X *);
+
+#endif

+ 1 - 0
drivers/gpu/drm/nouveau/core/include/subdev/bios/conn.h

@@ -16,6 +16,7 @@ enum dcb_connector_type {
 	DCB_CONNECTOR_eDP = 0x47,
 	DCB_CONNECTOR_HDMI_0 = 0x60,
 	DCB_CONNECTOR_HDMI_1 = 0x61,
+	DCB_CONNECTOR_HDMI_C = 0x63,
 	DCB_CONNECTOR_DMS59_DP0 = 0x64,
 	DCB_CONNECTOR_DMS59_DP1 = 0x65,
 	DCB_CONNECTOR_NONE = 0xff

+ 1 - 1
drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h

@@ -61,6 +61,6 @@ struct nvbios_ramcfg {
 };
 
 u8 nvbios_ramcfg_count(struct nouveau_bios *);
-u8 nvbios_ramcfg_index(struct nouveau_bios *);
+u8 nvbios_ramcfg_index(struct nouveau_subdev *);
 
 #endif

+ 7 - 0
drivers/gpu/drm/nouveau/core/include/subdev/bios/therm.h

@@ -31,6 +31,12 @@ struct nouveau_therm_trip_point {
 	int hysteresis;
 };
 
+enum nvbios_therm_fan_mode {
+	NVBIOS_THERM_FAN_TRIP = 0,
+	NVBIOS_THERM_FAN_LINEAR = 1,
+	NVBIOS_THERM_FAN_OTHER = 2,
+};
+
 struct nvbios_therm_fan {
 	u16 pwm_freq;
 
@@ -40,6 +46,7 @@ struct nvbios_therm_fan {
 	u16 bump_period;
 	u16 slow_down_period;
 
+	enum nvbios_therm_fan_mode fan_mode;
 	struct nouveau_therm_trip_point trip[NOUVEAU_TEMP_FAN_TRIP_MAX];
 	u8 nr_fan_trip;
 	u8 linear_min_temp;

+ 2 - 0
drivers/gpu/drm/nouveau/core/include/subdev/devinit.h

@@ -9,6 +9,7 @@ struct nouveau_devinit {
 	bool post;
 	void (*meminit)(struct nouveau_devinit *);
 	int  (*pll_set)(struct nouveau_devinit *, u32 type, u32 freq);
+	u32  (*mmio)(struct nouveau_devinit *, u32 addr);
 };
 
 static inline struct nouveau_devinit *
@@ -28,5 +29,6 @@ extern struct nouveau_oclass *nv98_devinit_oclass;
 extern struct nouveau_oclass *nva3_devinit_oclass;
 extern struct nouveau_oclass *nvaf_devinit_oclass;
 extern struct nouveau_oclass *nvc0_devinit_oclass;
+extern struct nouveau_oclass *gm107_devinit_oclass;
 
 #endif

+ 1 - 0
drivers/gpu/drm/nouveau/core/include/subdev/fb.h

@@ -105,6 +105,7 @@ extern struct nouveau_oclass *nvaa_fb_oclass;
 extern struct nouveau_oclass *nvaf_fb_oclass;
 extern struct nouveau_oclass *nvc0_fb_oclass;
 extern struct nouveau_oclass *nve0_fb_oclass;
+extern struct nouveau_oclass *gm107_fb_oclass;
 
 #include <subdev/bios/ramcfg.h>
 

+ 2 - 1
drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h

@@ -35,6 +35,7 @@ nouveau_ltcg(void *obj)
 #define _nouveau_ltcg_init _nouveau_subdev_init
 #define _nouveau_ltcg_fini _nouveau_subdev_fini
 
-extern struct nouveau_oclass nvc0_ltcg_oclass;
+extern struct nouveau_oclass *gf100_ltcg_oclass;
+extern struct nouveau_oclass *gm107_ltcg_oclass;
 
 #endif

+ 1 - 0
drivers/gpu/drm/nouveau/core/include/subdev/mc.h

@@ -12,6 +12,7 @@ struct nouveau_mc_intr {
 struct nouveau_mc {
 	struct nouveau_subdev base;
 	bool use_msi;
+	unsigned int irq;
 };
 
 static inline struct nouveau_mc *

+ 1 - 1
drivers/gpu/drm/nouveau/core/include/subdev/therm.h

@@ -31,7 +31,7 @@ struct nouveau_therm {
 	int (*pwm_ctrl)(struct nouveau_therm *, int line, bool);
 	int (*pwm_get)(struct nouveau_therm *, int line, u32 *, u32 *);
 	int (*pwm_set)(struct nouveau_therm *, int line, u32, u32);
-	int (*pwm_clock)(struct nouveau_therm *);
+	int (*pwm_clock)(struct nouveau_therm *, int line);
 
 	int (*fan_get)(struct nouveau_therm *);
 	int (*fan_set)(struct nouveau_therm *, int);

+ 1 - 0
drivers/gpu/drm/nouveau/core/include/subdev/timer.h

@@ -59,5 +59,6 @@ int nouveau_timer_create_(struct nouveau_object *, struct nouveau_engine *,
 			  struct nouveau_oclass *, int size, void **);
 
 extern struct nouveau_oclass nv04_timer_oclass;
+extern struct nouveau_oclass gk20a_timer_oclass;
 
 #endif

+ 1 - 11
drivers/gpu/drm/nouveau/core/os.h

@@ -5,6 +5,7 @@
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/pci.h>
+#include <linux/platform_device.h>
 #include <linux/printk.h>
 #include <linux/bitops.h>
 #include <linux/firmware.h>
@@ -23,17 +24,6 @@
 
 #include <asm/unaligned.h>
 
-static inline int
-ffsll(u64 mask)
-{
-	int i;
-	for (i = 0; i < 64; i++) {
-		if (mask & (1ULL << i))
-			return i + 1;
-	}
-	return 0;
-}
-
 #ifndef ioread32_native
 #ifdef __BIG_ENDIAN
 #define ioread16_native ioread16be

+ 2 - 2
drivers/gpu/drm/nouveau/core/subdev/bar/base.c

@@ -118,8 +118,8 @@ nouveau_bar_create_(struct nouveau_object *parent,
 	if (ret)
 		return ret;
 
-	bar->iomem = ioremap(pci_resource_start(device->pdev, 3),
-			     pci_resource_len(device->pdev, 3));
+	bar->iomem = ioremap(nv_device_resource_start(device, 3),
+			     nv_device_resource_len(device, 3));
 	return 0;
 }
 

+ 5 - 3
drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c

@@ -139,7 +139,7 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 
 	/* BAR3 */
 	start = 0x0100000000ULL;
-	limit = start + pci_resource_len(device->pdev, 3);
+	limit = start + nv_device_resource_len(device, 3);
 
 	ret = nouveau_vm_new(device, start, limit, start, &vm);
 	if (ret)
@@ -173,7 +173,7 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 
 	/* BAR1 */
 	start = 0x0000000000ULL;
-	limit = start + pci_resource_len(device->pdev, 1);
+	limit = start + nv_device_resource_len(device, 1);
 
 	ret = nouveau_vm_new(device, start, limit--, start, &vm);
 	if (ret)
@@ -231,7 +231,7 @@ static int
 nv50_bar_init(struct nouveau_object *object)
 {
 	struct nv50_bar_priv *priv = (void *)object;
-	int ret;
+	int ret, i;
 
 	ret = nouveau_bar_init(&priv->base);
 	if (ret)
@@ -249,6 +249,8 @@ nv50_bar_init(struct nouveau_object *object)
 	nv_wr32(priv, 0x001704, 0x40000000 | priv->mem->addr >> 12);
 	nv_wr32(priv, 0x001708, 0x80000000 | priv->bar1->node->offset >> 4);
 	nv_wr32(priv, 0x00170c, 0x80000000 | priv->bar3->node->offset >> 4);
+	for (i = 0; i < 8; i++)
+		nv_wr32(priv, 0x001900 + (i * 4), 0x00000000);
 	return 0;
 }
 

+ 7 - 8
drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c

@@ -84,7 +84,6 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	      struct nouveau_object **pobject)
 {
 	struct nouveau_device *device = nv_device(parent);
-	struct pci_dev *pdev = device->pdev;
 	struct nvc0_bar_priv *priv;
 	struct nouveau_gpuobj *mem;
 	struct nouveau_vm *vm;
@@ -107,14 +106,14 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	if (ret)
 		return ret;
 
-	ret = nouveau_vm_new(device, 0, pci_resource_len(pdev, 3), 0, &vm);
+	ret = nouveau_vm_new(device, 0, nv_device_resource_len(device, 3), 0, &vm);
 	if (ret)
 		return ret;
 
 	atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
 
 	ret = nouveau_gpuobj_new(nv_object(priv), NULL,
-				 (pci_resource_len(pdev, 3) >> 12) * 8,
+				 (nv_device_resource_len(device, 3) >> 12) * 8,
 				 0x1000, NVOBJ_FLAG_ZERO_ALLOC,
 				 &vm->pgt[0].obj[0]);
 	vm->pgt[0].refcount[0] = 1;
@@ -128,8 +127,8 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 
 	nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[0].pgd->addr));
 	nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[0].pgd->addr));
-	nv_wo32(mem, 0x0208, lower_32_bits(pci_resource_len(pdev, 3) - 1));
-	nv_wo32(mem, 0x020c, upper_32_bits(pci_resource_len(pdev, 3) - 1));
+	nv_wo32(mem, 0x0208, lower_32_bits(nv_device_resource_len(device, 3) - 1));
+	nv_wo32(mem, 0x020c, upper_32_bits(nv_device_resource_len(device, 3) - 1));
 
 	/* BAR1 */
 	ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
@@ -143,7 +142,7 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 	if (ret)
 		return ret;
 
-	ret = nouveau_vm_new(device, 0, pci_resource_len(pdev, 1), 0, &vm);
+	ret = nouveau_vm_new(device, 0, nv_device_resource_len(device, 1), 0, &vm);
 	if (ret)
 		return ret;
 
@@ -156,8 +155,8 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
 
 	nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[1].pgd->addr));
 	nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[1].pgd->addr));
-	nv_wo32(mem, 0x0208, lower_32_bits(pci_resource_len(pdev, 1) - 1));
-	nv_wo32(mem, 0x020c, upper_32_bits(pci_resource_len(pdev, 1) - 1));
+	nv_wo32(mem, 0x0208, lower_32_bits(nv_device_resource_len(device, 1) - 1));
+	nv_wo32(mem, 0x020c, upper_32_bits(nv_device_resource_len(device, 1) - 1));
 
 	priv->base.alloc = nouveau_bar_alloc;
 	priv->base.kmap = nvc0_bar_kmap;

+ 109 - 0
drivers/gpu/drm/nouveau/core/subdev/bios/P0260.c

@@ -0,0 +1,109 @@
+/*
+ * Copyright 2013 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <subdev/bios.h>
+#include <subdev/bios/bit.h>
+#include <subdev/bios/ramcfg.h>
+#include <subdev/bios/P0260.h>
+
+u32
+nvbios_P0260Te(struct nouveau_bios *bios,
+	       u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz)
+{
+	struct bit_entry bit_P;
+	u32 data = 0x00000000;
+
+	if (!bit_entry(bios, 'P', &bit_P)) {
+		if (bit_P.version == 2 && bit_P.length > 0x63)
+			data = nv_ro32(bios, bit_P.offset + 0x60);
+		if (data) {
+			*ver = nv_ro08(bios, data + 0);
+			switch (*ver) {
+			case 0x10:
+				*hdr = nv_ro08(bios, data + 1);
+				*cnt = nv_ro08(bios, data + 2);
+				*len = 4;
+				*xnr = nv_ro08(bios, data + 3);
+				*xsz = 4;
+				return data;
+			default:
+				break;
+			}
+		}
+	}
+
+	return 0x00000000;
+}
+
+u32
+nvbios_P0260Ee(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len)
+{
+	u8  hdr, cnt, xnr, xsz;
+	u32 data = nvbios_P0260Te(bios, ver, &hdr, &cnt, len, &xnr, &xsz);
+	if (data && idx < cnt)
+		return data + hdr + (idx * *len);
+	return 0x00000000;
+}
+
+u32
+nvbios_P0260Ep(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len,
+	       struct nvbios_P0260E *info)
+{
+	u32 data = nvbios_P0260Ee(bios, idx, ver, len);
+	memset(info, 0x00, sizeof(*info));
+	switch (!!data * *ver) {
+	case 0x10:
+		info->data = nv_ro32(bios, data);
+		return data;
+	default:
+		break;
+	}
+	return 0x00000000;
+}
+
+u32
+nvbios_P0260Xe(struct nouveau_bios *bios, int idx, u8 *ver, u8 *xsz)
+{
+	u8  hdr, cnt, len, xnr;
+	u32 data = nvbios_P0260Te(bios, ver, &hdr, &cnt, &len, &xnr, xsz);
+	if (data && idx < xnr)
+		return data + hdr + (cnt * len) + (idx * *xsz);
+	return 0x00000000;
+}
+
+u32
+nvbios_P0260Xp(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr,
+	       struct nvbios_P0260X *info)
+{
+	u32 data = nvbios_P0260Xe(bios, idx, ver, hdr);
+	memset(info, 0x00, sizeof(*info));
+	switch (!!data * *ver) {
+	case 0x10:
+		info->data = nv_ro32(bios, data);
+		return data;
+	default:
+		break;
+	}
+	return 0x00000000;
+}

+ 38 - 17
drivers/gpu/drm/nouveau/core/subdev/bios/base.c

@@ -90,10 +90,26 @@ nouveau_bios_shadow_pramin(struct nouveau_bios *bios)
 	int i;
 
 	if (device->card_type >= NV_50) {
-		if (  device->card_type < NV_C0 ||
-		    !(nv_rd32(bios, 0x022500) & 0x00000001))
-			addr = (u64)(nv_rd32(bios, 0x619f04) & 0xffffff00) << 8;
+		if (device->card_type >= NV_C0 && device->card_type < GM100) {
+			if (nv_rd32(bios, 0x022500) & 0x00000001)
+				return;
+		} else
+		if (device->card_type >= GM100) {
+			if (nv_rd32(bios, 0x021c04) & 0x00000001)
+				return;
+		}
+
+		addr = nv_rd32(bios, 0x619f04);
+		if (!(addr & 0x00000008)) {
+			nv_debug(bios, "... not enabled\n");
+			return;
+		}
+		if ( (addr & 0x00000003) != 1) {
+			nv_debug(bios, "... not in vram\n");
+			return;
+		}
 
+		addr = (u64)(addr >> 8) << 8;
 		if (!addr) {
 			addr  = (u64)nv_rd32(bios, 0x001700) << 16;
 			addr += 0xf0000;
@@ -141,6 +157,10 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios)
 		pcireg = 0x001850;
 	access = nv_mask(bios, pcireg, 0x00000001, 0x00000000);
 
+	/* WARNING: PROM accesses should always be 32-bits aligned. Other
+	 * accesses work on most chipset but do not on Kepler chipsets
+	 */
+
 	/* bail if no rom signature, with a workaround for a PROM reading
 	 * issue on some chipsets.  the first read after a period of
 	 * inactivity returns the wrong result, so retry the first header
@@ -148,31 +168,32 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios)
 	 */
 	i = 16;
 	do {
-		if (nv_rd08(bios, 0x300000) == 0x55)
+		if ((nv_rd32(bios, 0x300000) & 0xffff) == 0xaa55)
 			break;
 	} while (i--);
 
-	if (!i || nv_rd08(bios, 0x300001) != 0xaa)
-		goto out;
-
-	/* additional check (see note below) - read PCI record header */
-	pcir = nv_rd08(bios, 0x300018) |
-	       nv_rd08(bios, 0x300019) << 8;
-	if (nv_rd08(bios, 0x300000 + pcir) != 'P' ||
-	    nv_rd08(bios, 0x300001 + pcir) != 'C' ||
-	    nv_rd08(bios, 0x300002 + pcir) != 'I' ||
-	    nv_rd08(bios, 0x300003 + pcir) != 'R')
+	if (!i)
 		goto out;
 
 	/* read entire bios image to system memory */
-	bios->size = nv_rd08(bios, 0x300002) * 512;
+	bios->size = ((nv_rd32(bios, 0x300000) >> 16) & 0xff) * 512;
 	if (!bios->size)
 		goto out;
 
 	bios->data = kmalloc(bios->size, GFP_KERNEL);
 	if (bios->data) {
-		for (i = 0; i < bios->size; i++)
-			nv_wo08(bios, i, nv_rd08(bios, 0x300000 + i));
+		for (i = 0; i < bios->size; i+=4)
+			nv_wo32(bios, i, nv_rd32(bios, 0x300000 + i));
+	}
+
+	/* check the PCI record header */
+	pcir = nv_ro16(bios, 0x0018);
+	if (bios->data[pcir + 0] != 'P' ||
+	    bios->data[pcir + 1] != 'C' ||
+	    bios->data[pcir + 2] != 'I' ||
+	    bios->data[pcir + 3] != 'R') {
+		bios->size = 0;
+		kfree(bios->data);
 	}
 
 out:

+ 28 - 1
drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c

@@ -142,9 +142,36 @@ dcb_outp_parse(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len,
 		if (*ver >= 0x40) {
 			u32 conf = nv_ro32(bios, dcb + 0x04);
 			switch (outp->type) {
+			case DCB_OUTPUT_DP:
+				switch (conf & 0x00e00000) {
+				case 0x00000000:
+					outp->dpconf.link_bw = 0x06;
+					break;
+				case 0x00200000:
+					outp->dpconf.link_bw = 0x0a;
+					break;
+				case 0x00400000:
+				default:
+					outp->dpconf.link_bw = 0x14;
+					break;
+				}
+
+				switch (conf & 0x0f000000) {
+				case 0x0f000000:
+					outp->dpconf.link_nr = 4;
+					break;
+				case 0x03000000:
+					outp->dpconf.link_nr = 2;
+					break;
+				case 0x01000000:
+				default:
+					outp->dpconf.link_nr = 1;
+					break;
+				}
+
+				/* fall-through... */
 			case DCB_OUTPUT_TMDS:
 			case DCB_OUTPUT_LVDS:
-			case DCB_OUTPUT_DP:
 				outp->link = (conf & 0x00000030) >> 4;
 				outp->sorconf.link = outp->link; /*XXX*/
 				outp->extdev = 0x00;

+ 11 - 7
drivers/gpu/drm/nouveau/core/subdev/bios/init.c

@@ -118,6 +118,8 @@ init_conn(struct nvbios_init *init)
 static inline u32
 init_nvreg(struct nvbios_init *init, u32 reg)
 {
+	struct nouveau_devinit *devinit = nouveau_devinit(init->bios);
+
 	/* C51 (at least) sometimes has the lower bits set which the VBIOS
 	 * interprets to mean that access needs to go through certain IO
 	 * ports instead.  The NVIDIA binary driver has been seen to access
@@ -147,6 +149,9 @@ init_nvreg(struct nvbios_init *init, u32 reg)
 
 	if (reg & ~0x00fffffc)
 		warn("unknown bits in register 0x%08x\n", reg);
+
+	if (devinit->mmio)
+		reg = devinit->mmio(devinit, reg);
 	return reg;
 }
 
@@ -154,7 +159,7 @@ static u32
 init_rd32(struct nvbios_init *init, u32 reg)
 {
 	reg = init_nvreg(init, reg);
-	if (init_exec(init))
+	if (reg != ~0 && init_exec(init))
 		return nv_rd32(init->subdev, reg);
 	return 0x00000000;
 }
@@ -163,7 +168,7 @@ static void
 init_wr32(struct nvbios_init *init, u32 reg, u32 val)
 {
 	reg = init_nvreg(init, reg);
-	if (init_exec(init))
+	if (reg != ~0 && init_exec(init))
 		nv_wr32(init->subdev, reg, val);
 }
 
@@ -171,7 +176,7 @@ static u32
 init_mask(struct nvbios_init *init, u32 reg, u32 mask, u32 val)
 {
 	reg = init_nvreg(init, reg);
-	if (init_exec(init)) {
+	if (reg != ~0 && init_exec(init)) {
 		u32 tmp = nv_rd32(init->subdev, reg);
 		nv_wr32(init->subdev, reg, (tmp & ~mask) | val);
 		return tmp;
@@ -410,7 +415,7 @@ init_ram_restrict(struct nvbios_init *init)
 	 * in case *not* re-reading the strap causes similar breakage.
 	 */
 	if (!init->ramcfg || init->bios->version.major < 0x70)
-		init->ramcfg = 0x80000000 | nvbios_ramcfg_index(init->bios);
+		init->ramcfg = 0x80000000 | nvbios_ramcfg_index(init->subdev);
 	return (init->ramcfg & 0x7fffffff);
 }
 
@@ -845,9 +850,8 @@ init_idx_addr_latched(struct nvbios_init *init)
 	u32 data = nv_ro32(bios, init->offset + 13);
 	u8 count = nv_ro08(bios, init->offset + 17);
 
-	trace("INDEX_ADDRESS_LATCHED\t"
-	      "R[0x%06x] : R[0x%06x]\n\tCTRL &= 0x%08x |= 0x%08x\n",
-	      creg, dreg, mask, data);
+	trace("INDEX_ADDRESS_LATCHED\tR[0x%06x] : R[0x%06x]\n", creg, dreg);
+	trace("\tCTRL &= 0x%08x |= 0x%08x\n", mask, data);
 	init->offset += 18;
 
 	while (count--) {

+ 5 - 4
drivers/gpu/drm/nouveau/core/subdev/bios/ramcfg.c

@@ -27,9 +27,9 @@
 #include <subdev/bios/ramcfg.h>
 
 static u8
-nvbios_ramcfg_strap(struct nouveau_bios *bios)
+nvbios_ramcfg_strap(struct nouveau_subdev *subdev)
 {
-	return (nv_rd32(bios, 0x101000) & 0x0000003c) >> 2;
+	return (nv_rd32(subdev, 0x101000) & 0x0000003c) >> 2;
 }
 
 u8
@@ -48,9 +48,10 @@ nvbios_ramcfg_count(struct nouveau_bios *bios)
 }
 
 u8
-nvbios_ramcfg_index(struct nouveau_bios *bios)
+nvbios_ramcfg_index(struct nouveau_subdev *subdev)
 {
-	u8 strap = nvbios_ramcfg_strap(bios);
+	struct nouveau_bios *bios = nouveau_bios(subdev);
+	u8 strap = nvbios_ramcfg_strap(subdev);
 	u32 xlat = 0x00000000;
 	struct bit_entry bit_M;
 

+ 11 - 0
drivers/gpu/drm/nouveau/core/subdev/bios/therm.c

@@ -164,6 +164,7 @@ nvbios_therm_fan_parse(struct nouveau_bios *bios,
 
 	i = 0;
 	fan->nr_fan_trip = 0;
+	fan->fan_mode = NVBIOS_THERM_FAN_OTHER;
 	while ((entry = nvbios_therm_entry(bios, i++, &ver, &len))) {
 		s16 value = nv_ro16(bios, entry + 1);
 
@@ -174,6 +175,8 @@ nvbios_therm_fan_parse(struct nouveau_bios *bios,
 			break;
 		case 0x24:
 			fan->nr_fan_trip++;
+			if (fan->fan_mode > NVBIOS_THERM_FAN_TRIP)
+				fan->fan_mode = NVBIOS_THERM_FAN_TRIP;
 			cur_trip = &fan->trip[fan->nr_fan_trip - 1];
 			cur_trip->hysteresis = value & 0xf;
 			cur_trip->temp = (value & 0xff0) >> 4;
@@ -194,11 +197,19 @@ nvbios_therm_fan_parse(struct nouveau_bios *bios,
 			fan->slow_down_period = value;
 			break;
 		case 0x46:
+			if (fan->fan_mode > NVBIOS_THERM_FAN_LINEAR)
+				fan->fan_mode = NVBIOS_THERM_FAN_LINEAR;
 			fan->linear_min_temp = nv_ro08(bios, entry + 1);
 			fan->linear_max_temp = nv_ro08(bios, entry + 2);
 			break;
 		}
 	}
 
+	/* starting from fermi, fan management is always linear */
+	if (nv_device(bios)->card_type >= NV_C0 &&
+		fan->fan_mode == NVBIOS_THERM_FAN_OTHER) {
+		fan->fan_mode = NVBIOS_THERM_FAN_LINEAR;
+	}
+
 	return 0;
 }

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно