aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/vmwgfx
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2016-02-12 02:54:07 -0500
committerThomas Hellstrom <thellstrom@vmware.com>2016-03-14 09:56:44 -0400
commitb1097aeb6f23433c4e073a8d7447a8d919e1e163 (patch)
treef05484cadab9eeddd1663ab2fa942297aec069e1 /drivers/gpu/drm/vmwgfx
parent897b818077f3c11eda82ead57fd173c7f12f9796 (diff)
drm/vmwgfx: Rework screen target page flips v2
Gnome-Shell / Wayland assumes that page-flips can be done on a crtc regardless of framebuffer size and the crtc position within the framebuffer. Therefore rework the screen target code to correctly handle changes in framebuffer size and content_fb_type. Also make sure that we update the screen target correctly when the content_fb_type is not SAME_AS_DISPLAY. This commit breaks out the framebuffer binding code from crtc_set so it can be used both from page_flip() and crtc_set() and reworks those functions a bit to be more robust. v2: Address review comments by Sinclair Yeh. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Sinclair Yeh <syeh@vmware.com>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx')
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c422
1 files changed, 188 insertions, 234 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
index 4ef5ffd7189d..c93af718a740 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
@@ -96,7 +96,6 @@ struct vmw_stdu_surface_copy {
96 * content_vfbs dimensions, then this is a pointer into the 96 * content_vfbs dimensions, then this is a pointer into the
97 * corresponding field in content_vfbs. If not, then this 97 * corresponding field in content_vfbs. If not, then this
98 * is a separate buffer to which content_vfbs will blit to. 98 * is a separate buffer to which content_vfbs will blit to.
99 * @content_fb: holds the rendered content, can be a surface or DMA buffer
100 * @content_type: content_fb type 99 * @content_type: content_fb type
101 * @defined: true if the current display unit has been initialized 100 * @defined: true if the current display unit has been initialized
102 */ 101 */
@@ -104,8 +103,6 @@ struct vmw_screen_target_display_unit {
104 struct vmw_display_unit base; 103 struct vmw_display_unit base;
105 104
106 struct vmw_surface *display_srf; 105 struct vmw_surface *display_srf;
107 struct drm_framebuffer *content_fb;
108
109 enum stdu_content_type content_fb_type; 106 enum stdu_content_type content_fb_type;
110 107
111 bool defined; 108 bool defined;
@@ -122,22 +119,6 @@ static void vmw_stdu_destroy(struct vmw_screen_target_display_unit *stdu);
122 *****************************************************************************/ 119 *****************************************************************************/
123 120
124/** 121/**
125 * vmw_stdu_pin_display - pins the resource associated with the display surface
126 *
127 * @stdu: contains the display surface
128 *
129 * Since the display surface can either be a private surface allocated by us,
130 * or it can point to the content surface, we use this function to not pin the
131 * same resource twice.
132 */
133static int vmw_stdu_pin_display(struct vmw_screen_target_display_unit *stdu)
134{
135 return vmw_resource_pin(&stdu->display_srf->res, false);
136}
137
138
139
140/**
141 * vmw_stdu_unpin_display - unpins the resource associated with display surface 122 * vmw_stdu_unpin_display - unpins the resource associated with display surface
142 * 123 *
143 * @stdu: contains the display surface 124 * @stdu: contains the display surface
@@ -153,13 +134,7 @@ static void vmw_stdu_unpin_display(struct vmw_screen_target_display_unit *stdu)
153 struct vmw_resource *res = &stdu->display_srf->res; 134 struct vmw_resource *res = &stdu->display_srf->res;
154 135
155 vmw_resource_unpin(res); 136 vmw_resource_unpin(res);
156 137 vmw_surface_unreference(&stdu->display_srf);
157 if (stdu->content_fb_type != SAME_AS_DISPLAY) {
158 vmw_resource_unreference(&res);
159 stdu->content_fb_type = SAME_AS_DISPLAY;
160 }
161
162 stdu->display_srf = NULL;
163 } 138 }
164} 139}
165 140
@@ -185,6 +160,9 @@ static void vmw_stdu_crtc_destroy(struct drm_crtc *crtc)
185 * 160 *
186 * @dev_priv: VMW DRM device 161 * @dev_priv: VMW DRM device
187 * @stdu: display unit to create a Screen Target for 162 * @stdu: display unit to create a Screen Target for
163 * @mode: The mode to set.
164 * @crtc_x: X coordinate of screen target relative to framebuffer origin.
165 * @crtc_y: Y coordinate of screen target relative to framebuffer origin.
188 * 166 *
189 * Creates a STDU that we can used later. This function is called whenever the 167 * Creates a STDU that we can used later. This function is called whenever the
190 * framebuffer size changes. 168 * framebuffer size changes.
@@ -193,7 +171,9 @@ static void vmw_stdu_crtc_destroy(struct drm_crtc *crtc)
193 * 0 on success, error code on failure 171 * 0 on success, error code on failure
194 */ 172 */
195static int vmw_stdu_define_st(struct vmw_private *dev_priv, 173static int vmw_stdu_define_st(struct vmw_private *dev_priv,
196 struct vmw_screen_target_display_unit *stdu) 174 struct vmw_screen_target_display_unit *stdu,
175 struct drm_display_mode *mode,
176 int crtc_x, int crtc_y)
197{ 177{
198 struct { 178 struct {
199 SVGA3dCmdHeader header; 179 SVGA3dCmdHeader header;
@@ -211,14 +191,14 @@ static int vmw_stdu_define_st(struct vmw_private *dev_priv,
211 cmd->header.size = sizeof(cmd->body); 191 cmd->header.size = sizeof(cmd->body);
212 192
213 cmd->body.stid = stdu->base.unit; 193 cmd->body.stid = stdu->base.unit;
214 cmd->body.width = stdu->display_srf->base_size.width; 194 cmd->body.width = mode->hdisplay;
215 cmd->body.height = stdu->display_srf->base_size.height; 195 cmd->body.height = mode->vdisplay;
216 cmd->body.flags = (0 == cmd->body.stid) ? SVGA_STFLAG_PRIMARY : 0; 196 cmd->body.flags = (0 == cmd->body.stid) ? SVGA_STFLAG_PRIMARY : 0;
217 cmd->body.dpi = 0; 197 cmd->body.dpi = 0;
218 cmd->body.xRoot = stdu->base.crtc.x; 198 if (stdu->base.is_implicit) {
219 cmd->body.yRoot = stdu->base.crtc.y; 199 cmd->body.xRoot = crtc_x;
220 200 cmd->body.yRoot = crtc_y;
221 if (!stdu->base.is_implicit) { 201 } else {
222 cmd->body.xRoot = stdu->base.gui_x; 202 cmd->body.xRoot = stdu->base.gui_x;
223 cmd->body.yRoot = stdu->base.gui_y; 203 cmd->body.yRoot = stdu->base.gui_y;
224 } 204 }
@@ -392,126 +372,43 @@ static int vmw_stdu_destroy_st(struct vmw_private *dev_priv,
392 return ret; 372 return ret;
393} 373}
394 374
395
396
397/** 375/**
398 * vmw_stdu_crtc_set_config - Sets a mode 376 * vmw_stdu_bind_fb - Bind an fb to a defined screen target
399 *
400 * @set: mode parameters
401 * 377 *
402 * This function is the device-specific portion of the DRM CRTC mode set. 378 * @dev_priv: Pointer to a device private struct.
403 * For the SVGA device, we do this by defining a Screen Target, binding a 379 * @crtc: The crtc holding the screen target.
404 * GB Surface to that target, and finally update the screen target. 380 * @mode: The mode currently used by the screen target. Must be non-NULL.
381 * @new_fb: The new framebuffer to bind. Must be non-NULL.
405 * 382 *
406 * RETURNS: 383 * RETURNS:
407 * 0 on success, error code otherwise 384 * 0 on success, error code on failure.
408 */ 385 */
409static int vmw_stdu_crtc_set_config(struct drm_mode_set *set) 386static int vmw_stdu_bind_fb(struct vmw_private *dev_priv,
387 struct drm_crtc *crtc,
388 struct drm_display_mode *mode,
389 struct drm_framebuffer *new_fb)
410{ 390{
411 struct vmw_private *dev_priv; 391 struct vmw_screen_target_display_unit *stdu = vmw_crtc_to_stdu(crtc);
412 struct vmw_screen_target_display_unit *stdu; 392 struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(new_fb);
413 struct vmw_framebuffer *vfb; 393 struct vmw_surface *new_display_srf = NULL;
394 enum stdu_content_type new_content_type;
414 struct vmw_framebuffer_surface *new_vfbs; 395 struct vmw_framebuffer_surface *new_vfbs;
415 struct drm_display_mode *mode; 396 int ret;
416 struct drm_framebuffer *new_fb;
417 struct drm_crtc *crtc;
418 struct drm_encoder *encoder;
419 struct drm_connector *connector;
420 int ret;
421
422
423 if (!set || !set->crtc)
424 return -EINVAL;
425
426 crtc = set->crtc;
427 crtc->x = set->x;
428 crtc->y = set->y;
429 stdu = vmw_crtc_to_stdu(crtc);
430 mode = set->mode;
431 new_fb = set->fb;
432 dev_priv = vmw_priv(crtc->dev);
433
434
435 if (set->num_connectors > 1) {
436 DRM_ERROR("Too many connectors\n");
437 return -EINVAL;
438 }
439
440 if (set->num_connectors == 1 &&
441 set->connectors[0] != &stdu->base.connector) {
442 DRM_ERROR("Connectors don't match %p %p\n",
443 set->connectors[0], &stdu->base.connector);
444 return -EINVAL;
445 }
446
447
448 /* Since they always map one to one these are safe */
449 connector = &stdu->base.connector;
450 encoder = &stdu->base.encoder;
451
452
453 /*
454 * After this point the CRTC will be considered off unless a new fb
455 * is bound
456 */
457 if (stdu->defined) {
458 /* Unbind current surface by binding an invalid one */
459 ret = vmw_stdu_bind_st(dev_priv, stdu, NULL);
460 if (unlikely(ret != 0))
461 return ret;
462
463 /* Update Screen Target, display will now be blank */
464 if (crtc->primary->fb) {
465 vmw_stdu_update_st(dev_priv, stdu);
466 if (unlikely(ret != 0))
467 return ret;
468 }
469
470 crtc->primary->fb = NULL;
471 crtc->enabled = false;
472 encoder->crtc = NULL;
473 connector->encoder = NULL;
474
475 vmw_stdu_unpin_display(stdu);
476 stdu->content_fb = NULL;
477 stdu->content_fb_type = SAME_AS_DISPLAY;
478
479 ret = vmw_stdu_destroy_st(dev_priv, stdu);
480 /* The hardware is hung, give up */
481 if (unlikely(ret != 0))
482 return ret;
483 }
484
485
486 /* Any of these conditions means the caller wants CRTC off */
487 if (set->num_connectors == 0 || !mode || !new_fb)
488 return 0;
489
490
491 if (set->x + mode->hdisplay > new_fb->width ||
492 set->y + mode->vdisplay > new_fb->height) {
493 DRM_ERROR("Set outside of framebuffer\n");
494 return -EINVAL;
495 }
496 397
497 stdu->content_fb = new_fb; 398 WARN_ON_ONCE(!stdu->defined);
498 vfb = vmw_framebuffer_to_vfb(stdu->content_fb);
499 399
500 if (vfb->dmabuf) 400 if (!vfb->dmabuf && new_fb->width == mode->hdisplay &&
501 stdu->content_fb_type = SEPARATE_DMA; 401 new_fb->height == mode->vdisplay)
402 new_content_type = SAME_AS_DISPLAY;
403 else if (vfb->dmabuf)
404 new_content_type = SEPARATE_DMA;
405 else
406 new_content_type = SEPARATE_SURFACE;
502 407
503 /* 408 if (new_content_type != SAME_AS_DISPLAY &&
504 * If the requested mode is different than the width and height 409 !stdu->display_srf) {
505 * of the FB or if the content buffer is a DMA buf, then allocate
506 * a display FB that matches the dimension of the mode
507 */
508 if (mode->hdisplay != new_fb->width ||
509 mode->vdisplay != new_fb->height ||
510 stdu->content_fb_type != SAME_AS_DISPLAY) {
511 struct vmw_surface content_srf; 410 struct vmw_surface content_srf;
512 struct drm_vmw_size display_base_size = {0}; 411 struct drm_vmw_size display_base_size = {0};
513 struct vmw_surface *display_srf;
514
515 412
516 display_base_size.width = mode->hdisplay; 413 display_base_size.width = mode->hdisplay;
517 display_base_size.height = mode->vdisplay; 414 display_base_size.height = mode->vdisplay;
@@ -521,7 +418,7 @@ static int vmw_stdu_crtc_set_config(struct drm_mode_set *set)
521 * If content buffer is a DMA buf, then we have to construct 418 * If content buffer is a DMA buf, then we have to construct
522 * surface info 419 * surface info
523 */ 420 */
524 if (stdu->content_fb_type == SEPARATE_DMA) { 421 if (new_content_type == SEPARATE_DMA) {
525 422
526 switch (new_fb->bits_per_pixel) { 423 switch (new_fb->bits_per_pixel) {
527 case 32: 424 case 32:
@@ -538,17 +435,13 @@ static int vmw_stdu_crtc_set_config(struct drm_mode_set *set)
538 435
539 default: 436 default:
540 DRM_ERROR("Invalid format\n"); 437 DRM_ERROR("Invalid format\n");
541 ret = -EINVAL; 438 return -EINVAL;
542 goto err_unref_content;
543 } 439 }
544 440
545 content_srf.flags = 0; 441 content_srf.flags = 0;
546 content_srf.mip_levels[0] = 1; 442 content_srf.mip_levels[0] = 1;
547 content_srf.multisample_count = 0; 443 content_srf.multisample_count = 0;
548 } else { 444 } else {
549
550 stdu->content_fb_type = SEPARATE_SURFACE;
551
552 new_vfbs = vmw_framebuffer_to_vfbs(new_fb); 445 new_vfbs = vmw_framebuffer_to_vfbs(new_fb);
553 content_srf = *new_vfbs->surface; 446 content_srf = *new_vfbs->surface;
554 } 447 }
@@ -563,26 +456,125 @@ static int vmw_stdu_crtc_set_config(struct drm_mode_set *set)
563 content_srf.multisample_count, 456 content_srf.multisample_count,
564 0, 457 0,
565 display_base_size, 458 display_base_size,
566 &display_srf); 459 &new_display_srf);
567 if (unlikely(ret != 0)) { 460 if (unlikely(ret != 0)) {
568 DRM_ERROR("Cannot allocate a display FB.\n"); 461 DRM_ERROR("Could not allocate screen target surface.\n");
569 goto err_unref_content; 462 return ret;
570 } 463 }
571 464 } else if (new_content_type == SAME_AS_DISPLAY) {
572 stdu->display_srf = display_srf;
573 } else {
574 new_vfbs = vmw_framebuffer_to_vfbs(new_fb); 465 new_vfbs = vmw_framebuffer_to_vfbs(new_fb);
575 stdu->display_srf = new_vfbs->surface; 466 new_display_srf = vmw_surface_reference(new_vfbs->surface);
576 } 467 }
577 468
469 if (new_display_srf) {
470 /* Pin new surface before flipping */
471 ret = vmw_resource_pin(&new_display_srf->res, false);
472 if (ret)
473 goto out_srf_unref;
474
475 ret = vmw_stdu_bind_st(dev_priv, stdu, &new_display_srf->res);
476 if (ret)
477 goto out_srf_unpin;
578 478
579 ret = vmw_stdu_pin_display(stdu); 479 /* Unpin and unreference old surface */
580 if (unlikely(ret != 0)) { 480 vmw_stdu_unpin_display(stdu);
581 stdu->display_srf = NULL; 481
582 goto err_unref_content; 482 /* Transfer the reference */
483 stdu->display_srf = new_display_srf;
484 new_display_srf = NULL;
583 } 485 }
584 486
585 vmw_svga_enable(dev_priv); 487 crtc->primary->fb = new_fb;
488 stdu->content_fb_type = new_content_type;
489 return 0;
490
491out_srf_unpin:
492 vmw_resource_unpin(&new_display_srf->res);
493out_srf_unref:
494 vmw_surface_unreference(&new_display_srf);
495 return ret;
496}
497
498/**
499 * vmw_stdu_crtc_set_config - Sets a mode
500 *
501 * @set: mode parameters
502 *
503 * This function is the device-specific portion of the DRM CRTC mode set.
504 * For the SVGA device, we do this by defining a Screen Target, binding a
505 * GB Surface to that target, and finally update the screen target.
506 *
507 * RETURNS:
508 * 0 on success, error code otherwise
509 */
510static int vmw_stdu_crtc_set_config(struct drm_mode_set *set)
511{
512 struct vmw_private *dev_priv;
513 struct vmw_screen_target_display_unit *stdu;
514 struct drm_display_mode *mode;
515 struct drm_framebuffer *new_fb;
516 struct drm_crtc *crtc;
517 struct drm_encoder *encoder;
518 struct drm_connector *connector;
519 bool turning_off;
520 int ret;
521
522
523 if (!set || !set->crtc)
524 return -EINVAL;
525
526 crtc = set->crtc;
527 stdu = vmw_crtc_to_stdu(crtc);
528 mode = set->mode;
529 new_fb = set->fb;
530 dev_priv = vmw_priv(crtc->dev);
531 turning_off = set->num_connectors == 0 || !mode || !new_fb;
532
533 if (set->num_connectors > 1) {
534 DRM_ERROR("Too many connectors\n");
535 return -EINVAL;
536 }
537
538 if (set->num_connectors == 1 &&
539 set->connectors[0] != &stdu->base.connector) {
540 DRM_ERROR("Connectors don't match %p %p\n",
541 set->connectors[0], &stdu->base.connector);
542 return -EINVAL;
543 }
544
545 if (!turning_off && (set->x + mode->hdisplay > new_fb->width ||
546 set->y + mode->vdisplay > new_fb->height)) {
547 DRM_ERROR("Set outside of framebuffer\n");
548 return -EINVAL;
549 }
550
551 /* Since they always map one to one these are safe */
552 connector = &stdu->base.connector;
553 encoder = &stdu->base.encoder;
554
555 if (stdu->defined) {
556 ret = vmw_stdu_bind_st(dev_priv, stdu, NULL);
557 if (ret)
558 return ret;
559
560 vmw_stdu_unpin_display(stdu);
561 (void) vmw_stdu_update_st(dev_priv, stdu);
562
563 ret = vmw_stdu_destroy_st(dev_priv, stdu);
564 if (ret)
565 return ret;
566
567 crtc->primary->fb = NULL;
568 crtc->enabled = false;
569 encoder->crtc = NULL;
570 connector->encoder = NULL;
571 stdu->content_fb_type = SAME_AS_DISPLAY;
572 crtc->x = set->x;
573 crtc->y = set->y;
574 }
575
576 if (turning_off)
577 return 0;
586 578
587 /* 579 /*
588 * Steps to displaying a surface, assume surface is already 580 * Steps to displaying a surface, assume surface is already
@@ -592,35 +584,32 @@ static int vmw_stdu_crtc_set_config(struct drm_mode_set *set)
592 * 3. update that screen target (this is done later by 584 * 3. update that screen target (this is done later by
593 * vmw_kms_stdu_do_surface_dirty_or_present) 585 * vmw_kms_stdu_do_surface_dirty_or_present)
594 */ 586 */
595 ret = vmw_stdu_define_st(dev_priv, stdu); 587 /*
596 if (unlikely(ret != 0)) 588 * Note on error handling: We can't really restore the crtc to
597 goto err_unpin_display_and_content; 589 * it's original state on error, but we at least update the
590 * current state to what's submitted to hardware to enable
591 * future recovery.
592 */
593 vmw_svga_enable(dev_priv);
594 ret = vmw_stdu_define_st(dev_priv, stdu, mode, set->x, set->y);
595 if (ret)
596 return ret;
598 597
599 ret = vmw_stdu_bind_st(dev_priv, stdu, &stdu->display_srf->res); 598 crtc->x = set->x;
600 if (unlikely(ret != 0)) 599 crtc->y = set->y;
601 goto err_unpin_destroy_st; 600 crtc->mode = *mode;
602 601
602 ret = vmw_stdu_bind_fb(dev_priv, crtc, mode, new_fb);
603 if (ret)
604 return ret;
603 605
606 crtc->enabled = true;
604 connector->encoder = encoder; 607 connector->encoder = encoder;
605 encoder->crtc = crtc; 608 encoder->crtc = crtc;
606 609
607 crtc->mode = *mode; 610 return 0;
608 crtc->primary->fb = new_fb;
609 crtc->enabled = true;
610
611 return ret;
612
613err_unpin_destroy_st:
614 vmw_stdu_destroy_st(dev_priv, stdu);
615err_unpin_display_and_content:
616 vmw_stdu_unpin_display(stdu);
617err_unref_content:
618 stdu->content_fb = NULL;
619 return ret;
620} 611}
621 612
622
623
624/** 613/**
625 * vmw_stdu_crtc_page_flip - Binds a buffer to a screen target 614 * vmw_stdu_crtc_page_flip - Binds a buffer to a screen target
626 * 615 *
@@ -648,59 +637,31 @@ static int vmw_stdu_crtc_page_flip(struct drm_crtc *crtc,
648{ 637{
649 struct vmw_private *dev_priv = vmw_priv(crtc->dev); 638 struct vmw_private *dev_priv = vmw_priv(crtc->dev);
650 struct vmw_screen_target_display_unit *stdu; 639 struct vmw_screen_target_display_unit *stdu;
640 struct drm_vmw_rect vclips;
641 struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(new_fb);
651 int ret; 642 int ret;
652 643
653 if (crtc == NULL)
654 return -EINVAL;
655
656 dev_priv = vmw_priv(crtc->dev); 644 dev_priv = vmw_priv(crtc->dev);
657 stdu = vmw_crtc_to_stdu(crtc); 645 stdu = vmw_crtc_to_stdu(crtc);
658 crtc->primary->fb = new_fb;
659 stdu->content_fb = new_fb;
660
661 if (stdu->display_srf) {
662 /*
663 * If the display surface is the same as the content surface
664 * then remove the reference
665 */
666 if (stdu->content_fb_type == SAME_AS_DISPLAY) {
667 if (stdu->defined) {
668 /* Unbind the current surface */
669 ret = vmw_stdu_bind_st(dev_priv, stdu, NULL);
670 if (unlikely(ret != 0))
671 goto err_out;
672 }
673 vmw_stdu_unpin_display(stdu);
674 stdu->display_srf = NULL;
675 }
676 }
677
678
679 if (!new_fb) {
680 /* Blanks the display */
681 (void) vmw_stdu_update_st(dev_priv, stdu);
682
683 return 0;
684 }
685 646
647 if (!stdu->defined)
648 return -EINVAL;
686 649
687 if (stdu->content_fb_type == SAME_AS_DISPLAY) { 650 ret = vmw_stdu_bind_fb(dev_priv, crtc, &crtc->mode, new_fb);
688 stdu->display_srf = vmw_framebuffer_to_vfbs(new_fb)->surface; 651 if (ret)
689 ret = vmw_stdu_pin_display(stdu); 652 return ret;
690 if (ret) {
691 stdu->display_srf = NULL;
692 goto err_out;
693 }
694
695 /* Bind display surface */
696 ret = vmw_stdu_bind_st(dev_priv, stdu, &stdu->display_srf->res);
697 if (unlikely(ret != 0))
698 goto err_unpin_display_and_content;
699 }
700 653
701 /* Update display surface: after this point everything is bound */ 654 vclips.x = crtc->x;
702 ret = vmw_stdu_update_st(dev_priv, stdu); 655 vclips.y = crtc->y;
703 if (unlikely(ret != 0)) 656 vclips.w = crtc->mode.hdisplay;
657 vclips.h = crtc->mode.vdisplay;
658 if (vfb->dmabuf)
659 ret = vmw_kms_stdu_dma(dev_priv, NULL, vfb, NULL, NULL, &vclips,
660 1, 1, true, false);
661 else
662 ret = vmw_kms_stdu_surface_dirty(dev_priv, vfb, NULL, &vclips,
663 NULL, 0, 0, 1, 1, NULL);
664 if (ret)
704 return ret; 665 return ret;
705 666
706 if (event) { 667 if (event) {
@@ -721,14 +682,7 @@ static int vmw_stdu_crtc_page_flip(struct drm_crtc *crtc,
721 vmw_fifo_flush(dev_priv, false); 682 vmw_fifo_flush(dev_priv, false);
722 } 683 }
723 684
724 return ret; 685 return 0;
725
726err_unpin_display_and_content:
727 vmw_stdu_unpin_display(stdu);
728err_out:
729 crtc->primary->fb = NULL;
730 stdu->content_fb = NULL;
731 return ret;
732} 686}
733 687
734 688