From 2a8f20bb645cca835f9b9b615443e894e5d05d2e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 22 Jan 2021 09:10:58 +0000 Subject: [PATCH 1/9] drm/i915: Restrict DRM_I915_DEBUG to developer builds Let's not encourage everybody to build i915's debug code, and certainly not the build robots who need to scrutinise the production build. Since CI will complain if the debug build is broken, having the other build bots focus on the builds we don't cover ourselves should improve the build coverage. Reported-by: Stephen Rothwell Fixes: 4f86975f539d ("drm/i915: Add DEBUG_GEM to the recommended CI config") Signed-off-by: Chris Wilson Acked-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20210122091058.5145-1-chris@chris-wilson.co.uk (cherry picked from commit c442f658299d59b327a4bf21457ec8ece936f133) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/Kconfig.debug | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug index be76054c01d8..72a38f28393f 100644 --- a/drivers/gpu/drm/i915/Kconfig.debug +++ b/drivers/gpu/drm/i915/Kconfig.debug @@ -19,6 +19,8 @@ config DRM_I915_WERROR config DRM_I915_DEBUG bool "Enable additional driver debugging" depends on DRM_I915 + depends on EXPERT # only for developers + depends on !COMPILE_TEST # never built by robots select DEBUG_FS select PREEMPT_COUNT select I2C_CHARDEV From fbb2bdd22a994d415691c132ecaddcf99a2786e7 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 25 Jan 2021 11:48:30 +0300 Subject: [PATCH 2/9] drm/i915/gvt: fix uninitialized return in intel_gvt_update_reg_whitelist() Smatch found an uninitialized variable bug in this code: drivers/gpu/drm/i915/gvt/cmd_parser.c:3191 intel_gvt_update_reg_whitelist() error: uninitialized symbol 'ret'. The first thing that Smatch complains about is that "ret" isn't set if we don't enter the "for_each_engine(engine, &dev_priv->gt, id) {" loop. Presumably we always have at least one engine so that's a false positive. But it's definitely a bug to not set "ret" if i915_gem_object_pin_map() fails. Let's fix the bug and silence the false positive. Fixes: 493f30cd086e ("drm/i915/gvt: parse init context to update cmd accessible reg whitelist") Signed-off-by: Dan Carpenter Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/YA6F3oF8mRaNQWjb@mwanda (cherry picked from commit 784f70e17e6bc423a04fb6524634a76f68ab1192) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gvt/cmd_parser.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index 7fb91de06557..d54ea0e4681d 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -3103,7 +3103,7 @@ void intel_gvt_update_reg_whitelist(struct intel_vgpu *vgpu) struct intel_vgpu_submission *s = &vgpu->submission; struct i915_request *requests[I915_NUM_ENGINES] = {}; bool is_ctx_pinned[I915_NUM_ENGINES] = {}; - int ret; + int ret = 0; if (gvt->is_reg_whitelist_updated) return; @@ -3157,6 +3157,7 @@ void intel_gvt_update_reg_whitelist(struct intel_vgpu *vgpu) if (IS_ERR(vaddr)) { gvt_err("failed to pin init ctx obj, ring=%d, err=%lx\n", id, PTR_ERR(vaddr)); + ret = PTR_ERR(vaddr); goto out; } From 54fd4b9a4ac8b771cf345ca4dc3f47045a27fdc1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 25 Jan 2021 11:47:12 +0300 Subject: [PATCH 3/9] drm/i915/gem: Fix oops in error handling code This code will Oops when it tries to i915_gem_object_free(obj) because "obj" is an error pointer. Fixes: 97d553963250 ("drm/i915/region: convert object_create into object_init") Signed-off-by: Dan Carpenter Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/YA6FkPn5S4ZDUGxq@mwanda (cherry picked from commit ad8db423a30f0ac39a5483dfd726058135ff2bd2) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c index 551935348ad8..a1e197a6e999 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -753,22 +753,18 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_i915_private *i915, mutex_lock(&i915->mm.stolen_lock); ret = drm_mm_reserve_node(&i915->mm.stolen, stolen); mutex_unlock(&i915->mm.stolen_lock); - if (ret) { - obj = ERR_PTR(ret); + if (ret) goto err_free; - } obj = i915_gem_object_alloc(); if (!obj) { - obj = ERR_PTR(-ENOMEM); + ret = -ENOMEM; goto err_stolen; } ret = __i915_gem_object_create_stolen(mem, obj, stolen); - if (ret) { - obj = ERR_PTR(ret); + if (ret) goto err_object_free; - } i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE); return obj; @@ -779,7 +775,7 @@ err_stolen: i915_gem_stolen_remove_node(i915, stolen); err_free: kfree(stolen); - return obj; + return ERR_PTR(ret); } bool i915_gem_object_is_stolen(const struct drm_i915_gem_object *obj) From 29d88083d6ff697cedf918efd927d2dfff0bf9c4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 23 Jan 2021 14:55:43 +0000 Subject: [PATCH 4/9] drm/i915/gem: Move freeze/freeze_late next to suspend/suspend_late Push the hibernate pm routines next to the suspend pm routines in gem/i915_gem_pm.c. This has the side-effect of putting the wbinvd() abusers next to each other. Reported-by: Guenter Roeck Fixes: 30d2bfd09383 ("drm/i915/gem: Almagamate clflushes on freeze") Signed-off-by: Chris Wilson Cc: Matthew Auld Reviewed-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20210123145543.10533-1-chris@chris-wilson.co.uk (cherry picked from commit 6d8f02207420e76db693a00ccb44792474e297fc) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gem/i915_gem_pm.c | 41 +++++++++++++++++++++++ drivers/gpu/drm/i915/gem/i915_gem_pm.h | 3 ++ drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/i915_gem.c | 41 ----------------------- drivers/gpu/drm/i915/selftests/i915_gem.c | 1 + 6 files changed, 46 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pm.c b/drivers/gpu/drm/i915/gem/i915_gem_pm.c index 215766cc22bf..000e1cd8e920 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pm.c @@ -85,6 +85,47 @@ void i915_gem_suspend_late(struct drm_i915_private *i915) wbinvd_on_all_cpus(); } +int i915_gem_freeze(struct drm_i915_private *i915) +{ + /* Discard all purgeable objects, let userspace recover those as + * required after resuming. + */ + i915_gem_shrink_all(i915); + + return 0; +} + +int i915_gem_freeze_late(struct drm_i915_private *i915) +{ + struct drm_i915_gem_object *obj; + intel_wakeref_t wakeref; + + /* + * Called just before we write the hibernation image. + * + * We need to update the domain tracking to reflect that the CPU + * will be accessing all the pages to create and restore from the + * hibernation, and so upon restoration those pages will be in the + * CPU domain. + * + * To make sure the hibernation image contains the latest state, + * we update that state just before writing out the image. + * + * To try and reduce the hibernation image, we manually shrink + * the objects as well, see i915_gem_freeze() + */ + + with_intel_runtime_pm(&i915->runtime_pm, wakeref) + i915_gem_shrink(i915, -1UL, NULL, ~0); + i915_gem_drain_freed_objects(i915); + + wbinvd_on_all_cpus(); + list_for_each_entry(obj, &i915->mm.shrink_list, mm.link) + __start_cpu_write(obj); + + return 0; +} + void i915_gem_resume(struct drm_i915_private *i915) { GEM_TRACE("%s\n", dev_name(i915->drm.dev)); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pm.h b/drivers/gpu/drm/i915/gem/i915_gem_pm.h index 26b78dbdc225..c9a66630e92e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pm.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_pm.h @@ -19,4 +19,7 @@ void i915_gem_idle_work_handler(struct work_struct *work); void i915_gem_suspend(struct drm_i915_private *i915); void i915_gem_suspend_late(struct drm_i915_private *i915); +int i915_gem_freeze(struct drm_i915_private *i915); +int i915_gem_freeze_late(struct drm_i915_private *i915); + #endif /* __I915_GEM_PM_H__ */ diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2febda554bca..8e9cb44e66e5 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -65,6 +65,7 @@ #include "gem/i915_gem_context.h" #include "gem/i915_gem_ioctls.h" #include "gem/i915_gem_mman.h" +#include "gem/i915_gem_pm.h" #include "gt/intel_gt.h" #include "gt/intel_gt_pm.h" #include "gt/intel_rc6.h" diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 574f3575879d..56cc9191b8d0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1800,8 +1800,6 @@ int i915_gem_init_userptr(struct drm_i915_private *dev_priv); void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv); void i915_gem_init_early(struct drm_i915_private *dev_priv); void i915_gem_cleanup_early(struct drm_i915_private *dev_priv); -int i915_gem_freeze(struct drm_i915_private *dev_priv); -int i915_gem_freeze_late(struct drm_i915_private *dev_priv); struct intel_memory_region *i915_gem_shmem_setup(struct drm_i915_private *i915); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 9b04dff5eb32..aa4490934469 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1145,47 +1145,6 @@ void i915_gem_cleanup_early(struct drm_i915_private *dev_priv) drm_WARN_ON(&dev_priv->drm, dev_priv->mm.shrink_count); } -int i915_gem_freeze(struct drm_i915_private *dev_priv) -{ - /* Discard all purgeable objects, let userspace recover those as - * required after resuming. - */ - i915_gem_shrink_all(dev_priv); - - return 0; -} - -int i915_gem_freeze_late(struct drm_i915_private *i915) -{ - struct drm_i915_gem_object *obj; - intel_wakeref_t wakeref; - - /* - * Called just before we write the hibernation image. - * - * We need to update the domain tracking to reflect that the CPU - * will be accessing all the pages to create and restore from the - * hibernation, and so upon restoration those pages will be in the - * CPU domain. - * - * To make sure the hibernation image contains the latest state, - * we update that state just before writing out the image. - * - * To try and reduce the hibernation image, we manually shrink - * the objects as well, see i915_gem_freeze() - */ - - with_intel_runtime_pm(&i915->runtime_pm, wakeref) - i915_gem_shrink(i915, -1UL, NULL, ~0); - i915_gem_drain_freed_objects(i915); - - wbinvd_on_all_cpus(); - list_for_each_entry(obj, &i915->mm.shrink_list, mm.link) - __start_cpu_write(obj); - - return 0; -} - int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file) { struct drm_i915_file_private *file_priv; diff --git a/drivers/gpu/drm/i915/selftests/i915_gem.c b/drivers/gpu/drm/i915/selftests/i915_gem.c index 412e21604a05..dc394fb7ccfa 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem.c @@ -8,6 +8,7 @@ #include "gem/selftests/igt_gem_utils.h" #include "gem/selftests/mock_context.h" +#include "gem/i915_gem_pm.h" #include "gt/intel_gt.h" #include "gt/intel_gt_pm.h" From 58586680ffadc37636120d9f59955aa5f7a32b7d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 25 Jan 2021 22:01:52 +0000 Subject: [PATCH 5/9] drm/i915: Disable atomics in L3 for gen9 Enabling atomic operations in L3 leads to unrecoverable GPU hangs, as the machine stops responding milliseconds after receipt of the reset request [GDRT]. By disabling the cached atomics, the hang do not occur and we presume the GPU would reset normally for similar hangs. Sadly this is a shotgun approach, but since the impact is critical it is better to err on the safe side and work back from there. Reported-by: Jason Ekstrand Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=110998 Signed-off-by: Chris Wilson Cc: Jason Ekstrand Cc: Mika Kuoppala Cc: Tvrtko Ursulin Cc: Joonas Lahtinen Reviewed-by: Jason Ekstrand Link: https://patchwork.freedesktop.org/patch/msgid/20210125220152.24070-1-chris@chris-wilson.co.uk Cc: stable@vger.kernel.org (cherry picked from commit b267c7ae0ad5b437b068f46919b17f85000154b4) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gt/intel_workarounds.c | 8 ++++++++ drivers/gpu/drm/i915/i915_reg.h | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index 3fdcd5ff71dd..ec366cf9ef56 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -1834,6 +1834,14 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal) wa_write_or(wal, GEN8_L3SQCREG4, GEN8_LQSC_FLUSH_COHERENT_LINES); + + /* Disable atomics in L3 to prevent unrecoverable hangs */ + wa_write_clr_set(wal, GEN9_SCRATCH_LNCF1, + GEN9_LNCF_NONIA_COHERENT_ATOMICS_ENABLE, 0); + wa_write_clr_set(wal, GEN8_L3SQCREG4, + GEN8_LQSQ_NONIA_COHERENT_ATOMICS_ENABLE, 0); + wa_write_clr_set(wal, GEN9_SCRATCH1, + EVICTION_PERF_FIX_ENABLE, 0); } if (IS_HASWELL(i915)) { diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 598abd2f5b5f..7146cd0f3256 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -8225,6 +8225,7 @@ enum { #define GEN11_LQSC_CLEAN_EVICT_DISABLE (1 << 6) #define GEN8_LQSC_RO_PERF_DIS (1 << 27) #define GEN8_LQSC_FLUSH_COHERENT_LINES (1 << 21) +#define GEN8_LQSQ_NONIA_COHERENT_ATOMICS_ENABLE REG_BIT(22) /* GEN8 chicken */ #define HDC_CHICKEN0 _MMIO(0x7300) @@ -12107,6 +12108,12 @@ enum skl_power_gate { #define __GEN11_VCS2_MOCS0 0x10000 #define GEN11_MFX2_MOCS(i) _MMIO(__GEN11_VCS2_MOCS0 + (i) * 4) +#define GEN9_SCRATCH_LNCF1 _MMIO(0xb008) +#define GEN9_LNCF_NONIA_COHERENT_ATOMICS_ENABLE REG_BIT(0) + +#define GEN9_SCRATCH1 _MMIO(0xb11c) +#define EVICTION_PERF_FIX_ENABLE REG_BIT(8) + #define GEN10_SCRATCH_LNCF2 _MMIO(0xb0a0) #define PMFLUSHDONE_LNICRSDROP (1 << 20) #define PMFLUSH_GAPL3UNBLOCK (1 << 21) From d5109f739c9f14a3bda249cb48b16de1065932f0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 25 Jan 2021 22:02:47 +0000 Subject: [PATCH 6/9] drm/i915/gt: Flush before changing register state Flush; invalidate; change registers; invalidate; flush. Will this finally work on every device? Or will Baytrail complain again? On the positive side, we immediately see the benefit of having hsw-gt1 in CI. Fixes: ace44e13e577 ("drm/i915/gt: Clear CACHE_MODE prior to clearing residuals") Testcase: igt/gem_render_tiled_blits # hsw-gt1 Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Akeem G Abodunrin Acked-by: Mika Kuoppala Link: https://patchwork.freedesktop.org/patch/msgid/20210125220247.31701-1-chris@chris-wilson.co.uk (cherry picked from commit d30bbd62b1bfd9e0a33c3583c5a9e5d66f60cbd7) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gt/gen7_renderclear.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/gt/gen7_renderclear.c b/drivers/gpu/drm/i915/gt/gen7_renderclear.c index 8551e6de50e8..e403eb046a43 100644 --- a/drivers/gpu/drm/i915/gt/gen7_renderclear.c +++ b/drivers/gpu/drm/i915/gt/gen7_renderclear.c @@ -393,6 +393,7 @@ static void emit_batch(struct i915_vma * const vma, desc_count); /* Reset inherited context registers */ + gen7_emit_pipeline_flush(&cmds); gen7_emit_pipeline_invalidate(&cmds); batch_add(&cmds, MI_LOAD_REGISTER_IMM(2)); batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_0_GEN7)); From 7a6c6243b44a439bda4bf099032be35ebcf53406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 3 Feb 2021 11:30:44 +0200 Subject: [PATCH 7/9] drm/i915: Reject 446-480MHz HDMI clock on GLK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The BXT/GLK DPLL can't generate certain frequencies. We already reject the 233-240MHz range on both. But on GLK the DPLL max frequency was bumped from 300MHz to 594MHz, so now we get to also worry about the 446-480MHz range (double the original problem range). Reject any frequency within the higher problematic range as well. Cc: stable@vger.kernel.org Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/3000 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210203093044.30532-1-ville.syrjala@linux.intel.com Reviewed-by: Mika Kahola (cherry picked from commit 41751b3e5c1ac656a86f8d45a8891115281b729e) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/display/intel_hdmi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index d5f4b40a8460..95919d325b0b 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2218,7 +2218,11 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, has_hdmi_sink)) return MODE_CLOCK_HIGH; - /* BXT DPLL can't generate 223-240 MHz */ + /* GLK DPLL can't generate 446-480 MHz */ + if (IS_GEMINILAKE(dev_priv) && clock > 446666 && clock < 480000) + return MODE_CLOCK_RANGE; + + /* BXT/GLK DPLL can't generate 223-240 MHz */ if (IS_GEN9_LP(dev_priv) && clock > 223333 && clock < 240000) return MODE_CLOCK_RANGE; From 80cf9a88296c53bdbb1162d93d8640c8b2f58000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 9 Feb 2021 04:19:16 +0200 Subject: [PATCH 8/9] drm/i915: Disallow plane x+w>stride on ilk+ with X-tiling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ilk+ planes get notably unhappy when the plane x+w exceeds the stride. This wasn't a problem previously because we always aligned SURF to the closest tile boundary so the x offset never got particularly large. But now with async flips we have to align to 256KiB instead and thus this becomes a real issue. On ilk/snb/ivb it looks like the accesses just wrap early to the next tile row when scanout goes past the SURF+n*stride boundary, hsw/bdw suffer more heavily and start to underrun constantly. i965/g4x appear to be immune. vlv/chv I've not yet checked. Let's borrow another trick from the skl+ code and search backwards for a better SURF offset in the hopes of getting the x offset below the limit. IIRC when I ran into a similar issue on skl years ago it was causing the hardware to fall over pretty hard as well. And let's be consistent and include i965/g4x in the check as well, just in case I just got super lucky somehow when I wasn't able to reproduce the issue. Not that it really matters since we still use 4k SURF alignment for i965/g4x anyway. Fixes: 6ede6b0616b2 ("drm/i915: Implement async flips for vlv/chv") Fixes: 4bb18054adc4 ("drm/i915: Implement async flip for ilk/snb") Fixes: 2a636e240c77 ("drm/i915: Implement async flip for ivb/hsw") Fixes: cda195f13abd ("drm/i915: Implement async flips for bdw") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20210209021918.16234-1-ville.syrjala@linux.intel.com Reviewed-by: Chris Wilson (cherry picked from commit 59fb8218c8e5001f854e7d5fdb5fb135cba58102) Signed-off-by: Rodrigo Vivi [Rodrigo also exported some functions from intel_display.c during backport] --- drivers/gpu/drm/i915/display/i9xx_plane.c | 27 ++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_display.c | 12 ++++----- drivers/gpu/drm/i915/display/intel_display.h | 6 +++++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index d30374df67f0..e3e69e6cef65 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -255,6 +255,33 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state) else offset = 0; + /* + * When using an X-tiled surface the plane starts to + * misbehave if the x offset + width exceeds the stride. + * hsw/bdw: underrun galore + * ilk/snb/ivb: wrap to the next tile row mid scanout + * i965/g4x: so far appear immune to this + * vlv/chv: TODO check + * + * Linear surfaces seem to work just fine, even on hsw/bdw + * despite them not using the linear offset anymore. + */ + if (INTEL_GEN(dev_priv) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) { + u32 alignment = intel_surf_alignment(fb, 0); + int cpp = fb->format->cpp[0]; + + while ((src_x + src_w) * cpp > plane_state->color_plane[0].stride) { + if (offset == 0) { + drm_dbg_kms(&dev_priv->drm, + "Unable to find suitable display surface offset due to X-tiling\n"); + return -EINVAL; + } + + offset = intel_plane_adjust_aligned_offset(&src_x, &src_y, plane_state, 0, + offset, offset - alignment); + } + } + /* * Put the final coordinates back so that the src * coordinate checks will see the right values. diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9843a0f202a0..7ea1e5b487b6 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1322,8 +1322,8 @@ static bool has_async_flips(struct drm_i915_private *i915) return INTEL_GEN(i915) >= 5; } -static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb, - int color_plane) +unsigned int intel_surf_alignment(const struct drm_framebuffer *fb, + int color_plane) { struct drm_i915_private *dev_priv = to_i915(fb->dev); @@ -1590,10 +1590,10 @@ static u32 intel_adjust_aligned_offset(int *x, int *y, * Adjust the tile offset by moving the difference into * the x/y offsets. */ -static u32 intel_plane_adjust_aligned_offset(int *x, int *y, - const struct intel_plane_state *state, - int color_plane, - u32 old_offset, u32 new_offset) +u32 intel_plane_adjust_aligned_offset(int *x, int *y, + const struct intel_plane_state *state, + int color_plane, + u32 old_offset, u32 new_offset) { return intel_adjust_aligned_offset(x, y, state->hw.fb, color_plane, state->hw.rotation, diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 64ffa34544a7..76f8a805b0a3 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -653,6 +653,12 @@ void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state); struct intel_encoder * intel_get_crtc_new_encoder(const struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state); +unsigned int intel_surf_alignment(const struct drm_framebuffer *fb, + int color_plane); +u32 intel_plane_adjust_aligned_offset(int *x, int *y, + const struct intel_plane_state *state, + int color_plane, + u32 old_offset, u32 new_offset); /* modesetting */ void intel_modeset_init_hw(struct drm_i915_private *i915); From 81ce8f04aa96f7f6cae05770f68b5d15be91f5a2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 10 Feb 2021 12:27:28 +0000 Subject: [PATCH 9/9] drm/i915/gt: Correct surface base address for renderclear The surface_state_base is an offset into the batch, so we need to pass the correct batch address for STATE_BASE_ADDRESS. Fixes: 47f8253d2b89 ("drm/i915/gen7: Clear all EU/L3 residual contexts") Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Prathap Kumar Valsan Cc: Akeem G Abodunrin Cc: Hans de Goede Reviewed-by: Mika Kuoppala Cc: # v5.7+ Link: https://patchwork.freedesktop.org/patch/msgid/20210210122728.20097-1-chris@chris-wilson.co.uk (cherry picked from commit 1914911f4aa08ddc05bae71d3516419463e0c567) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gt/gen7_renderclear.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/gen7_renderclear.c b/drivers/gpu/drm/i915/gt/gen7_renderclear.c index e403eb046a43..de575fdb033f 100644 --- a/drivers/gpu/drm/i915/gt/gen7_renderclear.c +++ b/drivers/gpu/drm/i915/gt/gen7_renderclear.c @@ -240,7 +240,7 @@ gen7_emit_state_base_address(struct batch_chunk *batch, /* general */ *cs++ = batch_addr(batch) | BASE_ADDRESS_MODIFY; /* surface */ - *cs++ = batch_addr(batch) | surface_state_base | BASE_ADDRESS_MODIFY; + *cs++ = (batch_addr(batch) + surface_state_base) | BASE_ADDRESS_MODIFY; /* dynamic */ *cs++ = batch_addr(batch) | BASE_ADDRESS_MODIFY; /* indirect */