aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-06-10 02:39:21 -0400
committerDave Airlie <airlied@redhat.com>2014-06-10 02:39:21 -0400
commitb06c47a13c52cec01902d0094fdd7f78f4d54152 (patch)
tree65788289ccf59db1131a40452279f267782aa762
parent5b9adbd30d32a6176f6cb102f6fe73426636ed7b (diff)
parent255b329ca7f0e9b5fa6da3a68bb713684fe10305 (diff)
Merge branch 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next
There's really not a great deal this time due to me spending most of this window on Maxwell. But, here's the random bits and pieces that's currently queued. * 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: (25 commits) drm/gk208/gr: add missing registers to grctx init drm/nouveau/kms/nv04-nv40: fix pageflip events via special case. drm/nv50-/mc: fix kms pageflip events by reordering irq handling order. drm/nouveau/disp/nv04-nv40: abort scanoutpos query on vga analog. drm/nv50-/kms: wait for enough ring space in crtc_prepare() drm/nouveau/disp/dp: support training pattern 3 drm/nouveau/disp/dp: support aux read interval during link training drm/gk104/gpio: fix incorrect interrupt register usage drm/nouveau/core: punt all object state change messages to trace level drm/nouveau/clk: allow end-user reclocking for nv40, nvaa, and nve0 clock types drm/nouveau/fb: default NvMemExec to on, turning it off is used for debugging only drm/nouveau/bios: fix a potential NULL deref in the PROM shadowing function drm/nouveau/i2c: bump the i2c delay for the adt7473 drm/nouveau/therm/fan/tach: default to 2 pulses per revolution drm/nvf0/device: enable video decoding engines on gk110/gk208 drm/nvf1/device: add support for 0xf1 (gk110b) drm/nouveau/device: support for probing GK20A drm/nouveau/graph: add GK20A support drm/nouveau/graph: pad firmware code at load time drm/nouveau/graph: enable when using external fw ...
-rw-r--r--drivers/gpu/drm/nouveau/Makefile6
-rw-r--r--drivers/gpu/drm/nouveau/core/core/object.c10
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nve0.c54
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/dport.c16
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/dport.h8
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv04.c8
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/gk20a.c35
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxgk20a.c53
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h9
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c14
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/gk20a.c47
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c14
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nve4.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/fifo.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/graph.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/clock.h8
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/fb.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/ibus.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bar/base.c6
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c114
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/base.c9
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/base.c7
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c56
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/priv.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramgk20a.c152
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c10
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/ibus/gk20a.c103
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/ic.c6
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c10
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c4
48 files changed, 687 insertions, 122 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index b7d216264775..1aaa2ef577d9 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -102,6 +102,7 @@ nouveau-y += core/subdev/fb/nvaa.o
102nouveau-y += core/subdev/fb/nvaf.o 102nouveau-y += core/subdev/fb/nvaf.o
103nouveau-y += core/subdev/fb/nvc0.o 103nouveau-y += core/subdev/fb/nvc0.o
104nouveau-y += core/subdev/fb/nve0.o 104nouveau-y += core/subdev/fb/nve0.o
105nouveau-y += core/subdev/fb/gk20a.o
105nouveau-y += core/subdev/fb/gm107.o 106nouveau-y += core/subdev/fb/gm107.o
106nouveau-y += core/subdev/fb/ramnv04.o 107nouveau-y += core/subdev/fb/ramnv04.o
107nouveau-y += core/subdev/fb/ramnv10.o 108nouveau-y += core/subdev/fb/ramnv10.o
@@ -117,6 +118,7 @@ nouveau-y += core/subdev/fb/ramnva3.o
117nouveau-y += core/subdev/fb/ramnvaa.o 118nouveau-y += core/subdev/fb/ramnvaa.o
118nouveau-y += core/subdev/fb/ramnvc0.o 119nouveau-y += core/subdev/fb/ramnvc0.o
119nouveau-y += core/subdev/fb/ramnve0.o 120nouveau-y += core/subdev/fb/ramnve0.o
121nouveau-y += core/subdev/fb/ramgk20a.o
120nouveau-y += core/subdev/fb/ramgm107.o 122nouveau-y += core/subdev/fb/ramgm107.o
121nouveau-y += core/subdev/fb/sddr3.o 123nouveau-y += core/subdev/fb/sddr3.o
122nouveau-y += core/subdev/fb/gddr5.o 124nouveau-y += core/subdev/fb/gddr5.o
@@ -136,6 +138,7 @@ nouveau-y += core/subdev/i2c/nv94.o
136nouveau-y += core/subdev/i2c/nvd0.o 138nouveau-y += core/subdev/i2c/nvd0.o
137nouveau-y += core/subdev/ibus/nvc0.o 139nouveau-y += core/subdev/ibus/nvc0.o
138nouveau-y += core/subdev/ibus/nve0.o 140nouveau-y += core/subdev/ibus/nve0.o
141nouveau-y += core/subdev/ibus/gk20a.o
139nouveau-y += core/subdev/instmem/base.o 142nouveau-y += core/subdev/instmem/base.o
140nouveau-y += core/subdev/instmem/nv04.o 143nouveau-y += core/subdev/instmem/nv04.o
141nouveau-y += core/subdev/instmem/nv40.o 144nouveau-y += core/subdev/instmem/nv40.o
@@ -245,6 +248,7 @@ nouveau-y += core/engine/fifo/nv50.o
245nouveau-y += core/engine/fifo/nv84.o 248nouveau-y += core/engine/fifo/nv84.o
246nouveau-y += core/engine/fifo/nvc0.o 249nouveau-y += core/engine/fifo/nvc0.o
247nouveau-y += core/engine/fifo/nve0.o 250nouveau-y += core/engine/fifo/nve0.o
251nouveau-y += core/engine/fifo/gk20a.o
248nouveau-y += core/engine/fifo/nv108.o 252nouveau-y += core/engine/fifo/nv108.o
249nouveau-y += core/engine/graph/ctxnv40.o 253nouveau-y += core/engine/graph/ctxnv40.o
250nouveau-y += core/engine/graph/ctxnv50.o 254nouveau-y += core/engine/graph/ctxnv50.o
@@ -255,6 +259,7 @@ nouveau-y += core/engine/graph/ctxnvc8.o
255nouveau-y += core/engine/graph/ctxnvd7.o 259nouveau-y += core/engine/graph/ctxnvd7.o
256nouveau-y += core/engine/graph/ctxnvd9.o 260nouveau-y += core/engine/graph/ctxnvd9.o
257nouveau-y += core/engine/graph/ctxnve4.o 261nouveau-y += core/engine/graph/ctxnve4.o
262nouveau-y += core/engine/graph/ctxgk20a.o
258nouveau-y += core/engine/graph/ctxnvf0.o 263nouveau-y += core/engine/graph/ctxnvf0.o
259nouveau-y += core/engine/graph/ctxnv108.o 264nouveau-y += core/engine/graph/ctxnv108.o
260nouveau-y += core/engine/graph/ctxgm107.o 265nouveau-y += core/engine/graph/ctxgm107.o
@@ -275,6 +280,7 @@ nouveau-y += core/engine/graph/nvc8.o
275nouveau-y += core/engine/graph/nvd7.o 280nouveau-y += core/engine/graph/nvd7.o
276nouveau-y += core/engine/graph/nvd9.o 281nouveau-y += core/engine/graph/nvd9.o
277nouveau-y += core/engine/graph/nve4.o 282nouveau-y += core/engine/graph/nve4.o
283nouveau-y += core/engine/graph/gk20a.o
278nouveau-y += core/engine/graph/nvf0.o 284nouveau-y += core/engine/graph/nvf0.o
279nouveau-y += core/engine/graph/nv108.o 285nouveau-y += core/engine/graph/nv108.o
280nouveau-y += core/engine/graph/gm107.o 286nouveau-y += core/engine/graph/gm107.o
diff --git a/drivers/gpu/drm/nouveau/core/core/object.c b/drivers/gpu/drm/nouveau/core/core/object.c
index 7f48e288215f..124538555904 100644
--- a/drivers/gpu/drm/nouveau/core/core/object.c
+++ b/drivers/gpu/drm/nouveau/core/core/object.c
@@ -156,7 +156,7 @@ nouveau_object_ctor(struct nouveau_object *parent,
156 } 156 }
157 157
158 if (ret == 0) { 158 if (ret == 0) {
159 nv_debug(object, "created\n"); 159 nv_trace(object, "created\n");
160 atomic_set(&object->refcount, 1); 160 atomic_set(&object->refcount, 1);
161 } 161 }
162 162
@@ -166,7 +166,7 @@ nouveau_object_ctor(struct nouveau_object *parent,
166static void 166static void
167nouveau_object_dtor(struct nouveau_object *object) 167nouveau_object_dtor(struct nouveau_object *object)
168{ 168{
169 nv_debug(object, "destroying\n"); 169 nv_trace(object, "destroying\n");
170 nv_ofuncs(object)->dtor(object); 170 nv_ofuncs(object)->dtor(object);
171} 171}
172 172
@@ -337,7 +337,7 @@ nouveau_object_inc(struct nouveau_object *object)
337 goto fail_self; 337 goto fail_self;
338 } 338 }
339 339
340 nv_debug(object, "initialised\n"); 340 nv_trace(object, "initialised\n");
341 return 0; 341 return 0;
342 342
343fail_self: 343fail_self:
@@ -375,7 +375,7 @@ nouveau_object_decf(struct nouveau_object *object)
375 if (object->parent) 375 if (object->parent)
376 nouveau_object_dec(object->parent, false); 376 nouveau_object_dec(object->parent, false);
377 377
378 nv_debug(object, "stopped\n"); 378 nv_trace(object, "stopped\n");
379 return 0; 379 return 0;
380} 380}
381 381
@@ -411,7 +411,7 @@ nouveau_object_decs(struct nouveau_object *object)
411 } 411 }
412 } 412 }
413 413
414 nv_debug(object, "suspended\n"); 414 nv_trace(object, "suspended\n");
415 return 0; 415 return 0;
416 416
417fail_parent: 417fail_parent:
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
index 9784cbf8a9d2..459099e2515f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
@@ -156,6 +156,23 @@ nve0_identify(struct nouveau_device *device)
156 device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; 156 device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
157 device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass; 157 device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
158 break; 158 break;
159 case 0xea:
160 device->cname = "GK20A";
161 device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
162 device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
163 device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
164 device->oclass[NVDEV_SUBDEV_FB ] = gk20a_fb_oclass;
165 device->oclass[NVDEV_SUBDEV_IBUS ] = &gk20a_ibus_oclass;
166 device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
167 device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
168 device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
169 device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
170 device->oclass[NVDEV_ENGINE_FIFO ] = gk20a_fifo_oclass;
171 device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
172 device->oclass[NVDEV_ENGINE_GR ] = gk20a_graph_oclass;
173 device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
174 device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
175 break;
159 case 0xf0: 176 case 0xf0:
160 device->cname = "GK110"; 177 device->cname = "GK110";
161 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; 178 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
@@ -184,11 +201,42 @@ nve0_identify(struct nouveau_device *device)
184 device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; 201 device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
185 device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; 202 device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
186 device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass; 203 device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
187#if 0
188 device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; 204 device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
189 device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; 205 device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
190 device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; 206 device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
191#endif 207 device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass;
208 break;
209 case 0xf1:
210 device->cname = "GK110B";
211 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
212 device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass;
213 device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
214 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
215 device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
216 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
217 device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
218 device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
219 device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
220 device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
221 device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
222 device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass;
223 device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
224 device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
225 device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
226 device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
227 device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass;
228 device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
229 device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
230 device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
231 device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
232 device->oclass[NVDEV_ENGINE_GR ] = nvf0_graph_oclass;
233 device->oclass[NVDEV_ENGINE_DISP ] = nvf0_disp_oclass;
234 device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
235 device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
236 device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
237 device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
238 device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
239 device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
192 device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass; 240 device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass;
193 break; 241 break;
194 case 0x108: 242 case 0x108:
@@ -219,11 +267,9 @@ nve0_identify(struct nouveau_device *device)
219 device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; 267 device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
220 device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; 268 device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
221 device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass; 269 device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
222#if 0
223 device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; 270 device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
224 device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; 271 device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
225 device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; 272 device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
226#endif
227 break; 273 break;
228 default: 274 default:
229 nv_fatal(device, "unknown Kepler chipset\n"); 275 nv_fatal(device, "unknown Kepler chipset\n");
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c
index 3ca2d25b7f5e..13903533d7a2 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c
@@ -48,7 +48,7 @@ struct dp_state {
48 u8 version; 48 u8 version;
49 struct nouveau_i2c_port *aux; 49 struct nouveau_i2c_port *aux;
50 int head; 50 int head;
51 u8 dpcd[4]; 51 u8 dpcd[16];
52 int link_nr; 52 int link_nr;
53 u32 link_bw; 53 u32 link_bw;
54 u8 stat[6]; 54 u8 stat[6];
@@ -149,7 +149,10 @@ dp_link_train_update(struct dp_state *dp, u32 delay)
149{ 149{
150 int ret; 150 int ret;
151 151
152 udelay(delay); 152 if (dp->dpcd[DPCD_RC0E_AUX_RD_INTERVAL])
153 mdelay(dp->dpcd[DPCD_RC0E_AUX_RD_INTERVAL] * 4);
154 else
155 udelay(delay);
153 156
154 ret = nv_rdaux(dp->aux, DPCD_LS02, dp->stat, 6); 157 ret = nv_rdaux(dp->aux, DPCD_LS02, dp->stat, 6);
155 if (ret) 158 if (ret)
@@ -199,7 +202,10 @@ dp_link_train_eq(struct dp_state *dp)
199 bool eq_done = false, cr_done = true; 202 bool eq_done = false, cr_done = true;
200 int tries = 0, i; 203 int tries = 0, i;
201 204
202 dp_set_training_pattern(dp, 2); 205 if (dp->dpcd[2] & DPCD_RC02_TPS3_SUPPORTED)
206 dp_set_training_pattern(dp, 3);
207 else
208 dp_set_training_pattern(dp, 2);
203 209
204 do { 210 do {
205 if (dp_link_train_update(dp, 400)) 211 if (dp_link_train_update(dp, 400))
@@ -313,8 +319,10 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func,
313 } 319 }
314 320
315 /* bring capabilities within encoder limits */ 321 /* bring capabilities within encoder limits */
322 if (nv_oclass(disp)->handle < NV_ENGINE(DISP, 0x90))
323 dp->dpcd[2] &= ~DPCD_RC02_TPS3_SUPPORTED;
316 if ((dp->dpcd[2] & 0x1f) > dp->outp->dpconf.link_nr) { 324 if ((dp->dpcd[2] & 0x1f) > dp->outp->dpconf.link_nr) {
317 dp->dpcd[2] &= ~0x1f; 325 dp->dpcd[2] &= ~DPCD_RC02_MAX_LANE_COUNT;
318 dp->dpcd[2] |= dp->outp->dpconf.link_nr; 326 dp->dpcd[2] |= dp->outp->dpconf.link_nr;
319 } 327 }
320 if (dp->dpcd[1] > dp->outp->dpconf.link_bw) 328 if (dp->dpcd[1] > dp->outp->dpconf.link_bw)
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dport.h b/drivers/gpu/drm/nouveau/core/engine/disp/dport.h
index 0e1bbd18ff6c..43281c8e9e7b 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/dport.h
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/dport.h
@@ -2,15 +2,15 @@
2#define __NVKM_DISP_DPORT_H__ 2#define __NVKM_DISP_DPORT_H__
3 3
4/* DPCD Receiver Capabilities */ 4/* DPCD Receiver Capabilities */
5#define DPCD_RC00 0x00000 5#define DPCD_RC00_DPCD_REV 0x00000
6#define DPCD_RC00_DPCD_REV 0xff 6#define DPCD_RC01_MAX_LINK_RATE 0x00001
7#define DPCD_RC01 0x00001
8#define DPCD_RC01_MAX_LINK_RATE 0xff
9#define DPCD_RC02 0x00002 7#define DPCD_RC02 0x00002
10#define DPCD_RC02_ENHANCED_FRAME_CAP 0x80 8#define DPCD_RC02_ENHANCED_FRAME_CAP 0x80
9#define DPCD_RC02_TPS3_SUPPORTED 0x40
11#define DPCD_RC02_MAX_LANE_COUNT 0x1f 10#define DPCD_RC02_MAX_LANE_COUNT 0x1f
12#define DPCD_RC03 0x00003 11#define DPCD_RC03 0x00003
13#define DPCD_RC03_MAX_DOWNSPREAD 0x01 12#define DPCD_RC03_MAX_DOWNSPREAD 0x01
13#define DPCD_RC0E_AUX_RD_INTERVAL 0x0000e
14 14
15/* DPCD Link Configuration */ 15/* DPCD Link Configuration */
16#define DPCD_LC00 0x00100 16#define DPCD_LC00 0x00100
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c
index 6c89af792889..94a2cc69ec2c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c
@@ -51,6 +51,14 @@ nv04_disp_scanoutpos(struct nouveau_object *object, u32 mthd,
51 args->htotal = nv_rd32(priv, 0x680824 + (head * 0x2000)) & 0xffff; 51 args->htotal = nv_rd32(priv, 0x680824 + (head * 0x2000)) & 0xffff;
52 args->hblanke = args->htotal - 1; 52 args->hblanke = args->htotal - 1;
53 53
54 /*
55 * If output is vga instead of digital then vtotal/htotal is invalid
56 * so we have to give up and trigger the timestamping fallback in the
57 * drm core.
58 */
59 if (!args->vtotal || !args->htotal)
60 return -ENOTSUPP;
61
54 args->time[0] = ktime_to_ns(ktime_get()); 62 args->time[0] = ktime_to_ns(ktime_get());
55 line = nv_rd32(priv, 0x600868 + (head * 0x2000)); 63 line = nv_rd32(priv, 0x600868 + (head * 0x2000));
56 args->time[1] = ktime_to_ns(ktime_get()); 64 args->time[1] = ktime_to_ns(ktime_get());
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/gk20a.c b/drivers/gpu/drm/nouveau/core/engine/fifo/gk20a.c
new file mode 100644
index 000000000000..327456eae963
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/gk20a.c
@@ -0,0 +1,35 @@
1/*
2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include "nve0.h"
24
25struct nouveau_oclass *
26gk20a_fifo_oclass = &(struct nve0_fifo_impl) {
27 .base.handle = NV_ENGINE(FIFO, 0xea),
28 .base.ofuncs = &(struct nouveau_ofuncs) {
29 .ctor = nve0_fifo_ctor,
30 .dtor = nve0_fifo_dtor,
31 .init = nve0_fifo_init,
32 .fini = nve0_fifo_fini,
33 },
34 .channels = 128,
35}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h
index 014344ebee66..e96b32bb1bbc 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.h
@@ -8,6 +8,7 @@ int nve0_fifo_ctor(struct nouveau_object *, struct nouveau_object *,
8 struct nouveau_object **); 8 struct nouveau_object **);
9void nve0_fifo_dtor(struct nouveau_object *); 9void nve0_fifo_dtor(struct nouveau_object *);
10int nve0_fifo_init(struct nouveau_object *); 10int nve0_fifo_init(struct nouveau_object *);
11int nve0_fifo_fini(struct nouveau_object *, bool);
11 12
12struct nve0_fifo_impl { 13struct nve0_fifo_impl {
13 struct nouveau_oclass base; 14 struct nouveau_oclass base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk20a.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk20a.c
new file mode 100644
index 000000000000..224ee0287ab7
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxgk20a.c
@@ -0,0 +1,53 @@
1/*
2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include "ctxnvc0.h"
24
25static const struct nvc0_graph_pack
26gk20a_grctx_pack_mthd[] = {
27 { nve4_grctx_init_a097_0, 0xa297 },
28 { nvc0_grctx_init_902d_0, 0x902d },
29 {}
30};
31
32struct nouveau_oclass *
33gk20a_grctx_oclass = &(struct nvc0_grctx_oclass) {
34 .base.handle = NV_ENGCTX(GR, 0xea),
35 .base.ofuncs = &(struct nouveau_ofuncs) {
36 .ctor = nvc0_graph_context_ctor,
37 .dtor = nvc0_graph_context_dtor,
38 .init = _nouveau_graph_context_init,
39 .fini = _nouveau_graph_context_fini,
40 .rd32 = _nouveau_graph_context_rd32,
41 .wr32 = _nouveau_graph_context_wr32,
42 },
43 .main = nve4_grctx_generate_main,
44 .mods = nve4_grctx_generate_mods,
45 .unkn = nve4_grctx_generate_unkn,
46 .hub = nve4_grctx_pack_hub,
47 .gpc = nve4_grctx_pack_gpc,
48 .zcull = nvc0_grctx_pack_zcull,
49 .tpc = nve4_grctx_pack_tpc,
50 .ppc = nve4_grctx_pack_ppc,
51 .icmd = nve4_grctx_pack_icmd,
52 .mthd = gk20a_grctx_pack_mthd,
53}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c
index 48351b4d6d6b..8de4a4291548 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c
@@ -545,10 +545,12 @@ nv108_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
545 mmio_list(0x408010, 0x80000000, 0, 0); 545 mmio_list(0x408010, 0x80000000, 0, 0);
546 mmio_list(0x419004, 0x00000000, 8, 1); 546 mmio_list(0x419004, 0x00000000, 8, 1);
547 mmio_list(0x419008, 0x00000000, 0, 0); 547 mmio_list(0x419008, 0x00000000, 0, 0);
548 mmio_list(0x4064cc, 0x80000000, 0, 0);
548 mmio_list(0x408004, 0x00000000, 8, 0); 549 mmio_list(0x408004, 0x00000000, 8, 0);
549 mmio_list(0x408008, 0x80000030, 0, 0); 550 mmio_list(0x408008, 0x80000030, 0, 0);
550 mmio_list(0x418808, 0x00000000, 8, 0); 551 mmio_list(0x418808, 0x00000000, 8, 0);
551 mmio_list(0x41880c, 0x80000030, 0, 0); 552 mmio_list(0x41880c, 0x80000030, 0, 0);
553 mmio_list(0x4064c8, 0x00c20200, 0, 0);
552 mmio_list(0x418810, 0x80000000, 12, 2); 554 mmio_list(0x418810, 0x80000000, 12, 2);
553 mmio_list(0x419848, 0x10000000, 12, 2); 555 mmio_list(0x419848, 0x10000000, 12, 2);
554 556
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h
index 9c815d1f99ef..8da8b627b9d0 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.h
@@ -69,7 +69,9 @@ extern struct nouveau_oclass *nvd7_grctx_oclass;
69extern struct nouveau_oclass *nvd9_grctx_oclass; 69extern struct nouveau_oclass *nvd9_grctx_oclass;
70 70
71extern struct nouveau_oclass *nve4_grctx_oclass; 71extern struct nouveau_oclass *nve4_grctx_oclass;
72extern struct nouveau_oclass *gk20a_grctx_oclass;
72void nve4_grctx_generate_main(struct nvc0_graph_priv *, struct nvc0_grctx *); 73void nve4_grctx_generate_main(struct nvc0_graph_priv *, struct nvc0_grctx *);
74void nve4_grctx_generate_mods(struct nvc0_graph_priv *, struct nvc0_grctx *);
73void nve4_grctx_generate_unkn(struct nvc0_graph_priv *); 75void nve4_grctx_generate_unkn(struct nvc0_graph_priv *);
74void nve4_grctx_generate_r418bb8(struct nvc0_graph_priv *); 76void nve4_grctx_generate_r418bb8(struct nvc0_graph_priv *);
75 77
@@ -151,6 +153,13 @@ extern const struct nvc0_graph_init nve4_grctx_init_gpm_0[];
151 153
152extern const struct nvc0_graph_init nve4_grctx_init_pes_0[]; 154extern const struct nvc0_graph_init nve4_grctx_init_pes_0[];
153 155
156extern const struct nvc0_graph_pack nve4_grctx_pack_hub[];
157extern const struct nvc0_graph_pack nve4_grctx_pack_gpc[];
158extern const struct nvc0_graph_pack nve4_grctx_pack_tpc[];
159extern const struct nvc0_graph_pack nve4_grctx_pack_ppc[];
160extern const struct nvc0_graph_pack nve4_grctx_pack_icmd[];
161extern const struct nvc0_graph_init nve4_grctx_init_a097_0[];
162
154extern const struct nvc0_graph_pack nvf0_grctx_pack_mthd[]; 163extern const struct nvc0_graph_pack nvf0_grctx_pack_mthd[];
155 164
156extern const struct nvc0_graph_init nvf0_grctx_init_pri_0[]; 165extern const struct nvc0_graph_init nvf0_grctx_init_pri_0[];
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c
index 49a14b116a5f..c5b249238587 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c
@@ -272,13 +272,13 @@ nve4_grctx_init_icmd_0[] = {
272 {} 272 {}
273}; 273};
274 274
275static const struct nvc0_graph_pack 275const struct nvc0_graph_pack
276nve4_grctx_pack_icmd[] = { 276nve4_grctx_pack_icmd[] = {
277 { nve4_grctx_init_icmd_0 }, 277 { nve4_grctx_init_icmd_0 },
278 {} 278 {}
279}; 279};
280 280
281static const struct nvc0_graph_init 281const struct nvc0_graph_init
282nve4_grctx_init_a097_0[] = { 282nve4_grctx_init_a097_0[] = {
283 { 0x000800, 8, 0x40, 0x00000000 }, 283 { 0x000800, 8, 0x40, 0x00000000 },
284 { 0x000804, 8, 0x40, 0x00000000 }, 284 { 0x000804, 8, 0x40, 0x00000000 },
@@ -697,7 +697,7 @@ nve4_grctx_init_be_0[] = {
697 {} 697 {}
698}; 698};
699 699
700static const struct nvc0_graph_pack 700const struct nvc0_graph_pack
701nve4_grctx_pack_hub[] = { 701nve4_grctx_pack_hub[] = {
702 { nvc0_grctx_init_main_0 }, 702 { nvc0_grctx_init_main_0 },
703 { nve4_grctx_init_fe_0 }, 703 { nve4_grctx_init_fe_0 },
@@ -737,7 +737,7 @@ nve4_grctx_init_gpm_0[] = {
737 {} 737 {}
738}; 738};
739 739
740static const struct nvc0_graph_pack 740const struct nvc0_graph_pack
741nve4_grctx_pack_gpc[] = { 741nve4_grctx_pack_gpc[] = {
742 { nvc0_grctx_init_gpc_unk_0 }, 742 { nvc0_grctx_init_gpc_unk_0 },
743 { nvd9_grctx_init_prop_0 }, 743 { nvd9_grctx_init_prop_0 },
@@ -802,7 +802,7 @@ nve4_grctx_init_sm_0[] = {
802 {} 802 {}
803}; 803};
804 804
805static const struct nvc0_graph_pack 805const struct nvc0_graph_pack
806nve4_grctx_pack_tpc[] = { 806nve4_grctx_pack_tpc[] = {
807 { nvd7_grctx_init_pe_0 }, 807 { nvd7_grctx_init_pe_0 },
808 { nve4_grctx_init_tex_0 }, 808 { nve4_grctx_init_tex_0 },
@@ -826,7 +826,7 @@ nve4_grctx_init_cbm_0[] = {
826 {} 826 {}
827}; 827};
828 828
829static const struct nvc0_graph_pack 829const struct nvc0_graph_pack
830nve4_grctx_pack_ppc[] = { 830nve4_grctx_pack_ppc[] = {
831 { nve4_grctx_init_pes_0 }, 831 { nve4_grctx_init_pes_0 },
832 { nve4_grctx_init_cbm_0 }, 832 { nve4_grctx_init_cbm_0 },
@@ -838,7 +838,7 @@ nve4_grctx_pack_ppc[] = {
838 * PGRAPH context implementation 838 * PGRAPH context implementation
839 ******************************************************************************/ 839 ******************************************************************************/
840 840
841static void 841void
842nve4_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) 842nve4_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
843{ 843{
844 u32 magic[GPC_MAX][2]; 844 u32 magic[GPC_MAX][2];
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/gk20a.c b/drivers/gpu/drm/nouveau/core/engine/graph/gk20a.c
new file mode 100644
index 000000000000..83048a56430d
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/gk20a.c
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include "nvc0.h"
24#include "ctxnvc0.h"
25
26static struct nouveau_oclass
27gk20a_graph_sclass[] = {
28 { 0x902d, &nouveau_object_ofuncs },
29 { 0xa040, &nouveau_object_ofuncs },
30 { 0xa297, &nouveau_object_ofuncs },
31 { 0xa0c0, &nouveau_object_ofuncs },
32 {}
33};
34
35struct nouveau_oclass *
36gk20a_graph_oclass = &(struct nvc0_graph_oclass) {
37 .base.handle = NV_ENGINE(GR, 0xea),
38 .base.ofuncs = &(struct nouveau_ofuncs) {
39 .ctor = nvc0_graph_ctor,
40 .dtor = nvc0_graph_dtor,
41 .init = nve4_graph_init,
42 .fini = nve4_graph_fini,
43 },
44 .cclass = &gk20a_grctx_oclass,
45 .sclass = gk20a_graph_sclass,
46 .mmio = nve4_graph_pack_mmio,
47}.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
index f3c7329da0a0..bf7bdb1f291e 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
@@ -894,6 +894,10 @@ nvc0_graph_init_fw(struct nvc0_graph_priv *priv, u32 fuc_base,
894 nv_wr32(priv, fuc_base + 0x0188, i >> 6); 894 nv_wr32(priv, fuc_base + 0x0188, i >> 6);
895 nv_wr32(priv, fuc_base + 0x0184, code->data[i]); 895 nv_wr32(priv, fuc_base + 0x0184, code->data[i]);
896 } 896 }
897
898 /* code must be padded to 0x40 words */
899 for (; i & 0x3f; i++)
900 nv_wr32(priv, fuc_base + 0x0184, 0);
897} 901}
898 902
899static void 903static void
@@ -1259,10 +1263,14 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
1259 struct nvc0_graph_oclass *oclass = (void *)bclass; 1263 struct nvc0_graph_oclass *oclass = (void *)bclass;
1260 struct nouveau_device *device = nv_device(parent); 1264 struct nouveau_device *device = nv_device(parent);
1261 struct nvc0_graph_priv *priv; 1265 struct nvc0_graph_priv *priv;
1266 bool use_ext_fw, enable;
1262 int ret, i; 1267 int ret, i;
1263 1268
1264 ret = nouveau_graph_create(parent, engine, bclass, 1269 use_ext_fw = nouveau_boolopt(device->cfgopt, "NvGrUseFW",
1265 (oclass->fecs.ucode != NULL), &priv); 1270 oclass->fecs.ucode == NULL);
1271 enable = use_ext_fw || oclass->fecs.ucode != NULL;
1272
1273 ret = nouveau_graph_create(parent, engine, bclass, enable, &priv);
1266 *pobject = nv_object(priv); 1274 *pobject = nv_object(priv);
1267 if (ret) 1275 if (ret)
1268 return ret; 1276 return ret;
@@ -1272,7 +1280,7 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
1272 1280
1273 priv->base.units = nvc0_graph_units; 1281 priv->base.units = nvc0_graph_units;
1274 1282
1275 if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) { 1283 if (use_ext_fw) {
1276 nv_info(priv, "using external firmware\n"); 1284 nv_info(priv, "using external firmware\n");
1277 if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) || 1285 if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
1278 nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) || 1286 nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
index 90d44616c876..75203a99d902 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.h
@@ -116,6 +116,7 @@ int nvc0_graph_ctor(struct nouveau_object *, struct nouveau_object *,
116 struct nouveau_object **); 116 struct nouveau_object **);
117void nvc0_graph_dtor(struct nouveau_object *); 117void nvc0_graph_dtor(struct nouveau_object *);
118int nvc0_graph_init(struct nouveau_object *); 118int nvc0_graph_init(struct nouveau_object *);
119int nve4_graph_fini(struct nouveau_object *, bool);
119int nve4_graph_init(struct nouveau_object *); 120int nve4_graph_init(struct nouveau_object *);
120 121
121extern struct nouveau_oclass nvc0_graph_sclass[]; 122extern struct nouveau_oclass nvc0_graph_sclass[];
@@ -217,6 +218,7 @@ extern const struct nvc0_graph_init nve4_graph_init_main_0[];
217extern const struct nvc0_graph_init nve4_graph_init_tpccs_0[]; 218extern const struct nvc0_graph_init nve4_graph_init_tpccs_0[];
218extern const struct nvc0_graph_init nve4_graph_init_pe_0[]; 219extern const struct nvc0_graph_init nve4_graph_init_pe_0[];
219extern const struct nvc0_graph_init nve4_graph_init_be_0[]; 220extern const struct nvc0_graph_init nve4_graph_init_be_0[];
221extern const struct nvc0_graph_pack nve4_graph_pack_mmio[];
220 222
221extern const struct nvc0_graph_init nvf0_graph_init_fe_0[]; 223extern const struct nvc0_graph_init nvf0_graph_init_fe_0[];
222extern const struct nvc0_graph_init nvf0_graph_init_sked_0[]; 224extern const struct nvc0_graph_init nvf0_graph_init_sked_0[];
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c b/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c
index f7c011217175..51e0c075ad34 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nve4.c
@@ -151,7 +151,7 @@ nve4_graph_init_be_0[] = {
151 {} 151 {}
152}; 152};
153 153
154static const struct nvc0_graph_pack 154const struct nvc0_graph_pack
155nve4_graph_pack_mmio[] = { 155nve4_graph_pack_mmio[] = {
156 { nve4_graph_init_main_0 }, 156 { nve4_graph_init_main_0 },
157 { nvc0_graph_init_fe_0 }, 157 { nvc0_graph_init_fe_0 },
@@ -189,7 +189,7 @@ nve4_graph_pack_mmio[] = {
189 * PGRAPH engine/subdev functions 189 * PGRAPH engine/subdev functions
190 ******************************************************************************/ 190 ******************************************************************************/
191 191
192static int 192int
193nve4_graph_fini(struct nouveau_object *object, bool suspend) 193nve4_graph_fini(struct nouveau_object *object, bool suspend)
194{ 194{
195 struct nvc0_graph_priv *priv = (void *)object; 195 struct nvc0_graph_priv *priv = (void *)object;
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
index 26b6b2bb1112..b639eb2c74ff 100644
--- a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h
@@ -109,6 +109,7 @@ extern struct nouveau_oclass *nv50_fifo_oclass;
109extern struct nouveau_oclass *nv84_fifo_oclass; 109extern struct nouveau_oclass *nv84_fifo_oclass;
110extern struct nouveau_oclass *nvc0_fifo_oclass; 110extern struct nouveau_oclass *nvc0_fifo_oclass;
111extern struct nouveau_oclass *nve0_fifo_oclass; 111extern struct nouveau_oclass *nve0_fifo_oclass;
112extern struct nouveau_oclass *gk20a_fifo_oclass;
112extern struct nouveau_oclass *nv108_fifo_oclass; 113extern struct nouveau_oclass *nv108_fifo_oclass;
113 114
114void nv04_fifo_intr(struct nouveau_subdev *); 115void nv04_fifo_intr(struct nouveau_subdev *);
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/graph.h b/drivers/gpu/drm/nouveau/core/include/engine/graph.h
index 871edfdf3d5b..8c1d4772da0c 100644
--- a/drivers/gpu/drm/nouveau/core/include/engine/graph.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/graph.h
@@ -68,6 +68,7 @@ extern struct nouveau_oclass *nvc8_graph_oclass;
68extern struct nouveau_oclass *nvd7_graph_oclass; 68extern struct nouveau_oclass *nvd7_graph_oclass;
69extern struct nouveau_oclass *nvd9_graph_oclass; 69extern struct nouveau_oclass *nvd9_graph_oclass;
70extern struct nouveau_oclass *nve4_graph_oclass; 70extern struct nouveau_oclass *nve4_graph_oclass;
71extern struct nouveau_oclass *gk20a_graph_oclass;
71extern struct nouveau_oclass *nvf0_graph_oclass; 72extern struct nouveau_oclass *nvf0_graph_oclass;
72extern struct nouveau_oclass *nv108_graph_oclass; 73extern struct nouveau_oclass *nv108_graph_oclass;
73extern struct nouveau_oclass *gm107_graph_oclass; 74extern struct nouveau_oclass *gm107_graph_oclass;
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
index 8f4ced75444a..c01e29c9f89a 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
@@ -77,6 +77,8 @@ struct nouveau_clock {
77 int tstate; /* thermal adjustment (max-) */ 77 int tstate; /* thermal adjustment (max-) */
78 int dstate; /* display adjustment (min+) */ 78 int dstate; /* display adjustment (min+) */
79 79
80 bool allow_reclock;
81
80 int (*read)(struct nouveau_clock *, enum nv_clk_src); 82 int (*read)(struct nouveau_clock *, enum nv_clk_src);
81 int (*calc)(struct nouveau_clock *, struct nouveau_cstate *); 83 int (*calc)(struct nouveau_clock *, struct nouveau_cstate *);
82 int (*prog)(struct nouveau_clock *); 84 int (*prog)(struct nouveau_clock *);
@@ -106,8 +108,8 @@ struct nouveau_clocks {
106 int mdiv; 108 int mdiv;
107}; 109};
108 110
109#define nouveau_clock_create(p,e,o,i,d) \ 111#define nouveau_clock_create(p,e,o,i,r,d) \
110 nouveau_clock_create_((p), (e), (o), (i), sizeof(**d), (void **)d) 112 nouveau_clock_create_((p), (e), (o), (i), (r), sizeof(**d), (void **)d)
111#define nouveau_clock_destroy(p) ({ \ 113#define nouveau_clock_destroy(p) ({ \
112 struct nouveau_clock *clk = (p); \ 114 struct nouveau_clock *clk = (p); \
113 _nouveau_clock_dtor(nv_object(clk)); \ 115 _nouveau_clock_dtor(nv_object(clk)); \
@@ -121,7 +123,7 @@ struct nouveau_clocks {
121 123
122int nouveau_clock_create_(struct nouveau_object *, struct nouveau_object *, 124int nouveau_clock_create_(struct nouveau_object *, struct nouveau_object *,
123 struct nouveau_oclass *, 125 struct nouveau_oclass *,
124 struct nouveau_clocks *, int, void **); 126 struct nouveau_clocks *, bool, int, void **);
125void _nouveau_clock_dtor(struct nouveau_object *); 127void _nouveau_clock_dtor(struct nouveau_object *);
126int _nouveau_clock_init(struct nouveau_object *); 128int _nouveau_clock_init(struct nouveau_object *);
127#define _nouveau_clock_fini _nouveau_subdev_fini 129#define _nouveau_clock_fini _nouveau_subdev_fini
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
index 58c7ccdebb01..871e73914b24 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h
@@ -105,6 +105,7 @@ extern struct nouveau_oclass *nvaa_fb_oclass;
105extern struct nouveau_oclass *nvaf_fb_oclass; 105extern struct nouveau_oclass *nvaf_fb_oclass;
106extern struct nouveau_oclass *nvc0_fb_oclass; 106extern struct nouveau_oclass *nvc0_fb_oclass;
107extern struct nouveau_oclass *nve0_fb_oclass; 107extern struct nouveau_oclass *nve0_fb_oclass;
108extern struct nouveau_oclass *gk20a_fb_oclass;
108extern struct nouveau_oclass *gm107_fb_oclass; 109extern struct nouveau_oclass *gm107_fb_oclass;
109 110
110#include <subdev/bios/ramcfg.h> 111#include <subdev/bios/ramcfg.h>
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
index 88814f159d89..31df634c0fdc 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/ibus.h
@@ -30,5 +30,6 @@ nouveau_ibus(void *obj)
30 30
31extern struct nouveau_oclass nvc0_ibus_oclass; 31extern struct nouveau_oclass nvc0_ibus_oclass;
32extern struct nouveau_oclass nve0_ibus_oclass; 32extern struct nouveau_oclass nve0_ibus_oclass;
33extern struct nouveau_oclass gk20a_ibus_oclass;
33 34
34#endif 35#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/base.c b/drivers/gpu/drm/nouveau/core/subdev/bar/base.c
index bdf594116f3f..73b1ed20c8d5 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bar/base.c
@@ -118,8 +118,10 @@ nouveau_bar_create_(struct nouveau_object *parent,
118 if (ret) 118 if (ret)
119 return ret; 119 return ret;
120 120
121 bar->iomem = ioremap(nv_device_resource_start(device, 3), 121 if (nv_device_resource_len(device, 3) != 0)
122 nv_device_resource_len(device, 3)); 122 bar->iomem = ioremap(nv_device_resource_start(device, 3),
123 nv_device_resource_len(device, 3));
124
123 return 0; 125 return 0;
124} 126}
125 127
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
index 3f30db62e656..ca8139b9ab27 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
@@ -30,14 +30,16 @@
30 30
31#include "priv.h" 31#include "priv.h"
32 32
33struct nvc0_bar_priv_vm {
34 struct nouveau_gpuobj *mem;
35 struct nouveau_gpuobj *pgd;
36 struct nouveau_vm *vm;
37};
38
33struct nvc0_bar_priv { 39struct nvc0_bar_priv {
34 struct nouveau_bar base; 40 struct nouveau_bar base;
35 spinlock_t lock; 41 spinlock_t lock;
36 struct { 42 struct nvc0_bar_priv_vm bar[2];
37 struct nouveau_gpuobj *mem;
38 struct nouveau_gpuobj *pgd;
39 struct nouveau_vm *vm;
40 } bar[2];
41}; 43};
42 44
43static int 45static int
@@ -79,87 +81,87 @@ nvc0_bar_unmap(struct nouveau_bar *bar, struct nouveau_vma *vma)
79} 81}
80 82
81static int 83static int
82nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 84nvc0_bar_init_vm(struct nvc0_bar_priv *priv, struct nvc0_bar_priv_vm *bar_vm,
83 struct nouveau_oclass *oclass, void *data, u32 size, 85 int bar_nr)
84 struct nouveau_object **pobject)
85{ 86{
86 struct nouveau_device *device = nv_device(parent); 87 struct nouveau_device *device = nv_device(&priv->base);
87 struct nvc0_bar_priv *priv;
88 struct nouveau_gpuobj *mem;
89 struct nouveau_vm *vm; 88 struct nouveau_vm *vm;
89 resource_size_t bar_len;
90 int ret; 90 int ret;
91 91
92 ret = nouveau_bar_create(parent, engine, oclass, &priv);
93 *pobject = nv_object(priv);
94 if (ret)
95 return ret;
96
97 /* BAR3 */
98 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0, 92 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
99 &priv->bar[0].mem); 93 &bar_vm->mem);
100 mem = priv->bar[0].mem;
101 if (ret) 94 if (ret)
102 return ret; 95 return ret;
103 96
104 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0, 97 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
105 &priv->bar[0].pgd); 98 &bar_vm->pgd);
106 if (ret) 99 if (ret)
107 return ret; 100 return ret;
108 101
109 ret = nouveau_vm_new(device, 0, nv_device_resource_len(device, 3), 0, &vm); 102 bar_len = nv_device_resource_len(device, bar_nr);
103
104 ret = nouveau_vm_new(device, 0, bar_len, 0, &vm);
110 if (ret) 105 if (ret)
111 return ret; 106 return ret;
112 107
113 atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]); 108 atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
114 109
115 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 110 /*
116 (nv_device_resource_len(device, 3) >> 12) * 8, 111 * Bootstrap page table lookup.
117 0x1000, NVOBJ_FLAG_ZERO_ALLOC, 112 */
118 &vm->pgt[0].obj[0]); 113 if (bar_nr == 3) {
119 vm->pgt[0].refcount[0] = 1; 114 ret = nouveau_gpuobj_new(nv_object(priv), NULL,
120 if (ret) 115 (bar_len >> 12) * 8, 0x1000,
121 return ret; 116 NVOBJ_FLAG_ZERO_ALLOC,
117 &vm->pgt[0].obj[0]);
118 vm->pgt[0].refcount[0] = 1;
119 if (ret)
120 return ret;
121 }
122 122
123 ret = nouveau_vm_ref(vm, &priv->bar[0].vm, priv->bar[0].pgd); 123 ret = nouveau_vm_ref(vm, &bar_vm->vm, bar_vm->pgd);
124 nouveau_vm_ref(NULL, &vm, NULL); 124 nouveau_vm_ref(NULL, &vm, NULL);
125 if (ret) 125 if (ret)
126 return ret; 126 return ret;
127 127
128 nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[0].pgd->addr)); 128 nv_wo32(bar_vm->mem, 0x0200, lower_32_bits(bar_vm->pgd->addr));
129 nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[0].pgd->addr)); 129 nv_wo32(bar_vm->mem, 0x0204, upper_32_bits(bar_vm->pgd->addr));
130 nv_wo32(mem, 0x0208, lower_32_bits(nv_device_resource_len(device, 3) - 1)); 130 nv_wo32(bar_vm->mem, 0x0208, lower_32_bits(bar_len - 1));
131 nv_wo32(mem, 0x020c, upper_32_bits(nv_device_resource_len(device, 3) - 1)); 131 nv_wo32(bar_vm->mem, 0x020c, upper_32_bits(bar_len - 1));
132 132
133 /* BAR1 */ 133 return 0;
134 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0, 134}
135 &priv->bar[1].mem);
136 mem = priv->bar[1].mem;
137 if (ret)
138 return ret;
139 135
140 ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0, 136static int
141 &priv->bar[1].pgd); 137nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
142 if (ret) 138 struct nouveau_oclass *oclass, void *data, u32 size,
143 return ret; 139 struct nouveau_object **pobject)
140{
141 struct nouveau_device *device = nv_device(parent);
142 struct nvc0_bar_priv *priv;
143 bool has_bar3 = nv_device_resource_len(device, 3) != 0;
144 int ret;
144 145
145 ret = nouveau_vm_new(device, 0, nv_device_resource_len(device, 1), 0, &vm); 146 ret = nouveau_bar_create(parent, engine, oclass, &priv);
147 *pobject = nv_object(priv);
146 if (ret) 148 if (ret)
147 return ret; 149 return ret;
148 150
149 atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]); 151 /* BAR3 */
152 if (has_bar3) {
153 ret = nvc0_bar_init_vm(priv, &priv->bar[0], 3);
154 if (ret)
155 return ret;
156 priv->base.alloc = nouveau_bar_alloc;
157 priv->base.kmap = nvc0_bar_kmap;
158 }
150 159
151 ret = nouveau_vm_ref(vm, &priv->bar[1].vm, priv->bar[1].pgd); 160 /* BAR1 */
152 nouveau_vm_ref(NULL, &vm, NULL); 161 ret = nvc0_bar_init_vm(priv, &priv->bar[1], 1);
153 if (ret) 162 if (ret)
154 return ret; 163 return ret;
155 164
156 nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[1].pgd->addr));
157 nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[1].pgd->addr));
158 nv_wo32(mem, 0x0208, lower_32_bits(nv_device_resource_len(device, 1) - 1));
159 nv_wo32(mem, 0x020c, upper_32_bits(nv_device_resource_len(device, 1) - 1));
160
161 priv->base.alloc = nouveau_bar_alloc;
162 priv->base.kmap = nvc0_bar_kmap;
163 priv->base.umap = nvc0_bar_umap; 165 priv->base.umap = nvc0_bar_umap;
164 priv->base.unmap = nvc0_bar_unmap; 166 priv->base.unmap = nvc0_bar_unmap;
165 priv->base.flush = nv84_bar_flush; 167 priv->base.flush = nv84_bar_flush;
@@ -201,7 +203,9 @@ nvc0_bar_init(struct nouveau_object *object)
201 nv_mask(priv, 0x100c80, 0x00000001, 0x00000000); 203 nv_mask(priv, 0x100c80, 0x00000001, 0x00000000);
202 204
203 nv_wr32(priv, 0x001704, 0x80000000 | priv->bar[1].mem->addr >> 12); 205 nv_wr32(priv, 0x001704, 0x80000000 | priv->bar[1].mem->addr >> 12);
204 nv_wr32(priv, 0x001714, 0xc0000000 | priv->bar[0].mem->addr >> 12); 206 if (priv->bar[0].mem)
207 nv_wr32(priv, 0x001714,
208 0xc0000000 | priv->bar[0].mem->addr >> 12);
205 return 0; 209 return 0;
206} 210}
207 211
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
index 222e8ebb669d..d45704a2c2df 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
@@ -183,10 +183,11 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios)
183 goto out; 183 goto out;
184 184
185 bios->data = kmalloc(bios->size, GFP_KERNEL); 185 bios->data = kmalloc(bios->size, GFP_KERNEL);
186 if (bios->data) { 186 if (!bios->data)
187 for (i = 0; i < bios->size; i += 4) 187 goto out;
188 ((u32 *)bios->data)[i/4] = nv_rd32(bios, 0x300000 + i); 188
189 } 189 for (i = 0; i < bios->size; i += 4)
190 ((u32 *)bios->data)[i/4] = nv_rd32(bios, 0x300000 + i);
190 191
191 /* check the PCI record header */ 192 /* check the PCI record header */
192 pcir = nv_ro16(bios, 0x0018); 193 pcir = nv_ro16(bios, 0x0018);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/base.c b/drivers/gpu/drm/nouveau/core/subdev/clock/base.c
index dd62baead39c..22351f594d2a 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/base.c
@@ -346,8 +346,8 @@ nouveau_clock_ustate_update(struct nouveau_clock *clk, int req)
346 struct nouveau_pstate *pstate; 346 struct nouveau_pstate *pstate;
347 int i = 0; 347 int i = 0;
348 348
349 /* YKW repellant */ 349 if (!clk->allow_reclock)
350 return -ENOSYS; 350 return -ENOSYS;
351 351
352 if (req != -1 && req != -2) { 352 if (req != -1 && req != -2) {
353 list_for_each_entry(pstate, &clk->states, head) { 353 list_for_each_entry(pstate, &clk->states, head) {
@@ -456,6 +456,7 @@ nouveau_clock_create_(struct nouveau_object *parent,
456 struct nouveau_object *engine, 456 struct nouveau_object *engine,
457 struct nouveau_oclass *oclass, 457 struct nouveau_oclass *oclass,
458 struct nouveau_clocks *clocks, 458 struct nouveau_clocks *clocks,
459 bool allow_reclock,
459 int length, void **object) 460 int length, void **object)
460{ 461{
461 struct nouveau_device *device = nv_device(parent); 462 struct nouveau_device *device = nv_device(parent);
@@ -478,6 +479,8 @@ nouveau_clock_create_(struct nouveau_object *parent,
478 ret = nouveau_pstate_new(clk, idx++); 479 ret = nouveau_pstate_new(clk, idx++);
479 } while (ret == 0); 480 } while (ret == 0);
480 481
482 clk->allow_reclock = allow_reclock;
483
481 mode = nouveau_stropt(device->cfgopt, "NvClkMode", &arglen); 484 mode = nouveau_stropt(device->cfgopt, "NvClkMode", &arglen);
482 if (mode) { 485 if (mode) {
483 if (!strncasecmpz(mode, "disabled", arglen)) { 486 if (!strncasecmpz(mode, "disabled", arglen)) {
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
index b74db6cfc4e2..eb2d4425a49e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
@@ -82,7 +82,8 @@ nv04_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
82 struct nv04_clock_priv *priv; 82 struct nv04_clock_priv *priv;
83 int ret; 83 int ret;
84 84
85 ret = nouveau_clock_create(parent, engine, oclass, nv04_domain, &priv); 85 ret = nouveau_clock_create(parent, engine, oclass, nv04_domain, false,
86 &priv);
86 *pobject = nv_object(priv); 87 *pobject = nv_object(priv);
87 if (ret) 88 if (ret)
88 return ret; 89 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
index db7346f79080..8a9e16839791 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
@@ -213,7 +213,8 @@ nv40_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
213 struct nv40_clock_priv *priv; 213 struct nv40_clock_priv *priv;
214 int ret; 214 int ret;
215 215
216 ret = nouveau_clock_create(parent, engine, oclass, nv40_domain, &priv); 216 ret = nouveau_clock_create(parent, engine, oclass, nv40_domain, true,
217 &priv);
217 *pobject = nv_object(priv); 218 *pobject = nv_object(priv);
218 if (ret) 219 if (ret)
219 return ret; 220 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
index 250a6d96016b..8c132772ba9e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
@@ -507,7 +507,7 @@ nv50_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
507 int ret; 507 int ret;
508 508
509 ret = nouveau_clock_create(parent, engine, oclass, pclass->domains, 509 ret = nouveau_clock_create(parent, engine, oclass, pclass->domains,
510 &priv); 510 false, &priv);
511 *pobject = nv_object(priv); 511 *pobject = nv_object(priv);
512 if (ret) 512 if (ret)
513 return ret; 513 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
index 4f5a1373f002..9fb58354a80b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
@@ -302,7 +302,8 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
302 struct nva3_clock_priv *priv; 302 struct nva3_clock_priv *priv;
303 int ret; 303 int ret;
304 304
305 ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, &priv); 305 ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, false,
306 &priv);
306 *pobject = nv_object(priv); 307 *pobject = nv_object(priv);
307 if (ret) 308 if (ret)
308 return ret; 309 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c
index 7a723b4f564d..6a65fc9e9663 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c
@@ -421,7 +421,8 @@ nvaa_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
421 struct nvaa_clock_priv *priv; 421 struct nvaa_clock_priv *priv;
422 int ret; 422 int ret;
423 423
424 ret = nouveau_clock_create(parent, engine, oclass, nvaa_domains, &priv); 424 ret = nouveau_clock_create(parent, engine, oclass, nvaa_domains, true,
425 &priv);
425 *pobject = nv_object(priv); 426 *pobject = nv_object(priv);
426 if (ret) 427 if (ret)
427 return ret; 428 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
index c3105720ed24..dbf8517f54da 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
@@ -437,7 +437,8 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
437 struct nvc0_clock_priv *priv; 437 struct nvc0_clock_priv *priv;
438 int ret; 438 int ret;
439 439
440 ret = nouveau_clock_create(parent, engine, oclass, nvc0_domain, &priv); 440 ret = nouveau_clock_create(parent, engine, oclass, nvc0_domain, false,
441 &priv);
441 *pobject = nv_object(priv); 442 *pobject = nv_object(priv);
442 if (ret) 443 if (ret)
443 return ret; 444 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c
index d3c37c96f0e7..4ac1aa30ea11 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c
@@ -473,7 +473,8 @@ nve0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
473 struct nve0_clock_priv *priv; 473 struct nve0_clock_priv *priv;
474 int ret; 474 int ret;
475 475
476 ret = nouveau_clock_create(parent, engine, oclass, nve0_domain, &priv); 476 ret = nouveau_clock_create(parent, engine, oclass, nve0_domain, true,
477 &priv);
477 *pobject = nv_object(priv); 478 *pobject = nv_object(priv);
478 if (ret) 479 if (ret)
479 return ret; 480 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c b/drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c
new file mode 100644
index 000000000000..a16024a74771
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/gk20a.c
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include "nvc0.h"
24
25struct gk20a_fb_priv {
26 struct nouveau_fb base;
27};
28
29static int
30gk20a_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
31 struct nouveau_oclass *oclass, void *data, u32 size,
32 struct nouveau_object **pobject)
33{
34 struct gk20a_fb_priv *priv;
35 int ret;
36
37 ret = nouveau_fb_create(parent, engine, oclass, &priv);
38 *pobject = nv_object(priv);
39 if (ret)
40 return ret;
41
42 return 0;
43}
44
45struct nouveau_oclass *
46gk20a_fb_oclass = &(struct nouveau_fb_impl) {
47 .base.handle = NV_SUBDEV(FB, 0xea),
48 .base.ofuncs = &(struct nouveau_ofuncs) {
49 .ctor = gk20a_fb_ctor,
50 .dtor = _nouveau_fb_dtor,
51 .init = _nouveau_fb_init,
52 .fini = _nouveau_fb_fini,
53 },
54 .memtype = nvc0_fb_memtype_valid,
55 .ram = &gk20a_ram_oclass,
56}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
index da74c889aed4..82273f832e42 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
@@ -32,6 +32,7 @@ extern struct nouveau_oclass nva3_ram_oclass;
32extern struct nouveau_oclass nvaa_ram_oclass; 32extern struct nouveau_oclass nvaa_ram_oclass;
33extern struct nouveau_oclass nvc0_ram_oclass; 33extern struct nouveau_oclass nvc0_ram_oclass;
34extern struct nouveau_oclass nve0_ram_oclass; 34extern struct nouveau_oclass nve0_ram_oclass;
35extern struct nouveau_oclass gk20a_ram_oclass;
35extern struct nouveau_oclass gm107_ram_oclass; 36extern struct nouveau_oclass gm107_ram_oclass;
36 37
37int nouveau_sddr3_calc(struct nouveau_ram *ram); 38int nouveau_sddr3_calc(struct nouveau_ram *ram);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramgk20a.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramgk20a.c
new file mode 100644
index 000000000000..4d77d75e4673
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramgk20a.c
@@ -0,0 +1,152 @@
1/*
2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include "priv.h"
24
25#include <subdev/fb.h>
26
27struct gk20a_mem {
28 struct nouveau_mem base;
29 void *cpuaddr;
30 dma_addr_t handle;
31};
32#define to_gk20a_mem(m) container_of(m, struct gk20a_mem, base)
33
34static void
35gk20a_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
36{
37 struct device *dev = nv_device_base(nv_device(pfb));
38 struct gk20a_mem *mem = to_gk20a_mem(*pmem);
39
40 *pmem = NULL;
41 if (unlikely(mem == NULL))
42 return;
43
44 if (likely(mem->cpuaddr))
45 dma_free_coherent(dev, mem->base.size << PAGE_SHIFT,
46 mem->cpuaddr, mem->handle);
47
48 kfree(mem->base.pages);
49 kfree(mem);
50}
51
52static int
53gk20a_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
54 u32 memtype, struct nouveau_mem **pmem)
55{
56 struct device *dev = nv_device_base(nv_device(pfb));
57 struct gk20a_mem *mem;
58 u32 type = memtype & 0xff;
59 u32 npages, order;
60 int i;
61
62 nv_debug(pfb, "%s: size: %llx align: %x, ncmin: %x\n", __func__, size,
63 align, ncmin);
64
65 npages = size >> PAGE_SHIFT;
66 if (npages == 0)
67 npages = 1;
68
69 if (align == 0)
70 align = PAGE_SIZE;
71 align >>= PAGE_SHIFT;
72
73 /* round alignment to the next power of 2, if needed */
74 order = fls(align);
75 if ((align & (align - 1)) == 0)
76 order--;
77 align = BIT(order);
78
79 /* ensure returned address is correctly aligned */
80 npages = max(align, npages);
81
82 mem = kzalloc(sizeof(*mem), GFP_KERNEL);
83 if (!mem)
84 return -ENOMEM;
85
86 mem->base.size = npages;
87 mem->base.memtype = type;
88
89 mem->base.pages = kzalloc(sizeof(dma_addr_t) * npages, GFP_KERNEL);
90 if (!mem->base.pages) {
91 kfree(mem);
92 return -ENOMEM;
93 }
94
95 *pmem = &mem->base;
96
97 mem->cpuaddr = dma_alloc_coherent(dev, npages << PAGE_SHIFT,
98 &mem->handle, GFP_KERNEL);
99 if (!mem->cpuaddr) {
100 nv_error(pfb, "%s: cannot allocate memory!\n", __func__);
101 gk20a_ram_put(pfb, pmem);
102 return -ENOMEM;
103 }
104
105 align <<= PAGE_SHIFT;
106
107 /* alignment check */
108 if (unlikely(mem->handle & (align - 1)))
109 nv_warn(pfb, "memory not aligned as requested: %pad (0x%x)\n",
110 &mem->handle, align);
111
112 nv_debug(pfb, "alloc size: 0x%x, align: 0x%x, paddr: %pad, vaddr: %p\n",
113 npages << PAGE_SHIFT, align, &mem->handle, mem->cpuaddr);
114
115 for (i = 0; i < npages; i++)
116 mem->base.pages[i] = mem->handle + (PAGE_SIZE * i);
117
118 mem->base.offset = (u64)mem->base.pages[0];
119
120 return 0;
121}
122
123static int
124gk20a_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
125 struct nouveau_oclass *oclass, void *data, u32 datasize,
126 struct nouveau_object **pobject)
127{
128 struct nouveau_ram *ram;
129 int ret;
130
131 ret = nouveau_ram_create(parent, engine, oclass, &ram);
132 *pobject = nv_object(ram);
133 if (ret)
134 return ret;
135 ram->type = NV_MEM_TYPE_STOLEN;
136 ram->size = get_num_physpages() << PAGE_SHIFT;
137
138 ram->get = gk20a_ram_get;
139 ram->put = gk20a_ram_put;
140
141 return 0;
142}
143
144struct nouveau_oclass
145gk20a_ram_oclass = {
146 .ofuncs = &(struct nouveau_ofuncs) {
147 .ctor = gk20a_ram_ctor,
148 .dtor = _nouveau_ram_dtor,
149 .init = _nouveau_ram_init,
150 .fini = _nouveau_ram_fini,
151 },
152};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c
index ef91b6e893af..e5d12c24cc43 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c
@@ -211,7 +211,7 @@ nv50_ram_prog(struct nouveau_fb *pfb)
211 struct nv50_ram *ram = (void *)pfb->ram; 211 struct nv50_ram *ram = (void *)pfb->ram;
212 struct nv50_ramseq *hwsq = &ram->hwsq; 212 struct nv50_ramseq *hwsq = &ram->hwsq;
213 213
214 ram_exec(hwsq, nouveau_boolopt(device->cfgopt, "NvMemExec", false)); 214 ram_exec(hwsq, nouveau_boolopt(device->cfgopt, "NvMemExec", true));
215 return 0; 215 return 0;
216} 216}
217 217
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c
index 6eb97f16fbda..8076fb195dd5 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c
@@ -309,7 +309,7 @@ nva3_ram_prog(struct nouveau_fb *pfb)
309 struct nouveau_device *device = nv_device(pfb); 309 struct nouveau_device *device = nv_device(pfb);
310 struct nva3_ram *ram = (void *)pfb->ram; 310 struct nva3_ram *ram = (void *)pfb->ram;
311 struct nva3_ramfuc *fuc = &ram->fuc; 311 struct nva3_ramfuc *fuc = &ram->fuc;
312 ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false)); 312 ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", true));
313 return 0; 313 return 0;
314} 314}
315 315
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c
index 8edc92224c84..5a6a5027f749 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c
@@ -408,7 +408,7 @@ nvc0_ram_prog(struct nouveau_fb *pfb)
408 struct nouveau_device *device = nv_device(pfb); 408 struct nouveau_device *device = nv_device(pfb);
409 struct nvc0_ram *ram = (void *)pfb->ram; 409 struct nvc0_ram *ram = (void *)pfb->ram;
410 struct nvc0_ramfuc *fuc = &ram->fuc; 410 struct nvc0_ramfuc *fuc = &ram->fuc;
411 ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false)); 411 ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", true));
412 return 0; 412 return 0;
413} 413}
414 414
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
index 16752192cf87..84c7efbc4f38 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c
@@ -1111,7 +1111,7 @@ nve0_ram_prog(struct nouveau_fb *pfb)
1111 struct nouveau_device *device = nv_device(pfb); 1111 struct nouveau_device *device = nv_device(pfb);
1112 struct nve0_ram *ram = (void *)pfb->ram; 1112 struct nve0_ram *ram = (void *)pfb->ram;
1113 struct nve0_ramfuc *fuc = &ram->fuc; 1113 struct nve0_ramfuc *fuc = &ram->fuc;
1114 ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false)); 1114 ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", true));
1115 return (ram->base.next == &ram->base.xition); 1115 return (ram->base.next == &ram->base.xition);
1116} 1116}
1117 1117
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c
index 16b8c5bf5efa..8988621373b0 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nve0.c
@@ -44,7 +44,7 @@ nve0_gpio_intr(struct nouveau_subdev *subdev)
44 } 44 }
45 45
46 nv_wr32(priv, 0xdc00, intr0); 46 nv_wr32(priv, 0xdc00, intr0);
47 nv_wr32(priv, 0xdc88, intr1); 47 nv_wr32(priv, 0xdc80, intr1);
48} 48}
49 49
50void 50void
@@ -52,8 +52,8 @@ nve0_gpio_intr_enable(struct nouveau_event *event, int line)
52{ 52{
53 const u32 addr = line < 16 ? 0xdc00 : 0xdc80; 53 const u32 addr = line < 16 ? 0xdc00 : 0xdc80;
54 const u32 mask = 0x00010001 << (line & 0xf); 54 const u32 mask = 0x00010001 << (line & 0xf);
55 nv_wr32(event->priv, addr + 0x08, mask); 55 nv_wr32(event->priv, addr + 0x00, mask);
56 nv_mask(event->priv, addr + 0x00, mask, mask); 56 nv_mask(event->priv, addr + 0x08, mask, mask);
57} 57}
58 58
59void 59void
@@ -61,8 +61,8 @@ nve0_gpio_intr_disable(struct nouveau_event *event, int line)
61{ 61{
62 const u32 addr = line < 16 ? 0xdc00 : 0xdc80; 62 const u32 addr = line < 16 ? 0xdc00 : 0xdc80;
63 const u32 mask = 0x00010001 << (line & 0xf); 63 const u32 mask = 0x00010001 << (line & 0xf);
64 nv_wr32(event->priv, addr + 0x08, mask); 64 nv_mask(event->priv, addr + 0x08, mask, 0x00000000);
65 nv_mask(event->priv, addr + 0x00, mask, 0x00000000); 65 nv_wr32(event->priv, addr + 0x00, mask);
66} 66}
67 67
68int 68int
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ibus/gk20a.c b/drivers/gpu/drm/nouveau/core/subdev/ibus/gk20a.c
new file mode 100644
index 000000000000..245f0ebaa6af
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/ibus/gk20a.c
@@ -0,0 +1,103 @@
1/*
2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <subdev/ibus.h>
24#include <subdev/timer.h>
25
26struct gk20a_ibus_priv {
27 struct nouveau_ibus base;
28};
29
30static void
31gk20a_ibus_init_priv_ring(struct gk20a_ibus_priv *priv)
32{
33 nv_mask(priv, 0x137250, 0x3f, 0);
34
35 nv_mask(priv, 0x000200, 0x20, 0);
36 usleep_range(20, 30);
37 nv_mask(priv, 0x000200, 0x20, 0x20);
38
39 nv_wr32(priv, 0x12004c, 0x4);
40 nv_wr32(priv, 0x122204, 0x2);
41 nv_rd32(priv, 0x122204);
42}
43
44static void
45gk20a_ibus_intr(struct nouveau_subdev *subdev)
46{
47 struct gk20a_ibus_priv *priv = (void *)subdev;
48 u32 status0 = nv_rd32(priv, 0x120058);
49
50 if (status0 & 0x7) {
51 nv_debug(priv, "resetting priv ring\n");
52 gk20a_ibus_init_priv_ring(priv);
53 }
54
55 /* Acknowledge interrupt */
56 nv_mask(priv, 0x12004c, 0x2, 0x2);
57
58 if (!nv_wait(subdev, 0x12004c, 0x3f, 0x00))
59 nv_warn(priv, "timeout waiting for ringmaster ack\n");
60}
61
62static int
63gk20a_ibus_init(struct nouveau_object *object)
64{
65 struct gk20a_ibus_priv *priv = (void *)object;
66 int ret;
67
68 ret = _nouveau_ibus_init(object);
69 if (ret)
70 return ret;
71
72 gk20a_ibus_init_priv_ring(priv);
73
74 return 0;
75}
76
77static int
78gk20a_ibus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
79 struct nouveau_oclass *oclass, void *data, u32 size,
80 struct nouveau_object **pobject)
81{
82 struct gk20a_ibus_priv *priv;
83 int ret;
84
85 ret = nouveau_ibus_create(parent, engine, oclass, &priv);
86 *pobject = nv_object(priv);
87 if (ret)
88 return ret;
89
90 nv_subdev(priv)->intr = gk20a_ibus_intr;
91 return 0;
92}
93
94struct nouveau_oclass
95gk20a_ibus_oclass = {
96 .handle = NV_SUBDEV(IBUS, 0xea),
97 .ofuncs = &(struct nouveau_ofuncs) {
98 .ctor = gk20a_ibus_ctor,
99 .dtor = _nouveau_ibus_dtor,
100 .init = gk20a_ibus_init,
101 .fini = _nouveau_ibus_fini,
102 },
103};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
index e8822a934c48..90d8bf8ce0dc 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
@@ -26,6 +26,7 @@
26 26
27const struct nouveau_mc_intr 27const struct nouveau_mc_intr
28nv50_mc_intr[] = { 28nv50_mc_intr[] = {
29 { 0x04000000, NVDEV_ENGINE_DISP }, /* DISP before FIFO, so pageflip-timestamping works! */
29 { 0x00000001, NVDEV_ENGINE_MPEG }, 30 { 0x00000001, NVDEV_ENGINE_MPEG },
30 { 0x00000100, NVDEV_ENGINE_FIFO }, 31 { 0x00000100, NVDEV_ENGINE_FIFO },
31 { 0x00001000, NVDEV_ENGINE_GR }, 32 { 0x00001000, NVDEV_ENGINE_GR },
@@ -34,7 +35,6 @@ nv50_mc_intr[] = {
34 { 0x00020000, NVDEV_ENGINE_VP }, /* NV84- */ 35 { 0x00020000, NVDEV_ENGINE_VP }, /* NV84- */
35 { 0x00100000, NVDEV_SUBDEV_TIMER }, 36 { 0x00100000, NVDEV_SUBDEV_TIMER },
36 { 0x00200000, NVDEV_SUBDEV_GPIO }, 37 { 0x00200000, NVDEV_SUBDEV_GPIO },
37 { 0x04000000, NVDEV_ENGINE_DISP },
38 { 0x10000000, NVDEV_SUBDEV_BUS }, 38 { 0x10000000, NVDEV_SUBDEV_BUS },
39 { 0x80000000, NVDEV_ENGINE_SW }, 39 { 0x80000000, NVDEV_ENGINE_SW },
40 { 0x0002d101, NVDEV_SUBDEV_FB }, 40 { 0x0002d101, NVDEV_SUBDEV_FB },
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c
index f8a6f18e2d34..95b3d35388a8 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c
@@ -26,6 +26,7 @@
26 26
27static const struct nouveau_mc_intr 27static const struct nouveau_mc_intr
28nv98_mc_intr[] = { 28nv98_mc_intr[] = {
29 { 0x04000000, NVDEV_ENGINE_DISP }, /* DISP first, so pageflip timestamps work */
29 { 0x00000001, NVDEV_ENGINE_PPP }, 30 { 0x00000001, NVDEV_ENGINE_PPP },
30 { 0x00000100, NVDEV_ENGINE_FIFO }, 31 { 0x00000100, NVDEV_ENGINE_FIFO },
31 { 0x00001000, NVDEV_ENGINE_GR }, 32 { 0x00001000, NVDEV_ENGINE_GR },
@@ -37,7 +38,6 @@ nv98_mc_intr[] = {
37 { 0x00100000, NVDEV_SUBDEV_TIMER }, 38 { 0x00100000, NVDEV_SUBDEV_TIMER },
38 { 0x00200000, NVDEV_SUBDEV_GPIO }, 39 { 0x00200000, NVDEV_SUBDEV_GPIO },
39 { 0x00400000, NVDEV_ENGINE_COPY0 }, /* NVA3- */ 40 { 0x00400000, NVDEV_ENGINE_COPY0 }, /* NVA3- */
40 { 0x04000000, NVDEV_ENGINE_DISP },
41 { 0x10000000, NVDEV_SUBDEV_BUS }, 41 { 0x10000000, NVDEV_SUBDEV_BUS },
42 { 0x80000000, NVDEV_ENGINE_SW }, 42 { 0x80000000, NVDEV_ENGINE_SW },
43 { 0x0042d101, NVDEV_SUBDEV_FB }, 43 { 0x0042d101, NVDEV_SUBDEV_FB },
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
index 34472d317097..ac7f99a15fa7 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
@@ -26,6 +26,7 @@
26 26
27const struct nouveau_mc_intr 27const struct nouveau_mc_intr
28nvc0_mc_intr[] = { 28nvc0_mc_intr[] = {
29 { 0x04000000, NVDEV_ENGINE_DISP }, /* DISP first, so pageflip timestamps work. */
29 { 0x00000001, NVDEV_ENGINE_PPP }, 30 { 0x00000001, NVDEV_ENGINE_PPP },
30 { 0x00000020, NVDEV_ENGINE_COPY0 }, 31 { 0x00000020, NVDEV_ENGINE_COPY0 },
31 { 0x00000040, NVDEV_ENGINE_COPY1 }, 32 { 0x00000040, NVDEV_ENGINE_COPY1 },
@@ -40,7 +41,6 @@ nvc0_mc_intr[] = {
40 { 0x00200000, NVDEV_SUBDEV_GPIO }, 41 { 0x00200000, NVDEV_SUBDEV_GPIO },
41 { 0x01000000, NVDEV_SUBDEV_PWR }, 42 { 0x01000000, NVDEV_SUBDEV_PWR },
42 { 0x02000000, NVDEV_SUBDEV_LTCG }, 43 { 0x02000000, NVDEV_SUBDEV_LTCG },
43 { 0x04000000, NVDEV_ENGINE_DISP },
44 { 0x08000000, NVDEV_SUBDEV_FB }, 44 { 0x08000000, NVDEV_SUBDEV_FB },
45 { 0x10000000, NVDEV_SUBDEV_BUS }, 45 { 0x10000000, NVDEV_SUBDEV_BUS },
46 { 0x40000000, NVDEV_SUBDEV_IBUS }, 46 { 0x40000000, NVDEV_SUBDEV_IBUS },
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c b/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c
index 7610fc5f8fa2..ca9ad9fd47be 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c
@@ -60,9 +60,9 @@ static struct nouveau_i2c_board_info
60nv_board_infos[] = { 60nv_board_infos[] = {
61 { { I2C_BOARD_INFO("w83l785ts", 0x2d) }, 0 }, 61 { { I2C_BOARD_INFO("w83l785ts", 0x2d) }, 0 },
62 { { I2C_BOARD_INFO("w83781d", 0x2d) }, 0 }, 62 { { I2C_BOARD_INFO("w83781d", 0x2d) }, 0 },
63 { { I2C_BOARD_INFO("adt7473", 0x2e) }, 20 }, 63 { { I2C_BOARD_INFO("adt7473", 0x2e) }, 40 },
64 { { I2C_BOARD_INFO("adt7473", 0x2d) }, 20 }, 64 { { I2C_BOARD_INFO("adt7473", 0x2d) }, 40 },
65 { { I2C_BOARD_INFO("adt7473", 0x2c) }, 20 }, 65 { { I2C_BOARD_INFO("adt7473", 0x2c) }, 40 },
66 { { I2C_BOARD_INFO("f75375", 0x2e) }, 0 }, 66 { { I2C_BOARD_INFO("f75375", 0x2e) }, 0 },
67 { { I2C_BOARD_INFO("lm99", 0x4c) }, 0 }, 67 { { I2C_BOARD_INFO("lm99", 0x4c) }, 0 },
68 { { I2C_BOARD_INFO("lm90", 0x4c) }, 0 }, 68 { { I2C_BOARD_INFO("lm90", 0x4c) }, 0 },
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c
index 3b2c4580098b..0478b2e3fb1d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c
@@ -36,7 +36,7 @@ nva3_therm_fan_sense(struct nouveau_therm *therm)
36 u32 tach = nv_rd32(therm, 0x00e728) & 0x0000ffff; 36 u32 tach = nv_rd32(therm, 0x00e728) & 0x0000ffff;
37 u32 ctrl = nv_rd32(therm, 0x00e720); 37 u32 ctrl = nv_rd32(therm, 0x00e720);
38 if (ctrl & 0x00000001) 38 if (ctrl & 0x00000001)
39 return tach * 60; 39 return tach * 60 / 2;
40 return -ENODEV; 40 return -ENODEV;
41} 41}
42 42
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index da764a4ed958..26fbc4f43a5f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -798,6 +798,7 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
798 struct drm_device *dev = drm->dev; 798 struct drm_device *dev = drm->dev;
799 struct nouveau_page_flip_state *s; 799 struct nouveau_page_flip_state *s;
800 unsigned long flags; 800 unsigned long flags;
801 int crtcid = -1;
801 802
802 spin_lock_irqsave(&dev->event_lock, flags); 803 spin_lock_irqsave(&dev->event_lock, flags);
803 804
@@ -808,8 +809,13 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
808 } 809 }
809 810
810 s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head); 811 s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head);
811 if (s->event) 812 if (s->event) {
812 drm_send_vblank_event(dev, s->crtc, s->event); 813 /* Vblank timestamps/counts are only correct on >= NV-50 */
814 if (nv_device(drm->device)->card_type >= NV_50)
815 crtcid = s->crtc;
816
817 drm_send_vblank_event(dev, crtcid, s->event);
818 }
813 819
814 list_del(&s->head); 820 list_del(&s->head);
815 if (ps) 821 if (ps)
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 79f6dc724a85..3c58854aff03 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -1,4 +1,4 @@
1 /* 1/*
2 * Copyright 2011 Red Hat Inc. 2 * Copyright 2011 Red Hat Inc.
3 * 3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a 4 * Permission is hereby granted, free of charge, to any person obtaining a
@@ -957,7 +957,7 @@ nv50_crtc_prepare(struct drm_crtc *crtc)
957 957
958 nv50_display_flip_stop(crtc); 958 nv50_display_flip_stop(crtc);
959 959
960 push = evo_wait(mast, 2); 960 push = evo_wait(mast, 6);
961 if (push) { 961 if (push) {
962 if (nv50_vers(mast) < NV84_DISP_MAST_CLASS) { 962 if (nv50_vers(mast) < NV84_DISP_MAST_CLASS) {
963 evo_mthd(push, 0x0874 + (nv_crtc->index * 0x400), 1); 963 evo_mthd(push, 0x0874 + (nv_crtc->index * 0x400), 1);