1 /* 2 * Copyright (C) 2008 Maarten Maathuis. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial 15 * portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 */ 26 27 #include <drm/drmP.h> 28 #include <drm/drm_crtc_helper.h> 29 30 #include <nvif/class.h> 31 32 #include "nouveau_fbcon.h" 33 #include "dispnv04/hw.h" 34 #include "nouveau_crtc.h" 35 #include "nouveau_dma.h" 36 #include "nouveau_gem.h" 37 #include "nouveau_connector.h" 38 #include "nv50_display.h" 39 40 #include "nouveau_fence.h" 41 42 #include <nvif/cl0046.h> 43 #include <nvif/event.h> 44 45 static int 46 nouveau_display_vblank_handler(struct nvif_notify *notify) 47 { 48 struct nouveau_crtc *nv_crtc = 49 container_of(notify, typeof(*nv_crtc), vblank); 50 drm_crtc_handle_vblank(&nv_crtc->base); 51 return NVIF_NOTIFY_KEEP; 52 } 53 54 int 55 nouveau_display_vblank_enable(struct drm_device *dev, unsigned int pipe) 56 { 57 struct drm_crtc *crtc; 58 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 59 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 60 if (nv_crtc->index == pipe) { 61 nvif_notify_get(&nv_crtc->vblank); 62 return 0; 63 } 64 } 65 return -EINVAL; 66 } 67 68 void 69 nouveau_display_vblank_disable(struct drm_device *dev, unsigned int pipe) 70 { 71 struct drm_crtc *crtc; 72 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 73 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 74 if (nv_crtc->index == pipe) { 75 nvif_notify_put(&nv_crtc->vblank); 76 return; 77 } 78 } 79 } 80 81 static inline int 82 calc(int blanks, int blanke, int total, int line) 83 { 84 if (blanke >= blanks) { 85 if (line >= blanks) 86 line -= total; 87 } else { 88 if (line >= blanks) 89 line -= total; 90 line -= blanke + 1; 91 } 92 return line; 93 } 94 95 int 96 nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, 97 ktime_t *stime, ktime_t *etime) 98 { 99 struct { 100 struct nv04_disp_mthd_v0 base; 101 struct nv04_disp_scanoutpos_v0 scan; 102 } args = { 103 .base.method = NV04_DISP_SCANOUTPOS, 104 .base.head = nouveau_crtc(crtc)->index, 105 }; 106 struct nouveau_display *disp = nouveau_display(crtc->dev); 107 struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)]; 108 int ret, retry = 1; 109 110 do { 111 ret = nvif_mthd(&disp->disp, 0, &args, sizeof(args)); 112 if (ret != 0) 113 return 0; 114 115 if (args.scan.vline) { 116 ret |= DRM_SCANOUTPOS_ACCURATE; 117 ret |= DRM_SCANOUTPOS_VALID; 118 break; 119 } 120 121 if (retry) ndelay(vblank->linedur_ns); 122 } while (retry--); 123 124 *hpos = args.scan.hline; 125 *vpos = calc(args.scan.vblanks, args.scan.vblanke, 126 args.scan.vtotal, args.scan.vline); 127 if (stime) *stime = ns_to_ktime(args.scan.time[0]); 128 if (etime) *etime = ns_to_ktime(args.scan.time[1]); 129 130 if (*vpos < 0) 131 ret |= DRM_SCANOUTPOS_IN_VBLANK; 132 return ret; 133 } 134 135 int 136 nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, 137 unsigned int flags, int *vpos, int *hpos, 138 ktime_t *stime, ktime_t *etime, 139 const struct drm_display_mode *mode) 140 { 141 struct drm_crtc *crtc; 142 143 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 144 if (nouveau_crtc(crtc)->index == pipe) { 145 return nouveau_display_scanoutpos_head(crtc, vpos, hpos, 146 stime, etime); 147 } 148 } 149 150 return 0; 151 } 152 153 int 154 nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, 155 int *max_error, struct timeval *time, unsigned flags) 156 { 157 struct drm_crtc *crtc; 158 159 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 160 if (nouveau_crtc(crtc)->index == pipe) { 161 return drm_calc_vbltimestamp_from_scanoutpos(dev, 162 pipe, max_error, time, flags, 163 &crtc->hwmode); 164 } 165 } 166 167 return -EINVAL; 168 } 169 170 static void 171 nouveau_display_vblank_fini(struct drm_device *dev) 172 { 173 struct drm_crtc *crtc; 174 175 drm_vblank_cleanup(dev); 176 177 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 178 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 179 nvif_notify_fini(&nv_crtc->vblank); 180 } 181 } 182 183 static int 184 nouveau_display_vblank_init(struct drm_device *dev) 185 { 186 struct nouveau_display *disp = nouveau_display(dev); 187 struct drm_crtc *crtc; 188 int ret; 189 190 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 191 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 192 ret = nvif_notify_init(&disp->disp, 193 nouveau_display_vblank_handler, false, 194 NV04_DISP_NTFY_VBLANK, 195 &(struct nvif_notify_head_req_v0) { 196 .head = nv_crtc->index, 197 }, 198 sizeof(struct nvif_notify_head_req_v0), 199 sizeof(struct nvif_notify_head_rep_v0), 200 &nv_crtc->vblank); 201 if (ret) { 202 nouveau_display_vblank_fini(dev); 203 return ret; 204 } 205 } 206 207 ret = drm_vblank_init(dev, dev->mode_config.num_crtc); 208 if (ret) { 209 nouveau_display_vblank_fini(dev); 210 return ret; 211 } 212 213 return 0; 214 } 215 216 static void 217 nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) 218 { 219 struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); 220 struct nouveau_display *disp = nouveau_display(drm_fb->dev); 221 222 if (disp->fb_dtor) 223 disp->fb_dtor(drm_fb); 224 225 if (fb->nvbo) 226 drm_gem_object_unreference_unlocked(&fb->nvbo->gem); 227 228 drm_framebuffer_cleanup(drm_fb); 229 kfree(fb); 230 } 231 232 static int 233 nouveau_user_framebuffer_create_handle(struct drm_framebuffer *drm_fb, 234 struct drm_file *file_priv, 235 unsigned int *handle) 236 { 237 struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); 238 239 return drm_gem_handle_create(file_priv, &fb->nvbo->gem, handle); 240 } 241 242 static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = { 243 .destroy = nouveau_user_framebuffer_destroy, 244 .create_handle = nouveau_user_framebuffer_create_handle, 245 }; 246 247 int 248 nouveau_framebuffer_init(struct drm_device *dev, 249 struct nouveau_framebuffer *nv_fb, 250 const struct drm_mode_fb_cmd2 *mode_cmd, 251 struct nouveau_bo *nvbo) 252 { 253 struct nouveau_display *disp = nouveau_display(dev); 254 struct drm_framebuffer *fb = &nv_fb->base; 255 int ret; 256 257 drm_helper_mode_fill_fb_struct(fb, mode_cmd); 258 nv_fb->nvbo = nvbo; 259 260 ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs); 261 if (ret) 262 return ret; 263 264 if (disp->fb_ctor) { 265 ret = disp->fb_ctor(fb); 266 if (ret) 267 disp->fb_dtor(fb); 268 } 269 270 return ret; 271 } 272 273 static struct drm_framebuffer * 274 nouveau_user_framebuffer_create(struct drm_device *dev, 275 struct drm_file *file_priv, 276 const struct drm_mode_fb_cmd2 *mode_cmd) 277 { 278 struct nouveau_framebuffer *nouveau_fb; 279 struct drm_gem_object *gem; 280 int ret = -ENOMEM; 281 282 gem = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); 283 if (!gem) 284 return ERR_PTR(-ENOENT); 285 286 nouveau_fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL); 287 if (!nouveau_fb) 288 goto err_unref; 289 290 ret = nouveau_framebuffer_init(dev, nouveau_fb, mode_cmd, nouveau_gem_object(gem)); 291 if (ret) 292 goto err; 293 294 return &nouveau_fb->base; 295 296 err: 297 kfree(nouveau_fb); 298 err_unref: 299 drm_gem_object_unreference_unlocked(gem); 300 return ERR_PTR(ret); 301 } 302 303 static const struct drm_mode_config_funcs nouveau_mode_config_funcs = { 304 .fb_create = nouveau_user_framebuffer_create, 305 .output_poll_changed = nouveau_fbcon_output_poll_changed, 306 }; 307 308 309 struct nouveau_drm_prop_enum_list { 310 u8 gen_mask; 311 int type; 312 char *name; 313 }; 314 315 static struct nouveau_drm_prop_enum_list underscan[] = { 316 { 6, UNDERSCAN_AUTO, "auto" }, 317 { 6, UNDERSCAN_OFF, "off" }, 318 { 6, UNDERSCAN_ON, "on" }, 319 {} 320 }; 321 322 static struct nouveau_drm_prop_enum_list dither_mode[] = { 323 { 7, DITHERING_MODE_AUTO, "auto" }, 324 { 7, DITHERING_MODE_OFF, "off" }, 325 { 1, DITHERING_MODE_ON, "on" }, 326 { 6, DITHERING_MODE_STATIC2X2, "static 2x2" }, 327 { 6, DITHERING_MODE_DYNAMIC2X2, "dynamic 2x2" }, 328 { 4, DITHERING_MODE_TEMPORAL, "temporal" }, 329 {} 330 }; 331 332 static struct nouveau_drm_prop_enum_list dither_depth[] = { 333 { 6, DITHERING_DEPTH_AUTO, "auto" }, 334 { 6, DITHERING_DEPTH_6BPC, "6 bpc" }, 335 { 6, DITHERING_DEPTH_8BPC, "8 bpc" }, 336 {} 337 }; 338 339 #define PROP_ENUM(p,gen,n,list) do { \ 340 struct nouveau_drm_prop_enum_list *l = (list); \ 341 int c = 0; \ 342 while (l->gen_mask) { \ 343 if (l->gen_mask & (1 << (gen))) \ 344 c++; \ 345 l++; \ 346 } \ 347 if (c) { \ 348 p = drm_property_create(dev, DRM_MODE_PROP_ENUM, n, c); \ 349 l = (list); \ 350 c = 0; \ 351 while (p && l->gen_mask) { \ 352 if (l->gen_mask & (1 << (gen))) { \ 353 drm_property_add_enum(p, c, l->type, l->name); \ 354 c++; \ 355 } \ 356 l++; \ 357 } \ 358 } \ 359 } while(0) 360 361 int 362 nouveau_display_init(struct drm_device *dev) 363 { 364 struct nouveau_display *disp = nouveau_display(dev); 365 struct nouveau_drm *drm = nouveau_drm(dev); 366 struct drm_connector *connector; 367 int ret; 368 369 ret = disp->init(dev); 370 if (ret) 371 return ret; 372 373 /* enable polling for external displays */ 374 drm_kms_helper_poll_enable(dev); 375 376 /* enable hotplug interrupts */ 377 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 378 struct nouveau_connector *conn = nouveau_connector(connector); 379 nvif_notify_get(&conn->hpd); 380 } 381 382 /* enable flip completion events */ 383 nvif_notify_get(&drm->flip); 384 return ret; 385 } 386 387 void 388 nouveau_display_fini(struct drm_device *dev) 389 { 390 struct nouveau_display *disp = nouveau_display(dev); 391 struct nouveau_drm *drm = nouveau_drm(dev); 392 struct drm_connector *connector; 393 int head; 394 395 /* Make sure that drm and hw vblank irqs get properly disabled. */ 396 for (head = 0; head < dev->mode_config.num_crtc; head++) 397 drm_vblank_off(dev, head); 398 399 /* disable flip completion events */ 400 nvif_notify_put(&drm->flip); 401 402 /* disable hotplug interrupts */ 403 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 404 struct nouveau_connector *conn = nouveau_connector(connector); 405 nvif_notify_put(&conn->hpd); 406 } 407 408 drm_kms_helper_poll_disable(dev); 409 disp->fini(dev); 410 } 411 412 static void 413 nouveau_display_create_properties(struct drm_device *dev) 414 { 415 struct nouveau_display *disp = nouveau_display(dev); 416 int gen; 417 418 if (disp->disp.oclass < NV50_DISP) 419 gen = 0; 420 else 421 if (disp->disp.oclass < GF110_DISP) 422 gen = 1; 423 else 424 gen = 2; 425 426 PROP_ENUM(disp->dithering_mode, gen, "dithering mode", dither_mode); 427 PROP_ENUM(disp->dithering_depth, gen, "dithering depth", dither_depth); 428 PROP_ENUM(disp->underscan_property, gen, "underscan", underscan); 429 430 disp->underscan_hborder_property = 431 drm_property_create_range(dev, 0, "underscan hborder", 0, 128); 432 433 disp->underscan_vborder_property = 434 drm_property_create_range(dev, 0, "underscan vborder", 0, 128); 435 436 if (gen < 1) 437 return; 438 439 /* -90..+90 */ 440 disp->vibrant_hue_property = 441 drm_property_create_range(dev, 0, "vibrant hue", 0, 180); 442 443 /* -100..+100 */ 444 disp->color_vibrance_property = 445 drm_property_create_range(dev, 0, "color vibrance", 0, 200); 446 } 447 448 int 449 nouveau_display_create(struct drm_device *dev) 450 { 451 struct nouveau_drm *drm = nouveau_drm(dev); 452 struct nvkm_device *device = nvxx_device(&drm->device); 453 struct nouveau_display *disp; 454 int ret; 455 456 disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL); 457 if (!disp) 458 return -ENOMEM; 459 460 drm_mode_config_init(dev); 461 drm_mode_create_scaling_mode_property(dev); 462 drm_mode_create_dvi_i_properties(dev); 463 464 dev->mode_config.funcs = &nouveau_mode_config_funcs; 465 dev->mode_config.fb_base = device->func->resource_addr(device, 1); 466 467 dev->mode_config.min_width = 0; 468 dev->mode_config.min_height = 0; 469 if (drm->device.info.family < NV_DEVICE_INFO_V0_CELSIUS) { 470 dev->mode_config.max_width = 2048; 471 dev->mode_config.max_height = 2048; 472 } else 473 if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { 474 dev->mode_config.max_width = 4096; 475 dev->mode_config.max_height = 4096; 476 } else 477 if (drm->device.info.family < NV_DEVICE_INFO_V0_FERMI) { 478 dev->mode_config.max_width = 8192; 479 dev->mode_config.max_height = 8192; 480 } else { 481 dev->mode_config.max_width = 16384; 482 dev->mode_config.max_height = 16384; 483 } 484 485 dev->mode_config.preferred_depth = 24; 486 dev->mode_config.prefer_shadow = 1; 487 488 if (drm->device.info.chipset < 0x11) 489 dev->mode_config.async_page_flip = false; 490 else 491 dev->mode_config.async_page_flip = true; 492 493 drm_kms_helper_poll_init(dev); 494 drm_kms_helper_poll_disable(dev); 495 496 if (nouveau_modeset != 2 && drm->vbios.dcb.entries) { 497 static const u16 oclass[] = { 498 GP104_DISP, 499 GP100_DISP, 500 GM200_DISP, 501 GM107_DISP, 502 GK110_DISP, 503 GK104_DISP, 504 GF110_DISP, 505 GT214_DISP, 506 GT206_DISP, 507 GT200_DISP, 508 G82_DISP, 509 NV50_DISP, 510 NV04_DISP, 511 }; 512 int i; 513 514 for (i = 0, ret = -ENODEV; ret && i < ARRAY_SIZE(oclass); i++) { 515 ret = nvif_object_init(&drm->device.object, 0, 516 oclass[i], NULL, 0, &disp->disp); 517 } 518 519 if (ret == 0) { 520 nouveau_display_create_properties(dev); 521 if (disp->disp.oclass < NV50_DISP) 522 ret = nv04_display_create(dev); 523 else 524 ret = nv50_display_create(dev); 525 } 526 } else { 527 ret = 0; 528 } 529 530 if (ret) 531 goto disp_create_err; 532 533 if (dev->mode_config.num_crtc) { 534 ret = nouveau_display_vblank_init(dev); 535 if (ret) 536 goto vblank_err; 537 } 538 539 nouveau_backlight_init(dev); 540 return 0; 541 542 vblank_err: 543 disp->dtor(dev); 544 disp_create_err: 545 drm_kms_helper_poll_fini(dev); 546 drm_mode_config_cleanup(dev); 547 return ret; 548 } 549 550 void 551 nouveau_display_destroy(struct drm_device *dev) 552 { 553 struct nouveau_display *disp = nouveau_display(dev); 554 555 nouveau_backlight_exit(dev); 556 nouveau_display_vblank_fini(dev); 557 558 drm_kms_helper_poll_fini(dev); 559 drm_crtc_force_disable_all(dev); 560 drm_mode_config_cleanup(dev); 561 562 if (disp->dtor) 563 disp->dtor(dev); 564 565 nvif_object_fini(&disp->disp); 566 567 nouveau_drm(dev)->display = NULL; 568 kfree(disp); 569 } 570 571 int 572 nouveau_display_suspend(struct drm_device *dev, bool runtime) 573 { 574 struct drm_crtc *crtc; 575 576 nouveau_display_fini(dev); 577 578 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 579 struct nouveau_framebuffer *nouveau_fb; 580 581 nouveau_fb = nouveau_framebuffer(crtc->primary->fb); 582 if (!nouveau_fb || !nouveau_fb->nvbo) 583 continue; 584 585 nouveau_bo_unpin(nouveau_fb->nvbo); 586 } 587 588 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 589 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 590 if (nv_crtc->cursor.nvbo) { 591 if (nv_crtc->cursor.set_offset) 592 nouveau_bo_unmap(nv_crtc->cursor.nvbo); 593 nouveau_bo_unpin(nv_crtc->cursor.nvbo); 594 } 595 } 596 597 return 0; 598 } 599 600 void 601 nouveau_display_resume(struct drm_device *dev, bool runtime) 602 { 603 struct nouveau_drm *drm = nouveau_drm(dev); 604 struct drm_crtc *crtc; 605 int ret, head; 606 607 /* re-pin fb/cursors */ 608 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 609 struct nouveau_framebuffer *nouveau_fb; 610 611 nouveau_fb = nouveau_framebuffer(crtc->primary->fb); 612 if (!nouveau_fb || !nouveau_fb->nvbo) 613 continue; 614 615 ret = nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM, true); 616 if (ret) 617 NV_ERROR(drm, "Could not pin framebuffer\n"); 618 } 619 620 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 621 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 622 if (!nv_crtc->cursor.nvbo) 623 continue; 624 625 ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM, true); 626 if (!ret && nv_crtc->cursor.set_offset) 627 ret = nouveau_bo_map(nv_crtc->cursor.nvbo); 628 if (ret) 629 NV_ERROR(drm, "Could not pin/map cursor.\n"); 630 } 631 632 nouveau_display_init(dev); 633 634 /* Force CLUT to get re-loaded during modeset */ 635 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 636 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 637 638 nv_crtc->lut.depth = 0; 639 } 640 641 /* This should ensure we don't hit a locking problem when someone 642 * wakes us up via a connector. We should never go into suspend 643 * while the display is on anyways. 644 */ 645 if (runtime) 646 return; 647 648 drm_helper_resume_force_mode(dev); 649 650 /* Make sure that drm and hw vblank irqs get resumed if needed. */ 651 for (head = 0; head < dev->mode_config.num_crtc; head++) 652 drm_vblank_on(dev, head); 653 654 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 655 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 656 657 if (!nv_crtc->cursor.nvbo) 658 continue; 659 660 if (nv_crtc->cursor.set_offset) 661 nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.offset); 662 nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x, 663 nv_crtc->cursor_saved_y); 664 } 665 } 666 667 static int 668 nouveau_page_flip_emit(struct nouveau_channel *chan, 669 struct nouveau_bo *old_bo, 670 struct nouveau_bo *new_bo, 671 struct nouveau_page_flip_state *s, 672 struct nouveau_fence **pfence) 673 { 674 struct nouveau_fence_chan *fctx = chan->fence; 675 struct nouveau_drm *drm = chan->drm; 676 struct drm_device *dev = drm->dev; 677 unsigned long flags; 678 int ret; 679 680 /* Queue it to the pending list */ 681 spin_lock_irqsave(&dev->event_lock, flags); 682 list_add_tail(&s->head, &fctx->flip); 683 spin_unlock_irqrestore(&dev->event_lock, flags); 684 685 /* Synchronize with the old framebuffer */ 686 ret = nouveau_fence_sync(old_bo, chan, false, false); 687 if (ret) 688 goto fail; 689 690 /* Emit the pageflip */ 691 ret = RING_SPACE(chan, 2); 692 if (ret) 693 goto fail; 694 695 if (drm->device.info.family < NV_DEVICE_INFO_V0_FERMI) 696 BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); 697 else 698 BEGIN_NVC0(chan, FermiSw, NV_SW_PAGE_FLIP, 1); 699 OUT_RING (chan, 0x00000000); 700 FIRE_RING (chan); 701 702 ret = nouveau_fence_new(chan, false, pfence); 703 if (ret) 704 goto fail; 705 706 return 0; 707 fail: 708 spin_lock_irqsave(&dev->event_lock, flags); 709 list_del(&s->head); 710 spin_unlock_irqrestore(&dev->event_lock, flags); 711 return ret; 712 } 713 714 int 715 nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, 716 struct drm_pending_vblank_event *event, u32 flags) 717 { 718 const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1; 719 struct drm_device *dev = crtc->dev; 720 struct nouveau_drm *drm = nouveau_drm(dev); 721 struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->primary->fb)->nvbo; 722 struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo; 723 struct nouveau_page_flip_state *s; 724 struct nouveau_channel *chan; 725 struct nouveau_cli *cli; 726 struct nouveau_fence *fence; 727 int ret; 728 729 chan = drm->channel; 730 if (!chan) 731 return -ENODEV; 732 cli = (void *)chan->user.client; 733 734 s = kzalloc(sizeof(*s), GFP_KERNEL); 735 if (!s) 736 return -ENOMEM; 737 738 if (new_bo != old_bo) { 739 ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM, true); 740 if (ret) 741 goto fail_free; 742 } 743 744 mutex_lock(&cli->mutex); 745 ret = ttm_bo_reserve(&new_bo->bo, true, false, NULL); 746 if (ret) 747 goto fail_unpin; 748 749 /* synchronise rendering channel with the kernel's channel */ 750 ret = nouveau_fence_sync(new_bo, chan, false, true); 751 if (ret) { 752 ttm_bo_unreserve(&new_bo->bo); 753 goto fail_unpin; 754 } 755 756 if (new_bo != old_bo) { 757 ttm_bo_unreserve(&new_bo->bo); 758 759 ret = ttm_bo_reserve(&old_bo->bo, true, false, NULL); 760 if (ret) 761 goto fail_unpin; 762 } 763 764 /* Initialize a page flip struct */ 765 *s = (struct nouveau_page_flip_state) 766 { { }, event, crtc, fb->bits_per_pixel, fb->pitches[0], 767 new_bo->bo.offset }; 768 769 /* Keep vblanks on during flip, for the target crtc of this flip */ 770 drm_crtc_vblank_get(crtc); 771 772 /* Emit a page flip */ 773 if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { 774 ret = nv50_display_flip_next(crtc, fb, chan, swap_interval); 775 if (ret) 776 goto fail_unreserve; 777 } else { 778 struct nv04_display *dispnv04 = nv04_display(dev); 779 int head = nouveau_crtc(crtc)->index; 780 781 if (swap_interval) { 782 ret = RING_SPACE(chan, 8); 783 if (ret) 784 goto fail_unreserve; 785 786 BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1); 787 OUT_RING (chan, 0); 788 BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1); 789 OUT_RING (chan, head); 790 BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1); 791 OUT_RING (chan, 0); 792 BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1); 793 OUT_RING (chan, 0); 794 } 795 796 nouveau_bo_ref(new_bo, &dispnv04->image[head]); 797 } 798 799 ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); 800 if (ret) 801 goto fail_unreserve; 802 mutex_unlock(&cli->mutex); 803 804 /* Update the crtc struct and cleanup */ 805 crtc->primary->fb = fb; 806 807 nouveau_bo_fence(old_bo, fence, false); 808 ttm_bo_unreserve(&old_bo->bo); 809 if (old_bo != new_bo) 810 nouveau_bo_unpin(old_bo); 811 nouveau_fence_unref(&fence); 812 return 0; 813 814 fail_unreserve: 815 drm_crtc_vblank_put(crtc); 816 ttm_bo_unreserve(&old_bo->bo); 817 fail_unpin: 818 mutex_unlock(&cli->mutex); 819 if (old_bo != new_bo) 820 nouveau_bo_unpin(new_bo); 821 fail_free: 822 kfree(s); 823 return ret; 824 } 825 826 int 827 nouveau_finish_page_flip(struct nouveau_channel *chan, 828 struct nouveau_page_flip_state *ps) 829 { 830 struct nouveau_fence_chan *fctx = chan->fence; 831 struct nouveau_drm *drm = chan->drm; 832 struct drm_device *dev = drm->dev; 833 struct nouveau_page_flip_state *s; 834 unsigned long flags; 835 836 spin_lock_irqsave(&dev->event_lock, flags); 837 838 if (list_empty(&fctx->flip)) { 839 NV_ERROR(drm, "unexpected pageflip\n"); 840 spin_unlock_irqrestore(&dev->event_lock, flags); 841 return -EINVAL; 842 } 843 844 s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head); 845 if (s->event) { 846 if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { 847 drm_crtc_arm_vblank_event(s->crtc, s->event); 848 } else { 849 drm_crtc_send_vblank_event(s->crtc, s->event); 850 851 /* Give up ownership of vblank for page-flipped crtc */ 852 drm_crtc_vblank_put(s->crtc); 853 } 854 } 855 else { 856 /* Give up ownership of vblank for page-flipped crtc */ 857 drm_crtc_vblank_put(s->crtc); 858 } 859 860 list_del(&s->head); 861 if (ps) 862 *ps = *s; 863 kfree(s); 864 865 spin_unlock_irqrestore(&dev->event_lock, flags); 866 return 0; 867 } 868 869 int 870 nouveau_flip_complete(struct nvif_notify *notify) 871 { 872 struct nouveau_drm *drm = container_of(notify, typeof(*drm), flip); 873 struct nouveau_channel *chan = drm->channel; 874 struct nouveau_page_flip_state state; 875 876 if (!nouveau_finish_page_flip(chan, &state)) { 877 if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { 878 nv_set_crtc_base(drm->dev, drm_crtc_index(state.crtc), 879 state.offset + state.crtc->y * 880 state.pitch + state.crtc->x * 881 state.bpp / 8); 882 } 883 } 884 885 return NVIF_NOTIFY_KEEP; 886 } 887 888 int 889 nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, 890 struct drm_mode_create_dumb *args) 891 { 892 struct nouveau_bo *bo; 893 uint32_t domain; 894 int ret; 895 896 args->pitch = roundup(args->width * (args->bpp / 8), 256); 897 args->size = args->pitch * args->height; 898 args->size = roundup(args->size, PAGE_SIZE); 899 900 /* Use VRAM if there is any ; otherwise fallback to system memory */ 901 if (nouveau_drm(dev)->device.info.ram_size != 0) 902 domain = NOUVEAU_GEM_DOMAIN_VRAM; 903 else 904 domain = NOUVEAU_GEM_DOMAIN_GART; 905 906 ret = nouveau_gem_new(dev, args->size, 0, domain, 0, 0, &bo); 907 if (ret) 908 return ret; 909 910 ret = drm_gem_handle_create(file_priv, &bo->gem, &args->handle); 911 drm_gem_object_unreference_unlocked(&bo->gem); 912 return ret; 913 } 914 915 int 916 nouveau_display_dumb_map_offset(struct drm_file *file_priv, 917 struct drm_device *dev, 918 uint32_t handle, uint64_t *poffset) 919 { 920 struct drm_gem_object *gem; 921 922 gem = drm_gem_object_lookup(file_priv, handle); 923 if (gem) { 924 struct nouveau_bo *bo = nouveau_gem_object(gem); 925 *poffset = drm_vma_node_offset_addr(&bo->bo.vma_node); 926 drm_gem_object_unreference_unlocked(gem); 927 return 0; 928 } 929 930 return -ENOENT; 931 } 932