提交 c12fd0fe 编写于 作者: L Linus Torvalds

Merge tag 'drm-fixes-for-v4.17-rc4' of git://people.freedesktop.org/~airlied/linux

Pull drm fixes from Dave Airlie:
 "vmwgfx, i915, vc4, vga dac fixes.

  This seems eerily quiet, so I expect it will explode next week or
  something.

  One i915 model firmware, two vmwgfx fixes, one vc4 fix and one bridge
  leak fix"

* tag 'drm-fixes-for-v4.17-rc4' of git://people.freedesktop.org/~airlied/linux:
  drm/bridge: vga-dac: Fix edid memory leak
  drm/vc4: Make sure vc4_bo_{inc,dec}_usecnt() calls are balanced
  drm/i915/glk: Add MODULE_FIRMWARE for Geminilake
  drm/vmwgfx: Fix a buffer object leak
  drm/vmwgfx: Clean up fbdev modeset locking
......@@ -56,7 +56,9 @@ static int dumb_vga_get_modes(struct drm_connector *connector)
}
drm_mode_connector_update_edid_property(connector, edid);
return drm_add_edid_modes(connector, edid);
ret = drm_add_edid_modes(connector, edid);
kfree(edid);
return ret;
fallback:
/*
......
......@@ -35,6 +35,7 @@
*/
#define I915_CSR_GLK "i915/glk_dmc_ver1_04.bin"
MODULE_FIRMWARE(I915_CSR_GLK);
#define GLK_CSR_VERSION_REQUIRED CSR_VERSION(1, 4)
#define I915_CSR_CNL "i915/cnl_dmc_ver1_07.bin"
......
......@@ -760,6 +760,7 @@ static irqreturn_t vc4_crtc_irq_handler(int irq, void *data)
struct vc4_async_flip_state {
struct drm_crtc *crtc;
struct drm_framebuffer *fb;
struct drm_framebuffer *old_fb;
struct drm_pending_vblank_event *event;
struct vc4_seqno_cb cb;
......@@ -789,6 +790,23 @@ vc4_async_page_flip_complete(struct vc4_seqno_cb *cb)
drm_crtc_vblank_put(crtc);
drm_framebuffer_put(flip_state->fb);
/* Decrement the BO usecnt in order to keep the inc/dec calls balanced
* when the planes are updated through the async update path.
* FIXME: we should move to generic async-page-flip when it's
* available, so that we can get rid of this hand-made cleanup_fb()
* logic.
*/
if (flip_state->old_fb) {
struct drm_gem_cma_object *cma_bo;
struct vc4_bo *bo;
cma_bo = drm_fb_cma_get_gem_obj(flip_state->old_fb, 0);
bo = to_vc4_bo(&cma_bo->base);
vc4_bo_dec_usecnt(bo);
drm_framebuffer_put(flip_state->old_fb);
}
kfree(flip_state);
up(&vc4->async_modeset);
......@@ -813,9 +831,22 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0);
struct vc4_bo *bo = to_vc4_bo(&cma_bo->base);
/* Increment the BO usecnt here, so that we never end up with an
* unbalanced number of vc4_bo_{dec,inc}_usecnt() calls when the
* plane is later updated through the non-async path.
* FIXME: we should move to generic async-page-flip when it's
* available, so that we can get rid of this hand-made prepare_fb()
* logic.
*/
ret = vc4_bo_inc_usecnt(bo);
if (ret)
return ret;
flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL);
if (!flip_state)
if (!flip_state) {
vc4_bo_dec_usecnt(bo);
return -ENOMEM;
}
drm_framebuffer_get(fb);
flip_state->fb = fb;
......@@ -826,10 +857,23 @@ static int vc4_async_page_flip(struct drm_crtc *crtc,
ret = down_interruptible(&vc4->async_modeset);
if (ret) {
drm_framebuffer_put(fb);
vc4_bo_dec_usecnt(bo);
kfree(flip_state);
return ret;
}
/* Save the current FB before it's replaced by the new one in
* drm_atomic_set_fb_for_plane(). We'll need the old FB in
* vc4_async_page_flip_complete() to decrement the BO usecnt and keep
* it consistent.
* FIXME: we should move to generic async-page-flip when it's
* available, so that we can get rid of this hand-made cleanup_fb()
* logic.
*/
flip_state->old_fb = plane->state->fb;
if (flip_state->old_fb)
drm_framebuffer_get(flip_state->old_fb);
WARN_ON(drm_crtc_vblank_get(crtc) != 0);
/* Immediately update the plane's legacy fb pointer, so that later
......
......@@ -441,11 +441,11 @@ 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;
struct drm_modeset_acquire_ctx ctx;
int ret;
ctx = dev->mode_config.acquire_ctx;
drm_modeset_acquire_init(&ctx, 0);
restart:
/*
......@@ -458,7 +458,7 @@ static int vmwgfx_set_config_internal(struct drm_mode_set *set)
fb = set->fb;
ret = crtc->funcs->set_config(set, ctx);
ret = crtc->funcs->set_config(set, &ctx);
if (ret == 0) {
crtc->primary->crtc = crtc;
crtc->primary->fb = fb;
......@@ -473,20 +473,13 @@ static int vmwgfx_set_config_internal(struct drm_mode_set *set)
}
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;
drm_modeset_backoff(&ctx);
goto restart;
}
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
return ret;
}
......@@ -624,7 +617,6 @@ static int vmw_fb_set_par(struct fb_info *info)
}
mutex_lock(&par->bo_mutex);
drm_modeset_lock_all(vmw_priv->dev);
ret = vmw_fb_kms_framebuffer(info);
if (ret)
goto out_unlock;
......@@ -657,7 +649,6 @@ static int vmw_fb_set_par(struct fb_info *info)
drm_mode_destroy(vmw_priv->dev, old_mode);
par->set_mode = mode;
drm_modeset_unlock_all(vmw_priv->dev);
mutex_unlock(&par->bo_mutex);
return ret;
......@@ -713,18 +704,14 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
par->max_width = fb_width;
par->max_height = fb_height;
drm_modeset_lock_all(vmw_priv->dev);
ret = vmw_kms_fbdev_init_data(vmw_priv, 0, par->max_width,
par->max_height, &par->con,
&par->crtc, &init_mode);
if (ret) {
drm_modeset_unlock_all(vmw_priv->dev);
if (ret)
goto err_kms;
}
info->var.xres = init_mode->hdisplay;
info->var.yres = init_mode->vdisplay;
drm_modeset_unlock_all(vmw_priv->dev);
/*
* Create buffers and alloc memory
......@@ -832,7 +819,9 @@ int vmw_fb_close(struct vmw_private *vmw_priv)
cancel_delayed_work_sync(&par->local_work);
unregister_framebuffer(info);
mutex_lock(&par->bo_mutex);
(void) vmw_fb_kms_detach(par, true, true);
mutex_unlock(&par->bo_mutex);
vfree(par->vmalloc);
framebuffer_release(info);
......
......@@ -2595,6 +2595,7 @@ void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx,
vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf,
out_fence, NULL);
vmw_dmabuf_unreference(&ctx->buf);
vmw_resource_unreserve(res, false, NULL, 0);
mutex_unlock(&res->dev_priv->cmdbuf_mutex);
}
......@@ -2680,7 +2681,9 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
struct vmw_display_unit *du;
struct drm_display_mode *mode;
int i = 0;
int ret = 0;
mutex_lock(&dev_priv->dev->mode_config.mutex);
list_for_each_entry(con, &dev_priv->dev->mode_config.connector_list,
head) {
if (i == unit)
......@@ -2691,7 +2694,8 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
if (i != unit) {
DRM_ERROR("Could not find initial display unit.\n");
return -EINVAL;
ret = -EINVAL;
goto out_unlock;
}
if (list_empty(&con->modes))
......@@ -2699,7 +2703,8 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
if (list_empty(&con->modes)) {
DRM_ERROR("Could not find initial display mode.\n");
return -EINVAL;
ret = -EINVAL;
goto out_unlock;
}
du = vmw_connector_to_du(con);
......@@ -2720,7 +2725,10 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
head);
}
return 0;
out_unlock:
mutex_unlock(&dev_priv->dev->mode_config.mutex);
return ret;
}
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册