]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
Merge tag 'drm-fixes-2023-02-17' of git://anongit.freedesktop.org/drm/drm
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Feb 2023 04:23:32 +0000 (20:23 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 17 Feb 2023 04:23:32 +0000 (20:23 -0800)
Pull drm fixes from Dave Airlie:
 "Just a final collection of misc fixes, the biggest disables the
  recently added dynamic debugging support, it has a regression that
  needs some bigger fixes.

  Otherwise a bunch of fixes across the board, vc4, amdgpu and vmwgfx
  mostly, with some smaller i915 and ast fixes.

  drm:
   - dynamic debug disable for now

  fbdev:
   - deferred i/o device close fix

  amdgpu:
   - Fix GC11.x suspend warning
   - Fix display warning

  vc4:
   - YUV planes fix
   - hdmi display fix
   - crtc reduced blanking fix

  ast:
   - fix start address computation

  vmwgfx:
   - fix bo/handle races

  i915:
   - gen11 WA fix"

* tag 'drm-fixes-2023-02-17' of git://anongit.freedesktop.org/drm/drm:
  drm/amd/display: Fail atomic_check early on normalize_zpos error
  drm/amd/amdgpu: fix warning during suspend
  drm/vmwgfx: Do not drop the reference to the handle too soon
  drm/vmwgfx: Stop accessing buffer objects which failed init
  drm/i915/gen11: Wa_1408615072/Wa_1407596294 should be on GT list
  drm: Disable dynamic debug as broken
  drm/ast: Fix start address computation
  fbdev: Fix invalid page access after closing deferred I/O devices
  drm/vc4: crtc: Increase setup cost in core clock calculation to handle extreme reduced blanking
  drm/vc4: hdmi: Always enable GCP with AVMUTE cleared
  drm/vc4: Fix YUV plane handling when planes are in different buffers

19 files changed:
drivers/gpu/drm/Kconfig
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/ast/ast_mode.c
drivers/gpu/drm/i915/gt/intel_workarounds.c
drivers/gpu/drm/vc4/vc4_crtc.c
drivers/gpu/drm/vc4/vc4_hdmi.c
drivers/gpu/drm/vc4/vc4_plane.c
drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
drivers/video/fbdev/core/fb_defio.c
drivers/video/fbdev/core/fbmem.c
include/linux/fb.h

index 315cbdf6197927382caa6025a285e240e97a7712..9abfb482b615e7ccf282baa8c0b93e437177a54f 100644 (file)
@@ -53,7 +53,8 @@ config DRM_DEBUG_MM
 
 config DRM_USE_DYNAMIC_DEBUG
        bool "use dynamic debug to implement drm.debug"
-       default y
+       default n
+       depends on BROKEN
        depends on DRM
        depends on DYNAMIC_DEBUG || DYNAMIC_DEBUG_CORE
        depends on JUMP_LABEL
index 2f28a8c02f6412b687c7b5cace7bc670df352410..fbf2f24169eb5f9accc46796872ae6f8f54440f4 100644 (file)
@@ -4268,6 +4268,9 @@ exit:
        }
        adev->in_suspend = false;
 
+       if (adev->enable_mes)
+               amdgpu_mes_self_test(adev);
+
        if (amdgpu_acpi_smart_shift_update(dev, AMDGPU_SS_DEV_D0))
                DRM_WARN("smart shift update failed\n");
 
