diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-05 03:05:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-05 03:05:12 -0400 |
commit | c12fd0fe0c222e1e69cbbc41234ec525ee9b091b (patch) | |
tree | aede4b1fc1cfa621ae725311b1b79cb97e47dd35 | |
parent | 4b293907d36c4803df31f71693e6bd5917dba4d0 (diff) | |
parent | a02cbe2e34c576cdc5e7846a3cd55245ab81db47 (diff) |
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
-rw-r--r-- | drivers/gpu/drm/bridge/dumb-vga-dac.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_csr.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_crtc.c | 46 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 14 |
5 files changed, 70 insertions, 26 deletions
diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c b/drivers/gpu/drm/bridge/dumb-vga-dac.c index 498d5948d1a8..9837c8d69e69 100644 --- a/drivers/gpu/drm/bridge/dumb-vga-dac.c +++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c | |||
@@ -56,7 +56,9 @@ static int dumb_vga_get_modes(struct drm_connector *connector) | |||
56 | } | 56 | } |
57 | 57 | ||
58 | drm_mode_connector_update_edid_property(connector, edid); | 58 | drm_mode_connector_update_edid_property(connector, edid); |
59 | return drm_add_edid_modes(connector, edid); | 59 | ret = drm_add_edid_modes(connector, edid); |
60 | kfree(edid); | ||
61 | return ret; | ||
60 | 62 | ||
61 | fallback: | 63 | fallback: |
62 | /* | 64 | /* |
diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c index 41e6c75a7f3c..f9550ea46c26 100644 --- a/drivers/gpu/drm/i915/intel_csr.c +++ b/drivers/gpu/drm/i915/intel_csr.c | |||
@@ -35,6 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #define I915_CSR_GLK "i915/glk_dmc_ver1_04.bin" | 37 | #define I915_CSR_GLK "i915/glk_dmc_ver1_04.bin" |
38 | MODULE_FIRMWARE(I915_CSR_GLK); | ||
38 | #define GLK_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) | 39 | #define GLK_CSR_VERSION_REQUIRED CSR_VERSION(1, 4) |
39 | 40 | ||
40 | #define I915_CSR_CNL "i915/cnl_dmc_ver1_07.bin" | 41 | #define I915_CSR_CNL "i915/cnl_dmc_ver1_07.bin" |
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index bf4667481935..c61dff594195 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c | |||
@@ -760,6 +760,7 @@ static irqreturn_t vc4_crtc_irq_handler(int irq, void *data) | |||
760 | struct vc4_async_flip_state { | 760 | struct vc4_async_flip_state { |
761 | struct drm_crtc *crtc; | 761 | struct drm_crtc *crtc; |
762 | struct drm_framebuffer *fb; | 762 | struct drm_framebuffer *fb; |
763 | struct drm_framebuffer *old_fb; | ||
763 | struct drm_pending_vblank_event *event; | 764 | struct drm_pending_vblank_event *event; |
764 | 765 | ||
765 | struct vc4_seqno_cb cb; | 766 | struct vc4_seqno_cb cb; |
@@ -789,6 +790,23 @@ vc4_async_page_flip_complete(struct vc4_seqno_cb *cb) | |||
789 | 790 | ||
790 | drm_crtc_vblank_put(crtc); | 791 | drm_crtc_vblank_put(crtc); |
791 | drm_framebuffer_put(flip_state->fb); | 792 | drm_framebuffer_put(flip_state->fb); |
793 | |||
794 | /* Decrement the BO usecnt in order to keep the inc/dec calls balanced | ||
795 | * when the planes are updated through the async update path. | ||
796 | * FIXME: we should move to generic async-page-flip when it's | ||
797 | * available, so that we can get rid of this hand-made cleanup_fb() | ||
798 | * logic. | ||
799 | */ | ||
800 | if (flip_state->old_fb) { | ||
801 | struct drm_gem_cma_object *cma_bo; | ||
802 | struct vc4_bo *bo; | ||
803 | |||
804 | cma_bo = drm_fb_cma_get_gem_obj(flip_state->old_fb, 0); | ||
805 | bo = to_vc4_bo(&cma_bo->base); | ||
806 | vc4_bo_dec_usecnt(bo); | ||
807 | drm_framebuffer_put(flip_state->old_fb); | ||
808 | } | ||
809 | |||
792 | kfree(flip_state); | 810 | kfree(flip_state); |
793 | 811 | ||
794 | up(&vc4->async_modeset); | 812 | up(&vc4->async_modeset); |
@@ -813,9 +831,22 @@ static int vc4_async_page_flip(struct drm_crtc *crtc, | |||
813 | struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0); | 831 | struct drm_gem_cma_object *cma_bo = drm_fb_cma_get_gem_obj(fb, 0); |
814 | struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); | 832 | struct vc4_bo *bo = to_vc4_bo(&cma_bo->base); |
815 | 833 | ||
834 | /* Increment the BO usecnt here, so that we never end up with an | ||
835 | * unbalanced number of vc4_bo_{dec,inc}_usecnt() calls when the | ||
836 | * plane is later updated through the non-async path. | ||
837 | * FIXME: we should move to generic async-page-flip when it's | ||
838 | * available, so that we can get rid of this hand-made prepare_fb() | ||
839 | * logic. | ||
840 | */ | ||
841 | ret = vc4_bo_inc_usecnt(bo); | ||
842 | if (ret) | ||
843 | return ret; | ||
844 | |||
816 | flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL); | 845 | flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL); |
817 | if (!flip_state) | 846 | if (!flip_state) { |
847 | vc4_bo_dec_usecnt(bo); | ||
818 | return -ENOMEM; | 848 | return -ENOMEM; |
849 | } | ||
819 | 850 | ||
820 | drm_framebuffer_get(fb); | 851 | drm_framebuffer_get(fb); |
821 | flip_state->fb = fb; | 852 | flip_state->fb = fb; |
@@ -826,10 +857,23 @@ static int vc4_async_page_flip(struct drm_crtc *crtc, | |||
826 | ret = down_interruptible(&vc4->async_modeset); | 857 | ret = down_interruptible(&vc4->async_modeset); |
827 | if (ret) { | 858 | if (ret) { |
828 | drm_framebuffer_put(fb); | 859 | drm_framebuffer_put(fb); |
860 | vc4_bo_dec_usecnt(bo); | ||
829 | kfree(flip_state); | 861 | kfree(flip_state); |
830 | return ret; | 862 | return ret; |
831 | } | 863 | } |
832 | 864 | ||
865 | /* Save the current FB before it's replaced by the new one in | ||
866 | * drm_atomic_set_fb_for_plane(). We'll need the old FB in | ||
867 | * vc4_async_page_flip_complete() to decrement the BO usecnt and keep | ||
868 | * it consistent. | ||
869 | * FIXME: we should move to generic async-page-flip when it's | ||
870 | * available, so that we can get rid of this hand-made cleanup_fb() | ||
871 | * logic. | ||
872 | */ | ||
873 | flip_state->old_fb = plane->state->fb; | ||
874 | if (flip_state->old_fb) | ||
875 | drm_framebuffer_get(flip_state->old_fb); | ||
876 | |||
833 | WARN_ON(drm_crtc_vblank_get(crtc) != 0); | 877 | WARN_ON(drm_crtc_vblank_get(crtc) != 0); |
834 | 878 | ||
835 | /* Immediately update the plane's legacy fb pointer, so that later | 879 | /* Immediately update the plane's legacy fb pointer, so that later |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 2582ffd36bb5..ba0cdb743c3e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | |||
@@ -441,11 +441,11 @@ static int vmwgfx_set_config_internal(struct drm_mode_set *set) | |||
441 | struct drm_crtc *crtc = set->crtc; | 441 | struct drm_crtc *crtc = set->crtc; |
442 | struct drm_framebuffer *fb; | 442 | struct drm_framebuffer *fb; |
443 | struct drm_crtc *tmp; | 443 | struct drm_crtc *tmp; |
444 | struct drm_modeset_acquire_ctx *ctx; | ||
445 | struct drm_device *dev = set->crtc->dev; | 444 | struct drm_device *dev = set->crtc->dev; |
445 | struct drm_modeset_acquire_ctx ctx; | ||
446 | int ret; | 446 | int ret; |
447 | 447 | ||
448 | ctx = dev->mode_config.acquire_ctx; | 448 | drm_modeset_acquire_init(&ctx, 0); |
449 | 449 | ||
450 | restart: | 450 | restart: |
451 | /* | 451 | /* |
@@ -458,7 +458,7 @@ restart: | |||
458 | 458 | ||
459 | fb = set->fb; | 459 | fb = set->fb; |
460 | 460 | ||
461 | ret = crtc->funcs->set_config(set, ctx); | 461 | ret = crtc->funcs->set_config(set, &ctx); |
462 | if (ret == 0) { | 462 | if (ret == 0) { |
463 | crtc->primary->crtc = crtc; | 463 | crtc->primary->crtc = crtc; |
464 | crtc->primary->fb = fb; | 464 | crtc->primary->fb = fb; |
@@ -473,20 +473,13 @@ restart: | |||
473 | } | 473 | } |
474 | 474 | ||
475 | if (ret == -EDEADLK) { | 475 | if (ret == -EDEADLK) { |
476 | dev->mode_config.acquire_ctx = NULL; | 476 | drm_modeset_backoff(&ctx); |
477 | |||
478 | retry_locking: | ||
479 | drm_modeset_backoff(ctx); | ||
480 | |||
481 | ret = drm_modeset_lock_all_ctx(dev, ctx); | ||
482 | if (ret) | ||
483 | goto retry_locking; | ||
484 | |||
485 | dev->mode_config.acquire_ctx = ctx; | ||
486 | |||
487 | goto restart; | 477 | goto restart; |
488 | } | 478 | } |
489 | 479 | ||
480 | drm_modeset_drop_locks(&ctx); | ||
481 | drm_modeset_acquire_fini(&ctx); | ||
482 | |||
490 | return ret; | 483 | return ret; |
491 | } | 484 | } |
492 | 485 | ||
@@ -624,7 +617,6 @@ static int vmw_fb_set_par(struct fb_info *info) | |||
624 | } | 617 | } |
625 | 618 | ||
626 | mutex_lock(&par->bo_mutex); | 619 | mutex_lock(&par->bo_mutex); |
627 | drm_modeset_lock_all(vmw_priv->dev); | ||
628 | ret = vmw_fb_kms_framebuffer(info); | 620 | ret = vmw_fb_kms_framebuffer(info); |
629 | if (ret) | 621 | if (ret) |
630 | goto out_unlock; | 622 | goto out_unlock; |
@@ -657,7 +649,6 @@ out_unlock: | |||
657 | drm_mode_destroy(vmw_priv->dev, old_mode); | 649 | drm_mode_destroy(vmw_priv->dev, old_mode); |
658 | par->set_mode = mode; | 650 | par->set_mode = mode; |
659 | 651 | ||
660 | drm_modeset_unlock_all(vmw_priv->dev); | ||
661 | mutex_unlock(&par->bo_mutex); | 652 | mutex_unlock(&par->bo_mutex); |
662 | 653 | ||
663 | return ret; | 654 | return ret; |
@@ -713,18 +704,14 @@ int vmw_fb_init(struct vmw_private *vmw_priv) | |||
713 | par->max_width = fb_width; | 704 | par->max_width = fb_width; |
714 | par->max_height = fb_height; | 705 | par->max_height = fb_height; |
715 | 706 | ||
716 | drm_modeset_lock_all(vmw_priv->dev); | ||
717 | ret = vmw_kms_fbdev_init_data(vmw_priv, 0, par->max_width, | 707 | ret = vmw_kms_fbdev_init_data(vmw_priv, 0, par->max_width, |
718 | par->max_height, &par->con, | 708 | par->max_height, &par->con, |
719 | &par->crtc, &init_mode); | 709 | &par->crtc, &init_mode); |
720 | if (ret) { | 710 | if (ret) |
721 | drm_modeset_unlock_all(vmw_priv->dev); | ||
722 | goto err_kms; | 711 | goto err_kms; |
723 | } | ||
724 | 712 | ||
725 | info->var.xres = init_mode->hdisplay; | 713 | info->var.xres = init_mode->hdisplay; |
726 | info->var.yres = init_mode->vdisplay; | 714 | info->var.yres = init_mode->vdisplay; |
727 | drm_modeset_unlock_all(vmw_priv->dev); | ||
728 | 715 | ||
729 | /* | 716 | /* |
730 | * Create buffers and alloc memory | 717 | * Create buffers and alloc memory |
@@ -832,7 +819,9 @@ int vmw_fb_close(struct vmw_private *vmw_priv) | |||
832 | cancel_delayed_work_sync(&par->local_work); | 819 | cancel_delayed_work_sync(&par->local_work); |
833 | unregister_framebuffer(info); | 820 | unregister_framebuffer(info); |
834 | 821 | ||
822 | mutex_lock(&par->bo_mutex); | ||
835 | (void) vmw_fb_kms_detach(par, true, true); | 823 | (void) vmw_fb_kms_detach(par, true, true); |
824 | mutex_unlock(&par->bo_mutex); | ||
836 | 825 | ||
837 | vfree(par->vmalloc); | 826 | vfree(par->vmalloc); |
838 | framebuffer_release(info); | 827 | framebuffer_release(info); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index f11601b6fd74..96fd7a03d2f8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -2595,6 +2595,7 @@ void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx, | |||
2595 | vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf, | 2595 | vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf, |
2596 | out_fence, NULL); | 2596 | out_fence, NULL); |
2597 | 2597 | ||
2598 | vmw_dmabuf_unreference(&ctx->buf); | ||
2598 | vmw_resource_unreserve(res, false, NULL, 0); | 2599 | vmw_resource_unreserve(res, false, NULL, 0); |
2599 | mutex_unlock(&res->dev_priv->cmdbuf_mutex); | 2600 | mutex_unlock(&res->dev_priv->cmdbuf_mutex); |
2600 | } | 2601 | } |
@@ -2680,7 +2681,9 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, | |||
2680 | struct vmw_display_unit *du; | 2681 | struct vmw_display_unit *du; |
2681 | struct drm_display_mode *mode; | 2682 | struct drm_display_mode *mode; |
2682 | int i = 0; | 2683 | int i = 0; |
2684 | int ret = 0; | ||
2683 | 2685 | ||
2686 | mutex_lock(&dev_priv->dev->mode_config.mutex); | ||
2684 | list_for_each_entry(con, &dev_priv->dev->mode_config.connector_list, | 2687 | list_for_each_entry(con, &dev_priv->dev->mode_config.connector_list, |
2685 | head) { | 2688 | head) { |
2686 | if (i == unit) | 2689 | if (i == unit) |
@@ -2691,7 +2694,8 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, | |||
2691 | 2694 | ||
2692 | if (i != unit) { | 2695 | if (i != unit) { |
2693 | DRM_ERROR("Could not find initial display unit.\n"); | 2696 | DRM_ERROR("Could not find initial display unit.\n"); |
2694 | return -EINVAL; | 2697 | ret = -EINVAL; |
2698 | goto out_unlock; | ||
2695 | } | 2699 | } |
2696 | 2700 | ||
2697 | if (list_empty(&con->modes)) | 2701 | if (list_empty(&con->modes)) |
@@ -2699,7 +2703,8 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, | |||
2699 | 2703 | ||
2700 | if (list_empty(&con->modes)) { | 2704 | if (list_empty(&con->modes)) { |
2701 | DRM_ERROR("Could not find initial display mode.\n"); | 2705 | DRM_ERROR("Could not find initial display mode.\n"); |
2702 | return -EINVAL; | 2706 | ret = -EINVAL; |
2707 | goto out_unlock; | ||
2703 | } | 2708 | } |
2704 | 2709 | ||
2705 | du = vmw_connector_to_du(con); | 2710 | du = vmw_connector_to_du(con); |
@@ -2720,7 +2725,10 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv, | |||
2720 | head); | 2725 | head); |
2721 | } | 2726 | } |
2722 | 2727 | ||
2723 | return 0; | 2728 | out_unlock: |
2729 | mutex_unlock(&dev_priv->dev->mode_config.mutex); | ||
2730 | |||
2731 | return ret; | ||
2724 | } | 2732 | } |
2725 | 2733 | ||
2726 | /** | 2734 | /** |