Fri Oct 7 15:55:36 2016 UTC ()
CID 1373518: Memory corruption (off-by-one)


(christos)
diff -r1.2 -r1.3 xsrc/external/mit/xorg-server/dist/hw/xfree86/drivers/modesetting/drmmode_display.c

cvs diff -r1.2 -r1.3 xsrc/external/mit/xorg-server/dist/hw/xfree86/drivers/modesetting/drmmode_display.c (switch to unified diff)

--- xsrc/external/mit/xorg-server/dist/hw/xfree86/drivers/modesetting/drmmode_display.c 2016/10/07 15:43:38 1.2
+++ xsrc/external/mit/xorg-server/dist/hw/xfree86/drivers/modesetting/drmmode_display.c 2016/10/07 15:55:36 1.3
@@ -374,1873 +374,1873 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, @@ -374,1873 +374,1873 @@ drmmode_set_mode_major(xf86CrtcPtr crtc,
374 continue; 374 continue;
375 375
376 drmmode_output = output->driver_private; 376 drmmode_output = output->driver_private;
377 if (drmmode_output->output_id == -1) 377 if (drmmode_output->output_id == -1)
378 continue; 378 continue;
379 output_ids[output_count] = 379 output_ids[output_count] =
380 drmmode_output->mode_output->connector_id; 380 drmmode_output->mode_output->connector_id;
381 output_count++; 381 output_count++;
382 } 382 }
383 383
384 if (!xf86CrtcRotate(crtc)) { 384 if (!xf86CrtcRotate(crtc)) {
385 goto done; 385 goto done;
386 } 386 }
387 crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green, 387 crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
388 crtc->gamma_blue, crtc->gamma_size); 388 crtc->gamma_blue, crtc->gamma_size);
389 389
390 drmmode_ConvertToKMode(crtc->scrn, &kmode, mode); 390 drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
391 391
392 fb_id = drmmode->fb_id; 392 fb_id = drmmode->fb_id;
393 if (crtc->randr_crtc->scanout_pixmap) { 393 if (crtc->randr_crtc->scanout_pixmap) {
394 if (!drmmode->reverse_prime_offload_mode) { 394 if (!drmmode->reverse_prime_offload_mode) {
395 msPixmapPrivPtr ppriv = 395 msPixmapPrivPtr ppriv =
396 msGetPixmapPriv(drmmode, crtc->randr_crtc->scanout_pixmap); 396 msGetPixmapPriv(drmmode, crtc->randr_crtc->scanout_pixmap);
397 fb_id = ppriv->fb_id; 397 fb_id = ppriv->fb_id;
398 x = 0; 398 x = 0;
399 } else 399 } else
400 x = drmmode_crtc->prime_pixmap_x; 400 x = drmmode_crtc->prime_pixmap_x;
401 y = 0; 401 y = 0;
402 } 402 }
403 else if (drmmode_crtc->rotate_fb_id) { 403 else if (drmmode_crtc->rotate_fb_id) {
404 fb_id = drmmode_crtc->rotate_fb_id; 404 fb_id = drmmode_crtc->rotate_fb_id;
405 x = y = 0; 405 x = y = 0;
406 } 406 }
407 407
408 if (fb_id == 0) { 408 if (fb_id == 0) {
409 ret = drmModeAddFB(drmmode->fd, 409 ret = drmModeAddFB(drmmode->fd,
410 pScrn->virtualX, pScrn->virtualY, 410 pScrn->virtualX, pScrn->virtualY,
411 pScrn->depth, drmmode->kbpp, 411 pScrn->depth, drmmode->kbpp,
412 drmmode_bo_get_pitch(&drmmode->front_bo), 412 drmmode_bo_get_pitch(&drmmode->front_bo),
413 drmmode_bo_get_handle(&drmmode->front_bo), 413 drmmode_bo_get_handle(&drmmode->front_bo),
414 &drmmode->fb_id); 414 &drmmode->fb_id);
415 if (ret < 0) { 415 if (ret < 0) {
416 ErrorF("failed to add fb %d\n", ret); 416 ErrorF("failed to add fb %d\n", ret);
417 ret = FALSE; 417 ret = FALSE;
418 goto done; 418 goto done;
419 } 419 }
420 fb_id = drmmode->fb_id; 420 fb_id = drmmode->fb_id;
421 } 421 }
422 422
423 if (drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 423 if (drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
424 fb_id, x, y, output_ids, output_count, &kmode)) { 424 fb_id, x, y, output_ids, output_count, &kmode)) {
425 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, 425 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
426 "failed to set mode: %s\n", strerror(errno)); 426 "failed to set mode: %s\n", strerror(errno));
427 ret = FALSE; 427 ret = FALSE;
428 goto done; 428 goto done;
429 } else 429 } else
430 ret = TRUE; 430 ret = TRUE;
431 431
432 if (crtc->scrn->pScreen) 432 if (crtc->scrn->pScreen)
433 xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen); 433 xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen);
434 434
435 drmmode_crtc->need_modeset = FALSE; 435 drmmode_crtc->need_modeset = FALSE;
436 crtc->funcs->dpms(crtc, DPMSModeOn); 436 crtc->funcs->dpms(crtc, DPMSModeOn);
437 437
438 /* go through all the outputs and force DPMS them back on? */ 438 /* go through all the outputs and force DPMS them back on? */
439 for (i = 0; i < xf86_config->num_output; i++) { 439 for (i = 0; i < xf86_config->num_output; i++) {
440 xf86OutputPtr output = xf86_config->output[i]; 440 xf86OutputPtr output = xf86_config->output[i];
441 drmmode_output_private_ptr drmmode_output; 441 drmmode_output_private_ptr drmmode_output;
442 442
443 if (output->crtc != crtc) 443 if (output->crtc != crtc)
444 continue; 444 continue;
445 445
446 drmmode_output = output->driver_private; 446 drmmode_output = output->driver_private;
447 if (drmmode_output->output_id == -1) 447 if (drmmode_output->output_id == -1)
448 continue; 448 continue;
449 output->funcs->dpms(output, DPMSModeOn); 449 output->funcs->dpms(output, DPMSModeOn);
450 } 450 }
451 } 451 }
452 452
453#if 0 453#if 0
454 if (pScrn->pScreen && 454 if (pScrn->pScreen &&
455 !xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) 455 !xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE))
456 xf86_reload_cursors(pScrn->pScreen); 456 xf86_reload_cursors(pScrn->pScreen);
457#endif 457#endif
458 done: 458 done:
459 if (!ret) { 459 if (!ret) {
460 crtc->x = saved_x; 460 crtc->x = saved_x;
461 crtc->y = saved_y; 461 crtc->y = saved_y;
462 crtc->rotation = saved_rotation; 462 crtc->rotation = saved_rotation;
463 crtc->mode = saved_mode; 463 crtc->mode = saved_mode;
464 } else 464 } else
465 crtc->active = TRUE; 465 crtc->active = TRUE;
466 466
467 free(output_ids); 467 free(output_ids);
468 468
469 return ret; 469 return ret;
470} 470}
471 471
472static void 472static void
473drmmode_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg) 473drmmode_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg)
474{ 474{
475 475
476} 476}
477 477
478static void 478static void
479drmmode_set_cursor_position(xf86CrtcPtr crtc, int x, int y) 479drmmode_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
480{ 480{
481 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 481 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
482 drmmode_ptr drmmode = drmmode_crtc->drmmode; 482 drmmode_ptr drmmode = drmmode_crtc->drmmode;
483 483
484 drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y); 484 drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y);
485} 485}
486 486
487static Bool 487static Bool
488drmmode_set_cursor(xf86CrtcPtr crtc) 488drmmode_set_cursor(xf86CrtcPtr crtc)
489{ 489{
490 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 490 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
491 drmmode_ptr drmmode = drmmode_crtc->drmmode; 491 drmmode_ptr drmmode = drmmode_crtc->drmmode;
492 uint32_t handle = drmmode_crtc->cursor_bo->handle; 492 uint32_t handle = drmmode_crtc->cursor_bo->handle;
493 modesettingPtr ms = modesettingPTR(crtc->scrn); 493 modesettingPtr ms = modesettingPTR(crtc->scrn);
494 static Bool use_set_cursor2 = TRUE; 494 static Bool use_set_cursor2 = TRUE;
495 int ret; 495 int ret;
496 496
497 if (use_set_cursor2) { 497 if (use_set_cursor2) {
498 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 498 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
499 CursorPtr cursor = xf86_config->cursor; 499 CursorPtr cursor = xf86_config->cursor;
500 500
501 ret = 501 ret =
502 drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 502 drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
503 handle, ms->cursor_width, ms->cursor_height, 503 handle, ms->cursor_width, ms->cursor_height,
504 cursor->bits->xhot, cursor->bits->yhot); 504 cursor->bits->xhot, cursor->bits->yhot);
505 if (!ret) 505 if (!ret)
506 return TRUE; 506 return TRUE;
507 507
508 use_set_cursor2 = FALSE; 508 use_set_cursor2 = FALSE;
509 } 509 }
510 510
511 ret = drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, 511 ret = drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle,
512 ms->cursor_width, ms->cursor_height); 512 ms->cursor_width, ms->cursor_height);
513 513
514 if (ret) { 514 if (ret) {
515 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 515 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
516 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; 516 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
517 517
518 cursor_info->MaxWidth = cursor_info->MaxHeight = 0; 518 cursor_info->MaxWidth = cursor_info->MaxHeight = 0;
519 drmmode_crtc->drmmode->sw_cursor = TRUE; 519 drmmode_crtc->drmmode->sw_cursor = TRUE;
520 /* fallback to swcursor */ 520 /* fallback to swcursor */
521 return FALSE; 521 return FALSE;
522 } 522 }
523 return TRUE; 523 return TRUE;
524} 524}
525 525
526static void drmmode_hide_cursor(xf86CrtcPtr crtc); 526static void drmmode_hide_cursor(xf86CrtcPtr crtc);
527 527
528/* 528/*
529 * The load_cursor_argb_check driver hook. 529 * The load_cursor_argb_check driver hook.
530 * 530 *
531 * Sets the hardware cursor by calling the drmModeSetCursor2 ioctl. 531 * Sets the hardware cursor by calling the drmModeSetCursor2 ioctl.
532 * On failure, returns FALSE indicating that the X server should fall 532 * On failure, returns FALSE indicating that the X server should fall
533 * back to software cursors. 533 * back to software cursors.
534 */ 534 */
535static Bool 535static Bool
536drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 *image) 536drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 *image)
537{ 537{
538 modesettingPtr ms = modesettingPTR(crtc->scrn); 538 modesettingPtr ms = modesettingPTR(crtc->scrn);
539 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 539 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
540 int i; 540 int i;
541 uint32_t *ptr; 541 uint32_t *ptr;
542 static Bool first_time = TRUE; 542 static Bool first_time = TRUE;
543 543
544 /* cursor should be mapped already */ 544 /* cursor should be mapped already */
545 ptr = (uint32_t *) (drmmode_crtc->cursor_bo->ptr); 545 ptr = (uint32_t *) (drmmode_crtc->cursor_bo->ptr);
546 546
547 for (i = 0; i < ms->cursor_width * ms->cursor_height; i++) 547 for (i = 0; i < ms->cursor_width * ms->cursor_height; i++)
548 ptr[i] = image[i]; // cpu_to_le32(image[i]); 548 ptr[i] = image[i]; // cpu_to_le32(image[i]);
549 549
550 if (drmmode_crtc->cursor_up || first_time) { 550 if (drmmode_crtc->cursor_up || first_time) {
551 Bool ret = drmmode_set_cursor(crtc); 551 Bool ret = drmmode_set_cursor(crtc);
552 if (!drmmode_crtc->cursor_up) 552 if (!drmmode_crtc->cursor_up)
553 drmmode_hide_cursor(crtc); 553 drmmode_hide_cursor(crtc);
554 first_time = FALSE; 554 first_time = FALSE;
555 return ret; 555 return ret;
556 } 556 }
557 return TRUE; 557 return TRUE;
558} 558}
559 559
560static void 560static void
561drmmode_hide_cursor(xf86CrtcPtr crtc) 561drmmode_hide_cursor(xf86CrtcPtr crtc)
562{ 562{
563 modesettingPtr ms = modesettingPTR(crtc->scrn); 563 modesettingPtr ms = modesettingPTR(crtc->scrn);
564 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 564 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
565 drmmode_ptr drmmode = drmmode_crtc->drmmode; 565 drmmode_ptr drmmode = drmmode_crtc->drmmode;
566 566
567 drmmode_crtc->cursor_up = FALSE; 567 drmmode_crtc->cursor_up = FALSE;
568 drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 568 drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0,
569 ms->cursor_width, ms->cursor_height); 569 ms->cursor_width, ms->cursor_height);
570} 570}
571 571
572static void 572static void
573drmmode_show_cursor(xf86CrtcPtr crtc) 573drmmode_show_cursor(xf86CrtcPtr crtc)
574{ 574{
575 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 575 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
576 drmmode_crtc->cursor_up = TRUE; 576 drmmode_crtc->cursor_up = TRUE;
577 drmmode_set_cursor(crtc); 577 drmmode_set_cursor(crtc);
578} 578}
579 579
580static void 580static void
581drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t * red, uint16_t * green, 581drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t * red, uint16_t * green,
582 uint16_t * blue, int size) 582 uint16_t * blue, int size)
583{ 583{
584 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 584 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
585 drmmode_ptr drmmode = drmmode_crtc->drmmode; 585 drmmode_ptr drmmode = drmmode_crtc->drmmode;
586 586
587 drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 587 drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
588 size, red, green, blue); 588 size, red, green, blue);
589} 589}
590 590
591static Bool 591static Bool
592drmmode_set_scanout_pixmap_gpu(xf86CrtcPtr crtc, PixmapPtr ppix) 592drmmode_set_scanout_pixmap_gpu(xf86CrtcPtr crtc, PixmapPtr ppix)
593{ 593{
594 ScreenPtr screen = xf86ScrnToScreen(crtc->scrn); 594 ScreenPtr screen = xf86ScrnToScreen(crtc->scrn);
595 PixmapPtr screenpix = screen->GetScreenPixmap(screen); 595 PixmapPtr screenpix = screen->GetScreenPixmap(screen);
596 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); 596 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
597 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 597 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
598 drmmode_ptr drmmode = drmmode_crtc->drmmode; 598 drmmode_ptr drmmode = drmmode_crtc->drmmode;
599 int c, total_width = 0, max_height = 0, this_x = 0; 599 int c, total_width = 0, max_height = 0, this_x = 0;
600 600
601 if (!ppix) { 601 if (!ppix) {
602 if (crtc->randr_crtc->scanout_pixmap) { 602 if (crtc->randr_crtc->scanout_pixmap) {
603 PixmapStopDirtyTracking(crtc->randr_crtc->scanout_pixmap, screenpix); 603 PixmapStopDirtyTracking(crtc->randr_crtc->scanout_pixmap, screenpix);
604 if (drmmode->fb_id) { 604 if (drmmode->fb_id) {
605 drmModeRmFB(drmmode->fd, drmmode->fb_id); 605 drmModeRmFB(drmmode->fd, drmmode->fb_id);
606 drmmode->fb_id = 0; 606 drmmode->fb_id = 0;
607 } 607 }
608 } 608 }
609 drmmode_crtc->prime_pixmap_x = 0; 609 drmmode_crtc->prime_pixmap_x = 0;
610 return TRUE; 610 return TRUE;
611 } 611 }
612 /* iterate over all the attached crtcs to work out the bounding box */ 612 /* iterate over all the attached crtcs to work out the bounding box */
613 for (c = 0; c < xf86_config->num_crtc; c++) { 613 for (c = 0; c < xf86_config->num_crtc; c++) {
614 xf86CrtcPtr iter = xf86_config->crtc[c]; 614 xf86CrtcPtr iter = xf86_config->crtc[c];
615 if (!iter->enabled && iter != crtc) 615 if (!iter->enabled && iter != crtc)
616 continue; 616 continue;
617 if (iter == crtc) { 617 if (iter == crtc) {
618 this_x = total_width; 618 this_x = total_width;
619 total_width += ppix->drawable.width; 619 total_width += ppix->drawable.width;
620 if (max_height < ppix->drawable.height) 620 if (max_height < ppix->drawable.height)
621 max_height = ppix->drawable.height; 621 max_height = ppix->drawable.height;
622 } else { 622 } else {
623 total_width += iter->mode.HDisplay; 623 total_width += iter->mode.HDisplay;
624 if (max_height < iter->mode.VDisplay) 624 if (max_height < iter->mode.VDisplay)
625 max_height = iter->mode.VDisplay; 625 max_height = iter->mode.VDisplay;
626 } 626 }
627 } 627 }
628 628
629 if (total_width != screenpix->drawable.width || 629 if (total_width != screenpix->drawable.width ||
630 max_height != screenpix->drawable.height) { 630 max_height != screenpix->drawable.height) {
631 631
632 if (!drmmode_xf86crtc_resize(crtc->scrn, total_width, max_height)) 632 if (!drmmode_xf86crtc_resize(crtc->scrn, total_width, max_height))
633 return FALSE; 633 return FALSE;
634 634
635 screenpix = screen->GetScreenPixmap(screen); 635 screenpix = screen->GetScreenPixmap(screen);
636 screen->width = screenpix->drawable.width = total_width; 636 screen->width = screenpix->drawable.width = total_width;
637 screen->height = screenpix->drawable.height = max_height; 637 screen->height = screenpix->drawable.height = max_height;
638 } 638 }
639 drmmode_crtc->prime_pixmap_x = this_x; 639 drmmode_crtc->prime_pixmap_x = this_x;
640 PixmapStartDirtyTracking(ppix, screenpix, 0, 0, this_x, 0, RR_Rotate_0); 640 PixmapStartDirtyTracking(ppix, screenpix, 0, 0, this_x, 0, RR_Rotate_0);
641 return TRUE; 641 return TRUE;
642} 642}
643 643
644static Bool 644static Bool
645drmmode_set_scanout_pixmap_cpu(xf86CrtcPtr crtc, PixmapPtr ppix) 645drmmode_set_scanout_pixmap_cpu(xf86CrtcPtr crtc, PixmapPtr ppix)
646{ 646{
647 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 647 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
648 drmmode_ptr drmmode = drmmode_crtc->drmmode; 648 drmmode_ptr drmmode = drmmode_crtc->drmmode;
649 msPixmapPrivPtr ppriv; 649 msPixmapPrivPtr ppriv;
650 void *ptr; 650 void *ptr;
651 651
652 if (!ppix) { 652 if (!ppix) {
653 if (crtc->randr_crtc->scanout_pixmap) { 653 if (crtc->randr_crtc->scanout_pixmap) {
654 ppriv = msGetPixmapPriv(drmmode, crtc->randr_crtc->scanout_pixmap); 654 ppriv = msGetPixmapPriv(drmmode, crtc->randr_crtc->scanout_pixmap);
655 drmModeRmFB(drmmode->fd, ppriv->fb_id); 655 drmModeRmFB(drmmode->fd, ppriv->fb_id);
656 } 656 }
657 if (drmmode_crtc->slave_damage) { 657 if (drmmode_crtc->slave_damage) {
658 DamageUnregister(drmmode_crtc->slave_damage); 658 DamageUnregister(drmmode_crtc->slave_damage);
659 drmmode_crtc->slave_damage = NULL; 659 drmmode_crtc->slave_damage = NULL;
660 } 660 }
661 return TRUE; 661 return TRUE;
662 } 662 }
663 663
664 ppriv = msGetPixmapPriv(drmmode, ppix); 664 ppriv = msGetPixmapPriv(drmmode, ppix);
665 if (!drmmode_crtc->slave_damage) { 665 if (!drmmode_crtc->slave_damage) {
666 drmmode_crtc->slave_damage = DamageCreate(NULL, NULL, 666 drmmode_crtc->slave_damage = DamageCreate(NULL, NULL,
667 DamageReportNone, 667 DamageReportNone,
668 TRUE, 668 TRUE,
669 crtc->randr_crtc->pScreen, 669 crtc->randr_crtc->pScreen,
670 NULL); 670 NULL);
671 } 671 }
672 ptr = drmmode_map_slave_bo(drmmode, ppriv); 672 ptr = drmmode_map_slave_bo(drmmode, ppriv);
673 ppix->devPrivate.ptr = ptr; 673 ppix->devPrivate.ptr = ptr;
674 DamageRegister(&ppix->drawable, drmmode_crtc->slave_damage); 674 DamageRegister(&ppix->drawable, drmmode_crtc->slave_damage);
675 675
676 if (ppriv->fb_id == 0) { 676 if (ppriv->fb_id == 0) {
677 int ret = drmModeAddFB(drmmode->fd, ppix->drawable.width, 677 int ret = drmModeAddFB(drmmode->fd, ppix->drawable.width,
678 ppix->drawable.height, 678 ppix->drawable.height,
679 ppix->drawable.depth, 679 ppix->drawable.depth,
680 ppix->drawable.bitsPerPixel, 680 ppix->drawable.bitsPerPixel,
681 ppix->devKind, ppriv->backing_bo->handle, &ppriv->fb_id); 681 ppix->devKind, ppriv->backing_bo->handle, &ppriv->fb_id);
682 if (ret) { 682 if (ret) {
683 ErrorF("failed to set scanout pixmap cpu\n"); 683 ErrorF("failed to set scanout pixmap cpu\n");
684 return FALSE; 684 return FALSE;
685 } 685 }
686 } 686 }
687 return TRUE; 687 return TRUE;
688} 688}
689 689
690static Bool 690static Bool
691drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix) 691drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
692{ 692{
693 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 693 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
694 drmmode_ptr drmmode = drmmode_crtc->drmmode; 694 drmmode_ptr drmmode = drmmode_crtc->drmmode;
695 695
696 if (drmmode->reverse_prime_offload_mode) 696 if (drmmode->reverse_prime_offload_mode)
697 return drmmode_set_scanout_pixmap_gpu(crtc, ppix); 697 return drmmode_set_scanout_pixmap_gpu(crtc, ppix);
698 else 698 else
699 return drmmode_set_scanout_pixmap_cpu(crtc, ppix); 699 return drmmode_set_scanout_pixmap_cpu(crtc, ppix);
700} 700}
701 701
702static void * 702static void *
703drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height) 703drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
704{ 704{
705 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 705 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
706 drmmode_ptr drmmode = drmmode_crtc->drmmode; 706 drmmode_ptr drmmode = drmmode_crtc->drmmode;
707 int ret; 707 int ret;
708 708
709 if (!drmmode_create_bo(drmmode, &drmmode_crtc->rotate_bo, 709 if (!drmmode_create_bo(drmmode, &drmmode_crtc->rotate_bo,
710 width, height, drmmode->kbpp)) { 710 width, height, drmmode->kbpp)) {
711 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, 711 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
712 "Couldn't allocate shadow memory for rotated CRTC\n"); 712 "Couldn't allocate shadow memory for rotated CRTC\n");
713 return NULL; 713 return NULL;
714 } 714 }
715 715
716 ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth, 716 ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth,
717 drmmode->kbpp, 717 drmmode->kbpp,
718 drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo), 718 drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo),
719 drmmode_bo_get_handle(&drmmode_crtc->rotate_bo), 719 drmmode_bo_get_handle(&drmmode_crtc->rotate_bo),
720 &drmmode_crtc->rotate_fb_id); 720 &drmmode_crtc->rotate_fb_id);
721 721
722 if (ret) { 722 if (ret) {
723 ErrorF("failed to add rotate fb\n"); 723 ErrorF("failed to add rotate fb\n");
724 drmmode_bo_destroy(drmmode, &drmmode_crtc->rotate_bo); 724 drmmode_bo_destroy(drmmode, &drmmode_crtc->rotate_bo);
725 return NULL; 725 return NULL;
726 } 726 }
727 727
728#ifdef GLAMOR_HAS_GBM 728#ifdef GLAMOR_HAS_GBM
729 if (drmmode->gbm) 729 if (drmmode->gbm)
730 return drmmode_crtc->rotate_bo.gbm; 730 return drmmode_crtc->rotate_bo.gbm;
731#endif 731#endif
732 return drmmode_crtc->rotate_bo.dumb; 732 return drmmode_crtc->rotate_bo.dumb;
733} 733}
734 734
735static PixmapPtr 735static PixmapPtr
736drmmode_create_pixmap_header(ScreenPtr pScreen, int width, int height, 736drmmode_create_pixmap_header(ScreenPtr pScreen, int width, int height,
737 int depth, int bitsPerPixel, int devKind, 737 int depth, int bitsPerPixel, int devKind,
738 void *pPixData) 738 void *pPixData)
739{ 739{
740 PixmapPtr pixmap; 740 PixmapPtr pixmap;
741 741
742 /* width and height of 0 means don't allocate any pixmap data */ 742 /* width and height of 0 means don't allocate any pixmap data */
743 pixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 0); 743 pixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 0);
744 744
745 if (pixmap) { 745 if (pixmap) {
746 if ((*pScreen->ModifyPixmapHeader)(pixmap, width, height, depth, 746 if ((*pScreen->ModifyPixmapHeader)(pixmap, width, height, depth,
747 bitsPerPixel, devKind, pPixData)) 747 bitsPerPixel, devKind, pPixData))
748 return pixmap; 748 return pixmap;
749 (*pScreen->DestroyPixmap)(pixmap); 749 (*pScreen->DestroyPixmap)(pixmap);
750 } 750 }
751 return NullPixmap; 751 return NullPixmap;
752} 752}
753 753
754static Bool 754static Bool
755drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo); 755drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo);
756 756
757static PixmapPtr 757static PixmapPtr
758drmmode_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) 758drmmode_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
759{ 759{
760 ScrnInfoPtr scrn = crtc->scrn; 760 ScrnInfoPtr scrn = crtc->scrn;
761 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 761 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
762 drmmode_ptr drmmode = drmmode_crtc->drmmode; 762 drmmode_ptr drmmode = drmmode_crtc->drmmode;
763 uint32_t rotate_pitch; 763 uint32_t rotate_pitch;
764 PixmapPtr rotate_pixmap; 764 PixmapPtr rotate_pixmap;
765 void *pPixData = NULL; 765 void *pPixData = NULL;
766 766
767 if (!data) { 767 if (!data) {
768 data = drmmode_shadow_allocate(crtc, width, height); 768 data = drmmode_shadow_allocate(crtc, width, height);
769 if (!data) { 769 if (!data) {
770 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 770 xf86DrvMsg(scrn->scrnIndex, X_ERROR,
771 "Couldn't allocate shadow pixmap for rotated CRTC\n"); 771 "Couldn't allocate shadow pixmap for rotated CRTC\n");
772 return NULL; 772 return NULL;
773 } 773 }
774 } 774 }
775 775
776 if (!drmmode_bo_has_bo(&drmmode_crtc->rotate_bo)) { 776 if (!drmmode_bo_has_bo(&drmmode_crtc->rotate_bo)) {
777 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 777 xf86DrvMsg(scrn->scrnIndex, X_ERROR,
778 "Couldn't allocate shadow pixmap for rotated CRTC\n"); 778 "Couldn't allocate shadow pixmap for rotated CRTC\n");
779 return NULL; 779 return NULL;
780 } 780 }
781 781
782 pPixData = drmmode_bo_map(drmmode, &drmmode_crtc->rotate_bo); 782 pPixData = drmmode_bo_map(drmmode, &drmmode_crtc->rotate_bo);
783 rotate_pitch = drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo), 783 rotate_pitch = drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo),
784 784
785 rotate_pixmap = drmmode_create_pixmap_header(scrn->pScreen, 785 rotate_pixmap = drmmode_create_pixmap_header(scrn->pScreen,
786 width, height, 786 width, height,
787 scrn->depth, 787 scrn->depth,
788 drmmode->kbpp, 788 drmmode->kbpp,
789 rotate_pitch, 789 rotate_pitch,
790 pPixData); 790 pPixData);
791 791
792 if (rotate_pixmap == NULL) { 792 if (rotate_pixmap == NULL) {
793 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 793 xf86DrvMsg(scrn->scrnIndex, X_ERROR,
794 "Couldn't allocate shadow pixmap for rotated CRTC\n"); 794 "Couldn't allocate shadow pixmap for rotated CRTC\n");
795 return NULL; 795 return NULL;
796 } 796 }
797 797
798 drmmode_set_pixmap_bo(drmmode, rotate_pixmap, &drmmode_crtc->rotate_bo); 798 drmmode_set_pixmap_bo(drmmode, rotate_pixmap, &drmmode_crtc->rotate_bo);
799 799
800 return rotate_pixmap; 800 return rotate_pixmap;
801} 801}
802 802
803static void 803static void
804drmmode_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) 804drmmode_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
805{ 805{
806 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 806 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
807 drmmode_ptr drmmode = drmmode_crtc->drmmode; 807 drmmode_ptr drmmode = drmmode_crtc->drmmode;
808 808
809 if (rotate_pixmap) { 809 if (rotate_pixmap) {
810 drmmode_set_pixmap_bo(drmmode, rotate_pixmap, NULL); 810 drmmode_set_pixmap_bo(drmmode, rotate_pixmap, NULL);
811 rotate_pixmap->drawable.pScreen->DestroyPixmap(rotate_pixmap); 811 rotate_pixmap->drawable.pScreen->DestroyPixmap(rotate_pixmap);
812 } 812 }
813 813
814 if (data) { 814 if (data) {
815 drmModeRmFB(drmmode->fd, drmmode_crtc->rotate_fb_id); 815 drmModeRmFB(drmmode->fd, drmmode_crtc->rotate_fb_id);
816 drmmode_crtc->rotate_fb_id = 0; 816 drmmode_crtc->rotate_fb_id = 0;
817 817
818 drmmode_bo_destroy(drmmode, &drmmode_crtc->rotate_bo); 818 drmmode_bo_destroy(drmmode, &drmmode_crtc->rotate_bo);
819 memset(&drmmode_crtc->rotate_bo, 0, sizeof drmmode_crtc->rotate_bo); 819 memset(&drmmode_crtc->rotate_bo, 0, sizeof drmmode_crtc->rotate_bo);
820 } 820 }
821} 821}
822 822
823static const xf86CrtcFuncsRec drmmode_crtc_funcs = { 823static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
824 .dpms = drmmode_crtc_dpms, 824 .dpms = drmmode_crtc_dpms,
825 .set_mode_major = drmmode_set_mode_major, 825 .set_mode_major = drmmode_set_mode_major,
826 .set_cursor_colors = drmmode_set_cursor_colors, 826 .set_cursor_colors = drmmode_set_cursor_colors,
827 .set_cursor_position = drmmode_set_cursor_position, 827 .set_cursor_position = drmmode_set_cursor_position,
828 .show_cursor = drmmode_show_cursor, 828 .show_cursor = drmmode_show_cursor,
829 .hide_cursor = drmmode_hide_cursor, 829 .hide_cursor = drmmode_hide_cursor,
830 .load_cursor_argb_check = drmmode_load_cursor_argb_check, 830 .load_cursor_argb_check = drmmode_load_cursor_argb_check,
831 831
832 .gamma_set = drmmode_crtc_gamma_set, 832 .gamma_set = drmmode_crtc_gamma_set,
833 .destroy = NULL, /* XXX */ 833 .destroy = NULL, /* XXX */
834 .set_scanout_pixmap = drmmode_set_scanout_pixmap, 834 .set_scanout_pixmap = drmmode_set_scanout_pixmap,
835 .shadow_allocate = drmmode_shadow_allocate, 835 .shadow_allocate = drmmode_shadow_allocate,
836 .shadow_create = drmmode_shadow_create, 836 .shadow_create = drmmode_shadow_create,
837 .shadow_destroy = drmmode_shadow_destroy, 837 .shadow_destroy = drmmode_shadow_destroy,
838}; 838};
839 839
840static uint32_t 840static uint32_t
841drmmode_crtc_vblank_pipe(int crtc_id) 841drmmode_crtc_vblank_pipe(int crtc_id)
842{ 842{
843 if (crtc_id > 1) 843 if (crtc_id > 1)
844 return crtc_id << DRM_VBLANK_HIGH_CRTC_SHIFT; 844 return crtc_id << DRM_VBLANK_HIGH_CRTC_SHIFT;
845 else if (crtc_id > 0) 845 else if (crtc_id > 0)
846 return DRM_VBLANK_SECONDARY; 846 return DRM_VBLANK_SECONDARY;
847 else 847 else
848 return 0; 848 return 0;
849} 849}
850 850
851static unsigned int 851static unsigned int
852drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num) 852drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num)
853{ 853{
854 xf86CrtcPtr crtc; 854 xf86CrtcPtr crtc;
855 drmmode_crtc_private_ptr drmmode_crtc; 855 drmmode_crtc_private_ptr drmmode_crtc;
856 modesettingEntPtr ms_ent = ms_ent_priv(pScrn); 856 modesettingEntPtr ms_ent = ms_ent_priv(pScrn);
857 857
858 crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs); 858 crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs);
859 if (crtc == NULL) 859 if (crtc == NULL)
860 return 0; 860 return 0;
861 861
862 drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1); 862 drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
863 drmmode_crtc->mode_crtc = 863 drmmode_crtc->mode_crtc =
864 drmModeGetCrtc(drmmode->fd, mode_res->crtcs[num]); 864 drmModeGetCrtc(drmmode->fd, mode_res->crtcs[num]);
865 drmmode_crtc->drmmode = drmmode; 865 drmmode_crtc->drmmode = drmmode;
866 drmmode_crtc->vblank_pipe = drmmode_crtc_vblank_pipe(num); 866 drmmode_crtc->vblank_pipe = drmmode_crtc_vblank_pipe(num);
867 crtc->driver_private = drmmode_crtc; 867 crtc->driver_private = drmmode_crtc;
868 868
869 /* Mark num'th crtc as in use on this device. */ 869 /* Mark num'th crtc as in use on this device. */
870 ms_ent->assigned_crtcs |= (1 << num); 870 ms_ent->assigned_crtcs |= (1 << num);
871 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG, 871 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG,
872 "Allocated crtc nr. %d to this screen.\n", num); 872 "Allocated crtc nr. %d to this screen.\n", num);
873 873
874 return 1; 874 return 1;
875} 875}
876 876
877static xf86OutputStatus 877static xf86OutputStatus
878drmmode_output_detect(xf86OutputPtr output) 878drmmode_output_detect(xf86OutputPtr output)
879{ 879{
880 /* go to the hw and retrieve a new output struct */ 880 /* go to the hw and retrieve a new output struct */
881 drmmode_output_private_ptr drmmode_output = output->driver_private; 881 drmmode_output_private_ptr drmmode_output = output->driver_private;
882 drmmode_ptr drmmode = drmmode_output->drmmode; 882 drmmode_ptr drmmode = drmmode_output->drmmode;
883 xf86OutputStatus status; 883 xf86OutputStatus status;
884 884
885 if (drmmode_output->output_id == -1) 885 if (drmmode_output->output_id == -1)
886 return XF86OutputStatusDisconnected; 886 return XF86OutputStatusDisconnected;
887 887
888 drmModeFreeConnector(drmmode_output->mode_output); 888 drmModeFreeConnector(drmmode_output->mode_output);
889 889
890 drmmode_output->mode_output = 890 drmmode_output->mode_output =
891 drmModeGetConnector(drmmode->fd, drmmode_output->output_id); 891 drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
892 if (!drmmode_output->mode_output) 892 if (!drmmode_output->mode_output)
893 return XF86OutputStatusDisconnected; 893 return XF86OutputStatusDisconnected;
894 894
895 switch (drmmode_output->mode_output->connection) { 895 switch (drmmode_output->mode_output->connection) {
896 case DRM_MODE_CONNECTED: 896 case DRM_MODE_CONNECTED:
897 status = XF86OutputStatusConnected; 897 status = XF86OutputStatusConnected;
898 break; 898 break;
899 case DRM_MODE_DISCONNECTED: 899 case DRM_MODE_DISCONNECTED:
900 status = XF86OutputStatusDisconnected; 900 status = XF86OutputStatusDisconnected;
901 break; 901 break;
902 default: 902 default:
903 case DRM_MODE_UNKNOWNCONNECTION: 903 case DRM_MODE_UNKNOWNCONNECTION:
904 status = XF86OutputStatusUnknown; 904 status = XF86OutputStatusUnknown;
905 break; 905 break;
906 } 906 }
907 return status; 907 return status;
908} 908}
909 909
910static Bool 910static Bool
911drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes) 911drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
912{ 912{
913 return MODE_OK; 913 return MODE_OK;
914} 914}
915 915
916static void 916static void
917drmmode_output_attach_tile(xf86OutputPtr output) 917drmmode_output_attach_tile(xf86OutputPtr output)
918{ 918{
919 drmmode_output_private_ptr drmmode_output = output->driver_private; 919 drmmode_output_private_ptr drmmode_output = output->driver_private;
920 drmModeConnectorPtr koutput = drmmode_output->mode_output; 920 drmModeConnectorPtr koutput = drmmode_output->mode_output;
921 drmmode_ptr drmmode = drmmode_output->drmmode; 921 drmmode_ptr drmmode = drmmode_output->drmmode;
922 int i; 922 int i;
923 struct xf86CrtcTileInfo tile_info, *set = NULL; 923 struct xf86CrtcTileInfo tile_info, *set = NULL;
924 924
925 if (!koutput) { 925 if (!koutput) {
926 xf86OutputSetTile(output, NULL); 926 xf86OutputSetTile(output, NULL);
927 return; 927 return;
928 } 928 }
929 929
930 /* look for a TILE property */ 930 /* look for a TILE property */
931 for (i = 0; i < koutput->count_props; i++) { 931 for (i = 0; i < koutput->count_props; i++) {
932 drmModePropertyPtr props; 932 drmModePropertyPtr props;
933 props = drmModeGetProperty(drmmode->fd, koutput->props[i]); 933 props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
934 if (!props) 934 if (!props)
935 continue; 935 continue;
936 936
937 if (!(props->flags & DRM_MODE_PROP_BLOB)) { 937 if (!(props->flags & DRM_MODE_PROP_BLOB)) {
938 drmModeFreeProperty(props); 938 drmModeFreeProperty(props);
939 continue; 939 continue;
940 } 940 }
941 941
942 if (!strcmp(props->name, "TILE")) { 942 if (!strcmp(props->name, "TILE")) {
943 drmModeFreePropertyBlob(drmmode_output->tile_blob); 943 drmModeFreePropertyBlob(drmmode_output->tile_blob);
944 drmmode_output->tile_blob = 944 drmmode_output->tile_blob =
945 drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]); 945 drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
946 } 946 }
947 drmModeFreeProperty(props); 947 drmModeFreeProperty(props);
948 } 948 }
949 if (drmmode_output->tile_blob) { 949 if (drmmode_output->tile_blob) {
950 if (xf86OutputParseKMSTile(drmmode_output->tile_blob->data, drmmode_output->tile_blob->length, &tile_info) == TRUE) 950 if (xf86OutputParseKMSTile(drmmode_output->tile_blob->data, drmmode_output->tile_blob->length, &tile_info) == TRUE)
951 set = &tile_info; 951 set = &tile_info;
952 } 952 }
953 xf86OutputSetTile(output, set); 953 xf86OutputSetTile(output, set);
954} 954}
955 955
956static Bool 956static Bool
957has_panel_fitter(xf86OutputPtr output) 957has_panel_fitter(xf86OutputPtr output)
958{ 958{
959 drmmode_output_private_ptr drmmode_output = output->driver_private; 959 drmmode_output_private_ptr drmmode_output = output->driver_private;
960 drmModeConnectorPtr koutput = drmmode_output->mode_output; 960 drmModeConnectorPtr koutput = drmmode_output->mode_output;
961 drmmode_ptr drmmode = drmmode_output->drmmode; 961 drmmode_ptr drmmode = drmmode_output->drmmode;
962 int i; 962 int i;
963 963
964 /* Presume that if the output supports scaling, then we have a 964 /* Presume that if the output supports scaling, then we have a
965 * panel fitter capable of adjust any mode to suit. 965 * panel fitter capable of adjust any mode to suit.
966 */ 966 */
967 for (i = 0; i < koutput->count_props; i++) { 967 for (i = 0; i < koutput->count_props; i++) {
968 drmModePropertyPtr props; 968 drmModePropertyPtr props;
969 Bool found = FALSE; 969 Bool found = FALSE;
970 970
971 props = drmModeGetProperty(drmmode->fd, koutput->props[i]); 971 props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
972 if (props) { 972 if (props) {
973 found = strcmp(props->name, "scaling mode") == 0; 973 found = strcmp(props->name, "scaling mode") == 0;
974 drmModeFreeProperty(props); 974 drmModeFreeProperty(props);
975 } 975 }
976 976
977 if (found) 977 if (found)
978 return TRUE; 978 return TRUE;
979 } 979 }
980 980
981 return FALSE; 981 return FALSE;
982} 982}
983 983
984static DisplayModePtr 984static DisplayModePtr
985drmmode_output_add_gtf_modes(xf86OutputPtr output, DisplayModePtr Modes) 985drmmode_output_add_gtf_modes(xf86OutputPtr output, DisplayModePtr Modes)
986{ 986{
987 xf86MonPtr mon = output->MonInfo; 987 xf86MonPtr mon = output->MonInfo;
988 DisplayModePtr i, m, preferred = NULL; 988 DisplayModePtr i, m, preferred = NULL;
989 int max_x = 0, max_y = 0; 989 int max_x = 0, max_y = 0;
990 float max_vrefresh = 0.0; 990 float max_vrefresh = 0.0;
991 991
992 if (mon && GTF_SUPPORTED(mon->features.msc)) 992 if (mon && GTF_SUPPORTED(mon->features.msc))
993 return Modes; 993 return Modes;
994 994
995 if (!has_panel_fitter(output)) 995 if (!has_panel_fitter(output))
996 return Modes; 996 return Modes;
997 997
998 for (m = Modes; m; m = m->next) { 998 for (m = Modes; m; m = m->next) {
999 if (m->type & M_T_PREFERRED) 999 if (m->type & M_T_PREFERRED)
1000 preferred = m; 1000 preferred = m;
1001 max_x = max(max_x, m->HDisplay); 1001 max_x = max(max_x, m->HDisplay);
1002 max_y = max(max_y, m->VDisplay); 1002 max_y = max(max_y, m->VDisplay);
1003 max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(m)); 1003 max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(m));
1004 } 1004 }
1005 1005
1006 max_vrefresh = max(max_vrefresh, 60.0); 1006 max_vrefresh = max(max_vrefresh, 60.0);
1007 max_vrefresh *= (1 + SYNC_TOLERANCE); 1007 max_vrefresh *= (1 + SYNC_TOLERANCE);
1008 1008
1009 m = xf86GetDefaultModes(); 1009 m = xf86GetDefaultModes();
1010 xf86ValidateModesSize(output->scrn, m, max_x, max_y, 0); 1010 xf86ValidateModesSize(output->scrn, m, max_x, max_y, 0);
1011 1011
1012 for (i = m; i; i = i->next) { 1012 for (i = m; i; i = i->next) {
1013 if (xf86ModeVRefresh(i) > max_vrefresh) 1013 if (xf86ModeVRefresh(i) > max_vrefresh)
1014 i->status = MODE_VSYNC; 1014 i->status = MODE_VSYNC;
1015 if (preferred && 1015 if (preferred &&
1016 i->HDisplay >= preferred->HDisplay && 1016 i->HDisplay >= preferred->HDisplay &&
1017 i->VDisplay >= preferred->VDisplay && 1017 i->VDisplay >= preferred->VDisplay &&
1018 xf86ModeVRefresh(i) >= xf86ModeVRefresh(preferred)) 1018 xf86ModeVRefresh(i) >= xf86ModeVRefresh(preferred))
1019 i->status = MODE_VSYNC; 1019 i->status = MODE_VSYNC;
1020 } 1020 }
1021 1021
1022 xf86PruneInvalidModes(output->scrn, &m, FALSE); 1022 xf86PruneInvalidModes(output->scrn, &m, FALSE);
1023 1023
1024 return xf86ModesAdd(Modes, m); 1024 return xf86ModesAdd(Modes, m);
1025} 1025}
1026 1026
1027static DisplayModePtr 1027static DisplayModePtr
1028drmmode_output_get_modes(xf86OutputPtr output) 1028drmmode_output_get_modes(xf86OutputPtr output)
1029{ 1029{
1030 drmmode_output_private_ptr drmmode_output = output->driver_private; 1030 drmmode_output_private_ptr drmmode_output = output->driver_private;
1031 drmModeConnectorPtr koutput = drmmode_output->mode_output; 1031 drmModeConnectorPtr koutput = drmmode_output->mode_output;
1032 drmmode_ptr drmmode = drmmode_output->drmmode; 1032 drmmode_ptr drmmode = drmmode_output->drmmode;
1033 int i; 1033 int i;
1034 DisplayModePtr Modes = NULL, Mode; 1034 DisplayModePtr Modes = NULL, Mode;
1035 drmModePropertyPtr props; 1035 drmModePropertyPtr props;
1036 xf86MonPtr mon = NULL; 1036 xf86MonPtr mon = NULL;
1037 1037
1038 if (!koutput) 1038 if (!koutput)
1039 return NULL; 1039 return NULL;
1040 1040
1041 /* look for an EDID property */ 1041 /* look for an EDID property */
1042 for (i = 0; i < koutput->count_props; i++) { 1042 for (i = 0; i < koutput->count_props; i++) {
1043 props = drmModeGetProperty(drmmode->fd, koutput->props[i]); 1043 props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
1044 if (props && (props->flags & DRM_MODE_PROP_BLOB)) { 1044 if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
1045 if (!strcmp(props->name, "EDID")) { 1045 if (!strcmp(props->name, "EDID")) {
1046 if (drmmode_output->edid_blob) 1046 if (drmmode_output->edid_blob)
1047 drmModeFreePropertyBlob(drmmode_output->edid_blob); 1047 drmModeFreePropertyBlob(drmmode_output->edid_blob);
1048 drmmode_output->edid_blob = 1048 drmmode_output->edid_blob =
1049 drmModeGetPropertyBlob(drmmode->fd, 1049 drmModeGetPropertyBlob(drmmode->fd,
1050 koutput->prop_values[i]); 1050 koutput->prop_values[i]);
1051 } 1051 }
1052 drmModeFreeProperty(props); 1052 drmModeFreeProperty(props);
1053 } 1053 }
1054 } 1054 }
1055 1055
1056 if (drmmode_output->edid_blob) { 1056 if (drmmode_output->edid_blob) {
1057 mon = xf86InterpretEDID(output->scrn->scrnIndex, 1057 mon = xf86InterpretEDID(output->scrn->scrnIndex,
1058 drmmode_output->edid_blob->data); 1058 drmmode_output->edid_blob->data);
1059 if (mon && drmmode_output->edid_blob->length > 128) 1059 if (mon && drmmode_output->edid_blob->length > 128)
1060 mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA; 1060 mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
1061 } 1061 }
1062 xf86OutputSetEDID(output, mon); 1062 xf86OutputSetEDID(output, mon);
1063 1063
1064 drmmode_output_attach_tile(output); 1064 drmmode_output_attach_tile(output);
1065 1065
1066 /* modes should already be available */ 1066 /* modes should already be available */
1067 for (i = 0; i < koutput->count_modes; i++) { 1067 for (i = 0; i < koutput->count_modes; i++) {
1068 Mode = xnfalloc(sizeof(DisplayModeRec)); 1068 Mode = xnfalloc(sizeof(DisplayModeRec));
1069 1069
1070 drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode); 1070 drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode);
1071 Modes = xf86ModesAdd(Modes, Mode); 1071 Modes = xf86ModesAdd(Modes, Mode);
1072 1072
1073 } 1073 }
1074 1074
1075 return drmmode_output_add_gtf_modes(output, Modes); 1075 return drmmode_output_add_gtf_modes(output, Modes);
1076} 1076}
1077 1077
1078static void 1078static void
1079drmmode_output_destroy(xf86OutputPtr output) 1079drmmode_output_destroy(xf86OutputPtr output)
1080{ 1080{
1081 drmmode_output_private_ptr drmmode_output = output->driver_private; 1081 drmmode_output_private_ptr drmmode_output = output->driver_private;
1082 int i; 1082 int i;
1083 1083
1084 if (drmmode_output->edid_blob) 1084 if (drmmode_output->edid_blob)
1085 drmModeFreePropertyBlob(drmmode_output->edid_blob); 1085 drmModeFreePropertyBlob(drmmode_output->edid_blob);
1086 for (i = 0; i < drmmode_output->num_props; i++) { 1086 for (i = 0; i < drmmode_output->num_props; i++) {
1087 drmModeFreeProperty(drmmode_output->props[i].mode_prop); 1087 drmModeFreeProperty(drmmode_output->props[i].mode_prop);
1088 free(drmmode_output->props[i].atoms); 1088 free(drmmode_output->props[i].atoms);
1089 } 1089 }
1090 free(drmmode_output->props); 1090 free(drmmode_output->props);
1091 if (drmmode_output->mode_output) { 1091 if (drmmode_output->mode_output) {
1092 for (i = 0; i < drmmode_output->mode_output->count_encoders; i++) { 1092 for (i = 0; i < drmmode_output->mode_output->count_encoders; i++) {
1093 drmModeFreeEncoder(drmmode_output->mode_encoders[i]); 1093 drmModeFreeEncoder(drmmode_output->mode_encoders[i]);
1094 } 1094 }
1095 drmModeFreeConnector(drmmode_output->mode_output); 1095 drmModeFreeConnector(drmmode_output->mode_output);
1096 } 1096 }
1097 free(drmmode_output->mode_encoders); 1097 free(drmmode_output->mode_encoders);
1098 free(drmmode_output); 1098 free(drmmode_output);
1099 output->driver_private = NULL; 1099 output->driver_private = NULL;
1100} 1100}
1101 1101
1102static void 1102static void
1103drmmode_output_dpms(xf86OutputPtr output, int mode) 1103drmmode_output_dpms(xf86OutputPtr output, int mode)
1104{ 1104{
1105 drmmode_output_private_ptr drmmode_output = output->driver_private; 1105 drmmode_output_private_ptr drmmode_output = output->driver_private;
1106 xf86CrtcPtr crtc = output->crtc; 1106 xf86CrtcPtr crtc = output->crtc;
1107 drmModeConnectorPtr koutput = drmmode_output->mode_output; 1107 drmModeConnectorPtr koutput = drmmode_output->mode_output;
1108 drmmode_ptr drmmode = drmmode_output->drmmode; 1108 drmmode_ptr drmmode = drmmode_output->drmmode;
1109 1109
1110 if (!koutput) 1110 if (!koutput)
1111 return; 1111 return;
1112 1112
1113 drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id, 1113 drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id,
1114 drmmode_output->dpms_enum_id, mode); 1114 drmmode_output->dpms_enum_id, mode);
1115 1115
1116 if (mode == DPMSModeOn && crtc) { 1116 if (mode == DPMSModeOn && crtc) {
1117 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 1117 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1118 if (drmmode_crtc->need_modeset) 1118 if (drmmode_crtc->need_modeset)
1119 drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, 1119 drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation,
1120 crtc->x, crtc->y); 1120 crtc->x, crtc->y);
1121 } 1121 }
1122 return; 1122 return;
1123} 1123}
1124 1124
1125static Bool 1125static Bool
1126drmmode_property_ignore(drmModePropertyPtr prop) 1126drmmode_property_ignore(drmModePropertyPtr prop)
1127{ 1127{
1128 if (!prop) 1128 if (!prop)
1129 return TRUE; 1129 return TRUE;
1130 /* ignore blob prop */ 1130 /* ignore blob prop */
1131 if (prop->flags & DRM_MODE_PROP_BLOB) 1131 if (prop->flags & DRM_MODE_PROP_BLOB)
1132 return TRUE; 1132 return TRUE;
1133 /* ignore standard property */ 1133 /* ignore standard property */
1134 if (!strcmp(prop->name, "EDID") || !strcmp(prop->name, "DPMS")) 1134 if (!strcmp(prop->name, "EDID") || !strcmp(prop->name, "DPMS"))
1135 return TRUE; 1135 return TRUE;
1136 1136
1137 return FALSE; 1137 return FALSE;
1138} 1138}
1139 1139
1140static void 1140static void
1141drmmode_output_create_resources(xf86OutputPtr output) 1141drmmode_output_create_resources(xf86OutputPtr output)
1142{ 1142{
1143 drmmode_output_private_ptr drmmode_output = output->driver_private; 1143 drmmode_output_private_ptr drmmode_output = output->driver_private;
1144 drmModeConnectorPtr mode_output = drmmode_output->mode_output; 1144 drmModeConnectorPtr mode_output = drmmode_output->mode_output;
1145 drmmode_ptr drmmode = drmmode_output->drmmode; 1145 drmmode_ptr drmmode = drmmode_output->drmmode;
1146 drmModePropertyPtr drmmode_prop; 1146 drmModePropertyPtr drmmode_prop;
1147 int i, j, err; 1147 int i, j, err;
1148 1148
1149 drmmode_output->props = 1149 drmmode_output->props =
1150 calloc(mode_output->count_props, sizeof(drmmode_prop_rec)); 1150 calloc(mode_output->count_props, sizeof(drmmode_prop_rec));
1151 if (!drmmode_output->props) 1151 if (!drmmode_output->props)
1152 return; 1152 return;
1153 1153
1154 drmmode_output->num_props = 0; 1154 drmmode_output->num_props = 0;
1155 for (i = 0, j = 0; i < mode_output->count_props; i++) { 1155 for (i = 0, j = 0; i < mode_output->count_props; i++) {
1156 drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]); 1156 drmmode_prop = drmModeGetProperty(drmmode->fd, mode_output->props[i]);
1157 if (drmmode_property_ignore(drmmode_prop)) { 1157 if (drmmode_property_ignore(drmmode_prop)) {
1158 drmModeFreeProperty(drmmode_prop); 1158 drmModeFreeProperty(drmmode_prop);
1159 continue; 1159 continue;
1160 } 1160 }
1161 drmmode_output->props[j].mode_prop = drmmode_prop; 1161 drmmode_output->props[j].mode_prop = drmmode_prop;
1162 drmmode_output->props[j].value = mode_output->prop_values[i]; 1162 drmmode_output->props[j].value = mode_output->prop_values[i];
1163 drmmode_output->num_props++; 1163 drmmode_output->num_props++;
1164 j++; 1164 j++;
1165 } 1165 }
1166 1166
1167 for (i = 0; i < drmmode_output->num_props; i++) { 1167 for (i = 0; i < drmmode_output->num_props; i++) {
1168 drmmode_prop_ptr p = &drmmode_output->props[i]; 1168 drmmode_prop_ptr p = &drmmode_output->props[i];
1169 1169
1170 drmmode_prop = p->mode_prop; 1170 drmmode_prop = p->mode_prop;
1171 1171
1172 if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) { 1172 if (drmmode_prop->flags & DRM_MODE_PROP_RANGE) {
1173 INT32 prop_range[2]; 1173 INT32 prop_range[2];
1174 INT32 value = p->value; 1174 INT32 value = p->value;
1175 1175
1176 p->num_atoms = 1; 1176 p->num_atoms = 1;
1177 p->atoms = calloc(p->num_atoms, sizeof(Atom)); 1177 p->atoms = calloc(p->num_atoms, sizeof(Atom));
1178 if (!p->atoms) 1178 if (!p->atoms)
1179 continue; 1179 continue;
1180 p->atoms[0] = 1180 p->atoms[0] =
1181 MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); 1181 MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE);
1182 prop_range[0] = drmmode_prop->values[0]; 1182 prop_range[0] = drmmode_prop->values[0];
1183 prop_range[1] = drmmode_prop->values[1]; 1183 prop_range[1] = drmmode_prop->values[1];
1184 err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], 1184 err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
1185 FALSE, TRUE, 1185 FALSE, TRUE,
1186 drmmode_prop-> 1186 drmmode_prop->
1187 flags & DRM_MODE_PROP_IMMUTABLE ? 1187 flags & DRM_MODE_PROP_IMMUTABLE ?
1188 TRUE : FALSE, 2, prop_range); 1188 TRUE : FALSE, 2, prop_range);
1189 if (err != 0) { 1189 if (err != 0) {
1190 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, 1190 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
1191 "RRConfigureOutputProperty error, %d\n", err); 1191 "RRConfigureOutputProperty error, %d\n", err);
1192 } 1192 }
1193 err = RRChangeOutputProperty(output->randr_output, p->atoms[0], 1193 err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
1194 XA_INTEGER, 32, PropModeReplace, 1, 1194 XA_INTEGER, 32, PropModeReplace, 1,
1195 &value, FALSE, TRUE); 1195 &value, FALSE, TRUE);
1196 if (err != 0) { 1196 if (err != 0) {
1197 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, 1197 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
1198 "RRChangeOutputProperty error, %d\n", err); 1198 "RRChangeOutputProperty error, %d\n", err);
1199 } 1199 }
1200 } 1200 }
1201 else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) { 1201 else if (drmmode_prop->flags & DRM_MODE_PROP_ENUM) {
1202 p->num_atoms = drmmode_prop->count_enums + 1; 1202 p->num_atoms = drmmode_prop->count_enums + 1;
1203 p->atoms = calloc(p->num_atoms, sizeof(Atom)); 1203 p->atoms = calloc(p->num_atoms, sizeof(Atom));
1204 if (!p->atoms) 1204 if (!p->atoms)
1205 continue; 1205 continue;
1206 p->atoms[0] = 1206 p->atoms[0] =
1207 MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE); 1207 MakeAtom(drmmode_prop->name, strlen(drmmode_prop->name), TRUE);
1208 for (j = 1; j <= drmmode_prop->count_enums; j++) { 1208 for (j = 1; j <= drmmode_prop->count_enums; j++) {
1209 struct drm_mode_property_enum *e = &drmmode_prop->enums[j - 1]; 1209 struct drm_mode_property_enum *e = &drmmode_prop->enums[j - 1];
1210 1210
1211 p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE); 1211 p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE);
1212 } 1212 }
1213 err = RRConfigureOutputProperty(output->randr_output, p->atoms[0], 1213 err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
1214 FALSE, FALSE, 1214 FALSE, FALSE,
1215 drmmode_prop-> 1215 drmmode_prop->
1216 flags & DRM_MODE_PROP_IMMUTABLE ? 1216 flags & DRM_MODE_PROP_IMMUTABLE ?
1217 TRUE : FALSE, p->num_atoms - 1, 1217 TRUE : FALSE, p->num_atoms - 1,
1218 (INT32 *) &p->atoms[1]); 1218 (INT32 *) &p->atoms[1]);
1219 if (err != 0) { 1219 if (err != 0) {
1220 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, 1220 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
1221 "RRConfigureOutputProperty error, %d\n", err); 1221 "RRConfigureOutputProperty error, %d\n", err);
1222 } 1222 }
1223 for (j = 0; j < drmmode_prop->count_enums; j++) 1223 for (j = 0; j < drmmode_prop->count_enums; j++)
1224 if (drmmode_prop->enums[j].value == p->value) 1224 if (drmmode_prop->enums[j].value == p->value)
1225 break; 1225 break;
1226 /* there's always a matching value */ 1226 /* there's always a matching value */
1227 err = RRChangeOutputProperty(output->randr_output, p->atoms[0], 1227 err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
1228 XA_ATOM, 32, PropModeReplace, 1, 1228 XA_ATOM, 32, PropModeReplace, 1,
1229 &p->atoms[j + 1], FALSE, TRUE); 1229 &p->atoms[j + 1], FALSE, TRUE);
1230 if (err != 0) { 1230 if (err != 0) {
1231 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, 1231 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
1232 "RRChangeOutputProperty error, %d\n", err); 1232 "RRChangeOutputProperty error, %d\n", err);
1233 } 1233 }
1234 } 1234 }
1235 } 1235 }
1236} 1236}
1237 1237
1238static Bool 1238static Bool
1239drmmode_output_set_property(xf86OutputPtr output, Atom property, 1239drmmode_output_set_property(xf86OutputPtr output, Atom property,
1240 RRPropertyValuePtr value) 1240 RRPropertyValuePtr value)
1241{ 1241{
1242 drmmode_output_private_ptr drmmode_output = output->driver_private; 1242 drmmode_output_private_ptr drmmode_output = output->driver_private;
1243 drmmode_ptr drmmode = drmmode_output->drmmode; 1243 drmmode_ptr drmmode = drmmode_output->drmmode;
1244 int i; 1244 int i;
1245 1245
1246 for (i = 0; i < drmmode_output->num_props; i++) { 1246 for (i = 0; i < drmmode_output->num_props; i++) {
1247 drmmode_prop_ptr p = &drmmode_output->props[i]; 1247 drmmode_prop_ptr p = &drmmode_output->props[i];
1248 1248
1249 if (p->atoms[0] != property) 1249 if (p->atoms[0] != property)
1250 continue; 1250 continue;
1251 1251
1252 if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) { 1252 if (p->mode_prop->flags & DRM_MODE_PROP_RANGE) {
1253 uint32_t val; 1253 uint32_t val;
1254 1254
1255 if (value->type != XA_INTEGER || value->format != 32 || 1255 if (value->type != XA_INTEGER || value->format != 32 ||
1256 value->size != 1) 1256 value->size != 1)
1257 return FALSE; 1257 return FALSE;
1258 val = *(uint32_t *) value->data; 1258 val = *(uint32_t *) value->data;
1259 1259
1260 drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, 1260 drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id,
1261 p->mode_prop->prop_id, (uint64_t) val); 1261 p->mode_prop->prop_id, (uint64_t) val);
1262 return TRUE; 1262 return TRUE;
1263 } 1263 }
1264 else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) { 1264 else if (p->mode_prop->flags & DRM_MODE_PROP_ENUM) {
1265 Atom atom; 1265 Atom atom;
1266 const char *name; 1266 const char *name;
1267 int j; 1267 int j;
1268 1268
1269 if (value->type != XA_ATOM || value->format != 32 || 1269 if (value->type != XA_ATOM || value->format != 32 ||
1270 value->size != 1) 1270 value->size != 1)
1271 return FALSE; 1271 return FALSE;
1272 memcpy(&atom, value->data, 4); 1272 memcpy(&atom, value->data, 4);
1273 name = NameForAtom(atom); 1273 name = NameForAtom(atom);
1274 1274
1275 /* search for matching name string, then set its value down */ 1275 /* search for matching name string, then set its value down */
1276 for (j = 0; j < p->mode_prop->count_enums; j++) { 1276 for (j = 0; j < p->mode_prop->count_enums; j++) {
1277 if (!strcmp(p->mode_prop->enums[j].name, name)) { 1277 if (!strcmp(p->mode_prop->enums[j].name, name)) {
1278 drmModeConnectorSetProperty(drmmode->fd, 1278 drmModeConnectorSetProperty(drmmode->fd,
1279 drmmode_output->output_id, 1279 drmmode_output->output_id,
1280 p->mode_prop->prop_id, 1280 p->mode_prop->prop_id,
1281 p->mode_prop->enums[j].value); 1281 p->mode_prop->enums[j].value);
1282 return TRUE; 1282 return TRUE;
1283 } 1283 }
1284 } 1284 }
1285 } 1285 }
1286 } 1286 }
1287 1287
1288 return TRUE; 1288 return TRUE;
1289} 1289}
1290 1290
1291static Bool 1291static Bool
1292drmmode_output_get_property(xf86OutputPtr output, Atom property) 1292drmmode_output_get_property(xf86OutputPtr output, Atom property)
1293{ 1293{
1294 return TRUE; 1294 return TRUE;
1295} 1295}
1296 1296
1297static const xf86OutputFuncsRec drmmode_output_funcs = { 1297static const xf86OutputFuncsRec drmmode_output_funcs = {
1298 .dpms = drmmode_output_dpms, 1298 .dpms = drmmode_output_dpms,
1299 .create_resources = drmmode_output_create_resources, 1299 .create_resources = drmmode_output_create_resources,
1300 .set_property = drmmode_output_set_property, 1300 .set_property = drmmode_output_set_property,
1301 .get_property = drmmode_output_get_property, 1301 .get_property = drmmode_output_get_property,
1302 .detect = drmmode_output_detect, 1302 .detect = drmmode_output_detect,
1303 .mode_valid = drmmode_output_mode_valid, 1303 .mode_valid = drmmode_output_mode_valid,
1304 1304
1305 .get_modes = drmmode_output_get_modes, 1305 .get_modes = drmmode_output_get_modes,
1306 .destroy = drmmode_output_destroy 1306 .destroy = drmmode_output_destroy
1307}; 1307};
1308 1308
1309static int subpixel_conv_table[7] = { 1309static int subpixel_conv_table[7] = {
1310 0, 1310 0,
1311 SubPixelUnknown, 1311 SubPixelUnknown,
1312 SubPixelHorizontalRGB, 1312 SubPixelHorizontalRGB,
1313 SubPixelHorizontalBGR, 1313 SubPixelHorizontalBGR,
1314 SubPixelVerticalRGB, 1314 SubPixelVerticalRGB,
1315 SubPixelVerticalBGR, 1315 SubPixelVerticalBGR,
1316 SubPixelNone 1316 SubPixelNone
1317}; 1317};
1318 1318
1319static const char *const output_names[] = { 1319static const char *const output_names[] = {
1320 "None", 1320 "None",
1321 "VGA", 1321 "VGA",
1322 "DVI-I", 1322 "DVI-I",
1323 "DVI-D", 1323 "DVI-D",
1324 "DVI-A", 1324 "DVI-A",
1325 "Composite", 1325 "Composite",
1326 "SVIDEO", 1326 "SVIDEO",
1327 "LVDS", 1327 "LVDS",
1328 "Component", 1328 "Component",
1329 "DIN", 1329 "DIN",
1330 "DP", 1330 "DP",
1331 "HDMI", 1331 "HDMI",
1332 "HDMI-B", 1332 "HDMI-B",
1333 "TV", 1333 "TV",
1334 "eDP", 1334 "eDP",
1335 "Virtual", 1335 "Virtual",
1336 "DSI", 1336 "DSI",
1337}; 1337};
1338 1338
1339static xf86OutputPtr find_output(ScrnInfoPtr pScrn, int id) 1339static xf86OutputPtr find_output(ScrnInfoPtr pScrn, int id)
1340{ 1340{
1341 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1341 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1342 int i; 1342 int i;
1343 for (i = 0; i < xf86_config->num_output; i++) { 1343 for (i = 0; i < xf86_config->num_output; i++) {
1344 xf86OutputPtr output = xf86_config->output[i]; 1344 xf86OutputPtr output = xf86_config->output[i];
1345 drmmode_output_private_ptr drmmode_output; 1345 drmmode_output_private_ptr drmmode_output;
1346 1346
1347 drmmode_output = output->driver_private; 1347 drmmode_output = output->driver_private;
1348 if (drmmode_output->output_id == id) 1348 if (drmmode_output->output_id == id)
1349 return output; 1349 return output;
1350 } 1350 }
1351 return NULL; 1351 return NULL;
1352} 1352}
1353 1353
1354static int parse_path_blob(drmModePropertyBlobPtr path_blob, int *conn_base_id, char **path) 1354static int parse_path_blob(drmModePropertyBlobPtr path_blob, int *conn_base_id, char **path)
1355{ 1355{
1356 char *conn; 1356 char *conn;
1357 char conn_id[5]; 1357 char conn_id[5];
1358 int id, len; 1358 int id, len;
1359 char *blob_data; 1359 char *blob_data;
1360 1360
1361 if (!path_blob) 1361 if (!path_blob)
1362 return -1; 1362 return -1;
1363 1363
1364 blob_data = path_blob->data; 1364 blob_data = path_blob->data;
1365 /* we only handle MST paths for now */ 1365 /* we only handle MST paths for now */
1366 if (strncmp(blob_data, "mst:", 4)) 1366 if (strncmp(blob_data, "mst:", 4))
1367 return -1; 1367 return -1;
1368 1368
1369 conn = strchr(blob_data + 4, '-'); 1369 conn = strchr(blob_data + 4, '-');
1370 if (!conn) 1370 if (!conn)
1371 return -1; 1371 return -1;
1372 len = conn - (blob_data + 4); 1372 len = conn - (blob_data + 4);
1373 if (len + 1> 5) 1373 if (len + 1 >= sizeof(conn_id))
1374 return -1; 1374 return -1;
1375 memcpy(conn_id, blob_data + 4, len); 1375 memcpy(conn_id, blob_data + 4, len);
1376 conn_id[len + 1] = '\0'; 1376 conn_id[len + 1] = '\0';
1377 id = strtoul(conn_id, NULL, 10); 1377 id = strtoul(conn_id, NULL, 10);
1378 1378
1379 *conn_base_id = id; 1379 *conn_base_id = id;
1380 1380
1381 *path = conn + 1; 1381 *path = conn + 1;
1382 return 0; 1382 return 0;
1383} 1383}
1384 1384
1385static void 1385static void
1386drmmode_create_name(ScrnInfoPtr pScrn, drmModeConnectorPtr koutput, char *name, 1386drmmode_create_name(ScrnInfoPtr pScrn, drmModeConnectorPtr koutput, char *name,
1387 drmModePropertyBlobPtr path_blob) 1387 drmModePropertyBlobPtr path_blob)
1388{ 1388{
1389 int ret; 1389 int ret;
1390 char *extra_path; 1390 char *extra_path;
1391 int conn_id; 1391 int conn_id;
1392 xf86OutputPtr output; 1392 xf86OutputPtr output;
1393 1393
1394 ret = parse_path_blob(path_blob, &conn_id, &extra_path); 1394 ret = parse_path_blob(path_blob, &conn_id, &extra_path);
1395 if (ret == -1) 1395 if (ret == -1)
1396 goto fallback; 1396 goto fallback;
1397 1397
1398 output = find_output(pScrn, conn_id); 1398 output = find_output(pScrn, conn_id);
1399 if (!output) 1399 if (!output)
1400 goto fallback; 1400 goto fallback;
1401 1401
1402 snprintf(name, 32, "%s-%s", output->name, extra_path); 1402 snprintf(name, 32, "%s-%s", output->name, extra_path);
1403 return; 1403 return;
1404 1404
1405 fallback: 1405 fallback:
1406 if (koutput->connector_type >= MS_ARRAY_SIZE(output_names)) 1406 if (koutput->connector_type >= MS_ARRAY_SIZE(output_names))
1407 snprintf(name, 32, "Unknown%d-%d", koutput->connector_type, koutput->connector_type_id); 1407 snprintf(name, 32, "Unknown%d-%d", koutput->connector_type, koutput->connector_type_id);
1408#ifdef MODESETTING_OUTPUT_SLAVE_SUPPORT 1408#ifdef MODESETTING_OUTPUT_SLAVE_SUPPORT
1409 else if (pScrn->is_gpu) 1409 else if (pScrn->is_gpu)
1410 snprintf(name, 32, "%s-%d-%d", output_names[koutput->connector_type], pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1, koutput->connector_type_id); 1410 snprintf(name, 32, "%s-%d-%d", output_names[koutput->connector_type], pScrn->scrnIndex - GPU_SCREEN_OFFSET + 1, koutput->connector_type_id);
1411#endif 1411#endif
1412 else 1412 else
1413 snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id); 1413 snprintf(name, 32, "%s-%d", output_names[koutput->connector_type], koutput->connector_type_id);
1414} 1414}
1415 1415
1416static unsigned int 1416static unsigned int
1417drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, Bool dynamic, int crtcshift) 1417drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num, Bool dynamic, int crtcshift)
1418{ 1418{
1419 xf86OutputPtr output; 1419 xf86OutputPtr output;
1420 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1420 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1421 drmModeConnectorPtr koutput; 1421 drmModeConnectorPtr koutput;
1422 drmModeEncoderPtr *kencoders = NULL; 1422 drmModeEncoderPtr *kencoders = NULL;
1423 drmmode_output_private_ptr drmmode_output; 1423 drmmode_output_private_ptr drmmode_output;
1424 drmModePropertyPtr props; 1424 drmModePropertyPtr props;
1425 char name[32]; 1425 char name[32];
1426 int i; 1426 int i;
1427 drmModePropertyBlobPtr path_blob = NULL; 1427 drmModePropertyBlobPtr path_blob = NULL;
1428 const char *s; 1428 const char *s;
1429 koutput = 1429 koutput =
1430 drmModeGetConnector(drmmode->fd, mode_res->connectors[num]); 1430 drmModeGetConnector(drmmode->fd, mode_res->connectors[num]);
1431 if (!koutput) 1431 if (!koutput)
1432 return 0; 1432 return 0;
1433 1433
1434 for (i = 0; i < koutput->count_props; i++) { 1434 for (i = 0; i < koutput->count_props; i++) {
1435 props = drmModeGetProperty(drmmode->fd, koutput->props[i]); 1435 props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
1436 if (props && (props->flags & DRM_MODE_PROP_BLOB)) { 1436 if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
1437 if (!strcmp(props->name, "PATH")) { 1437 if (!strcmp(props->name, "PATH")) {
1438 path_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]); 1438 path_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
1439 drmModeFreeProperty(props); 1439 drmModeFreeProperty(props);
1440 break; 1440 break;
1441 } 1441 }
1442 drmModeFreeProperty(props); 1442 drmModeFreeProperty(props);
1443 } 1443 }
1444 } 1444 }
1445 1445
1446 drmmode_create_name(pScrn, koutput, name, path_blob); 1446 drmmode_create_name(pScrn, koutput, name, path_blob);
1447 1447
1448 if (path_blob) 1448 if (path_blob)
1449 drmModeFreePropertyBlob(path_blob); 1449 drmModeFreePropertyBlob(path_blob);
1450 1450
1451 if (path_blob && dynamic) { 1451 if (path_blob && dynamic) {
1452 /* see if we have an output with this name already 1452 /* see if we have an output with this name already
1453 and hook stuff up */ 1453 and hook stuff up */
1454 for (i = 0; i < xf86_config->num_output; i++) { 1454 for (i = 0; i < xf86_config->num_output; i++) {
1455 output = xf86_config->output[i]; 1455 output = xf86_config->output[i];
1456 1456
1457 if (strncmp(output->name, name, 32)) 1457 if (strncmp(output->name, name, 32))
1458 continue; 1458 continue;
1459 1459
1460 drmmode_output = output->driver_private; 1460 drmmode_output = output->driver_private;
1461 drmmode_output->output_id = mode_res->connectors[num]; 1461 drmmode_output->output_id = mode_res->connectors[num];
1462 drmmode_output->mode_output = koutput; 1462 drmmode_output->mode_output = koutput;
1463 return 1; 1463 return 1;
1464 } 1464 }
1465 } 1465 }
1466 1466
1467 kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders); 1467 kencoders = calloc(sizeof(drmModeEncoderPtr), koutput->count_encoders);
1468 if (!kencoders) { 1468 if (!kencoders) {
1469 goto out_free_encoders; 1469 goto out_free_encoders;
1470 } 1470 }
1471 1471
1472 for (i = 0; i < koutput->count_encoders; i++) { 1472 for (i = 0; i < koutput->count_encoders; i++) {
1473 kencoders[i] = drmModeGetEncoder(drmmode->fd, koutput->encoders[i]); 1473 kencoders[i] = drmModeGetEncoder(drmmode->fd, koutput->encoders[i]);
1474 if (!kencoders[i]) { 1474 if (!kencoders[i]) {
1475 goto out_free_encoders; 1475 goto out_free_encoders;
1476 } 1476 }
1477 } 1477 }
1478 1478
1479 if (xf86IsEntityShared(pScrn->entityList[0])) { 1479 if (xf86IsEntityShared(pScrn->entityList[0])) {
1480 if ((s = xf86GetOptValString(drmmode->Options, OPTION_ZAPHOD_HEADS))) { 1480 if ((s = xf86GetOptValString(drmmode->Options, OPTION_ZAPHOD_HEADS))) {
1481 if (!drmmode_zaphod_string_matches(pScrn, s, name)) 1481 if (!drmmode_zaphod_string_matches(pScrn, s, name))
1482 goto out_free_encoders; 1482 goto out_free_encoders;
1483 } else { 1483 } else {
1484 if (!drmmode->is_secondary && (num != 0)) 1484 if (!drmmode->is_secondary && (num != 0))
1485 goto out_free_encoders; 1485 goto out_free_encoders;
1486 else if (drmmode->is_secondary && (num != 1)) 1486 else if (drmmode->is_secondary && (num != 1))
1487 goto out_free_encoders; 1487 goto out_free_encoders;
1488 } 1488 }
1489 } 1489 }
1490 1490
1491 output = xf86OutputCreate(pScrn, &drmmode_output_funcs, name); 1491 output = xf86OutputCreate(pScrn, &drmmode_output_funcs, name);
1492 if (!output) { 1492 if (!output) {
1493 goto out_free_encoders; 1493 goto out_free_encoders;
1494 } 1494 }
1495 1495
1496 drmmode_output = calloc(sizeof(drmmode_output_private_rec), 1); 1496 drmmode_output = calloc(sizeof(drmmode_output_private_rec), 1);
1497 if (!drmmode_output) { 1497 if (!drmmode_output) {
1498 xf86OutputDestroy(output); 1498 xf86OutputDestroy(output);
1499 goto out_free_encoders; 1499 goto out_free_encoders;
1500 } 1500 }
1501 1501
1502 drmmode_output->output_id = mode_res->connectors[num]; 1502 drmmode_output->output_id = mode_res->connectors[num];
1503 drmmode_output->mode_output = koutput; 1503 drmmode_output->mode_output = koutput;
1504 drmmode_output->mode_encoders = kencoders; 1504 drmmode_output->mode_encoders = kencoders;
1505 drmmode_output->drmmode = drmmode; 1505 drmmode_output->drmmode = drmmode;
1506 output->mm_width = koutput->mmWidth; 1506 output->mm_width = koutput->mmWidth;
1507 output->mm_height = koutput->mmHeight; 1507 output->mm_height = koutput->mmHeight;
1508 1508
1509 output->subpixel_order = subpixel_conv_table[koutput->subpixel]; 1509 output->subpixel_order = subpixel_conv_table[koutput->subpixel];
1510 output->interlaceAllowed = TRUE; 1510 output->interlaceAllowed = TRUE;
1511 output->doubleScanAllowed = TRUE; 1511 output->doubleScanAllowed = TRUE;
1512 output->driver_private = drmmode_output; 1512 output->driver_private = drmmode_output;
1513 1513
1514 output->possible_crtcs = 0x7f; 1514 output->possible_crtcs = 0x7f;
1515 for (i = 0; i < koutput->count_encoders; i++) { 1515 for (i = 0; i < koutput->count_encoders; i++) {
1516 output->possible_crtcs &= kencoders[i]->possible_crtcs >> crtcshift; 1516 output->possible_crtcs &= kencoders[i]->possible_crtcs >> crtcshift;
1517 } 1517 }
1518 /* work out the possible clones later */ 1518 /* work out the possible clones later */
1519 output->possible_clones = 0; 1519 output->possible_clones = 0;
1520 1520
1521 for (i = 0; i < koutput->count_props; i++) { 1521 for (i = 0; i < koutput->count_props; i++) {
1522 props = drmModeGetProperty(drmmode->fd, koutput->props[i]); 1522 props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
1523 if (props && (props->flags & DRM_MODE_PROP_ENUM)) { 1523 if (props && (props->flags & DRM_MODE_PROP_ENUM)) {
1524 if (!strcmp(props->name, "DPMS")) { 1524 if (!strcmp(props->name, "DPMS")) {
1525 drmmode_output->dpms_enum_id = koutput->props[i]; 1525 drmmode_output->dpms_enum_id = koutput->props[i];
1526 drmModeFreeProperty(props); 1526 drmModeFreeProperty(props);
1527 break; 1527 break;
1528 } 1528 }
1529 drmModeFreeProperty(props); 1529 drmModeFreeProperty(props);
1530 } 1530 }
1531 } 1531 }
1532 1532
1533 if (dynamic) 1533 if (dynamic)
1534 output->randr_output = RROutputCreate(xf86ScrnToScreen(pScrn), output->name, strlen(output->name), output); 1534 output->randr_output = RROutputCreate(xf86ScrnToScreen(pScrn), output->name, strlen(output->name), output);
1535 return 1; 1535 return 1;
1536 1536
1537 out_free_encoders: 1537 out_free_encoders:
1538 if (kencoders) { 1538 if (kencoders) {
1539 for (i = 0; i < koutput->count_encoders; i++) 1539 for (i = 0; i < koutput->count_encoders; i++)
1540 drmModeFreeEncoder(kencoders[i]); 1540 drmModeFreeEncoder(kencoders[i]);
1541 free(kencoders); 1541 free(kencoders);
1542 } 1542 }
1543 drmModeFreeConnector(koutput); 1543 drmModeFreeConnector(koutput);
1544 1544
1545 return 0; 1545 return 0;
1546} 1546}
1547 1547
1548static uint32_t 1548static uint32_t
1549find_clones(ScrnInfoPtr scrn, xf86OutputPtr output) 1549find_clones(ScrnInfoPtr scrn, xf86OutputPtr output)
1550{ 1550{
1551 drmmode_output_private_ptr drmmode_output = 1551 drmmode_output_private_ptr drmmode_output =
1552 output->driver_private, clone_drmout; 1552 output->driver_private, clone_drmout;
1553 int i; 1553 int i;
1554 xf86OutputPtr clone_output; 1554 xf86OutputPtr clone_output;
1555 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 1555 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
1556 int index_mask = 0; 1556 int index_mask = 0;
1557 1557
1558 if (drmmode_output->enc_clone_mask == 0) 1558 if (drmmode_output->enc_clone_mask == 0)
1559 return index_mask; 1559 return index_mask;
1560 1560
1561 for (i = 0; i < xf86_config->num_output; i++) { 1561 for (i = 0; i < xf86_config->num_output; i++) {
1562 clone_output = xf86_config->output[i]; 1562 clone_output = xf86_config->output[i];
1563 clone_drmout = clone_output->driver_private; 1563 clone_drmout = clone_output->driver_private;
1564 if (output == clone_output) 1564 if (output == clone_output)
1565 continue; 1565 continue;
1566 1566
1567 if (clone_drmout->enc_mask == 0) 1567 if (clone_drmout->enc_mask == 0)
1568 continue; 1568 continue;
1569 if (drmmode_output->enc_clone_mask == clone_drmout->enc_mask) 1569 if (drmmode_output->enc_clone_mask == clone_drmout->enc_mask)
1570 index_mask |= (1 << i); 1570 index_mask |= (1 << i);
1571 } 1571 }
1572 return index_mask; 1572 return index_mask;
1573} 1573}
1574 1574
1575static void 1575static void
1576drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, drmModeResPtr mode_res) 1576drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, drmModeResPtr mode_res)
1577{ 1577{
1578 int i, j; 1578 int i, j;
1579 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 1579 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
1580 1580
1581 for (i = 0; i < xf86_config->num_output; i++) { 1581 for (i = 0; i < xf86_config->num_output; i++) {
1582 xf86OutputPtr output = xf86_config->output[i]; 1582 xf86OutputPtr output = xf86_config->output[i];
1583 drmmode_output_private_ptr drmmode_output; 1583 drmmode_output_private_ptr drmmode_output;
1584 1584
1585 drmmode_output = output->driver_private; 1585 drmmode_output = output->driver_private;
1586 drmmode_output->enc_clone_mask = 0xff; 1586 drmmode_output->enc_clone_mask = 0xff;
1587 /* and all the possible encoder clones for this output together */ 1587 /* and all the possible encoder clones for this output together */
1588 for (j = 0; j < drmmode_output->mode_output->count_encoders; j++) { 1588 for (j = 0; j < drmmode_output->mode_output->count_encoders; j++) {
1589 int k; 1589 int k;
1590 1590
1591 for (k = 0; k < mode_res->count_encoders; k++) { 1591 for (k = 0; k < mode_res->count_encoders; k++) {
1592 if (mode_res->encoders[k] == 1592 if (mode_res->encoders[k] ==
1593 drmmode_output->mode_encoders[j]->encoder_id) 1593 drmmode_output->mode_encoders[j]->encoder_id)
1594 drmmode_output->enc_mask |= (1 << k); 1594 drmmode_output->enc_mask |= (1 << k);
1595 } 1595 }
1596 1596
1597 drmmode_output->enc_clone_mask &= 1597 drmmode_output->enc_clone_mask &=
1598 drmmode_output->mode_encoders[j]->possible_clones; 1598 drmmode_output->mode_encoders[j]->possible_clones;
1599 } 1599 }
1600 } 1600 }
1601 1601
1602 for (i = 0; i < xf86_config->num_output; i++) { 1602 for (i = 0; i < xf86_config->num_output; i++) {
1603 xf86OutputPtr output = xf86_config->output[i]; 1603 xf86OutputPtr output = xf86_config->output[i];
1604 1604
1605 output->possible_clones = find_clones(scrn, output); 1605 output->possible_clones = find_clones(scrn, output);
1606 } 1606 }
1607} 1607}
1608 1608
1609static Bool 1609static Bool
1610drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo) 1610drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo)
1611{ 1611{
1612#ifdef GLAMOR 1612#ifdef GLAMOR
1613 ScrnInfoPtr scrn = drmmode->scrn; 1613 ScrnInfoPtr scrn = drmmode->scrn;
1614 1614
1615 if (!drmmode->glamor) 1615 if (!drmmode->glamor)
1616 return TRUE; 1616 return TRUE;
1617 1617
1618 if (bo == NULL) { 1618 if (bo == NULL) {
1619 glamor_egl_destroy_textured_pixmap(pixmap); 1619 glamor_egl_destroy_textured_pixmap(pixmap);
1620 return TRUE; 1620 return TRUE;
1621 } 1621 }
1622 1622
1623#ifdef GLAMOR_HAS_GBM 1623#ifdef GLAMOR_HAS_GBM
1624 if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->gbm)) { 1624 if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->gbm)) {
1625 xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed"); 1625 xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed");
1626 return FALSE; 1626 return FALSE;
1627 } 1627 }
1628#else 1628#else
1629 if (!glamor_egl_create_textured_pixmap(pixmap, 1629 if (!glamor_egl_create_textured_pixmap(pixmap,
1630 drmmode_bo_get_handle(&drmmode->front_bo), 1630 drmmode_bo_get_handle(&drmmode->front_bo),
1631 scrn->displayWidth * 1631 scrn->displayWidth *
1632 scrn->bitsPerPixel / 8)) { 1632 scrn->bitsPerPixel / 8)) {
1633 xf86DrvMsg(scrn->scrnIndex, X_ERROR, 1633 xf86DrvMsg(scrn->scrnIndex, X_ERROR,
1634 "glamor_egl_create_textured_pixmap() failed\n"); 1634 "glamor_egl_create_textured_pixmap() failed\n");
1635 return FALSE; 1635 return FALSE;
1636 } 1636 }
1637#endif 1637#endif
1638#endif 1638#endif
1639 1639
1640 return TRUE; 1640 return TRUE;
1641} 1641}
1642 1642
1643Bool 1643Bool
1644drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode) 1644drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode)
1645{ 1645{
1646 ScreenPtr screen = xf86ScrnToScreen(drmmode->scrn); 1646 ScreenPtr screen = xf86ScrnToScreen(drmmode->scrn);
1647 PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen); 1647 PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
1648 1648
1649 if (!drmmode_set_pixmap_bo(drmmode, screen_pixmap, &drmmode->front_bo)) 1649 if (!drmmode_set_pixmap_bo(drmmode, screen_pixmap, &drmmode->front_bo))
1650 return FALSE; 1650 return FALSE;
1651 1651
1652#ifdef GLAMOR 1652#ifdef GLAMOR
1653 if (drmmode->glamor) 1653 if (drmmode->glamor)
1654 glamor_set_screen_pixmap(screen_pixmap, NULL); 1654 glamor_set_screen_pixmap(screen_pixmap, NULL);
1655#endif 1655#endif
1656 1656
1657 return TRUE; 1657 return TRUE;
1658} 1658}
1659 1659
1660static Bool 1660static Bool
1661drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height) 1661drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
1662{ 1662{
1663 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); 1663 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
1664 1664
1665 drmmode_crtc_private_ptr 1665 drmmode_crtc_private_ptr
1666 drmmode_crtc = xf86_config->crtc[0]->driver_private; 1666 drmmode_crtc = xf86_config->crtc[0]->driver_private;
1667 drmmode_ptr drmmode = drmmode_crtc->drmmode; 1667 drmmode_ptr drmmode = drmmode_crtc->drmmode;
1668 drmmode_bo old_front; 1668 drmmode_bo old_front;
1669 Bool ret; 1669 Bool ret;
1670 ScreenPtr screen = xf86ScrnToScreen(scrn); 1670 ScreenPtr screen = xf86ScrnToScreen(scrn);
1671 uint32_t old_fb_id; 1671 uint32_t old_fb_id;
1672 int i, pitch, old_width, old_height, old_pitch; 1672 int i, pitch, old_width, old_height, old_pitch;
1673 int cpp = (scrn->bitsPerPixel + 7) / 8; 1673 int cpp = (scrn->bitsPerPixel + 7) / 8;
1674 int kcpp = (drmmode->kbpp + 7) / 8; 1674 int kcpp = (drmmode->kbpp + 7) / 8;
1675 PixmapPtr ppix = screen->GetScreenPixmap(screen); 1675 PixmapPtr ppix = screen->GetScreenPixmap(screen);
1676 void *new_pixels = NULL; 1676 void *new_pixels = NULL;
1677 1677
1678 if (scrn->virtualX == width && scrn->virtualY == height) 1678 if (scrn->virtualX == width && scrn->virtualY == height)
1679 return TRUE; 1679 return TRUE;
1680 1680
1681 xf86DrvMsg(scrn->scrnIndex, X_INFO, 1681 xf86DrvMsg(scrn->scrnIndex, X_INFO,
1682 "Allocate new frame buffer %dx%d stride\n", width, height); 1682 "Allocate new frame buffer %dx%d stride\n", width, height);
1683 1683
1684 if (drmmode->triple_buffer_pixmap) { 1684 if (drmmode->triple_buffer_pixmap) {
1685 screen->DestroyPixmap(drmmode->triple_buffer_pixmap); 1685 screen->DestroyPixmap(drmmode->triple_buffer_pixmap);
1686 drmmode->triple_buffer_pixmap = NULL; 1686 drmmode->triple_buffer_pixmap = NULL;
1687 } 1687 }
1688 1688
1689 old_width = scrn->virtualX; 1689 old_width = scrn->virtualX;
1690 old_height = scrn->virtualY; 1690 old_height = scrn->virtualY;
1691 old_pitch = drmmode_bo_get_pitch(&drmmode->front_bo); 1691 old_pitch = drmmode_bo_get_pitch(&drmmode->front_bo);
1692 old_fb_id = drmmode->fb_id; 1692 old_fb_id = drmmode->fb_id;
1693 old_front = drmmode->front_bo; 1693 old_front = drmmode->front_bo;
1694 1694
1695 if (!drmmode_create_bo(drmmode, &drmmode->front_bo, 1695 if (!drmmode_create_bo(drmmode, &drmmode->front_bo,
1696 width, height, drmmode->kbpp)) 1696 width, height, drmmode->kbpp))
1697 goto fail; 1697 goto fail;
1698 1698
1699 pitch = drmmode_bo_get_pitch(&drmmode->front_bo); 1699 pitch = drmmode_bo_get_pitch(&drmmode->front_bo);
1700 1700
1701 scrn->virtualX = width; 1701 scrn->virtualX = width;
1702 scrn->virtualY = height; 1702 scrn->virtualY = height;
1703 scrn->displayWidth = pitch / kcpp; 1703 scrn->displayWidth = pitch / kcpp;
1704 1704
1705 ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth, 1705 ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
1706 scrn->bitsPerPixel, pitch, 1706 scrn->bitsPerPixel, pitch,
1707 drmmode_bo_get_handle(&drmmode->front_bo), 1707 drmmode_bo_get_handle(&drmmode->front_bo),
1708 &drmmode->fb_id); 1708 &drmmode->fb_id);
1709 if (ret) 1709 if (ret)
1710 goto fail; 1710 goto fail;
1711 1711
1712 if (!drmmode->gbm) { 1712 if (!drmmode->gbm) {
1713 new_pixels = drmmode_map_front_bo(drmmode); 1713 new_pixels = drmmode_map_front_bo(drmmode);
1714 if (!new_pixels) 1714 if (!new_pixels)
1715 goto fail; 1715 goto fail;
1716 } 1716 }
1717 1717
1718 if (drmmode->shadow_enable) { 1718 if (drmmode->shadow_enable) {
1719 uint32_t size = scrn->displayWidth * scrn->virtualY * cpp; 1719 uint32_t size = scrn->displayWidth * scrn->virtualY * cpp;
1720 new_pixels = calloc(1, size); 1720 new_pixels = calloc(1, size);
1721 if (new_pixels == NULL) 1721 if (new_pixels == NULL)
1722 goto fail; 1722 goto fail;
1723 free(drmmode->shadow_fb); 1723 free(drmmode->shadow_fb);
1724 drmmode->shadow_fb = new_pixels; 1724 drmmode->shadow_fb = new_pixels;
1725 } 1725 }
1726 1726
1727 screen->ModifyPixmapHeader(ppix, width, height, -1, -1, 1727 screen->ModifyPixmapHeader(ppix, width, height, -1, -1,
1728 scrn->displayWidth * cpp, new_pixels); 1728 scrn->displayWidth * cpp, new_pixels);
1729 1729
1730 if (!drmmode_glamor_handle_new_screen_pixmap(drmmode)) 1730 if (!drmmode_glamor_handle_new_screen_pixmap(drmmode))
1731 goto fail; 1731 goto fail;
1732 1732
1733 for (i = 0; i < xf86_config->num_crtc; i++) { 1733 for (i = 0; i < xf86_config->num_crtc; i++) {
1734 xf86CrtcPtr crtc = xf86_config->crtc[i]; 1734 xf86CrtcPtr crtc = xf86_config->crtc[i];
1735 1735
1736 if (!crtc->enabled) 1736 if (!crtc->enabled)
1737 continue; 1737 continue;
1738 1738
1739 drmmode_set_mode_major(crtc, &crtc->mode, 1739 drmmode_set_mode_major(crtc, &crtc->mode,
1740 crtc->rotation, crtc->x, crtc->y); 1740 crtc->rotation, crtc->x, crtc->y);
1741 } 1741 }
1742 1742
1743 if (old_fb_id) { 1743 if (old_fb_id) {
1744 drmModeRmFB(drmmode->fd, old_fb_id); 1744 drmModeRmFB(drmmode->fd, old_fb_id);
1745 drmmode_bo_destroy(drmmode, &old_front); 1745 drmmode_bo_destroy(drmmode, &old_front);
1746 } 1746 }
1747 1747
1748 return TRUE; 1748 return TRUE;
1749 1749
1750 fail: 1750 fail:
1751 drmmode_bo_destroy(drmmode, &drmmode->front_bo); 1751 drmmode_bo_destroy(drmmode, &drmmode->front_bo);
1752 drmmode->front_bo = old_front; 1752 drmmode->front_bo = old_front;
1753 scrn->virtualX = old_width; 1753 scrn->virtualX = old_width;
1754 scrn->virtualY = old_height; 1754 scrn->virtualY = old_height;
1755 scrn->displayWidth = old_pitch / kcpp; 1755 scrn->displayWidth = old_pitch / kcpp;
1756 drmmode->fb_id = old_fb_id; 1756 drmmode->fb_id = old_fb_id;
1757 1757
1758 return FALSE; 1758 return FALSE;
1759} 1759}
1760 1760
1761static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = { 1761static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
1762 drmmode_xf86crtc_resize 1762 drmmode_xf86crtc_resize
1763}; 1763};
1764 1764
1765Bool 1765Bool
1766drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp) 1766drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
1767{ 1767{
1768 modesettingEntPtr ms_ent = ms_ent_priv(pScrn); 1768 modesettingEntPtr ms_ent = ms_ent_priv(pScrn);
1769 int i; 1769 int i;
1770 int ret; 1770 int ret;
1771 uint64_t value = 0; 1771 uint64_t value = 0;
1772 unsigned int crtcs_needed = 0; 1772 unsigned int crtcs_needed = 0;
1773 drmModeResPtr mode_res; 1773 drmModeResPtr mode_res;
1774 int crtcshift; 1774 int crtcshift;
1775 1775
1776 /* check for dumb capability */ 1776 /* check for dumb capability */
1777 ret = drmGetCap(drmmode->fd, DRM_CAP_DUMB_BUFFER, &value); 1777 ret = drmGetCap(drmmode->fd, DRM_CAP_DUMB_BUFFER, &value);
1778 if (ret > 0 || value != 1) { 1778 if (ret > 0 || value != 1) {
1779 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1779 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1780 "KMS doesn't support dumb interface\n"); 1780 "KMS doesn't support dumb interface\n");
1781 return FALSE; 1781 return FALSE;
1782 } 1782 }
1783 1783
1784 xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs); 1784 xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
1785 1785
1786 drmmode->scrn = pScrn; 1786 drmmode->scrn = pScrn;
1787 drmmode->cpp = cpp; 1787 drmmode->cpp = cpp;
1788 mode_res = drmModeGetResources(drmmode->fd); 1788 mode_res = drmModeGetResources(drmmode->fd);
1789 if (!mode_res) 1789 if (!mode_res)
1790 return FALSE; 1790 return FALSE;
1791 1791
1792 crtcshift = ffs(ms_ent->assigned_crtcs ^ 0xffffffff) - 1; 1792 crtcshift = ffs(ms_ent->assigned_crtcs ^ 0xffffffff) - 1;
1793 for (i = 0; i < mode_res->count_connectors; i++) 1793 for (i = 0; i < mode_res->count_connectors; i++)
1794 crtcs_needed += drmmode_output_init(pScrn, drmmode, mode_res, i, FALSE, 1794 crtcs_needed += drmmode_output_init(pScrn, drmmode, mode_res, i, FALSE,
1795 crtcshift); 1795 crtcshift);
1796 1796
1797 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG, 1797 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG,
1798 "Up to %d crtcs needed for screen.\n", crtcs_needed); 1798 "Up to %d crtcs needed for screen.\n", crtcs_needed);
1799 1799
1800 xf86CrtcSetSizeRange(pScrn, 320, 200, mode_res->max_width, 1800 xf86CrtcSetSizeRange(pScrn, 320, 200, mode_res->max_width,
1801 mode_res->max_height); 1801 mode_res->max_height);
1802 for (i = 0; i < mode_res->count_crtcs; i++) 1802 for (i = 0; i < mode_res->count_crtcs; i++)
1803 if (!xf86IsEntityShared(pScrn->entityList[0]) || 1803 if (!xf86IsEntityShared(pScrn->entityList[0]) ||
1804 (crtcs_needed && !(ms_ent->assigned_crtcs & (1 << i)))) 1804 (crtcs_needed && !(ms_ent->assigned_crtcs & (1 << i))))
1805 crtcs_needed -= drmmode_crtc_init(pScrn, drmmode, mode_res, i); 1805 crtcs_needed -= drmmode_crtc_init(pScrn, drmmode, mode_res, i);
1806 1806
1807 /* All ZaphodHeads outputs provided with matching crtcs? */ 1807 /* All ZaphodHeads outputs provided with matching crtcs? */
1808 if (xf86IsEntityShared(pScrn->entityList[0]) && (crtcs_needed > 0)) 1808 if (xf86IsEntityShared(pScrn->entityList[0]) && (crtcs_needed > 0))
1809 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 1809 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1810 "%d ZaphodHeads crtcs unavailable. Some outputs will stay off.\n", 1810 "%d ZaphodHeads crtcs unavailable. Some outputs will stay off.\n",
1811 crtcs_needed); 1811 crtcs_needed);
1812 1812
1813 /* workout clones */ 1813 /* workout clones */
1814 drmmode_clones_init(pScrn, drmmode, mode_res); 1814 drmmode_clones_init(pScrn, drmmode, mode_res);
1815 1815
1816 drmModeFreeResources(mode_res); 1816 drmModeFreeResources(mode_res);
1817 xf86ProviderSetup(pScrn, NULL, "modesetting"); 1817 xf86ProviderSetup(pScrn, NULL, "modesetting");
1818 1818
1819 xf86InitialConfiguration(pScrn, TRUE); 1819 xf86InitialConfiguration(pScrn, TRUE);
1820 1820
1821 return TRUE; 1821 return TRUE;
1822} 1822}
1823 1823
1824void 1824void
1825drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y) 1825drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y)
1826{ 1826{
1827 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); 1827 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
1828 xf86OutputPtr output = config->output[config->compat_output]; 1828 xf86OutputPtr output = config->output[config->compat_output];
1829 xf86CrtcPtr crtc = output->crtc; 1829 xf86CrtcPtr crtc = output->crtc;
1830 1830
1831 if (crtc && crtc->enabled) { 1831 if (crtc && crtc->enabled) {
1832 drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, x, y); 1832 drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation, x, y);
1833 } 1833 }
1834} 1834}
1835 1835
1836Bool 1836Bool
1837drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode) 1837drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
1838{ 1838{
1839 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); 1839 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
1840 int c; 1840 int c;
1841 1841
1842 for (c = 0; c < config->num_crtc; c++) { 1842 for (c = 0; c < config->num_crtc; c++) {
1843 xf86CrtcPtr crtc = config->crtc[c]; 1843 xf86CrtcPtr crtc = config->crtc[c];
1844 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 1844 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1845 xf86OutputPtr output = NULL; 1845 xf86OutputPtr output = NULL;
1846 int o; 1846 int o;
1847 1847
1848 /* Skip disabled CRTCs */ 1848 /* Skip disabled CRTCs */
1849 if (!crtc->enabled) { 1849 if (!crtc->enabled) {
1850 drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 1850 drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
1851 0, 0, 0, NULL, 0, NULL); 1851 0, 0, 0, NULL, 0, NULL);
1852 continue; 1852 continue;
1853 } 1853 }
1854 1854
1855 if (config->output[config->compat_output]->crtc == crtc) 1855 if (config->output[config->compat_output]->crtc == crtc)
1856 output = config->output[config->compat_output]; 1856 output = config->output[config->compat_output];
1857 else { 1857 else {
1858 for (o = 0; o < config->num_output; o++) 1858 for (o = 0; o < config->num_output; o++)
1859 if (config->output[o]->crtc == crtc) { 1859 if (config->output[o]->crtc == crtc) {
1860 output = config->output[o]; 1860 output = config->output[o];
1861 break; 1861 break;
1862 } 1862 }
1863 } 1863 }
1864 /* paranoia */ 1864 /* paranoia */
1865 if (!output) 1865 if (!output)
1866 continue; 1866 continue;
1867 1867
1868 /* Mark that we'll need to re-set the mode for sure */ 1868 /* Mark that we'll need to re-set the mode for sure */
1869 memset(&crtc->mode, 0, sizeof(crtc->mode)); 1869 memset(&crtc->mode, 0, sizeof(crtc->mode));
1870 if (!crtc->desiredMode.CrtcHDisplay) { 1870 if (!crtc->desiredMode.CrtcHDisplay) {
1871 DisplayModePtr mode = 1871 DisplayModePtr mode =
1872 xf86OutputFindClosestMode(output, pScrn->currentMode); 1872 xf86OutputFindClosestMode(output, pScrn->currentMode);
1873 1873
1874 if (!mode) 1874 if (!mode)
1875 return FALSE; 1875 return FALSE;
1876 crtc->desiredMode = *mode; 1876 crtc->desiredMode = *mode;
1877 crtc->desiredRotation = RR_Rotate_0; 1877 crtc->desiredRotation = RR_Rotate_0;
1878 crtc->desiredX = 0; 1878 crtc->desiredX = 0;
1879 crtc->desiredY = 0; 1879 crtc->desiredY = 0;
1880 } 1880 }
1881 1881
1882 if (!crtc->funcs-> 1882 if (!crtc->funcs->
1883 set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation, 1883 set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation,
1884 crtc->desiredX, crtc->desiredY)) 1884 crtc->desiredX, crtc->desiredY))
1885 return FALSE; 1885 return FALSE;
1886 } 1886 }
1887 return TRUE; 1887 return TRUE;
1888} 1888}
1889 1889
1890static void 1890static void
1891drmmode_load_palette(ScrnInfoPtr pScrn, int numColors, 1891drmmode_load_palette(ScrnInfoPtr pScrn, int numColors,
1892 int *indices, LOCO * colors, VisualPtr pVisual) 1892 int *indices, LOCO * colors, VisualPtr pVisual)
1893{ 1893{
1894 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 1894 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1895 uint16_t lut_r[256], lut_g[256], lut_b[256]; 1895 uint16_t lut_r[256], lut_g[256], lut_b[256];
1896 int index, j, i; 1896 int index, j, i;
1897 int c; 1897 int c;
1898 1898
1899 for (c = 0; c < xf86_config->num_crtc; c++) { 1899 for (c = 0; c < xf86_config->num_crtc; c++) {
1900 xf86CrtcPtr crtc = xf86_config->crtc[c]; 1900 xf86CrtcPtr crtc = xf86_config->crtc[c];
1901 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 1901 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1902 1902
1903 for (i = 0; i < 256; i++) { 1903 for (i = 0; i < 256; i++) {
1904 lut_r[i] = drmmode_crtc->lut_r[i] << 6; 1904 lut_r[i] = drmmode_crtc->lut_r[i] << 6;
1905 lut_g[i] = drmmode_crtc->lut_g[i] << 6; 1905 lut_g[i] = drmmode_crtc->lut_g[i] << 6;
1906 lut_b[i] = drmmode_crtc->lut_b[i] << 6; 1906 lut_b[i] = drmmode_crtc->lut_b[i] << 6;
1907 } 1907 }
1908 1908
1909 switch (pScrn->depth) { 1909 switch (pScrn->depth) {
1910 case 15: 1910 case 15:
1911 for (i = 0; i < numColors; i++) { 1911 for (i = 0; i < numColors; i++) {
1912 index = indices[i]; 1912 index = indices[i];
1913 for (j = 0; j < 8; j++) { 1913 for (j = 0; j < 8; j++) {
1914 lut_r[index * 8 + j] = colors[index].red << 6; 1914 lut_r[index * 8 + j] = colors[index].red << 6;
1915 lut_g[index * 8 + j] = colors[index].green << 6; 1915 lut_g[index * 8 + j] = colors[index].green << 6;
1916 lut_b[index * 8 + j] = colors[index].blue << 6; 1916 lut_b[index * 8 + j] = colors[index].blue << 6;
1917 } 1917 }
1918 } 1918 }
1919 break; 1919 break;
1920 case 16: 1920 case 16:
1921 for (i = 0; i < numColors; i++) { 1921 for (i = 0; i < numColors; i++) {
1922 index = indices[i]; 1922 index = indices[i];
1923 1923
1924 if (i <= 31) { 1924 if (i <= 31) {
1925 for (j = 0; j < 8; j++) { 1925 for (j = 0; j < 8; j++) {
1926 lut_r[index * 8 + j] = colors[index].red << 6; 1926 lut_r[index * 8 + j] = colors[index].red << 6;
1927 lut_b[index * 8 + j] = colors[index].blue << 6; 1927 lut_b[index * 8 + j] = colors[index].blue << 6;
1928 } 1928 }
1929 } 1929 }
1930 1930
1931 for (j = 0; j < 4; j++) { 1931 for (j = 0; j < 4; j++) {
1932 lut_g[index * 4 + j] = colors[index].green << 6; 1932 lut_g[index * 4 + j] = colors[index].green << 6;
1933 } 1933 }
1934 } 1934 }
1935 break; 1935 break;
1936 default: 1936 default:
1937 for (i = 0; i < numColors; i++) { 1937 for (i = 0; i < numColors; i++) {
1938 index = indices[i]; 1938 index = indices[i];
1939 lut_r[index] = colors[index].red << 6; 1939 lut_r[index] = colors[index].red << 6;
1940 lut_g[index] = colors[index].green << 6; 1940 lut_g[index] = colors[index].green << 6;
1941 lut_b[index] = colors[index].blue << 6; 1941 lut_b[index] = colors[index].blue << 6;
1942 } 1942 }
1943 break; 1943 break;
1944 } 1944 }
1945 1945
1946 /* Make the change through RandR */ 1946 /* Make the change through RandR */
1947 if (crtc->randr_crtc) 1947 if (crtc->randr_crtc)
1948 RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b); 1948 RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
1949 else 1949 else
1950 crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256); 1950 crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
1951 } 1951 }
1952} 1952}
1953 1953
1954Bool 1954Bool
1955drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn) 1955drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn)
1956{ 1956{
1957 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, "Initializing kms color map\n"); 1957 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0, "Initializing kms color map\n");
1958 if (!miCreateDefColormap(pScreen)) 1958 if (!miCreateDefColormap(pScreen))
1959 return FALSE; 1959 return FALSE;
1960 /* all radeons support 10 bit CLUTs */ 1960 /* all radeons support 10 bit CLUTs */
1961 if (!xf86HandleColormaps(pScreen, 256, 10, 1961 if (!xf86HandleColormaps(pScreen, 256, 10,
1962 drmmode_load_palette, NULL, CMAP_PALETTED_TRUECOLOR 1962 drmmode_load_palette, NULL, CMAP_PALETTED_TRUECOLOR
1963#if 0 /* This option messes up text mode! (eich@suse.de) */ 1963#if 0 /* This option messes up text mode! (eich@suse.de) */
1964 | CMAP_LOAD_EVEN_IF_OFFSCREEN 1964 | CMAP_LOAD_EVEN_IF_OFFSCREEN
1965#endif 1965#endif
1966 | CMAP_RELOAD_ON_MODE_SWITCH)) 1966 | CMAP_RELOAD_ON_MODE_SWITCH))
1967 return FALSE; 1967 return FALSE;
1968 return TRUE; 1968 return TRUE;
1969} 1969}
1970 1970
1971#ifdef CONFIG_UDEV_KMS 1971#ifdef CONFIG_UDEV_KMS
1972static void 1972static void
1973drmmode_handle_uevents(int fd, void *closure) 1973drmmode_handle_uevents(int fd, void *closure)
1974{ 1974{
1975 drmmode_ptr drmmode = closure; 1975 drmmode_ptr drmmode = closure;
1976 ScrnInfoPtr scrn = drmmode->scrn; 1976 ScrnInfoPtr scrn = drmmode->scrn;
1977 struct udev_device *dev; 1977 struct udev_device *dev;
1978 drmModeResPtr mode_res; 1978 drmModeResPtr mode_res;
1979 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); 1979 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
1980 int i, j; 1980 int i, j;
1981 Bool found; 1981 Bool found;
1982 Bool changed = FALSE; 1982 Bool changed = FALSE;
1983 1983
1984 dev = udev_monitor_receive_device(drmmode->uevent_monitor); 1984 dev = udev_monitor_receive_device(drmmode->uevent_monitor);
1985 if (!dev) 1985 if (!dev)
1986 return; 1986 return;
1987 1987
1988 mode_res = drmModeGetResources(drmmode->fd); 1988 mode_res = drmModeGetResources(drmmode->fd);
1989 if (!mode_res) 1989 if (!mode_res)
1990 goto out; 1990 goto out;
1991 1991
1992 if (mode_res->count_crtcs != config->num_crtc) { 1992 if (mode_res->count_crtcs != config->num_crtc) {
1993 ErrorF("number of CRTCs changed - failed to handle, %d vs %d\n", mode_res->count_crtcs, config->num_crtc); 1993 ErrorF("number of CRTCs changed - failed to handle, %d vs %d\n", mode_res->count_crtcs, config->num_crtc);
1994 goto out_free_res; 1994 goto out_free_res;
1995 } 1995 }
1996 1996
1997 /* figure out if we have gotten rid of any connectors 1997 /* figure out if we have gotten rid of any connectors
1998 traverse old output list looking for outputs */ 1998 traverse old output list looking for outputs */
1999 for (i = 0; i < config->num_output; i++) { 1999 for (i = 0; i < config->num_output; i++) {
2000 xf86OutputPtr output = config->output[i]; 2000 xf86OutputPtr output = config->output[i];
2001 drmmode_output_private_ptr drmmode_output; 2001 drmmode_output_private_ptr drmmode_output;
2002 2002
2003 drmmode_output = output->driver_private; 2003 drmmode_output = output->driver_private;
2004 found = FALSE; 2004 found = FALSE;
2005 for (j = 0; j < mode_res->count_connectors; j++) { 2005 for (j = 0; j < mode_res->count_connectors; j++) {
2006 if (mode_res->connectors[j] == drmmode_output->output_id) { 2006 if (mode_res->connectors[j] == drmmode_output->output_id) {
2007 found = TRUE; 2007 found = TRUE;
2008 break; 2008 break;
2009 } 2009 }
2010 } 2010 }
2011 if (found) 2011 if (found)
2012 continue; 2012 continue;
2013 2013
2014 drmModeFreeConnector(drmmode_output->mode_output); 2014 drmModeFreeConnector(drmmode_output->mode_output);
2015 drmmode_output->mode_output = NULL; 2015 drmmode_output->mode_output = NULL;
2016 drmmode_output->output_id = -1; 2016 drmmode_output->output_id = -1;
2017 2017
2018 changed = TRUE; 2018 changed = TRUE;
2019 } 2019 }
2020 2020
2021 /* find new output ids we don't have outputs for */ 2021 /* find new output ids we don't have outputs for */
2022 for (i = 0; i < mode_res->count_connectors; i++) { 2022 for (i = 0; i < mode_res->count_connectors; i++) {
2023 found = FALSE; 2023 found = FALSE;
2024 2024
2025 for (j = 0; j < config->num_output; j++) { 2025 for (j = 0; j < config->num_output; j++) {
2026 xf86OutputPtr output = config->output[j]; 2026 xf86OutputPtr output = config->output[j];
2027 drmmode_output_private_ptr drmmode_output; 2027 drmmode_output_private_ptr drmmode_output;
2028 2028
2029 drmmode_output = output->driver_private; 2029 drmmode_output = output->driver_private;
2030 if (mode_res->connectors[i] == drmmode_output->output_id) { 2030 if (mode_res->connectors[i] == drmmode_output->output_id) {
2031 found = TRUE; 2031 found = TRUE;
2032 break; 2032 break;
2033 } 2033 }
2034 } 2034 }
2035 if (found) 2035 if (found)
2036 continue; 2036 continue;
2037 2037
2038 changed = TRUE; 2038 changed = TRUE;
2039 drmmode_output_init(scrn, drmmode, mode_res, i, TRUE, 0); 2039 drmmode_output_init(scrn, drmmode, mode_res, i, TRUE, 0);
2040 } 2040 }
2041 2041
2042 if (changed) { 2042 if (changed) {
2043 RRSetChanged(xf86ScrnToScreen(scrn)); 2043 RRSetChanged(xf86ScrnToScreen(scrn));
2044 RRTellChanged(xf86ScrnToScreen(scrn)); 2044 RRTellChanged(xf86ScrnToScreen(scrn));
2045 } 2045 }
2046 2046
2047out_free_res: 2047out_free_res:
2048 drmModeFreeResources(mode_res); 2048 drmModeFreeResources(mode_res);
2049out: 2049out:
2050 RRGetInfo(xf86ScrnToScreen(scrn), TRUE); 2050 RRGetInfo(xf86ScrnToScreen(scrn), TRUE);
2051 udev_device_unref(dev); 2051 udev_device_unref(dev);
2052} 2052}
2053#endif 2053#endif
2054 2054
2055void 2055void
2056drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode) 2056drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
2057{ 2057{
2058#ifdef CONFIG_UDEV_KMS 2058#ifdef CONFIG_UDEV_KMS
2059 struct udev *u; 2059 struct udev *u;
2060 struct udev_monitor *mon; 2060 struct udev_monitor *mon;
2061 2061
2062 u = udev_new(); 2062 u = udev_new();
2063 if (!u) 2063 if (!u)
2064 return; 2064 return;
2065 mon = udev_monitor_new_from_netlink(u, "udev"); 2065 mon = udev_monitor_new_from_netlink(u, "udev");
2066 if (!mon) { 2066 if (!mon) {
2067 udev_unref(u); 2067 udev_unref(u);
2068 return; 2068 return;
2069 } 2069 }
2070 2070
2071 if (udev_monitor_filter_add_match_subsystem_devtype(mon, 2071 if (udev_monitor_filter_add_match_subsystem_devtype(mon,
2072 "drm", 2072 "drm",
2073 "drm_minor") < 0 || 2073 "drm_minor") < 0 ||
2074 udev_monitor_enable_receiving(mon) < 0) { 2074 udev_monitor_enable_receiving(mon) < 0) {
2075 udev_monitor_unref(mon); 2075 udev_monitor_unref(mon);
2076 udev_unref(u); 2076 udev_unref(u);
2077 return; 2077 return;
2078 } 2078 }
2079 2079
2080 drmmode->uevent_handler = 2080 drmmode->uevent_handler =
2081 xf86AddGeneralHandler(udev_monitor_get_fd(mon), 2081 xf86AddGeneralHandler(udev_monitor_get_fd(mon),
2082 drmmode_handle_uevents, drmmode); 2082 drmmode_handle_uevents, drmmode);
2083 2083
2084 drmmode->uevent_monitor = mon; 2084 drmmode->uevent_monitor = mon;
2085#endif 2085#endif
2086} 2086}
2087 2087
2088void 2088void
2089drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode) 2089drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode)
2090{ 2090{
2091#ifdef CONFIG_UDEV_KMS 2091#ifdef CONFIG_UDEV_KMS
2092 if (drmmode->uevent_handler) { 2092 if (drmmode->uevent_handler) {
2093 struct udev *u = udev_monitor_get_udev(drmmode->uevent_monitor); 2093 struct udev *u = udev_monitor_get_udev(drmmode->uevent_monitor);
2094 2094
2095 xf86RemoveGeneralHandler(drmmode->uevent_handler); 2095 xf86RemoveGeneralHandler(drmmode->uevent_handler);
2096 2096
2097 udev_monitor_unref(drmmode->uevent_monitor); 2097 udev_monitor_unref(drmmode->uevent_monitor);
2098 udev_unref(u); 2098 udev_unref(u);
2099 } 2099 }
2100#endif 2100#endif
2101} 2101}
2102 2102
2103/* create front and cursor BOs */ 2103/* create front and cursor BOs */
2104Bool 2104Bool
2105drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode) 2105drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
2106{ 2106{
2107 modesettingPtr ms = modesettingPTR(pScrn); 2107 modesettingPtr ms = modesettingPTR(pScrn);
2108 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2108 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2109 int width; 2109 int width;
2110 int height; 2110 int height;
2111 int bpp = ms->drmmode.kbpp; 2111 int bpp = ms->drmmode.kbpp;
2112 int i; 2112 int i;
2113 int cpp = (bpp + 7) / 8; 2113 int cpp = (bpp + 7) / 8;
2114 2114
2115 width = pScrn->virtualX; 2115 width = pScrn->virtualX;
2116 height = pScrn->virtualY; 2116 height = pScrn->virtualY;
2117 2117
2118 if (!drmmode_create_bo(drmmode, &drmmode->front_bo, width, height, bpp)) 2118 if (!drmmode_create_bo(drmmode, &drmmode->front_bo, width, height, bpp))
2119 return FALSE; 2119 return FALSE;
2120 pScrn->displayWidth = drmmode_bo_get_pitch(&drmmode->front_bo) / cpp; 2120 pScrn->displayWidth = drmmode_bo_get_pitch(&drmmode->front_bo) / cpp;
2121 2121
2122 width = ms->cursor_width; 2122 width = ms->cursor_width;
2123 height = ms->cursor_height; 2123 height = ms->cursor_height;
2124 bpp = 32; 2124 bpp = 32;
2125 for (i = 0; i < xf86_config->num_crtc; i++) { 2125 for (i = 0; i < xf86_config->num_crtc; i++) {
2126 xf86CrtcPtr crtc = xf86_config->crtc[i]; 2126 xf86CrtcPtr crtc = xf86_config->crtc[i];
2127 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 2127 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
2128 2128
2129 drmmode_crtc->cursor_bo = 2129 drmmode_crtc->cursor_bo =
2130 dumb_bo_create(drmmode->fd, width, height, bpp); 2130 dumb_bo_create(drmmode->fd, width, height, bpp);
2131 } 2131 }
2132 return TRUE; 2132 return TRUE;
2133} 2133}
2134 2134
2135void * 2135void *
2136drmmode_map_front_bo(drmmode_ptr drmmode) 2136drmmode_map_front_bo(drmmode_ptr drmmode)
2137{ 2137{
2138 return drmmode_bo_map(drmmode, &drmmode->front_bo); 2138 return drmmode_bo_map(drmmode, &drmmode->front_bo);
2139} 2139}
2140 2140
2141void * 2141void *
2142drmmode_map_slave_bo(drmmode_ptr drmmode, msPixmapPrivPtr ppriv) 2142drmmode_map_slave_bo(drmmode_ptr drmmode, msPixmapPrivPtr ppriv)
2143{ 2143{
2144 int ret; 2144 int ret;
2145 2145
2146 if (ppriv->backing_bo->ptr) 2146 if (ppriv->backing_bo->ptr)
2147 return ppriv->backing_bo->ptr; 2147 return ppriv->backing_bo->ptr;
2148 2148
2149 ret = dumb_bo_map(drmmode->fd, ppriv->backing_bo); 2149 ret = dumb_bo_map(drmmode->fd, ppriv->backing_bo);
2150 if (ret) 2150 if (ret)
2151 return NULL; 2151 return NULL;
2152 2152
2153 return ppriv->backing_bo->ptr; 2153 return ppriv->backing_bo->ptr;
2154} 2154}
2155 2155
2156Bool 2156Bool
2157drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode) 2157drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
2158{ 2158{
2159 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2159 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2160 int i, ret; 2160 int i, ret;
2161 2161
2162 for (i = 0; i < xf86_config->num_crtc; i++) { 2162 for (i = 0; i < xf86_config->num_crtc; i++) {
2163 xf86CrtcPtr crtc = xf86_config->crtc[i]; 2163 xf86CrtcPtr crtc = xf86_config->crtc[i];
2164 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 2164 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
2165 2165
2166 ret = dumb_bo_map(drmmode->fd, drmmode_crtc->cursor_bo); 2166 ret = dumb_bo_map(drmmode->fd, drmmode_crtc->cursor_bo);
2167 if (ret) 2167 if (ret)
2168 return FALSE; 2168 return FALSE;
2169 } 2169 }
2170 return TRUE; 2170 return TRUE;
2171} 2171}
2172 2172
2173void 2173void
2174drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode) 2174drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
2175{ 2175{
2176 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 2176 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2177 int i; 2177 int i;
2178 2178
2179 if (drmmode->fb_id) { 2179 if (drmmode->fb_id) {
2180 drmModeRmFB(drmmode->fd, drmmode->fb_id); 2180 drmModeRmFB(drmmode->fd, drmmode->fb_id);
2181 drmmode->fb_id = 0; 2181 drmmode->fb_id = 0;
2182 } 2182 }
2183 2183
2184 drmmode_bo_destroy(drmmode, &drmmode->front_bo); 2184 drmmode_bo_destroy(drmmode, &drmmode->front_bo);
2185 2185
2186 for (i = 0; i < xf86_config->num_crtc; i++) { 2186 for (i = 0; i < xf86_config->num_crtc; i++) {
2187 xf86CrtcPtr crtc = xf86_config->crtc[i]; 2187 xf86CrtcPtr crtc = xf86_config->crtc[i];
2188 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; 2188 drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
2189 2189
2190 dumb_bo_destroy(drmmode->fd, drmmode_crtc->cursor_bo); 2190 dumb_bo_destroy(drmmode->fd, drmmode_crtc->cursor_bo);
2191 } 2191 }
2192} 2192}
2193 2193
2194/* ugly workaround to see if we can create 32bpp */ 2194/* ugly workaround to see if we can create 32bpp */
2195void 2195void
2196drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int *depth, 2196drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int *depth,
2197 int *bpp) 2197 int *bpp)
2198{ 2198{
2199 drmModeResPtr mode_res; 2199 drmModeResPtr mode_res;
2200 uint64_t value; 2200 uint64_t value;
2201 struct dumb_bo *bo; 2201 struct dumb_bo *bo;
2202 uint32_t fb_id; 2202 uint32_t fb_id;
2203 int ret; 2203 int ret;
2204 2204
2205 /* 16 is fine */ 2205 /* 16 is fine */
2206 ret = drmGetCap(drmmode->fd, DRM_CAP_DUMB_PREFERRED_DEPTH, &value); 2206 ret = drmGetCap(drmmode->fd, DRM_CAP_DUMB_PREFERRED_DEPTH, &value);
2207 if (!ret && (value == 16 || value == 8)) { 2207 if (!ret && (value == 16 || value == 8)) {
2208 *depth = value; 2208 *depth = value;
2209 *bpp = value; 2209 *bpp = value;
2210 return; 2210 return;
2211 } 2211 }
2212 2212
2213 *depth = 24; 2213 *depth = 24;
2214 mode_res = drmModeGetResources(drmmode->fd); 2214 mode_res = drmModeGetResources(drmmode->fd);
2215 if (!mode_res) 2215 if (!mode_res)
2216 return; 2216 return;
2217 2217
2218 if (mode_res->min_width == 0) 2218 if (mode_res->min_width == 0)
2219 mode_res->min_width = 1; 2219 mode_res->min_width = 1;
2220 if (mode_res->min_height == 0) 2220 if (mode_res->min_height == 0)
2221 mode_res->min_height = 1; 2221 mode_res->min_height = 1;
2222 /*create a bo */ 2222 /*create a bo */
2223 bo = dumb_bo_create(drmmode->fd, mode_res->min_width, mode_res->min_height, 2223 bo = dumb_bo_create(drmmode->fd, mode_res->min_width, mode_res->min_height,
2224 32); 2224 32);
2225 if (!bo) { 2225 if (!bo) {
2226 *bpp = 24; 2226 *bpp = 24;
2227 goto out; 2227 goto out;
2228 } 2228 }
2229 2229
2230 ret = drmModeAddFB(drmmode->fd, mode_res->min_width, mode_res->min_height, 2230 ret = drmModeAddFB(drmmode->fd, mode_res->min_width, mode_res->min_height,
2231 24, 32, bo->pitch, bo->handle, &fb_id); 2231 24, 32, bo->pitch, bo->handle, &fb_id);
2232 2232
2233 if (ret) { 2233 if (ret) {
2234 *bpp = 24; 2234 *bpp = 24;
2235 dumb_bo_destroy(drmmode->fd, bo); 2235 dumb_bo_destroy(drmmode->fd, bo);
2236 goto out; 2236 goto out;
2237 } 2237 }
2238 2238
2239 drmModeRmFB(drmmode->fd, fb_id); 2239 drmModeRmFB(drmmode->fd, fb_id);
2240 *bpp = 32; 2240 *bpp = 32;
2241 2241
2242 dumb_bo_destroy(drmmode->fd, bo); 2242 dumb_bo_destroy(drmmode->fd, bo);
2243 out: 2243 out:
2244 drmModeFreeResources(mode_res); 2244 drmModeFreeResources(mode_res);
2245 return; 2245 return;
2246} 2246}