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