index 5dff79e8f3011010c85622a31bb48b1dc9453092..1c4787000a5f392e08018e9ac5d27d363cc7dc85 100644 (file)
@@ -1344,7 +1344,7 @@ static int mes_v11_0_late_init(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
        /* it's only intended for use in mes_self_test case, not for s0ix and reset */
-       if (!amdgpu_in_reset(adev) && !adev->in_s0ix &&
+       if (!amdgpu_in_reset(adev) && !adev->in_s0ix && !adev->in_suspend &&
            (adev->ip_versions[GC_HWIP][0] != IP_VERSION(11, 0, 3)))
                amdgpu_mes_self_test(adev);
 
index 93dee3d1a483f184ae5224b89c4f9f5fae6fec4c..9c7b69d377bd3c8752e5e2133dce3a74174aed34 100644 (file)
@@ -9658,7 +9658,11 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
         * `dcn10_can_pipe_disable_cursor`). By now, all modified planes are in
         * atomic state, so call drm helper to normalize zpos.
         */
-       drm_atomic_normalize_zpos(dev, state);
+       ret = drm_atomic_normalize_zpos(dev, state);
+       if (ret) {
+               drm_dbg(dev, "drm_atomic_normalize_zpos() failed\n");
+               goto fail;
+       }
 
        /* Remove exiting planes if they are modified */
        for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
index c7443317c747cab918fb565e7bfea468c1c06017..66a4a41c3fe94468c4c91519871ce5edb06403f9 100644 (file)
@@ -714,7 +714,7 @@ static int ast_primary_plane_init(struct ast_private *ast)
        struct ast_plane *ast_primary_plane = &ast->primary_plane;
        struct drm_plane *primary_plane = &ast_primary_plane->base;
        void __iomem *vaddr = ast->vram;
-       u64 offset = ast->vram_base;
+       u64 offset = 0; /* with shmem, the primary plane is always at offset 0 */
        unsigned long cursor_size = roundup(AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE, PAGE_SIZE);
        unsigned long size = ast->vram_fb_available - cursor_size;
        int ret;
@@ -972,7 +972,7 @@ static int ast_cursor_plane_init(struct ast_private *ast)
                return -ENOMEM;
 
        vaddr = ast->vram + ast->vram_fb_available - size;
-       offset = ast->vram_base + ast->vram_fb_available - size;
+       offset = ast->vram_fb_available - size;
 
        ret = ast_plane_init(dev, ast_cursor_plane, vaddr, offset, size,
                             0x01, &ast_cursor_plane_funcs,
index 949c19339015b074af9e75662edda4268dbc4912..a0740308555d85f12af2d16f3766409f9564ecc4 100644 (file)
@@ -1355,6 +1355,13 @@ icl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
                    GAMT_CHKN_BIT_REG,
                    GAMT_CHKN_DISABLE_L3_COH_PIPE);
 
+       /*
+        * Wa_1408615072:icl,ehl  (vsunit)
+        * Wa_1407596294:icl,ehl  (hsunit)
+        */
+       wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE,
+                   VSUNIT_CLKGATE_DIS | HSUNIT_CLKGATE_DIS);
+
        /* Wa_1407352427:icl,ehl */
        wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE2,
                    PSDUNIT_CLKGATE_DIS);
@@ -2539,13 +2546,6 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
                wa_masked_en(wal, GEN9_CSFE_CHICKEN1_RCS,
                             GEN11_ENABLE_32_PLANE_MODE);
 
-               /*
-                * Wa_1408615072:icl,ehl  (vsunit)
-                * Wa_1407596294:icl,ehl  (hsunit)
-                */
-               wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE,
-                           VSUNIT_CLKGATE_DIS | HSUNIT_CLKGATE_DIS);
-
                /*
                 * Wa_1408767742:icl[a2..forever],ehl[all]
                 * Wa_1605460711:icl[a0..c0]
index 0108613e79d53ce6b110491dcba3ec0991561cfe..7258975331ca71a81326b84f7d487069801d96dc 100644 (file)
@@ -711,7 +711,7 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
                struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
 
                if (vc4_encoder->type == VC4_ENCODER_TYPE_HDMI0) {
-                       vc4_state->hvs_load = max(mode->clock * mode->hdisplay / mode->htotal + 1000,
+                       vc4_state->hvs_load = max(mode->clock * mode->hdisplay / mode->htotal + 8000,
                                                  mode->clock * 9 / 10) * 1000;
                } else {
                        vc4_state->hvs_load = mode->clock * 1000;
index 55744216392b295a9861f789d395953704534764..7546103f149973e924f28b09c96559e1f97fafdd 100644 (file)
 #define VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_1_SHIFT 8
 #define VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_1_MASK  VC4_MASK(15, 8)
 
+#define VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_0_MASK  VC4_MASK(7, 0)
+#define VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_0_SET_AVMUTE    BIT(0)
+#define VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_0_CLEAR_AVMUTE  BIT(4)
+
 # define VC4_HD_M_SW_RST                       BIT(2)
 # define VC4_HD_M_ENABLE                       BIT(0)
 
@@ -1306,7 +1310,6 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
                                        VC4_HDMI_VERTB_VBP));
        unsigned long flags;
        unsigned char gcp;
-       bool gcp_en;
        u32 reg;
        int idx;
 
@@ -1341,16 +1344,13 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
        switch (vc4_state->output_bpc) {
        case 12:
                gcp = 6;
-               gcp_en = true;
                break;
        case 10:
                gcp = 5;
-               gcp_en = true;
                break;
        case 8:
        default:
-               gcp = 4;
-               gcp_en = false;
+               gcp = 0;
                break;
        }
 
@@ -1359,8 +1359,7 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
         * doesn't signal in GCP.
         */
        if (vc4_state->output_format == VC4_HDMI_OUTPUT_YUV422) {
-               gcp = 4;
-               gcp_en = false;
+               gcp = 0;
        }
 
        reg = HDMI_READ(HDMI_DEEP_COLOR_CONFIG_1);
