diff options
| -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 | /** |
