diff options
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index a56e5d0ca3c6..b77fe0bc18a7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR MIT /************************************************************************** * - * Copyright 2009-2022 VMware, Inc., Palo Alto, CA., USA + * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -25,11 +25,13 @@ * **************************************************************************/ +#include "vmwgfx_bo.h" +#include "vmwgfx_kms.h" + #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_fourcc.h> -#include "vmwgfx_kms.h" #define vmw_crtc_to_ldu(x) \ container_of(x, struct vmw_legacy_display_unit, base.crtc) @@ -134,6 +136,47 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) return 0; } +/* + * Pin the buffer in a location suitable for access by the + * display system. + */ +static int vmw_ldu_fb_pin(struct vmw_framebuffer *vfb) +{ + struct vmw_private *dev_priv = vmw_priv(vfb->base.dev); + struct vmw_bo *buf; + int ret; + + buf = vfb->bo ? vmw_framebuffer_to_vfbd(&vfb->base)->buffer : + vmw_framebuffer_to_vfbs(&vfb->base)->surface->res.backup; + + if (!buf) + return 0; + WARN_ON(dev_priv->active_display_unit != vmw_du_legacy); + + if (dev_priv->active_display_unit == vmw_du_legacy) { + vmw_overlay_pause_all(dev_priv); + ret = vmw_bo_pin_in_start_of_vram(dev_priv, buf, false); + vmw_overlay_resume_all(dev_priv); + } else + ret = -EINVAL; + + return ret; +} + +static int vmw_ldu_fb_unpin(struct vmw_framebuffer *vfb) +{ + struct vmw_private *dev_priv = vmw_priv(vfb->base.dev); + struct vmw_bo *buf; + + buf = vfb->bo ? vmw_framebuffer_to_vfbd(&vfb->base)->buffer : + vmw_framebuffer_to_vfbs(&vfb->base)->surface->res.backup; + + if (WARN_ON(!buf)) + return 0; + + return vmw_bo_unpin(dev_priv, buf, false); +} + static int vmw_ldu_del_active(struct vmw_private *vmw_priv, struct vmw_legacy_display_unit *ldu) { @@ -145,8 +188,7 @@ static int vmw_ldu_del_active(struct vmw_private *vmw_priv, list_del_init(&ldu->active); if (--(ld->num_active) == 0) { BUG_ON(!ld->fb); - if (ld->fb->unpin) - ld->fb->unpin(ld->fb); + WARN_ON(vmw_ldu_fb_unpin(ld->fb)); ld->fb = NULL; } @@ -163,11 +205,10 @@ static int vmw_ldu_add_active(struct vmw_private *vmw_priv, BUG_ON(!ld->num_active && ld->fb); if (vfb != ld->fb) { - if (ld->fb && ld->fb->unpin) - ld->fb->unpin(ld->fb); + if (ld->fb) + WARN_ON(vmw_ldu_fb_unpin(ld->fb)); vmw_svga_enable(vmw_priv); - if (vfb->pin) - vfb->pin(vfb); + WARN_ON(vmw_ldu_fb_pin(vfb)); ld->fb = vfb; } |