@@ -1373,11 +1372,12 @@ static void vc5_hdmi_set_timings(struct vc4_hdmi *vc4_hdmi,
        reg = HDMI_READ(HDMI_GCP_WORD_1);
        reg &= ~VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_1_MASK;
        reg |= VC4_SET_FIELD(gcp, VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_1);
+       reg &= ~VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_0_MASK;
+       reg |= VC5_HDMI_GCP_WORD_1_GCP_SUBPACKET_BYTE_0_CLEAR_AVMUTE;
        HDMI_WRITE(HDMI_GCP_WORD_1, reg);
 
        reg = HDMI_READ(HDMI_GCP_CONFIG);
-       reg &= ~VC5_HDMI_GCP_CONFIG_GCP_ENABLE;
-       reg |= gcp_en ? VC5_HDMI_GCP_CONFIG_GCP_ENABLE : 0;
+       reg |= VC5_HDMI_GCP_CONFIG_GCP_ENABLE;
        HDMI_WRITE(HDMI_GCP_CONFIG, reg);
 
        reg = HDMI_READ(HDMI_MISC_CONTROL);
index 8b92a45a3c898f8ea9d75722e1c940310b7f474b..bd5acc4a8687613ab48697b8eaaf1d216ae547a9 100644 (file)
@@ -340,7 +340,7 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
 {
        struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
        struct drm_framebuffer *fb = state->fb;
-       struct drm_gem_dma_object *bo = drm_fb_dma_get_gem_obj(fb, 0);
+       struct drm_gem_dma_object *bo;
        int num_planes = fb->format->num_planes;
        struct drm_crtc_state *crtc_state;
        u32 h_subsample = fb->format->hsub;
@@ -359,8 +359,10 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
        if (ret)
                return ret;
 
-       for (i = 0; i < num_planes; i++)
+       for (i = 0; i < num_planes; i++) {
+               bo = drm_fb_dma_get_gem_obj(fb, i);
                vc4_state->offsets[i] = bo->dma_addr + fb->offsets[i];
+       }
 
        /*
         * We don't support subpixel source positioning for scaling,
index aa1cd5126a321dd8f72e104304c537b75b864fb5..4dcf2eb7aa801a378a29bb0bbfa9b94f54d3a08e 100644 (file)
@@ -462,6 +462,9 @@ int vmw_bo_create(struct vmw_private *vmw,
                return -ENOMEM;
        }
 
+       /*
+        * vmw_bo_init will delete the *p_bo object if it fails
+        */
        ret = vmw_bo_init(vmw, *p_bo, size,
                          placement, interruptible, pin,
                          bo_free);
@@ -470,7 +473,6 @@ int vmw_bo_create(struct vmw_private *vmw,
 
        return ret;
 out_error:
-       kfree(*p_bo);
        *p_bo = NULL;
        return ret;
 }
@@ -596,6 +598,7 @@ static int vmw_user_bo_synccpu_release(struct drm_file *filp,
                ttm_bo_put(&vmw_bo->base);
        }
 
+       drm_gem_object_put(&vmw_bo->base.base);
        return ret;
 }
 
@@ -636,6 +639,7 @@ int vmw_user_bo_synccpu_ioctl(struct drm_device *dev, void *data,
 
                ret = vmw_user_bo_synccpu_grab(vbo, arg->flags);
                vmw_bo_unreference(&vbo);
+               drm_gem_object_put(&vbo->base.base);
                if (unlikely(ret != 0)) {
                        if (ret == -ERESTARTSYS || ret == -EBUSY)
                                return -EBUSY;
@@ -693,7 +697,7 @@ int vmw_bo_unref_ioctl(struct drm_device *dev, void *data,
  * struct vmw_buffer_object should be placed.
  * Return: Zero on success, Negative error code on error.
  *
- * The vmw buffer object pointer will be refcounted.
+ * The vmw buffer object pointer will be refcounted (both ttm and gem)
  */
 int vmw_user_bo_lookup(struct drm_file *filp,
                       uint32_t handle,
@@ -710,7 +714,6 @@ int vmw_user_bo_lookup(struct drm_file *filp,
 
        *out = gem_to_vmw_bo(gobj);
        ttm_bo_get(&(*out)->base);
-       drm_gem_object_put(gobj);
 
        return 0;
 }
@@ -791,7 +794,8 @@ int vmw_dumb_create(struct drm_file *file_priv,
        ret = vmw_gem_object_create_with_handle(dev_priv, file_priv,
                                                args->size, &args->handle,
                                                &vbo);
-
+       /* drop reference from allocate - handle holds it now */
+       drm_gem_object_put(&vbo->base.base);
        return ret;
 }
 
index a44d53e33cdb14346545fe61e99f076004201b6b..c0686283ffd164e96c4d7669efca67093628f61e 100644 (file)
@@ -1160,6 +1160,7 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv,
        }
        ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, true, false);
        ttm_bo_put(&vmw_bo->base);
+       drm_gem_object_put(&vmw_bo->base.base);
        if (unlikely(ret != 0))
                return ret;
 
@@ -1214,6 +1215,7 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv,
        }
        ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, false, false);
        ttm_bo_put(&vmw_bo->base);
+       drm_gem_object_put(&vmw_bo->base.base);
        if (unlikely(ret != 0))
                return ret;
 
index ce609e7d758f85a473f5e477c844f6a620a27239..4d2c28e39f4e099dd6a83d74bdbb7366fc9fd174 100644 (file)
@@ -146,14 +146,12 @@ int vmw_gem_object_create_with_handle(struct vmw_private *dev_priv,
                                    &vmw_sys_placement :
                                    &vmw_vram_sys_placement,
                            true, false, &vmw_gem_destroy, p_vbo);
-
-       (*p_vbo)->base.base.funcs = &vmw_gem_object_funcs;
        if (ret != 0)
                goto out_no_bo;
 
+       (*p_vbo)->base.base.funcs = &vmw_gem_object_funcs;
+
        ret = drm_gem_handle_create(filp, &(*p_vbo)->base.base, handle);
-       /* drop reference from allocate - handle holds it now */
-       drm_gem_object_put(&(*p_vbo)->base.base);
 out_no_bo:
        return ret;
 }
