[PATCH] drm/vmwgfx: Fix fbdev emulation using legacy functions
Thomas Hellstrom
thellstrom at vmware.com
Fri Apr 7 08:31:29 UTC 2017
Hi, Daniel.
It appears to work fine. Thanks!
Do you want to take it through drm-misc or want me to take it throuch
vmwgfx-next?
Reviewed-by: Thomas Hellstrom <thellstrom at vmware.com>
/Thomas
On 04/06/2017 10:02 PM, Daniel Vetter wrote:
> I've broken this by removing the backoff handling from the
> set_config2atomic helper in
>
> commit 38b6441e4e75c0b319cfe4d9364c1059fc1e3c2b
> Author: Daniel Vetter <daniel.vetter at 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 at vmware.com>
> Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
> ---
> drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 58 ++++++++++++++++++++++++++++++++++++--
> 1 file 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,
> return 0;
> }
>
> +static int vmwgfx_set_config_internal(struct drm_mode_set *set)
> +{
> + struct drm_crtc *crtc = set->crtc;
> + struct drm_framebuffer *fb;
> + struct drm_crtc *tmp;
> + struct drm_modeset_acquire_ctx *ctx;
> + struct drm_device *dev = set->crtc->dev;
> + int ret;
> +
> + ctx = dev->mode_config.acquire_ctx;
> +
> +restart:
> + /*
> + * NOTE: ->set_config can also disable other crtcs (if we steal all
> + * connectors from it), hence we need to refcount the fbs across all
> + * crtcs. Atomic modeset will have saner semantics ...
> + */
> + drm_for_each_crtc(tmp, dev)
> + tmp->primary->old_fb = tmp->primary->fb;
> +
> + fb = set->fb;
> +
> + ret = crtc->funcs->set_config(set, ctx);
> + if (ret == 0) {
> + crtc->primary->crtc = crtc;
> + crtc->primary->fb = fb;
> + }
> +
> + drm_for_each_crtc(tmp, dev) {
> + if (tmp->primary->fb)
> + drm_framebuffer_get(tmp->primary->fb);
> + if (tmp->primary->old_fb)
> + drm_framebuffer_put(tmp->primary->old_fb);
> + tmp->primary->old_fb = NULL;
> + }
> +
> + if (ret == -EDEADLK) {
> + dev->mode_config.acquire_ctx = NULL;
> +
> +retry_locking:
> + drm_modeset_backoff(ctx);
> +
> + ret = drm_modeset_lock_all_ctx(dev, ctx);
> + if (ret)
> + goto retry_locking;
> +
> + dev->mode_config.acquire_ctx = ctx;
> +
> + goto restart;
> + }
> +
> + return ret;
> +}
> +
> static int vmw_fb_kms_detach(struct vmw_fb_par *par,
> bool detach_bo,
> bool unref_bo)
> @@ -436,7 +490,7 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par,
> set.fb = NULL;
> set.num_connectors = 0;
> set.connectors = &par->con;
> - ret = drm_mode_set_config_internal(&set);
> + ret = vmwgfx_set_config_internal(&set);
> if (ret) {
> DRM_ERROR("Could not unset a mode.\n");
> return ret;
> @@ -578,7 +632,7 @@ static int vmw_fb_set_par(struct fb_info *info)
> set.num_connectors = 1;
> set.connectors = &par->con;
>
> - ret = drm_mode_set_config_internal(&set);
> + ret = vmwgfx_set_config_internal(&set);
> if (ret)
> goto out_unlock;
>
More information about the dri-devel
mailing list