drm/vmwgfx: Add implicit framebuffer checks to the screen target code
Just like for screen objects, make sure we use only a single framebuffer for implicit placement. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Sinclair Yeh <syeh@vmware.com>
This commit is contained in:
parent
75c0685549
commit
4d492a07ad
|
@ -510,6 +510,7 @@ out_srf_unref:
|
||||||
static int vmw_stdu_crtc_set_config(struct drm_mode_set *set)
|
static int vmw_stdu_crtc_set_config(struct drm_mode_set *set)
|
||||||
{
|
{
|
||||||
struct vmw_private *dev_priv;
|
struct vmw_private *dev_priv;
|
||||||
|
struct vmw_framebuffer *vfb;
|
||||||
struct vmw_screen_target_display_unit *stdu;
|
struct vmw_screen_target_display_unit *stdu;
|
||||||
struct drm_display_mode *mode;
|
struct drm_display_mode *mode;
|
||||||
struct drm_framebuffer *new_fb;
|
struct drm_framebuffer *new_fb;
|
||||||
|
@ -529,6 +530,7 @@ static int vmw_stdu_crtc_set_config(struct drm_mode_set *set)
|
||||||
new_fb = set->fb;
|
new_fb = set->fb;
|
||||||
dev_priv = vmw_priv(crtc->dev);
|
dev_priv = vmw_priv(crtc->dev);
|
||||||
turning_off = set->num_connectors == 0 || !mode || !new_fb;
|
turning_off = set->num_connectors == 0 || !mode || !new_fb;
|
||||||
|
vfb = (new_fb) ? vmw_framebuffer_to_vfb(new_fb) : NULL;
|
||||||
|
|
||||||
if (set->num_connectors > 1) {
|
if (set->num_connectors > 1) {
|
||||||
DRM_ERROR("Too many connectors\n");
|
DRM_ERROR("Too many connectors\n");
|
||||||
|
@ -548,6 +550,14 @@ static int vmw_stdu_crtc_set_config(struct drm_mode_set *set)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only one active implicit frame-buffer at a time. */
|
||||||
|
if (!turning_off && stdu->base.is_implicit && dev_priv->implicit_fb &&
|
||||||
|
!(dev_priv->num_implicit == 1 && stdu->base.active_implicit)
|
||||||
|
&& dev_priv->implicit_fb != vfb) {
|
||||||
|
DRM_ERROR("Multiple implicit framebuffers not supported.\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Since they always map one to one these are safe */
|
/* Since they always map one to one these are safe */
|
||||||
connector = &stdu->base.connector;
|
connector = &stdu->base.connector;
|
||||||
encoder = &stdu->base.encoder;
|
encoder = &stdu->base.encoder;
|
||||||
|
@ -559,6 +569,7 @@ static int vmw_stdu_crtc_set_config(struct drm_mode_set *set)
|
||||||
|
|
||||||
vmw_stdu_unpin_display(stdu);
|
vmw_stdu_unpin_display(stdu);
|
||||||
(void) vmw_stdu_update_st(dev_priv, stdu);
|
(void) vmw_stdu_update_st(dev_priv, stdu);
|
||||||
|
vmw_kms_del_active(dev_priv, &stdu->base);
|
||||||
|
|
||||||
ret = vmw_stdu_destroy_st(dev_priv, stdu);
|
ret = vmw_stdu_destroy_st(dev_priv, stdu);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -603,6 +614,7 @@ static int vmw_stdu_crtc_set_config(struct drm_mode_set *set)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
vmw_kms_add_active(dev_priv, &stdu->base, vfb);
|
||||||
crtc->enabled = true;
|
crtc->enabled = true;
|
||||||
connector->encoder = encoder;
|
connector->encoder = encoder;
|
||||||
encoder->crtc = crtc;
|
encoder->crtc = crtc;
|
||||||
|
@ -644,13 +656,16 @@ static int vmw_stdu_crtc_page_flip(struct drm_crtc *crtc,
|
||||||
dev_priv = vmw_priv(crtc->dev);
|
dev_priv = vmw_priv(crtc->dev);
|
||||||
stdu = vmw_crtc_to_stdu(crtc);
|
stdu = vmw_crtc_to_stdu(crtc);
|
||||||
|
|
||||||
if (!stdu->defined)
|
if (!stdu->defined || !vmw_kms_crtc_flippable(dev_priv, crtc))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ret = vmw_stdu_bind_fb(dev_priv, crtc, &crtc->mode, new_fb);
|
ret = vmw_stdu_bind_fb(dev_priv, crtc, &crtc->mode, new_fb);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (stdu->base.is_implicit)
|
||||||
|
vmw_kms_update_implicit_fb(dev_priv, crtc);
|
||||||
|
|
||||||
vclips.x = crtc->x;
|
vclips.x = crtc->x;
|
||||||
vclips.y = crtc->y;
|
vclips.y = crtc->y;
|
||||||
vclips.w = crtc->mode.hdisplay;
|
vclips.w = crtc->mode.hdisplay;
|
||||||
|
|
Loading…
Reference in a new issue