@@ -180,6 +178,8 @@ int vmw_gem_object_create_ioctl(struct drm_device *dev, void *data,
        rep->map_handle = drm_vma_node_offset_addr(&vbo->base.base.vma_node);
        rep->cur_gmr_id = handle;
        rep->cur_gmr_offset = 0;
+       /* drop reference from allocate - handle holds it now */
+       drm_gem_object_put(&vbo->base.base);
 out_no_bo:
        return ret;
 }
index 257f090071f1edd54784d3050220d9824d3f7962..445d619e1fdc804e9b780411ad7087067f7c3b88 100644 (file)
@@ -1815,8 +1815,10 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
 
 err_out:
        /* vmw_user_lookup_handle takes one ref so does new_fb */
-       if (bo)
+       if (bo) {
                vmw_bo_unreference(&bo);
+               drm_gem_object_put(&bo->base.base);
+       }
        if (surface)
                vmw_surface_unreference(&surface);
 
index e9f5c89b4ca6936b82d3e1eb91acfe6389b6abbd..b5b311f2a91a4061511a5afb56c65c00dd7f93c0 100644 (file)
@@ -458,6 +458,7 @@ int vmw_overlay_ioctl(struct drm_device *dev, void *data,
        ret = vmw_overlay_update_stream(dev_priv, buf, arg, true);
 
        vmw_bo_unreference(&buf);
+       drm_gem_object_put(&buf->base.base);
 
 out_unlock:
        mutex_unlock(&overlay->mutex);
index 108a496b5d1895ad4df21726d5e5222d56a7eb15..51e83dfa1cace6a8362523cb84b23d03c89562dc 100644 (file)
@@ -807,6 +807,7 @@ static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv,
                                    num_output_sig, tfile, shader_handle);
 out_bad_arg:
        vmw_bo_unreference(&buffer);
