[PATCH 02/13] drm/i915/cdclk: Fix voltage_level programming edge case

Gustavo Sousa gustavo.sousa at intel.com
Fri Mar 29 17:04:55 UTC 2024


Quoting Ville Syrjala (2024-03-27 14:45:33-03:00)
>From: Ville Syrjälä <ville.syrjala at linux.intel.com>
>
>Currently we only consider the relationship of the
>old and new CDCLK frequencies when determining whether
>to do the repgramming from intel_set_cdclk_pre_plane_update()
>or intel_set_cdclk_post_plane_update().
>
>It is technically possible to have a situation where the
>CDCLK frequency is decreasing, but the voltage_level is
>increasing due a DDI port. In this case we should bump
>the voltage level already in intel_set_cdclk_pre_plane_update()
>(so that the voltage_level will have been increased by the
>time the port gets enabled), while leaving the CDCLK frequency
>unchanged (as active planes/etc. may still depend on it).
>We can then reduce the CDCLK frequency to its final value
>from intel_set_cdclk_post_plane_update().
>
>In order to handle that correctly we shall construct a
>suitable amalgam of the old and new cdclk states in
>intel_set_cdclk_pre_plane_update().
>
>And we can simply call intel_set_cdclk() unconditionally
>in both places as it will not do anything if nothing actually
>changes vs. the current hw state.
>
>v2: Handle cdclk_state->disable_pipes
>
>Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
>---
> drivers/gpu/drm/i915/display/intel_cdclk.c | 27 +++++++++++++---------
> 1 file changed, 16 insertions(+), 11 deletions(-)
>
>diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
>index 619529dba095..504c5cbbcfff 100644
>--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
>+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
>@@ -2600,6 +2600,7 @@ intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state)
>                 intel_atomic_get_old_cdclk_state(state);
>         const struct intel_cdclk_state *new_cdclk_state =
>                 intel_atomic_get_new_cdclk_state(state);
>+        struct intel_cdclk_config cdclk_config;
> 
>         if (!intel_cdclk_changed(&old_cdclk_state->actual,
>                                  &new_cdclk_state->actual))
>@@ -2608,13 +2609,21 @@ intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state)
>         if (IS_DG2(i915))
>                 intel_cdclk_pcode_pre_notify(state);
> 
>-        if (new_cdclk_state->disable_pipes ||
>-            old_cdclk_state->actual.cdclk <= new_cdclk_state->actual.cdclk) {
>-                drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);
>+        if (new_cdclk_state->disable_pipes) {
>+                cdclk_config = new_cdclk_state->actual;
>+        } else {
>+                if (new_cdclk_state->actual.cdclk >= old_cdclk_state->actual.cdclk)
>+                        cdclk_config = new_cdclk_state->actual;
>+                else
>+                        cdclk_config = old_cdclk_state->actual;
> 
>-                intel_set_cdclk(i915, &new_cdclk_state->actual,
>-                                new_cdclk_state->pipe);
>+                cdclk_config.voltage_level = max(new_cdclk_state->actual.voltage_level,
>+                                                 old_cdclk_state->actual.voltage_level);
>         }
>+
>+        drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);
>+
>+        intel_set_cdclk(i915, &cdclk_config, new_cdclk_state->pipe);

Not sure if there could be unwanted side effects with passing
new_cdclk_state->pipe when using old_cdclk_state->actual. Because
voltage_level might have changed, parts of the cdclk change sequence end
up being exercised even when cdclk_config == old_cdclk_state->actual.

Well, even if those side effects might be harmless, I wonder if it would
be better if we used INVALID_PIPE when using old_cdclk_state->actual.

--
Gustavo Sousa

> }
> 
> /**
>@@ -2640,13 +2649,9 @@ intel_set_cdclk_post_plane_update(struct intel_atomic_state *state)
>         if (IS_DG2(i915))
>                 intel_cdclk_pcode_post_notify(state);
> 
>-        if (!new_cdclk_state->disable_pipes &&
>-            old_cdclk_state->actual.cdclk > new_cdclk_state->actual.cdclk) {
>-                drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);
>+        drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);
> 
>-                intel_set_cdclk(i915, &new_cdclk_state->actual,
>-                                new_cdclk_state->pipe);
>-        }
>+        intel_set_cdclk(i915, &new_cdclk_state->actual, new_cdclk_state->pipe);
> }
> 
> static int intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state)
>-- 
>2.43.2
>


More information about the Intel-gfx mailing list