From 25bbfb930716390405770bb79f0d348ef93c5a7c Mon Sep 17 00:00:00 2001 From: John Harrison Date: Mon, 12 Sep 2022 18:09:29 -0700 Subject: [PATCH 1/6] drm/i915/guc: Fix release build bug in 'remove log size module parameters' A patch was merged to remove the GuC log size override module parameters. That patch was broken and caused kernel error messages on boot in non CONFIG_DEBUG_GUC|GEM builds: [ 12.085121] i915 0000:00:02.0: [drm] *ERROR* Zero GuC log crash dump size! [ 12.092035] i915 0000:00:02.0: [drm] *ERROR* Zero GuC log debug size! So fit it. Fixes: f54e515c9180 ("drm/i915/guc: Remove log size module parameters") Cc: Joonas Lahtinen Cc: Jani Nikula Cc: Rodrigo Vivi Cc: Tvrtko Ursulin Cc: Alan Previn Cc: Jani Nikula Cc: Lucas De Marchi Cc: Matthew Brost Cc: Julia Lawall Cc: Chris Wilson Signed-off-by: John Harrison Reviewed-by: Daniele Ceraolo Spurio Link: https://patchwork.freedesktop.org/patch/msgid/20220913010929.2734885-2-John.C.Harrison@Intel.com (cherry picked from commit 01f0ce3e859619ea84104d668a87ace924bd12df) Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 25 +--------------------- 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c index b071973ac41c..55d3ef93e86f 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c @@ -36,24 +36,6 @@ struct guc_log_section { const char *name; }; -static s32 scale_log_param(struct intel_guc_log *log, const struct guc_log_section *section, - s32 param) -{ - /* -1 means default */ - if (param < 0) - return section->default_val; - - /* Check for 32-bit overflow */ - if (param >= SZ_4K) { - drm_err(&guc_to_gt(log_to_guc(log))->i915->drm, "Size too large for GuC %s log: %dMB!", - section->name, param); - return section->default_val; - } - - /* Param units are 1MB */ - return param * SZ_1M; -} - static void _guc_log_init_sizes(struct intel_guc_log *log) { struct intel_guc *guc = log_to_guc(log); @@ -78,15 +60,10 @@ static void _guc_log_init_sizes(struct intel_guc_log *log) "capture", } }; - s32 params[GUC_LOG_SECTIONS_LIMIT] = { - GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE / SZ_1M, - GUC_LOG_DEFAULT_DEBUG_BUFFER_SIZE / SZ_1M, - GUC_LOG_DEFAULT_CAPTURE_BUFFER_SIZE / SZ_1M, - }; int i; for (i = 0; i < GUC_LOG_SECTIONS_LIMIT; i++) - log->sizes[i].bytes = scale_log_param(log, sections + i, params[i]); + log->sizes[i].bytes = sections[i].default_val; /* If debug size > 1MB then bump default crash size to keep the same units */ if (log->sizes[GUC_LOG_SECTIONS_DEBUG].bytes >= SZ_1M && From aa17e57e5c67330c36d915da2925ca27099c096a Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 16 Sep 2022 14:38:50 +0300 Subject: [PATCH 2/6] drm/i915/display: remove ipc_enabled from struct drm_i915_private MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ipc_enabled member was supposed to be moved under the display wm sub-struct, but due to a rebase fail only the new one was added and the old one was left behind. Finish the job. Fixes: 70296670f672 ("drm/i915/display: move IPC under display wm sub-struct") Cc: Ville Syrjälä Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20220916113850.3712354-1-jani.nikula@intel.com (cherry picked from commit 48176104003058e2ba540fd815ec46c350d65926) Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_drv.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9f9372931fd2..bdc81db76dbd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -397,8 +397,6 @@ struct drm_i915_private { */ u8 snps_phy_failed_calibration; - bool ipc_enabled; - struct i915_pmu pmu; struct i915_drm_clients clients; From 86a4e84a9d5247daa2eafef05078ae9f3e003bf1 Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Tue, 20 Sep 2022 19:06:28 +0200 Subject: [PATCH 3/6] drm/i915: Do not cleanup obj with NULL bo->resource For delayed BO release i915_ttm_delete_mem_notify() gets called twice, once with proper bo->resource and another time with NULL. We shouldn't do anything for the 2nd time as we already cleaned up the obj once. References: https://gitlab.freedesktop.org/drm/intel/-/issues/6850 Fixes: ad74457a6b5a96 ("drm/i915/dgfx: Release mmap on rpm suspend") Signed-off-by: Nirmoy Das Reviewed-by: Matthew Auld Signed-off-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20220920170628.3391-1-nirmoy.das@intel.com (cherry picked from commit fb7818989976317cc2e78008aa2df7b9fe423c86) Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 0544b0a4a43a..e3fc38dd5db0 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -511,7 +511,7 @@ static void i915_ttm_delete_mem_notify(struct ttm_buffer_object *bo) struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo); intel_wakeref_t wakeref = 0; - if (likely(obj)) { + if (bo->resource && likely(obj)) { /* ttm_bo_release() already has dma_resv_lock */ if (i915_ttm_cpu_maps_iomem(bo->resource)) wakeref = intel_runtime_pm_get(&to_i915(obj->base.dev)->runtime_pm); From 47c3d0752bb6b412b8d1c08a1e88738fe5b9829f Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 16 Sep 2022 11:26:42 +0300 Subject: [PATCH 4/6] drm/i915: fix device info for devices without display Commit 00c6cbfd4e8a ("drm/i915: move pipe_mask and cpu_transcoder_mask to runtime info") moved the pipe_mask member from struct intel_device_info to intel_runtime_info, but overlooked some of our platforms initializing device info .display = {}. This is significant, as pipe_mask is the single point of truth for a device having a display or not; the platforms in question left pipe_mask to whatever was set for the platforms they "inherit" from in the complex macro scheme we have. Add new NO_DISPLAY macro initializing .__runtime.pipe_mask = 0, which will cause the device info .display sub-struct to be zeroed in intel_device_info_runtime_init(). A better solution (or simply audit of proper use of HAS_DISPLAY() checks) is required before moving forward with [1]. Also clear all the display related members in runtime info if there's no display. The latter is a bit tedious, but it's for completeness at this time, to ensure similar functionality as before. [1] https://lore.kernel.org/r/dfda1bf67f02ceb07c280b7a13216405fd1f7a34.1660137416.git.jani.nikula@intel.com Fixes: 00c6cbfd4e8a ("drm/i915: move pipe_mask and cpu_transcoder_mask to runtime info") Cc: Lucas De Marchi Cc: Maarten Lankhort Signed-off-by: Jani Nikula Reviewed-by: Gwan-gyeong Mun Acked-by: Lucas De Marchi Link: https://patchwork.freedesktop.org/patch/msgid/20220916082642.3451961-1-jani.nikula@intel.com (cherry picked from commit 86570b7b126bd516aba770d1fc4c971c55c66dca) Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_pci.c | 11 ++++++----- drivers/gpu/drm/i915/intel_device_info.c | 6 ++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 77e7df21f539..cd4487a1d3be 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -41,6 +41,8 @@ .__runtime.media.ip.ver = (x), \ .__runtime.display.ip.ver = (x) +#define NO_DISPLAY .__runtime.pipe_mask = 0 + #define I845_PIPE_OFFSETS \ .display.pipe_offsets = { \ [TRANSCODER_A] = PIPE_A_OFFSET, \ @@ -519,9 +521,8 @@ static const struct intel_device_info ivb_m_gt2_info = { static const struct intel_device_info ivb_q_info = { GEN7_FEATURES, PLATFORM(INTEL_IVYBRIDGE), + NO_DISPLAY, .gt = 2, - .__runtime.pipe_mask = 0, /* legal, last one wins */ - .__runtime.cpu_transcoder_mask = 0, .has_l3_dpf = 1, }; @@ -1039,7 +1040,7 @@ static const struct intel_device_info xehpsdv_info = { XE_HPM_FEATURES, DGFX_FEATURES, PLATFORM(INTEL_XEHPSDV), - .display = { }, + NO_DISPLAY, .has_64k_pages = 1, .needs_compact_pt = 1, .has_media_ratio_mode = 1, @@ -1081,7 +1082,7 @@ static const struct intel_device_info dg2_info = { static const struct intel_device_info ats_m_info = { DG2_FEATURES, - .display = { 0 }, + NO_DISPLAY, .require_force_probe = 1, .tuning_thread_rr_after_dep = 1, }; @@ -1103,7 +1104,7 @@ static const struct intel_device_info pvc_info = { .__runtime.graphics.ip.rel = 60, .__runtime.media.ip.rel = 60, PLATFORM(INTEL_PONTEVECCHIO), - .display = { 0 }, + NO_DISPLAY, .has_flat_ccs = 0, .__runtime.platform_engine_mask = BIT(BCS0) | diff --git a/drivers/gpu/drm/i915/intel_device_info.c b/drivers/gpu/drm/i915/intel_device_info.c index 1434dc33cf49..20575eb77ea7 100644 --- a/drivers/gpu/drm/i915/intel_device_info.c +++ b/drivers/gpu/drm/i915/intel_device_info.c @@ -433,8 +433,14 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv) dev_priv->drm.driver_features &= ~(DRIVER_MODESET | DRIVER_ATOMIC); memset(&info->display, 0, sizeof(info->display)); + + runtime->cpu_transcoder_mask = 0; memset(runtime->num_sprites, 0, sizeof(runtime->num_sprites)); memset(runtime->num_scalers, 0, sizeof(runtime->num_scalers)); + runtime->fbc_mask = 0; + runtime->has_hdcp = false; + runtime->has_dmc = false; + runtime->has_dsc = false; } } From a50ab1bbab26b26fa070e83c47687e6a0bd52302 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 22 Sep 2022 22:12:36 +0300 Subject: [PATCH 5/6] drm/i915: Force DPLL calculation for TC ports after readout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We always allocate two DPLLs (TC and TBT) for TC ports. This is because we can't know ahead of time wherher we need to put the PHY into DP-Alt or TBT mode. However during readout we can obviously only read out the state of the DPLL that the port is actually using. Thus the state after readout will not have both DPLLs populated. We run into problems if during readout the TC port is in DP-Alt mode, but we then perform a modeset on the port without going through the full .compute_config() machinery, and during said modeset the port cannot be switched back into DP-Alt mode and we need to take the TBT fallback path. Such a modeset can happen eg. due to cdclk reprogramming. This wasn't a problem earlier because we did all the DPLL calculations much later in the modeset. So even if flagged a modeset very late we'd still have gone through the DPLL calculations. But now all the DPLL calculations happen much earlier and so we need to deal with it, or else we'll attempt a modeset without a DPLL. To guarantee that we always have both DPLLs fully cal/ulated for TC ports force a full modeset computation during the initial commit. v2: Avoid bitwise operation on bool (Jani) Call the return variable 'fastset' to convey its meaning Reported-by: Lee Shawn C Fixes: b000abd3b3d2 ("drm/i915: Do .crtc_compute_clock() earlier") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20220922191236.4194-1-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula (cherry picked from commit eddb4afcb6c533d3f75f5f1a77e292fece27570e) Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/display/intel_ddi.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 643832d55c28..da8472cdc135 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3600,10 +3600,22 @@ static void intel_ddi_sync_state(struct intel_encoder *encoder, static bool intel_ddi_initial_fastset_check(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state) { - if (intel_crtc_has_dp_encoder(crtc_state)) - return intel_dp_initial_fastset_check(encoder, crtc_state); + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + enum phy phy = intel_port_to_phy(i915, encoder->port); + bool fastset = true; - return true; + if (intel_phy_is_tc(i915, phy)) { + drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] Forcing full modeset to compute TC port DPLLs\n", + encoder->base.base.id, encoder->base.name); + crtc_state->uapi.mode_changed = true; + fastset = false; + } + + if (intel_crtc_has_dp_encoder(crtc_state) && + !intel_dp_initial_fastset_check(encoder, crtc_state)) + fastset = false; + + return fastset; } static enum intel_output_type From 20e377e7b2e7c327039f10db80ba5bcc1f6c882d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 26 Sep 2022 16:33:33 +0100 Subject: [PATCH 6/6] drm/i915/gt: Use i915_vm_put on ppgtt_create error paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that the scratch page and page directories have a reference back to the i915_address_space, we cannot do an immediate free of the ppgtt upon error as those buffer objects will perform a later i915_vm_put in their deferred frees. The downside is that by replacing the onion unwind along the error paths, the ppgtt cleanup must handle a partially constructed vm. This includes ensuring that the vm->cleanup is set prior to the error path. Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/6900 Signed-off-by: Chris Wilson Fixes: 4d8151ae5329 ("drm/i915: Don't free shared locks while shared") Cc: Thomas Hellström Cc: Matthew Auld Cc: # v5.14+ Reviewed-by: Matthew Auld Signed-off-by: Matthew Auld Link: https://patchwork.freedesktop.org/patch/msgid/20220926153333.102195-1-matthew.auld@intel.com (cherry picked from commit c286558f58535cf97b717b946d6c96d774a09d17) Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/gt/gen6_ppgtt.c | 16 ++++---- drivers/gpu/drm/i915/gt/gen8_ppgtt.c | 58 ++++++++++++++-------------- drivers/gpu/drm/i915/gt/intel_gtt.c | 3 ++ 3 files changed, 41 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c index 1bb766c79dcb..5aaacc53fa4c 100644 --- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c +++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c @@ -247,6 +247,7 @@ err_scratch1: i915_gem_object_put(vm->scratch[1]); err_scratch0: i915_gem_object_put(vm->scratch[0]); + vm->scratch[0] = NULL; return ret; } @@ -268,9 +269,10 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm) gen6_ppgtt_free_pd(ppgtt); free_scratch(vm); - mutex_destroy(&ppgtt->flush); + if (ppgtt->base.pd) + free_pd(&ppgtt->base.vm, ppgtt->base.pd); - free_pd(&ppgtt->base.vm, ppgtt->base.pd); + mutex_destroy(&ppgtt->flush); } static void pd_vma_bind(struct i915_address_space *vm, @@ -449,19 +451,17 @@ struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt) err = gen6_ppgtt_init_scratch(ppgtt); if (err) - goto err_free; + goto err_put; ppgtt->base.pd = gen6_alloc_top_pd(ppgtt); if (IS_ERR(ppgtt->base.pd)) { err = PTR_ERR(ppgtt->base.pd); - goto err_scratch; + goto err_put; } return &ppgtt->base; -err_scratch: - free_scratch(&ppgtt->base.vm); -err_free: - kfree(ppgtt); +err_put: + i915_vm_put(&ppgtt->base.vm); return ERR_PTR(err); } diff --git a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c index c7bd5d71b03e..2128b7a72a25 100644 --- a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c +++ b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c @@ -196,7 +196,10 @@ static void gen8_ppgtt_cleanup(struct i915_address_space *vm) if (intel_vgpu_active(vm->i915)) gen8_ppgtt_notify_vgt(ppgtt, false); - __gen8_ppgtt_cleanup(vm, ppgtt->pd, gen8_pd_top_count(vm), vm->top); + if (ppgtt->pd) + __gen8_ppgtt_cleanup(vm, ppgtt->pd, + gen8_pd_top_count(vm), vm->top); + free_scratch(vm); } @@ -803,8 +806,10 @@ static int gen8_init_scratch(struct i915_address_space *vm) struct drm_i915_gem_object *obj; obj = vm->alloc_pt_dma(vm, I915_GTT_PAGE_SIZE_4K); - if (IS_ERR(obj)) + if (IS_ERR(obj)) { + ret = PTR_ERR(obj); goto free_scratch; + } ret = map_pt_dma(vm, obj); if (ret) { @@ -823,7 +828,8 @@ static int gen8_init_scratch(struct i915_address_space *vm) free_scratch: while (i--) i915_gem_object_put(vm->scratch[i]); - return -ENOMEM; + vm->scratch[0] = NULL; + return ret; } static int gen8_preallocate_top_level_pdp(struct i915_ppgtt *ppgtt) @@ -901,6 +907,7 @@ err_pd: struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt, unsigned long lmem_pt_obj_flags) { + struct i915_page_directory *pd; struct i915_ppgtt *ppgtt; int err; @@ -946,21 +953,7 @@ struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt, ppgtt->vm.alloc_scratch_dma = alloc_pt_dma; } - err = gen8_init_scratch(&ppgtt->vm); - if (err) - goto err_free; - - ppgtt->pd = gen8_alloc_top_pd(&ppgtt->vm); - if (IS_ERR(ppgtt->pd)) { - err = PTR_ERR(ppgtt->pd); - goto err_free_scratch; - } - - if (!i915_vm_is_4lvl(&ppgtt->vm)) { - err = gen8_preallocate_top_level_pdp(ppgtt); - if (err) - goto err_free_pd; - } + ppgtt->vm.pte_encode = gen8_pte_encode; ppgtt->vm.bind_async_flags = I915_VMA_LOCAL_BIND; ppgtt->vm.insert_entries = gen8_ppgtt_insert; @@ -971,22 +964,31 @@ struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt, ppgtt->vm.allocate_va_range = gen8_ppgtt_alloc; ppgtt->vm.clear_range = gen8_ppgtt_clear; ppgtt->vm.foreach = gen8_ppgtt_foreach; + ppgtt->vm.cleanup = gen8_ppgtt_cleanup; - ppgtt->vm.pte_encode = gen8_pte_encode; + err = gen8_init_scratch(&ppgtt->vm); + if (err) + goto err_put; + + pd = gen8_alloc_top_pd(&ppgtt->vm); + if (IS_ERR(pd)) { + err = PTR_ERR(pd); + goto err_put; + } + ppgtt->pd = pd; + + if (!i915_vm_is_4lvl(&ppgtt->vm)) { + err = gen8_preallocate_top_level_pdp(ppgtt); + if (err) + goto err_put; + } if (intel_vgpu_active(gt->i915)) gen8_ppgtt_notify_vgt(ppgtt, true); - ppgtt->vm.cleanup = gen8_ppgtt_cleanup; - return ppgtt; -err_free_pd: - __gen8_ppgtt_cleanup(&ppgtt->vm, ppgtt->pd, - gen8_pd_top_count(&ppgtt->vm), ppgtt->vm.top); -err_free_scratch: - free_scratch(&ppgtt->vm); -err_free: - kfree(ppgtt); +err_put: + i915_vm_put(&ppgtt->vm); return ERR_PTR(err); } diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c index b67831833c9a..2eaeba14319e 100644 --- a/drivers/gpu/drm/i915/gt/intel_gtt.c +++ b/drivers/gpu/drm/i915/gt/intel_gtt.c @@ -405,6 +405,9 @@ void free_scratch(struct i915_address_space *vm) { int i; + if (!vm->scratch[0]) + return; + for (i = 0; i <= vm->top; i++) i915_gem_object_put(vm->scratch[i]); }