+       drm_gem_object_put(&buffer->base.base);
        return ret;
 }
 
index 3bc63ae768f34e8e1dfa1321fb758a72e92d16ea..dcfb003841b314886e465ed954f363db66b745b1 100644 (file)
@@ -683,7 +683,7 @@ static void vmw_user_surface_base_release(struct ttm_base_object **p_base)
            container_of(base, struct vmw_user_surface, prime.base);
        struct vmw_resource *res = &user_srf->srf.res;
 
-       if (base->shareable && res && res->backup)
+       if (res && res->backup)
                drm_gem_object_put(&res->backup->base.base);
 
        *p_base = NULL;
@@ -864,7 +864,11 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
                        goto out_unlock;
                }
                vmw_bo_reference(res->backup);
-               drm_gem_object_get(&res->backup->base.base);
+               /*
+                * We don't expose the handle to the userspace and surface
+                * already holds a gem reference
+                */
+               drm_gem_handle_delete(file_priv, backup_handle);
        }
 
        tmp = vmw_resource_reference(&srf->res);
@@ -1568,8 +1572,6 @@ vmw_gb_surface_define_internal(struct drm_device *dev,
                        drm_vma_node_offset_addr(&res->backup->base.base.vma_node);
                rep->buffer_size = res->backup->base.base.size;
                rep->buffer_handle = backup_handle;
-               if (user_srf->prime.base.shareable)
-                       drm_gem_object_get(&res->backup->base.base);
        } else {
                rep->buffer_map_handle = 0;
                rep->buffer_size = 0;
index c730253ab85cee86a796aa784179bfb13c3c4b7a..583cbcf0944670c844413dd3c678ee733b8ce0e0 100644 (file)
@@ -313,7 +313,7 @@ void fb_deferred_io_open(struct fb_info *info,
 }
 EXPORT_SYMBOL_GPL(fb_deferred_io_open);
 
-void fb_deferred_io_cleanup(struct fb_info *info)
+void fb_deferred_io_release(struct fb_info *info)
 {
        struct fb_deferred_io *fbdefio = info->fbdefio;
        struct page *page;
@@ -327,6 +327,14 @@ void fb_deferred_io_cleanup(struct fb_info *info)
                page = fb_deferred_io_page(info, i);
                page->mapping = NULL;
        }
+}
+EXPORT_SYMBOL_GPL(fb_deferred_io_release);
+
+void fb_deferred_io_cleanup(struct fb_info *info)
+{
+       struct fb_deferred_io *fbdefio = info->fbdefio;
+
+       fb_deferred_io_release(info);
 
        kvfree(info->pagerefs);
        mutex_destroy(&fbdefio->lock);
index 3a6c8458eb8d5349c84230f4a9b8e30b5a20882a..ab3545a00abc530967d75de3cb163a8bb0ca2555 100644 (file)
@@ -1454,6 +1454,10 @@ __releases(&info->lock)
        struct fb_info * const info = file->private_data;
 
        lock_fb_info(info);
+#if IS_ENABLED(CONFIG_FB_DEFERRED_IO)
+       if (info->fbdefio)
+               fb_deferred_io_release(info);
+#endif
        if (info->fbops->fb_release)
                info->fbops->fb_release(info,1);
        module_put(info->fbops->owner);
index 96b96323e9cba93bfa8e10f8c0e749f69aa17a3e..73eb1f85ea8e5f09790301210ebfac5ba13c642a 100644 (file)
@@ -662,6 +662,7 @@ extern int  fb_deferred_io_init(struct fb_info *info);
 extern void fb_deferred_io_open(struct fb_info *info,
                                struct inode *inode,
                                struct file *file);
+extern void fb_deferred_io_release(struct fb_info *info);
 extern void fb_deferred_io_cleanup(struct fb_info *info);
 extern int fb_deferred_io_fsync(struct file *file, loff_t start,
                                loff_t end, int datasync);