mirror of https://gitee.com/openkylin/linux.git
vmwgfx, i915, vc4, vga dac fixes
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJa7PCmAAoJEAx081l5xIa+orgP/jmICUFC/ytFaBHT1kmqL8s6 pm1xqyGV8c0oLGprJG7swWoFxWs4BSM0F729JTbQYqvtksBhQ2WFjKX3L954ZnmR 2PA94umuaa/W+DLU6dEVuxBDlQcFy7yjkbw0PmK5IMaRrTObZpIFqC68RW84L/Cm B+Nwg/88ZJ2KjNY/iBbimul9VPUOoo1jofxrhylQENjSqQm7E2/IvaS69WPk1hym v6fTnuPi1gZ49IvH+A/kGSiPYxmN2zz49fG5JRYxxFiMES7IFWVuOEp09mwx24R/ dRXkUK0IchMuWljfGpm+DYaOcCwIBgV/nkr4lLnK3OACoRhNpvV9L7sJMWl34tYx l3SLZm5NnWaRnlr7npnijCPke+OfkgO8IV3GU5vBKuH3txhx/q535MSiCbk1XBx5 mdLvYb/mCsdaRrSBgTIBVhe88cdWVzAMBZ36tU0h8gYpOBSk2u38BfaeBQPlX6kX K5gGjpXQldrTqcum/HrLIAPMQ8zdQHi7ODq31qOt/SLDehD0i42sbnvBk6W3hRZS YZ/vLmedal/T72kvU7MV8NmnDdm1Ci578sWASiwwu5r8d4wr2Nh2u8SJMtRNmMdg WIiCBpa9Jy6zcNzQ+FBBD3rIB1yRJP4tFfMP2RGMlyCz3SrFAkvnJR0Sy2zgxJM2 anUGsamRcvZYXfar/iRI =68k8 -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
c12fd0fe0c
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue