aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2017-04-06 16:02:56 -0400
committerSean Paul <seanpaul@chromium.org>2017-04-07 13:28:32 -0400
commit3bacf4361cd07f988a13de78d672928606df24ad (patch)
tree78eace07770d10efae75dd08af7e8f313e1ff622
parentc1bb81888746b6fff8c3b0abfecc751ab73b3a08 (diff)
drm/vmwgfx: Fix fbdev emulation using legacy functions
I've broken this by removing the backoff handling from the set_config2atomic helper in commit 38b6441e4e75c0b319cfe4d9364c1059fc1e3c2b Author: Daniel Vetter <daniel.vetter@ffwll.ch> Date: Wed Mar 22 22:50:58 2017 +0100 drm/atomic-helper: Remove the backoff hack from set_config Fixing this properly would mean we get to wire the acquire_ctx all the way through vmwgfx fbdev code, and doing the same was tricky for the shared fbdev layer. Probably much better to look into refactoring the entire code to use the helpers, but since that's not a viable long-term solution fix the issue by open-coding a vmwgfx version of set_config, that does the legacy backoff dance internally. Note: Just compile-tested. The idea is to take drm_mode_set_config_internal(), remove the "is this a legacy driver" check, and whack the drm_atomic_legacy_backoff trickery at the end. Since drm_atomic_legacy_backoff is for atomic commits only we need to open-code it. Cc: Thomas Hellstrom <thellstrom@vmware.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com> Signed-off-by: Sean Paul <seanpaul@chromium.org> Link: http://patchwork.freedesktop.org/patch/msgid/20170406200256.26040-1-daniel.vetter@ffwll.ch
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fb.c58
1 files changed, 56 insertions, 2 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
index 09e120d50e65..6f4cb4678cbc 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
@@ -418,6 +418,60 @@ static int vmw_fb_compute_depth(struct fb_var_screeninfo *var,
418 return 0; 418 return 0;
419} 419}
420 420
421static int vmwgfx_set_config_internal(struct drm_mode_set *set)
422{
423 struct drm_crtc *crtc = set->crtc;
424 struct drm_framebuffer *fb;
425 struct drm_crtc *tmp;
426 struct drm_modeset_acquire_ctx *ctx;
427 struct drm_device *dev = set->crtc->dev;
428 int ret;
429
430 ctx = dev->mode_config.acquire_ctx;
431
432restart:
433 /*
434 * NOTE: ->set_config can also disable other crtcs (if we steal all
435 * connectors from it), hence we need to refcount the fbs across all
436 * crtcs. Atomic modeset will have saner semantics ...
437 */
438 drm_for_each_crtc(tmp, dev)
439 tmp->primary->old_fb = tmp->primary->fb;
440
441 fb = set->fb;
442
443 ret = crtc->funcs->set_config(set, ctx);
444 if (ret == 0) {
445 crtc->primary->crtc = crtc;
446 crtc->primary->fb = fb;
447 }
448
449 drm_for_each_crtc(tmp, dev) {
450 if (tmp->primary->fb)
451 drm_framebuffer_get(tmp->primary->fb);
452 if (tmp->primary->old_fb)
453 drm_framebuffer_put(tmp->primary->old_fb);
454 tmp->primary->old_fb = NULL;
455 }
456
457 if (ret == -EDEADLK) {
458 dev->mode_config.acquire_ctx = NULL;
459
460retry_locking:
461 drm_modeset_backoff(ctx);
462
463 ret = drm_modeset_lock_all_ctx(dev, ctx);
464 if (ret)
465 goto retry_locking;
466
467 dev->mode_config.acquire_ctx = ctx;
468
469 goto restart;
470 }
471
472 return ret;
473}
474
421static int vmw_fb_kms_detach(struct vmw_fb_par *par, 475static int vmw_fb_kms_detach(struct vmw_fb_par *par,
422 bool detach_bo, 476 bool detach_bo,
423 bool unref_bo) 477 bool unref_bo)
@@ -436,7 +490,7 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par,
436 set.fb = NULL; 490 set.fb = NULL;
437 set.num_connectors = 0; 491 set.num_connectors = 0;
438 set.connectors = &par->con; 492 set.connectors = &par->con;
439 ret = drm_mode_set_config_internal(&set); 493 ret = vmwgfx_set_config_internal(&set);
440 if (ret) { 494 if (ret) {
441 DRM_ERROR("Could not unset a mode.\n"); 495 DRM_ERROR("Could not unset a mode.\n");
442 return ret; 496 return ret;
@@ -578,7 +632,7 @@ static int vmw_fb_set_par(struct fb_info *info)
578 set.num_connectors = 1; 632 set.num_connectors = 1;
579 set.connectors = &par->con; 633 set.connectors = &par->con;
580 634
581 ret = drm_mode_set_config_internal(&set); 635 ret = vmwgfx_set_config_internal(&set);
582 if (ret) 636 if (ret)
583 goto out_unlock; 637 goto out_unlock;
584 638