From 9d691c197631f152d7dc6788098f372b64d3bc43 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Fri, 27 Jan 2023 16:30:02 +0100 Subject: drm/i915: implement async_flip mode per plane tracking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Current implementation of async flip w/a relies on assumption that previous atomic commit contains valid information if async_flip is still enabled on the plane. It is incorrect. If previous commit did not modify the plane its state->uapi.async_flip can be false. As a result DMAR/PIPE errors can be observed: i915 0000:00:02.0: [drm] *ERROR* Fault errors on pipe A: 0x00000080 i915 0000:00:02.0: [drm] *ERROR* Fault errors on pipe A: 0x00000080 DMAR: DRHD: handling fault status reg 2 DMAR: [DMA Read NO_PASID] Request device [00:02.0] fault addr 0x0 [fault reason 0x06] PTE Read access is not set v2: update async_flip_planes in more reliable places (Ville) v3: reset async_flip_planes and do_async_flip in more scenarios (Ville) v4: move all resets to plane loops (Ville) Signed-off-by: Andrzej Hajda Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230127153003.2225111-1-andrzej.hajda@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 717ca3d7890d..fcd3f1c7af32 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1252,7 +1252,8 @@ static void intel_crtc_async_flip_disable_wa(struct intel_atomic_state *state, intel_atomic_get_old_crtc_state(state, crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - u8 update_planes = new_crtc_state->update_planes; + u8 disable_async_flip_planes = old_crtc_state->async_flip_planes & + ~new_crtc_state->async_flip_planes; const struct intel_plane_state *old_plane_state; struct intel_plane *plane; bool need_vbl_wait = false; @@ -1261,7 +1262,7 @@ static void intel_crtc_async_flip_disable_wa(struct intel_atomic_state *state, for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) { if (plane->need_async_flip_disable_wa && plane->pipe == crtc->pipe && - update_planes & BIT(plane->id)) { + disable_async_flip_planes & BIT(plane->id)) { /* * Apart from the async flip bit we want to * preserve the old state for the plane. @@ -1378,7 +1379,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, * WA for platforms where async address update enable bit * is double buffered and only latched at start of vblank. */ - if (old_crtc_state->uapi.async_flip && !new_crtc_state->uapi.async_flip) + if (old_crtc_state->async_flip_planes & ~new_crtc_state->async_flip_planes) intel_crtc_async_flip_disable_wa(state, crtc); } @@ -5939,6 +5940,8 @@ int intel_modeset_all_pipes(struct intel_atomic_state *state, return ret; crtc_state->update_planes |= crtc_state->active_planes; + crtc_state->async_flip_planes = 0; + crtc_state->do_async_flip = false; } return 0; -- cgit From 16bede135fb1319c22dfa55b2de20f482fcc9cd9 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 31 Jan 2023 11:00:52 +0200 Subject: drm/i915/lvds: Extract intel_lvds_regs.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extract the integrated LVDS port register definitions into their own header file. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230130180540.8972-5-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index fcd3f1c7af32..166662ade593 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -94,6 +94,7 @@ #include "intel_hotplug.h" #include "intel_hti.h" #include "intel_lvds.h" +#include "intel_lvds_regs.h" #include "intel_modeset_setup.h" #include "intel_modeset_verify.h" #include "intel_overlay.h" -- cgit From ac7215c423a34837b634c90cf29681537bd9998c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 7 Feb 2023 13:06:19 +0200 Subject: drm/i915/dmc: drop "ucode" from function names The ucode part in the init, fini, suspend and resume function names is just unnecessary. Drop it. Cc: Imre Deak Signed-off-by: Jani Nikula Reviewed-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20230207110619.1821992-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 166662ade593..a8c91fda40a8 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8639,7 +8639,7 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915) if (!HAS_DISPLAY(i915)) return 0; - intel_dmc_ucode_init(i915); + intel_dmc_init(i915); i915->display.wq.modeset = alloc_ordered_workqueue("i915_modeset", 0); i915->display.wq.flip = alloc_workqueue("i915_flip", WQ_HIGHPRI | @@ -8674,7 +8674,7 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915) return 0; cleanup_vga_client_pw_domain_dmc: - intel_dmc_ucode_fini(i915); + intel_dmc_fini(i915); intel_power_domains_driver_remove(i915); intel_vga_unregister(i915); cleanup_bios: @@ -9000,7 +9000,7 @@ void intel_modeset_driver_remove_noirq(struct drm_i915_private *i915) /* part #3: call after gem init */ void intel_modeset_driver_remove_nogem(struct drm_i915_private *i915) { - intel_dmc_ucode_fini(i915); + intel_dmc_fini(i915); intel_power_domains_driver_remove(i915); -- cgit From e5e43d3363d7c53d99163e94cc61d418230da17c Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Wed, 25 Jan 2023 10:56:03 +0100 Subject: drm/i915/display: Pass drm_i915_private as param to i915 funcs For i915 functions pass struct drm_i915_private directly instead of struct drm_device. v2: Use to_i915(dev) directly without alias(Andrzej). Cc: Rodrigo Vivi Suggested-by: Jani Nikula Signed-off-by: Nirmoy Das Reviewed-by: Jani Nikula Reviewed-by: Andrzej Hajda Signed-off-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20230125095603.17845-1-nirmoy.das@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index a8c91fda40a8..322f3b2c741d 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -9051,7 +9051,7 @@ void intel_display_driver_register(struct drm_i915_private *i915) * enabled. We do it last so that the async config cannot run * before the connectors are registered. */ - intel_fbdev_initial_config_async(&i915->drm); + intel_fbdev_initial_config_async(i915); /* * We need to coordinate the hotplugs with the asynchronous -- cgit From 2bf91341ee42fddb6615936701bf2ed68689d452 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 8 Feb 2023 13:42:58 +0200 Subject: drm/i915: Move display power initialization during driver probing later Determining whether the display engine is present on a platform happens only in intel_device_info_runtime_init(). Initializing the display power functionality depends on this condition, so move intel_power_domains_init() later after the runtime init function has been called. The next patch fixing platforms without display, depends on this patch. Acked-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230208114300.3123934-3-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 322f3b2c741d..8a17c0e00672 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8634,6 +8634,10 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915) goto cleanup_bios; /* FIXME: completely on the wrong abstraction layer */ + ret = intel_power_domains_init(i915); + if (ret < 0) + goto cleanup_vga; + intel_power_domains_init_hw(i915, false); if (!HAS_DISPLAY(i915)) @@ -8676,6 +8680,7 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915) cleanup_vga_client_pw_domain_dmc: intel_dmc_fini(i915); intel_power_domains_driver_remove(i915); +cleanup_vga: intel_vga_unregister(i915); cleanup_bios: intel_bios_driver_remove(i915); -- cgit From 94b49d53acece870d242f6b148aff3940cb6c92e Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 13 Feb 2023 21:59:57 +0200 Subject: drm/i915/wm: move remaining watermark code out of intel_pm.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add new files intel_wm.[ch] and i9xx_wm.[ch] under display/ to hold generic and pre-SKL watermark code, respectively. SKL+ watermark code has already been split out to skl_watermark.[ch]. Use the _wm.[ch] naming for brevity; we may want to rename skl_watermark.[ch] later accordingly. Add new intel_wm_init() to call either skl_wm_init() or i9xx_wm_init(i915) depending on the platform, the latter comprising of the remains of intel_init_pm(). Sprinkle in some minor checkpatch fixes while moving the code. v2: - Rebase - Fix copyright year Cc: Ville Syrjälä Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/ddf04a07a37f0368b3fef85d4ebb924082fec6cd.1676317696.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 8a17c0e00672..8f95c994b3a7 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -55,6 +55,7 @@ #include "i915_reg.h" #include "i915_utils.h" #include "i9xx_plane.h" +#include "i9xx_wm.h" #include "icl_dsi.h" #include "intel_acpi.h" #include "intel_atomic.h" @@ -117,6 +118,7 @@ #include "intel_vdsc.h" #include "intel_vga.h" #include "intel_vrr.h" +#include "intel_wm.h" #include "skl_scaler.h" #include "skl_universal_plane.h" #include "skl_watermark.h" @@ -8699,7 +8701,7 @@ int intel_modeset_init_nogem(struct drm_i915_private *i915) if (!HAS_DISPLAY(i915)) return 0; - intel_init_pm(i915); + intel_wm_init(i915); intel_panel_sanitize_ssc(i915); -- cgit From 284c5baa44218ef615ed8f5edcd6cfdedaef6abc Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 13 Feb 2023 21:59:58 +0200 Subject: drm/i915/wm: move functions to call watermark hooks to intel_wm.[ch] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the wrappers to call watermark hooks into intel_wm.[ch]. This declutters intel_display.c nicely. Cc: Ville Syrjälä Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/2c8243c5c81b8cd8e34d51f55f3533373c305d0e.1676317696.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 95 ---------------------------- 1 file changed, 95 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 8f95c994b3a7..82e687b40db4 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -133,101 +133,6 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state); static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state); static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state); -/** - * intel_update_watermarks - update FIFO watermark values based on current modes - * @dev_priv: i915 device - * - * Calculate watermark values for the various WM regs based on current mode - * and plane configuration. - * - * There are several cases to deal with here: - * - normal (i.e. non-self-refresh) - * - self-refresh (SR) mode - * - lines are large relative to FIFO size (buffer can hold up to 2) - * - lines are small relative to FIFO size (buffer can hold more than 2 - * lines), so need to account for TLB latency - * - * The normal calculation is: - * watermark = dotclock * bytes per pixel * latency - * where latency is platform & configuration dependent (we assume pessimal - * values here). - * - * The SR calculation is: - * watermark = (trunc(latency/line time)+1) * surface width * - * bytes per pixel - * where - * line time = htotal / dotclock - * surface width = hdisplay for normal plane and 64 for cursor - * and latency is assumed to be high, as above. - * - * The final value programmed to the register should always be rounded up, - * and include an extra 2 entries to account for clock crossings. - * - * We don't use the sprite, so we can ignore that. And on Crestline we have - * to set the non-SR watermarks to 8. - */ -void intel_update_watermarks(struct drm_i915_private *dev_priv) -{ - if (dev_priv->display.funcs.wm->update_wm) - dev_priv->display.funcs.wm->update_wm(dev_priv); -} - -static int intel_compute_pipe_wm(struct intel_atomic_state *state, - struct intel_crtc *crtc) -{ - struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (dev_priv->display.funcs.wm->compute_pipe_wm) - return dev_priv->display.funcs.wm->compute_pipe_wm(state, crtc); - return 0; -} - -static int intel_compute_intermediate_wm(struct intel_atomic_state *state, - struct intel_crtc *crtc) -{ - struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (!dev_priv->display.funcs.wm->compute_intermediate_wm) - return 0; - if (drm_WARN_ON(&dev_priv->drm, - !dev_priv->display.funcs.wm->compute_pipe_wm)) - return 0; - return dev_priv->display.funcs.wm->compute_intermediate_wm(state, crtc); -} - -static bool intel_initial_watermarks(struct intel_atomic_state *state, - struct intel_crtc *crtc) -{ - struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (dev_priv->display.funcs.wm->initial_watermarks) { - dev_priv->display.funcs.wm->initial_watermarks(state, crtc); - return true; - } - return false; -} - -static void intel_atomic_update_watermarks(struct intel_atomic_state *state, - struct intel_crtc *crtc) -{ - struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (dev_priv->display.funcs.wm->atomic_update_watermarks) - dev_priv->display.funcs.wm->atomic_update_watermarks(state, crtc); -} - -static void intel_optimize_watermarks(struct intel_atomic_state *state, - struct intel_crtc *crtc) -{ - struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (dev_priv->display.funcs.wm->optimize_watermarks) - dev_priv->display.funcs.wm->optimize_watermarks(state, crtc); -} - -static int intel_compute_global_watermarks(struct intel_atomic_state *state) -{ - struct drm_i915_private *dev_priv = to_i915(state->base.dev); - if (dev_priv->display.funcs.wm->compute_global_watermarks) - return dev_priv->display.funcs.wm->compute_global_watermarks(state); - return 0; -} - /* returns HPLL frequency in kHz */ int vlv_get_hpll_vco(struct drm_i915_private *dev_priv) { -- cgit From 3dadb4a17035ad4c84670d2ee1a3070f5fab4bbc Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 15 Feb 2023 16:19:06 +0200 Subject: drm/i915/wm: move ILK watermark sanitization to i9xx_wm.[ch] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move sanitize_watermarks() to i9xx_wm.[ch] and rename as ilk_wm_sanitize(). The slightly unfortunate downside is having to expose intel_atomic_check() from intel_display.c, but this declutters intel_display.c nicely. v2: - Move to i9xx_wm.[ch] instead of intel_wm.[ch] (Ville) Cc: Ville Syrjälä Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230215141910.433043-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 124 +-------------------------- 1 file changed, 3 insertions(+), 121 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 82e687b40db4..89e8913c1ba1 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6602,8 +6602,8 @@ static int intel_bigjoiner_add_affected_crtcs(struct intel_atomic_state *state) * @dev: drm device * @_state: state to validate */ -static int intel_atomic_check(struct drm_device *dev, - struct drm_atomic_state *_state) +int intel_atomic_check(struct drm_device *dev, + struct drm_atomic_state *_state) { struct drm_i915_private *dev_priv = to_i915(dev); struct intel_atomic_state *state = to_intel_atomic_state(_state); @@ -8263,124 +8263,6 @@ void intel_modeset_init_hw(struct drm_i915_private *i915) cdclk_state->logical = cdclk_state->actual = i915->display.cdclk.hw; } -static int sanitize_watermarks_add_affected(struct drm_atomic_state *state) -{ - struct drm_plane *plane; - struct intel_crtc *crtc; - - for_each_intel_crtc(state->dev, crtc) { - struct intel_crtc_state *crtc_state; - - crtc_state = intel_atomic_get_crtc_state(state, crtc); - if (IS_ERR(crtc_state)) - return PTR_ERR(crtc_state); - - if (crtc_state->hw.active) { - /* - * Preserve the inherited flag to avoid - * taking the full modeset path. - */ - crtc_state->inherited = true; - } - } - - drm_for_each_plane(plane, state->dev) { - struct drm_plane_state *plane_state; - - plane_state = drm_atomic_get_plane_state(state, plane); - if (IS_ERR(plane_state)) - return PTR_ERR(plane_state); - } - - return 0; -} - -/* - * Calculate what we think the watermarks should be for the state we've read - * out of the hardware and then immediately program those watermarks so that - * we ensure the hardware settings match our internal state. - * - * We can calculate what we think WM's should be by creating a duplicate of the - * current state (which was constructed during hardware readout) and running it - * through the atomic check code to calculate new watermark values in the - * state object. - */ -static void sanitize_watermarks(struct drm_i915_private *dev_priv) -{ - struct drm_atomic_state *state; - struct intel_atomic_state *intel_state; - struct intel_crtc *crtc; - struct intel_crtc_state *crtc_state; - struct drm_modeset_acquire_ctx ctx; - int ret; - int i; - - /* Only supported on platforms that use atomic watermark design */ - if (!dev_priv->display.funcs.wm->optimize_watermarks) - return; - - state = drm_atomic_state_alloc(&dev_priv->drm); - if (drm_WARN_ON(&dev_priv->drm, !state)) - return; - - intel_state = to_intel_atomic_state(state); - - drm_modeset_acquire_init(&ctx, 0); - -retry: - state->acquire_ctx = &ctx; - - /* - * Hardware readout is the only time we don't want to calculate - * intermediate watermarks (since we don't trust the current - * watermarks). - */ - if (!HAS_GMCH(dev_priv)) - intel_state->skip_intermediate_wm = true; - - ret = sanitize_watermarks_add_affected(state); - if (ret) - goto fail; - - ret = intel_atomic_check(&dev_priv->drm, state); - if (ret) - goto fail; - - /* Write calculated watermark values back */ - for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) { - crtc_state->wm.need_postvbl_update = true; - intel_optimize_watermarks(intel_state, crtc); - - to_intel_crtc_state(crtc->base.state)->wm = crtc_state->wm; - } - -fail: - if (ret == -EDEADLK) { - drm_atomic_state_clear(state); - drm_modeset_backoff(&ctx); - goto retry; - } - - /* - * If we fail here, it means that the hardware appears to be - * programmed in a way that shouldn't be possible, given our - * understanding of watermark requirements. This might mean a - * mistake in the hardware readout code or a mistake in the - * watermark calculations for a given platform. Raise a WARN - * so that this is noticeable. - * - * If this actually happens, we'll have to just leave the - * BIOS-programmed watermarks untouched and hope for the best. - */ - drm_WARN(&dev_priv->drm, ret, - "Could not determine valid watermarks for inherited state\n"); - - drm_atomic_state_put(state); - - drm_modeset_drop_locks(&ctx); - drm_modeset_acquire_fini(&ctx); -} - static int intel_initial_commit(struct drm_device *dev) { struct drm_atomic_state *state = NULL; @@ -8662,7 +8544,7 @@ int intel_modeset_init_nogem(struct drm_i915_private *i915) * since the watermark calculation done here will use pstate->fb. */ if (!HAS_GMCH(i915)) - sanitize_watermarks(i915); + ilk_wm_sanitize(i915); return 0; } -- cgit From 2bd4054c7d5c888db8a2f985c8f01a9278792210 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Thu, 5 Jan 2023 14:10:38 +0100 Subject: drm/i915/display/core: use intel_de_rmw if possible The helper makes the code more compact and readable. Signed-off-by: Andrzej Hajda Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20230105131046.2173431-1-andrzej.hajda@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 89e8913c1ba1..c355ee01d4db 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -201,11 +201,11 @@ static void skl_wa_827(struct drm_i915_private *dev_priv, enum pipe pipe, bool enable) { if (enable) - intel_de_write(dev_priv, CLKGATE_DIS_PSL(pipe), - intel_de_read(dev_priv, CLKGATE_DIS_PSL(pipe)) | DUPS1_GATING_DIS | DUPS2_GATING_DIS); + intel_de_rmw(dev_priv, CLKGATE_DIS_PSL(pipe), + 0, DUPS1_GATING_DIS | DUPS2_GATING_DIS); else - intel_de_write(dev_priv, CLKGATE_DIS_PSL(pipe), - intel_de_read(dev_priv, CLKGATE_DIS_PSL(pipe)) & ~(DUPS1_GATING_DIS | DUPS2_GATING_DIS)); + intel_de_rmw(dev_priv, CLKGATE_DIS_PSL(pipe), + DUPS1_GATING_DIS | DUPS2_GATING_DIS, 0); } /* Wa_2006604312:icl,ehl */ @@ -214,11 +214,9 @@ icl_wa_scalerclkgating(struct drm_i915_private *dev_priv, enum pipe pipe, bool enable) { if (enable) - intel_de_write(dev_priv, CLKGATE_DIS_PSL(pipe), - intel_de_read(dev_priv, CLKGATE_DIS_PSL(pipe)) | DPFR_GATING_DIS); + intel_de_rmw(dev_priv, CLKGATE_DIS_PSL(pipe), 0, DPFR_GATING_DIS); else - intel_de_write(dev_priv, CLKGATE_DIS_PSL(pipe), - intel_de_read(dev_priv, CLKGATE_DIS_PSL(pipe)) & ~DPFR_GATING_DIS); + intel_de_rmw(dev_priv, CLKGATE_DIS_PSL(pipe), DPFR_GATING_DIS, 0); } /* Wa_1604331009:icl,jsl,ehl */ @@ -1710,12 +1708,10 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state) enum transcoder transcoder = crtc_state->cpu_transcoder; i915_reg_t reg = DISPLAY_VER(dev_priv) >= 14 ? MTL_CHICKEN_TRANS(transcoder) : CHICKEN_TRANS(transcoder); - u32 val; - val = intel_de_read(dev_priv, reg); - val &= ~HSW_FRAME_START_DELAY_MASK; - val |= HSW_FRAME_START_DELAY(crtc_state->framestart_delay - 1); - intel_de_write(dev_priv, reg, val); + intel_de_rmw(dev_priv, reg, + HSW_FRAME_START_DELAY_MASK, + HSW_FRAME_START_DELAY(crtc_state->framestart_delay - 1)); } static void icl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state, -- cgit From 46b3c0f683d6a2128f7f2bf236bcdc62caec5c83 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 15 Feb 2023 17:01:29 +0200 Subject: drm/i915: Reduce ELD hex dumps a bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do the ELD hexdumps only up to the last differing byte. The rest is typically all zeroes anyway so not much point in dumping it. Couldn't find anything for memcmp_diff_len() so rolled my own. v2: Use semantics and function name suggested by Jani Cc: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230215150129.13288-1-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index c355ee01d4db..92dbb83a531b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5344,6 +5344,20 @@ pipe_config_dp_vsc_sdp_mismatch(struct drm_i915_private *dev_priv, } } +/* Returns the length up to and including the last differing byte */ +static size_t +memcmp_diff_len(const u8 *a, const u8 *b, size_t len) +{ + int i; + + for (i = len - 1; i >= 0; i--) { + if (a[i] != b[i]) + return i + 1; + } + + return 0; +} + static void pipe_config_buffer_mismatch(struct drm_i915_private *dev_priv, bool fastset, const char *name, @@ -5353,6 +5367,9 @@ pipe_config_buffer_mismatch(struct drm_i915_private *dev_priv, if (!drm_debug_enabled(DRM_UT_KMS)) return; + /* only dump up to the last difference */ + len = memcmp_diff_len(a, b, len); + drm_dbg_kms(&dev_priv->drm, "fastset mismatch in %s buffer\n", name); print_hex_dump(KERN_DEBUG, "expected: ", DUMP_PREFIX_NONE, @@ -5360,6 +5377,9 @@ pipe_config_buffer_mismatch(struct drm_i915_private *dev_priv, print_hex_dump(KERN_DEBUG, "found: ", DUMP_PREFIX_NONE, 16, 0, b, len, false); } else { + /* only dump up to the last difference */ + len = memcmp_diff_len(a, b, len); + drm_err(&dev_priv->drm, "mismatch in %s buffer\n", name); print_hex_dump(KERN_ERR, "expected: ", DUMP_PREFIX_NONE, 16, 0, a, len, false); -- cgit From 5ac421a9ec6668369b7910d4b1e7f5e7e9e9ec94 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 14 Feb 2023 00:52:49 +0200 Subject: drm/i915: Give CPU transcoder timing registers TRANS_ prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Name the CPU transcoder timing registers TRANS_FOO rather than just FOO. This is the modern name, after the pipe/transcoder split happened. Makes it a bit more obvious whether you pass in a pipe or a transcoder. PIPESRC is a bit special as it's a pipe register, even though it lives in the transcoder registers range (0x60000 instead of 0x70000). And BCLRPAT I suppose is a transcoder register (since it has something to do with the timing generator), but it doesn't even exist after gen4 so I left it to use the only name it ever had in bspec. And while at it let's pass in the correct enum in few more places why don't we. Although in all those places the distinction doesn't matter. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230213225258.2127-4-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 49 ++++++++++++++-------------- 1 file changed, 25 insertions(+), 24 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 92dbb83a531b..ac8d33b7fe01 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1751,7 +1751,7 @@ static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_sta intel_set_transcoder_timings(crtc_state); if (cpu_transcoder != TRANSCODER_EDP) - intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder), + intel_de_write(dev_priv, TRANS_MULT(cpu_transcoder), crtc_state->pixel_multiplier - 1); hsw_set_frame_start_delay(crtc_state); @@ -2747,21 +2747,21 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta } if (DISPLAY_VER(dev_priv) > 3) - intel_de_write(dev_priv, VSYNCSHIFT(cpu_transcoder), - vsyncshift); + intel_de_write(dev_priv, TRANS_VSYNCSHIFT(cpu_transcoder), + vsyncshift); - intel_de_write(dev_priv, HTOTAL(cpu_transcoder), + intel_de_write(dev_priv, TRANS_HTOTAL(cpu_transcoder), (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16)); - intel_de_write(dev_priv, HBLANK(cpu_transcoder), + intel_de_write(dev_priv, TRANS_HBLANK(cpu_transcoder), (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16)); - intel_de_write(dev_priv, HSYNC(cpu_transcoder), + intel_de_write(dev_priv, TRANS_HSYNC(cpu_transcoder), (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16)); - intel_de_write(dev_priv, VTOTAL(cpu_transcoder), + intel_de_write(dev_priv, TRANS_VTOTAL(cpu_transcoder), (adjusted_mode->crtc_vdisplay - 1) | ((crtc_vtotal - 1) << 16)); - intel_de_write(dev_priv, VBLANK(cpu_transcoder), + intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder), (adjusted_mode->crtc_vblank_start - 1) | ((crtc_vblank_end - 1) << 16)); - intel_de_write(dev_priv, VSYNC(cpu_transcoder), + intel_de_write(dev_priv, TRANS_VSYNC(cpu_transcoder), (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16)); /* Workaround: when the EDP input selection is B, the VTOTAL_B must be @@ -2770,8 +2770,8 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta * bits. */ if (IS_HASWELL(dev_priv) && cpu_transcoder == TRANSCODER_EDP && (pipe == PIPE_B || pipe == PIPE_C)) - intel_de_write(dev_priv, VTOTAL(pipe), - intel_de_read(dev_priv, VTOTAL(cpu_transcoder))); + intel_de_write(dev_priv, TRANS_VTOTAL(pipe), + intel_de_read(dev_priv, TRANS_VTOTAL(cpu_transcoder))); } @@ -2813,33 +2813,33 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc, enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; u32 tmp; - tmp = intel_de_read(dev_priv, HTOTAL(cpu_transcoder)); + tmp = intel_de_read(dev_priv, TRANS_HTOTAL(cpu_transcoder)); pipe_config->hw.adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1; pipe_config->hw.adjusted_mode.crtc_htotal = ((tmp >> 16) & 0xffff) + 1; if (!transcoder_is_dsi(cpu_transcoder)) { - tmp = intel_de_read(dev_priv, HBLANK(cpu_transcoder)); + tmp = intel_de_read(dev_priv, TRANS_HBLANK(cpu_transcoder)); pipe_config->hw.adjusted_mode.crtc_hblank_start = (tmp & 0xffff) + 1; pipe_config->hw.adjusted_mode.crtc_hblank_end = ((tmp >> 16) & 0xffff) + 1; } - tmp = intel_de_read(dev_priv, HSYNC(cpu_transcoder)); + tmp = intel_de_read(dev_priv, TRANS_HSYNC(cpu_transcoder)); pipe_config->hw.adjusted_mode.crtc_hsync_start = (tmp & 0xffff) + 1; pipe_config->hw.adjusted_mode.crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1; - tmp = intel_de_read(dev_priv, VTOTAL(cpu_transcoder)); + tmp = intel_de_read(dev_priv, TRANS_VTOTAL(cpu_transcoder)); pipe_config->hw.adjusted_mode.crtc_vdisplay = (tmp & 0xffff) + 1; pipe_config->hw.adjusted_mode.crtc_vtotal = ((tmp >> 16) & 0xffff) + 1; if (!transcoder_is_dsi(cpu_transcoder)) { - tmp = intel_de_read(dev_priv, VBLANK(cpu_transcoder)); + tmp = intel_de_read(dev_priv, TRANS_VBLANK(cpu_transcoder)); pipe_config->hw.adjusted_mode.crtc_vblank_start = (tmp & 0xffff) + 1; pipe_config->hw.adjusted_mode.crtc_vblank_end = ((tmp >> 16) & 0xffff) + 1; } - tmp = intel_de_read(dev_priv, VSYNC(cpu_transcoder)); + tmp = intel_de_read(dev_priv, TRANS_VSYNC(cpu_transcoder)); pipe_config->hw.adjusted_mode.crtc_vsync_start = (tmp & 0xffff) + 1; pipe_config->hw.adjusted_mode.crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1; @@ -3995,7 +3995,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, !transcoder_is_dsi(pipe_config->cpu_transcoder)) { pipe_config->pixel_multiplier = intel_de_read(dev_priv, - PIPE_MULT(pipe_config->cpu_transcoder)) + 1; + TRANS_MULT(pipe_config->cpu_transcoder)) + 1; } else { pipe_config->pixel_multiplier = 1; } @@ -8601,6 +8601,7 @@ int intel_modeset_init(struct drm_i915_private *i915) void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) { struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe); + enum transcoder cpu_transcoder = (enum transcoder)pipe; /* 640x480@60Hz, ~25175 kHz */ struct dpll clock = { .m1 = 18, @@ -8627,12 +8628,12 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) PLL_REF_INPUT_DREFCLK | DPLL_VCO_ENABLE; - intel_de_write(dev_priv, HTOTAL(pipe), (640 - 1) | ((800 - 1) << 16)); - intel_de_write(dev_priv, HBLANK(pipe), (640 - 1) | ((800 - 1) << 16)); - intel_de_write(dev_priv, HSYNC(pipe), (656 - 1) | ((752 - 1) << 16)); - intel_de_write(dev_priv, VTOTAL(pipe), (480 - 1) | ((525 - 1) << 16)); - intel_de_write(dev_priv, VBLANK(pipe), (480 - 1) | ((525 - 1) << 16)); - intel_de_write(dev_priv, VSYNC(pipe), (490 - 1) | ((492 - 1) << 16)); + intel_de_write(dev_priv, TRANS_HTOTAL(cpu_transcoder), (640 - 1) | ((800 - 1) << 16)); + intel_de_write(dev_priv, TRANS_HBLANK(cpu_transcoder), (640 - 1) | ((800 - 1) << 16)); + intel_de_write(dev_priv, TRANS_HSYNC(cpu_transcoder), (656 - 1) | ((752 - 1) << 16)); + intel_de_write(dev_priv, TRANS_VTOTAL(cpu_transcoder), (480 - 1) | ((525 - 1) << 16)); + intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder), (480 - 1) | ((525 - 1) << 16)); + intel_de_write(dev_priv, TRANS_VSYNC(cpu_transcoder), (490 - 1) | ((492 - 1) << 16)); intel_de_write(dev_priv, PIPESRC(pipe), ((640 - 1) << 16) | (480 - 1)); intel_de_write(dev_priv, FP0(pipe), fp); -- cgit From 3eb08ea58e5717cf758b9eff6d9604aa3525ab94 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 14 Feb 2023 00:52:50 +0200 Subject: drm/i915: s/PIPECONF/TRANSCONF/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename PIPECONF to TRANSCONF to make it clear what it actually applies to. While the usual convention is to pick the earliers name I think in this case it's more clear to use the later name. Especially as even the register offset is in the wrong range (0x70000 vs. 0x60000) and thus makes it look like this is per-pipe. There is one place in gvt that's doing something with TRANSCONF while iterating with for_each_pipe(). So that might not be doing the right thing for TRANSCODER_EDP, dunno. Not knowing what it does I left it as is to avoid breakage. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230213225258.2127-5-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 171 ++++++++++++++------------- 1 file changed, 86 insertions(+), 85 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ac8d33b7fe01..77ea780b7107 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -301,8 +301,8 @@ intel_wait_for_pipe_off(const struct intel_crtc_state *old_crtc_state) enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; /* Wait for the Pipe State to go off */ - if (intel_de_wait_for_clear(dev_priv, PIPECONF(cpu_transcoder), - PIPECONF_STATE_ENABLE, 100)) + if (intel_de_wait_for_clear(dev_priv, TRANSCONF(cpu_transcoder), + TRANSCONF_STATE_ENABLE, 100)) drm_WARN(&dev_priv->drm, 1, "pipe_off wait timed out\n"); } else { intel_wait_for_pipe_scanline_stopped(crtc); @@ -323,8 +323,8 @@ void assert_transcoder(struct drm_i915_private *dev_priv, power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); if (wakeref) { - u32 val = intel_de_read(dev_priv, PIPECONF(cpu_transcoder)); - cur_state = !!(val & PIPECONF_ENABLE); + u32 val = intel_de_read(dev_priv, TRANSCONF(cpu_transcoder)); + cur_state = !!(val & TRANSCONF_ENABLE); intel_display_power_put(dev_priv, power_domain, wakeref); } else { @@ -436,15 +436,15 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state) intel_de_rmw(dev_priv, PIPE_ARB_CTL(pipe), 0, PIPE_ARB_USE_PROG_SLOTS); - reg = PIPECONF(cpu_transcoder); + reg = TRANSCONF(cpu_transcoder); val = intel_de_read(dev_priv, reg); - if (val & PIPECONF_ENABLE) { + if (val & TRANSCONF_ENABLE) { /* we keep both pipes enabled on 830 */ drm_WARN_ON(&dev_priv->drm, !IS_I830(dev_priv)); return; } - intel_de_write(dev_priv, reg, val | PIPECONF_ENABLE); + intel_de_write(dev_priv, reg, val | TRANSCONF_ENABLE); intel_de_posting_read(dev_priv, reg); /* @@ -475,9 +475,9 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state) */ assert_planes_disabled(crtc); - reg = PIPECONF(cpu_transcoder); + reg = TRANSCONF(cpu_transcoder); val = intel_de_read(dev_priv, reg); - if ((val & PIPECONF_ENABLE) == 0) + if ((val & TRANSCONF_ENABLE) == 0) return; /* @@ -485,11 +485,11 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state) * so best keep it disabled when not needed. */ if (old_crtc_state->double_wide) - val &= ~PIPECONF_DOUBLE_WIDE; + val &= ~TRANSCONF_DOUBLE_WIDE; /* Don't disable pipe or pipe PLLs if needed */ if (!IS_I830(dev_priv)) - val &= ~PIPECONF_ENABLE; + val &= ~TRANSCONF_ENABLE; if (DISPLAY_VER(dev_priv) >= 14) intel_de_rmw(dev_priv, MTL_CHICKEN_TRANS(cpu_transcoder), @@ -499,7 +499,7 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state) FECSTALL_DIS_DPTSTREAM_DPTTG, 0); intel_de_write(dev_priv, reg, val); - if ((val & PIPECONF_ENABLE) == 0) + if ((val & TRANSCONF_ENABLE) == 0) intel_wait_for_pipe_off(old_crtc_state); } @@ -2800,9 +2800,9 @@ static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state) if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) - return intel_de_read(dev_priv, PIPECONF(cpu_transcoder)) & PIPECONF_INTERLACE_MASK_HSW; + return intel_de_read(dev_priv, TRANSCONF(cpu_transcoder)) & TRANSCONF_INTERLACE_MASK_HSW; else - return intel_de_read(dev_priv, PIPECONF(cpu_transcoder)) & PIPECONF_INTERLACE_MASK; + return intel_de_read(dev_priv, TRANSCONF(cpu_transcoder)) & TRANSCONF_INTERLACE_MASK; } static void intel_get_transcoder_timings(struct intel_crtc *crtc, @@ -2887,7 +2887,8 @@ void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - u32 pipeconf = 0; + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + u32 val = 0; /* * - We keep both pipes enabled on 830 @@ -2895,18 +2896,18 @@ void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state) * - During fastset the pipe is already enabled and must remain so */ if (IS_I830(dev_priv) || !intel_crtc_needs_modeset(crtc_state)) - pipeconf |= PIPECONF_ENABLE; + val |= TRANSCONF_ENABLE; if (crtc_state->double_wide) - pipeconf |= PIPECONF_DOUBLE_WIDE; + val |= TRANSCONF_DOUBLE_WIDE; /* only g4x and later have fancy bpc/dither controls */ if (IS_G4X(dev_priv) || IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { /* Bspec claims that we can't use dithering for 30bpp pipes. */ if (crtc_state->dither && crtc_state->pipe_bpp != 30) - pipeconf |= PIPECONF_DITHER_EN | - PIPECONF_DITHER_TYPE_SP; + val |= TRANSCONF_DITHER_EN | + TRANSCONF_DITHER_TYPE_SP; switch (crtc_state->pipe_bpp) { default: @@ -2914,13 +2915,13 @@ void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state) MISSING_CASE(crtc_state->pipe_bpp); fallthrough; case 18: - pipeconf |= PIPECONF_BPC_6; + val |= TRANSCONF_BPC_6; break; case 24: - pipeconf |= PIPECONF_BPC_8; + val |= TRANSCONF_BPC_8; break; case 30: - pipeconf |= PIPECONF_BPC_10; + val |= TRANSCONF_BPC_10; break; } } @@ -2928,23 +2929,23 @@ void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state) if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) { if (DISPLAY_VER(dev_priv) < 4 || intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO)) - pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; + val |= TRANSCONF_INTERLACE_W_FIELD_INDICATION; else - pipeconf |= PIPECONF_INTERLACE_W_SYNC_SHIFT; + val |= TRANSCONF_INTERLACE_W_SYNC_SHIFT; } else { - pipeconf |= PIPECONF_INTERLACE_PROGRESSIVE; + val |= TRANSCONF_INTERLACE_PROGRESSIVE; } if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && crtc_state->limited_color_range) - pipeconf |= PIPECONF_COLOR_RANGE_SELECT; + val |= TRANSCONF_COLOR_RANGE_SELECT; - pipeconf |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode); + val |= TRANSCONF_GAMMA_MODE(crtc_state->gamma_mode); - pipeconf |= PIPECONF_FRAME_START_DELAY(crtc_state->framestart_delay - 1); + val |= TRANSCONF_FRAME_START_DELAY(crtc_state->framestart_delay - 1); - intel_de_write(dev_priv, PIPECONF(crtc->pipe), pipeconf); - intel_de_posting_read(dev_priv, PIPECONF(crtc->pipe)); + intel_de_write(dev_priv, TRANSCONF(cpu_transcoder), val); + intel_de_posting_read(dev_priv, TRANSCONF(cpu_transcoder)); } static bool i9xx_has_pfit(struct drm_i915_private *dev_priv) @@ -3103,20 +3104,20 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, ret = false; - tmp = intel_de_read(dev_priv, PIPECONF(crtc->pipe)); - if (!(tmp & PIPECONF_ENABLE)) + tmp = intel_de_read(dev_priv, TRANSCONF(pipe_config->cpu_transcoder)); + if (!(tmp & TRANSCONF_ENABLE)) goto out; if (IS_G4X(dev_priv) || IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { - switch (tmp & PIPECONF_BPC_MASK) { - case PIPECONF_BPC_6: + switch (tmp & TRANSCONF_BPC_MASK) { + case TRANSCONF_BPC_6: pipe_config->pipe_bpp = 18; break; - case PIPECONF_BPC_8: + case TRANSCONF_BPC_8: pipe_config->pipe_bpp = 24; break; - case PIPECONF_BPC_10: + case TRANSCONF_BPC_10: pipe_config->pipe_bpp = 30; break; default: @@ -3126,12 +3127,12 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, } if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && - (tmp & PIPECONF_COLOR_RANGE_SELECT)) + (tmp & TRANSCONF_COLOR_RANGE_SELECT)) pipe_config->limited_color_range = true; - pipe_config->gamma_mode = REG_FIELD_GET(PIPECONF_GAMMA_MODE_MASK_I9XX, tmp); + pipe_config->gamma_mode = REG_FIELD_GET(TRANSCONF_GAMMA_MODE_MASK_I9XX, tmp); - pipe_config->framestart_delay = REG_FIELD_GET(PIPECONF_FRAME_START_DELAY_MASK, tmp) + 1; + pipe_config->framestart_delay = REG_FIELD_GET(TRANSCONF_FRAME_START_DELAY_MASK, tmp) + 1; if (IS_CHERRYVIEW(dev_priv)) pipe_config->cgm_mode = intel_de_read(dev_priv, @@ -3141,7 +3142,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, intel_color_get_config(pipe_config); if (DISPLAY_VER(dev_priv) < 4) - pipe_config->double_wide = tmp & PIPECONF_DOUBLE_WIDE; + pipe_config->double_wide = tmp & TRANSCONF_DOUBLE_WIDE; intel_get_transcoder_timings(crtc, pipe_config); intel_get_pipe_src_size(crtc, pipe_config); @@ -3211,7 +3212,7 @@ void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - enum pipe pipe = crtc->pipe; + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 val = 0; /* @@ -3219,7 +3220,7 @@ void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state) * - During fastset the pipe is already enabled and must remain so */ if (!intel_crtc_needs_modeset(crtc_state)) - val |= PIPECONF_ENABLE; + val |= TRANSCONF_ENABLE; switch (crtc_state->pipe_bpp) { default: @@ -3227,26 +3228,26 @@ void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state) MISSING_CASE(crtc_state->pipe_bpp); fallthrough; case 18: - val |= PIPECONF_BPC_6; + val |= TRANSCONF_BPC_6; break; case 24: - val |= PIPECONF_BPC_8; + val |= TRANSCONF_BPC_8; break; case 30: - val |= PIPECONF_BPC_10; + val |= TRANSCONF_BPC_10; break; case 36: - val |= PIPECONF_BPC_12; + val |= TRANSCONF_BPC_12; break; } if (crtc_state->dither) - val |= PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP; + val |= TRANSCONF_DITHER_EN | TRANSCONF_DITHER_TYPE_SP; if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) - val |= PIPECONF_INTERLACE_IF_ID_ILK; + val |= TRANSCONF_INTERLACE_IF_ID_ILK; else - val |= PIPECONF_INTERLACE_PF_PD_ILK; + val |= TRANSCONF_INTERLACE_PF_PD_ILK; /* * This would end up with an odd purple hue over @@ -3257,18 +3258,18 @@ void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state) if (crtc_state->limited_color_range && !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO)) - val |= PIPECONF_COLOR_RANGE_SELECT; + val |= TRANSCONF_COLOR_RANGE_SELECT; if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) - val |= PIPECONF_OUTPUT_COLORSPACE_YUV709; + val |= TRANSCONF_OUTPUT_COLORSPACE_YUV709; - val |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode); + val |= TRANSCONF_GAMMA_MODE(crtc_state->gamma_mode); - val |= PIPECONF_FRAME_START_DELAY(crtc_state->framestart_delay - 1); - val |= PIPECONF_MSA_TIMING_DELAY(crtc_state->msa_timing_delay); + val |= TRANSCONF_FRAME_START_DELAY(crtc_state->framestart_delay - 1); + val |= TRANSCONF_MSA_TIMING_DELAY(crtc_state->msa_timing_delay); - intel_de_write(dev_priv, PIPECONF(pipe), val); - intel_de_posting_read(dev_priv, PIPECONF(pipe)); + intel_de_write(dev_priv, TRANSCONF(cpu_transcoder), val); + intel_de_posting_read(dev_priv, TRANSCONF(cpu_transcoder)); } static void hsw_set_transconf(const struct intel_crtc_state *crtc_state) @@ -3283,22 +3284,22 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state) * - During fastset the pipe is already enabled and must remain so */ if (!intel_crtc_needs_modeset(crtc_state)) - val |= PIPECONF_ENABLE; + val |= TRANSCONF_ENABLE; if (IS_HASWELL(dev_priv) && crtc_state->dither) - val |= PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP; + val |= TRANSCONF_DITHER_EN | TRANSCONF_DITHER_TYPE_SP; if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) - val |= PIPECONF_INTERLACE_IF_ID_ILK; + val |= TRANSCONF_INTERLACE_IF_ID_ILK; else - val |= PIPECONF_INTERLACE_PF_PD_ILK; + val |= TRANSCONF_INTERLACE_PF_PD_ILK; if (IS_HASWELL(dev_priv) && crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) - val |= PIPECONF_OUTPUT_COLORSPACE_YUV_HSW; + val |= TRANSCONF_OUTPUT_COLORSPACE_YUV_HSW; - intel_de_write(dev_priv, PIPECONF(cpu_transcoder), val); - intel_de_posting_read(dev_priv, PIPECONF(cpu_transcoder)); + intel_de_write(dev_priv, TRANSCONF(cpu_transcoder), val); + intel_de_posting_read(dev_priv, TRANSCONF(cpu_transcoder)); } static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state) @@ -3523,33 +3524,33 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc, pipe_config->shared_dpll = NULL; ret = false; - tmp = intel_de_read(dev_priv, PIPECONF(crtc->pipe)); - if (!(tmp & PIPECONF_ENABLE)) + tmp = intel_de_read(dev_priv, TRANSCONF(pipe_config->cpu_transcoder)); + if (!(tmp & TRANSCONF_ENABLE)) goto out; - switch (tmp & PIPECONF_BPC_MASK) { - case PIPECONF_BPC_6: + switch (tmp & TRANSCONF_BPC_MASK) { + case TRANSCONF_BPC_6: pipe_config->pipe_bpp = 18; break; - case PIPECONF_BPC_8: + case TRANSCONF_BPC_8: pipe_config->pipe_bpp = 24; break; - case PIPECONF_BPC_10: + case TRANSCONF_BPC_10: pipe_config->pipe_bpp = 30; break; - case PIPECONF_BPC_12: + case TRANSCONF_BPC_12: pipe_config->pipe_bpp = 36; break; default: break; } - if (tmp & PIPECONF_COLOR_RANGE_SELECT) + if (tmp & TRANSCONF_COLOR_RANGE_SELECT) pipe_config->limited_color_range = true; - switch (tmp & PIPECONF_OUTPUT_COLORSPACE_MASK) { - case PIPECONF_OUTPUT_COLORSPACE_YUV601: - case PIPECONF_OUTPUT_COLORSPACE_YUV709: + switch (tmp & TRANSCONF_OUTPUT_COLORSPACE_MASK) { + case TRANSCONF_OUTPUT_COLORSPACE_YUV601: + case TRANSCONF_OUTPUT_COLORSPACE_YUV709: pipe_config->output_format = INTEL_OUTPUT_FORMAT_YCBCR444; break; default: @@ -3557,11 +3558,11 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc, break; } - pipe_config->gamma_mode = REG_FIELD_GET(PIPECONF_GAMMA_MODE_MASK_ILK, tmp); + pipe_config->gamma_mode = REG_FIELD_GET(TRANSCONF_GAMMA_MODE_MASK_ILK, tmp); - pipe_config->framestart_delay = REG_FIELD_GET(PIPECONF_FRAME_START_DELAY_MASK, tmp) + 1; + pipe_config->framestart_delay = REG_FIELD_GET(TRANSCONF_FRAME_START_DELAY_MASK, tmp) + 1; - pipe_config->msa_timing_delay = REG_FIELD_GET(PIPECONF_MSA_TIMING_DELAY_MASK, tmp); + pipe_config->msa_timing_delay = REG_FIELD_GET(TRANSCONF_MSA_TIMING_DELAY_MASK, tmp); pipe_config->csc_mode = intel_de_read(dev_priv, PIPE_CSC_MODE(crtc->pipe)); @@ -3838,9 +3839,9 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, pipe_config->pch_pfit.force_thru = true; } - tmp = intel_de_read(dev_priv, PIPECONF(pipe_config->cpu_transcoder)); + tmp = intel_de_read(dev_priv, TRANSCONF(pipe_config->cpu_transcoder)); - return tmp & PIPECONF_ENABLE; + return tmp & TRANSCONF_ENABLE; } static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, @@ -3944,9 +3945,9 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, if (IS_HASWELL(dev_priv)) { u32 tmp = intel_de_read(dev_priv, - PIPECONF(pipe_config->cpu_transcoder)); + TRANSCONF(pipe_config->cpu_transcoder)); - if (tmp & PIPECONF_OUTPUT_COLORSPACE_YUV_HSW) + if (tmp & TRANSCONF_OUTPUT_COLORSPACE_YUV_HSW) pipe_config->output_format = INTEL_OUTPUT_FORMAT_YCBCR444; else pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; @@ -8665,8 +8666,8 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) udelay(150); /* wait for warmup */ } - intel_de_write(dev_priv, PIPECONF(pipe), PIPECONF_ENABLE); - intel_de_posting_read(dev_priv, PIPECONF(pipe)); + intel_de_write(dev_priv, TRANSCONF(pipe), TRANSCONF_ENABLE); + intel_de_posting_read(dev_priv, TRANSCONF(pipe)); intel_wait_for_pipe_scanline_moving(crtc); } @@ -8689,8 +8690,8 @@ void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) drm_WARN_ON(&dev_priv->drm, intel_de_read(dev_priv, CURCNTR(PIPE_B)) & MCURSOR_MODE_MASK); - intel_de_write(dev_priv, PIPECONF(pipe), 0); - intel_de_posting_read(dev_priv, PIPECONF(pipe)); + intel_de_write(dev_priv, TRANSCONF(pipe), 0); + intel_de_posting_read(dev_priv, TRANSCONF(pipe)); intel_wait_for_pipe_scanline_stopped(crtc); -- cgit From 9c0cd4bb9a2da8c69cd9331ba1824bca027d6090 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 14 Feb 2023 00:52:54 +0200 Subject: drm/i915: Add local adjusted_mode variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up the eyesore in intel_get_transcoder_timings() a bit by adding a local 'adjusted_mode' variable. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230213225258.2127-9-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 35 +++++++++++++--------------- 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 77ea780b7107..2f856d2a3c78 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2811,42 +2811,39 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc, struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; + struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; u32 tmp; tmp = intel_de_read(dev_priv, TRANS_HTOTAL(cpu_transcoder)); - pipe_config->hw.adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1; - pipe_config->hw.adjusted_mode.crtc_htotal = ((tmp >> 16) & 0xffff) + 1; + adjusted_mode->crtc_hdisplay = (tmp & 0xffff) + 1; + adjusted_mode->crtc_htotal = ((tmp >> 16) & 0xffff) + 1; if (!transcoder_is_dsi(cpu_transcoder)) { tmp = intel_de_read(dev_priv, TRANS_HBLANK(cpu_transcoder)); - pipe_config->hw.adjusted_mode.crtc_hblank_start = - (tmp & 0xffff) + 1; - pipe_config->hw.adjusted_mode.crtc_hblank_end = - ((tmp >> 16) & 0xffff) + 1; + adjusted_mode->crtc_hblank_start = (tmp & 0xffff) + 1; + adjusted_mode->crtc_hblank_end = ((tmp >> 16) & 0xffff) + 1; } tmp = intel_de_read(dev_priv, TRANS_HSYNC(cpu_transcoder)); - pipe_config->hw.adjusted_mode.crtc_hsync_start = (tmp & 0xffff) + 1; - pipe_config->hw.adjusted_mode.crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1; + adjusted_mode->crtc_hsync_start = (tmp & 0xffff) + 1; + adjusted_mode->crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1; tmp = intel_de_read(dev_priv, TRANS_VTOTAL(cpu_transcoder)); - pipe_config->hw.adjusted_mode.crtc_vdisplay = (tmp & 0xffff) + 1; - pipe_config->hw.adjusted_mode.crtc_vtotal = ((tmp >> 16) & 0xffff) + 1; + adjusted_mode->crtc_vdisplay = (tmp & 0xffff) + 1; + adjusted_mode->crtc_vtotal = ((tmp >> 16) & 0xffff) + 1; if (!transcoder_is_dsi(cpu_transcoder)) { tmp = intel_de_read(dev_priv, TRANS_VBLANK(cpu_transcoder)); - pipe_config->hw.adjusted_mode.crtc_vblank_start = - (tmp & 0xffff) + 1; - pipe_config->hw.adjusted_mode.crtc_vblank_end = - ((tmp >> 16) & 0xffff) + 1; + adjusted_mode->crtc_vblank_start = (tmp & 0xffff) + 1; + adjusted_mode->crtc_vblank_end = ((tmp >> 16) & 0xffff) + 1; } tmp = intel_de_read(dev_priv, TRANS_VSYNC(cpu_transcoder)); - pipe_config->hw.adjusted_mode.crtc_vsync_start = (tmp & 0xffff) + 1; - pipe_config->hw.adjusted_mode.crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1; + adjusted_mode->crtc_vsync_start = (tmp & 0xffff) + 1; + adjusted_mode->crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1; if (intel_pipe_is_interlaced(pipe_config)) { - pipe_config->hw.adjusted_mode.flags |= DRM_MODE_FLAG_INTERLACE; - pipe_config->hw.adjusted_mode.crtc_vtotal += 1; - pipe_config->hw.adjusted_mode.crtc_vblank_end += 1; + adjusted_mode->flags |= DRM_MODE_FLAG_INTERLACE; + adjusted_mode->crtc_vtotal += 1; + adjusted_mode->crtc_vblank_end += 1; } } -- cgit From 050db7d70c3c6cf72d11dde8961f953f990b9c6e Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 14 Feb 2023 00:52:55 +0200 Subject: drm/i915: Define transcoder timing register bitmasks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define the contents of the transcoder timing registers using REG_GENMASK() & co. For ease of maintenance let's just define the bitmasks with the full 16bit width (also used by the current hand rolled stuff) even though not all bits are actually used. None of the unsued bits have ever contained anything. Jani spotted that the CRT load detection code did use narrower bitmasks, so that is now going to change. But that is fine since any garbage in the high bits would have been caught by the state checker that always used the full 16bit masks. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230213225258.2127-10-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 64 +++++++++++++++++----------- 1 file changed, 39 insertions(+), 25 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 2f856d2a3c78..1d34429f361e 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2751,18 +2751,24 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta vsyncshift); intel_de_write(dev_priv, TRANS_HTOTAL(cpu_transcoder), - (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16)); + HACTIVE(adjusted_mode->crtc_hdisplay - 1) | + HTOTAL(adjusted_mode->crtc_htotal - 1)); intel_de_write(dev_priv, TRANS_HBLANK(cpu_transcoder), - (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16)); + HBLANK_START(adjusted_mode->crtc_hblank_start - 1) | + HBLANK_END(adjusted_mode->crtc_hblank_end - 1)); intel_de_write(dev_priv, TRANS_HSYNC(cpu_transcoder), - (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16)); + HSYNC_START(adjusted_mode->crtc_hsync_start - 1) | + HSYNC_END(adjusted_mode->crtc_hsync_end - 1)); intel_de_write(dev_priv, TRANS_VTOTAL(cpu_transcoder), - (adjusted_mode->crtc_vdisplay - 1) | ((crtc_vtotal - 1) << 16)); + VACTIVE(adjusted_mode->crtc_vdisplay - 1) | + VTOTAL(crtc_vtotal - 1)); intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder), - (adjusted_mode->crtc_vblank_start - 1) | ((crtc_vblank_end - 1) << 16)); + VBLANK_START(adjusted_mode->crtc_vblank_start - 1) | + VBLANK_END(crtc_vblank_end - 1)); intel_de_write(dev_priv, TRANS_VSYNC(cpu_transcoder), - (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16)); + VSYNC_START(adjusted_mode->crtc_vsync_start - 1) | + VSYNC_END(adjusted_mode->crtc_vsync_end - 1)); /* Workaround: when the EDP input selection is B, the VTOTAL_B must be * programmed with the VTOTAL_EDP value. Same for VTOTAL_C. This is @@ -2815,30 +2821,31 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc, u32 tmp; tmp = intel_de_read(dev_priv, TRANS_HTOTAL(cpu_transcoder)); - adjusted_mode->crtc_hdisplay = (tmp & 0xffff) + 1; - adjusted_mode->crtc_htotal = ((tmp >> 16) & 0xffff) + 1; + adjusted_mode->crtc_hdisplay = REG_FIELD_GET(HACTIVE_MASK, tmp) + 1; + adjusted_mode->crtc_htotal = REG_FIELD_GET(HTOTAL_MASK, tmp) + 1; if (!transcoder_is_dsi(cpu_transcoder)) { tmp = intel_de_read(dev_priv, TRANS_HBLANK(cpu_transcoder)); - adjusted_mode->crtc_hblank_start = (tmp & 0xffff) + 1; - adjusted_mode->crtc_hblank_end = ((tmp >> 16) & 0xffff) + 1; + adjusted_mode->crtc_hblank_start = REG_FIELD_GET(HBLANK_START_MASK, tmp) + 1; + adjusted_mode->crtc_hblank_end = REG_FIELD_GET(HBLANK_END_MASK, tmp) + 1; } + tmp = intel_de_read(dev_priv, TRANS_HSYNC(cpu_transcoder)); - adjusted_mode->crtc_hsync_start = (tmp & 0xffff) + 1; - adjusted_mode->crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1; + adjusted_mode->crtc_hsync_start = REG_FIELD_GET(HSYNC_START_MASK, tmp) + 1; + adjusted_mode->crtc_hsync_end = REG_FIELD_GET(HSYNC_END_MASK, tmp) + 1; tmp = intel_de_read(dev_priv, TRANS_VTOTAL(cpu_transcoder)); - adjusted_mode->crtc_vdisplay = (tmp & 0xffff) + 1; - adjusted_mode->crtc_vtotal = ((tmp >> 16) & 0xffff) + 1; + adjusted_mode->crtc_vdisplay = REG_FIELD_GET(VACTIVE_MASK, tmp) + 1; + adjusted_mode->crtc_vtotal = REG_FIELD_GET(VTOTAL_MASK, tmp) + 1; if (!transcoder_is_dsi(cpu_transcoder)) { tmp = intel_de_read(dev_priv, TRANS_VBLANK(cpu_transcoder)); - adjusted_mode->crtc_vblank_start = (tmp & 0xffff) + 1; - adjusted_mode->crtc_vblank_end = ((tmp >> 16) & 0xffff) + 1; + adjusted_mode->crtc_vblank_start = REG_FIELD_GET(VBLANK_START_MASK, tmp) + 1; + adjusted_mode->crtc_vblank_end = REG_FIELD_GET(VBLANK_END_MASK, tmp) + 1; } tmp = intel_de_read(dev_priv, TRANS_VSYNC(cpu_transcoder)); - adjusted_mode->crtc_vsync_start = (tmp & 0xffff) + 1; - adjusted_mode->crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1; + adjusted_mode->crtc_vsync_start = REG_FIELD_GET(VSYNC_START_MASK, tmp) + 1; + adjusted_mode->crtc_vsync_end = REG_FIELD_GET(VSYNC_END_MASK, tmp) + 1; if (intel_pipe_is_interlaced(pipe_config)) { adjusted_mode->flags |= DRM_MODE_FLAG_INTERLACE; @@ -8626,13 +8633,20 @@ void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe) PLL_REF_INPUT_DREFCLK | DPLL_VCO_ENABLE; - intel_de_write(dev_priv, TRANS_HTOTAL(cpu_transcoder), (640 - 1) | ((800 - 1) << 16)); - intel_de_write(dev_priv, TRANS_HBLANK(cpu_transcoder), (640 - 1) | ((800 - 1) << 16)); - intel_de_write(dev_priv, TRANS_HSYNC(cpu_transcoder), (656 - 1) | ((752 - 1) << 16)); - intel_de_write(dev_priv, TRANS_VTOTAL(cpu_transcoder), (480 - 1) | ((525 - 1) << 16)); - intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder), (480 - 1) | ((525 - 1) << 16)); - intel_de_write(dev_priv, TRANS_VSYNC(cpu_transcoder), (490 - 1) | ((492 - 1) << 16)); - intel_de_write(dev_priv, PIPESRC(pipe), ((640 - 1) << 16) | (480 - 1)); + intel_de_write(dev_priv, TRANS_HTOTAL(cpu_transcoder), + HACTIVE(640 - 1) | HTOTAL(800 - 1)); + intel_de_write(dev_priv, TRANS_HBLANK(cpu_transcoder), + HBLANK_START(640 - 1) | HBLANK_END(800 - 1)); + intel_de_write(dev_priv, TRANS_HSYNC(cpu_transcoder), + HSYNC_START(656 - 1) | HSYNC_END(752 - 1)); + intel_de_write(dev_priv, TRANS_VTOTAL(cpu_transcoder), + VACTIVE(480 - 1) | VTOTAL(525 - 1)); + intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder), + VBLANK_START(480 - 1) | VBLANK_END(525 - 1)); + intel_de_write(dev_priv, TRANS_VSYNC(cpu_transcoder), + VSYNC_START(490 - 1) | VSYNC_END(492 - 1)); + intel_de_write(dev_priv, PIPESRC(pipe), + PIPESRC_WIDTH(640 - 1) | PIPESRC_HEIGHT(480 - 1)); intel_de_write(dev_priv, FP0(pipe), fp); intel_de_write(dev_priv, FP1(pipe), fp); -- cgit From 2846cf3fdb8b500e374efdcad3134633dcc5ce60 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 14 Feb 2023 00:52:56 +0200 Subject: drm/i915: Configure TRANS_SET_CONTEXT_LATENCY correctly on ADL+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On TGL VBLANK.VBLANK_START was the mechanism by which we can delay the pipe's internal vblank in relation to the transcoder's vblank. On ADL+ that no longer does anything. Instead we must now use the new TRANS_SET_CONTEXT_LATENCY register. Program it accordingly. And since VBLANK.VBLANK_START is no longer used by the hardware on ADL+ let's just zero it out to make it stand out in register dumps. Seeing the zeroed value should hopefully remind people to check the other register instead. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230213225258.2127-11-ville.syrjala@linux.intel.com Acked-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 1d34429f361e..6268037c39fc 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2724,12 +2724,14 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta enum pipe pipe = crtc->pipe; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - u32 crtc_vtotal, crtc_vblank_end; + u32 crtc_vdisplay, crtc_vtotal, crtc_vblank_start, crtc_vblank_end; int vsyncshift = 0; /* We need to be careful not to changed the adjusted mode, for otherwise * the hw state checker will get angry at the mismatch. */ + crtc_vdisplay = adjusted_mode->crtc_vdisplay; crtc_vtotal = adjusted_mode->crtc_vtotal; + crtc_vblank_start = adjusted_mode->crtc_vblank_start; crtc_vblank_end = adjusted_mode->crtc_vblank_end; if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { @@ -2746,6 +2748,21 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta vsyncshift += adjusted_mode->crtc_htotal; } + /* + * VBLANK_START no longer works on ADL+, instead we must use + * TRANS_SET_CONTEXT_LATENCY to configure the pipe vblank start. + */ + if (DISPLAY_VER(dev_priv) >= 13) { + intel_de_write(dev_priv, TRANS_SET_CONTEXT_LATENCY(cpu_transcoder), + crtc_vblank_start - crtc_vdisplay); + + /* + * VBLANK_START not used by hw, just clear it + * to make it stand out in register dumps. + */ + crtc_vblank_start = 1; + } + if (DISPLAY_VER(dev_priv) > 3) intel_de_write(dev_priv, TRANS_VSYNCSHIFT(cpu_transcoder), vsyncshift); @@ -2761,10 +2778,10 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta HSYNC_END(adjusted_mode->crtc_hsync_end - 1)); intel_de_write(dev_priv, TRANS_VTOTAL(cpu_transcoder), - VACTIVE(adjusted_mode->crtc_vdisplay - 1) | + VACTIVE(crtc_vdisplay - 1) | VTOTAL(crtc_vtotal - 1)); intel_de_write(dev_priv, TRANS_VBLANK(cpu_transcoder), - VBLANK_START(adjusted_mode->crtc_vblank_start - 1) | + VBLANK_START(crtc_vblank_start - 1) | VBLANK_END(crtc_vblank_end - 1)); intel_de_write(dev_priv, TRANS_VSYNC(cpu_transcoder), VSYNC_START(adjusted_mode->crtc_vsync_start - 1) | @@ -2852,6 +2869,11 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc, adjusted_mode->crtc_vtotal += 1; adjusted_mode->crtc_vblank_end += 1; } + + if (DISPLAY_VER(dev_priv) >= 13 && !transcoder_is_dsi(cpu_transcoder)) + adjusted_mode->crtc_vblank_start = + adjusted_mode->crtc_vdisplay + + intel_de_read(dev_priv, TRANS_SET_CONTEXT_LATENCY(cpu_transcoder)); } static void intel_bigjoiner_adjust_pipe_src(struct intel_crtc_state *crtc_state) -- cgit From 1552dd6ef99fb54479afdd2fb84473b9655cad3c Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 14 Feb 2023 00:52:57 +0200 Subject: drm/i915: Sprinkle some FIXMEs about TGL+ DSI transcoder timing mess MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DSI code has some local hacks to program TRANS_VBLANK on TGL+ (ICL DSI transcoders didn't have this register). That will not work when we need to start using the delayed vblank (for DSB purposes). Too lazy to figure out what the is going on there, so just sprinkle FIXMEs in the hopes someone else will spot them eventually. v2: Only TRANS_{HBLANK,SET_CONTEXT_LATENCY} still no not exist for DSI transcoders, only TRANS_VBLANK Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230213225258.2127-12-ville.syrjala@linux.intel.com Acked-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 6268037c39fc..463fa4835d12 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2855,6 +2855,7 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc, adjusted_mode->crtc_vdisplay = REG_FIELD_GET(VACTIVE_MASK, tmp) + 1; adjusted_mode->crtc_vtotal = REG_FIELD_GET(VTOTAL_MASK, tmp) + 1; + /* FIXME TGL+ DSI transcoders have this! */ if (!transcoder_is_dsi(cpu_transcoder)) { tmp = intel_de_read(dev_priv, TRANS_VBLANK(cpu_transcoder)); adjusted_mode->crtc_vblank_start = REG_FIELD_GET(VBLANK_START_MASK, tmp) + 1; -- cgit From 9548fefcaf9ab61291c0bd427627aa773b19dc75 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 14 Feb 2023 00:52:58 +0200 Subject: drm/i915: Remove pointless register read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We just wrote the EDP transcoder's VTOTAL register a few lines earlier, so instead of reading it back out again let's just generate the same value for the transocder B/C register. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230213225258.2127-13-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 463fa4835d12..e882d68fdca9 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2794,8 +2794,8 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta if (IS_HASWELL(dev_priv) && cpu_transcoder == TRANSCODER_EDP && (pipe == PIPE_B || pipe == PIPE_C)) intel_de_write(dev_priv, TRANS_VTOTAL(pipe), - intel_de_read(dev_priv, TRANS_VTOTAL(cpu_transcoder))); - + VACTIVE(crtc_vdisplay - 1) | + VTOTAL(crtc_vtotal - 1)); } static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state) -- cgit From c3f059483671426266f681833bac6c09b0736247 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 1 Mar 2023 17:19:49 +0200 Subject: drm/i915/display: split out DSC and DSS registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Relatively few places need the DSC and DSS register definitions. Move them to intel_vdsc_regs.h. Signed-off-by: Jani Nikula Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230301151949.1591501-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index e882d68fdca9..7f2f736a0dee 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -116,6 +116,7 @@ #include "intel_tv.h" #include "intel_vblank.h" #include "intel_vdsc.h" +#include "intel_vdsc_regs.h" #include "intel_vga.h" #include "intel_vrr.h" #include "intel_wm.h" -- cgit From 2553bacaf953b48c59357f5a622282bc0c45adae Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 23 Feb 2023 17:20:48 +0200 Subject: drm/i915: Preserve crtc_state->inherited during state clearing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit intel_crtc_prepare_cleared_state() is unintentionally losing the "inherited" flag. This will happen if intel_initial_commit() is forced to go through the full modeset calculations for whatever reason. Afterwards the first real commit from userspace will not get forced to the full modeset path, and thus eg. audio state may not get recomputed properly. So if the monitor was already enabled during boot audio will not work until userspace itself does an explicit full modeset. Cc: stable@vger.kernel.org Tested-by: Lee Shawn C Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230223152048.20878-1-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar --- drivers/gpu/drm/i915/display/intel_display.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 7f2f736a0dee..d96f7bbca30f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5079,6 +5079,7 @@ intel_crtc_prepare_cleared_state(struct intel_atomic_state *state, * only fields that are know to not cause problems are preserved. */ saved_state->uapi = crtc_state->uapi; + saved_state->inherited = crtc_state->inherited; saved_state->scaler_state = crtc_state->scaler_state; saved_state->shared_dpll = crtc_state->shared_dpll; saved_state->dpll_hw_state = crtc_state->dpll_hw_state; -- cgit From 673515ba0249e47a0e69c56a16af24399c824d60 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 8 Mar 2023 18:25:03 +0200 Subject: drm/i915/opregion: Register display debugfs later, after initialization steps Move the display debugfs registration later, after initializing steps for opregion/acpi/audio. These latter ones don't depend on the debugfs entries, OTOH some debugfs entries may depend on the initialized state. Reviewed-by: Jani Nikula Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230308162503.3219200-3-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d96f7bbca30f..c94574130278 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8883,14 +8883,14 @@ void intel_display_driver_register(struct drm_i915_private *i915) if (!HAS_DISPLAY(i915)) return; - intel_display_debugfs_register(i915); - /* Must be done after probing outputs */ intel_opregion_register(i915); intel_acpi_video_register(i915); intel_audio_init(i915); + intel_display_debugfs_register(i915); + /* * Some ports require correctly set-up hpd registers for * detection to work properly (leading to ghost connected -- cgit From c640f6c5570a6af904db37979d344ace8312c675 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 14 Mar 2023 15:02:48 +0200 Subject: drm/i915: s/PIPEMISC/PIPE_MISC/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PIPEMISC vs. PIPE_MISC inconsitency is ugly. Unify the naming (PIPE_MISC is also what bspec has always called it). Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230314130255.23273-3-ville.syrjala@linux.intel.com Reviewed-by: Jouni Högander --- drivers/gpu/drm/i915/display/intel_display.c | 56 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index c94574130278..8b009eb7c1da 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -131,7 +131,7 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state); static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state); static void hsw_set_transconf(const struct intel_crtc_state *crtc_state); -static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state); +static void bdw_set_pipe_misc(const struct intel_crtc_state *crtc_state); static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state); /* returns HPLL frequency in kHz */ @@ -1793,7 +1793,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, intel_set_pipe_src_size(new_crtc_state); if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) - bdw_set_pipemisc(new_crtc_state); + bdw_set_pipe_misc(new_crtc_state); if (!intel_crtc_is_bigjoiner_slave(new_crtc_state) && !transcoder_is_dsi(cpu_transcoder)) @@ -3074,20 +3074,20 @@ static void chv_crtc_clock_get(struct intel_crtc *crtc, } static enum intel_output_format -bdw_get_pipemisc_output_format(struct intel_crtc *crtc) +bdw_get_pipe_misc_output_format(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 tmp; - tmp = intel_de_read(dev_priv, PIPEMISC(crtc->pipe)); + tmp = intel_de_read(dev_priv, PIPE_MISC(crtc->pipe)); - if (tmp & PIPEMISC_YUV420_ENABLE) { + if (tmp & PIPE_MISC_YUV420_ENABLE) { /* We support 4:2:0 in full blend mode only */ drm_WARN_ON(&dev_priv->drm, - (tmp & PIPEMISC_YUV420_MODE_FULL_BLEND) == 0); + (tmp & PIPE_MISC_YUV420_MODE_FULL_BLEND) == 0); return INTEL_OUTPUT_FORMAT_YCBCR420; - } else if (tmp & PIPEMISC_OUTPUT_COLORSPACE_YUV) { + } else if (tmp & PIPE_MISC_OUTPUT_COLORSPACE_YUV) { return INTEL_OUTPUT_FORMAT_YCBCR444; } else { return INTEL_OUTPUT_FORMAT_RGB; @@ -3330,7 +3330,7 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state) intel_de_posting_read(dev_priv, TRANSCONF(cpu_transcoder)); } -static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state) +static void bdw_set_pipe_misc(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); @@ -3338,18 +3338,18 @@ static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state) switch (crtc_state->pipe_bpp) { case 18: - val |= PIPEMISC_BPC_6; + val |= PIPE_MISC_BPC_6; break; case 24: - val |= PIPEMISC_BPC_8; + val |= PIPE_MISC_BPC_8; break; case 30: - val |= PIPEMISC_BPC_10; + val |= PIPE_MISC_BPC_10; break; case 36: /* Port output 12BPC defined for ADLP+ */ if (DISPLAY_VER(dev_priv) > 12) - val |= PIPEMISC_BPC_12_ADLP; + val |= PIPE_MISC_BPC_12_ADLP; break; default: MISSING_CASE(crtc_state->pipe_bpp); @@ -3357,38 +3357,38 @@ static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state) } if (crtc_state->dither) - val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP; + val |= PIPE_MISC_DITHER_ENABLE | PIPE_MISC_DITHER_TYPE_SP; if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 || crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444) - val |= PIPEMISC_OUTPUT_COLORSPACE_YUV; + val |= PIPE_MISC_OUTPUT_COLORSPACE_YUV; if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) - val |= PIPEMISC_YUV420_ENABLE | - PIPEMISC_YUV420_MODE_FULL_BLEND; + val |= PIPE_MISC_YUV420_ENABLE | + PIPE_MISC_YUV420_MODE_FULL_BLEND; if (DISPLAY_VER(dev_priv) >= 11 && is_hdr_mode(crtc_state)) - val |= PIPEMISC_HDR_MODE_PRECISION; + val |= PIPE_MISC_HDR_MODE_PRECISION; if (DISPLAY_VER(dev_priv) >= 12) - val |= PIPEMISC_PIXEL_ROUNDING_TRUNC; + val |= PIPE_MISC_PIXEL_ROUNDING_TRUNC; - intel_de_write(dev_priv, PIPEMISC(crtc->pipe), val); + intel_de_write(dev_priv, PIPE_MISC(crtc->pipe), val); } -int bdw_get_pipemisc_bpp(struct intel_crtc *crtc) +int bdw_get_pipe_misc_bpp(struct intel_crtc *crtc) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); u32 tmp; - tmp = intel_de_read(dev_priv, PIPEMISC(crtc->pipe)); + tmp = intel_de_read(dev_priv, PIPE_MISC(crtc->pipe)); - switch (tmp & PIPEMISC_BPC_MASK) { - case PIPEMISC_BPC_6: + switch (tmp & PIPE_MISC_BPC_MASK) { + case PIPE_MISC_BPC_6: return 18; - case PIPEMISC_BPC_8: + case PIPE_MISC_BPC_8: return 24; - case PIPEMISC_BPC_10: + case PIPE_MISC_BPC_10: return 30; /* * PORT OUTPUT 12 BPC defined for ADLP+. @@ -3400,7 +3400,7 @@ int bdw_get_pipemisc_bpp(struct intel_crtc *crtc) * on older platforms, need to find a workaround for 12 BPC * MIPI DSI HW readout. */ - case PIPEMISC_BPC_12_ADLP: + case PIPE_MISC_BPC_12_ADLP: if (DISPLAY_VER(dev_priv) > 12) return 36; fallthrough; @@ -3981,7 +3981,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; } else { pipe_config->output_format = - bdw_get_pipemisc_output_format(crtc); + bdw_get_pipe_misc_output_format(crtc); } pipe_config->gamma_mode = intel_de_read(dev_priv, @@ -6967,7 +6967,7 @@ static void commit_pipe_pre_planes(struct intel_atomic_state *state, intel_color_commit_arm(new_crtc_state); if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) - bdw_set_pipemisc(new_crtc_state); + bdw_set_pipe_misc(new_crtc_state); if (intel_crtc_needs_fastset(new_crtc_state)) intel_pipe_fastset(old_crtc_state, new_crtc_state); -- cgit From c931ef0041fe0a7b62b7d15774a831f3bc85713a Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 14 Mar 2023 15:02:50 +0200 Subject: drm/i915: Program VLV/CHV PIPE_MSA_MISC register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VLV/CHV have an extra register to configure some stereo3d signalling details via DP MSA. Make sure we reset that register to zero (since we don't do any stereo3d stuff). Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230314130255.23273-5-ville.syrjala@linux.intel.com Reviewed-by: Jouni Högander --- drivers/gpu/drm/i915/display/intel_display.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 8b009eb7c1da..b8691bcdf409 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2139,6 +2139,8 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state, intel_set_pipe_src_size(new_crtc_state); + intel_de_write(dev_priv, VLV_PIPE_MSA_MISC(pipe), 0); + if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) { intel_de_write(dev_priv, CHV_BLEND(pipe), CHV_BLEND_LEGACY); intel_de_write(dev_priv, CHV_CANVAS(pipe), 0); -- cgit From 0ec2a5b291af32dcd2b52dc8c1d53c3037238939 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 14 Mar 2023 15:02:54 +0200 Subject: drm/i915: Relocate intel_plane_check_src_coordinates() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move intel_plane_check_src_coordinates() from the pre-skl sprite plane specific code to a more suitable place for common plane code. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230314130255.23273-9-ville.syrjala@linux.intel.com Reviewed-by: Jouni Högander --- drivers/gpu/drm/i915/display/intel_display.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index b8691bcdf409..7305ad6592d3 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -111,7 +111,6 @@ #include "intel_quirks.h" #include "intel_sdvo.h" #include "intel_snps_phy.h" -#include "intel_sprite.h" #include "intel_tc.h" #include "intel_tv.h" #include "intel_vblank.h" -- cgit From 6e8acb6686d805ac5d127fb691e28e742248c523 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Sat, 11 Mar 2023 01:58:26 +0200 Subject: drm/i915: Add belts and suspenders locking for seamless M/N changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add some (probably overkill) locking to protect the vblank timestamping constants updates during seamless M/N fastsets. As everything should be naturally aligned I think the individual pieces should probably end up updating atomically enough. So this is only really meant to guarantee everyone sees a consistent whole. All the drm_vblank.c usage is covered by vblank_time_lock, and uncore.lock will take care of __intel_get_crtc_scanline() that can also be called from outside the core vblank functionality. Currently only crtc_clock and framedur_ns can change, but in the future might fastset also across eg. vtotal/vblank_end changes, so let's just grab the locks across the whole thing. Reviewed-by: Jani Nikula Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230310235828.17439-2-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 7305ad6592d3..4fd64dcfaf12 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5907,6 +5907,8 @@ void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state) struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct drm_display_mode adjusted_mode; + int vmax_vblank_start = 0; + unsigned long irqflags; drm_mode_init(&adjusted_mode, &crtc_state->hw.adjusted_mode); @@ -5914,11 +5916,28 @@ void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state) adjusted_mode.crtc_vtotal = crtc_state->vrr.vmax; adjusted_mode.crtc_vblank_end = crtc_state->vrr.vmax; adjusted_mode.crtc_vblank_start = intel_vrr_vmin_vblank_start(crtc_state); - crtc->vmax_vblank_start = intel_vrr_vmax_vblank_start(crtc_state); + vmax_vblank_start = intel_vrr_vmax_vblank_start(crtc_state); } + /* + * Belts and suspenders locking to guarantee everyone sees 100% + * consistent state during fastset seamless refresh rate changes. + * + * vblank_time_lock takes care of all drm_vblank.c stuff, and + * uncore.lock takes care of __intel_get_crtc_scanline() which + * may get called elsewhere as well. + * + * TODO maybe just protect everything (including + * __intel_get_crtc_scanline()) with vblank_time_lock? + * Need to audit everything to make sure it's safe. + */ + spin_lock_irqsave(&dev_priv->drm.vblank_time_lock, irqflags); + spin_lock(&dev_priv->uncore.lock); + drm_calc_timestamping_constants(&crtc->base, &adjusted_mode); + crtc->vmax_vblank_start = vmax_vblank_start; + crtc->mode_flags = crtc_state->mode_flags; /* @@ -5962,6 +5981,9 @@ void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state) } else { crtc->scanline_offset = 1; } + + spin_unlock(&dev_priv->uncore.lock); + spin_unlock_irqrestore(&dev_priv->drm.vblank_time_lock, irqflags); } /* -- cgit From 84f4ebe8c1abbe375babbea46eab746a0060e80c Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Sat, 11 Mar 2023 01:58:27 +0200 Subject: drm/i915: Relocate intel_crtc_update_active_timings() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move intel_crtc_update_active_timings() into intel_vblank.c where it more properly belongs. Also do the s/dev_priv/i915/ modernization rename while at it. Reviewed-by: Jani Nikula Reviewed-by: Mitul Golani Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230310235828.17439-3-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 84 ---------------------------- 1 file changed, 84 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 4fd64dcfaf12..e044b97a516b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5902,90 +5902,6 @@ int intel_modeset_all_pipes(struct intel_atomic_state *state, return 0; } -void intel_crtc_update_active_timings(const struct intel_crtc_state *crtc_state) -{ - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - struct drm_display_mode adjusted_mode; - int vmax_vblank_start = 0; - unsigned long irqflags; - - drm_mode_init(&adjusted_mode, &crtc_state->hw.adjusted_mode); - - if (crtc_state->vrr.enable) { - adjusted_mode.crtc_vtotal = crtc_state->vrr.vmax; - adjusted_mode.crtc_vblank_end = crtc_state->vrr.vmax; - adjusted_mode.crtc_vblank_start = intel_vrr_vmin_vblank_start(crtc_state); - vmax_vblank_start = intel_vrr_vmax_vblank_start(crtc_state); - } - - /* - * Belts and suspenders locking to guarantee everyone sees 100% - * consistent state during fastset seamless refresh rate changes. - * - * vblank_time_lock takes care of all drm_vblank.c stuff, and - * uncore.lock takes care of __intel_get_crtc_scanline() which - * may get called elsewhere as well. - * - * TODO maybe just protect everything (including - * __intel_get_crtc_scanline()) with vblank_time_lock? - * Need to audit everything to make sure it's safe. - */ - spin_lock_irqsave(&dev_priv->drm.vblank_time_lock, irqflags); - spin_lock(&dev_priv->uncore.lock); - - drm_calc_timestamping_constants(&crtc->base, &adjusted_mode); - - crtc->vmax_vblank_start = vmax_vblank_start; - - crtc->mode_flags = crtc_state->mode_flags; - - /* - * The scanline counter increments at the leading edge of hsync. - * - * On most platforms it starts counting from vtotal-1 on the - * first active line. That means the scanline counter value is - * always one less than what we would expect. Ie. just after - * start of vblank, which also occurs at start of hsync (on the - * last active line), the scanline counter will read vblank_start-1. - * - * On gen2 the scanline counter starts counting from 1 instead - * of vtotal-1, so we have to subtract one (or rather add vtotal-1 - * to keep the value positive), instead of adding one. - * - * On HSW+ the behaviour of the scanline counter depends on the output - * type. For DP ports it behaves like most other platforms, but on HDMI - * there's an extra 1 line difference. So we need to add two instead of - * one to the value. - * - * On VLV/CHV DSI the scanline counter would appear to increment - * approx. 1/3 of a scanline before start of vblank. Unfortunately - * that means we can't tell whether we're in vblank or not while - * we're on that particular line. We must still set scanline_offset - * to 1 so that the vblank timestamps come out correct when we query - * the scanline counter from within the vblank interrupt handler. - * However if queried just before the start of vblank we'll get an - * answer that's slightly in the future. - */ - if (DISPLAY_VER(dev_priv) == 2) { - int vtotal; - - vtotal = adjusted_mode.crtc_vtotal; - if (adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) - vtotal /= 2; - - crtc->scanline_offset = vtotal - 1; - } else if (HAS_DDI(dev_priv) && - intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) { - crtc->scanline_offset = 2; - } else { - crtc->scanline_offset = 1; - } - - spin_unlock(&dev_priv->uncore.lock); - spin_unlock_irqrestore(&dev_priv->drm.vblank_time_lock, irqflags); -} - /* * This implements the workaround described in the "notes" section of the mode * set sequence documentation. When going from no pipes or single pipe to -- cgit From 3962ca4e080a525fc9eae87aa6b2286f1fae351d Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 20 Mar 2023 11:54:35 +0200 Subject: drm/i915: Add a .color_post_update() hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We're going to need stuff after the color management register latching has happened. Add a corresponding hook. Cc: #v5.19+ Cc: Manasi Navare Cc: Drew Davenport Cc: Imre Deak Cc: Jouni Högander Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230320095438.17328-4-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/display/intel_display.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index e044b97a516b..c91dff8c5d89 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1115,6 +1115,9 @@ static void intel_post_plane_update(struct intel_atomic_state *state, if (needs_cursorclk_wa(old_crtc_state) && !needs_cursorclk_wa(new_crtc_state)) icl_wa_cursorclkgating(dev_priv, pipe, false); + + if (intel_crtc_needs_color_update(new_crtc_state)) + intel_color_post_update(new_crtc_state); } static void intel_crtc_enable_flip_done(struct intel_atomic_state *state, -- cgit From 41b4c7fe72b6105a4b49395eea9aa40cef94288d Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 20 Mar 2023 20:35:32 +0200 Subject: drm/i915: Disable DC states for all commits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keeping DC states enabled is incompatible with the _noarm()/_arm() split we use for writing pipe/plane registers. When DC5 and PSR are enabled, all pipe/plane registers effectively become self-arming on account of DC5 exit arming the update, and PSR exit latching it. What probably saves us most of the time is that (with PIPE_MISC[21]=0) all pipe register writes themselves trigger PSR exit, and then we don't re-enter PSR until the idle frame count has elapsed. So it may be that the PSR exit happens already before we've updated the state too much. Also the PSR1 panel (at least on this KBL) seems to discard the first frame we trasmit, presumably still scanning out from its internal framebuffer at that point. So only the second frame we transmit is actually visible. But I suppose that could also be panel specific behaviour. I haven't checked out how other PSR panels behave, nor did I bother to check what the eDP spec has to say about this. And since this really is all about DC states, let's switch from the MODESET domain to the DC_OFF domain. Functionally they are 100% identical. We should probably remove the MODESET domain... And for good measure let's toss in an assert to the place where we do the _noarm() register writes to make sure DC states are in fact off. v2: Just use intel_display_power_is_enabled() (Imre) Cc: #v5.17+ Cc: Manasi Navare Cc: Drew Davenport Cc: Jouni Högander Reviewed-by: Imre Deak Fixes: d13dde449580 ("drm/i915: Split pipe+output CSC programming to noarm+arm pair") Fixes: f8a005eb8972 ("drm/i915: Optimize icl+ universal plane programming") Fixes: 890b6ec4a522 ("drm/i915: Split skl+ plane update into noarm+arm pair") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230320183532.17727-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index c91dff8c5d89..31585f4aa163 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6985,6 +6985,8 @@ static void intel_update_crtc(struct intel_atomic_state *state, intel_fbc_update(state, crtc); + drm_WARN_ON(&i915->drm, !intel_display_power_is_enabled(i915, POWER_DOMAIN_DC_OFF)); + if (!modeset && intel_crtc_needs_color_update(new_crtc_state)) intel_color_commit_noarm(new_crtc_state); @@ -7352,8 +7354,28 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) drm_atomic_helper_wait_for_dependencies(&state->base); drm_dp_mst_atomic_wait_for_dependencies(&state->base); - if (state->modeset) - wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET); + /* + * During full modesets we write a lot of registers, wait + * for PLLs, etc. Doing that while DC states are enabled + * is not a good idea. + * + * During fastsets and other updates we also need to + * disable DC states due to the following scenario: + * 1. DC5 exit and PSR exit happen + * 2. Some or all _noarm() registers are written + * 3. Due to some long delay PSR is re-entered + * 4. DC5 entry -> DMC saves the already written new + * _noarm() registers and the old not yet written + * _arm() registers + * 5. DC5 exit -> DMC restores a mixture of old and + * new register values and arms the update + * 6. PSR exit -> hardware latches a mixture of old and + * new register values -> corrupted frame, or worse + * 7. New _arm() registers are finally written + * 8. Hardware finally latches a complete set of new + * register values, and subsequent frames will be OK again + */ + wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DC_OFF); intel_atomic_prepare_plane_clear_colors(state); @@ -7502,8 +7524,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * the culprit. */ intel_uncore_arm_unclaimed_mmio_detection(&dev_priv->uncore); - intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET, wakeref); } + intel_display_power_put(dev_priv, POWER_DOMAIN_DC_OFF, wakeref); intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref); /* -- cgit From c5de248484afeb6de259239a23645790038d9df3 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 20 Mar 2023 11:05:21 +0200 Subject: drm/i915/dpt: Add a modparam to disable DPT via the chicken bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add i915.enable_dpt modparam to allow disabling the DPT usage in hardware via the chicken bit. Useful when debugging potential DPT issues. Quickly smoke tested on ADL. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230320090522.9909-6-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- drivers/gpu/drm/i915/display/intel_display.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 31585f4aa163..37d03380b844 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6968,6 +6968,12 @@ static void intel_update_crtc(struct intel_atomic_state *state, intel_atomic_get_new_crtc_state(state, crtc); bool modeset = intel_crtc_needs_modeset(new_crtc_state); + if (old_crtc_state->inherited || + intel_crtc_needs_modeset(new_crtc_state)) { + if (HAS_DPT(i915)) + intel_dpt_configure(crtc); + } + if (!modeset) { if (new_crtc_state->preload_luts && intel_crtc_needs_color_update(new_crtc_state)) -- cgit From 3acac2d06a7e0f0b182b86b25bb8a2e9b3300406 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:32 +0200 Subject: drm/i915: Move shared DPLL disabling into CRTC disable hook The spec requires disabling the PLL on TC ports before disconnecting the port's PHY. Prepare for that by moving the PLL disabling to the CRTC disable hook, while disconnecting the PHY will be moved to the post_pll_disable() encoder hook in the next patch. v2: Move the call from intel_crtc_disable_noatomic() as well. Reviewed-by: Mika Kahola # v1 Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-27-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index b53a1d969344..1ed584d04c10 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1905,6 +1905,8 @@ static void ilk_crtc_disable(struct intel_atomic_state *state, intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); + + intel_disable_shared_dpll(old_crtc_state); } static void hsw_crtc_disable(struct intel_atomic_state *state, @@ -1923,6 +1925,8 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, intel_encoders_post_disable(state, crtc); } + intel_disable_shared_dpll(old_crtc_state); + intel_dmc_disable_pipe(i915, crtc->pipe); } @@ -7041,7 +7045,6 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state, dev_priv->display.funcs.display->crtc_disable(state, crtc); crtc->active = false; intel_fbc_disable(crtc); - intel_disable_shared_dpll(old_crtc_state); if (!new_crtc_state->hw.active) intel_initial_watermarks(state, crtc); -- cgit From b108bdd0e22a402bd3e4a6391acbb6aefad31a9e Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:33 +0200 Subject: drm/i915: Disable DPLLs before disconnecting the TC PHY Bspec requires disabling the DPLLs on TC ports before disconnecting the port's PHY. Add a post_pll_disable encoder hook and move the call to disconnect the port's PHY from the post_disable hook to the new hook. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-28-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 1ed584d04c10..ca0db2332ded 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1927,6 +1927,8 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, intel_disable_shared_dpll(old_crtc_state); + intel_encoders_post_pll_disable(state, crtc); + intel_dmc_disable_pipe(i915, crtc->pipe); } -- cgit From 0f752b2178c988117927154fe3b1d2e619c80c57 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:35 +0200 Subject: drm/i915: Remove the encoder update_prepare()/complete() hooks The encoder update_prepare()/complete() hooks were added to hold a TC port link reference for all outputs in the atomic state around the whole modeset enable sequence - thus locking the ports' TC mode - and set the TBT/DP-alt PLL type corresponding to the current TC mode. Since nothing depends on the PLL selection before/after then encoder's pre_pll_enable/post_pll_disable hooks are called, the above steps can be moved to these hooks, so do that and remove the update_prepare()/complete() hooks. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-30-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 78 ---------------------------- 1 file changed, 78 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ca0db2332ded..810156099b02 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1320,36 +1320,11 @@ static void intel_crtc_disable_planes(struct intel_atomic_state *state, intel_frontbuffer_flip(dev_priv, fb_bits); } -/* - * intel_connector_primary_encoder - get the primary encoder for a connector - * @connector: connector for which to return the encoder - * - * Returns the primary encoder for a connector. There is a 1:1 mapping from - * all connectors to their encoder, except for DP-MST connectors which have - * both a virtual and a primary encoder. These DP-MST primary encoders can be - * pointed to by as many DP-MST connectors as there are pipes. - */ -static struct intel_encoder * -intel_connector_primary_encoder(struct intel_connector *connector) -{ - struct intel_encoder *encoder; - - if (connector->mst_port) - return &dp_to_dig_port(connector->mst_port)->base; - - encoder = intel_attached_encoder(connector); - drm_WARN_ON(connector->base.dev, !encoder); - - return encoder; -} - static void intel_encoders_update_prepare(struct intel_atomic_state *state) { struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; - struct drm_connector_state *new_conn_state; - struct drm_connector *connector; int i; /* @@ -1365,57 +1340,6 @@ static void intel_encoders_update_prepare(struct intel_atomic_state *state) new_crtc_state->dpll_hw_state = old_crtc_state->dpll_hw_state; } } - - if (!state->modeset) - return; - - for_each_new_connector_in_state(&state->base, connector, new_conn_state, - i) { - struct intel_connector *intel_connector; - struct intel_encoder *encoder; - struct intel_crtc *crtc; - - if (!intel_connector_needs_modeset(state, connector)) - continue; - - intel_connector = to_intel_connector(connector); - encoder = intel_connector_primary_encoder(intel_connector); - if (!encoder->update_prepare) - continue; - - crtc = new_conn_state->crtc ? - to_intel_crtc(new_conn_state->crtc) : NULL; - encoder->update_prepare(state, encoder, crtc); - } -} - -static void intel_encoders_update_complete(struct intel_atomic_state *state) -{ - struct drm_connector_state *new_conn_state; - struct drm_connector *connector; - int i; - - if (!state->modeset) - return; - - for_each_new_connector_in_state(&state->base, connector, new_conn_state, - i) { - struct intel_connector *intel_connector; - struct intel_encoder *encoder; - struct intel_crtc *crtc; - - if (!intel_connector_needs_modeset(state, connector)) - continue; - - intel_connector = to_intel_connector(connector); - encoder = intel_connector_primary_encoder(intel_connector); - if (!encoder->update_complete) - continue; - - crtc = new_conn_state->crtc ? - to_intel_crtc(new_conn_state->crtc) : NULL; - encoder->update_complete(state, encoder, crtc); - } } static void intel_encoders_pre_pll_enable(struct intel_atomic_state *state, @@ -7445,8 +7369,6 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) /* Now enable the clocks, plane, pipe, and connectors that we set up. */ dev_priv->display.funcs.display->commit_modeset_enables(state); - intel_encoders_update_complete(state); - if (state->modeset) intel_set_cdclk_post_plane_update(state); -- cgit From d670c78ea7564f9baf915c8e1dc5898a9e6c360b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 3 Apr 2023 15:24:27 +0300 Subject: drm/i915: rename intel_pm.[ch] to intel_clock_gating.[ch] Observe that intel_pm.[ch] is now purely about clock gating, so rename them to intel_clock_gating.[ch]. Rename the functions to intel_clock_gating_*() to follow coding conventions. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20230403122428.3526263-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 810156099b02..010ee793e1ff 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -63,6 +63,7 @@ #include "intel_audio.h" #include "intel_bw.h" #include "intel_cdclk.h" +#include "intel_clock_gating.h" #include "intel_color.h" #include "intel_crt.h" #include "intel_crtc.h" @@ -105,7 +106,6 @@ #include "intel_pcode.h" #include "intel_pipe_crc.h" #include "intel_plane_initial.h" -#include "intel_pm.h" #include "intel_pps.h" #include "intel_psr.h" #include "intel_quirks.h" @@ -850,7 +850,7 @@ void intel_display_finish_reset(struct drm_i915_private *i915) */ intel_pps_unlock_regs_wa(i915); intel_modeset_init_hw(i915); - intel_init_clock_gating(i915); + intel_clock_gating_init(i915); intel_hpd_init(i915); ret = __intel_display_resume(i915, state, ctx); -- cgit From 631420b06597a33c72b6dcef78d1c2dea17f452d Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 13 Apr 2023 23:06:02 +0300 Subject: drm/i915: Make intel_get_crtc_new_encoder() less oopsy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The point of the WARN was to print something, not oops straight up. Currently that is precisely what happens if we can't find the connector for the crtc in the atomic state. Get the dev pointer from the atomic state instead of the potentially NULL encoder to avoid that. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230413200602.6037-2-ville.syrjala@linux.intel.com Fixes: 3a47ae201e07 ("drm/i915/display: Make WARN* drm specific where encoder ptr is available") Reviewed-by: Jani Nikula (cherry picked from commit 3b6692357f70498f617ea1b31a0378070a0acf1c) Signed-off-by: Joonas Lahtinen --- drivers/gpu/drm/i915/display/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 010ee793e1ff..3c29792137a5 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -959,7 +959,7 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state, num_encoders++; } - drm_WARN(encoder->base.dev, num_encoders != 1, + drm_WARN(state->base.dev, num_encoders != 1, "%d encoders for pipe %c\n", num_encoders, pipe_name(master_crtc->pipe)); -- cgit From 45dfbd992923f4df174db4e23b96fca7e30d73e2 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Wed, 10 May 2023 13:31:18 +0300 Subject: drm/i915: Fix PIPEDMC disabling for a bigjoiner configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For a bigjoiner configuration display->crtc_disable() will be called first for the slave CRTCs and then for the master CRTC. However slave CRTCs will be actually disabled only after the master CRTC is disabled (from the encoder disable hooks called with the master CRTC state). Hence the slave PIPEDMCs can be disabled only after the master CRTC is disabled, make this so. intel_encoders_post_pll_disable() must be called only for the master CRTC, as for the other two encoder disable hooks. While at it fix this up as well. This didn't cause a problem, since intel_encoders_post_pll_disable() will call the corresponding hook only for an encoder/connector connected to the given CRTC, however slave CRTCs will have no associated encoder/connector. Fixes: 3af2ff0840be ("drm/i915: Enable a PIPEDMC whenever its corresponding pipe is enabled") Cc: Rodrigo Vivi Cc: Ville Syrjälä Reviewed-by: Ville Syrjälä Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230510103131.1618266-2-imre.deak@intel.com (cherry picked from commit 7eeef32719f6af935a1554813e6bc206446339cd) Signed-off-by: Joonas Lahtinen --- drivers/gpu/drm/i915/display/intel_display.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/i915/display/intel_display.c') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 3c29792137a5..0aae9a1eb3d5 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1851,9 +1851,17 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, intel_disable_shared_dpll(old_crtc_state); - intel_encoders_post_pll_disable(state, crtc); + if (!intel_crtc_is_bigjoiner_slave(old_crtc_state)) { + struct intel_crtc *slave_crtc; + + intel_encoders_post_pll_disable(state, crtc); - intel_dmc_disable_pipe(i915, crtc->pipe); + intel_dmc_disable_pipe(i915, crtc->pipe); + + for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc, + intel_crtc_bigjoiner_slave_pipes(old_crtc_state)) + intel_dmc_disable_pipe(i915, slave_crtc->pipe); + } } static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state) -- cgit