summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-04-26 15:42:02 +1000
committerDave Airlie <airlied@redhat.com>2013-04-26 15:42:02 +1000
commit36d9b1541cedecd59e9d8fff0bbf9b7e9dd9704e (patch)
tree3472ef1eb4c63ecd0b8e98188b42bad9b6c55ad3
parenta90b590e957d66ea357aeff4cee8425f2567ed33 (diff)
parent893e90c554c1ef85684b335655a5030d38a4a1b0 (diff)
Merge branch 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next
"Nothing overly exciting here aside from calim's fermi/kepler vram compression patches. The rest is misc fixes I gathered from the list. Most of the stuff from me is fixing issues that have come up from the work on kepler PM, as well as a commit moving all the old-school modesetting out of the way (no code changes here). There's other patches to go on top of that, but, it'll have to wait until I can rip out the old PM code, it's a bit tangled." * 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: (38 commits) drm/nouveau/fifo: implement channel creation event generation drm/nouveau/core: allow non-maskable events drm/nouveau/timer: allow alarms to be cancelled drm/nouveau/device: tweak the device/subdev relationship a little drm/nouveau/device: enable proper constructor/destructor drm/nouveau/device: have engine object initialised before creation drm/nouveau/device: convert to engine, rather than subdev drm/nv50-/disp: use self as parent for subobjects drm/nv50-/fifo: use parent as self for subobjects drm/nv20-nv30/gr: use parent as self for subobjects drm/nvc0-/gr: use self as parent for subobjects drm/nv04-nv40/instmem: use self as parent for subobjects drm/nv04-nv40/vm: use self as parent for subobjects drm/nv50-/bar: use self as parent for subobjects drm/nv04-nv40/instmem: remove parent deref hack drm/nouveau/i2c: remove parent deref hack drm/nouveau/core: rebase object ref/use counts after ctor/init/fini events drm/nv50/disp: inform core when we're not creating a new context drm/nouveau/therm: send some messages to debug level drm/nve0/gr: add handling for a bunch of PGRAPH traps ...
-rw-r--r--drivers/gpu/drm/nouveau/Makefile25
-rw-r--r--drivers/gpu/drm/nouveau/core/core/client.c7
-rw-r--r--drivers/gpu/drm/nouveau/core/core/engine.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/core/event.c12
-rw-r--r--drivers/gpu/drm/nouveau/core/core/object.c19
-rw-r--r--drivers/gpu/drm/nouveau/core/core/parent.c8
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/base.c (renamed from drivers/gpu/drm/nouveau/core/subdev/device/base.c)183
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nv04.c (renamed from drivers/gpu/drm/nouveau/core/subdev/device/nv04.c)2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nv10.c (renamed from drivers/gpu/drm/nouveau/core/subdev/device/nv10.c)2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nv20.c (renamed from drivers/gpu/drm/nouveau/core/subdev/device/nv20.c)2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nv30.c (renamed from drivers/gpu/drm/nouveau/core/subdev/device/nv30.c)2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nv40.c (renamed from drivers/gpu/drm/nouveau/core/subdev/device/nv40.c)2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nv50.c (renamed from drivers/gpu/drm/nouveau/core/subdev/device/nv50.c)20
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nvc0.c (renamed from drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c)30
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nve0.c (renamed from drivers/gpu/drm/nouveau/core/subdev/device/nve0.c)2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/dport.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.c5
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/base.c7
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c18
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c22
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c9
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c7
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c51
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c13
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc5
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc3
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv20.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv25.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv30.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv34.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv35.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv40.c10
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nv50.c10
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c31
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h3
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nve0.c230
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/software/nvc0.c29
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/device.h6
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/parent.h4
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/device.h (renamed from drivers/gpu/drm/nouveau/core/include/subdev/device.h)1
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/fifo.h3
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/graph.h4
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h7
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/mc.h30
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/therm.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/os.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c22
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c14
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/init.c56
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c72
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/i2c/base.c6
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c20
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c12
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c129
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/base.c60
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c175
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c221
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/priv.h3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/temp.c14
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c13
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c58
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/Makefile10
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/arb.c (renamed from drivers/gpu/drm/nouveau/nouveau_calc.c)2
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/crtc.c (renamed from drivers/gpu/drm/nouveau/nv04_crtc.c)5
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/cursor.c (renamed from drivers/gpu/drm/nouveau/nv04_cursor.c)3
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/dac.c (renamed from drivers/gpu/drm/nouveau/nv04_dac.c)2
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/dfp.c (renamed from drivers/gpu/drm/nouveau/nv04_dfp.c)2
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/disp.c (renamed from drivers/gpu/drm/nouveau/nv04_display.c)2
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/disp.h (renamed from drivers/gpu/drm/nouveau/nv04_display.h)0
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/hw.c (renamed from drivers/gpu/drm/nouveau/nouveau_hw.c)2
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/hw.h (renamed from drivers/gpu/drm/nouveau/nouveau_hw.h)3
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/nvreg.h (renamed from drivers/gpu/drm/nouveau/nvreg.h)0
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/tvmodesnv17.c (renamed from drivers/gpu/drm/nouveau/nv17_tv_modes.c)4
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/tvnv04.c (renamed from drivers/gpu/drm/nouveau/nv04_tv.c)2
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/tvnv17.c (renamed from drivers/gpu/drm/nouveau/nv17_tv.c)4
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/tvnv17.h (renamed from drivers/gpu/drm/nouveau/nv17_tv.h)0
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_abi16.c12
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_backlight.c3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c23
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.h13
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_encoder.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_irq.c76
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_irq.h11
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_ttm.c25
-rw-r--r--drivers/gpu/drm/nouveau/nv04_pm.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv40_pm.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv50_pm.c2
105 files changed, 1316 insertions, 644 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index 90f9140eeefd..52930a20d8f8 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -53,15 +53,6 @@ nouveau-y += core/subdev/clock/nva3.o
53nouveau-y += core/subdev/clock/nvc0.o 53nouveau-y += core/subdev/clock/nvc0.o
54nouveau-y += core/subdev/clock/pllnv04.o 54nouveau-y += core/subdev/clock/pllnv04.o
55nouveau-y += core/subdev/clock/pllnva3.o 55nouveau-y += core/subdev/clock/pllnva3.o
56nouveau-y += core/subdev/device/base.o
57nouveau-y += core/subdev/device/nv04.o
58nouveau-y += core/subdev/device/nv10.o
59nouveau-y += core/subdev/device/nv20.o
60nouveau-y += core/subdev/device/nv30.o
61nouveau-y += core/subdev/device/nv40.o
62nouveau-y += core/subdev/device/nv50.o
63nouveau-y += core/subdev/device/nvc0.o
64nouveau-y += core/subdev/device/nve0.o
65nouveau-y += core/subdev/devinit/base.o 56nouveau-y += core/subdev/devinit/base.o
66nouveau-y += core/subdev/devinit/nv04.o 57nouveau-y += core/subdev/devinit/nv04.o
67nouveau-y += core/subdev/devinit/nv05.o 58nouveau-y += core/subdev/devinit/nv05.o
@@ -126,6 +117,7 @@ nouveau-y += core/subdev/therm/ic.o
126nouveau-y += core/subdev/therm/temp.o 117nouveau-y += core/subdev/therm/temp.o
127nouveau-y += core/subdev/therm/nv40.o 118nouveau-y += core/subdev/therm/nv40.o
128nouveau-y += core/subdev/therm/nv50.o 119nouveau-y += core/subdev/therm/nv50.o
120nouveau-y += core/subdev/therm/nv84.o
129nouveau-y += core/subdev/therm/nva3.o 121nouveau-y += core/subdev/therm/nva3.o
130nouveau-y += core/subdev/therm/nvd0.o 122nouveau-y += core/subdev/therm/nvd0.o
131nouveau-y += core/subdev/timer/base.o 123nouveau-y += core/subdev/timer/base.o
@@ -150,6 +142,15 @@ nouveau-y += core/engine/copy/nvc0.o
150nouveau-y += core/engine/copy/nve0.o 142nouveau-y += core/engine/copy/nve0.o
151nouveau-y += core/engine/crypt/nv84.o 143nouveau-y += core/engine/crypt/nv84.o
152nouveau-y += core/engine/crypt/nv98.o 144nouveau-y += core/engine/crypt/nv98.o
145nouveau-y += core/engine/device/base.o
146nouveau-y += core/engine/device/nv04.o
147nouveau-y += core/engine/device/nv10.o
148nouveau-y += core/engine/device/nv20.o
149nouveau-y += core/engine/device/nv30.o
150nouveau-y += core/engine/device/nv40.o
151nouveau-y += core/engine/device/nv50.o
152nouveau-y += core/engine/device/nvc0.o
153nouveau-y += core/engine/device/nve0.o
153nouveau-y += core/engine/disp/base.o 154nouveau-y += core/engine/disp/base.o
154nouveau-y += core/engine/disp/nv04.o 155nouveau-y += core/engine/disp/nv04.o
155nouveau-y += core/engine/disp/nv50.o 156nouveau-y += core/engine/disp/nv50.o
@@ -212,7 +213,7 @@ nouveau-y += core/engine/vp/nve0.o
212 213
213# drm/core 214# drm/core
214nouveau-y += nouveau_drm.o nouveau_chan.o nouveau_dma.o nouveau_fence.o 215nouveau-y += nouveau_drm.o nouveau_chan.o nouveau_dma.o nouveau_fence.o
215nouveau-y += nouveau_irq.o nouveau_vga.o nouveau_agp.o 216nouveau-y += nouveau_vga.o nouveau_agp.o
216nouveau-y += nouveau_ttm.o nouveau_sgdma.o nouveau_bo.o nouveau_gem.o 217nouveau-y += nouveau_ttm.o nouveau_sgdma.o nouveau_bo.o nouveau_gem.o
217nouveau-y += nouveau_prime.o nouveau_abi16.o 218nouveau-y += nouveau_prime.o nouveau_abi16.o
218nouveau-y += nv04_fence.o nv10_fence.o nv17_fence.o 219nouveau-y += nv04_fence.o nv10_fence.o nv17_fence.o
@@ -224,9 +225,7 @@ nouveau-y += nouveau_connector.o nouveau_dp.o
224nouveau-y += nv04_fbcon.o nv50_fbcon.o nvc0_fbcon.o 225nouveau-y += nv04_fbcon.o nv50_fbcon.o nvc0_fbcon.o
225 226
226# drm/kms/nv04:nv50 227# drm/kms/nv04:nv50
227nouveau-y += nouveau_hw.o nouveau_calc.o 228include $(src)/dispnv04/Makefile
228nouveau-y += nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o
229nouveau-y += nv04_crtc.o nv04_display.o nv04_cursor.o
230 229
231# drm/kms/nv50- 230# drm/kms/nv50-
232nouveau-y += nv50_display.o 231nouveau-y += nv50_display.o
diff --git a/drivers/gpu/drm/nouveau/core/core/client.c b/drivers/gpu/drm/nouveau/core/core/client.c
index 295c22165eac..9079c0ac58e6 100644
--- a/drivers/gpu/drm/nouveau/core/core/client.c
+++ b/drivers/gpu/drm/nouveau/core/core/client.c
@@ -27,7 +27,7 @@
27#include <core/handle.h> 27#include <core/handle.h>
28#include <core/option.h> 28#include <core/option.h>
29 29
30#include <subdev/device.h> 30#include <engine/device.h>
31 31
32static void 32static void
33nouveau_client_dtor(struct nouveau_object *object) 33nouveau_client_dtor(struct nouveau_object *object)
@@ -58,8 +58,9 @@ nouveau_client_create_(const char *name, u64 devname, const char *cfg,
58 return -ENODEV; 58 return -ENODEV;
59 59
60 ret = nouveau_namedb_create_(NULL, NULL, &nouveau_client_oclass, 60 ret = nouveau_namedb_create_(NULL, NULL, &nouveau_client_oclass,
61 NV_CLIENT_CLASS, nouveau_device_sclass, 61 NV_CLIENT_CLASS, NULL,
62 0, length, pobject); 62 (1ULL << NVDEV_ENGINE_DEVICE),
63 length, pobject);
63 client = *pobject; 64 client = *pobject;
64 if (ret) 65 if (ret)
65 return ret; 66 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/core/engine.c b/drivers/gpu/drm/nouveau/core/core/engine.c
index 09b3bd502fd0..c8bed4a26833 100644
--- a/drivers/gpu/drm/nouveau/core/core/engine.c
+++ b/drivers/gpu/drm/nouveau/core/core/engine.c
@@ -33,7 +33,6 @@ nouveau_engine_create_(struct nouveau_object *parent,
33 const char *iname, const char *fname, 33 const char *iname, const char *fname,
34 int length, void **pobject) 34 int length, void **pobject)
35{ 35{
36 struct nouveau_device *device = nv_device(parent);
37 struct nouveau_engine *engine; 36 struct nouveau_engine *engine;
38 int ret; 37 int ret;
39 38
@@ -43,7 +42,8 @@ nouveau_engine_create_(struct nouveau_object *parent,
43 if (ret) 42 if (ret)
44 return ret; 43 return ret;
45 44
46 if (!nouveau_boolopt(device->cfgopt, iname, enable)) { 45 if ( parent &&
46 !nouveau_boolopt(nv_device(parent)->cfgopt, iname, enable)) {
47 if (!enable) 47 if (!enable)
48 nv_warn(engine, "disabled, %s=1 to enable\n", iname); 48 nv_warn(engine, "disabled, %s=1 to enable\n", iname);
49 return -ENODEV; 49 return -ENODEV;
diff --git a/drivers/gpu/drm/nouveau/core/core/event.c b/drivers/gpu/drm/nouveau/core/core/event.c
index 6d01e0f0fc8a..7eb81c1b6fab 100644
--- a/drivers/gpu/drm/nouveau/core/core/event.c
+++ b/drivers/gpu/drm/nouveau/core/core/event.c
@@ -27,8 +27,10 @@ static void
27nouveau_event_put_locked(struct nouveau_event *event, int index, 27nouveau_event_put_locked(struct nouveau_event *event, int index,
28 struct nouveau_eventh *handler) 28 struct nouveau_eventh *handler)
29{ 29{
30 if (!--event->index[index].refs) 30 if (!--event->index[index].refs) {
31 event->disable(event, index); 31 if (event->disable)
32 event->disable(event, index);
33 }
32 list_del(&handler->head); 34 list_del(&handler->head);
33} 35}
34 36
@@ -53,8 +55,10 @@ nouveau_event_get(struct nouveau_event *event, int index,
53 spin_lock_irqsave(&event->lock, flags); 55 spin_lock_irqsave(&event->lock, flags);
54 if (index < event->index_nr) { 56 if (index < event->index_nr) {
55 list_add(&handler->head, &event->index[index].list); 57 list_add(&handler->head, &event->index[index].list);
56 if (!event->index[index].refs++) 58 if (!event->index[index].refs++) {
57 event->enable(event, index); 59 if (event->enable)
60 event->enable(event, index);
61 }
58 } 62 }
59 spin_unlock_irqrestore(&event->lock, flags); 63 spin_unlock_irqrestore(&event->lock, flags);
60} 64}
diff --git a/drivers/gpu/drm/nouveau/core/core/object.c b/drivers/gpu/drm/nouveau/core/core/object.c
index 3b2e7b6304d3..7f48e288215f 100644
--- a/drivers/gpu/drm/nouveau/core/core/object.c
+++ b/drivers/gpu/drm/nouveau/core/core/object.c
@@ -136,26 +136,30 @@ nouveau_object_ctor(struct nouveau_object *parent,
136 struct nouveau_object **pobject) 136 struct nouveau_object **pobject)
137{ 137{
138 struct nouveau_ofuncs *ofuncs = oclass->ofuncs; 138 struct nouveau_ofuncs *ofuncs = oclass->ofuncs;
139 struct nouveau_object *object = NULL;
139 int ret; 140 int ret;
140 141
141 *pobject = NULL; 142 ret = ofuncs->ctor(parent, engine, oclass, data, size, &object);
142 143 *pobject = object;
143 ret = ofuncs->ctor(parent, engine, oclass, data, size, pobject);
144 if (ret < 0) { 144 if (ret < 0) {
145 if (ret != -ENODEV) { 145 if (ret != -ENODEV) {
146 nv_error(parent, "failed to create 0x%08x, %d\n", 146 nv_error(parent, "failed to create 0x%08x, %d\n",
147 oclass->handle, ret); 147 oclass->handle, ret);
148 } 148 }
149 149
150 if (*pobject) { 150 if (object) {
151 ofuncs->dtor(*pobject); 151 ofuncs->dtor(object);
152 *pobject = NULL; 152 *pobject = NULL;
153 } 153 }
154 154
155 return ret; 155 return ret;
156 } 156 }
157 157
158 nv_debug(*pobject, "created\n"); 158 if (ret == 0) {
159 nv_debug(object, "created\n");
160 atomic_set(&object->refcount, 1);
161 }
162
159 return 0; 163 return 0;
160} 164}
161 165
@@ -327,6 +331,7 @@ nouveau_object_inc(struct nouveau_object *object)
327 } 331 }
328 332
329 ret = nv_ofuncs(object)->init(object); 333 ret = nv_ofuncs(object)->init(object);
334 atomic_set(&object->usecount, 1);
330 if (ret) { 335 if (ret) {
331 nv_error(object, "init failed, %d\n", ret); 336 nv_error(object, "init failed, %d\n", ret);
332 goto fail_self; 337 goto fail_self;
@@ -357,6 +362,7 @@ nouveau_object_decf(struct nouveau_object *object)
357 nv_trace(object, "stopping...\n"); 362 nv_trace(object, "stopping...\n");
358 363
359 ret = nv_ofuncs(object)->fini(object, false); 364 ret = nv_ofuncs(object)->fini(object, false);
365 atomic_set(&object->usecount, 0);
360 if (ret) 366 if (ret)
361 nv_warn(object, "failed fini, %d\n", ret); 367 nv_warn(object, "failed fini, %d\n", ret);
362 368
@@ -381,6 +387,7 @@ nouveau_object_decs(struct nouveau_object *object)
381 nv_trace(object, "suspending...\n"); 387 nv_trace(object, "suspending...\n");
382 388
383 ret = nv_ofuncs(object)->fini(object, true); 389 ret = nv_ofuncs(object)->fini(object, true);
390 atomic_set(&object->usecount, 0);
384 if (ret) { 391 if (ret) {
385 nv_error(object, "failed suspend, %d\n", ret); 392 nv_error(object, "failed suspend, %d\n", ret);
386 return ret; 393 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/core/parent.c b/drivers/gpu/drm/nouveau/core/core/parent.c
index db7c54943102..313380ce632d 100644
--- a/drivers/gpu/drm/nouveau/core/core/parent.c
+++ b/drivers/gpu/drm/nouveau/core/core/parent.c
@@ -24,6 +24,7 @@
24 24
25#include <core/object.h> 25#include <core/object.h>
26#include <core/parent.h> 26#include <core/parent.h>
27#include <core/client.h>
27 28
28int 29int
29nouveau_parent_sclass(struct nouveau_object *parent, u16 handle, 30nouveau_parent_sclass(struct nouveau_object *parent, u16 handle,
@@ -50,7 +51,12 @@ nouveau_parent_sclass(struct nouveau_object *parent, u16 handle,
50 while (mask) { 51 while (mask) {
51 int i = ffsll(mask) - 1; 52 int i = ffsll(mask) - 1;
52 53
53 if ((engine = nouveau_engine(parent, i))) { 54 if (nv_iclass(parent, NV_CLIENT_CLASS))
55 engine = nv_engine(nv_client(parent)->device);
56 else
57 engine = nouveau_engine(parent, i);
58
59 if (engine) {
54 oclass = engine->sclass; 60 oclass = engine->sclass;
55 while (oclass->ofuncs) { 61 while (oclass->ofuncs) {
56 if ((oclass->handle & 0xffff) == handle) { 62 if ((oclass->handle & 0xffff) == handle) {
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c
index 3937ced5c753..86d24904e9d3 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/base.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c
@@ -29,7 +29,7 @@
29 29
30#include <core/class.h> 30#include <core/class.h>
31 31
32#include <subdev/device.h> 32#include <engine/device.h>
33 33
34static DEFINE_MUTEX(nv_devices_mutex); 34static DEFINE_MUTEX(nv_devices_mutex);
35static LIST_HEAD(nv_devices); 35static LIST_HEAD(nv_devices);
@@ -55,7 +55,6 @@ nouveau_device_find(u64 name)
55struct nouveau_devobj { 55struct nouveau_devobj {
56 struct nouveau_parent base; 56 struct nouveau_parent base;
57 struct nouveau_object *subdev[NVDEV_SUBDEV_NR]; 57 struct nouveau_object *subdev[NVDEV_SUBDEV_NR];
58 bool created;
59}; 58};
60 59
61static const u64 disable_map[] = { 60static const u64 disable_map[] = {
@@ -238,26 +237,24 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
238 } 237 }
239 238
240 /* ensure requested subsystems are available for use */ 239 /* ensure requested subsystems are available for use */
241 for (i = 0, c = 0; i < NVDEV_SUBDEV_NR; i++) { 240 for (i = 1, c = 1; i < NVDEV_SUBDEV_NR; i++) {
242 if (!(oclass = device->oclass[i]) || (disable & (1ULL << i))) 241 if (!(oclass = device->oclass[i]) || (disable & (1ULL << i)))
243 continue; 242 continue;
244 243
245 if (!device->subdev[i]) { 244 if (device->subdev[i]) {
246 ret = nouveau_object_ctor(nv_object(device), NULL,
247 oclass, NULL, i,
248 &devobj->subdev[i]);
249 if (ret == -ENODEV)
250 continue;
251 if (ret)
252 return ret;
253
254 if (nv_iclass(devobj->subdev[i], NV_ENGINE_CLASS))
255 nouveau_subdev_reset(devobj->subdev[i]);
256 } else {
257 nouveau_object_ref(device->subdev[i], 245 nouveau_object_ref(device->subdev[i],
258 &devobj->subdev[i]); 246 &devobj->subdev[i]);
247 continue;
259 } 248 }
260 249
250 ret = nouveau_object_ctor(nv_object(device), NULL,
251 oclass, NULL, i,
252 &devobj->subdev[i]);
253 if (ret == -ENODEV)
254 continue;
255 if (ret)
256 return ret;
257
261 /* note: can't init *any* subdevs until devinit has been run 258 /* note: can't init *any* subdevs until devinit has been run
262 * due to not knowing exactly what the vbios init tables will 259 * due to not knowing exactly what the vbios init tables will
263 * mess with. devinit also can't be run until all of its 260 * mess with. devinit also can't be run until all of its
@@ -273,6 +270,10 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
273 ret = nouveau_object_inc(subdev); 270 ret = nouveau_object_inc(subdev);
274 if (ret) 271 if (ret)
275 return ret; 272 return ret;
273 atomic_dec(&nv_object(device)->usecount);
274 } else
275 if (subdev) {
276 nouveau_subdev_reset(subdev);
276 } 277 }
277 } 278 }
278 } 279 }
@@ -292,74 +293,6 @@ nouveau_devobj_dtor(struct nouveau_object *object)
292 nouveau_parent_destroy(&devobj->base); 293 nouveau_parent_destroy(&devobj->base);
293} 294}
294 295
295static int
296nouveau_devobj_init(struct nouveau_object *object)
297{
298 struct nouveau_devobj *devobj = (void *)object;
299 struct nouveau_object *subdev;
300 int ret, i;
301
302 ret = nouveau_parent_init(&devobj->base);
303 if (ret)
304 return ret;
305
306 for (i = 0; devobj->created && i < NVDEV_SUBDEV_NR; i++) {
307 if ((subdev = devobj->subdev[i])) {
308 if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
309 ret = nouveau_object_inc(subdev);
310 if (ret)
311 goto fail;
312 }
313 }
314 }
315
316 devobj->created = true;
317 return 0;
318
319fail:
320 for (--i; i >= 0; i--) {
321 if ((subdev = devobj->subdev[i])) {
322 if (!nv_iclass(subdev, NV_ENGINE_CLASS))
323 nouveau_object_dec(subdev, false);
324 }
325 }
326
327 return ret;
328}
329
330static int
331nouveau_devobj_fini(struct nouveau_object *object, bool suspend)
332{
333 struct nouveau_devobj *devobj = (void *)object;
334 struct nouveau_object *subdev;
335 int ret, i;
336
337 for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) {
338 if ((subdev = devobj->subdev[i])) {
339 if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
340 ret = nouveau_object_dec(subdev, suspend);
341 if (ret && suspend)
342 goto fail;
343 }
344 }
345 }
346
347 ret = nouveau_parent_fini(&devobj->base, suspend);
348fail:
349 for (; ret && suspend && i < NVDEV_SUBDEV_NR; i++) {
350 if ((subdev = devobj->subdev[i])) {
351 if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
352 ret = nouveau_object_inc(subdev);
353 if (ret) {
354 /* XXX */
355 }
356 }
357 }
358 }
359
360 return ret;
361}
362
363static u8 296static u8
364nouveau_devobj_rd08(struct nouveau_object *object, u64 addr) 297nouveau_devobj_rd08(struct nouveau_object *object, u64 addr)
365{ 298{
@@ -400,8 +333,8 @@ static struct nouveau_ofuncs
400nouveau_devobj_ofuncs = { 333nouveau_devobj_ofuncs = {
401 .ctor = nouveau_devobj_ctor, 334 .ctor = nouveau_devobj_ctor,
402 .dtor = nouveau_devobj_dtor, 335 .dtor = nouveau_devobj_dtor,
403 .init = nouveau_devobj_init, 336 .init = _nouveau_parent_init,
404 .fini = nouveau_devobj_fini, 337 .fini = _nouveau_parent_fini,
405 .rd08 = nouveau_devobj_rd08, 338 .rd08 = nouveau_devobj_rd08,
406 .rd16 = nouveau_devobj_rd16, 339 .rd16 = nouveau_devobj_rd16,
407 .rd32 = nouveau_devobj_rd32, 340 .rd32 = nouveau_devobj_rd32,
@@ -413,12 +346,76 @@ nouveau_devobj_ofuncs = {
413/****************************************************************************** 346/******************************************************************************
414 * nouveau_device: engine functions 347 * nouveau_device: engine functions
415 *****************************************************************************/ 348 *****************************************************************************/
416struct nouveau_oclass 349static struct nouveau_oclass
417nouveau_device_sclass[] = { 350nouveau_device_sclass[] = {
418 { 0x0080, &nouveau_devobj_ofuncs }, 351 { 0x0080, &nouveau_devobj_ofuncs },
419 {} 352 {}
420}; 353};
421 354
355static int
356nouveau_device_fini(struct nouveau_object *object, bool suspend)
357{
358 struct nouveau_device *device = (void *)object;
359 struct nouveau_object *subdev;
360 int ret, i;
361
362 for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) {
363 if ((subdev = device->subdev[i])) {
364 if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
365 ret = nouveau_object_dec(subdev, suspend);
366 if (ret && suspend)
367 goto fail;
368 }
369 }
370 }
371
372 ret = 0;
373fail:
374 for (; ret && i < NVDEV_SUBDEV_NR; i++) {
375 if ((subdev = device->subdev[i])) {
376 if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
377 ret = nouveau_object_inc(subdev);
378 if (ret) {
379 /* XXX */
380 }
381 }
382 }
383 }
384
385 return ret;
386}
387
388static int
389nouveau_device_init(struct nouveau_object *object)
390{
391 struct nouveau_device *device = (void *)object;
392 struct nouveau_object *subdev;
393 int ret, i;
394
395 for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
396 if ((subdev = device->subdev[i])) {
397 if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
398 ret = nouveau_object_inc(subdev);
399 if (ret)
400 goto fail;
401 } else {
402 nouveau_subdev_reset(subdev);
403 }
404 }
405 }
406
407 ret = 0;
408fail:
409 for (--i; ret && i >= 0; i--) {
410 if ((subdev = device->subdev[i])) {
411 if (!nv_iclass(subdev, NV_ENGINE_CLASS))
412 nouveau_object_dec(subdev, false);
413 }
414 }
415
416 return ret;
417}
418
422static void 419static void
423nouveau_device_dtor(struct nouveau_object *object) 420nouveau_device_dtor(struct nouveau_object *object)
424{ 421{
@@ -428,17 +425,19 @@ nouveau_device_dtor(struct nouveau_object *object)
428 list_del(&device->head); 425 list_del(&device->head);
429 mutex_unlock(&nv_devices_mutex); 426 mutex_unlock(&nv_devices_mutex);
430 427
431 if (device->base.mmio) 428 if (nv_subdev(device)->mmio)
432 iounmap(device->base.mmio); 429 iounmap(nv_subdev(device)->mmio);
433 430
434 nouveau_subdev_destroy(&device->base); 431 nouveau_engine_destroy(&device->base);
435} 432}
436 433
437static struct nouveau_oclass 434static struct nouveau_oclass
438nouveau_device_oclass = { 435nouveau_device_oclass = {
439 .handle = NV_SUBDEV(DEVICE, 0x00), 436 .handle = NV_ENGINE(DEVICE, 0x00),
440 .ofuncs = &(struct nouveau_ofuncs) { 437 .ofuncs = &(struct nouveau_ofuncs) {
441 .dtor = nouveau_device_dtor, 438 .dtor = nouveau_device_dtor,
439 .init = nouveau_device_init,
440 .fini = nouveau_device_fini,
442 }, 441 },
443}; 442};
444 443
@@ -456,13 +455,12 @@ nouveau_device_create_(struct pci_dev *pdev, u64 name, const char *sname,
456 goto done; 455 goto done;
457 } 456 }
458 457
459 ret = nouveau_subdev_create_(NULL, NULL, &nouveau_device_oclass, 0, 458 ret = nouveau_engine_create_(NULL, NULL, &nouveau_device_oclass, true,
460 "DEVICE", "device", length, pobject); 459 "DEVICE", "device", length, pobject);
461 device = *pobject; 460 device = *pobject;
462 if (ret) 461 if (ret)
463 goto done; 462 goto done;
464 463
465 atomic_set(&nv_object(device)->usecount, 2);
466 device->pdev = pdev; 464 device->pdev = pdev;
467 device->handle = name; 465 device->handle = name;
468 device->cfgopt = cfg; 466 device->cfgopt = cfg;
@@ -470,6 +468,7 @@ nouveau_device_create_(struct pci_dev *pdev, u64 name, const char *sname,
470 device->name = sname; 468 device->name = sname;
471 469
472 nv_subdev(device)->debug = nouveau_dbgopt(device->dbgopt, "DEVICE"); 470 nv_subdev(device)->debug = nouveau_dbgopt(device->dbgopt, "DEVICE");
471 nv_engine(device)->sclass = nouveau_device_sclass;
473 list_add(&device->head, &nv_devices); 472 list_add(&device->head, &nv_devices);
474done: 473done:
475 mutex_unlock(&nv_devices_mutex); 474 mutex_unlock(&nv_devices_mutex);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c b/drivers/gpu/drm/nouveau/core/engine/device/nv04.c
index 473c5c03d3c9..a0284cf09c0f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nv04.c
@@ -22,7 +22,6 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include <subdev/device.h>
26#include <subdev/bios.h> 25#include <subdev/bios.h>
27#include <subdev/bus.h> 26#include <subdev/bus.h>
28#include <subdev/i2c.h> 27#include <subdev/i2c.h>
@@ -34,6 +33,7 @@
34#include <subdev/instmem.h> 33#include <subdev/instmem.h>
35#include <subdev/vm.h> 34#include <subdev/vm.h>
36 35
36#include <engine/device.h>
37#include <engine/dmaobj.h> 37#include <engine/dmaobj.h>
38#include <engine/fifo.h> 38#include <engine/fifo.h>
39#include <engine/software.h> 39#include <engine/software.h>
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c b/drivers/gpu/drm/nouveau/core/engine/device/nv10.c
index d0774f5bebe1..1b7809a095c3 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nv10.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nv10.c
@@ -22,7 +22,6 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include <subdev/device.h>
26#include <subdev/bios.h> 25#include <subdev/bios.h>
27#include <subdev/bus.h> 26#include <subdev/bus.h>
28#include <subdev/gpio.h> 27#include <subdev/gpio.h>
@@ -35,6 +34,7 @@
35#include <subdev/instmem.h> 34#include <subdev/instmem.h>
36#include <subdev/vm.h> 35#include <subdev/vm.h>
37 36
37#include <engine/device.h>
38#include <engine/dmaobj.h> 38#include <engine/dmaobj.h>
39#include <engine/fifo.h> 39#include <engine/fifo.h>
40#include <engine/software.h> 40#include <engine/software.h>
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c b/drivers/gpu/drm/nouveau/core/engine/device/nv20.c
index ab920e0dc45b..12a4005fa619 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nv20.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nv20.c
@@ -22,7 +22,6 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include <subdev/device.h>
26#include <subdev/bios.h> 25#include <subdev/bios.h>
27#include <subdev/bus.h> 26#include <subdev/bus.h>
28#include <subdev/gpio.h> 27#include <subdev/gpio.h>
@@ -36,6 +35,7 @@
36#include <subdev/instmem.h> 35#include <subdev/instmem.h>
37#include <subdev/vm.h> 36#include <subdev/vm.h>
38 37
38#include <engine/device.h>
39#include <engine/dmaobj.h> 39#include <engine/dmaobj.h>
40#include <engine/fifo.h> 40#include <engine/fifo.h>
41#include <engine/software.h> 41#include <engine/software.h>
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c b/drivers/gpu/drm/nouveau/core/engine/device/nv30.c
index 5f2110261b04..cef0f1ea4c21 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nv30.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nv30.c
@@ -22,7 +22,6 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include <subdev/device.h>
26#include <subdev/bios.h> 25#include <subdev/bios.h>
27#include <subdev/bus.h> 26#include <subdev/bus.h>
28#include <subdev/gpio.h> 27#include <subdev/gpio.h>
@@ -35,6 +34,7 @@
35#include <subdev/instmem.h> 34#include <subdev/instmem.h>
36#include <subdev/vm.h> 35#include <subdev/vm.h>
37 36
37#include <engine/device.h>
38#include <engine/dmaobj.h> 38#include <engine/dmaobj.h>
39#include <engine/fifo.h> 39#include <engine/fifo.h>
40#include <engine/software.h> 40#include <engine/software.h>
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c
index f3d55efe9ac9..1719cb0ee595 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c
@@ -22,7 +22,6 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include <subdev/device.h>
26#include <subdev/bios.h> 25#include <subdev/bios.h>
27#include <subdev/bus.h> 26#include <subdev/bus.h>
28#include <subdev/vm.h> 27#include <subdev/vm.h>
@@ -37,6 +36,7 @@
37#include <subdev/instmem.h> 36#include <subdev/instmem.h>
38#include <subdev/vm.h> 37#include <subdev/vm.h>
39 38
39#include <engine/device.h>
40#include <engine/dmaobj.h> 40#include <engine/dmaobj.h>
41#include <engine/fifo.h> 41#include <engine/fifo.h>
42#include <engine/software.h> 42#include <engine/software.h>
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c
index 5ed2fa51ddc2..5e8c3de75593 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c
@@ -22,7 +22,6 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include <subdev/device.h>
26#include <subdev/bios.h> 25#include <subdev/bios.h>
27#include <subdev/bus.h> 26#include <subdev/bus.h>
28#include <subdev/gpio.h> 27#include <subdev/gpio.h>
@@ -38,6 +37,7 @@
38#include <subdev/vm.h> 37#include <subdev/vm.h>
39#include <subdev/bar.h> 38#include <subdev/bar.h>
40 39
40#include <engine/device.h>
41#include <engine/dmaobj.h> 41#include <engine/dmaobj.h>
42#include <engine/fifo.h> 42#include <engine/fifo.h>
43#include <engine/software.h> 43#include <engine/software.h>
@@ -83,7 +83,7 @@ nv50_identify(struct nouveau_device *device)
83 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; 83 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
84 device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass; 84 device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
85 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; 85 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
86 device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass; 86 device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
87 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; 87 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
88 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 88 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
89 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; 89 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
@@ -109,7 +109,7 @@ nv50_identify(struct nouveau_device *device)
109 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; 109 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
110 device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass; 110 device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
111 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; 111 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
112 device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass; 112 device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
113 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; 113 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
114 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 114 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
115 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; 115 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
@@ -135,7 +135,7 @@ nv50_identify(struct nouveau_device *device)
135 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; 135 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
136 device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass; 136 device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
137 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; 137 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
138 device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass; 138 device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
139 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; 139 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
140 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 140 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
141 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; 141 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
@@ -161,7 +161,7 @@ nv50_identify(struct nouveau_device *device)
161 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; 161 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
162 device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; 162 device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
163 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; 163 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
164 device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass; 164 device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
165 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; 165 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
166 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 166 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
167 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; 167 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
@@ -187,7 +187,7 @@ nv50_identify(struct nouveau_device *device)
187 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; 187 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
188 device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; 188 device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
189 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; 189 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
190 device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass; 190 device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
191 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; 191 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
192 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 192 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
193 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; 193 device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass;
@@ -213,7 +213,7 @@ nv50_identify(struct nouveau_device *device)
213 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; 213 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
214 device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; 214 device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
215 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; 215 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
216 device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass; 216 device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
217 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; 217 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
218 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 218 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
219 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; 219 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
@@ -239,7 +239,7 @@ nv50_identify(struct nouveau_device *device)
239 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; 239 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
240 device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass; 240 device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass;
241 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; 241 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
242 device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass; 242 device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
243 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; 243 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
244 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 244 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
245 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; 245 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
@@ -265,7 +265,7 @@ nv50_identify(struct nouveau_device *device)
265 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; 265 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
266 device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; 266 device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
267 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; 267 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
268 device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass; 268 device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
269 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; 269 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
270 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 270 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
271 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; 271 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
@@ -291,7 +291,7 @@ nv50_identify(struct nouveau_device *device)
291 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; 291 device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass;
292 device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; 292 device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass;
293 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; 293 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass;
294 device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass; 294 device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass;
295 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; 295 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
296 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; 296 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
297 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; 297 device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
index 4393eb4d6564..955af122c3a6 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c
@@ -22,7 +22,6 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include <subdev/device.h>
26#include <subdev/bios.h> 25#include <subdev/bios.h>
27#include <subdev/bus.h> 26#include <subdev/bus.h>
28#include <subdev/gpio.h> 27#include <subdev/gpio.h>
@@ -40,6 +39,7 @@
40#include <subdev/vm.h> 39#include <subdev/vm.h>
41#include <subdev/bar.h> 40#include <subdev/bar.h>
42 41
42#include <engine/device.h>
43#include <engine/dmaobj.h> 43#include <engine/dmaobj.h>
44#include <engine/fifo.h> 44#include <engine/fifo.h>
45#include <engine/software.h> 45#include <engine/software.h>
@@ -285,6 +285,34 @@ nvc0_identify(struct nouveau_device *device)
285 device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; 285 device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
286 device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass; 286 device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass;
287 break; 287 break;
288 case 0xd7:
289 device->cname = "GF117";
290 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
291 device->oclass[NVDEV_SUBDEV_GPIO ] = &nvd0_gpio_oclass;
292 device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
293 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass;
294 device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
295 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
296 device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass;
297 device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass;
298 device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass;
299 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
300 device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass;
301 device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass;
302 device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass;
303 device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass;
304 device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
305 device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
306 device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
307 device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass;
308 device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass;
309 device->oclass[NVDEV_ENGINE_GR ] = &nvc0_graph_oclass;
310 device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass;
311 device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass;
312 device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
313 device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass;
314 device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass;
315 break;
288 default: 316 default:
289 nv_fatal(device, "unknown Fermi chipset\n"); 317 nv_fatal(device, "unknown Fermi chipset\n");
290 return -EINVAL; 318 return -EINVAL;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
index 5c12391619fd..e6a77944f43b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/device/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
@@ -22,7 +22,6 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include <subdev/device.h>
26#include <subdev/bios.h> 25#include <subdev/bios.h>
27#include <subdev/bus.h> 26#include <subdev/bus.h>
28#include <subdev/gpio.h> 27#include <subdev/gpio.h>
@@ -40,6 +39,7 @@
40#include <subdev/vm.h> 39#include <subdev/vm.h>
41#include <subdev/bar.h> 40#include <subdev/bar.h>
42 41
42#include <engine/device.h>
43#include <engine/dmaobj.h> 43#include <engine/dmaobj.h>
44#include <engine/fifo.h> 44#include <engine/fifo.h>
45#include <engine/software.h> 45#include <engine/software.h>
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c
index fa27b02ff829..31cc8fe8e7f0 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c
@@ -191,7 +191,7 @@ dp_link_train_cr(struct dp_state *dp)
191static int 191static int
192dp_link_train_eq(struct dp_state *dp) 192dp_link_train_eq(struct dp_state *dp)
193{ 193{
194 bool eq_done, cr_done = true; 194 bool eq_done = false, cr_done = true;
195 int tries = 0, i; 195 int tries = 0, i;
196 196
197 dp_set_training_pattern(dp, 2); 197 dp_set_training_pattern(dp, 2);
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
index 02e369f80449..6a38402fa56c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
@@ -572,7 +572,8 @@ nv50_disp_base_ctor(struct nouveau_object *parent,
572 priv->base.vblank->priv = priv; 572 priv->base.vblank->priv = priv;
573 priv->base.vblank->enable = nv50_disp_base_vblank_enable; 573 priv->base.vblank->enable = nv50_disp_base_vblank_enable;
574 priv->base.vblank->disable = nv50_disp_base_vblank_disable; 574 priv->base.vblank->disable = nv50_disp_base_vblank_disable;
575 return nouveau_ramht_new(parent, parent, 0x1000, 0, &base->ramht); 575 return nouveau_ramht_new(nv_object(base), nv_object(base), 0x1000, 0,
576 &base->ramht);
576} 577}
577 578
578static void 579static void
@@ -719,7 +720,7 @@ nv50_disp_data_ctor(struct nouveau_object *parent,
719 if (nv_mclass(parent) != NV_DEVICE_CLASS) { 720 if (nv_mclass(parent) != NV_DEVICE_CLASS) {
720 atomic_inc(&parent->refcount); 721 atomic_inc(&parent->refcount);
721 *pobject = parent; 722 *pobject = parent;
722 return 0; 723 return 1;
723 } 724 }
724 725
725 /* allocate display hardware to client */ 726 /* allocate display hardware to client */
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
index 788dd34ccb54..019eacd8a68f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
@@ -473,7 +473,8 @@ nvd0_disp_base_ctor(struct nouveau_object *parent,
473 priv->base.vblank->enable = nvd0_disp_base_vblank_enable; 473 priv->base.vblank->enable = nvd0_disp_base_vblank_enable;
474 priv->base.vblank->disable = nvd0_disp_base_vblank_disable; 474 priv->base.vblank->disable = nvd0_disp_base_vblank_disable;
475 475
476 return nouveau_ramht_new(parent, parent, 0x1000, 0, &base->ramht); 476 return nouveau_ramht_new(nv_object(base), nv_object(base), 0x1000, 0,
477 &base->ramht);
477} 478}
478 479
479static void 480static void
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c
index 7341ebe131fa..d3ec436d9cb5 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c
@@ -91,6 +91,8 @@ nouveau_fifo_channel_create_(struct nouveau_object *parent,
91 if (!chan->user) 91 if (!chan->user)
92 return -EFAULT; 92 return -EFAULT;
93 93
94 nouveau_event_trigger(priv->cevent, 0);
95
94 chan->size = size; 96 chan->size = size;
95 return 0; 97 return 0;
96} 98}
@@ -167,6 +169,7 @@ nouveau_fifo_destroy(struct nouveau_fifo *priv)
167{ 169{
168 kfree(priv->channel); 170 kfree(priv->channel);
169 nouveau_event_destroy(&priv->uevent); 171 nouveau_event_destroy(&priv->uevent);
172 nouveau_event_destroy(&priv->cevent);
170 nouveau_engine_destroy(&priv->base); 173 nouveau_engine_destroy(&priv->base);
171} 174}
172 175
@@ -191,6 +194,10 @@ nouveau_fifo_create_(struct nouveau_object *parent,
191 if (!priv->channel) 194 if (!priv->channel)
192 return -ENOMEM; 195 return -ENOMEM;
193 196
197 ret = nouveau_event_create(1, &priv->cevent);
198 if (ret)
199 return ret;
200
194 ret = nouveau_event_create(1, &priv->uevent); 201 ret = nouveau_event_create(1, &priv->uevent);
195 if (ret) 202 if (ret)
196 return ret; 203 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
index 840af6172788..ddaeb5572903 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
@@ -210,7 +210,8 @@ nv50_fifo_chan_ctor_dma(struct nouveau_object *parent,
210 nv_parent(chan)->object_attach = nv50_fifo_object_attach; 210 nv_parent(chan)->object_attach = nv50_fifo_object_attach;
211 nv_parent(chan)->object_detach = nv50_fifo_object_detach; 211 nv_parent(chan)->object_detach = nv50_fifo_object_detach;
212 212
213 ret = nouveau_ramht_new(parent, parent, 0x8000, 16, &chan->ramht); 213 ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
214 &chan->ramht);
214 if (ret) 215 if (ret)
215 return ret; 216 return ret;
216 217
@@ -263,7 +264,8 @@ nv50_fifo_chan_ctor_ind(struct nouveau_object *parent,
263 nv_parent(chan)->object_attach = nv50_fifo_object_attach; 264 nv_parent(chan)->object_attach = nv50_fifo_object_attach;
264 nv_parent(chan)->object_detach = nv50_fifo_object_detach; 265 nv_parent(chan)->object_detach = nv50_fifo_object_detach;
265 266
266 ret = nouveau_ramht_new(parent, parent, 0x8000, 16, &chan->ramht); 267 ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
268 &chan->ramht);
267 if (ret) 269 if (ret)
268 return ret; 270 return ret;
269 271
@@ -373,17 +375,17 @@ nv50_fifo_context_ctor(struct nouveau_object *parent,
373 if (ret) 375 if (ret)
374 return ret; 376 return ret;
375 377
376 ret = nouveau_gpuobj_new(parent, nv_object(base), 0x0200, 0x1000, 378 ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x0200,
377 NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc); 379 0x1000, NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc);
378 if (ret) 380 if (ret)
379 return ret; 381 return ret;
380 382
381 ret = nouveau_gpuobj_new(parent, nv_object(base), 0x1200, 0, 383 ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x1200, 0,
382 NVOBJ_FLAG_ZERO_ALLOC, &base->eng); 384 NVOBJ_FLAG_ZERO_ALLOC, &base->eng);
383 if (ret) 385 if (ret)
384 return ret; 386 return ret;
385 387
386 ret = nouveau_gpuobj_new(parent, nv_object(base), 0x4000, 0, 0, 388 ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x4000, 0, 0,
387 &base->pgd); 389 &base->pgd);
388 if (ret) 390 if (ret)
389 return ret; 391 return ret;
@@ -437,12 +439,12 @@ nv50_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
437 if (ret) 439 if (ret)
438 return ret; 440 return ret;
439 441
440 ret = nouveau_gpuobj_new(parent, NULL, 128 * 4, 0x1000, 0, 442 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
441 &priv->playlist[0]); 443 &priv->playlist[0]);
442 if (ret) 444 if (ret)
443 return ret; 445 return ret;
444 446
445 ret = nouveau_gpuobj_new(parent, NULL, 128 * 4, 0x1000, 0, 447 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
446 &priv->playlist[1]); 448 &priv->playlist[1]);
447 if (ret) 449 if (ret)
448 return ret; 450 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
index 094000e87871..35b94bd18808 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
@@ -180,7 +180,8 @@ nv84_fifo_chan_ctor_dma(struct nouveau_object *parent,
180 if (ret) 180 if (ret)
181 return ret; 181 return ret;
182 182
183 ret = nouveau_ramht_new(parent, parent, 0x8000, 16, &chan->ramht); 183 ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
184 &chan->ramht);
184 if (ret) 185 if (ret)
185 return ret; 186 return ret;
186 187
@@ -242,7 +243,8 @@ nv84_fifo_chan_ctor_ind(struct nouveau_object *parent,
242 if (ret) 243 if (ret)
243 return ret; 244 return ret;
244 245
245 ret = nouveau_ramht_new(parent, parent, 0x8000, 16, &chan->ramht); 246 ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
247 &chan->ramht);
246 if (ret) 248 if (ret)
247 return ret; 249 return ret;
248 250
@@ -336,12 +338,12 @@ nv84_fifo_context_ctor(struct nouveau_object *parent,
336 if (ret) 338 if (ret)
337 return ret; 339 return ret;
338 340
339 ret = nouveau_gpuobj_new(parent, nv_object(base), 0x0200, 0, 341 ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x0200, 0,
340 NVOBJ_FLAG_ZERO_ALLOC, &base->eng); 342 NVOBJ_FLAG_ZERO_ALLOC, &base->eng);
341 if (ret) 343 if (ret)
342 return ret; 344 return ret;
343 345
344 ret = nouveau_gpuobj_new(parent, nv_object(base), 0x4000, 0, 346 ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x4000, 0,
345 0, &base->pgd); 347 0, &base->pgd);
346 if (ret) 348 if (ret)
347 return ret; 349 return ret;
@@ -350,13 +352,13 @@ nv84_fifo_context_ctor(struct nouveau_object *parent,
350 if (ret) 352 if (ret)
351 return ret; 353 return ret;
352 354
353 ret = nouveau_gpuobj_new(parent, nv_object(base), 0x1000, 0x400, 355 ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x1000,
354 NVOBJ_FLAG_ZERO_ALLOC, &base->cache); 356 0x400, NVOBJ_FLAG_ZERO_ALLOC, &base->cache);
355 if (ret) 357 if (ret)
356 return ret; 358 return ret;
357 359
358 ret = nouveau_gpuobj_new(parent, nv_object(base), 0x0100, 0x100, 360 ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x0100,
359 NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc); 361 0x100, NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc);
360 if (ret) 362 if (ret)
361 return ret; 363 return ret;
362 364
@@ -407,12 +409,12 @@ nv84_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
407 if (ret) 409 if (ret)
408 return ret; 410 return ret;
409 411
410 ret = nouveau_gpuobj_new(parent, NULL, 128 * 4, 0x1000, 0, 412 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
411 &priv->playlist[0]); 413 &priv->playlist[0]);
412 if (ret) 414 if (ret)
413 return ret; 415 return ret;
414 416
415 ret = nouveau_gpuobj_new(parent, NULL, 128 * 4, 0x1000, 0, 417 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
416 &priv->playlist[1]); 418 &priv->playlist[1]);
417 if (ret) 419 if (ret)
418 return ret; 420 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
index 4f226afb5591..4d4a6b905370 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
@@ -292,7 +292,8 @@ nvc0_fifo_context_ctor(struct nouveau_object *parent,
292 if (ret) 292 if (ret)
293 return ret; 293 return ret;
294 294
295 ret = nouveau_gpuobj_new(parent, NULL, 0x10000, 0x1000, 0, &base->pgd); 295 ret = nouveau_gpuobj_new(nv_object(base), NULL, 0x10000, 0x1000, 0,
296 &base->pgd);
296 if (ret) 297 if (ret)
297 return ret; 298 return ret;
298 299
@@ -623,17 +624,17 @@ nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
623 if (ret) 624 if (ret)
624 return ret; 625 return ret;
625 626
626 ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0x1000, 0, 627 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0x1000, 0,
627 &priv->playlist[0]); 628 &priv->playlist[0]);
628 if (ret) 629 if (ret)
629 return ret; 630 return ret;
630 631
631 ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0x1000, 0, 632 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0x1000, 0,
632 &priv->playlist[1]); 633 &priv->playlist[1]);
633 if (ret) 634 if (ret)
634 return ret; 635 return ret;
635 636
636 ret = nouveau_gpuobj_new(parent, NULL, 128 * 0x1000, 0x1000, 0, 637 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 0x1000, 0x1000, 0,
637 &priv->user.mem); 638 &priv->user.mem);
638 if (ret) 639 if (ret)
639 return ret; 640 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
index 4419e40d88e9..9151919fb831 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
@@ -96,7 +96,7 @@ nve0_fifo_playlist_update(struct nve0_fifo_priv *priv, u32 engine)
96 96
97 cur = engn->playlist[engn->cur_playlist]; 97 cur = engn->playlist[engn->cur_playlist];
98 if (unlikely(cur == NULL)) { 98 if (unlikely(cur == NULL)) {
99 int ret = nouveau_gpuobj_new(nv_object(priv)->parent, NULL, 99 int ret = nouveau_gpuobj_new(nv_object(priv), NULL,
100 0x8000, 0x1000, 0, &cur); 100 0x8000, 0x1000, 0, &cur);
101 if (ret) { 101 if (ret) {
102 nv_error(priv, "playlist alloc failed\n"); 102 nv_error(priv, "playlist alloc failed\n");
@@ -333,7 +333,8 @@ nve0_fifo_context_ctor(struct nouveau_object *parent,
333 if (ret) 333 if (ret)
334 return ret; 334 return ret;
335 335
336 ret = nouveau_gpuobj_new(parent, NULL, 0x10000, 0x1000, 0, &base->pgd); 336 ret = nouveau_gpuobj_new(nv_object(base), NULL, 0x10000, 0x1000, 0,
337 &base->pgd);
337 if (ret) 338 if (ret)
338 return ret; 339 return ret;
339 340
@@ -595,7 +596,7 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
595 if (ret) 596 if (ret)
596 return ret; 597 return ret;
597 598
598 ret = nouveau_gpuobj_new(parent, NULL, 4096 * 0x200, 0x1000, 599 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 4096 * 0x200, 0x1000,
599 NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem); 600 NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem);
600 if (ret) 601 if (ret)
601 return ret; 602 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c
index 0b7951a85943..4cc6269d4077 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c
@@ -36,7 +36,6 @@ int
36nvc0_grctx_init(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) 36nvc0_grctx_init(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
37{ 37{
38 struct nouveau_bar *bar = nouveau_bar(priv); 38 struct nouveau_bar *bar = nouveau_bar(priv);
39 struct nouveau_object *parent = nv_object(priv);
40 struct nouveau_gpuobj *chan; 39 struct nouveau_gpuobj *chan;
41 u32 size = (0x80000 + priv->size + 4095) & ~4095; 40 u32 size = (0x80000 + priv->size + 4095) & ~4095;
42 int ret, i; 41 int ret, i;
@@ -44,7 +43,7 @@ nvc0_grctx_init(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
44 /* allocate memory to for a "channel", which we'll use to generate 43 /* allocate memory to for a "channel", which we'll use to generate
45 * the default context values 44 * the default context values
46 */ 45 */
47 ret = nouveau_gpuobj_new(parent, NULL, size, 0x1000, 46 ret = nouveau_gpuobj_new(nv_object(priv), NULL, size, 0x1000,
48 NVOBJ_FLAG_ZERO_ALLOC, &info->chan); 47 NVOBJ_FLAG_ZERO_ALLOC, &info->chan);
49 chan = info->chan; 48 chan = info->chan;
50 if (ret) { 49 if (ret) {
@@ -1399,7 +1398,7 @@ nvc0_grctx_generate_90c0(struct nvc0_graph_priv *priv)
1399{ 1398{
1400 int i; 1399 int i;
1401 1400
1402 for (i = 0; nv_device(priv)->chipset == 0xd9 && i < 4; i++) { 1401 for (i = 0; nv_device(priv)->chipset >= 0xd0 && i < 4; i++) {
1403 nv_mthd(priv, 0x90c0, 0x2700 + (i * 0x40), 0x00000000); 1402 nv_mthd(priv, 0x90c0, 0x2700 + (i * 0x40), 0x00000000);
1404 nv_mthd(priv, 0x90c0, 0x2720 + (i * 0x40), 0x00000000); 1403 nv_mthd(priv, 0x90c0, 0x2720 + (i * 0x40), 0x00000000);
1405 nv_mthd(priv, 0x90c0, 0x2704 + (i * 0x40), 0x00000000); 1404 nv_mthd(priv, 0x90c0, 0x2704 + (i * 0x40), 0x00000000);
@@ -1415,7 +1414,7 @@ nvc0_grctx_generate_90c0(struct nvc0_graph_priv *priv)
1415 nv_mthd(priv, 0x90c0, 0x27ac, 0x00000000); 1414 nv_mthd(priv, 0x90c0, 0x27ac, 0x00000000);
1416 nv_mthd(priv, 0x90c0, 0x27cc, 0x00000000); 1415 nv_mthd(priv, 0x90c0, 0x27cc, 0x00000000);
1417 nv_mthd(priv, 0x90c0, 0x27ec, 0x00000000); 1416 nv_mthd(priv, 0x90c0, 0x27ec, 0x00000000);
1418 for (i = 0; nv_device(priv)->chipset == 0xd9 && i < 4; i++) { 1417 for (i = 0; nv_device(priv)->chipset >= 0xd0 && i < 4; i++) {
1419 nv_mthd(priv, 0x90c0, 0x2710 + (i * 0x40), 0x00014000); 1418 nv_mthd(priv, 0x90c0, 0x2710 + (i * 0x40), 0x00014000);
1420 nv_mthd(priv, 0x90c0, 0x2730 + (i * 0x40), 0x00014000); 1419 nv_mthd(priv, 0x90c0, 0x2730 + (i * 0x40), 0x00014000);
1421 nv_mthd(priv, 0x90c0, 0x2714 + (i * 0x40), 0x00000040); 1420 nv_mthd(priv, 0x90c0, 0x2714 + (i * 0x40), 0x00000040);
@@ -1615,7 +1614,7 @@ static void
1615nvc0_grctx_generate_shaders(struct nvc0_graph_priv *priv) 1614nvc0_grctx_generate_shaders(struct nvc0_graph_priv *priv)
1616{ 1615{
1617 1616
1618 if (nv_device(priv)->chipset == 0xd9) { 1617 if (nv_device(priv)->chipset >= 0xd0) {
1619 nv_wr32(priv, 0x405800, 0x0f8000bf); 1618 nv_wr32(priv, 0x405800, 0x0f8000bf);
1620 nv_wr32(priv, 0x405830, 0x02180218); 1619 nv_wr32(priv, 0x405830, 0x02180218);
1621 nv_wr32(priv, 0x405834, 0x08000000); 1620 nv_wr32(priv, 0x405834, 0x08000000);
@@ -1658,10 +1657,10 @@ nvc0_grctx_generate_unk64xx(struct nvc0_graph_priv *priv)
1658 nv_wr32(priv, 0x4064ac, 0x00003fff); 1657 nv_wr32(priv, 0x4064ac, 0x00003fff);
1659 nv_wr32(priv, 0x4064b4, 0x00000000); 1658 nv_wr32(priv, 0x4064b4, 0x00000000);
1660 nv_wr32(priv, 0x4064b8, 0x00000000); 1659 nv_wr32(priv, 0x4064b8, 0x00000000);
1661 if (nv_device(priv)->chipset == 0xd9) 1660 if (nv_device(priv)->chipset >= 0xd0)
1662 nv_wr32(priv, 0x4064bc, 0x00000000); 1661 nv_wr32(priv, 0x4064bc, 0x00000000);
1663 if (nv_device(priv)->chipset == 0xc1 || 1662 if (nv_device(priv)->chipset == 0xc1 ||
1664 nv_device(priv)->chipset == 0xd9) { 1663 nv_device(priv)->chipset >= 0xd0) {
1665 nv_wr32(priv, 0x4064c0, 0x80140078); 1664 nv_wr32(priv, 0x4064c0, 0x80140078);
1666 nv_wr32(priv, 0x4064c4, 0x0086ffff); 1665 nv_wr32(priv, 0x4064c4, 0x0086ffff);
1667 } 1666 }
@@ -1701,7 +1700,7 @@ nvc0_grctx_generate_rop(struct nvc0_graph_priv *priv)
1701 /* ROPC_BROADCAST */ 1700 /* ROPC_BROADCAST */
1702 nv_wr32(priv, 0x408800, 0x02802a3c); 1701 nv_wr32(priv, 0x408800, 0x02802a3c);
1703 nv_wr32(priv, 0x408804, 0x00000040); 1702 nv_wr32(priv, 0x408804, 0x00000040);
1704 if (chipset == 0xd9) { 1703 if (chipset >= 0xd0) {
1705 nv_wr32(priv, 0x408808, 0x1043e005); 1704 nv_wr32(priv, 0x408808, 0x1043e005);
1706 nv_wr32(priv, 0x408900, 0x3080b801); 1705 nv_wr32(priv, 0x408900, 0x3080b801);
1707 nv_wr32(priv, 0x408904, 0x1043e005); 1706 nv_wr32(priv, 0x408904, 0x1043e005);
@@ -1735,7 +1734,7 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
1735 nv_wr32(priv, 0x418408, 0x00000000); 1734 nv_wr32(priv, 0x418408, 0x00000000);
1736 nv_wr32(priv, 0x41840c, 0x00001008); 1735 nv_wr32(priv, 0x41840c, 0x00001008);
1737 nv_wr32(priv, 0x418410, 0x0fff0fff); 1736 nv_wr32(priv, 0x418410, 0x0fff0fff);
1738 nv_wr32(priv, 0x418414, chipset != 0xd9 ? 0x00200fff : 0x02200fff); 1737 nv_wr32(priv, 0x418414, chipset < 0xd0 ? 0x00200fff : 0x02200fff);
1739 nv_wr32(priv, 0x418450, 0x00000000); 1738 nv_wr32(priv, 0x418450, 0x00000000);
1740 nv_wr32(priv, 0x418454, 0x00000000); 1739 nv_wr32(priv, 0x418454, 0x00000000);
1741 nv_wr32(priv, 0x418458, 0x00000000); 1740 nv_wr32(priv, 0x418458, 0x00000000);
@@ -1750,14 +1749,14 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
1750 nv_wr32(priv, 0x418700, 0x00000002); 1749 nv_wr32(priv, 0x418700, 0x00000002);
1751 nv_wr32(priv, 0x418704, 0x00000080); 1750 nv_wr32(priv, 0x418704, 0x00000080);
1752 nv_wr32(priv, 0x418708, 0x00000000); 1751 nv_wr32(priv, 0x418708, 0x00000000);
1753 nv_wr32(priv, 0x41870c, chipset != 0xd9 ? 0x07c80000 : 0x00000000); 1752 nv_wr32(priv, 0x41870c, chipset < 0xd0 ? 0x07c80000 : 0x00000000);
1754 nv_wr32(priv, 0x418710, 0x00000000); 1753 nv_wr32(priv, 0x418710, 0x00000000);
1755 nv_wr32(priv, 0x418800, chipset != 0xd9 ? 0x0006860a : 0x7006860a); 1754 nv_wr32(priv, 0x418800, chipset < 0xd0 ? 0x0006860a : 0x7006860a);
1756 nv_wr32(priv, 0x418808, 0x00000000); 1755 nv_wr32(priv, 0x418808, 0x00000000);
1757 nv_wr32(priv, 0x41880c, 0x00000000); 1756 nv_wr32(priv, 0x41880c, 0x00000000);
1758 nv_wr32(priv, 0x418810, 0x00000000); 1757 nv_wr32(priv, 0x418810, 0x00000000);
1759 nv_wr32(priv, 0x418828, 0x00008442); 1758 nv_wr32(priv, 0x418828, 0x00008442);
1760 if (chipset == 0xc1 || chipset == 0xd9) 1759 if (chipset == 0xc1 || chipset >= 0xd0)
1761 nv_wr32(priv, 0x418830, 0x10000001); 1760 nv_wr32(priv, 0x418830, 0x10000001);
1762 else 1761 else
1763 nv_wr32(priv, 0x418830, 0x00000001); 1762 nv_wr32(priv, 0x418830, 0x00000001);
@@ -1768,7 +1767,7 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
1768 nv_wr32(priv, 0x4188f0, 0x00000000); 1767 nv_wr32(priv, 0x4188f0, 0x00000000);
1769 nv_wr32(priv, 0x4188f4, 0x00000000); 1768 nv_wr32(priv, 0x4188f4, 0x00000000);
1770 nv_wr32(priv, 0x4188f8, 0x00000000); 1769 nv_wr32(priv, 0x4188f8, 0x00000000);
1771 if (chipset == 0xd9) 1770 if (chipset >= 0xd0)
1772 nv_wr32(priv, 0x4188fc, 0x20100008); 1771 nv_wr32(priv, 0x4188fc, 0x20100008);
1773 else if (chipset == 0xc1) 1772 else if (chipset == 0xc1)
1774 nv_wr32(priv, 0x4188fc, 0x00100018); 1773 nv_wr32(priv, 0x4188fc, 0x00100018);
@@ -1787,7 +1786,7 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
1787 nv_wr32(priv, 0x418a14 + (i * 0x20), 0x00000000); 1786 nv_wr32(priv, 0x418a14 + (i * 0x20), 0x00000000);
1788 nv_wr32(priv, 0x418a18 + (i * 0x20), 0x00000000); 1787 nv_wr32(priv, 0x418a18 + (i * 0x20), 0x00000000);
1789 } 1788 }
1790 nv_wr32(priv, 0x418b00, chipset != 0xd9 ? 0x00000000 : 0x00000006); 1789 nv_wr32(priv, 0x418b00, chipset < 0xd0 ? 0x00000000 : 0x00000006);
1791 nv_wr32(priv, 0x418b08, 0x0a418820); 1790 nv_wr32(priv, 0x418b08, 0x0a418820);
1792 nv_wr32(priv, 0x418b0c, 0x062080e6); 1791 nv_wr32(priv, 0x418b0c, 0x062080e6);
1793 nv_wr32(priv, 0x418b10, 0x020398a4); 1792 nv_wr32(priv, 0x418b10, 0x020398a4);
@@ -1804,7 +1803,7 @@ nvc0_grctx_generate_gpc(struct nvc0_graph_priv *priv)
1804 nv_wr32(priv, 0x418c24, 0x00000000); 1803 nv_wr32(priv, 0x418c24, 0x00000000);
1805 nv_wr32(priv, 0x418c28, 0x00000000); 1804 nv_wr32(priv, 0x418c28, 0x00000000);
1806 nv_wr32(priv, 0x418c2c, 0x00000000); 1805 nv_wr32(priv, 0x418c2c, 0x00000000);
1807 if (chipset == 0xc1 || chipset == 0xd9) 1806 if (chipset == 0xc1 || chipset >= 0xd0)
1808 nv_wr32(priv, 0x418c6c, 0x00000001); 1807 nv_wr32(priv, 0x418c6c, 0x00000001);
1809 nv_wr32(priv, 0x418c80, 0x20200004); 1808 nv_wr32(priv, 0x418c80, 0x20200004);
1810 nv_wr32(priv, 0x418c8c, 0x00000001); 1809 nv_wr32(priv, 0x418c8c, 0x00000001);
@@ -1823,7 +1822,7 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv)
1823 nv_wr32(priv, 0x419818, 0x00000000); 1822 nv_wr32(priv, 0x419818, 0x00000000);
1824 nv_wr32(priv, 0x41983c, 0x00038bc7); 1823 nv_wr32(priv, 0x41983c, 0x00038bc7);
1825 nv_wr32(priv, 0x419848, 0x00000000); 1824 nv_wr32(priv, 0x419848, 0x00000000);
1826 if (chipset == 0xc1 || chipset == 0xd9) 1825 if (chipset == 0xc1 || chipset >= 0xd0)
1827 nv_wr32(priv, 0x419864, 0x00000129); 1826 nv_wr32(priv, 0x419864, 0x00000129);
1828 else 1827 else
1829 nv_wr32(priv, 0x419864, 0x0000012a); 1828 nv_wr32(priv, 0x419864, 0x0000012a);
@@ -1836,7 +1835,7 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv)
1836 nv_wr32(priv, 0x419a14, 0x00000200); 1835 nv_wr32(priv, 0x419a14, 0x00000200);
1837 nv_wr32(priv, 0x419a1c, 0x00000000); 1836 nv_wr32(priv, 0x419a1c, 0x00000000);
1838 nv_wr32(priv, 0x419a20, 0x00000800); 1837 nv_wr32(priv, 0x419a20, 0x00000800);
1839 if (chipset == 0xd9) 1838 if (chipset >= 0xd0)
1840 nv_wr32(priv, 0x00419ac4, 0x0017f440); 1839 nv_wr32(priv, 0x00419ac4, 0x0017f440);
1841 else if (chipset != 0xc0 && chipset != 0xc8) 1840 else if (chipset != 0xc0 && chipset != 0xc8)
1842 nv_wr32(priv, 0x00419ac4, 0x0007f440); 1841 nv_wr32(priv, 0x00419ac4, 0x0007f440);
@@ -1847,16 +1846,16 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv)
1847 nv_wr32(priv, 0x419b10, 0x0a418820); 1846 nv_wr32(priv, 0x419b10, 0x0a418820);
1848 nv_wr32(priv, 0x419b14, 0x000000e6); 1847 nv_wr32(priv, 0x419b14, 0x000000e6);
1849 nv_wr32(priv, 0x419bd0, 0x00900103); 1848 nv_wr32(priv, 0x419bd0, 0x00900103);
1850 if (chipset == 0xc1 || chipset == 0xd9) 1849 if (chipset == 0xc1 || chipset >= 0xd0)
1851 nv_wr32(priv, 0x419be0, 0x00400001); 1850 nv_wr32(priv, 0x419be0, 0x00400001);
1852 else 1851 else
1853 nv_wr32(priv, 0x419be0, 0x00000001); 1852 nv_wr32(priv, 0x419be0, 0x00000001);
1854 nv_wr32(priv, 0x419be4, 0x00000000); 1853 nv_wr32(priv, 0x419be4, 0x00000000);
1855 nv_wr32(priv, 0x419c00, chipset != 0xd9 ? 0x00000002 : 0x0000000a); 1854 nv_wr32(priv, 0x419c00, chipset < 0xd0 ? 0x00000002 : 0x0000000a);
1856 nv_wr32(priv, 0x419c04, 0x00000006); 1855 nv_wr32(priv, 0x419c04, 0x00000006);
1857 nv_wr32(priv, 0x419c08, 0x00000002); 1856 nv_wr32(priv, 0x419c08, 0x00000002);
1858 nv_wr32(priv, 0x419c20, 0x00000000); 1857 nv_wr32(priv, 0x419c20, 0x00000000);
1859 if (nv_device(priv)->chipset == 0xd9) { 1858 if (nv_device(priv)->chipset >= 0xd0) {
1860 nv_wr32(priv, 0x419c24, 0x00084210); 1859 nv_wr32(priv, 0x419c24, 0x00084210);
1861 nv_wr32(priv, 0x419c28, 0x3cf3cf3c); 1860 nv_wr32(priv, 0x419c28, 0x3cf3cf3c);
1862 nv_wr32(priv, 0x419cb0, 0x00020048); 1861 nv_wr32(priv, 0x419cb0, 0x00020048);
@@ -1868,12 +1867,12 @@ nvc0_grctx_generate_tp(struct nvc0_graph_priv *priv)
1868 } 1867 }
1869 nv_wr32(priv, 0x419ce8, 0x00000000); 1868 nv_wr32(priv, 0x419ce8, 0x00000000);
1870 nv_wr32(priv, 0x419cf4, 0x00000183); 1869 nv_wr32(priv, 0x419cf4, 0x00000183);
1871 if (chipset == 0xc1 || chipset == 0xd9) 1870 if (chipset == 0xc1 || chipset >= 0xd0)
1872 nv_wr32(priv, 0x419d20, 0x12180000); 1871 nv_wr32(priv, 0x419d20, 0x12180000);
1873 else 1872 else
1874 nv_wr32(priv, 0x419d20, 0x02180000); 1873 nv_wr32(priv, 0x419d20, 0x02180000);
1875 nv_wr32(priv, 0x419d24, 0x00001fff); 1874 nv_wr32(priv, 0x419d24, 0x00001fff);
1876 if (chipset == 0xc1 || chipset == 0xd9) 1875 if (chipset == 0xc1 || chipset >= 0xd0)
1877 nv_wr32(priv, 0x419d44, 0x02180218); 1876 nv_wr32(priv, 0x419d44, 0x02180218);
1878 nv_wr32(priv, 0x419e04, 0x00000000); 1877 nv_wr32(priv, 0x419e04, 0x00000000);
1879 nv_wr32(priv, 0x419e08, 0x00000000); 1878 nv_wr32(priv, 0x419e08, 0x00000000);
@@ -2210,7 +2209,7 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv)
2210 nv_icmd(priv, 0x00000215, 0x00000040); 2209 nv_icmd(priv, 0x00000215, 0x00000040);
2211 nv_icmd(priv, 0x00000216, 0x00000040); 2210 nv_icmd(priv, 0x00000216, 0x00000040);
2212 nv_icmd(priv, 0x00000217, 0x00000040); 2211 nv_icmd(priv, 0x00000217, 0x00000040);
2213 if (nv_device(priv)->chipset == 0xd9) { 2212 if (nv_device(priv)->chipset >= 0xd0) {
2214 for (i = 0x0400; i <= 0x0417; i++) 2213 for (i = 0x0400; i <= 0x0417; i++)
2215 nv_icmd(priv, i, 0x00000040); 2214 nv_icmd(priv, i, 0x00000040);
2216 } 2215 }
@@ -2222,7 +2221,7 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv)
2222 nv_icmd(priv, 0x0000021d, 0x0000c080); 2221 nv_icmd(priv, 0x0000021d, 0x0000c080);
2223 nv_icmd(priv, 0x0000021e, 0x0000c080); 2222 nv_icmd(priv, 0x0000021e, 0x0000c080);
2224 nv_icmd(priv, 0x0000021f, 0x0000c080); 2223 nv_icmd(priv, 0x0000021f, 0x0000c080);
2225 if (nv_device(priv)->chipset == 0xd9) { 2224 if (nv_device(priv)->chipset >= 0xd0) {
2226 for (i = 0x0440; i <= 0x0457; i++) 2225 for (i = 0x0440; i <= 0x0457; i++)
2227 nv_icmd(priv, i, 0x0000c080); 2226 nv_icmd(priv, i, 0x0000c080);
2228 } 2227 }
@@ -2789,7 +2788,7 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv)
2789 nv_icmd(priv, 0x00000585, 0x0000003f); 2788 nv_icmd(priv, 0x00000585, 0x0000003f);
2790 nv_icmd(priv, 0x00000576, 0x00000003); 2789 nv_icmd(priv, 0x00000576, 0x00000003);
2791 if (nv_device(priv)->chipset == 0xc1 || 2790 if (nv_device(priv)->chipset == 0xc1 ||
2792 nv_device(priv)->chipset == 0xd9) 2791 nv_device(priv)->chipset >= 0xd0)
2793 nv_icmd(priv, 0x0000057b, 0x00000059); 2792 nv_icmd(priv, 0x0000057b, 0x00000059);
2794 nv_icmd(priv, 0x00000586, 0x00000040); 2793 nv_icmd(priv, 0x00000586, 0x00000040);
2795 nv_icmd(priv, 0x00000582, 0x00000080); 2794 nv_icmd(priv, 0x00000582, 0x00000080);
@@ -2891,7 +2890,7 @@ nvc0_grctx_generate(struct nvc0_graph_priv *priv)
2891 nv_icmd(priv, 0x00000957, 0x00000003); 2890 nv_icmd(priv, 0x00000957, 0x00000003);
2892 nv_icmd(priv, 0x0000095e, 0x20164010); 2891 nv_icmd(priv, 0x0000095e, 0x20164010);
2893 nv_icmd(priv, 0x0000095f, 0x00000020); 2892 nv_icmd(priv, 0x0000095f, 0x00000020);
2894 if (nv_device(priv)->chipset == 0xd9) 2893 if (nv_device(priv)->chipset >= 0xd0)
2895 nv_icmd(priv, 0x0000097d, 0x00000020); 2894 nv_icmd(priv, 0x0000097d, 0x00000020);
2896 nv_icmd(priv, 0x00000683, 0x00000006); 2895 nv_icmd(priv, 0x00000683, 0x00000006);
2897 nv_icmd(priv, 0x00000685, 0x003fffff); 2896 nv_icmd(priv, 0x00000685, 0x003fffff);
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c
index 6d8c63931ee6..ae27dae3fe38 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve0.c
@@ -2772,10 +2772,15 @@ nve0_grctx_generate(struct nvc0_graph_priv *priv)
2772 for (i = 0; i < 8; i++) 2772 for (i = 0; i < 8; i++)
2773 nv_wr32(priv, 0x4064d0 + (i * 0x04), 0x00000000); 2773 nv_wr32(priv, 0x4064d0 + (i * 0x04), 0x00000000);
2774 2774
2775 nv_wr32(priv, 0x405b00, 0x201); 2775 nv_wr32(priv, 0x405b00, (priv->tpc_total << 8) | priv->gpc_nr);
2776 nv_wr32(priv, 0x408850, 0x2); 2776 if (priv->gpc_nr == 1) {
2777 nv_wr32(priv, 0x408958, 0x2); 2777 nv_mask(priv, 0x408850, 0x0000000f, priv->tpc_nr[0]);
2778 nv_wr32(priv, 0x419f78, 0xa); 2778 nv_mask(priv, 0x408958, 0x0000000f, priv->tpc_nr[0]);
2779 } else {
2780 nv_mask(priv, 0x408850, 0x0000000f, priv->gpc_nr);
2781 nv_mask(priv, 0x408958, 0x0000000f, priv->gpc_nr);
2782 }
2783 nv_mask(priv, 0x419f78, 0x00000001, 0x00000000);
2779 2784
2780 nve0_grctx_generate_icmd(priv); 2785 nve0_grctx_generate_icmd(priv);
2781 nve0_grctx_generate_a097(priv); 2786 nve0_grctx_generate_a097(priv);
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc
index b86cc60dcd56..f7055af0f2a6 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvc0.fuc
@@ -87,6 +87,11 @@ chipsets:
87.b16 #nvd9_gpc_mmio_tail 87.b16 #nvd9_gpc_mmio_tail
88.b16 #nvd9_tpc_mmio_head 88.b16 #nvd9_tpc_mmio_head
89.b16 #nvd9_tpc_mmio_tail 89.b16 #nvd9_tpc_mmio_tail
90.b8 0xd7 0 0 0
91.b16 #nvd9_gpc_mmio_head
92.b16 #nvd9_gpc_mmio_tail
93.b16 #nvd9_tpc_mmio_head
94.b16 #nvd9_tpc_mmio_tail
90.b8 0 0 0 0 95.b8 0 0 0 0
91 96
92// GPC mmio lists 97// GPC mmio lists
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc
index 0bcfa4d447e5..7fbdebb2bafb 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc
@@ -62,6 +62,9 @@ chipsets:
62.b8 0xd9 0 0 0 62.b8 0xd9 0 0 0
63.b16 #nvd9_hub_mmio_head 63.b16 #nvd9_hub_mmio_head
64.b16 #nvd9_hub_mmio_tail 64.b16 #nvd9_hub_mmio_tail
65.b8 0xd7 0 0 0
66.b16 #nvd9_hub_mmio_head
67.b16 #nvd9_hub_mmio_tail
65.b8 0 0 0 0 68.b8 0 0 0 0
66 69
67nvc0_hub_mmio_head: 70nvc0_hub_mmio_head:
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c
index 0607b9801748..b24559315903 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c
@@ -254,7 +254,7 @@ nv20_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
254 if (ret) 254 if (ret)
255 return ret; 255 return ret;
256 256
257 ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16, 257 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
258 NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab); 258 NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
259 if (ret) 259 if (ret)
260 return ret; 260 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c
index b2b650dd8b28..7a80d005a974 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv25.c
@@ -142,7 +142,7 @@ nv25_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
142 if (ret) 142 if (ret)
143 return ret; 143 return ret;
144 144
145 ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16, 145 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
146 NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab); 146 NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
147 if (ret) 147 if (ret)
148 return ret; 148 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c
index 700462fa0ae0..3e1f32ee43d4 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv2a.c
@@ -109,7 +109,7 @@ nv2a_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
109 if (ret) 109 if (ret)
110 return ret; 110 return ret;
111 111
112 ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16, 112 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
113 NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab); 113 NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
114 if (ret) 114 if (ret)
115 return ret; 115 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c
index cedadaa92d3f..e451db32e92a 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv30.c
@@ -143,7 +143,7 @@ nv30_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
143 if (ret) 143 if (ret)
144 return ret; 144 return ret;
145 145
146 ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16, 146 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
147 NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab); 147 NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
148 if (ret) 148 if (ret)
149 return ret; 149 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c
index 273f6320027b..9385ac7b44a4 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv34.c
@@ -143,7 +143,7 @@ nv34_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
143 if (ret) 143 if (ret)
144 return ret; 144 return ret;
145 145
146 ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16, 146 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
147 NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab); 147 NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
148 if (ret) 148 if (ret)
149 return ret; 149 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c
index f40ee2116ee1..9ce84b73f86a 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv35.c
@@ -141,7 +141,7 @@ nv35_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
141 if (ret) 141 if (ret)
142 return ret; 142 return ret;
143 143
144 ret = nouveau_gpuobj_new(parent, NULL, 32 * 4, 16, 144 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 32 * 4, 16,
145 NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab); 145 NVOBJ_FLAG_ZERO_ALLOC, &priv->ctxtab);
146 if (ret) 146 if (ret)
147 return ret; 147 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
index 17049d5c723d..193a5de1b482 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.c
@@ -46,6 +46,14 @@ struct nv40_graph_chan {
46 struct nouveau_graph_chan base; 46 struct nouveau_graph_chan base;
47}; 47};
48 48
49static u64
50nv40_graph_units(struct nouveau_graph *graph)
51{
52 struct nv40_graph_priv *priv = (void *)graph;
53
54 return nv_rd32(priv, 0x1540);
55}
56
49/******************************************************************************* 57/*******************************************************************************
50 * Graphics object classes 58 * Graphics object classes
51 ******************************************************************************/ 59 ******************************************************************************/
@@ -359,6 +367,8 @@ nv40_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
359 else 367 else
360 nv_engine(priv)->sclass = nv40_graph_sclass; 368 nv_engine(priv)->sclass = nv40_graph_sclass;
361 nv_engine(priv)->tile_prog = nv40_graph_tile_prog; 369 nv_engine(priv)->tile_prog = nv40_graph_tile_prog;
370
371 priv->base.units = nv40_graph_units;
362 return 0; 372 return 0;
363} 373}
364 374
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c
index f2b1a7a124f2..1ac36110ca19 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv50.c
@@ -48,6 +48,14 @@ struct nv50_graph_chan {
48 struct nouveau_graph_chan base; 48 struct nouveau_graph_chan base;
49}; 49};
50 50
51static u64
52nv50_graph_units(struct nouveau_graph *graph)
53{
54 struct nv50_graph_priv *priv = (void *)graph;
55
56 return nv_rd32(priv, 0x1540);
57}
58
51/******************************************************************************* 59/*******************************************************************************
52 * Graphics object classes 60 * Graphics object classes
53 ******************************************************************************/ 61 ******************************************************************************/
@@ -819,6 +827,8 @@ nv50_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
819 nv_subdev(priv)->intr = nv50_graph_intr; 827 nv_subdev(priv)->intr = nv50_graph_intr;
820 nv_engine(priv)->cclass = &nv50_graph_cclass; 828 nv_engine(priv)->cclass = &nv50_graph_cclass;
821 829
830 priv->base.units = nv50_graph_units;
831
822 switch (nv_device(priv)->chipset) { 832 switch (nv_device(priv)->chipset) {
823 case 0x50: 833 case 0x50:
824 nv_engine(priv)->sclass = nv50_graph_sclass; 834 nv_engine(priv)->sclass = nv50_graph_sclass;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
index 0de0dd724aff..f9b9d82c287f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
@@ -60,6 +60,19 @@ nvc8_graph_sclass[] = {
60 {} 60 {}
61}; 61};
62 62
63u64
64nvc0_graph_units(struct nouveau_graph *graph)
65{
66 struct nvc0_graph_priv *priv = (void *)graph;
67 u64 cfg;
68
69 cfg = (u32)priv->gpc_nr;
70 cfg |= (u32)priv->tpc_total << 8;
71 cfg |= (u64)priv->rop_nr << 32;
72
73 return cfg;
74}
75
63/******************************************************************************* 76/*******************************************************************************
64 * PGRAPH context 77 * PGRAPH context
65 ******************************************************************************/ 78 ******************************************************************************/
@@ -89,7 +102,8 @@ nvc0_graph_context_ctor(struct nouveau_object *parent,
89 * fuc to modify some per-context register settings on first load 102 * fuc to modify some per-context register settings on first load
90 * of the context. 103 * of the context.
91 */ 104 */
92 ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0x100, 0, &chan->mmio); 105 ret = nouveau_gpuobj_new(nv_object(chan), NULL, 0x1000, 0x100, 0,
106 &chan->mmio);
93 if (ret) 107 if (ret)
94 return ret; 108 return ret;
95 109
@@ -101,8 +115,8 @@ nvc0_graph_context_ctor(struct nouveau_object *parent,
101 115
102 /* allocate buffers referenced by mmio list */ 116 /* allocate buffers referenced by mmio list */
103 for (i = 0; data->size && i < ARRAY_SIZE(priv->mmio_data); i++) { 117 for (i = 0; data->size && i < ARRAY_SIZE(priv->mmio_data); i++) {
104 ret = nouveau_gpuobj_new(parent, NULL, data->size, data->align, 118 ret = nouveau_gpuobj_new(nv_object(chan), NULL, data->size,
105 0, &chan->data[i].mem); 119 data->align, 0, &chan->data[i].mem);
106 if (ret) 120 if (ret)
107 return ret; 121 return ret;
108 122
@@ -518,9 +532,10 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
518{ 532{
519 struct nouveau_device *device = nv_device(parent); 533 struct nouveau_device *device = nv_device(parent);
520 struct nvc0_graph_priv *priv; 534 struct nvc0_graph_priv *priv;
535 bool enable = device->chipset != 0xd7;
521 int ret, i; 536 int ret, i;
522 537
523 ret = nouveau_graph_create(parent, engine, oclass, true, &priv); 538 ret = nouveau_graph_create(parent, engine, oclass, enable, &priv);
524 *pobject = nv_object(priv); 539 *pobject = nv_object(priv);
525 if (ret) 540 if (ret)
526 return ret; 541 return ret;
@@ -529,6 +544,8 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
529 nv_subdev(priv)->intr = nvc0_graph_intr; 544 nv_subdev(priv)->intr = nvc0_graph_intr;
530 nv_engine(priv)->cclass = &nvc0_graph_cclass; 545 nv_engine(priv)->cclass = &nvc0_graph_cclass;
531 546
547 priv->base.units = nvc0_graph_units;
548
532 if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) { 549 if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) {
533 nv_info(priv, "using external firmware\n"); 550 nv_info(priv, "using external firmware\n");
534 if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) || 551 if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
@@ -551,11 +568,13 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
551 break; 568 break;
552 } 569 }
553 570
554 ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b4); 571 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
572 &priv->unk4188b4);
555 if (ret) 573 if (ret)
556 return ret; 574 return ret;
557 575
558 ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b8); 576 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
577 &priv->unk4188b8);
559 if (ret) 578 if (ret)
560 return ret; 579 return ret;
561 580
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
index a1e78de46456..c870dad0f670 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
@@ -118,6 +118,7 @@ nvc0_graph_class(void *obj)
118 return 0x9197; 118 return 0x9197;
119 case 0xc8: 119 case 0xc8:
120 case 0xd9: 120 case 0xd9:
121 case 0xd7:
121 return 0x9297; 122 return 0x9297;
122 case 0xe4: 123 case 0xe4:
123 case 0xe7: 124 case 0xe7:
@@ -169,4 +170,6 @@ int nvc0_graph_context_ctor(struct nouveau_object *, struct nouveau_object *,
169 struct nouveau_object **); 170 struct nouveau_object **);
170void nvc0_graph_context_dtor(struct nouveau_object *); 171void nvc0_graph_context_dtor(struct nouveau_object *);
171 172
173u64 nvc0_graph_units(struct nouveau_graph *);
174
172#endif 175#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
index 4857f913efdd..678c16f63055 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c
@@ -77,11 +77,207 @@ nve0_graph_ctxctl_isr(struct nvc0_graph_priv *priv)
77 nv_wr32(priv, 0x409c20, ustat); 77 nv_wr32(priv, 0x409c20, ustat);
78} 78}
79 79
80static const struct nouveau_enum nve0_mp_warp_error[] = {
81 { 0x00, "NO_ERROR" },
82 { 0x01, "STACK_MISMATCH" },
83 { 0x05, "MISALIGNED_PC" },
84 { 0x08, "MISALIGNED_GPR" },
85 { 0x09, "INVALID_OPCODE" },
86 { 0x0d, "GPR_OUT_OF_BOUNDS" },
87 { 0x0e, "MEM_OUT_OF_BOUNDS" },
88 { 0x0f, "UNALIGNED_MEM_ACCESS" },
89 { 0x11, "INVALID_PARAM" },
90 {}
91};
92
93static const struct nouveau_enum nve0_mp_global_error[] = {
94 { 2, "MULTIPLE_WARP_ERRORS" },
95 { 3, "OUT_OF_STACK_SPACE" },
96 {}
97};
98
99static const struct nouveau_enum nve0_gpc_rop_error[] = {
100 { 1, "RT_PITCH_OVERRUN" },
101 { 4, "RT_WIDTH_OVERRUN" },
102 { 5, "RT_HEIGHT_OVERRUN" },
103 { 7, "ZETA_STORAGE_TYPE_MISMATCH" },
104 { 8, "RT_STORAGE_TYPE_MISMATCH" },
105 { 10, "RT_LINEAR_MISMATCH" },
106 {}
107};
108
109static const struct nouveau_enum nve0_sked_error[] = {
110 { 7, "CONSTANT_BUFFER_SIZE" },
111 { 9, "LOCAL_MEMORY_SIZE_POS" },
112 { 10, "LOCAL_MEMORY_SIZE_NEG" },
113 { 11, "WARP_CSTACK_SIZE" },
114 { 12, "TOTAL_TEMP_SIZE" },
115 { 13, "REGISTER_COUNT" },
116 { 18, "TOTAL_THREADS" },
117 { 20, "PROGRAM_OFFSET" },
118 { 21, "SHARED_MEMORY_SIZE" },
119 { 25, "SHARED_CONFIG_TOO_SMALL" },
120 { 26, "TOTAL_REGISTER_COUNT" },
121 {}
122};
123
124static void
125nve0_graph_mp_trap(struct nvc0_graph_priv *priv, int gpc, int tp)
126{
127 int i;
128 u32 werr = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x648));
129 u32 gerr = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x650));
130
131 nv_error(priv, "GPC%i/TP%i/MP trap:", gpc, tp);
132
133 for (i = 0; i <= 31; ++i) {
134 if (!(gerr & (1 << i)))
135 continue;
136 pr_cont(" ");
137 nouveau_enum_print(nve0_mp_global_error, i);
138 }
139 if (werr) {
140 pr_cont(" ");
141 nouveau_enum_print(nve0_mp_warp_error, werr & 0xffff);
142 }
143 pr_cont("\n");
144
145 /* disable MP trap to avoid spam */
146 nv_mask(priv, TPC_UNIT(gpc, tp, 0x50c), 0x2, 0x0);
147
148 /* TODO: figure out how to resume after an MP trap */
149}
150
151static void
152nve0_graph_tp_trap(struct nvc0_graph_priv *priv, int gpc, int tp)
153{
154 u32 stat = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x508));
155
156 if (stat & 0x1) {
157 u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x224));
158 nv_error(priv, "GPC%i/TP%i/TEX trap: %08x\n",
159 gpc, tp, trap);
160
161 nv_wr32(priv, TPC_UNIT(gpc, tp, 0x224), 0xc0000000);
162 stat &= ~0x1;
163 }
164
165 if (stat & 0x2) {
166 nve0_graph_mp_trap(priv, gpc, tp);
167 stat &= ~0x2;
168 }
169
170 if (stat & 0x4) {
171 u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x084));
172 nv_error(priv, "GPC%i/TP%i/POLY trap: %08x\n",
173 gpc, tp, trap);
174
175 nv_wr32(priv, TPC_UNIT(gpc, tp, 0x084), 0xc0000000);
176 stat &= ~0x4;
177 }
178
179 if (stat & 0x8) {
180 u32 trap = nv_rd32(priv, TPC_UNIT(gpc, tp, 0x48c));
181 nv_error(priv, "GPC%i/TP%i/L1C trap: %08x\n",
182 gpc, tp, trap);
183
184 nv_wr32(priv, TPC_UNIT(gpc, tp, 0x48c), 0xc0000000);
185 stat &= ~0x8;
186 }
187
188 if (stat) {
189 nv_error(priv, "GPC%i/TP%i: unknown stat %08x\n",
190 gpc, tp, stat);
191 }
192}
193
194static void
195nve0_graph_gpc_trap(struct nvc0_graph_priv *priv)
196{
197 const u32 mask = nv_rd32(priv, 0x400118);
198 int gpc;
199
200 for (gpc = 0; gpc < 4; ++gpc) {
201 u32 stat;
202 int tp;
203
204 if (!(mask & (1 << gpc)))
205 continue;
206 stat = nv_rd32(priv, GPC_UNIT(gpc, 0x2c90));
207
208 if (stat & 0x0001) {
209 u32 trap[4];
210 int i;
211
212 trap[0] = nv_rd32(priv, GPC_UNIT(gpc, 0x0420));
213 trap[1] = nv_rd32(priv, GPC_UNIT(gpc, 0x0434));
214 trap[2] = nv_rd32(priv, GPC_UNIT(gpc, 0x0438));
215 trap[3] = nv_rd32(priv, GPC_UNIT(gpc, 0x043c));
216
217 nv_error(priv, "GPC%i/PROP trap:", gpc);
218 for (i = 0; i <= 29; ++i) {
219 if (!(trap[0] & (1 << i)))
220 continue;
221 pr_cont(" ");
222 nouveau_enum_print(nve0_gpc_rop_error, i);
223 }
224 pr_cont("\n");
225
226 nv_error(priv, "x = %u, y = %u, "
227 "format = %x, storage type = %x\n",
228 trap[1] & 0xffff,
229 trap[1] >> 16,
230 (trap[2] >> 8) & 0x3f,
231 trap[3] & 0xff);
232
233 nv_wr32(priv, GPC_UNIT(gpc, 0x0420), 0xc0000000);
234 stat &= ~0x0001;
235 }
236
237 if (stat & 0x0002) {
238 u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0900));
239 nv_error(priv, "GPC%i/ZCULL trap: %08x\n", gpc,
240 trap);
241 nv_wr32(priv, GPC_UNIT(gpc, 0x0900), 0xc0000000);
242 stat &= ~0x0002;
243 }
244
245 if (stat & 0x0004) {
246 u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x1028));
247 nv_error(priv, "GPC%i/CCACHE trap: %08x\n", gpc,
248 trap);
249 nv_wr32(priv, GPC_UNIT(gpc, 0x1028), 0xc0000000);
250 stat &= ~0x0004;
251 }
252
253 if (stat & 0x0008) {
254 u32 trap = nv_rd32(priv, GPC_UNIT(gpc, 0x0824));
255 nv_error(priv, "GPC%i/ESETUP trap %08x\n", gpc,
256 trap);
257 nv_wr32(priv, GPC_UNIT(gpc, 0x0824), 0xc0000000);
258 stat &= ~0x0008;
259 }
260
261 for (tp = 0; tp < 8; ++tp) {
262 if (stat & (1 << (16 + tp)))
263 nve0_graph_tp_trap(priv, gpc, tp);
264 }
265 stat &= ~0xff0000;
266
267 if (stat) {
268 nv_error(priv, "GPC%i: unknown stat %08x\n",
269 gpc, stat);
270 }
271 }
272}
273
274
80static void 275static void
81nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst, 276nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst,
82 struct nouveau_object *engctx) 277 struct nouveau_object *engctx)
83{ 278{
84 u32 trap = nv_rd32(priv, 0x400108); 279 u32 trap = nv_rd32(priv, 0x400108);
280 int i;
85 int rop; 281 int rop;
86 282
87 if (trap & 0x00000001) { 283 if (trap & 0x00000001) {
@@ -102,6 +298,32 @@ nve0_graph_trap_isr(struct nvc0_graph_priv *priv, int chid, u64 inst,
102 trap &= ~0x00000010; 298 trap &= ~0x00000010;
103 } 299 }
104 300
301 if (trap & 0x00000100) {
302 u32 stat = nv_rd32(priv, 0x407020);
303 nv_error(priv, "SKED ch %d [0x%010llx %s]:",
304 chid, inst, nouveau_client_name(engctx));
305
306 for (i = 0; i <= 29; ++i) {
307 if (!(stat & (1 << i)))
308 continue;
309 pr_cont(" ");
310 nouveau_enum_print(nve0_sked_error, i);
311 }
312 pr_cont("\n");
313
314 if (stat & 0x3fffffff)
315 nv_wr32(priv, 0x407020, 0x40000000);
316 nv_wr32(priv, 0x400108, 0x00000100);
317 trap &= ~0x00000100;
318 }
319
320 if (trap & 0x01000000) {
321 nv_error(priv, "GPC ch %d [0x%010llx %s]:\n",
322 chid, inst, nouveau_client_name(engctx));
323 nve0_graph_gpc_trap(priv);
324 trap &= ~0x01000000;
325 }
326
105 if (trap & 0x02000000) { 327 if (trap & 0x02000000) {
106 for (rop = 0; rop < priv->rop_nr; rop++) { 328 for (rop = 0; rop < priv->rop_nr; rop++) {
107 u32 statz = nv_rd32(priv, ROP_UNIT(rop, 0x070)); 329 u32 statz = nv_rd32(priv, ROP_UNIT(rop, 0x070));
@@ -217,6 +439,8 @@ nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
217 nv_engine(priv)->cclass = &nve0_graph_cclass; 439 nv_engine(priv)->cclass = &nve0_graph_cclass;
218 nv_engine(priv)->sclass = nve0_graph_sclass; 440 nv_engine(priv)->sclass = nve0_graph_sclass;
219 441
442 priv->base.units = nvc0_graph_units;
443
220 if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) { 444 if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) {
221 nv_info(priv, "using external firmware\n"); 445 nv_info(priv, "using external firmware\n");
222 if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) || 446 if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
@@ -227,11 +451,13 @@ nve0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
227 priv->firmware = true; 451 priv->firmware = true;
228 } 452 }
229 453
230 ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b4); 454 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
455 &priv->unk4188b4);
231 if (ret) 456 if (ret)
232 return ret; 457 return ret;
233 458
234 ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 256, 0, &priv->unk4188b8); 459 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 256, 0,
460 &priv->unk4188b8);
235 if (ret) 461 if (ret)
236 return ret; 462 return ret;
237 463
diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c
index a523eaad47e3..d698e710ddd4 100644
--- a/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c
@@ -94,6 +94,32 @@ nvc0_software_mthd_flip(struct nouveau_object *object, u32 mthd,
94 return -EINVAL; 94 return -EINVAL;
95} 95}
96 96
97static int
98nvc0_software_mthd_mp_control(struct nouveau_object *object, u32 mthd,
99 void *args, u32 size)
100{
101 struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent);
102 struct nvc0_software_priv *priv = (void *)nv_object(chan)->engine;
103 u32 data = *(u32 *)args;
104
105 switch (mthd) {
106 case 0x600:
107 nv_wr32(priv, 0x419e00, data); /* MP.PM_UNK000 */
108 break;
109 case 0x644:
110 if (data & ~0x1ffffe)
111 return -EINVAL;
112 nv_wr32(priv, 0x419e44, data); /* MP.TRAP_WARP_ERROR_EN */
113 break;
114 case 0x6ac:
115 nv_wr32(priv, 0x419eac, data); /* MP.PM_UNK0AC */
116 break;
117 default:
118 return -EINVAL;
119 }
120 return 0;
121}
122
97static struct nouveau_omthds 123static struct nouveau_omthds
98nvc0_software_omthds[] = { 124nvc0_software_omthds[] = {
99 { 0x0400, 0x0400, nvc0_software_mthd_vblsem_offset }, 125 { 0x0400, 0x0400, nvc0_software_mthd_vblsem_offset },
@@ -101,6 +127,9 @@ nvc0_software_omthds[] = {
101 { 0x0408, 0x0408, nvc0_software_mthd_vblsem_value }, 127 { 0x0408, 0x0408, nvc0_software_mthd_vblsem_value },
102 { 0x040c, 0x040c, nvc0_software_mthd_vblsem_release }, 128 { 0x040c, 0x040c, nvc0_software_mthd_vblsem_release },
103 { 0x0500, 0x0500, nvc0_software_mthd_flip }, 129 { 0x0500, 0x0500, nvc0_software_mthd_flip },
130 { 0x0600, 0x0600, nvc0_software_mthd_mp_control },
131 { 0x0644, 0x0644, nvc0_software_mthd_mp_control },
132 { 0x06ac, 0x06ac, nvc0_software_mthd_mp_control },
104 {} 133 {}
105}; 134};
106 135
diff --git a/drivers/gpu/drm/nouveau/core/include/core/device.h b/drivers/gpu/drm/nouveau/core/include/core/device.h
index d351a4e5819c..05840f3eee98 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/device.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/device.h
@@ -6,7 +6,7 @@
6#include <core/engine.h> 6#include <core/engine.h>
7 7
8enum nv_subdev_type { 8enum nv_subdev_type {
9 NVDEV_SUBDEV_DEVICE, 9 NVDEV_ENGINE_DEVICE,
10 NVDEV_SUBDEV_VBIOS, 10 NVDEV_SUBDEV_VBIOS,
11 11
12 /* All subdevs from DEVINIT to DEVINIT_LAST will be created before 12 /* All subdevs from DEVINIT to DEVINIT_LAST will be created before
@@ -57,7 +57,7 @@ enum nv_subdev_type {
57}; 57};
58 58
59struct nouveau_device { 59struct nouveau_device {
60 struct nouveau_subdev base; 60 struct nouveau_engine base;
61 struct list_head head; 61 struct list_head head;
62 62
63 struct pci_dev *pdev; 63 struct pci_dev *pdev;
@@ -99,7 +99,7 @@ nv_device(void *obj)
99 99
100#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA 100#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
101 if (unlikely(!nv_iclass(device, NV_SUBDEV_CLASS) || 101 if (unlikely(!nv_iclass(device, NV_SUBDEV_CLASS) ||
102 (nv_hclass(device) & 0xff) != NVDEV_SUBDEV_DEVICE)) { 102 (nv_hclass(device) & 0xff) != NVDEV_ENGINE_DEVICE)) {
103 nv_assert("BAD CAST -> NvDevice, 0x%08x 0x%08x", 103 nv_assert("BAD CAST -> NvDevice, 0x%08x 0x%08x",
104 nv_hclass(object), nv_hclass(device)); 104 nv_hclass(object), nv_hclass(device));
105 } 105 }
diff --git a/drivers/gpu/drm/nouveau/core/include/core/parent.h b/drivers/gpu/drm/nouveau/core/include/core/parent.h
index 31cd852c96df..9f5ea900ff00 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/parent.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/parent.h
@@ -51,8 +51,8 @@ int nouveau_parent_create_(struct nouveau_object *, struct nouveau_object *,
51void nouveau_parent_destroy(struct nouveau_parent *); 51void nouveau_parent_destroy(struct nouveau_parent *);
52 52
53void _nouveau_parent_dtor(struct nouveau_object *); 53void _nouveau_parent_dtor(struct nouveau_object *);
54#define _nouveau_parent_init _nouveau_object_init 54#define _nouveau_parent_init nouveau_object_init
55#define _nouveau_parent_fini _nouveau_object_fini 55#define _nouveau_parent_fini nouveau_object_fini
56 56
57int nouveau_parent_sclass(struct nouveau_object *, u16 handle, 57int nouveau_parent_sclass(struct nouveau_object *, u16 handle,
58 struct nouveau_object **pengine, 58 struct nouveau_object **pengine,
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/device.h b/drivers/gpu/drm/nouveau/core/include/engine/device.h
index c9e4c4afa50e..b3dd2c4c2f1e 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/device.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/device.h
@@ -18,7 +18,6 @@ int nv50_identify(struct nouveau_device *);
18int nvc0_identify(struct nouveau_device *); 18int nvc0_identify(struct nouveau_device *);
19int nve0_identify(struct nouveau_device *); 19int nve0_identify(struct nouveau_device *);
20 20
21extern struct nouveau_oclass nouveau_device_sclass[];
22struct nouveau_device *nouveau_device_find(u64 name); 21struct nouveau_device *nouveau_device_find(u64 name);
23 22
24#endif 23#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
index b46c197709f3..633c2f806482 100644
--- a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
@@ -65,7 +65,8 @@ struct nouveau_fifo_base {
65struct nouveau_fifo { 65struct nouveau_fifo {
66 struct nouveau_engine base; 66 struct nouveau_engine base;
67 67
68 struct nouveau_event *uevent; 68 struct nouveau_event *cevent; /* channel creation event */
69 struct nouveau_event *uevent; /* async user trigger */
69 70
70 struct nouveau_object **channel; 71 struct nouveau_object **channel;
71 spinlock_t lock; 72 spinlock_t lock;
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/graph.h b/drivers/gpu/drm/nouveau/core/include/engine/graph.h
index 6943b40d0817..5d392439f2ac 100644
--- a/drivers/gpu/drm/nouveau/core/include/engine/graph.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/graph.h
@@ -26,6 +26,10 @@ struct nouveau_graph_chan {
26 26
27struct nouveau_graph { 27struct nouveau_graph {
28 struct nouveau_engine base; 28 struct nouveau_engine base;
29
30 /* Returns chipset-specific counts of units packed into an u64.
31 */
32 u64 (*units)(struct nouveau_graph *);
29}; 33};
30 34
31static inline struct nouveau_graph * 35static inline struct nouveau_graph *
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h
index f351f63bc654..a1985ed3d58d 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/ltcg.h
@@ -4,8 +4,15 @@
4#include <core/subdev.h> 4#include <core/subdev.h>
5#include <core/device.h> 5#include <core/device.h>
6 6
7struct nouveau_mm_node;
8
7struct nouveau_ltcg { 9struct nouveau_ltcg {
8 struct nouveau_subdev base; 10 struct nouveau_subdev base;
11
12 int (*tags_alloc)(struct nouveau_ltcg *, u32 count,
13 struct nouveau_mm_node **);
14 void (*tags_free)(struct nouveau_ltcg *, struct nouveau_mm_node **);
15 void (*tags_clear)(struct nouveau_ltcg *, u32 first, u32 count);
9}; 16};
10 17
11static inline struct nouveau_ltcg * 18static inline struct nouveau_ltcg *
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
index fded97cea500..d5502267c30f 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h
@@ -21,18 +21,22 @@ nouveau_mc(void *obj)
21} 21}
22 22
23#define nouveau_mc_create(p,e,o,d) \ 23#define nouveau_mc_create(p,e,o,d) \
24 nouveau_subdev_create_((p), (e), (o), 0, "PMC", "master", \ 24 nouveau_mc_create_((p), (e), (o), sizeof(**d), (void **)d)
25 sizeof(**d), (void **)d) 25#define nouveau_mc_destroy(p) ({ \
26#define nouveau_mc_destroy(p) \ 26 struct nouveau_mc *pmc = (p); _nouveau_mc_dtor(nv_object(pmc)); \
27 nouveau_subdev_destroy(&(p)->base) 27})
28#define nouveau_mc_init(p) \ 28#define nouveau_mc_init(p) ({ \
29 nouveau_subdev_init(&(p)->base) 29 struct nouveau_mc *pmc = (p); _nouveau_mc_init(nv_object(pmc)); \
30#define nouveau_mc_fini(p,s) \ 30})
31 nouveau_subdev_fini(&(p)->base, (s)) 31#define nouveau_mc_fini(p,s) ({ \
32 32 struct nouveau_mc *pmc = (p); _nouveau_mc_fini(nv_object(pmc), (s)); \
33#define _nouveau_mc_dtor _nouveau_subdev_dtor 33})
34#define _nouveau_mc_init _nouveau_subdev_init 34
35#define _nouveau_mc_fini _nouveau_subdev_fini 35int nouveau_mc_create_(struct nouveau_object *, struct nouveau_object *,
36 struct nouveau_oclass *, int, void **);
37void _nouveau_mc_dtor(struct nouveau_object *);
38int _nouveau_mc_init(struct nouveau_object *);
39int _nouveau_mc_fini(struct nouveau_object *, bool);
36 40
37extern struct nouveau_oclass nv04_mc_oclass; 41extern struct nouveau_oclass nv04_mc_oclass;
38extern struct nouveau_oclass nv44_mc_oclass; 42extern struct nouveau_oclass nv44_mc_oclass;
@@ -40,8 +44,6 @@ extern struct nouveau_oclass nv50_mc_oclass;
40extern struct nouveau_oclass nv98_mc_oclass; 44extern struct nouveau_oclass nv98_mc_oclass;
41extern struct nouveau_oclass nvc0_mc_oclass; 45extern struct nouveau_oclass nvc0_mc_oclass;
42 46
43void nouveau_mc_intr(struct nouveau_subdev *);
44
45extern const struct nouveau_mc_intr nv04_mc_intr[]; 47extern const struct nouveau_mc_intr nv04_mc_intr[];
46int nv04_mc_init(struct nouveau_object *); 48int nv04_mc_init(struct nouveau_object *);
47int nv50_mc_init(struct nouveau_object *); 49int nv50_mc_init(struct nouveau_object *);
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h
index 0b20fc0d19c1..c075998d82e6 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h
@@ -73,6 +73,7 @@ int _nouveau_therm_fini(struct nouveau_object *, bool);
73 73
74extern struct nouveau_oclass nv40_therm_oclass; 74extern struct nouveau_oclass nv40_therm_oclass;
75extern struct nouveau_oclass nv50_therm_oclass; 75extern struct nouveau_oclass nv50_therm_oclass;
76extern struct nouveau_oclass nv84_therm_oclass;
76extern struct nouveau_oclass nva3_therm_oclass; 77extern struct nouveau_oclass nva3_therm_oclass;
77extern struct nouveau_oclass nvd0_therm_oclass; 78extern struct nouveau_oclass nvd0_therm_oclass;
78 79
diff --git a/drivers/gpu/drm/nouveau/core/os.h b/drivers/gpu/drm/nouveau/core/os.h
index eb496033b55c..3bd9be2ab37f 100644
--- a/drivers/gpu/drm/nouveau/core/os.h
+++ b/drivers/gpu/drm/nouveau/core/os.h
@@ -17,6 +17,7 @@
17#include <linux/acpi.h> 17#include <linux/acpi.h>
18#include <linux/dmi.h> 18#include <linux/dmi.h>
19#include <linux/reboot.h> 19#include <linux/reboot.h>
20#include <linux/interrupt.h>
20 21
21#include <asm/unaligned.h> 22#include <asm/unaligned.h>
22 23
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c
index c3acf5b70d9e..649f1ced1fe0 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nv50.c
@@ -122,18 +122,20 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
122 if (ret) 122 if (ret)
123 return ret; 123 return ret;
124 124
125 ret = nouveau_gpuobj_new(parent, NULL, 0x20000, 0, NVOBJ_FLAG_HEAP, 125 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x20000, 0,
126 &priv->mem); 126 NVOBJ_FLAG_HEAP, &priv->mem);
127 heap = nv_object(priv->mem); 127 heap = nv_object(priv->mem);
128 if (ret) 128 if (ret)
129 return ret; 129 return ret;
130 130
131 ret = nouveau_gpuobj_new(parent, heap, (device->chipset == 0x50) ? 131 ret = nouveau_gpuobj_new(nv_object(priv), heap,
132 0x1400 : 0x0200, 0, 0, &priv->pad); 132 (device->chipset == 0x50) ? 0x1400 : 0x0200,
133 0, 0, &priv->pad);
133 if (ret) 134 if (ret)
134 return ret; 135 return ret;
135 136
136 ret = nouveau_gpuobj_new(parent, heap, 0x4000, 0, 0, &priv->pgd); 137 ret = nouveau_gpuobj_new(nv_object(priv), heap, 0x4000, 0,
138 0, &priv->pgd);
137 if (ret) 139 if (ret)
138 return ret; 140 return ret;
139 141
@@ -145,9 +147,9 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
145 if (ret) 147 if (ret)
146 return ret; 148 return ret;
147 149
148 ret = nouveau_gpuobj_new(parent, heap, ((limit-- - start) >> 12) * 8, 150 ret = nouveau_gpuobj_new(nv_object(priv), heap,
149 0x1000, NVOBJ_FLAG_ZERO_ALLOC, 151 ((limit-- - start) >> 12) * 8, 0x1000,
150 &vm->pgt[0].obj[0]); 152 NVOBJ_FLAG_ZERO_ALLOC, &vm->pgt[0].obj[0]);
151 vm->pgt[0].refcount[0] = 1; 153 vm->pgt[0].refcount[0] = 1;
152 if (ret) 154 if (ret)
153 return ret; 155 return ret;
@@ -157,7 +159,7 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
157 if (ret) 159 if (ret)
158 return ret; 160 return ret;
159 161
160 ret = nouveau_gpuobj_new(parent, heap, 24, 16, 0, &priv->bar3); 162 ret = nouveau_gpuobj_new(nv_object(priv), heap, 24, 16, 0, &priv->bar3);
161 if (ret) 163 if (ret)
162 return ret; 164 return ret;
163 165
@@ -182,7 +184,7 @@ nv50_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
182 if (ret) 184 if (ret)
183 return ret; 185 return ret;
184 186
185 ret = nouveau_gpuobj_new(parent, heap, 24, 16, 0, &priv->bar1); 187 ret = nouveau_gpuobj_new(nv_object(priv), heap, 24, 16, 0, &priv->bar1);
186 if (ret) 188 if (ret)
187 return ret; 189 return ret;
188 190
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
index 77a6fb725d3f..f8a44956dec1 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
@@ -101,12 +101,14 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
101 return ret; 101 return ret;
102 102
103 /* BAR3 */ 103 /* BAR3 */
104 ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0, 0, &priv->bar[0].mem); 104 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
105 &priv->bar[0].mem);
105 mem = priv->bar[0].mem; 106 mem = priv->bar[0].mem;
106 if (ret) 107 if (ret)
107 return ret; 108 return ret;
108 109
109 ret = nouveau_gpuobj_new(parent, NULL, 0x8000, 0, 0, &priv->bar[0].pgd); 110 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
111 &priv->bar[0].pgd);
110 if (ret) 112 if (ret)
111 return ret; 113 return ret;
112 114
@@ -114,7 +116,7 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
114 if (ret) 116 if (ret)
115 return ret; 117 return ret;
116 118
117 ret = nouveau_gpuobj_new(parent, NULL, 119 ret = nouveau_gpuobj_new(nv_object(priv), NULL,
118 (pci_resource_len(pdev, 3) >> 12) * 8, 120 (pci_resource_len(pdev, 3) >> 12) * 8,
119 0x1000, NVOBJ_FLAG_ZERO_ALLOC, 121 0x1000, NVOBJ_FLAG_ZERO_ALLOC,
120 &vm->pgt[0].obj[0]); 122 &vm->pgt[0].obj[0]);
@@ -133,12 +135,14 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
133 nv_wo32(mem, 0x020c, upper_32_bits(pci_resource_len(pdev, 3) - 1)); 135 nv_wo32(mem, 0x020c, upper_32_bits(pci_resource_len(pdev, 3) - 1));
134 136
135 /* BAR1 */ 137 /* BAR1 */
136 ret = nouveau_gpuobj_new(parent, NULL, 0x1000, 0, 0, &priv->bar[1].mem); 138 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
139 &priv->bar[1].mem);
137 mem = priv->bar[1].mem; 140 mem = priv->bar[1].mem;
138 if (ret) 141 if (ret)
139 return ret; 142 return ret;
140 143
141 ret = nouveau_gpuobj_new(parent, NULL, 0x8000, 0, 0, &priv->bar[1].pgd); 144 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
145 &priv->bar[1].pgd);
142 if (ret) 146 if (ret)
143 return ret; 147 return ret;
144 148
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
index 9c41b58d57e2..c300b5e7b670 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
@@ -64,27 +64,33 @@ init_exec_force(struct nvbios_init *init, bool exec)
64static inline int 64static inline int
65init_or(struct nvbios_init *init) 65init_or(struct nvbios_init *init)
66{ 66{
67 if (init->outp) 67 if (init_exec(init)) {
68 return ffs(init->outp->or) - 1; 68 if (init->outp)
69 error("script needs OR!!\n"); 69 return ffs(init->outp->or) - 1;
70 error("script needs OR!!\n");
71 }
70 return 0; 72 return 0;
71} 73}
72 74
73static inline int 75static inline int
74init_link(struct nvbios_init *init) 76init_link(struct nvbios_init *init)
75{ 77{
76 if (init->outp) 78 if (init_exec(init)) {
77 return !(init->outp->sorconf.link & 1); 79 if (init->outp)
78 error("script needs OR link\n"); 80 return !(init->outp->sorconf.link & 1);
81 error("script needs OR link\n");
82 }
79 return 0; 83 return 0;
80} 84}
81 85
82static inline int 86static inline int
83init_crtc(struct nvbios_init *init) 87init_crtc(struct nvbios_init *init)
84{ 88{
85 if (init->crtc >= 0) 89 if (init_exec(init)) {
86 return init->crtc; 90 if (init->crtc >= 0)
87 error("script needs crtc\n"); 91 return init->crtc;
92 error("script needs crtc\n");
93 }
88 return 0; 94 return 0;
89} 95}
90 96
@@ -92,16 +98,21 @@ static u8
92init_conn(struct nvbios_init *init) 98init_conn(struct nvbios_init *init)
93{ 99{
94 struct nouveau_bios *bios = init->bios; 100 struct nouveau_bios *bios = init->bios;
101 u8 ver, len;
102 u16 conn;
95 103
96 if (init->outp) { 104 if (init_exec(init)) {
97 u8 ver, len; 105 if (init->outp) {
98 u16 conn = dcb_conn(bios, init->outp->connector, &ver, &len); 106 conn = init->outp->connector;
99 if (conn) 107 conn = dcb_conn(bios, conn, &ver, &len);
100 return nv_ro08(bios, conn); 108 if (conn)
109 return nv_ro08(bios, conn);
110 }
111
112 error("script needs connector type\n");
101 } 113 }
102 114
103 error("script needs connector type\n"); 115 return 0xff;
104 return 0x00;
105} 116}
106 117
107static inline u32 118static inline u32
@@ -227,7 +238,8 @@ init_i2c(struct nvbios_init *init, int index)
227 } else 238 } else
228 if (index < 0) { 239 if (index < 0) {
229 if (!init->outp) { 240 if (!init->outp) {
230 error("script needs output for i2c\n"); 241 if (init_exec(init))
242 error("script needs output for i2c\n");
231 return NULL; 243 return NULL;
232 } 244 }
233 245
@@ -544,7 +556,8 @@ init_tmds_reg(struct nvbios_init *init, u8 tmds)
544 return 0x6808b0 + dacoffset; 556 return 0x6808b0 + dacoffset;
545 } 557 }
546 558
547 error("tmds opcodes need dcb\n"); 559 if (init_exec(init))
560 error("tmds opcodes need dcb\n");
548 } else { 561 } else {
549 if (tmds < ARRAY_SIZE(pramdac_table)) 562 if (tmds < ARRAY_SIZE(pramdac_table))
550 return pramdac_table[tmds]; 563 return pramdac_table[tmds];
@@ -792,7 +805,8 @@ init_dp_condition(struct nvbios_init *init)
792 break; 805 break;
793 } 806 }
794 807
795 warn("script needs dp output table data\n"); 808 if (init_exec(init))
809 warn("script needs dp output table data\n");
796 break; 810 break;
797 case 5: 811 case 5:
798 if (!(init_rdauxr(init, 0x0d) & 1)) 812 if (!(init_rdauxr(init, 0x0d) & 1))
@@ -816,7 +830,7 @@ init_io_mask_or(struct nvbios_init *init)
816 u8 or = init_or(init); 830 u8 or = init_or(init);
817 u8 data; 831 u8 data;
818 832
819 trace("IO_MASK_OR\t0x03d4[0x%02x] &= ~(1 << 0x%02x)", index, or); 833 trace("IO_MASK_OR\t0x03d4[0x%02x] &= ~(1 << 0x%02x)\n", index, or);
820 init->offset += 2; 834 init->offset += 2;
821 835
822 data = init_rdvgai(init, 0x03d4, index); 836 data = init_rdvgai(init, 0x03d4, index);
@@ -835,7 +849,7 @@ init_io_or(struct nvbios_init *init)
835 u8 or = init_or(init); 849 u8 or = init_or(init);
836 u8 data; 850 u8 data;
837 851
838 trace("IO_OR\t0x03d4[0x%02x] |= (1 << 0x%02x)", index, or); 852 trace("IO_OR\t0x03d4[0x%02x] |= (1 << 0x%02x)\n", index, or);
839 init->offset += 2; 853 init->offset += 2;
840 854
841 data = init_rdvgai(init, 0x03d4, index); 855 data = init_rdvgai(init, 0x03d4, index);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
index 7606ed15b6fa..86ad59203c8b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c
@@ -23,6 +23,7 @@
23 */ 23 */
24 24
25#include <subdev/fb.h> 25#include <subdev/fb.h>
26#include <subdev/ltcg.h>
26#include <subdev/bios.h> 27#include <subdev/bios.h>
27 28
28struct nvc0_fb_priv { 29struct nvc0_fb_priv {
@@ -31,34 +32,14 @@ struct nvc0_fb_priv {
31 dma_addr_t r100c10; 32 dma_addr_t r100c10;
32}; 33};
33 34
34/* 0 = unsupported 35extern const u8 nvc0_pte_storage_type_map[256];
35 * 1 = non-compressed 36
36 * 3 = compressed
37 */
38static const u8 types[256] = {
39 1, 1, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
40 0, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0,
41 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3,
43 3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
47 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 1, 1, 1, 1, 0,
48 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49 0, 0, 0, 3, 3, 3, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0,
50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
51 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3,
52 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 3,
53 3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0,
54 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 1, 1, 0
55};
56 37
57static bool 38static bool
58nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags) 39nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags)
59{ 40{
60 u8 memtype = (tile_flags & 0x0000ff00) >> 8; 41 u8 memtype = (tile_flags & 0x0000ff00) >> 8;
61 return likely((types[memtype] == 1)); 42 return likely((nvc0_pte_storage_type_map[memtype] != 0xff));
62} 43}
63 44
64static int 45static int
@@ -130,6 +111,7 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
130 int type = (memtype & 0x0ff); 111 int type = (memtype & 0x0ff);
131 int back = (memtype & 0x800); 112 int back = (memtype & 0x800);
132 int ret; 113 int ret;
114 const bool comp = nvc0_pte_storage_type_map[type] != type;
133 115
134 size >>= 12; 116 size >>= 12;
135 align >>= 12; 117 align >>= 12;
@@ -142,10 +124,22 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
142 return -ENOMEM; 124 return -ENOMEM;
143 125
144 INIT_LIST_HEAD(&mem->regions); 126 INIT_LIST_HEAD(&mem->regions);
145 mem->memtype = type;
146 mem->size = size; 127 mem->size = size;
147 128
148 mutex_lock(&pfb->base.mutex); 129 mutex_lock(&pfb->base.mutex);
130 if (comp) {
131 struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb->base.base.parent);
132
133 /* compression only works with lpages */
134 if (align == (1 << (17 - 12))) {
135 int n = size >> 5;
136 ltcg->tags_alloc(ltcg, n, &mem->tag);
137 }
138 if (unlikely(!mem->tag))
139 type = nvc0_pte_storage_type_map[type];
140 }
141 mem->memtype = type;
142
149 do { 143 do {
150 if (back) 144 if (back)
151 ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r); 145 ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r);
@@ -168,6 +162,17 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
168 return 0; 162 return 0;
169} 163}
170 164
165static void
166nvc0_fb_vram_del(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
167{
168 struct nouveau_ltcg *ltcg = nouveau_ltcg(pfb->base.base.parent);
169
170 if ((*pmem)->tag)
171 ltcg->tags_free(ltcg, &(*pmem)->tag);
172
173 nv50_fb_vram_del(pfb, pmem);
174}
175
171static int 176static int
172nvc0_fb_init(struct nouveau_object *object) 177nvc0_fb_init(struct nouveau_object *object)
173{ 178{
@@ -178,7 +183,8 @@ nvc0_fb_init(struct nouveau_object *object)
178 if (ret) 183 if (ret)
179 return ret; 184 return ret;
180 185
181 nv_wr32(priv, 0x100c10, priv->r100c10 >> 8); 186 if (priv->r100c10_page)
187 nv_wr32(priv, 0x100c10, priv->r100c10 >> 8);
182 return 0; 188 return 0;
183} 189}
184 190
@@ -214,16 +220,16 @@ nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
214 priv->base.memtype_valid = nvc0_fb_memtype_valid; 220 priv->base.memtype_valid = nvc0_fb_memtype_valid;
215 priv->base.ram.init = nvc0_fb_vram_init; 221 priv->base.ram.init = nvc0_fb_vram_init;
216 priv->base.ram.get = nvc0_fb_vram_new; 222 priv->base.ram.get = nvc0_fb_vram_new;
217 priv->base.ram.put = nv50_fb_vram_del; 223 priv->base.ram.put = nvc0_fb_vram_del;
218 224
219 priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO); 225 priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
220 if (!priv->r100c10_page) 226 if (priv->r100c10_page) {
221 return -ENOMEM; 227 priv->r100c10 = pci_map_page(device->pdev, priv->r100c10_page,
222 228 0, PAGE_SIZE,
223 priv->r100c10 = pci_map_page(device->pdev, priv->r100c10_page, 0, 229 PCI_DMA_BIDIRECTIONAL);
224 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); 230 if (pci_dma_mapping_error(device->pdev, priv->r100c10))
225 if (pci_dma_mapping_error(device->pdev, priv->r100c10)) 231 return -EFAULT;
226 return -EFAULT; 232 }
227 233
228 return nouveau_fb_preinit(&priv->base); 234 return nouveau_fb_preinit(&priv->base);
229} 235}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
index 2e98e8a3f1aa..8ae2625415e1 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
@@ -140,12 +140,8 @@ nouveau_i2c_port_create_(struct nouveau_object *parent,
140 } 140 }
141 141
142 /* drop port's i2c subdev refcount, i2c handles this itself */ 142 /* drop port's i2c subdev refcount, i2c handles this itself */
143 if (ret == 0) { 143 if (ret == 0)
144 list_add_tail(&port->head, &i2c->ports); 144 list_add_tail(&port->head, &i2c->ports);
145 atomic_dec(&parent->refcount);
146 atomic_dec(&engine->refcount);
147 }
148
149 return ret; 145 return ret;
150} 146}
151 147
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c
index f5bbd3834116..795393d7b2f5 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.c
@@ -93,7 +93,6 @@ nv04_instmem_alloc(struct nouveau_instmem *imem, struct nouveau_object *parent,
93 u32 size, u32 align, struct nouveau_object **pobject) 93 u32 size, u32 align, struct nouveau_object **pobject)
94{ 94{
95 struct nouveau_object *engine = nv_object(imem); 95 struct nouveau_object *engine = nv_object(imem);
96 struct nv04_instmem_priv *priv = (void *)(imem);
97 int ret; 96 int ret;
98 97
99 ret = nouveau_object_ctor(parent, engine, &nv04_instobj_oclass, 98 ret = nouveau_object_ctor(parent, engine, &nv04_instobj_oclass,
@@ -101,14 +100,6 @@ nv04_instmem_alloc(struct nouveau_instmem *imem, struct nouveau_object *parent,
101 if (ret) 100 if (ret)
102 return ret; 101 return ret;
103 102
104 /* INSTMEM itself creates objects to reserve (and preserve across
105 * suspend/resume) various fixed data locations, each one of these
106 * takes a reference on INSTMEM itself, causing it to never be
107 * freed. We drop all the self-references here to avoid this.
108 */
109 if (unlikely(!priv->created))
110 atomic_dec(&engine->refcount);
111
112 return 0; 103 return 0;
113} 104}
114 105
@@ -134,27 +125,28 @@ nv04_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
134 return ret; 125 return ret;
135 126
136 /* 0x00000-0x10000: reserve for probable vbios image */ 127 /* 0x00000-0x10000: reserve for probable vbios image */
137 ret = nouveau_gpuobj_new(parent, NULL, 0x10000, 0, 0, &priv->vbios); 128 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x10000, 0, 0,
129 &priv->vbios);
138 if (ret) 130 if (ret)
139 return ret; 131 return ret;
140 132
141 /* 0x10000-0x18000: reserve for RAMHT */ 133 /* 0x10000-0x18000: reserve for RAMHT */
142 ret = nouveau_ramht_new(parent, NULL, 0x08000, 0, &priv->ramht); 134 ret = nouveau_ramht_new(nv_object(priv), NULL, 0x08000, 0, &priv->ramht);
143 if (ret) 135 if (ret)
144 return ret; 136 return ret;
145 137
146 /* 0x18000-0x18800: reserve for RAMFC (enough for 32 nv30 channels) */ 138 /* 0x18000-0x18800: reserve for RAMFC (enough for 32 nv30 channels) */
147 ret = nouveau_gpuobj_new(parent, NULL, 0x00800, 0, 139 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x00800, 0,
148 NVOBJ_FLAG_ZERO_ALLOC, &priv->ramfc); 140 NVOBJ_FLAG_ZERO_ALLOC, &priv->ramfc);
149 if (ret) 141 if (ret)
150 return ret; 142 return ret;
151 143
152 /* 0x18800-0x18a00: reserve for RAMRO */ 144 /* 0x18800-0x18a00: reserve for RAMRO */
153 ret = nouveau_gpuobj_new(parent, NULL, 0x00200, 0, 0, &priv->ramro); 145 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x00200, 0, 0,
146 &priv->ramro);
154 if (ret) 147 if (ret)
155 return ret; 148 return ret;
156 149
157 priv->created = true;
158 return 0; 150 return 0;
159} 151}
160 152
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h
index 7983d8d9b358..b15b61310236 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv04.h
@@ -9,7 +9,6 @@
9 9
10struct nv04_instmem_priv { 10struct nv04_instmem_priv {
11 struct nouveau_instmem base; 11 struct nouveau_instmem base;
12 bool created;
13 12
14 void __iomem *iomem; 13 void __iomem *iomem;
15 struct nouveau_mm heap; 14 struct nouveau_mm heap;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c
index da64253201ef..716bf41bc3c1 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c
@@ -82,31 +82,33 @@ nv40_instmem_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
82 return ret; 82 return ret;
83 83
84 /* 0x00000-0x10000: reserve for probable vbios image */ 84 /* 0x00000-0x10000: reserve for probable vbios image */
85 ret = nouveau_gpuobj_new(parent, NULL, 0x10000, 0, 0, &priv->vbios); 85 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x10000, 0, 0,
86 &priv->vbios);
86 if (ret) 87 if (ret)
87 return ret; 88 return ret;
88 89
89 /* 0x10000-0x18000: reserve for RAMHT */ 90 /* 0x10000-0x18000: reserve for RAMHT */
90 ret = nouveau_ramht_new(parent, NULL, 0x08000, 0, &priv->ramht); 91 ret = nouveau_ramht_new(nv_object(priv), NULL, 0x08000, 0,
92 &priv->ramht);
91 if (ret) 93 if (ret)
92 return ret; 94 return ret;
93 95
94 /* 0x18000-0x18200: reserve for RAMRO 96 /* 0x18000-0x18200: reserve for RAMRO
95 * 0x18200-0x20000: padding 97 * 0x18200-0x20000: padding
96 */ 98 */
97 ret = nouveau_gpuobj_new(parent, NULL, 0x08000, 0, 0, &priv->ramro); 99 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x08000, 0, 0,
100 &priv->ramro);
98 if (ret) 101 if (ret)
99 return ret; 102 return ret;
100 103
101 /* 0x20000-0x21000: reserve for RAMFC 104 /* 0x20000-0x21000: reserve for RAMFC
102 * 0x21000-0x40000: padding and some unknown crap 105 * 0x21000-0x40000: padding and some unknown crap
103 */ 106 */
104 ret = nouveau_gpuobj_new(parent, NULL, 0x20000, 0, 107 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x20000, 0,
105 NVOBJ_FLAG_ZERO_ALLOC, &priv->ramfc); 108 NVOBJ_FLAG_ZERO_ALLOC, &priv->ramfc);
106 if (ret) 109 if (ret)
107 return ret; 110 return ret;
108 111
109 priv->created = true;
110 return 0; 112 return 0;
111} 113}
112 114
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
index 078a2b9d6bd6..e4940fb166e8 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/ltcg/nvc0.c
@@ -23,10 +23,17 @@
23 */ 23 */
24 24
25#include <subdev/ltcg.h> 25#include <subdev/ltcg.h>
26#include <subdev/fb.h>
27#include <subdev/timer.h>
26 28
27struct nvc0_ltcg_priv { 29struct nvc0_ltcg_priv {
28 struct nouveau_ltcg base; 30 struct nouveau_ltcg base;
31 u32 part_nr;
32 u32 part_mask;
29 u32 subp_nr; 33 u32 subp_nr;
34 struct nouveau_mm tags;
35 u32 num_tags;
36 struct nouveau_mm_node *tag_ram;
30}; 37};
31 38
32static void 39static void
@@ -62,11 +69,104 @@ nvc0_ltcg_intr(struct nouveau_subdev *subdev)
62} 69}
63 70
64static int 71static int
72nvc0_ltcg_tags_alloc(struct nouveau_ltcg *ltcg, u32 n,
73 struct nouveau_mm_node **pnode)
74{
75 struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
76 int ret;
77
78 ret = nouveau_mm_head(&priv->tags, 1, n, n, 1, pnode);
79 if (ret)
80 *pnode = NULL;
81
82 return ret;
83}
84
85static void
86nvc0_ltcg_tags_free(struct nouveau_ltcg *ltcg, struct nouveau_mm_node **pnode)
87{
88 struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
89
90 nouveau_mm_free(&priv->tags, pnode);
91}
92
93static void
94nvc0_ltcg_tags_clear(struct nouveau_ltcg *ltcg, u32 first, u32 count)
95{
96 struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
97 u32 last = first + count - 1;
98 int p, i;
99
100 BUG_ON((first > last) || (last >= priv->num_tags));
101
102 nv_wr32(priv, 0x17e8cc, first);
103 nv_wr32(priv, 0x17e8d0, last);
104 nv_wr32(priv, 0x17e8c8, 0x4); /* trigger clear */
105
106 /* wait until it's finished with clearing */
107 for (p = 0; p < priv->part_nr; ++p) {
108 if (!(priv->part_mask & (1 << p)))
109 continue;
110 for (i = 0; i < priv->subp_nr; ++i)
111 nv_wait(priv, 0x1410c8 + p * 0x2000 + i * 0x400, ~0, 0);
112 }
113}
114
115/* TODO: Figure out tag memory details and drop the over-cautious allocation.
116 */
117static int
118nvc0_ltcg_init_tag_ram(struct nouveau_fb *pfb, struct nvc0_ltcg_priv *priv)
119{
120 u32 tag_size, tag_margin, tag_align;
121 int ret;
122
123 nv_wr32(priv, 0x17e8d8, priv->part_nr);
124
125 /* tags for 1/4 of VRAM should be enough (8192/4 per GiB of VRAM) */
126 priv->num_tags = (pfb->ram.size >> 17) / 4;
127 if (priv->num_tags > (1 << 17))
128 priv->num_tags = 1 << 17; /* we have 17 bits in PTE */
129 priv->num_tags = (priv->num_tags + 63) & ~63; /* round up to 64 */
130
131 tag_align = priv->part_nr * 0x800;
132 tag_margin = (tag_align < 0x6000) ? 0x6000 : tag_align;
133
134 /* 4 part 4 sub: 0x2000 bytes for 56 tags */
135 /* 3 part 4 sub: 0x6000 bytes for 168 tags */
136 /*
137 * About 147 bytes per tag. Let's be safe and allocate x2, which makes
138 * 0x4980 bytes for 64 tags, and round up to 0x6000 bytes for 64 tags.
139 *
140 * For 4 GiB of memory we'll have 8192 tags which makes 3 MiB, < 0.1 %.
141 */
142 tag_size = (priv->num_tags / 64) * 0x6000 + tag_margin;
143 tag_size += tag_align;
144 tag_size = (tag_size + 0xfff) >> 12; /* round up */
145
146 ret = nouveau_mm_tail(&pfb->vram, 0, tag_size, tag_size, 1,
147 &priv->tag_ram);
148 if (ret) {
149 priv->num_tags = 0;
150 } else {
151 u64 tag_base = (priv->tag_ram->offset << 12) + tag_margin;
152
153 tag_base += tag_align - 1;
154 ret = do_div(tag_base, tag_align);
155
156 nv_wr32(priv, 0x17e8d4, tag_base);
157 }
158 ret = nouveau_mm_init(&priv->tags, 0, priv->num_tags, 1);
159
160 return ret;
161}
162
163static int
65nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 164nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
66 struct nouveau_oclass *oclass, void *data, u32 size, 165 struct nouveau_oclass *oclass, void *data, u32 size,
67 struct nouveau_object **pobject) 166 struct nouveau_object **pobject)
68{ 167{
69 struct nvc0_ltcg_priv *priv; 168 struct nvc0_ltcg_priv *priv;
169 struct nouveau_fb *pfb = nouveau_fb(parent);
70 int ret; 170 int ret;
71 171
72 ret = nouveau_ltcg_create(parent, engine, oclass, &priv); 172 ret = nouveau_ltcg_create(parent, engine, oclass, &priv);
@@ -74,19 +174,44 @@ nvc0_ltcg_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
74 if (ret) 174 if (ret)
75 return ret; 175 return ret;
76 176
77 priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 24; 177 priv->part_nr = nv_rd32(priv, 0x022438);
178 priv->part_mask = nv_rd32(priv, 0x022554);
179
180 priv->subp_nr = nv_rd32(priv, 0x17e8dc) >> 28;
181
78 nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */ 182 nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */
79 183
184 ret = nvc0_ltcg_init_tag_ram(pfb, priv);
185 if (ret)
186 return ret;
187
188 priv->base.tags_alloc = nvc0_ltcg_tags_alloc;
189 priv->base.tags_free = nvc0_ltcg_tags_free;
190 priv->base.tags_clear = nvc0_ltcg_tags_clear;
191
80 nv_subdev(priv)->intr = nvc0_ltcg_intr; 192 nv_subdev(priv)->intr = nvc0_ltcg_intr;
81 return 0; 193 return 0;
82} 194}
83 195
196static void
197nvc0_ltcg_dtor(struct nouveau_object *object)
198{
199 struct nouveau_ltcg *ltcg = (struct nouveau_ltcg *)object;
200 struct nvc0_ltcg_priv *priv = (struct nvc0_ltcg_priv *)ltcg;
201 struct nouveau_fb *pfb = nouveau_fb(ltcg->base.base.parent);
202
203 nouveau_mm_fini(&priv->tags);
204 nouveau_mm_free(&pfb->vram, &priv->tag_ram);
205
206 nouveau_ltcg_destroy(ltcg);
207}
208
84struct nouveau_oclass 209struct nouveau_oclass
85nvc0_ltcg_oclass = { 210nvc0_ltcg_oclass = {
86 .handle = NV_SUBDEV(LTCG, 0xc0), 211 .handle = NV_SUBDEV(LTCG, 0xc0),
87 .ofuncs = &(struct nouveau_ofuncs) { 212 .ofuncs = &(struct nouveau_ofuncs) {
88 .ctor = nvc0_ltcg_ctor, 213 .ctor = nvc0_ltcg_ctor,
89 .dtor = _nouveau_ltcg_dtor, 214 .dtor = nvc0_ltcg_dtor,
90 .init = _nouveau_ltcg_init, 215 .init = _nouveau_ltcg_init,
91 .fini = _nouveau_ltcg_fini, 216 .fini = _nouveau_ltcg_fini,
92 }, 217 },
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
index 8379aafa6e1b..1c0330b8c9a4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c
@@ -24,10 +24,10 @@
24 24
25#include <subdev/mc.h> 25#include <subdev/mc.h>
26 26
27void 27static irqreturn_t
28nouveau_mc_intr(struct nouveau_subdev *subdev) 28nouveau_mc_intr(int irq, void *arg)
29{ 29{
30 struct nouveau_mc *pmc = nouveau_mc(subdev); 30 struct nouveau_mc *pmc = arg;
31 const struct nouveau_mc_intr *map = pmc->intr_map; 31 const struct nouveau_mc_intr *map = pmc->intr_map;
32 struct nouveau_subdev *unit; 32 struct nouveau_subdev *unit;
33 u32 stat, intr; 33 u32 stat, intr;
@@ -35,7 +35,7 @@ nouveau_mc_intr(struct nouveau_subdev *subdev)
35 intr = stat = nv_rd32(pmc, 0x000100); 35 intr = stat = nv_rd32(pmc, 0x000100);
36 while (stat && map->stat) { 36 while (stat && map->stat) {
37 if (stat & map->stat) { 37 if (stat & map->stat) {
38 unit = nouveau_subdev(subdev, map->unit); 38 unit = nouveau_subdev(pmc, map->unit);
39 if (unit && unit->intr) 39 if (unit && unit->intr)
40 unit->intr(unit); 40 unit->intr(unit);
41 intr &= ~map->stat; 41 intr &= ~map->stat;
@@ -46,4 +46,56 @@ nouveau_mc_intr(struct nouveau_subdev *subdev)
46 if (intr) { 46 if (intr) {
47 nv_error(pmc, "unknown intr 0x%08x\n", stat); 47 nv_error(pmc, "unknown intr 0x%08x\n", stat);
48 } 48 }
49
50 return stat ? IRQ_HANDLED : IRQ_NONE;
51}
52
53int
54_nouveau_mc_fini(struct nouveau_object *object, bool suspend)
55{
56 struct nouveau_mc *pmc = (void *)object;
57 nv_wr32(pmc, 0x000140, 0x00000000);
58 return nouveau_subdev_fini(&pmc->base, suspend);
59}
60
61int
62_nouveau_mc_init(struct nouveau_object *object)
63{
64 struct nouveau_mc *pmc = (void *)object;
65 int ret = nouveau_subdev_init(&pmc->base);
66 if (ret)
67 return ret;
68 nv_wr32(pmc, 0x000140, 0x00000001);
69 return 0;
70}
71
72void
73_nouveau_mc_dtor(struct nouveau_object *object)
74{
75 struct nouveau_device *device = nv_device(object);
76 struct nouveau_mc *pmc = (void *)object;
77 free_irq(device->pdev->irq, pmc);
78 nouveau_subdev_destroy(&pmc->base);
79}
80
81int
82nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
83 struct nouveau_oclass *oclass, int length, void **pobject)
84{
85 struct nouveau_device *device = nv_device(parent);
86 struct nouveau_mc *pmc;
87 int ret;
88
89 ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PMC",
90 "master", length, pobject);
91 pmc = *pobject;
92 if (ret)
93 return ret;
94
95 ret = request_irq(device->pdev->irq, nouveau_mc_intr,
96 IRQF_SHARED, "nouveau", pmc);
97 if (ret < 0)
98 return ret;
99
100 return 0;
49} 101}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c
index 89da8fa7ea0f..8c769715227b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c
@@ -55,7 +55,6 @@ nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
55 if (ret) 55 if (ret)
56 return ret; 56 return ret;
57 57
58 nv_subdev(priv)->intr = nouveau_mc_intr;
59 priv->base.intr_map = nv04_mc_intr; 58 priv->base.intr_map = nv04_mc_intr;
60 return 0; 59 return 0;
61} 60}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c
index 397d868359ad..51919371810f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c
@@ -41,7 +41,6 @@ nv44_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
41 if (ret) 41 if (ret)
42 return ret; 42 return ret;
43 43
44 nv_subdev(priv)->intr = nouveau_mc_intr;
45 priv->base.intr_map = nv04_mc_intr; 44 priv->base.intr_map = nv04_mc_intr;
46 return 0; 45 return 0;
47} 46}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
index 5965add6daee..d796924f9930 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
@@ -57,7 +57,6 @@ nv50_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
57 if (ret) 57 if (ret)
58 return ret; 58 return ret;
59 59
60 nv_subdev(priv)->intr = nouveau_mc_intr;
61 priv->base.intr_map = nv50_mc_intr; 60 priv->base.intr_map = nv50_mc_intr;
62 return 0; 61 return 0;
63} 62}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c
index 3a80b29dce0f..e82fd21b5041 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c
@@ -59,7 +59,6 @@ nv98_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
59 if (ret) 59 if (ret)
60 return ret; 60 return ret;
61 61
62 nv_subdev(priv)->intr = nouveau_mc_intr;
63 priv->base.intr_map = nv98_mc_intr; 62 priv->base.intr_map = nv98_mc_intr;
64 return 0; 63 return 0;
65} 64}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
index 42bbf72023a8..737bd4b682e1 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
@@ -61,7 +61,6 @@ nvc0_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
61 if (ret) 61 if (ret)
62 return ret; 62 return ret;
63 63
64 nv_subdev(priv)->intr = nouveau_mc_intr;
65 priv->base.intr_map = nvc0_mc_intr; 64 priv->base.intr_map = nvc0_mc_intr;
66 return 0; 65 return 0;
67} 66}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c
index a70d1b7e397b..002e51b3af93 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c
@@ -165,7 +165,7 @@ nv40_fan_pwm_set(struct nouveau_therm *therm, int line, u32 divs, u32 duty)
165 return 0; 165 return 0;
166} 166}
167 167
168static void 168void
169nv40_therm_intr(struct nouveau_subdev *subdev) 169nv40_therm_intr(struct nouveau_subdev *subdev)
170{ 170{
171 struct nouveau_therm *therm = nouveau_therm(subdev); 171 struct nouveau_therm *therm = nouveau_therm(subdev);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c
index 86632cbd65ce..8cf7597a2182 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c
@@ -118,145 +118,36 @@ nv50_fan_pwm_clock(struct nouveau_therm *therm)
118 return pwm_clock; 118 return pwm_clock;
119} 119}
120 120
121int
122nv50_temp_get(struct nouveau_therm *therm)
123{
124 return nv_rd32(therm, 0x20400);
125}
126
127static void
128nv50_therm_program_alarms(struct nouveau_therm *therm)
129{
130 struct nouveau_therm_priv *priv = (void *)therm;
131 struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
132 unsigned long flags;
133
134 spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags);
135
136 /* enable RISING and FALLING IRQs for shutdown, THRS 0, 1, 2 and 4 */
137 nv_wr32(therm, 0x20000, 0x000003ff);
138
139 /* shutdown: The computer should be shutdown when reached */
140 nv_wr32(therm, 0x20484, sensor->thrs_shutdown.hysteresis);
141 nv_wr32(therm, 0x20480, sensor->thrs_shutdown.temp);
142
143 /* THRS_1 : fan boost*/
144 nv_wr32(therm, 0x204c4, sensor->thrs_fan_boost.temp);
145
146 /* THRS_2 : critical */
147 nv_wr32(therm, 0x204c0, sensor->thrs_critical.temp);
148
149 /* THRS_4 : down clock */
150 nv_wr32(therm, 0x20414, sensor->thrs_down_clock.temp);
151 spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags);
152
153 nv_info(therm,
154 "Programmed thresholds [ %d(%d), %d(%d), %d(%d), %d(%d) ]\n",
155 sensor->thrs_fan_boost.temp, sensor->thrs_fan_boost.hysteresis,
156 sensor->thrs_down_clock.temp,
157 sensor->thrs_down_clock.hysteresis,
158 sensor->thrs_critical.temp, sensor->thrs_critical.hysteresis,
159 sensor->thrs_shutdown.temp, sensor->thrs_shutdown.hysteresis);
160
161}
162
163/* must be called with alarm_program_lock taken ! */
164static void 121static void
165nv50_therm_threshold_hyst_emulation(struct nouveau_therm *therm, 122nv50_sensor_setup(struct nouveau_therm *therm)
166 uint32_t thrs_reg, u8 status_bit,
167 const struct nvbios_therm_threshold *thrs,
168 enum nouveau_therm_thrs thrs_name)
169{ 123{
170 enum nouveau_therm_thrs_direction direction; 124 nv_mask(therm, 0x20010, 0x40000000, 0x0);
171 enum nouveau_therm_thrs_state prev_state, new_state; 125 mdelay(20); /* wait for the temperature to stabilize */
172 int temp, cur;
173
174 prev_state = nouveau_therm_sensor_get_threshold_state(therm, thrs_name);
175 temp = nv_rd32(therm, thrs_reg);
176
177 /* program the next threshold */
178 if (temp == thrs->temp) {
179 nv_wr32(therm, thrs_reg, thrs->temp - thrs->hysteresis);
180 new_state = NOUVEAU_THERM_THRS_HIGHER;
181 } else {
182 nv_wr32(therm, thrs_reg, thrs->temp);
183 new_state = NOUVEAU_THERM_THRS_LOWER;
184 }
185
186 /* fix the state (in case someone reprogrammed the alarms) */
187 cur = therm->temp_get(therm);
188 if (new_state == NOUVEAU_THERM_THRS_LOWER && cur > thrs->temp)
189 new_state = NOUVEAU_THERM_THRS_HIGHER;
190 else if (new_state == NOUVEAU_THERM_THRS_HIGHER &&
191 cur < thrs->temp - thrs->hysteresis)
192 new_state = NOUVEAU_THERM_THRS_LOWER;
193 nouveau_therm_sensor_set_threshold_state(therm, thrs_name, new_state);
194
195 /* find the direction */
196 if (prev_state < new_state)
197 direction = NOUVEAU_THERM_THRS_RISING;
198 else if (prev_state > new_state)
199 direction = NOUVEAU_THERM_THRS_FALLING;
200 else
201 return;
202
203 /* advertise a change in direction */
204 nouveau_therm_sensor_event(therm, thrs_name, direction);
205} 126}
206 127
207static void 128static int
208nv50_therm_intr(struct nouveau_subdev *subdev) 129nv50_temp_get(struct nouveau_therm *therm)
209{ 130{
210 struct nouveau_therm *therm = nouveau_therm(subdev);
211 struct nouveau_therm_priv *priv = (void *)therm; 131 struct nouveau_therm_priv *priv = (void *)therm;
212 struct nvbios_therm_sensor *sensor = &priv->bios_sensor; 132 struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
213 unsigned long flags; 133 int core_temp;
214 uint32_t intr;
215
216 spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags);
217
218 intr = nv_rd32(therm, 0x20100);
219
220 /* THRS_4: downclock */
221 if (intr & 0x002) {
222 nv50_therm_threshold_hyst_emulation(therm, 0x20414, 24,
223 &sensor->thrs_down_clock,
224 NOUVEAU_THERM_THRS_DOWNCLOCK);
225 intr &= ~0x002;
226 }
227 134
228 /* shutdown */ 135 core_temp = nv_rd32(therm, 0x20014) & 0x3fff;
229 if (intr & 0x004) {
230 nv50_therm_threshold_hyst_emulation(therm, 0x20480, 20,
231 &sensor->thrs_shutdown,
232 NOUVEAU_THERM_THRS_SHUTDOWN);
233 intr &= ~0x004;
234 }
235
236 /* THRS_1 : fan boost */
237 if (intr & 0x008) {
238 nv50_therm_threshold_hyst_emulation(therm, 0x204c4, 21,
239 &sensor->thrs_fan_boost,
240 NOUVEAU_THERM_THRS_FANBOOST);
241 intr &= ~0x008;
242 }
243 136
244 /* THRS_2 : critical */ 137 /* if the slope or the offset is unset, do no use the sensor */
245 if (intr & 0x010) { 138 if (!sensor->slope_div || !sensor->slope_mult ||
246 nv50_therm_threshold_hyst_emulation(therm, 0x204c0, 22, 139 !sensor->offset_num || !sensor->offset_den)
247 &sensor->thrs_critical, 140 return -ENODEV;
248 NOUVEAU_THERM_THRS_CRITICAL);
249 intr &= ~0x010;
250 }
251 141
252 if (intr) 142 core_temp = core_temp * sensor->slope_mult / sensor->slope_div;
253 nv_error(therm, "unhandled intr 0x%08x\n", intr); 143 core_temp = core_temp + sensor->offset_num / sensor->offset_den;
144 core_temp = core_temp + sensor->offset_constant - 8;
254 145
255 /* ACK everything */ 146 /* reserve negative temperatures for errors */
256 nv_wr32(therm, 0x20100, 0xffffffff); 147 if (core_temp < 0)
257 nv_wr32(therm, 0x1100, 0x10000); /* PBUS */ 148 core_temp = 0;
258 149
259 spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags); 150 return core_temp;
260} 151}
261 152
262static int 153static int
@@ -278,33 +169,29 @@ nv50_therm_ctor(struct nouveau_object *parent,
278 priv->base.base.pwm_set = nv50_fan_pwm_set; 169 priv->base.base.pwm_set = nv50_fan_pwm_set;
279 priv->base.base.pwm_clock = nv50_fan_pwm_clock; 170 priv->base.base.pwm_clock = nv50_fan_pwm_clock;
280 priv->base.base.temp_get = nv50_temp_get; 171 priv->base.base.temp_get = nv50_temp_get;
281 priv->base.sensor.program_alarms = nv50_therm_program_alarms; 172 priv->base.sensor.program_alarms = nouveau_therm_program_alarms_polling;
282 nv_subdev(priv)->intr = nv50_therm_intr; 173 nv_subdev(priv)->intr = nv40_therm_intr;
283
284 /* init the thresholds */
285 nouveau_therm_sensor_set_threshold_state(&priv->base.base,
286 NOUVEAU_THERM_THRS_SHUTDOWN,
287 NOUVEAU_THERM_THRS_LOWER);
288 nouveau_therm_sensor_set_threshold_state(&priv->base.base,
289 NOUVEAU_THERM_THRS_FANBOOST,
290 NOUVEAU_THERM_THRS_LOWER);
291 nouveau_therm_sensor_set_threshold_state(&priv->base.base,
292 NOUVEAU_THERM_THRS_CRITICAL,
293 NOUVEAU_THERM_THRS_LOWER);
294 nouveau_therm_sensor_set_threshold_state(&priv->base.base,
295 NOUVEAU_THERM_THRS_DOWNCLOCK,
296 NOUVEAU_THERM_THRS_LOWER);
297 174
298 return nouveau_therm_preinit(&priv->base.base); 175 return nouveau_therm_preinit(&priv->base.base);
299} 176}
300 177
178static int
179nv50_therm_init(struct nouveau_object *object)
180{
181 struct nouveau_therm *therm = (void *)object;
182
183 nv50_sensor_setup(therm);
184
185 return _nouveau_therm_init(object);
186}
187
301struct nouveau_oclass 188struct nouveau_oclass
302nv50_therm_oclass = { 189nv50_therm_oclass = {
303 .handle = NV_SUBDEV(THERM, 0x50), 190 .handle = NV_SUBDEV(THERM, 0x50),
304 .ofuncs = &(struct nouveau_ofuncs) { 191 .ofuncs = &(struct nouveau_ofuncs) {
305 .ctor = nv50_therm_ctor, 192 .ctor = nv50_therm_ctor,
306 .dtor = _nouveau_therm_dtor, 193 .dtor = _nouveau_therm_dtor,
307 .init = _nouveau_therm_init, 194 .init = nv50_therm_init,
308 .fini = _nouveau_therm_fini, 195 .fini = _nouveau_therm_fini,
309 }, 196 },
310}; 197};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c
new file mode 100644
index 000000000000..42ba633ccff7
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c
@@ -0,0 +1,221 @@
1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 * Martin Peres
24 */
25
26#include "priv.h"
27
28struct nv84_therm_priv {
29 struct nouveau_therm_priv base;
30};
31
32int
33nv84_temp_get(struct nouveau_therm *therm)
34{
35 return nv_rd32(therm, 0x20400);
36}
37
38static void
39nv84_therm_program_alarms(struct nouveau_therm *therm)
40{
41 struct nouveau_therm_priv *priv = (void *)therm;
42 struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
43 unsigned long flags;
44
45 spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags);
46
47 /* enable RISING and FALLING IRQs for shutdown, THRS 0, 1, 2 and 4 */
48 nv_wr32(therm, 0x20000, 0x000003ff);
49
50 /* shutdown: The computer should be shutdown when reached */
51 nv_wr32(therm, 0x20484, sensor->thrs_shutdown.hysteresis);
52 nv_wr32(therm, 0x20480, sensor->thrs_shutdown.temp);
53
54 /* THRS_1 : fan boost*/
55 nv_wr32(therm, 0x204c4, sensor->thrs_fan_boost.temp);
56
57 /* THRS_2 : critical */
58 nv_wr32(therm, 0x204c0, sensor->thrs_critical.temp);
59
60 /* THRS_4 : down clock */
61 nv_wr32(therm, 0x20414, sensor->thrs_down_clock.temp);
62 spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags);
63
64 nv_debug(therm,
65 "Programmed thresholds [ %d(%d), %d(%d), %d(%d), %d(%d) ]\n",
66 sensor->thrs_fan_boost.temp, sensor->thrs_fan_boost.hysteresis,
67 sensor->thrs_down_clock.temp,
68 sensor->thrs_down_clock.hysteresis,
69 sensor->thrs_critical.temp, sensor->thrs_critical.hysteresis,
70 sensor->thrs_shutdown.temp, sensor->thrs_shutdown.hysteresis);
71
72}
73
74/* must be called with alarm_program_lock taken ! */
75static void
76nv84_therm_threshold_hyst_emulation(struct nouveau_therm *therm,
77 uint32_t thrs_reg, u8 status_bit,
78 const struct nvbios_therm_threshold *thrs,
79 enum nouveau_therm_thrs thrs_name)
80{
81 enum nouveau_therm_thrs_direction direction;
82 enum nouveau_therm_thrs_state prev_state, new_state;
83 int temp, cur;
84
85 prev_state = nouveau_therm_sensor_get_threshold_state(therm, thrs_name);
86 temp = nv_rd32(therm, thrs_reg);
87
88 /* program the next threshold */
89 if (temp == thrs->temp) {
90 nv_wr32(therm, thrs_reg, thrs->temp - thrs->hysteresis);
91 new_state = NOUVEAU_THERM_THRS_HIGHER;
92 } else {
93 nv_wr32(therm, thrs_reg, thrs->temp);
94 new_state = NOUVEAU_THERM_THRS_LOWER;
95 }
96
97 /* fix the state (in case someone reprogrammed the alarms) */
98 cur = therm->temp_get(therm);
99 if (new_state == NOUVEAU_THERM_THRS_LOWER && cur > thrs->temp)
100 new_state = NOUVEAU_THERM_THRS_HIGHER;
101 else if (new_state == NOUVEAU_THERM_THRS_HIGHER &&
102 cur < thrs->temp - thrs->hysteresis)
103 new_state = NOUVEAU_THERM_THRS_LOWER;
104 nouveau_therm_sensor_set_threshold_state(therm, thrs_name, new_state);
105
106 /* find the direction */
107 if (prev_state < new_state)
108 direction = NOUVEAU_THERM_THRS_RISING;
109 else if (prev_state > new_state)
110 direction = NOUVEAU_THERM_THRS_FALLING;
111 else
112 return;
113
114 /* advertise a change in direction */
115 nouveau_therm_sensor_event(therm, thrs_name, direction);
116}
117
118static void
119nv84_therm_intr(struct nouveau_subdev *subdev)
120{
121 struct nouveau_therm *therm = nouveau_therm(subdev);
122 struct nouveau_therm_priv *priv = (void *)therm;
123 struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
124 unsigned long flags;
125 uint32_t intr;
126
127 spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags);
128
129 intr = nv_rd32(therm, 0x20100);
130
131 /* THRS_4: downclock */
132 if (intr & 0x002) {
133 nv84_therm_threshold_hyst_emulation(therm, 0x20414, 24,
134 &sensor->thrs_down_clock,
135 NOUVEAU_THERM_THRS_DOWNCLOCK);
136 intr &= ~0x002;
137 }
138
139 /* shutdown */
140 if (intr & 0x004) {
141 nv84_therm_threshold_hyst_emulation(therm, 0x20480, 20,
142 &sensor->thrs_shutdown,
143 NOUVEAU_THERM_THRS_SHUTDOWN);
144 intr &= ~0x004;
145 }
146
147 /* THRS_1 : fan boost */
148 if (intr & 0x008) {
149 nv84_therm_threshold_hyst_emulation(therm, 0x204c4, 21,
150 &sensor->thrs_fan_boost,
151 NOUVEAU_THERM_THRS_FANBOOST);
152 intr &= ~0x008;
153 }
154
155 /* THRS_2 : critical */
156 if (intr & 0x010) {
157 nv84_therm_threshold_hyst_emulation(therm, 0x204c0, 22,
158 &sensor->thrs_critical,
159 NOUVEAU_THERM_THRS_CRITICAL);
160 intr &= ~0x010;
161 }
162
163 if (intr)
164 nv_error(therm, "unhandled intr 0x%08x\n", intr);
165
166 /* ACK everything */
167 nv_wr32(therm, 0x20100, 0xffffffff);
168 nv_wr32(therm, 0x1100, 0x10000); /* PBUS */
169
170 spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags);
171}
172
173static int
174nv84_therm_ctor(struct nouveau_object *parent,
175 struct nouveau_object *engine,
176 struct nouveau_oclass *oclass, void *data, u32 size,
177 struct nouveau_object **pobject)
178{
179 struct nv84_therm_priv *priv;
180 int ret;
181
182 ret = nouveau_therm_create(parent, engine, oclass, &priv);
183 *pobject = nv_object(priv);
184 if (ret)
185 return ret;
186
187 priv->base.base.pwm_ctrl = nv50_fan_pwm_ctrl;
188 priv->base.base.pwm_get = nv50_fan_pwm_get;
189 priv->base.base.pwm_set = nv50_fan_pwm_set;
190 priv->base.base.pwm_clock = nv50_fan_pwm_clock;
191 priv->base.base.temp_get = nv84_temp_get;
192 priv->base.sensor.program_alarms = nv84_therm_program_alarms;
193 nv_subdev(priv)->intr = nv84_therm_intr;
194
195 /* init the thresholds */
196 nouveau_therm_sensor_set_threshold_state(&priv->base.base,
197 NOUVEAU_THERM_THRS_SHUTDOWN,
198 NOUVEAU_THERM_THRS_LOWER);
199 nouveau_therm_sensor_set_threshold_state(&priv->base.base,
200 NOUVEAU_THERM_THRS_FANBOOST,
201 NOUVEAU_THERM_THRS_LOWER);
202 nouveau_therm_sensor_set_threshold_state(&priv->base.base,
203 NOUVEAU_THERM_THRS_CRITICAL,
204 NOUVEAU_THERM_THRS_LOWER);
205 nouveau_therm_sensor_set_threshold_state(&priv->base.base,
206 NOUVEAU_THERM_THRS_DOWNCLOCK,
207 NOUVEAU_THERM_THRS_LOWER);
208
209 return nouveau_therm_preinit(&priv->base.base);
210}
211
212struct nouveau_oclass
213nv84_therm_oclass = {
214 .handle = NV_SUBDEV(THERM, 0x84),
215 .ofuncs = &(struct nouveau_ofuncs) {
216 .ctor = nv84_therm_ctor,
217 .dtor = _nouveau_therm_dtor,
218 .init = _nouveau_therm_init,
219 .fini = _nouveau_therm_fini,
220 },
221};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c
index 2dcc5437116a..d11a7c400813 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c
@@ -81,7 +81,7 @@ nva3_therm_ctor(struct nouveau_object *parent,
81 priv->base.base.pwm_get = nv50_fan_pwm_get; 81 priv->base.base.pwm_get = nv50_fan_pwm_get;
82 priv->base.base.pwm_set = nv50_fan_pwm_set; 82 priv->base.base.pwm_set = nv50_fan_pwm_set;
83 priv->base.base.pwm_clock = nv50_fan_pwm_clock; 83 priv->base.base.pwm_clock = nv50_fan_pwm_clock;
84 priv->base.base.temp_get = nv50_temp_get; 84 priv->base.base.temp_get = nv84_temp_get;
85 priv->base.base.fan_sense = nva3_therm_fan_sense; 85 priv->base.base.fan_sense = nva3_therm_fan_sense;
86 priv->base.sensor.program_alarms = nouveau_therm_program_alarms_polling; 86 priv->base.sensor.program_alarms = nouveau_therm_program_alarms_polling;
87 return nouveau_therm_preinit(&priv->base.base); 87 return nouveau_therm_preinit(&priv->base.base);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c
index d7d30ee8332e..54c28bdc4204 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c
@@ -135,7 +135,7 @@ nvd0_therm_ctor(struct nouveau_object *parent,
135 priv->base.base.pwm_get = nvd0_fan_pwm_get; 135 priv->base.base.pwm_get = nvd0_fan_pwm_get;
136 priv->base.base.pwm_set = nvd0_fan_pwm_set; 136 priv->base.base.pwm_set = nvd0_fan_pwm_set;
137 priv->base.base.pwm_clock = nvd0_fan_pwm_clock; 137 priv->base.base.pwm_clock = nvd0_fan_pwm_clock;
138 priv->base.base.temp_get = nv50_temp_get; 138 priv->base.base.temp_get = nv84_temp_get;
139 priv->base.base.fan_sense = nva3_therm_fan_sense; 139 priv->base.base.fan_sense = nva3_therm_fan_sense;
140 priv->base.sensor.program_alarms = nouveau_therm_program_alarms_polling; 140 priv->base.sensor.program_alarms = nouveau_therm_program_alarms_polling;
141 return nouveau_therm_preinit(&priv->base.base); 141 return nouveau_therm_preinit(&priv->base.base);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
index 438d9824b774..15ca64e481f1 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h
@@ -134,11 +134,12 @@ void nouveau_therm_sensor_event(struct nouveau_therm *therm,
134 enum nouveau_therm_thrs_direction dir); 134 enum nouveau_therm_thrs_direction dir);
135void nouveau_therm_program_alarms_polling(struct nouveau_therm *therm); 135void nouveau_therm_program_alarms_polling(struct nouveau_therm *therm);
136 136
137void nv40_therm_intr(struct nouveau_subdev *);
137int nv50_fan_pwm_ctrl(struct nouveau_therm *, int, bool); 138int nv50_fan_pwm_ctrl(struct nouveau_therm *, int, bool);
138int nv50_fan_pwm_get(struct nouveau_therm *, int, u32 *, u32 *); 139int nv50_fan_pwm_get(struct nouveau_therm *, int, u32 *, u32 *);
139int nv50_fan_pwm_set(struct nouveau_therm *, int, u32, u32); 140int nv50_fan_pwm_set(struct nouveau_therm *, int, u32, u32);
140int nv50_fan_pwm_clock(struct nouveau_therm *); 141int nv50_fan_pwm_clock(struct nouveau_therm *);
141int nv50_temp_get(struct nouveau_therm *therm); 142int nv84_temp_get(struct nouveau_therm *therm);
142 143
143int nva3_therm_fan_sense(struct nouveau_therm *); 144int nva3_therm_fan_sense(struct nouveau_therm *);
144 145
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
index 470f6a47b656..dde746c78c8a 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c
@@ -205,13 +205,13 @@ nouveau_therm_program_alarms_polling(struct nouveau_therm *therm)
205 struct nouveau_therm_priv *priv = (void *)therm; 205 struct nouveau_therm_priv *priv = (void *)therm;
206 struct nvbios_therm_sensor *sensor = &priv->bios_sensor; 206 struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
207 207
208 nv_info(therm, 208 nv_debug(therm,
209 "programmed thresholds [ %d(%d), %d(%d), %d(%d), %d(%d) ]\n", 209 "programmed thresholds [ %d(%d), %d(%d), %d(%d), %d(%d) ]\n",
210 sensor->thrs_fan_boost.temp, sensor->thrs_fan_boost.hysteresis, 210 sensor->thrs_fan_boost.temp, sensor->thrs_fan_boost.hysteresis,
211 sensor->thrs_down_clock.temp, 211 sensor->thrs_down_clock.temp,
212 sensor->thrs_down_clock.hysteresis, 212 sensor->thrs_down_clock.hysteresis,
213 sensor->thrs_critical.temp, sensor->thrs_critical.hysteresis, 213 sensor->thrs_critical.temp, sensor->thrs_critical.hysteresis,
214 sensor->thrs_shutdown.temp, sensor->thrs_shutdown.hysteresis); 214 sensor->thrs_shutdown.temp, sensor->thrs_shutdown.hysteresis);
215 215
216 alarm_timer_callback(&priv->sensor.therm_poll_alarm); 216 alarm_timer_callback(&priv->sensor.therm_poll_alarm);
217} 217}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
index 8e1bae4f12e8..9469b8275675 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
@@ -96,11 +96,16 @@ nv04_timer_alarm(struct nouveau_timer *ptimer, u64 time,
96 96
97 /* append new alarm to list, in soonest-alarm-first order */ 97 /* append new alarm to list, in soonest-alarm-first order */
98 spin_lock_irqsave(&priv->lock, flags); 98 spin_lock_irqsave(&priv->lock, flags);
99 list_for_each_entry(list, &priv->alarms, head) { 99 if (!time) {
100 if (list->timestamp > alarm->timestamp) 100 if (!list_empty(&alarm->head))
101 break; 101 list_del(&alarm->head);
102 } else {
103 list_for_each_entry(list, &priv->alarms, head) {
104 if (list->timestamp > alarm->timestamp)
105 break;
106 }
107 list_add_tail(&alarm->head, &list->head);
102 } 108 }
103 list_add_tail(&alarm->head, &list->head);
104 spin_unlock_irqrestore(&priv->lock, flags); 109 spin_unlock_irqrestore(&priv->lock, flags);
105 110
106 /* process pending alarms */ 111 /* process pending alarms */
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c
index 6adbbc9cc361..ed45437167f2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv04.c
@@ -110,7 +110,7 @@ nv04_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
110 if (ret) 110 if (ret)
111 return ret; 111 return ret;
112 112
113 ret = nouveau_gpuobj_new(parent, NULL, 113 ret = nouveau_gpuobj_new(nv_object(priv), NULL,
114 (NV04_PDMA_SIZE / NV04_PDMA_PAGE) * 4 + 114 (NV04_PDMA_SIZE / NV04_PDMA_PAGE) * 4 +
115 8, 16, NVOBJ_FLAG_ZERO_ALLOC, 115 8, 16, NVOBJ_FLAG_ZERO_ALLOC,
116 &priv->vm->pgt[0].obj[0]); 116 &priv->vm->pgt[0].obj[0]);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c
index 9474cfca6e4c..064c76262876 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c
@@ -119,7 +119,7 @@ nv41_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
119 if (ret) 119 if (ret)
120 return ret; 120 return ret;
121 121
122 ret = nouveau_gpuobj_new(parent, NULL, 122 ret = nouveau_gpuobj_new(nv_object(priv), NULL,
123 (NV41_GART_SIZE / NV41_GART_PAGE) * 4, 123 (NV41_GART_SIZE / NV41_GART_PAGE) * 4,
124 16, NVOBJ_FLAG_ZERO_ALLOC, 124 16, NVOBJ_FLAG_ZERO_ALLOC,
125 &priv->vm->pgt[0].obj[0]); 125 &priv->vm->pgt[0].obj[0]);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c
index aa8131436e3d..fae1f67d5948 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c
@@ -196,7 +196,7 @@ nv44_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
196 if (ret) 196 if (ret)
197 return ret; 197 return ret;
198 198
199 ret = nouveau_gpuobj_new(parent, NULL, 199 ret = nouveau_gpuobj_new(nv_object(priv), NULL,
200 (NV44_GART_SIZE / NV44_GART_PAGE) * 4, 200 (NV44_GART_SIZE / NV44_GART_PAGE) * 4,
201 512 * 1024, NVOBJ_FLAG_ZERO_ALLOC, 201 512 * 1024, NVOBJ_FLAG_ZERO_ALLOC,
202 &priv->vm->pgt[0].obj[0]); 202 &priv->vm->pgt[0].obj[0]);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
index 30c61e6c2017..4c3b0a23b9d6 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
@@ -28,12 +28,54 @@
28#include <subdev/timer.h> 28#include <subdev/timer.h>
29#include <subdev/fb.h> 29#include <subdev/fb.h>
30#include <subdev/vm.h> 30#include <subdev/vm.h>
31#include <subdev/ltcg.h>
31 32
32struct nvc0_vmmgr_priv { 33struct nvc0_vmmgr_priv {
33 struct nouveau_vmmgr base; 34 struct nouveau_vmmgr base;
34 spinlock_t lock; 35 spinlock_t lock;
35}; 36};
36 37
38
39/* Map from compressed to corresponding uncompressed storage type.
40 * The value 0xff represents an invalid storage type.
41 */
42const u8 nvc0_pte_storage_type_map[256] =
43{
44 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0x01, /* 0x00 */
45 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
46 0xff, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, /* 0x10 */
47 0x11, 0x11, 0x11, 0xff, 0xff, 0xff, 0xff, 0xff,
48 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x26, 0x27, /* 0x20 */
49 0x28, 0x29, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
50 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x30 */
51 0xff, 0xff, 0x26, 0x27, 0x28, 0x29, 0x26, 0x27,
52 0x28, 0x29, 0xff, 0xff, 0xff, 0xff, 0x46, 0xff, /* 0x40 */
53 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
54 0xff, 0x46, 0x46, 0x46, 0x46, 0xff, 0xff, 0xff, /* 0x50 */
55 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
56 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x60 */
57 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
58 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x70 */
59 0xff, 0xff, 0xff, 0x7b, 0xff, 0xff, 0xff, 0xff,
60 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7b, 0x7b, /* 0x80 */
61 0x7b, 0x7b, 0xff, 0x8b, 0x8c, 0x8d, 0x8e, 0xff,
62 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x90 */
63 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
64 0xff, 0xff, 0xff, 0x8b, 0x8c, 0x8d, 0x8e, 0xa7, /* 0xa0 */
65 0xa8, 0xa9, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff,
66 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */
67 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa7,
68 0xa8, 0xa9, 0xaa, 0xc3, 0xff, 0xff, 0xff, 0xff, /* 0xc0 */
69 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xc3, 0xc3,
70 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xd0 */
71 0xfe, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe,
72 0xfe, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, /* 0xe0 */
73 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xfe, 0xff,
74 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, /* 0xf0 */
75 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xfd, 0xfe, 0xff
76};
77
78
37static void 79static void
38nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 index, 80nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 index,
39 struct nouveau_gpuobj *pgt[2]) 81 struct nouveau_gpuobj *pgt[2])
@@ -68,10 +110,20 @@ static void
68nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, 110nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
69 struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta) 111 struct nouveau_mem *mem, u32 pte, u32 cnt, u64 phys, u64 delta)
70{ 112{
71 u32 next = 1 << (vma->node->type - 8); 113 u64 next = 1 << (vma->node->type - 8);
72 114
73 phys = nvc0_vm_addr(vma, phys, mem->memtype, 0); 115 phys = nvc0_vm_addr(vma, phys, mem->memtype, 0);
74 pte <<= 3; 116 pte <<= 3;
117
118 if (mem->tag) {
119 struct nouveau_ltcg *ltcg =
120 nouveau_ltcg(vma->vm->vmm->base.base.parent);
121 u32 tag = mem->tag->offset + (delta >> 17);
122 phys |= (u64)tag << (32 + 12);
123 next |= (u64)1 << (32 + 12);
124 ltcg->tags_clear(ltcg, tag, cnt);
125 }
126
75 while (cnt--) { 127 while (cnt--) {
76 nv_wo32(pgt, pte + 0, lower_32_bits(phys)); 128 nv_wo32(pgt, pte + 0, lower_32_bits(phys));
77 nv_wo32(pgt, pte + 4, upper_32_bits(phys)); 129 nv_wo32(pgt, pte + 4, upper_32_bits(phys));
@@ -85,10 +137,12 @@ nvc0_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt,
85 struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list) 137 struct nouveau_mem *mem, u32 pte, u32 cnt, dma_addr_t *list)
86{ 138{
87 u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 7 : 5; 139 u32 target = (vma->access & NV_MEM_ACCESS_NOSNOOP) ? 7 : 5;
140 /* compressed storage types are invalid for system memory */
141 u32 memtype = nvc0_pte_storage_type_map[mem->memtype & 0xff];
88 142
89 pte <<= 3; 143 pte <<= 3;
90 while (cnt--) { 144 while (cnt--) {
91 u64 phys = nvc0_vm_addr(vma, *list++, mem->memtype, target); 145 u64 phys = nvc0_vm_addr(vma, *list++, memtype, target);
92 nv_wo32(pgt, pte + 0, lower_32_bits(phys)); 146 nv_wo32(pgt, pte + 0, lower_32_bits(phys));
93 nv_wo32(pgt, pte + 4, upper_32_bits(phys)); 147 nv_wo32(pgt, pte + 4, upper_32_bits(phys));
94 pte += 8; 148 pte += 8;
diff --git a/drivers/gpu/drm/nouveau/dispnv04/Makefile b/drivers/gpu/drm/nouveau/dispnv04/Makefile
new file mode 100644
index 000000000000..ea3f5b8a0f95
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/dispnv04/Makefile
@@ -0,0 +1,10 @@
1nouveau-y += dispnv04/arb.o
2nouveau-y += dispnv04/crtc.o
3nouveau-y += dispnv04/cursor.o
4nouveau-y += dispnv04/dac.o
5nouveau-y += dispnv04/dfp.o
6nouveau-y += dispnv04/disp.o
7nouveau-y += dispnv04/hw.o
8nouveau-y += dispnv04/tvmodesnv17.o
9nouveau-y += dispnv04/tvnv04.o
10nouveau-y += dispnv04/tvnv17.o
diff --git a/drivers/gpu/drm/nouveau/nouveau_calc.c b/drivers/gpu/drm/nouveau/dispnv04/arb.c
index 6da576445b3d..2e70462883e8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_calc.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/arb.c
@@ -25,7 +25,7 @@
25 25
26#include "nouveau_drm.h" 26#include "nouveau_drm.h"
27#include "nouveau_reg.h" 27#include "nouveau_reg.h"
28#include "nouveau_hw.h" 28#include "hw.h"
29 29
30/****************************************************************************\ 30/****************************************************************************\
31* * 31* *
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
index 6578cd28c556..0782bd2f1e04 100644
--- a/drivers/gpu/drm/nouveau/nv04_crtc.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
@@ -33,10 +33,10 @@
33#include "nouveau_encoder.h" 33#include "nouveau_encoder.h"
34#include "nouveau_connector.h" 34#include "nouveau_connector.h"
35#include "nouveau_crtc.h" 35#include "nouveau_crtc.h"
36#include "nouveau_hw.h" 36#include "hw.h"
37#include "nvreg.h" 37#include "nvreg.h"
38#include "nouveau_fbcon.h" 38#include "nouveau_fbcon.h"
39#include "nv04_display.h" 39#include "disp.h"
40 40
41#include <subdev/bios/pll.h> 41#include <subdev/bios/pll.h>
42#include <subdev/clock.h> 42#include <subdev/clock.h>
@@ -1070,4 +1070,3 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num)
1070 1070
1071 return 0; 1071 return 0;
1072} 1072}
1073
diff --git a/drivers/gpu/drm/nouveau/nv04_cursor.c b/drivers/gpu/drm/nouveau/dispnv04/cursor.c
index fe86f0de348f..a810303169de 100644
--- a/drivers/gpu/drm/nouveau/nv04_cursor.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/cursor.c
@@ -3,7 +3,7 @@
3#include "nouveau_drm.h" 3#include "nouveau_drm.h"
4#include "nouveau_reg.h" 4#include "nouveau_reg.h"
5#include "nouveau_crtc.h" 5#include "nouveau_crtc.h"
6#include "nouveau_hw.h" 6#include "hw.h"
7 7
8static void 8static void
9nv04_cursor_show(struct nouveau_crtc *nv_crtc, bool update) 9nv04_cursor_show(struct nouveau_crtc *nv_crtc, bool update)
@@ -68,4 +68,3 @@ nv04_cursor_init(struct nouveau_crtc *crtc)
68 crtc->cursor.show = nv04_cursor_show; 68 crtc->cursor.show = nv04_cursor_show;
69 return 0; 69 return 0;
70} 70}
71
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/dispnv04/dac.c
index 64f7020fb605..434b920f6bd4 100644
--- a/drivers/gpu/drm/nouveau/nv04_dac.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/dac.c
@@ -31,7 +31,7 @@
31#include "nouveau_encoder.h" 31#include "nouveau_encoder.h"
32#include "nouveau_connector.h" 32#include "nouveau_connector.h"
33#include "nouveau_crtc.h" 33#include "nouveau_crtc.h"
34#include "nouveau_hw.h" 34#include "hw.h"
35#include "nvreg.h" 35#include "nvreg.h"
36 36
37#include <subdev/bios/gpio.h> 37#include <subdev/bios/gpio.h>
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/dispnv04/dfp.c
index 7e24cdf1cb39..93dd23ff0093 100644
--- a/drivers/gpu/drm/nouveau/nv04_dfp.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/dfp.c
@@ -32,7 +32,7 @@
32#include "nouveau_encoder.h" 32#include "nouveau_encoder.h"
33#include "nouveau_connector.h" 33#include "nouveau_connector.h"
34#include "nouveau_crtc.h" 34#include "nouveau_crtc.h"
35#include "nouveau_hw.h" 35#include "hw.h"
36#include "nvreg.h" 36#include "nvreg.h"
37 37
38#include <drm/i2c/sil164.h> 38#include <drm/i2c/sil164.h>
diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/dispnv04/disp.c
index ad48444c385c..4908d3fd0486 100644
--- a/drivers/gpu/drm/nouveau/nv04_display.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c
@@ -30,7 +30,7 @@
30 30
31#include "nouveau_drm.h" 31#include "nouveau_drm.h"
32#include "nouveau_reg.h" 32#include "nouveau_reg.h"
33#include "nouveau_hw.h" 33#include "hw.h"
34#include "nouveau_encoder.h" 34#include "nouveau_encoder.h"
35#include "nouveau_connector.h" 35#include "nouveau_connector.h"
36 36
diff --git a/drivers/gpu/drm/nouveau/nv04_display.h b/drivers/gpu/drm/nouveau/dispnv04/disp.h
index a0a031dad13f..a0a031dad13f 100644
--- a/drivers/gpu/drm/nouveau/nv04_display.h
+++ b/drivers/gpu/drm/nouveau/dispnv04/disp.h
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/dispnv04/hw.c
index 617a06ffdb46..973056b86207 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hw.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/hw.c
@@ -24,7 +24,7 @@
24 24
25#include <drm/drmP.h> 25#include <drm/drmP.h>
26#include "nouveau_drm.h" 26#include "nouveau_drm.h"
27#include "nouveau_hw.h" 27#include "hw.h"
28 28
29#include <subdev/bios/pll.h> 29#include <subdev/bios/pll.h>
30#include <subdev/clock.h> 30#include <subdev/clock.h>
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.h b/drivers/gpu/drm/nouveau/dispnv04/hw.h
index 7dff1021fab4..eeb70d912d99 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hw.h
+++ b/drivers/gpu/drm/nouveau/dispnv04/hw.h
@@ -24,7 +24,8 @@
24#define __NOUVEAU_HW_H__ 24#define __NOUVEAU_HW_H__
25 25
26#include <drm/drmP.h> 26#include <drm/drmP.h>
27#include "nv04_display.h" 27#include "disp.h"
28#include "nvreg.h"
28 29
29#include <subdev/bios/pll.h> 30#include <subdev/bios/pll.h>
30 31
diff --git a/drivers/gpu/drm/nouveau/nvreg.h b/drivers/gpu/drm/nouveau/dispnv04/nvreg.h
index bbfb1a68fb11..bbfb1a68fb11 100644
--- a/drivers/gpu/drm/nouveau/nvreg.h
+++ b/drivers/gpu/drm/nouveau/dispnv04/nvreg.h
diff --git a/drivers/gpu/drm/nouveau/nv17_tv_modes.c b/drivers/gpu/drm/nouveau/dispnv04/tvmodesnv17.c
index 1cdfe2a5875d..08c6f5e50610 100644
--- a/drivers/gpu/drm/nouveau/nv17_tv_modes.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/tvmodesnv17.c
@@ -29,8 +29,8 @@
29#include "nouveau_drm.h" 29#include "nouveau_drm.h"
30#include "nouveau_encoder.h" 30#include "nouveau_encoder.h"
31#include "nouveau_crtc.h" 31#include "nouveau_crtc.h"
32#include "nouveau_hw.h" 32#include "hw.h"
33#include "nv17_tv.h" 33#include "tvnv17.h"
34 34
35char *nv17_tv_norm_names[NUM_TV_NORMS] = { 35char *nv17_tv_norm_names[NUM_TV_NORMS] = {
36 [TV_NORM_PAL] = "PAL", 36 [TV_NORM_PAL] = "PAL",
diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c
index 4a69ccdef9b4..bf13db4e8631 100644
--- a/drivers/gpu/drm/nouveau/nv04_tv.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c
@@ -30,7 +30,7 @@
30#include "nouveau_encoder.h" 30#include "nouveau_encoder.h"
31#include "nouveau_connector.h" 31#include "nouveau_connector.h"
32#include "nouveau_crtc.h" 32#include "nouveau_crtc.h"
33#include "nouveau_hw.h" 33#include "hw.h"
34#include <drm/drm_crtc_helper.h> 34#include <drm/drm_crtc_helper.h>
35 35
36#include <drm/i2c/ch7006.h> 36#include <drm/i2c/ch7006.h>
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
index 977e42be2050..acef48f4a4ea 100644
--- a/drivers/gpu/drm/nouveau/nv17_tv.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
@@ -31,8 +31,8 @@
31#include "nouveau_encoder.h" 31#include "nouveau_encoder.h"
32#include "nouveau_connector.h" 32#include "nouveau_connector.h"
33#include "nouveau_crtc.h" 33#include "nouveau_crtc.h"
34#include "nouveau_hw.h" 34#include "hw.h"
35#include "nv17_tv.h" 35#include "tvnv17.h"
36 36
37#include <core/device.h> 37#include <core/device.h>
38 38
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.h b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.h
index 7b331543a41b..7b331543a41b 100644
--- a/drivers/gpu/drm/nouveau/nv17_tv.h
+++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.h
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c
index 5eb3e0da7c6e..1c4c6c9161ac 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.c
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c
@@ -30,6 +30,7 @@
30#include <subdev/fb.h> 30#include <subdev/fb.h>
31#include <subdev/timer.h> 31#include <subdev/timer.h>
32#include <subdev/instmem.h> 32#include <subdev/instmem.h>
33#include <engine/graph.h>
33 34
34#include "nouveau_drm.h" 35#include "nouveau_drm.h"
35#include "nouveau_dma.h" 36#include "nouveau_dma.h"
@@ -168,6 +169,7 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
168 struct nouveau_drm *drm = nouveau_drm(dev); 169 struct nouveau_drm *drm = nouveau_drm(dev);
169 struct nouveau_device *device = nv_device(drm->device); 170 struct nouveau_device *device = nv_device(drm->device);
170 struct nouveau_timer *ptimer = nouveau_timer(device); 171 struct nouveau_timer *ptimer = nouveau_timer(device);
172 struct nouveau_graph *graph = (void *)nouveau_engine(device, NVDEV_ENGINE_GR);
171 struct drm_nouveau_getparam *getparam = data; 173 struct drm_nouveau_getparam *getparam = data;
172 174
173 switch (getparam->param) { 175 switch (getparam->param) {
@@ -208,14 +210,8 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
208 getparam->value = 1; 210 getparam->value = 1;
209 break; 211 break;
210 case NOUVEAU_GETPARAM_GRAPH_UNITS: 212 case NOUVEAU_GETPARAM_GRAPH_UNITS:
211 /* NV40 and NV50 versions are quite different, but register 213 getparam->value = graph->units ? graph->units(graph) : 0;
212 * address is the same. User is supposed to know the card 214 break;
213 * family anyway... */
214 if (device->chipset >= 0x40) {
215 getparam->value = nv_rd32(device, 0x001540);
216 break;
217 }
218 /* FALLTHRU */
219 default: 215 default:
220 nv_debug(device, "unknown parameter %lld\n", getparam->param); 216 nv_debug(device, "unknown parameter %lld\n", getparam->param);
221 return -EINVAL; 217 return -EINVAL;
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c
index 5d940302d2aa..2ffad2176b7f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
+++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
@@ -239,6 +239,9 @@ nouveau_backlight_init(struct drm_device *dev)
239 case NV_40: 239 case NV_40:
240 return nv40_backlight_init(connector); 240 return nv40_backlight_init(connector);
241 case NV_50: 241 case NV_50:
242 case NV_C0:
243 case NV_D0:
244 case NV_E0:
242 return nv50_backlight_init(connector); 245 return nv50_backlight_init(connector);
243 default: 246 default:
244 break; 247 break;
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 50a6dd02f7c5..6aa2137e093a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -28,7 +28,7 @@
28 28
29#include "nouveau_drm.h" 29#include "nouveau_drm.h"
30#include "nouveau_reg.h" 30#include "nouveau_reg.h"
31#include "nouveau_hw.h" 31#include "dispnv04/hw.h"
32#include "nouveau_encoder.h" 32#include "nouveau_encoder.h"
33 33
34#include <linux/io-mapping.h> 34#include <linux/io-mapping.h>
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
index 7ccd28f11adf..0067586eb015 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -24,8 +24,6 @@
24#ifndef __NOUVEAU_DISPBIOS_H__ 24#ifndef __NOUVEAU_DISPBIOS_H__
25#define __NOUVEAU_DISPBIOS_H__ 25#define __NOUVEAU_DISPBIOS_H__
26 26
27#include "nvreg.h"
28
29#define DCB_MAX_NUM_ENTRIES 16 27#define DCB_MAX_NUM_ENTRIES 16
30#define DCB_MAX_NUM_I2C_ENTRIES 16 28#define DCB_MAX_NUM_I2C_ENTRIES 16
31#define DCB_MAX_NUM_GPIO_ENTRIES 32 29#define DCB_MAX_NUM_GPIO_ENTRIES 32
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 4dd7ae2ac6c6..4da776f344d7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -32,7 +32,7 @@
32 32
33#include "nouveau_reg.h" 33#include "nouveau_reg.h"
34#include "nouveau_drm.h" 34#include "nouveau_drm.h"
35#include "nouveau_hw.h" 35#include "dispnv04/hw.h"
36#include "nouveau_acpi.h" 36#include "nouveau_acpi.h"
37 37
38#include "nouveau_display.h" 38#include "nouveau_display.h"
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 4610c3a29bbe..7bf22d4a3d96 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -28,7 +28,7 @@
28#include <drm/drm_crtc_helper.h> 28#include <drm/drm_crtc_helper.h>
29 29
30#include "nouveau_fbcon.h" 30#include "nouveau_fbcon.h"
31#include "nouveau_hw.h" 31#include "dispnv04/hw.h"
32#include "nouveau_crtc.h" 32#include "nouveau_crtc.h"
33#include "nouveau_dma.h" 33#include "nouveau_dma.h"
34#include "nouveau_gem.h" 34#include "nouveau_gem.h"
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index c95decf543e9..c33b13fb18db 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -31,13 +31,12 @@
31#include <core/gpuobj.h> 31#include <core/gpuobj.h>
32#include <core/class.h> 32#include <core/class.h>
33 33
34#include <subdev/device.h> 34#include <engine/device.h>
35#include <subdev/vm.h>
36
37#include <engine/disp.h> 35#include <engine/disp.h>
38 36
37#include <subdev/vm.h>
38
39#include "nouveau_drm.h" 39#include "nouveau_drm.h"
40#include "nouveau_irq.h"
41#include "nouveau_dma.h" 40#include "nouveau_dma.h"
42#include "nouveau_ttm.h" 41#include "nouveau_ttm.h"
43#include "nouveau_gem.h" 42#include "nouveau_gem.h"
@@ -365,10 +364,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
365 if (ret) 364 if (ret)
366 goto fail_bios; 365 goto fail_bios;
367 366
368 ret = nouveau_irq_init(dev);
369 if (ret)
370 goto fail_irq;
371
372 ret = nouveau_display_create(dev); 367 ret = nouveau_display_create(dev);
373 if (ret) 368 if (ret)
374 goto fail_dispctor; 369 goto fail_dispctor;
@@ -388,8 +383,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
388fail_dispinit: 383fail_dispinit:
389 nouveau_display_destroy(dev); 384 nouveau_display_destroy(dev);
390fail_dispctor: 385fail_dispctor:
391 nouveau_irq_fini(dev);
392fail_irq:
393 nouveau_bios_takedown(dev); 386 nouveau_bios_takedown(dev);
394fail_bios: 387fail_bios:
395 nouveau_ttm_fini(drm); 388 nouveau_ttm_fini(drm);
@@ -415,7 +408,6 @@ nouveau_drm_unload(struct drm_device *dev)
415 nouveau_display_fini(dev); 408 nouveau_display_fini(dev);
416 nouveau_display_destroy(dev); 409 nouveau_display_destroy(dev);
417 410
418 nouveau_irq_fini(dev);
419 nouveau_bios_takedown(dev); 411 nouveau_bios_takedown(dev);
420 412
421 nouveau_ttm_fini(drm); 413 nouveau_ttm_fini(drm);
@@ -533,7 +525,6 @@ nouveau_do_resume(struct drm_device *dev)
533 nouveau_fence(drm)->resume(drm); 525 nouveau_fence(drm)->resume(drm);
534 526
535 nouveau_run_vbios_init(dev); 527 nouveau_run_vbios_init(dev);
536 nouveau_irq_postinstall(dev);
537 nouveau_pm_resume(dev); 528 nouveau_pm_resume(dev);
538 529
539 if (dev->mode_config.num_crtc) { 530 if (dev->mode_config.num_crtc) {
@@ -669,8 +660,7 @@ static struct drm_driver
669driver = { 660driver = {
670 .driver_features = 661 .driver_features =
671 DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG | 662 DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
672 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | 663 DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME,
673 DRIVER_MODESET | DRIVER_PRIME,
674 664
675 .load = nouveau_drm_load, 665 .load = nouveau_drm_load,
676 .unload = nouveau_drm_unload, 666 .unload = nouveau_drm_unload,
@@ -684,11 +674,6 @@ driver = {
684 .debugfs_cleanup = nouveau_debugfs_takedown, 674 .debugfs_cleanup = nouveau_debugfs_takedown,
685#endif 675#endif
686 676
687 .irq_preinstall = nouveau_irq_preinstall,
688 .irq_postinstall = nouveau_irq_postinstall,
689 .irq_uninstall = nouveau_irq_uninstall,
690 .irq_handler = nouveau_irq_handler,
691
692 .get_vblank_counter = drm_vblank_count, 677 .get_vblank_counter = drm_vblank_count,
693 .enable_vblank = nouveau_drm_vblank_enable, 678 .enable_vblank = nouveau_drm_vblank_enable,
694 .disable_vblank = nouveau_drm_vblank_disable, 679 .disable_vblank = nouveau_drm_vblank_disable,
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h
index 9c39bafbef2c..f2b30f89dee0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.h
@@ -10,7 +10,18 @@
10 10
11#define DRIVER_MAJOR 1 11#define DRIVER_MAJOR 1
12#define DRIVER_MINOR 1 12#define DRIVER_MINOR 1
13#define DRIVER_PATCHLEVEL 0 13#define DRIVER_PATCHLEVEL 1
14
15/*
16 * 1.1.1:
17 * - added support for tiled system memory buffer objects
18 * - added support for NOUVEAU_GETPARAM_GRAPH_UNITS on [nvc0,nve0].
19 * - added support for compressed memory storage types on [nvc0,nve0].
20 * - added support for software methods 0x600,0x644,0x6ac on nvc0
21 * to control registers on the MPs to enable performance counters,
22 * and to control the warp error enable mask (OpenGL requires out of
23 * bounds access to local memory to be silently ignored / return 0).
24 */
14 25
15#include <core/client.h> 26#include <core/client.h>
16#include <core/event.h> 27#include <core/event.h>
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index e24341229d5e..24660c0f713d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -30,7 +30,7 @@
30#include <subdev/bios/dcb.h> 30#include <subdev/bios/dcb.h>
31 31
32#include <drm/drm_encoder_slave.h> 32#include <drm/drm_encoder_slave.h>
33#include "nv04_display.h" 33#include "dispnv04/disp.h"
34 34
35#define NV_DPMS_CLEARED 0x80 35#define NV_DPMS_CLEARED 0x80
36 36
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c
deleted file mode 100644
index 1303680affd3..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_irq.c
+++ /dev/null
@@ -1,76 +0,0 @@
1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24
25#include <subdev/mc.h>
26
27#include "nouveau_drm.h"
28#include "nouveau_irq.h"
29#include "nv50_display.h"
30
31void
32nouveau_irq_preinstall(struct drm_device *dev)
33{
34 nv_wr32(nouveau_dev(dev), 0x000140, 0x00000000);
35}
36
37int
38nouveau_irq_postinstall(struct drm_device *dev)
39{
40 nv_wr32(nouveau_dev(dev), 0x000140, 0x00000001);
41 return 0;
42}
43
44void
45nouveau_irq_uninstall(struct drm_device *dev)
46{
47 nv_wr32(nouveau_dev(dev), 0x000140, 0x00000000);
48}
49
50irqreturn_t
51nouveau_irq_handler(DRM_IRQ_ARGS)
52{
53 struct drm_device *dev = arg;
54 struct nouveau_device *device = nouveau_dev(dev);
55 struct nouveau_mc *pmc = nouveau_mc(device);
56 u32 stat;
57
58 stat = nv_rd32(device, 0x000100);
59 if (stat == 0 || stat == ~0)
60 return IRQ_NONE;
61
62 nv_subdev(pmc)->intr(nv_subdev(pmc));
63 return IRQ_HANDLED;
64}
65
66int
67nouveau_irq_init(struct drm_device *dev)
68{
69 return drm_irq_install(dev);
70}
71
72void
73nouveau_irq_fini(struct drm_device *dev)
74{
75 drm_irq_uninstall(dev);
76}
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.h b/drivers/gpu/drm/nouveau/nouveau_irq.h
deleted file mode 100644
index 06714ad857bb..000000000000
--- a/drivers/gpu/drm/nouveau/nouveau_irq.h
+++ /dev/null
@@ -1,11 +0,0 @@
1#ifndef __NOUVEAU_IRQ_H__
2#define __NOUVEAU_IRQ_H__
3
4extern int nouveau_irq_init(struct drm_device *);
5extern void nouveau_irq_fini(struct drm_device *);
6extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS);
7extern void nouveau_irq_preinstall(struct drm_device *);
8extern int nouveau_irq_postinstall(struct drm_device *);
9extern void nouveau_irq_uninstall(struct drm_device *);
10
11#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c
index 9be9cb58e19b..f19a15a3bc03 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -35,14 +35,16 @@
35static int 35static int
36nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize) 36nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long psize)
37{ 37{
38 /* nothing to do */ 38 struct nouveau_drm *drm = nouveau_bdev(man->bdev);
39 struct nouveau_fb *pfb = nouveau_fb(drm->device);
40 man->priv = pfb;
39 return 0; 41 return 0;
40} 42}
41 43
42static int 44static int
43nouveau_vram_manager_fini(struct ttm_mem_type_manager *man) 45nouveau_vram_manager_fini(struct ttm_mem_type_manager *man)
44{ 46{
45 /* nothing to do */ 47 man->priv = NULL;
46 return 0; 48 return 0;
47} 49}
48 50
@@ -104,7 +106,8 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
104static void 106static void
105nouveau_vram_manager_debug(struct ttm_mem_type_manager *man, const char *prefix) 107nouveau_vram_manager_debug(struct ttm_mem_type_manager *man, const char *prefix)
106{ 108{
107 struct nouveau_mm *mm = man->priv; 109 struct nouveau_fb *pfb = man->priv;
110 struct nouveau_mm *mm = &pfb->vram;
108 struct nouveau_mm_node *r; 111 struct nouveau_mm_node *r;
109 u32 total = 0, free = 0; 112 u32 total = 0, free = 0;
110 113
@@ -161,6 +164,8 @@ nouveau_gart_manager_new(struct ttm_mem_type_manager *man,
161 struct ttm_placement *placement, 164 struct ttm_placement *placement,
162 struct ttm_mem_reg *mem) 165 struct ttm_mem_reg *mem)
163{ 166{
167 struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
168 struct nouveau_bo *nvbo = nouveau_bo(bo);
164 struct nouveau_mem *node; 169 struct nouveau_mem *node;
165 170
166 if (unlikely((mem->num_pages << PAGE_SHIFT) >= 512 * 1024 * 1024)) 171 if (unlikely((mem->num_pages << PAGE_SHIFT) >= 512 * 1024 * 1024))
@@ -171,6 +176,20 @@ nouveau_gart_manager_new(struct ttm_mem_type_manager *man,
171 return -ENOMEM; 176 return -ENOMEM;
172 node->page_shift = 12; 177 node->page_shift = 12;
173 178
179 switch (nv_device(drm->device)->card_type) {
180 case NV_50:
181 if (nv_device(drm->device)->chipset != 0x50)
182 node->memtype = (nvbo->tile_flags & 0x7f00) >> 8;
183 break;
184 case NV_C0:
185 case NV_D0:
186 case NV_E0:
187 node->memtype = (nvbo->tile_flags & 0xff00) >> 8;
188 break;
189 default:
190 break;
191 }
192
174 mem->mm_node = node; 193 mem->mm_node = node;
175 mem->start = 0; 194 mem->start = 0;
176 return 0; 195 return 0;
diff --git a/drivers/gpu/drm/nouveau/nv04_pm.c b/drivers/gpu/drm/nouveau/nv04_pm.c
index 2a0cc9d0614a..27afc0ea28b0 100644
--- a/drivers/gpu/drm/nouveau/nv04_pm.c
+++ b/drivers/gpu/drm/nouveau/nv04_pm.c
@@ -25,7 +25,7 @@
25#include <drm/drmP.h> 25#include <drm/drmP.h>
26#include "nouveau_drm.h" 26#include "nouveau_drm.h"
27#include "nouveau_reg.h" 27#include "nouveau_reg.h"
28#include "nouveau_hw.h" 28#include "dispnv04/hw.h"
29#include "nouveau_pm.h" 29#include "nouveau_pm.h"
30 30
31#include <subdev/bios/pll.h> 31#include <subdev/bios/pll.h>
diff --git a/drivers/gpu/drm/nouveau/nv40_pm.c b/drivers/gpu/drm/nouveau/nv40_pm.c
index 3382064c7f33..3af5bcd0b203 100644
--- a/drivers/gpu/drm/nouveau/nv40_pm.c
+++ b/drivers/gpu/drm/nouveau/nv40_pm.c
@@ -26,7 +26,7 @@
26#include "nouveau_drm.h" 26#include "nouveau_drm.h"
27#include "nouveau_bios.h" 27#include "nouveau_bios.h"
28#include "nouveau_pm.h" 28#include "nouveau_pm.h"
29#include "nouveau_hw.h" 29#include "dispnv04/hw.h"
30 30
31#include <subdev/bios/pll.h> 31#include <subdev/bios/pll.h>
32#include <subdev/clock.h> 32#include <subdev/clock.h>
diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c b/drivers/gpu/drm/nouveau/nv50_pm.c
index 8bd5d2781baf..69620e39c90c 100644
--- a/drivers/gpu/drm/nouveau/nv50_pm.c
+++ b/drivers/gpu/drm/nouveau/nv50_pm.c
@@ -25,7 +25,7 @@
25#include <drm/drmP.h> 25#include <drm/drmP.h>
26#include "nouveau_drm.h" 26#include "nouveau_drm.h"
27#include "nouveau_bios.h" 27#include "nouveau_bios.h"
28#include "nouveau_hw.h" 28#include "dispnv04/hw.h"
29#include "nouveau_pm.h" 29#include "nouveau_pm.h"
30#include "nouveau_hwsq.h" 30#include "nouveau_hwsq.h"
31 31