diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/hsw_ips.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/hsw_ips.c | 63 |
1 files changed, 29 insertions, 34 deletions
diff --git a/drivers/gpu/drm/i915/display/hsw_ips.c b/drivers/gpu/drm/i915/display/hsw_ips.c index 927fe56aec77..008d339d5c21 100644 --- a/drivers/gpu/drm/i915/display/hsw_ips.c +++ b/drivers/gpu/drm/i915/display/hsw_ips.c @@ -56,7 +56,7 @@ static void hsw_ips_enable(const struct intel_crtc_state *crtc_state) * the HW state readout code will complain that the expected * IPS_CTL value is not the one we read. */ - if (intel_de_wait_for_set(display, IPS_CTL, IPS_ENABLE, 50)) + if (intel_de_wait_for_set_ms(display, IPS_CTL, IPS_ENABLE, 50)) drm_err(display->drm, "Timed out waiting for IPS enable\n"); } @@ -78,7 +78,7 @@ bool hsw_ips_disable(const struct intel_crtc_state *crtc_state) * 42ms timeout value leads to occasional timeouts so use 100ms * instead. */ - if (intel_de_wait_for_clear(display, IPS_CTL, IPS_ENABLE, 100)) + if (intel_de_wait_for_clear_ms(display, IPS_CTL, IPS_ENABLE, 100)) drm_err(display->drm, "Timed out waiting for IPS disable\n"); } else { @@ -191,45 +191,46 @@ bool hsw_crtc_supports_ips(struct intel_crtc *crtc) static bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state) { - struct intel_display *display = to_intel_display(crtc_state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - /* IPS only exists on ULT machines and is tied to pipe A. */ if (!hsw_crtc_supports_ips(crtc)) return false; - if (!display->params.enable_ips) - return false; - if (crtc_state->pipe_bpp > 24) return false; - /* - * We compare against max which means we must take - * the increased cdclk requirement into account when - * calculating the new cdclk. - * - * Should measure whether using a lower cdclk w/o IPS - */ - if (display->platform.broadwell && - crtc_state->pixel_rate > display->cdclk.max_cdclk_freq * 95 / 100) - return false; - return true; } +static int _hsw_ips_min_cdclk(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + + if (display->platform.broadwell) + return DIV_ROUND_UP(crtc_state->pixel_rate * 100, 95); + + /* no IPS specific limits to worry about */ + return 0; +} + int hsw_ips_min_cdclk(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); + int min_cdclk; - if (!display->platform.broadwell) + if (!hsw_crtc_state_ips_capable(crtc_state)) return 0; - if (!hsw_crtc_state_ips_capable(crtc_state)) + min_cdclk = _hsw_ips_min_cdclk(crtc_state); + + /* + * Do not ask for more than the max CDCLK frequency, + * if that is not enough IPS will simply not be used. + */ + if (min_cdclk > display->cdclk.max_cdclk_freq) return 0; - /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */ - return DIV_ROUND_UP(crtc_state->pixel_rate * 100, 95); + return min_cdclk; } int hsw_ips_compute_config(struct intel_atomic_state *state, @@ -244,6 +245,12 @@ int hsw_ips_compute_config(struct intel_atomic_state *state, if (!hsw_crtc_state_ips_capable(crtc_state)) return 0; + if (_hsw_ips_min_cdclk(crtc_state) > display->cdclk.max_cdclk_freq) + return 0; + + if (!display->params.enable_ips) + return 0; + /* * When IPS gets enabled, the pipe CRC changes. Since IPS gets * enabled and disabled dynamically based on package C states, @@ -257,18 +264,6 @@ int hsw_ips_compute_config(struct intel_atomic_state *state, if (!(crtc_state->active_planes & ~BIT(PLANE_CURSOR))) return 0; - if (display->platform.broadwell) { - const struct intel_cdclk_state *cdclk_state; - - cdclk_state = intel_atomic_get_cdclk_state(state); - if (IS_ERR(cdclk_state)) - return PTR_ERR(cdclk_state); - - /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */ - if (crtc_state->pixel_rate > intel_cdclk_logical(cdclk_state) * 95 / 100) - return 0; - } - crtc_state->ips_enabled = true; return 0; |
