aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_display.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c289
1 files changed, 144 insertions, 145 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index 47ad74255bf1..1cc7b603c753 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -27,6 +27,8 @@
27#include <drm/drmP.h> 27#include <drm/drmP.h>
28#include <drm/drm_crtc_helper.h> 28#include <drm/drm_crtc_helper.h>
29 29
30#include <nvif/class.h>
31
30#include "nouveau_fbcon.h" 32#include "nouveau_fbcon.h"
31#include "dispnv04/hw.h" 33#include "dispnv04/hw.h"
32#include "nouveau_crtc.h" 34#include "nouveau_crtc.h"
@@ -37,35 +39,42 @@
37 39
38#include "nouveau_fence.h" 40#include "nouveau_fence.h"
39 41
40#include <engine/disp.h> 42#include <nvif/event.h>
41
42#include <core/class.h>
43 43
44static int 44static int
45nouveau_display_vblank_handler(void *data, u32 type, int head) 45nouveau_display_vblank_handler(struct nvif_notify *notify)
46{ 46{
47 struct nouveau_drm *drm = data; 47 struct nouveau_crtc *nv_crtc =
48 drm_handle_vblank(drm->dev, head); 48 container_of(notify, typeof(*nv_crtc), vblank);
49 return NVKM_EVENT_KEEP; 49 drm_handle_vblank(nv_crtc->base.dev, nv_crtc->index);
50 return NVIF_NOTIFY_KEEP;
50} 51}
51 52
52int 53int
53nouveau_display_vblank_enable(struct drm_device *dev, int head) 54nouveau_display_vblank_enable(struct drm_device *dev, int head)
54{ 55{
55 struct nouveau_display *disp = nouveau_display(dev); 56 struct drm_crtc *crtc;
56 if (disp) { 57 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
57 nouveau_event_get(disp->vblank[head]); 58 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
58 return 0; 59 if (nv_crtc->index == head) {
60 nvif_notify_get(&nv_crtc->vblank);
61 return 0;
62 }
59 } 63 }
60 return -EIO; 64 return -EINVAL;
61} 65}
62 66
63void 67void
64nouveau_display_vblank_disable(struct drm_device *dev, int head) 68nouveau_display_vblank_disable(struct drm_device *dev, int head)
65{ 69{
66 struct nouveau_display *disp = nouveau_display(dev); 70 struct drm_crtc *crtc;
67 if (disp) 71 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
68 nouveau_event_put(disp->vblank[head]); 72 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
73 if (nv_crtc->index == head) {
74 nvif_notify_put(&nv_crtc->vblank);
75 return;
76 }
77 }
69} 78}
70 79
71static inline int 80static inline int
@@ -86,17 +95,22 @@ int
86nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, 95nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos,
87 ktime_t *stime, ktime_t *etime) 96 ktime_t *stime, ktime_t *etime)
88{ 97{
89 const u32 mthd = NV04_DISP_SCANOUTPOS + nouveau_crtc(crtc)->index; 98 struct {
99 struct nv04_disp_mthd_v0 base;
100 struct nv04_disp_scanoutpos_v0 scan;
101 } args = {
102 .base.method = NV04_DISP_SCANOUTPOS,
103 .base.head = nouveau_crtc(crtc)->index,
104 };
90 struct nouveau_display *disp = nouveau_display(crtc->dev); 105 struct nouveau_display *disp = nouveau_display(crtc->dev);
91 struct nv04_display_scanoutpos args;
92 int ret, retry = 1; 106 int ret, retry = 1;
93 107
94 do { 108 do {
95 ret = nv_exec(disp->core, mthd, &args, sizeof(args)); 109 ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args));
96 if (ret != 0) 110 if (ret != 0)
97 return 0; 111 return 0;
98 112
99 if (args.vline) { 113 if (args.scan.vline) {
100 ret |= DRM_SCANOUTPOS_ACCURATE; 114 ret |= DRM_SCANOUTPOS_ACCURATE;
101 ret |= DRM_SCANOUTPOS_VALID; 115 ret |= DRM_SCANOUTPOS_VALID;
102 break; 116 break;
@@ -105,10 +119,11 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos,
105 if (retry) ndelay(crtc->linedur_ns); 119 if (retry) ndelay(crtc->linedur_ns);
106 } while (retry--); 120 } while (retry--);
107 121
108 *hpos = args.hline; 122 *hpos = args.scan.hline;
109 *vpos = calc(args.vblanks, args.vblanke, args.vtotal, args.vline); 123 *vpos = calc(args.scan.vblanks, args.scan.vblanke,
110 if (stime) *stime = ns_to_ktime(args.time[0]); 124 args.scan.vtotal, args.scan.vline);
111 if (etime) *etime = ns_to_ktime(args.time[1]); 125 if (stime) *stime = ns_to_ktime(args.scan.time[0]);
126 if (etime) *etime = ns_to_ktime(args.scan.time[1]);
112 127
113 if (*vpos < 0) 128 if (*vpos < 0)
114 ret |= DRM_SCANOUTPOS_INVBL; 129 ret |= DRM_SCANOUTPOS_INVBL;
@@ -151,16 +166,13 @@ nouveau_display_vblstamp(struct drm_device *dev, int head, int *max_error,
151static void 166static void
152nouveau_display_vblank_fini(struct drm_device *dev) 167nouveau_display_vblank_fini(struct drm_device *dev)
153{ 168{
154 struct nouveau_display *disp = nouveau_display(dev); 169 struct drm_crtc *crtc;
155 int i;
156 170
157 drm_vblank_cleanup(dev); 171 drm_vblank_cleanup(dev);
158 172
159 if (disp->vblank) { 173 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
160 for (i = 0; i < dev->mode_config.num_crtc; i++) 174 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
161 nouveau_event_ref(NULL, &disp->vblank[i]); 175 nvif_notify_fini(&nv_crtc->vblank);
162 kfree(disp->vblank);
163 disp->vblank = NULL;
164 } 176 }
165} 177}
166 178
@@ -168,19 +180,20 @@ static int
168nouveau_display_vblank_init(struct drm_device *dev) 180nouveau_display_vblank_init(struct drm_device *dev)
169{ 181{
170 struct nouveau_display *disp = nouveau_display(dev); 182 struct nouveau_display *disp = nouveau_display(dev);
171 struct nouveau_drm *drm = nouveau_drm(dev); 183 struct drm_crtc *crtc;
172 struct nouveau_disp *pdisp = nouveau_disp(drm->device); 184 int ret;
173 int ret, i;
174
175 disp->vblank = kzalloc(dev->mode_config.num_crtc *
176 sizeof(*disp->vblank), GFP_KERNEL);
177 if (!disp->vblank)
178 return -ENOMEM;
179 185
180 for (i = 0; i < dev->mode_config.num_crtc; i++) { 186 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
181 ret = nouveau_event_new(pdisp->vblank, 1, i, 187 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
182 nouveau_display_vblank_handler, 188 ret = nvif_notify_init(&disp->disp, NULL,
183 drm, &disp->vblank[i]); 189 nouveau_display_vblank_handler, false,
190 NV04_DISP_NTFY_VBLANK,
191 &(struct nvif_notify_head_req_v0) {
192 .head = nv_crtc->index,
193 },
194 sizeof(struct nvif_notify_head_req_v0),
195 sizeof(struct nvif_notify_head_rep_v0),
196 &nv_crtc->vblank);
184 if (ret) { 197 if (ret) {
185 nouveau_display_vblank_fini(dev); 198 nouveau_display_vblank_fini(dev);
186 return ret; 199 return ret;
@@ -200,6 +213,10 @@ static void
200nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) 213nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb)
201{ 214{
202 struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); 215 struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
216 struct nouveau_display *disp = nouveau_display(drm_fb->dev);
217
218 if (disp->fb_dtor)
219 disp->fb_dtor(drm_fb);
203 220
204 if (fb->nvbo) 221 if (fb->nvbo)
205 drm_gem_object_unreference_unlocked(&fb->nvbo->gem); 222 drm_gem_object_unreference_unlocked(&fb->nvbo->gem);
@@ -229,63 +246,24 @@ nouveau_framebuffer_init(struct drm_device *dev,
229 struct drm_mode_fb_cmd2 *mode_cmd, 246 struct drm_mode_fb_cmd2 *mode_cmd,
230 struct nouveau_bo *nvbo) 247 struct nouveau_bo *nvbo)
231{ 248{
232 struct nouveau_drm *drm = nouveau_drm(dev); 249 struct nouveau_display *disp = nouveau_display(dev);
233 struct drm_framebuffer *fb = &nv_fb->base; 250 struct drm_framebuffer *fb = &nv_fb->base;
234 int ret; 251 int ret;
235 252
236 drm_helper_mode_fill_fb_struct(fb, mode_cmd); 253 drm_helper_mode_fill_fb_struct(fb, mode_cmd);
237 nv_fb->nvbo = nvbo; 254 nv_fb->nvbo = nvbo;
238 255
239 if (nv_device(drm->device)->card_type >= NV_50) {
240 u32 tile_flags = nouveau_bo_tile_layout(nvbo);
241 if (tile_flags == 0x7a00 ||
242 tile_flags == 0xfe00)
243 nv_fb->r_dma = NvEvoFB32;
244 else
245 if (tile_flags == 0x7000)
246 nv_fb->r_dma = NvEvoFB16;
247 else
248 nv_fb->r_dma = NvEvoVRAM_LP;
249
250 switch (fb->depth) {
251 case 8: nv_fb->r_format = 0x1e00; break;
252 case 15: nv_fb->r_format = 0xe900; break;
253 case 16: nv_fb->r_format = 0xe800; break;
254 case 24:
255 case 32: nv_fb->r_format = 0xcf00; break;
256 case 30: nv_fb->r_format = 0xd100; break;
257 default:
258 NV_ERROR(drm, "unknown depth %d\n", fb->depth);
259 return -EINVAL;
260 }
261
262 if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) {
263 NV_ERROR(drm, "framebuffer requires contiguous bo\n");
264 return -EINVAL;
265 }
266
267 if (nv_device(drm->device)->chipset == 0x50)
268 nv_fb->r_format |= (tile_flags << 8);
269
270 if (!tile_flags) {
271 if (nv_device(drm->device)->card_type < NV_D0)
272 nv_fb->r_pitch = 0x00100000 | fb->pitches[0];
273 else
274 nv_fb->r_pitch = 0x01000000 | fb->pitches[0];
275 } else {
276 u32 mode = nvbo->tile_mode;
277 if (nv_device(drm->device)->card_type >= NV_C0)
278 mode >>= 4;
279 nv_fb->r_pitch = ((fb->pitches[0] / 4) << 4) | mode;
280 }
281 }
282
283 ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs); 256 ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs);
284 if (ret) { 257 if (ret)
285 return ret; 258 return ret;
259
260 if (disp->fb_ctor) {
261 ret = disp->fb_ctor(fb);
262 if (ret)
263 disp->fb_dtor(fb);
286 } 264 }
287 265
288 return 0; 266 return ret;
289} 267}
290 268
291static struct drm_framebuffer * 269static struct drm_framebuffer *
@@ -393,7 +371,7 @@ nouveau_display_init(struct drm_device *dev)
393 /* enable hotplug interrupts */ 371 /* enable hotplug interrupts */
394 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 372 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
395 struct nouveau_connector *conn = nouveau_connector(connector); 373 struct nouveau_connector *conn = nouveau_connector(connector);
396 if (conn->hpd) nouveau_event_get(conn->hpd); 374 nvif_notify_get(&conn->hpd);
397 } 375 }
398 376
399 return ret; 377 return ret;
@@ -404,37 +382,32 @@ nouveau_display_fini(struct drm_device *dev)
404{ 382{
405 struct nouveau_display *disp = nouveau_display(dev); 383 struct nouveau_display *disp = nouveau_display(dev);
406 struct drm_connector *connector; 384 struct drm_connector *connector;
385 int head;
386
387 /* Make sure that drm and hw vblank irqs get properly disabled. */
388 for (head = 0; head < dev->mode_config.num_crtc; head++)
389 drm_vblank_off(dev, head);
407 390
408 /* disable hotplug interrupts */ 391 /* disable hotplug interrupts */
409 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 392 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
410 struct nouveau_connector *conn = nouveau_connector(connector); 393 struct nouveau_connector *conn = nouveau_connector(connector);
411 if (conn->hpd) nouveau_event_put(conn->hpd); 394 nvif_notify_put(&conn->hpd);
412 } 395 }
413 396
414 drm_kms_helper_poll_disable(dev); 397 drm_kms_helper_poll_disable(dev);
415 disp->fini(dev); 398 disp->fini(dev);
416} 399}
417 400
418int 401static void
419nouveau_display_create(struct drm_device *dev) 402nouveau_display_create_properties(struct drm_device *dev)
420{ 403{
421 struct nouveau_drm *drm = nouveau_drm(dev); 404 struct nouveau_display *disp = nouveau_display(dev);
422 struct nouveau_device *device = nouveau_dev(dev); 405 int gen;
423 struct nouveau_display *disp;
424 int ret, gen;
425
426 disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL);
427 if (!disp)
428 return -ENOMEM;
429
430 drm_mode_config_init(dev);
431 drm_mode_create_scaling_mode_property(dev);
432 drm_mode_create_dvi_i_properties(dev);
433 406
434 if (nv_device(drm->device)->card_type < NV_50) 407 if (disp->disp.oclass < NV50_DISP)
435 gen = 0; 408 gen = 0;
436 else 409 else
437 if (nv_device(drm->device)->card_type < NV_D0) 410 if (disp->disp.oclass < GF110_DISP)
438 gen = 1; 411 gen = 1;
439 else 412 else
440 gen = 2; 413 gen = 2;
@@ -449,26 +422,43 @@ nouveau_display_create(struct drm_device *dev)
449 disp->underscan_vborder_property = 422 disp->underscan_vborder_property =
450 drm_property_create_range(dev, 0, "underscan vborder", 0, 128); 423 drm_property_create_range(dev, 0, "underscan vborder", 0, 128);
451 424
452 if (gen >= 1) { 425 if (gen < 1)
453 /* -90..+90 */ 426 return;
454 disp->vibrant_hue_property =
455 drm_property_create_range(dev, 0, "vibrant hue", 0, 180);
456 427
457 /* -100..+100 */ 428 /* -90..+90 */
458 disp->color_vibrance_property = 429 disp->vibrant_hue_property =
459 drm_property_create_range(dev, 0, "color vibrance", 0, 200); 430 drm_property_create_range(dev, 0, "vibrant hue", 0, 180);
460 } 431
432 /* -100..+100 */
433 disp->color_vibrance_property =
434 drm_property_create_range(dev, 0, "color vibrance", 0, 200);
435}
436
437int
438nouveau_display_create(struct drm_device *dev)
439{
440 struct nouveau_drm *drm = nouveau_drm(dev);
441 struct nouveau_display *disp;
442 int ret;
443
444 disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL);
445 if (!disp)
446 return -ENOMEM;
447
448 drm_mode_config_init(dev);
449 drm_mode_create_scaling_mode_property(dev);
450 drm_mode_create_dvi_i_properties(dev);
461 451
462 dev->mode_config.funcs = &nouveau_mode_config_funcs; 452 dev->mode_config.funcs = &nouveau_mode_config_funcs;
463 dev->mode_config.fb_base = nv_device_resource_start(device, 1); 453 dev->mode_config.fb_base = nv_device_resource_start(nvkm_device(&drm->device), 1);
464 454
465 dev->mode_config.min_width = 0; 455 dev->mode_config.min_width = 0;
466 dev->mode_config.min_height = 0; 456 dev->mode_config.min_height = 0;
467 if (nv_device(drm->device)->card_type < NV_10) { 457 if (drm->device.info.family < NV_DEVICE_INFO_V0_CELSIUS) {
468 dev->mode_config.max_width = 2048; 458 dev->mode_config.max_width = 2048;
469 dev->mode_config.max_height = 2048; 459 dev->mode_config.max_height = 2048;
470 } else 460 } else
471 if (nv_device(drm->device)->card_type < NV_50) { 461 if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) {
472 dev->mode_config.max_width = 4096; 462 dev->mode_config.max_width = 4096;
473 dev->mode_config.max_height = 4096; 463 dev->mode_config.max_height = 4096;
474 } else { 464 } else {
@@ -479,7 +469,7 @@ nouveau_display_create(struct drm_device *dev)
479 dev->mode_config.preferred_depth = 24; 469 dev->mode_config.preferred_depth = 24;
480 dev->mode_config.prefer_shadow = 1; 470 dev->mode_config.prefer_shadow = 1;
481 471
482 if (nv_device(drm->device)->chipset < 0x11) 472 if (drm->device.info.chipset < 0x11)
483 dev->mode_config.async_page_flip = false; 473 dev->mode_config.async_page_flip = false;
484 else 474 else
485 dev->mode_config.async_page_flip = true; 475 dev->mode_config.async_page_flip = true;
@@ -487,29 +477,30 @@ nouveau_display_create(struct drm_device *dev)
487 drm_kms_helper_poll_init(dev); 477 drm_kms_helper_poll_init(dev);
488 drm_kms_helper_poll_disable(dev); 478 drm_kms_helper_poll_disable(dev);
489 479
490 if (drm->vbios.dcb.entries) { 480 if (nouveau_modeset != 2 && drm->vbios.dcb.entries) {
491 static const u16 oclass[] = { 481 static const u16 oclass[] = {
492 GM107_DISP_CLASS, 482 GM107_DISP,
493 NVF0_DISP_CLASS, 483 GK110_DISP,
494 NVE0_DISP_CLASS, 484 GK104_DISP,
495 NVD0_DISP_CLASS, 485 GF110_DISP,
496 NVA3_DISP_CLASS, 486 GT214_DISP,
497 NV94_DISP_CLASS, 487 GT206_DISP,
498 NVA0_DISP_CLASS, 488 GT200_DISP,
499 NV84_DISP_CLASS, 489 G82_DISP,
500 NV50_DISP_CLASS, 490 NV50_DISP,
501 NV04_DISP_CLASS, 491 NV04_DISP,
502 }; 492 };
503 int i; 493 int i;
504 494
505 for (i = 0, ret = -ENODEV; ret && i < ARRAY_SIZE(oclass); i++) { 495 for (i = 0, ret = -ENODEV; ret && i < ARRAY_SIZE(oclass); i++) {
506 ret = nouveau_object_new(nv_object(drm), NVDRM_DEVICE, 496 ret = nvif_object_init(nvif_object(&drm->device), NULL,
507 NVDRM_DISPLAY, oclass[i], 497 NVDRM_DISPLAY, oclass[i],
508 NULL, 0, &disp->core); 498 NULL, 0, &disp->disp);
509 } 499 }
510 500
511 if (ret == 0) { 501 if (ret == 0) {
512 if (nv_mclass(disp->core) < NV50_DISP_CLASS) 502 nouveau_display_create_properties(dev);
503 if (disp->disp.oclass < NV50_DISP)
513 ret = nv04_display_create(dev); 504 ret = nv04_display_create(dev);
514 else 505 else
515 ret = nv50_display_create(dev); 506 ret = nv50_display_create(dev);
@@ -542,7 +533,6 @@ void
542nouveau_display_destroy(struct drm_device *dev) 533nouveau_display_destroy(struct drm_device *dev)
543{ 534{
544 struct nouveau_display *disp = nouveau_display(dev); 535 struct nouveau_display *disp = nouveau_display(dev);
545 struct nouveau_drm *drm = nouveau_drm(dev);
546 536
547 nouveau_backlight_exit(dev); 537 nouveau_backlight_exit(dev);
548 nouveau_display_vblank_fini(dev); 538 nouveau_display_vblank_fini(dev);
@@ -553,7 +543,7 @@ nouveau_display_destroy(struct drm_device *dev)
553 if (disp->dtor) 543 if (disp->dtor)
554 disp->dtor(dev); 544 disp->dtor(dev);
555 545
556 nouveau_object_del(nv_object(drm), NVDRM_DEVICE, NVDRM_DISPLAY); 546 nvif_object_fini(&disp->disp);
557 547
558 nouveau_drm(dev)->display = NULL; 548 nouveau_drm(dev)->display = NULL;
559 kfree(disp); 549 kfree(disp);
@@ -620,6 +610,8 @@ void
620nouveau_display_resume(struct drm_device *dev) 610nouveau_display_resume(struct drm_device *dev)
621{ 611{
622 struct drm_crtc *crtc; 612 struct drm_crtc *crtc;
613 int head;
614
623 nouveau_display_init(dev); 615 nouveau_display_init(dev);
624 616
625 /* Force CLUT to get re-loaded during modeset */ 617 /* Force CLUT to get re-loaded during modeset */
@@ -629,6 +621,10 @@ nouveau_display_resume(struct drm_device *dev)
629 nv_crtc->lut.depth = 0; 621 nv_crtc->lut.depth = 0;
630 } 622 }
631 623
624 /* Make sure that drm and hw vblank irqs get resumed if needed. */
625 for (head = 0; head < dev->mode_config.num_crtc; head++)
626 drm_vblank_on(dev, head);
627
632 drm_helper_resume_force_mode(dev); 628 drm_helper_resume_force_mode(dev);
633 629
634 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 630 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
@@ -669,7 +665,7 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
669 if (ret) 665 if (ret)
670 goto fail; 666 goto fail;
671 667
672 if (nv_device(drm->device)->card_type < NV_C0) 668 if (drm->device.info.family < NV_DEVICE_INFO_V0_FERMI)
673 BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); 669 BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
674 else 670 else
675 BEGIN_NVC0(chan, FermiSw, NV_SW_PAGE_FLIP, 1); 671 BEGIN_NVC0(chan, FermiSw, NV_SW_PAGE_FLIP, 1);
@@ -698,12 +694,15 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
698 struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->primary->fb)->nvbo; 694 struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->primary->fb)->nvbo;
699 struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo; 695 struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo;
700 struct nouveau_page_flip_state *s; 696 struct nouveau_page_flip_state *s;
701 struct nouveau_channel *chan = drm->channel; 697 struct nouveau_channel *chan;
698 struct nouveau_cli *cli;
702 struct nouveau_fence *fence; 699 struct nouveau_fence *fence;
703 int ret; 700 int ret;
704 701
705 if (!drm->channel) 702 chan = drm->channel;
703 if (!chan)
706 return -ENODEV; 704 return -ENODEV;
705 cli = (void *)nvif_client(&chan->device->base);
707 706
708 s = kzalloc(sizeof(*s), GFP_KERNEL); 707 s = kzalloc(sizeof(*s), GFP_KERNEL);
709 if (!s) 708 if (!s)
@@ -715,7 +714,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
715 goto fail_free; 714 goto fail_free;
716 } 715 }
717 716
718 mutex_lock(&chan->cli->mutex); 717 mutex_lock(&cli->mutex);
719 718
720 /* synchronise rendering channel with the kernel's channel */ 719 /* synchronise rendering channel with the kernel's channel */
721 spin_lock(&new_bo->bo.bdev->fence_lock); 720 spin_lock(&new_bo->bo.bdev->fence_lock);
@@ -740,7 +739,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
740 drm_vblank_get(dev, nouveau_crtc(crtc)->index); 739 drm_vblank_get(dev, nouveau_crtc(crtc)->index);
741 740
742 /* Emit a page flip */ 741 /* Emit a page flip */
743 if (nv_device(drm->device)->card_type >= NV_50) { 742 if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
744 ret = nv50_display_flip_next(crtc, fb, chan, swap_interval); 743 ret = nv50_display_flip_next(crtc, fb, chan, swap_interval);
745 if (ret) 744 if (ret)
746 goto fail_unreserve; 745 goto fail_unreserve;
@@ -769,7 +768,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
769 ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); 768 ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence);
770 if (ret) 769 if (ret)
771 goto fail_unreserve; 770 goto fail_unreserve;
772 mutex_unlock(&chan->cli->mutex); 771 mutex_unlock(&cli->mutex);
773 772
774 /* Update the crtc struct and cleanup */ 773 /* Update the crtc struct and cleanup */
775 crtc->primary->fb = fb; 774 crtc->primary->fb = fb;
@@ -785,7 +784,7 @@ fail_unreserve:
785 drm_vblank_put(dev, nouveau_crtc(crtc)->index); 784 drm_vblank_put(dev, nouveau_crtc(crtc)->index);
786 ttm_bo_unreserve(&old_bo->bo); 785 ttm_bo_unreserve(&old_bo->bo);
787fail_unpin: 786fail_unpin:
788 mutex_unlock(&chan->cli->mutex); 787 mutex_unlock(&cli->mutex);
789 if (old_bo != new_bo) 788 if (old_bo != new_bo)
790 nouveau_bo_unpin(new_bo); 789 nouveau_bo_unpin(new_bo);
791fail_free: 790fail_free:
@@ -815,7 +814,7 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
815 s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head); 814 s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head);
816 if (s->event) { 815 if (s->event) {
817 /* Vblank timestamps/counts are only correct on >= NV-50 */ 816 /* Vblank timestamps/counts are only correct on >= NV-50 */
818 if (nv_device(drm->device)->card_type >= NV_50) 817 if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA)
819 crtcid = s->crtc; 818 crtcid = s->crtc;
820 819
821 drm_send_vblank_event(dev, crtcid, s->event); 820 drm_send_vblank_event(dev, crtcid, s->event);
@@ -841,7 +840,7 @@ nouveau_flip_complete(void *data)
841 struct nouveau_page_flip_state state; 840 struct nouveau_page_flip_state state;
842 841
843 if (!nouveau_finish_page_flip(chan, &state)) { 842 if (!nouveau_finish_page_flip(chan, &state)) {
844 if (nv_device(drm->device)->card_type < NV_50) { 843 if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) {
845 nv_set_crtc_base(drm->dev, state.crtc, state.offset + 844 nv_set_crtc_base(drm->dev, state.crtc, state.offset +
846 state.y * state.pitch + 845 state.y * state.pitch +
847 state.x * state.bpp / 8); 846 state.x * state.bpp / 8);