diff options
author | Sinclair Yeh <syeh@vmware.com> | 2017-03-23 17:29:22 -0400 |
---|---|---|
committer | Sinclair Yeh <syeh@vmware.com> | 2017-03-31 18:21:12 -0400 |
commit | 904bb5e5817f5c5b42e6e3775699c728fd420284 (patch) | |
tree | 57628b2490c84b9ef8c2f25cd5d926aff9e73e68 | |
parent | aa74f0687cfe998e59b20d6454f45e8aa4403c45 (diff) |
drm/vmwgfx: Switch over to internal atomic API for STDU
Switch over to using internal atomic API for mode set.
This removes the legacy set_config API, replacing it with
drm_atomic_helper_set_config(). The DRM helper will use various
vmwgfx-specific atomic functions to set a mode.
DRIVER_ATOMIC capability flag is not yet set, so the user mode
will still use the legacy mode set IOCTL.
v2:
* Avoid a clash between page-flip pinning and setcrtc pinning, modify
the page-flip code to use the page-flip helper and the atomic callbacks.
To enable this, we will need to add a wrapper around atomic_commit.
* Add vmw_kms_set_config() to work around vmwgfx xorg driver bug
Signed-off-by: Sinclair Yeh <syeh@vmware.com>
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 325 |
3 files changed, 51 insertions, 295 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 1071e1075da8..fe226e723287 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -2885,3 +2885,23 @@ vmw_kms_create_implicit_placement_property(struct vmw_private *dev_priv, | |||
2885 | "implicit_placement", 0, 1); | 2885 | "implicit_placement", 0, 1); |
2886 | 2886 | ||
2887 | } | 2887 | } |
2888 | |||
2889 | |||
2890 | /** | ||
2891 | * vmw_kms_set_config - Wrapper around drm_atomic_helper_set_config | ||
2892 | * | ||
2893 | * @set: The configuration to set. | ||
2894 | * | ||
2895 | * The vmwgfx Xorg driver doesn't assign the mode::type member, which | ||
2896 | * when drm_mode_set_crtcinfo is called as part of the configuration setting | ||
2897 | * causes it to return incorrect crtc dimensions causing severe problems in | ||
2898 | * the vmwgfx modesetting. So explicitly clear that member before calling | ||
2899 | * into drm_atomic_helper_set_config. | ||
2900 | */ | ||
2901 | int vmw_kms_set_config(struct drm_mode_set *set) | ||
2902 | { | ||
2903 | if (set && set->mode) | ||
2904 | set->mode->type = 0; | ||
2905 | |||
2906 | return drm_atomic_helper_set_config(set); | ||
2907 | } | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index de6a0b64bb4b..7689f477b726 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | |||
@@ -449,5 +449,6 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv, | |||
449 | bool to_surface, | 449 | bool to_surface, |
450 | bool interruptible); | 450 | bool interruptible); |
451 | 451 | ||
452 | int vmw_kms_set_config(struct drm_mode_set *set); | ||
452 | 453 | ||
453 | #endif | 454 | #endif |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index 76ca5fa1e3bf..b7999eb4f5fc 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | |||
@@ -104,8 +104,7 @@ struct vmw_stdu_surface_copy { | |||
104 | */ | 104 | */ |
105 | struct vmw_screen_target_display_unit { | 105 | struct vmw_screen_target_display_unit { |
106 | struct vmw_display_unit base; | 106 | struct vmw_display_unit base; |
107 | 107 | const struct vmw_surface *display_srf; | |
108 | struct vmw_surface *display_srf; | ||
109 | enum stdu_content_type content_fb_type; | 108 | enum stdu_content_type content_fb_type; |
110 | 109 | ||
111 | bool defined; | 110 | bool defined; |
@@ -118,32 +117,6 @@ static void vmw_stdu_destroy(struct vmw_screen_target_display_unit *stdu); | |||
118 | 117 | ||
119 | 118 | ||
120 | /****************************************************************************** | 119 | /****************************************************************************** |
121 | * Screen Target Display Unit helper Functions | ||
122 | *****************************************************************************/ | ||
123 | |||
124 | /** | ||
125 | * vmw_stdu_unpin_display - unpins the resource associated with display surface | ||
126 | * | ||
127 | * @stdu: contains the display surface | ||
128 | * | ||
129 | * If the display surface was privatedly allocated by | ||
130 | * vmw_surface_gb_priv_define() and not registered as a framebuffer, then it | ||
131 | * won't be automatically cleaned up when all the framebuffers are freed. As | ||
132 | * such, we have to explicitly call vmw_resource_unreference() to get it freed. | ||
133 | */ | ||
134 | static void vmw_stdu_unpin_display(struct vmw_screen_target_display_unit *stdu) | ||
135 | { | ||
136 | if (stdu->display_srf) { | ||
137 | struct vmw_resource *res = &stdu->display_srf->res; | ||
138 | |||
139 | vmw_resource_unpin(res); | ||
140 | vmw_surface_unreference(&stdu->display_srf); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | |||
145 | |||
146 | /****************************************************************************** | ||
147 | * Screen Target Display Unit CRTC Functions | 120 | * Screen Target Display Unit CRTC Functions |
148 | *****************************************************************************/ | 121 | *****************************************************************************/ |
149 | 122 | ||
@@ -228,7 +201,7 @@ static int vmw_stdu_define_st(struct vmw_private *dev_priv, | |||
228 | */ | 201 | */ |
229 | static int vmw_stdu_bind_st(struct vmw_private *dev_priv, | 202 | static int vmw_stdu_bind_st(struct vmw_private *dev_priv, |
230 | struct vmw_screen_target_display_unit *stdu, | 203 | struct vmw_screen_target_display_unit *stdu, |
231 | struct vmw_resource *res) | 204 | const struct vmw_resource *res) |
232 | { | 205 | { |
233 | SVGA3dSurfaceImageId image; | 206 | SVGA3dSurfaceImageId image; |
234 | 207 | ||
@@ -377,129 +350,6 @@ static int vmw_stdu_destroy_st(struct vmw_private *dev_priv, | |||
377 | return ret; | 350 | return ret; |
378 | } | 351 | } |
379 | 352 | ||
380 | /** | ||
381 | * vmw_stdu_bind_fb - Bind an fb to a defined screen target | ||
382 | * | ||
383 | * @dev_priv: Pointer to a device private struct. | ||
384 | * @crtc: The crtc holding the screen target. | ||
385 | * @mode: The mode currently used by the screen target. Must be non-NULL. | ||
386 | * @new_fb: The new framebuffer to bind. Must be non-NULL. | ||
387 | * | ||
388 | * RETURNS: | ||
389 | * 0 on success, error code on failure. | ||
390 | */ | ||
391 | static int vmw_stdu_bind_fb(struct vmw_private *dev_priv, | ||
392 | struct drm_crtc *crtc, | ||
393 | struct drm_display_mode *mode, | ||
394 | struct drm_framebuffer *new_fb) | ||
395 | { | ||
396 | struct vmw_screen_target_display_unit *stdu = vmw_crtc_to_stdu(crtc); | ||
397 | struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(new_fb); | ||
398 | struct vmw_surface *new_display_srf = NULL; | ||
399 | enum stdu_content_type new_content_type; | ||
400 | struct vmw_framebuffer_surface *new_vfbs; | ||
401 | int ret; | ||
402 | |||
403 | WARN_ON_ONCE(!stdu->defined); | ||
404 | |||
405 | new_vfbs = (vfb->dmabuf) ? NULL : vmw_framebuffer_to_vfbs(new_fb); | ||
406 | |||
407 | if (new_vfbs && new_vfbs->surface->base_size.width == mode->hdisplay && | ||
408 | new_vfbs->surface->base_size.height == mode->vdisplay) | ||
409 | new_content_type = SAME_AS_DISPLAY; | ||
410 | else if (vfb->dmabuf) | ||
411 | new_content_type = SEPARATE_DMA; | ||
412 | else | ||
413 | new_content_type = SEPARATE_SURFACE; | ||
414 | |||
415 | if (new_content_type != SAME_AS_DISPLAY && | ||
416 | !stdu->display_srf) { | ||
417 | struct vmw_surface content_srf; | ||
418 | struct drm_vmw_size display_base_size = {0}; | ||
419 | |||
420 | display_base_size.width = mode->hdisplay; | ||
421 | display_base_size.height = mode->vdisplay; | ||
422 | display_base_size.depth = 1; | ||
423 | |||
424 | /* | ||
425 | * If content buffer is a DMA buf, then we have to construct | ||
426 | * surface info | ||
427 | */ | ||
428 | if (new_content_type == SEPARATE_DMA) { | ||
429 | |||
430 | switch (new_fb->format->cpp[0] * 8) { | ||
431 | case 32: | ||
432 | content_srf.format = SVGA3D_X8R8G8B8; | ||
433 | break; | ||
434 | |||
435 | case 16: | ||
436 | content_srf.format = SVGA3D_R5G6B5; | ||
437 | break; | ||
438 | |||
439 | case 8: | ||
440 | content_srf.format = SVGA3D_P8; | ||
441 | break; | ||
442 | |||
443 | default: | ||
444 | DRM_ERROR("Invalid format\n"); | ||
445 | return -EINVAL; | ||
446 | } | ||
447 | |||
448 | content_srf.flags = 0; | ||
449 | content_srf.mip_levels[0] = 1; | ||
450 | content_srf.multisample_count = 0; | ||
451 | } else { | ||
452 | content_srf = *new_vfbs->surface; | ||
453 | } | ||
454 | |||
455 | |||
456 | ret = vmw_surface_gb_priv_define(crtc->dev, | ||
457 | 0, /* because kernel visible only */ | ||
458 | content_srf.flags, | ||
459 | content_srf.format, | ||
460 | true, /* a scanout buffer */ | ||
461 | content_srf.mip_levels[0], | ||
462 | content_srf.multisample_count, | ||
463 | 0, | ||
464 | display_base_size, | ||
465 | &new_display_srf); | ||
466 | if (unlikely(ret != 0)) { | ||
467 | DRM_ERROR("Could not allocate screen target surface.\n"); | ||
468 | return ret; | ||
469 | } | ||
470 | } else if (new_content_type == SAME_AS_DISPLAY) { | ||
471 | new_display_srf = vmw_surface_reference(new_vfbs->surface); | ||
472 | } | ||
473 | |||
474 | if (new_display_srf) { | ||
475 | /* Pin new surface before flipping */ | ||
476 | ret = vmw_resource_pin(&new_display_srf->res, false); | ||
477 | if (ret) | ||
478 | goto out_srf_unref; | ||
479 | |||
480 | ret = vmw_stdu_bind_st(dev_priv, stdu, &new_display_srf->res); | ||
481 | if (ret) | ||
482 | goto out_srf_unpin; | ||
483 | |||
484 | /* Unpin and unreference old surface */ | ||
485 | vmw_stdu_unpin_display(stdu); | ||
486 | |||
487 | /* Transfer the reference */ | ||
488 | stdu->display_srf = new_display_srf; | ||
489 | new_display_srf = NULL; | ||
490 | } | ||
491 | |||
492 | crtc->primary->fb = new_fb; | ||
493 | stdu->content_fb_type = new_content_type; | ||
494 | return 0; | ||
495 | |||
496 | out_srf_unpin: | ||
497 | vmw_resource_unpin(&new_display_srf->res); | ||
498 | out_srf_unref: | ||
499 | vmw_surface_unreference(&new_display_srf); | ||
500 | return ret; | ||
501 | } | ||
502 | |||
503 | 353 | ||
504 | /** | 354 | /** |
505 | * vmw_stdu_crtc_mode_set_nofb - Updates screen target size | 355 | * vmw_stdu_crtc_mode_set_nofb - Updates screen target size |
@@ -601,136 +451,6 @@ static void vmw_stdu_crtc_helper_disable(struct drm_crtc *crtc) | |||
601 | } | 451 | } |
602 | 452 | ||
603 | /** | 453 | /** |
604 | * vmw_stdu_crtc_set_config - Sets a mode | ||
605 | * | ||
606 | * @set: mode parameters | ||
607 | * | ||
608 | * This function is the device-specific portion of the DRM CRTC mode set. | ||
609 | * For the SVGA device, we do this by defining a Screen Target, binding a | ||
610 | * GB Surface to that target, and finally update the screen target. | ||
611 | * | ||
612 | * RETURNS: | ||
613 | * 0 on success, error code otherwise | ||
614 | */ | ||
615 | static int vmw_stdu_crtc_set_config(struct drm_mode_set *set) | ||
616 | { | ||
617 | struct vmw_private *dev_priv; | ||
618 | struct vmw_framebuffer *vfb; | ||
619 | struct vmw_screen_target_display_unit *stdu; | ||
620 | struct drm_display_mode *mode; | ||
621 | struct drm_framebuffer *new_fb; | ||
622 | struct drm_crtc *crtc; | ||
623 | struct drm_encoder *encoder; | ||
624 | struct drm_connector *connector; | ||
625 | bool turning_off; | ||
626 | int ret; | ||
627 | |||
628 | |||
629 | if (!set || !set->crtc) | ||
630 | return -EINVAL; | ||
631 | |||
632 | crtc = set->crtc; | ||
633 | stdu = vmw_crtc_to_stdu(crtc); | ||
634 | mode = set->mode; | ||
635 | new_fb = set->fb; | ||
636 | dev_priv = vmw_priv(crtc->dev); | ||
637 | turning_off = set->num_connectors == 0 || !mode || !new_fb; | ||
638 | vfb = (new_fb) ? vmw_framebuffer_to_vfb(new_fb) : NULL; | ||
639 | |||
640 | if (set->num_connectors > 1) { | ||
641 | DRM_ERROR("Too many connectors\n"); | ||
642 | return -EINVAL; | ||
643 | } | ||
644 | |||
645 | if (set->num_connectors == 1 && | ||
646 | set->connectors[0] != &stdu->base.connector) { | ||
647 | DRM_ERROR("Connectors don't match %p %p\n", | ||
648 | set->connectors[0], &stdu->base.connector); | ||
649 | return -EINVAL; | ||
650 | } | ||
651 | |||
652 | if (!turning_off && (set->x + mode->hdisplay > new_fb->width || | ||
653 | set->y + mode->vdisplay > new_fb->height)) { | ||
654 | DRM_ERROR("Set outside of framebuffer\n"); | ||
655 | return -EINVAL; | ||
656 | } | ||
657 | |||
658 | /* Only one active implicit frame-buffer at a time. */ | ||
659 | mutex_lock(&dev_priv->global_kms_state_mutex); | ||
660 | if (!turning_off && stdu->base.is_implicit && dev_priv->implicit_fb && | ||
661 | !(dev_priv->num_implicit == 1 && stdu->base.active_implicit) | ||
662 | && dev_priv->implicit_fb != vfb) { | ||
663 | mutex_unlock(&dev_priv->global_kms_state_mutex); | ||
664 | DRM_ERROR("Multiple implicit framebuffers not supported.\n"); | ||
665 | return -EINVAL; | ||
666 | } | ||
667 | mutex_unlock(&dev_priv->global_kms_state_mutex); | ||
668 | |||
669 | /* Since they always map one to one these are safe */ | ||
670 | connector = &stdu->base.connector; | ||
671 | encoder = &stdu->base.encoder; | ||
672 | |||
673 | if (stdu->defined) { | ||
674 | ret = vmw_stdu_bind_st(dev_priv, stdu, NULL); | ||
675 | if (ret) | ||
676 | return ret; | ||
677 | |||
678 | vmw_stdu_unpin_display(stdu); | ||
679 | (void) vmw_stdu_update_st(dev_priv, stdu); | ||
680 | vmw_kms_del_active(dev_priv, &stdu->base); | ||
681 | |||
682 | ret = vmw_stdu_destroy_st(dev_priv, stdu); | ||
683 | if (ret) | ||
684 | return ret; | ||
685 | |||
686 | crtc->primary->fb = NULL; | ||
687 | crtc->enabled = false; | ||
688 | encoder->crtc = NULL; | ||
689 | connector->encoder = NULL; | ||
690 | stdu->content_fb_type = SAME_AS_DISPLAY; | ||
691 | crtc->x = set->x; | ||
692 | crtc->y = set->y; | ||
693 | } | ||
694 | |||
695 | if (turning_off) | ||
696 | return 0; | ||
697 | |||
698 | /* | ||
699 | * Steps to displaying a surface, assume surface is already | ||
700 | * bound: | ||
701 | * 1. define a screen target | ||
702 | * 2. bind a fb to the screen target | ||
703 | * 3. update that screen target (this is done later by | ||
704 | * vmw_kms_stdu_do_surface_dirty_or_present) | ||
705 | */ | ||
706 | /* | ||
707 | * Note on error handling: We can't really restore the crtc to | ||
708 | * it's original state on error, but we at least update the | ||
709 | * current state to what's submitted to hardware to enable | ||
710 | * future recovery. | ||
711 | */ | ||
712 | vmw_svga_enable(dev_priv); | ||
713 | ret = vmw_stdu_define_st(dev_priv, stdu, mode, set->x, set->y); | ||
714 | if (ret) | ||
715 | return ret; | ||
716 | |||
717 | crtc->x = set->x; | ||
718 | crtc->y = set->y; | ||
719 | crtc->mode = *mode; | ||
720 | |||
721 | ret = vmw_stdu_bind_fb(dev_priv, crtc, mode, new_fb); | ||
722 | if (ret) | ||
723 | return ret; | ||
724 | |||
725 | vmw_kms_add_active(dev_priv, &stdu->base, vfb); | ||
726 | crtc->enabled = true; | ||
727 | connector->encoder = encoder; | ||
728 | encoder->crtc = crtc; | ||
729 | |||
730 | return 0; | ||
731 | } | ||
732 | |||
733 | /** | ||
734 | * vmw_stdu_crtc_page_flip - Binds a buffer to a screen target | 454 | * vmw_stdu_crtc_page_flip - Binds a buffer to a screen target |
735 | * | 455 | * |
736 | * @crtc: CRTC to attach FB to | 456 | * @crtc: CRTC to attach FB to |
@@ -756,9 +476,9 @@ static int vmw_stdu_crtc_page_flip(struct drm_crtc *crtc, | |||
756 | 476 | ||
757 | { | 477 | { |
758 | struct vmw_private *dev_priv = vmw_priv(crtc->dev); | 478 | struct vmw_private *dev_priv = vmw_priv(crtc->dev); |
759 | struct vmw_screen_target_display_unit *stdu; | 479 | struct vmw_screen_target_display_unit *stdu = vmw_crtc_to_stdu(crtc); |
760 | struct drm_vmw_rect vclips; | ||
761 | struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(new_fb); | 480 | struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(new_fb); |
481 | struct drm_vmw_rect vclips; | ||
762 | int ret; | 482 | int ret; |
763 | 483 | ||
764 | dev_priv = vmw_priv(crtc->dev); | 484 | dev_priv = vmw_priv(crtc->dev); |
@@ -767,25 +487,42 @@ static int vmw_stdu_crtc_page_flip(struct drm_crtc *crtc, | |||
767 | if (!stdu->defined || !vmw_kms_crtc_flippable(dev_priv, crtc)) | 487 | if (!stdu->defined || !vmw_kms_crtc_flippable(dev_priv, crtc)) |
768 | return -EINVAL; | 488 | return -EINVAL; |
769 | 489 | ||
770 | ret = vmw_stdu_bind_fb(dev_priv, crtc, &crtc->mode, new_fb); | 490 | /* |
771 | if (ret) | 491 | * We're always async, but the helper doesn't know how to set async |
492 | * so lie to the helper. Also, the helper expects someone | ||
493 | * to pick the event up from the crtc state, and if nobody does, | ||
494 | * it will free it. Since we handle the event in this function, | ||
495 | * don't hand it to the helper. | ||
496 | */ | ||
497 | flags &= ~DRM_MODE_PAGE_FLIP_ASYNC; | ||
498 | ret = drm_atomic_helper_page_flip(crtc, new_fb, NULL, flags); | ||
499 | if (ret) { | ||
500 | DRM_ERROR("Page flip error %d.\n", ret); | ||
772 | return ret; | 501 | return ret; |
502 | } | ||
773 | 503 | ||
774 | if (stdu->base.is_implicit) | 504 | if (stdu->base.is_implicit) |
775 | vmw_kms_update_implicit_fb(dev_priv, crtc); | 505 | vmw_kms_update_implicit_fb(dev_priv, crtc); |
776 | 506 | ||
507 | /* | ||
508 | * Now that we've bound a new surface to the screen target, | ||
509 | * update the contents. | ||
510 | */ | ||
777 | vclips.x = crtc->x; | 511 | vclips.x = crtc->x; |
778 | vclips.y = crtc->y; | 512 | vclips.y = crtc->y; |
779 | vclips.w = crtc->mode.hdisplay; | 513 | vclips.w = crtc->mode.hdisplay; |
780 | vclips.h = crtc->mode.vdisplay; | 514 | vclips.h = crtc->mode.vdisplay; |
515 | |||
781 | if (vfb->dmabuf) | 516 | if (vfb->dmabuf) |
782 | ret = vmw_kms_stdu_dma(dev_priv, NULL, vfb, NULL, NULL, &vclips, | 517 | ret = vmw_kms_stdu_dma(dev_priv, NULL, vfb, NULL, NULL, &vclips, |
783 | 1, 1, true, false); | 518 | 1, 1, true, false); |
784 | else | 519 | else |
785 | ret = vmw_kms_stdu_surface_dirty(dev_priv, vfb, NULL, &vclips, | 520 | ret = vmw_kms_stdu_surface_dirty(dev_priv, vfb, NULL, &vclips, |
786 | NULL, 0, 0, 1, 1, NULL); | 521 | NULL, 0, 0, 1, 1, NULL); |
787 | if (ret) | 522 | if (ret) { |
523 | DRM_ERROR("Page flip update error %d.\n", ret); | ||
788 | return ret; | 524 | return ret; |
525 | } | ||
789 | 526 | ||
790 | if (event) { | 527 | if (event) { |
791 | struct vmw_fence_obj *fence = NULL; | 528 | struct vmw_fence_obj *fence = NULL; |
@@ -802,7 +539,7 @@ static int vmw_stdu_crtc_page_flip(struct drm_crtc *crtc, | |||
802 | true); | 539 | true); |
803 | vmw_fence_obj_unreference(&fence); | 540 | vmw_fence_obj_unreference(&fence); |
804 | } else { | 541 | } else { |
805 | vmw_fifo_flush(dev_priv, false); | 542 | (void) vmw_fifo_flush(dev_priv, false); |
806 | } | 543 | } |
807 | 544 | ||
808 | return 0; | 545 | return 0; |
@@ -1123,7 +860,7 @@ static const struct drm_crtc_funcs vmw_stdu_crtc_funcs = { | |||
1123 | .reset = vmw_du_crtc_reset, | 860 | .reset = vmw_du_crtc_reset, |
1124 | .atomic_duplicate_state = vmw_du_crtc_duplicate_state, | 861 | .atomic_duplicate_state = vmw_du_crtc_duplicate_state, |
1125 | .atomic_destroy_state = vmw_du_crtc_destroy_state, | 862 | .atomic_destroy_state = vmw_du_crtc_destroy_state, |
1126 | .set_config = vmw_stdu_crtc_set_config, | 863 | .set_config = vmw_kms_set_config, |
1127 | .page_flip = vmw_stdu_crtc_page_flip, | 864 | .page_flip = vmw_stdu_crtc_page_flip, |
1128 | }; | 865 | }; |
1129 | 866 | ||
@@ -1425,8 +1162,8 @@ vmw_stdu_primary_plane_atomic_update(struct drm_plane *plane, | |||
1425 | 1162 | ||
1426 | 1163 | ||
1427 | static const struct drm_plane_funcs vmw_stdu_plane_funcs = { | 1164 | static const struct drm_plane_funcs vmw_stdu_plane_funcs = { |
1428 | .update_plane = drm_primary_helper_update, | 1165 | .update_plane = drm_atomic_helper_update_plane, |
1429 | .disable_plane = drm_primary_helper_disable, | 1166 | .disable_plane = drm_atomic_helper_disable_plane, |
1430 | .destroy = vmw_du_primary_plane_destroy, | 1167 | .destroy = vmw_du_primary_plane_destroy, |
1431 | .reset = vmw_du_plane_reset, | 1168 | .reset = vmw_du_plane_reset, |
1432 | .atomic_duplicate_state = vmw_du_plane_duplicate_state, | 1169 | .atomic_duplicate_state = vmw_du_plane_duplicate_state, |
@@ -1434,8 +1171,8 @@ static const struct drm_plane_funcs vmw_stdu_plane_funcs = { | |||
1434 | }; | 1171 | }; |
1435 | 1172 | ||
1436 | static const struct drm_plane_funcs vmw_stdu_cursor_funcs = { | 1173 | static const struct drm_plane_funcs vmw_stdu_cursor_funcs = { |
1437 | .update_plane = vmw_du_cursor_plane_update, | 1174 | .update_plane = drm_atomic_helper_update_plane, |
1438 | .disable_plane = vmw_du_cursor_plane_disable, | 1175 | .disable_plane = drm_atomic_helper_disable_plane, |
1439 | .destroy = vmw_du_cursor_plane_destroy, | 1176 | .destroy = vmw_du_cursor_plane_destroy, |
1440 | .reset = vmw_du_plane_reset, | 1177 | .reset = vmw_du_plane_reset, |
1441 | .atomic_duplicate_state = vmw_du_plane_duplicate_state, | 1178 | .atomic_duplicate_state = vmw_du_plane_duplicate_state, |
@@ -1625,8 +1362,6 @@ err_free: | |||
1625 | */ | 1362 | */ |
1626 | static void vmw_stdu_destroy(struct vmw_screen_target_display_unit *stdu) | 1363 | static void vmw_stdu_destroy(struct vmw_screen_target_display_unit *stdu) |
1627 | { | 1364 | { |
1628 | vmw_stdu_unpin_display(stdu); | ||
1629 | |||
1630 | vmw_du_cleanup(&stdu->base); | 1365 | vmw_du_cleanup(&stdu->base); |
1631 | kfree(stdu); | 1366 | kfree(stdu); |
1632 | } | 1367 | } |