aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2017-11-22 13:39:01 -0500
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2017-11-30 10:49:42 -0500
commit24f2845056892b297fa95edbddceefd38acc0e62 (patch)
treee91e777c82c74ac667804da6984d24c00a19bf2f
parent5643205c6340b565a3be0fe0e7305dc4aa551c74 (diff)
drm/i915: Make ips_enabled a property depending on whether IPS is enabled, v3.
ips_enabled was used as a variable of whether IPS can be enabled or not, but should be used to test whether IPS is actually enabled. Changes since v1: - Call needs_modeset on new crtc state. (Ville) - IPS can be enabled with sprite plane enabled too. (Ville) - Fix CDCLK vs IPS workaround. (Ville) Changes since v2: - Only re-enable fastset when inheriting mode. (Ville) - Put the conditions for enabling and disabling IPS in a helper. Changes since v3: - Keep the max_cdclk workaround working. (Ville) - Also check logical cdclk out of paranoia. - Remove planes check from IPS disable function for initial disable. - Remove assert_plane_enabled/disabled checks and use crtc_state->active_planes for hsw_enable_ips only, always allow calling hsw_disable_ips to disable it initially in hw. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20171122183901.47720-1-maarten.lankhorst@linux.intel.com [mlankhorst: pipe_config -> crtc_state (Ville)] Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
-rw-r--r--drivers/gpu/drm/i915/intel_cdclk.c2
-rw-r--r--drivers/gpu/drm/i915/intel_display.c168
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_pipe_crc.c2
4 files changed, 109 insertions, 64 deletions
diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c
index e8884c2ade98..9c5ceb98d48f 100644
--- a/drivers/gpu/drm/i915/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/intel_cdclk.c
@@ -1896,7 +1896,7 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
1896 min_cdclk = intel_pixel_rate_to_cdclk(dev_priv, crtc_state->pixel_rate); 1896 min_cdclk = intel_pixel_rate_to_cdclk(dev_priv, crtc_state->pixel_rate);
1897 1897
1898 /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */ 1898 /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
1899 if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled) 1899 if (IS_BROADWELL(dev_priv) && hsw_crtc_state_ips_capable(crtc_state))
1900 min_cdclk = DIV_ROUND_UP(min_cdclk * 100, 95); 1900 min_cdclk = DIV_ROUND_UP(min_cdclk * 100, 95);
1901 1901
1902 /* BSpec says "Do not use DisplayPort with CDCLK less than 432 MHz, 1902 /* BSpec says "Do not use DisplayPort with CDCLK less than 432 MHz,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 76c75d34e799..68f101c0e909 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -489,7 +489,7 @@ static const struct intel_limit intel_limits_bxt = {
489}; 489};
490 490
491static bool 491static bool
492needs_modeset(struct drm_crtc_state *state) 492needs_modeset(const struct drm_crtc_state *state)
493{ 493{
494 return drm_atomic_crtc_needs_modeset(state); 494 return drm_atomic_crtc_needs_modeset(state);
495} 495}
@@ -4833,7 +4833,7 @@ void hsw_enable_ips(const struct intel_crtc_state *crtc_state)
4833 struct drm_device *dev = crtc->base.dev; 4833 struct drm_device *dev = crtc->base.dev;
4834 struct drm_i915_private *dev_priv = to_i915(dev); 4834 struct drm_i915_private *dev_priv = to_i915(dev);
4835 4835
4836 if (!crtc->config->ips_enabled) 4836 if (!crtc_state->ips_enabled)
4837 return; 4837 return;
4838 4838
4839 /* 4839 /*
@@ -4841,8 +4841,7 @@ void hsw_enable_ips(const struct intel_crtc_state *crtc_state)
4841 * This function is called from post_plane_update, which is run after 4841 * This function is called from post_plane_update, which is run after
4842 * a vblank wait. 4842 * a vblank wait.
4843 */ 4843 */
4844 4844 WARN_ON(!(crtc_state->active_planes & ~BIT(PLANE_CURSOR)));
4845 assert_plane_enabled(to_intel_plane(crtc->base.primary));
4846 4845
4847 if (IS_BROADWELL(dev_priv)) { 4846 if (IS_BROADWELL(dev_priv)) {
4848 mutex_lock(&dev_priv->pcu_lock); 4847 mutex_lock(&dev_priv->pcu_lock);
@@ -4877,8 +4876,6 @@ void hsw_disable_ips(const struct intel_crtc_state *crtc_state)
4877 if (!crtc_state->ips_enabled) 4876 if (!crtc_state->ips_enabled)
4878 return; 4877 return;
4879 4878
4880 assert_plane_enabled(to_intel_plane(crtc->base.primary));
4881
4882 if (IS_BROADWELL(dev_priv)) { 4879 if (IS_BROADWELL(dev_priv)) {
4883 mutex_lock(&dev_priv->pcu_lock); 4880 mutex_lock(&dev_priv->pcu_lock);
4884 WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0)); 4881 WARN_ON(sandybridge_pcode_write(dev_priv, DISPLAY_IPS_CONTROL, 0));
@@ -4932,14 +4929,6 @@ intel_post_enable_primary(struct drm_crtc *crtc,
4932 int pipe = intel_crtc->pipe; 4929 int pipe = intel_crtc->pipe;
4933 4930
4934 /* 4931 /*
4935 * FIXME IPS should be fine as long as one plane is
4936 * enabled, but in practice it seems to have problems
4937 * when going from primary only to sprite only and vice
4938 * versa.
4939 */
4940 hsw_enable_ips(new_crtc_state);
4941
4942 /*
4943 * Gen2 reports pipe underruns whenever all planes are disabled. 4932 * Gen2 reports pipe underruns whenever all planes are disabled.
4944 * So don't enable underrun reporting before at least some planes 4933 * So don't enable underrun reporting before at least some planes
4945 * are enabled. 4934 * are enabled.
@@ -4954,10 +4943,9 @@ intel_post_enable_primary(struct drm_crtc *crtc,
4954 intel_check_pch_fifo_underruns(dev_priv); 4943 intel_check_pch_fifo_underruns(dev_priv);
4955} 4944}
4956 4945
4957/* FIXME move all this to pre_plane_update() with proper state tracking */ 4946/* FIXME get rid of this and use pre_plane_update */
4958static void 4947static void
4959intel_pre_disable_primary(struct drm_crtc *crtc, 4948intel_pre_disable_primary_noatomic(struct drm_crtc *crtc)
4960 const struct intel_crtc_state *old_crtc_state)
4961{ 4949{
4962 struct drm_device *dev = crtc->dev; 4950 struct drm_device *dev = crtc->dev;
4963 struct drm_i915_private *dev_priv = to_i915(dev); 4951 struct drm_i915_private *dev_priv = to_i915(dev);
@@ -4966,32 +4954,12 @@ intel_pre_disable_primary(struct drm_crtc *crtc,
4966 4954
4967 /* 4955 /*
4968 * Gen2 reports pipe underruns whenever all planes are disabled. 4956 * Gen2 reports pipe underruns whenever all planes are disabled.
4969 * So diasble underrun reporting before all the planes get disabled. 4957 * So disable underrun reporting before all the planes get disabled.
4970 * FIXME: Need to fix the logic to work when we turn off all planes
4971 * but leave the pipe running.
4972 */ 4958 */
4973 if (IS_GEN2(dev_priv)) 4959 if (IS_GEN2(dev_priv))
4974 intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false); 4960 intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
4975 4961
4976 /* 4962 hsw_disable_ips(to_intel_crtc_state(crtc->state));
4977 * FIXME IPS should be fine as long as one plane is
4978 * enabled, but in practice it seems to have problems
4979 * when going from primary only to sprite only and vice
4980 * versa.
4981 */
4982 hsw_disable_ips(old_crtc_state);
4983}
4984
4985/* FIXME get rid of this and use pre_plane_update */
4986static void
4987intel_pre_disable_primary_noatomic(struct drm_crtc *crtc)
4988{
4989 struct drm_device *dev = crtc->dev;
4990 struct drm_i915_private *dev_priv = to_i915(dev);
4991 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
4992 int pipe = intel_crtc->pipe;
4993
4994 intel_pre_disable_primary(crtc, to_intel_crtc_state(crtc->state));
4995 4963
4996 /* 4964 /*
4997 * Vblank time updates from the shadow to live plane control register 4965 * Vblank time updates from the shadow to live plane control register
@@ -5007,6 +4975,38 @@ intel_pre_disable_primary_noatomic(struct drm_crtc *crtc)
5007 intel_wait_for_vblank(dev_priv, pipe); 4975 intel_wait_for_vblank(dev_priv, pipe);
5008} 4976}
5009 4977
4978static bool hsw_pre_update_disable_ips(const struct intel_crtc_state *old_crtc_state,
4979 const struct intel_crtc_state *new_crtc_state)
4980{
4981 if (!old_crtc_state->ips_enabled)
4982 return false;
4983
4984 if (needs_modeset(&new_crtc_state->base))
4985 return true;
4986
4987 return !new_crtc_state->ips_enabled;
4988}
4989
4990static bool hsw_post_update_enable_ips(const struct intel_crtc_state *old_crtc_state,
4991 const struct intel_crtc_state *new_crtc_state)
4992{
4993 if (!new_crtc_state->ips_enabled)
4994 return false;
4995
4996 if (needs_modeset(&new_crtc_state->base))
4997 return true;
4998
4999 /*
5000 * We can't read out IPS on broadwell, assume the worst and
5001 * forcibly enable IPS on the first fastset.
5002 */
5003 if (new_crtc_state->update_pipe &&
5004 old_crtc_state->base.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
5005 return true;
5006
5007 return !old_crtc_state->ips_enabled;
5008}
5009
5010static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state) 5010static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
5011{ 5011{
5012 struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc); 5012 struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
@@ -5023,6 +5023,9 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
5023 if (pipe_config->update_wm_post && pipe_config->base.active) 5023 if (pipe_config->update_wm_post && pipe_config->base.active)
5024 intel_update_watermarks(crtc); 5024 intel_update_watermarks(crtc);
5025 5025
5026 if (hsw_post_update_enable_ips(old_crtc_state, pipe_config))
5027 hsw_enable_ips(pipe_config);
5028
5026 if (old_pri_state) { 5029 if (old_pri_state) {
5027 struct intel_plane_state *primary_state = 5030 struct intel_plane_state *primary_state =
5028 intel_atomic_get_new_plane_state(to_intel_atomic_state(old_state), 5031 intel_atomic_get_new_plane_state(to_intel_atomic_state(old_state),
@@ -5053,6 +5056,9 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
5053 struct intel_atomic_state *old_intel_state = 5056 struct intel_atomic_state *old_intel_state =
5054 to_intel_atomic_state(old_state); 5057 to_intel_atomic_state(old_state);
5055 5058
5059 if (hsw_pre_update_disable_ips(old_crtc_state, pipe_config))
5060 hsw_disable_ips(old_crtc_state);
5061
5056 if (old_pri_state) { 5062 if (old_pri_state) {
5057 struct intel_plane_state *primary_state = 5063 struct intel_plane_state *primary_state =
5058 intel_atomic_get_new_plane_state(old_intel_state, 5064 intel_atomic_get_new_plane_state(old_intel_state,
@@ -5061,10 +5067,13 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
5061 to_intel_plane_state(old_pri_state); 5067 to_intel_plane_state(old_pri_state);
5062 5068
5063 intel_fbc_pre_update(crtc, pipe_config, primary_state); 5069 intel_fbc_pre_update(crtc, pipe_config, primary_state);
5064 5070 /*
5065 if (old_primary_state->base.visible && 5071 * Gen2 reports pipe underruns whenever all planes are disabled.
5072 * So disable underrun reporting before all the planes get disabled.
5073 */
5074 if (IS_GEN2(dev_priv) && old_primary_state->base.visible &&
5066 (modeset || !primary_state->base.visible)) 5075 (modeset || !primary_state->base.visible))
5067 intel_pre_disable_primary(&crtc->base, old_crtc_state); 5076 intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, false);
5068 } 5077 }
5069 5078
5070 /* 5079 /*
@@ -6195,18 +6204,20 @@ retry:
6195 return ret; 6204 return ret;
6196} 6205}
6197 6206
6198static bool pipe_config_supports_ips(struct drm_i915_private *dev_priv, 6207bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
6199 struct intel_crtc_state *pipe_config)
6200{ 6208{
6201 if (pipe_config->ips_force_disable) 6209 struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
6210 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
6211
6212 /* IPS only exists on ULT machines and is tied to pipe A. */
6213 if (!hsw_crtc_supports_ips(crtc))
6202 return false; 6214 return false;
6203 6215
6204 if (pipe_config->pipe_bpp > 24) 6216 if (!i915_modparams.enable_ips)
6205 return false; 6217 return false;
6206 6218
6207 /* HSW can handle pixel rate up to cdclk? */ 6219 if (crtc_state->pipe_bpp > 24)
6208 if (IS_HASWELL(dev_priv)) 6220 return false;
6209 return true;
6210 6221
6211 /* 6222 /*
6212 * We compare against max which means we must take 6223 * We compare against max which means we must take
@@ -6215,19 +6226,41 @@ static bool pipe_config_supports_ips(struct drm_i915_private *dev_priv,
6215 * 6226 *
6216 * Should measure whether using a lower cdclk w/o IPS 6227 * Should measure whether using a lower cdclk w/o IPS
6217 */ 6228 */
6218 return pipe_config->pixel_rate <= 6229 if (IS_BROADWELL(dev_priv) &&
6219 dev_priv->max_cdclk_freq * 95 / 100; 6230 crtc_state->pixel_rate > dev_priv->max_cdclk_freq * 95 / 100)
6231 return false;
6232
6233 return true;
6220} 6234}
6221 6235
6222static void hsw_compute_ips_config(struct intel_crtc *crtc, 6236static bool hsw_compute_ips_config(struct intel_crtc_state *crtc_state)
6223 struct intel_crtc_state *pipe_config)
6224{ 6237{
6225 struct drm_device *dev = crtc->base.dev; 6238 struct drm_i915_private *dev_priv =
6226 struct drm_i915_private *dev_priv = to_i915(dev); 6239 to_i915(crtc_state->base.crtc->dev);
6240 struct intel_atomic_state *intel_state =
6241 to_intel_atomic_state(crtc_state->base.state);
6227 6242
6228 pipe_config->ips_enabled = i915_modparams.enable_ips && 6243 if (!hsw_crtc_state_ips_capable(crtc_state))
6229 hsw_crtc_supports_ips(crtc) && 6244 return false;
6230 pipe_config_supports_ips(dev_priv, pipe_config); 6245
6246 if (crtc_state->ips_force_disable)
6247 return false;
6248
6249 /*
6250 * FIXME IPS should be fine as long as one plane is
6251 * enabled, but in practice it seems to have problems
6252 * when going from primary only to sprite only and vice
6253 * versa.
6254 */
6255 if (!(crtc_state->active_planes & BIT(PLANE_PRIMARY)))
6256 return false;
6257
6258 /* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
6259 if (IS_BROADWELL(dev_priv) &&
6260 crtc_state->pixel_rate > intel_state->cdclk.logical.cdclk * 95 / 100)
6261 return false;
6262
6263 return true;
6231} 6264}
6232 6265
6233static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc) 6266static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
@@ -6345,9 +6378,6 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
6345 6378
6346 intel_crtc_compute_pixel_rate(pipe_config); 6379 intel_crtc_compute_pixel_rate(pipe_config);
6347 6380
6348 if (HAS_IPS(dev_priv))
6349 hsw_compute_ips_config(crtc, pipe_config);
6350
6351 if (pipe_config->has_pch_encoder) 6381 if (pipe_config->has_pch_encoder)
6352 return ironlake_fdi_compute_config(crtc, pipe_config); 6382 return ironlake_fdi_compute_config(crtc, pipe_config);
6353 6383
@@ -9183,6 +9213,19 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
9183 ironlake_get_pfit_config(crtc, pipe_config); 9213 ironlake_get_pfit_config(crtc, pipe_config);
9184 } 9214 }
9185 9215
9216 if (hsw_crtc_supports_ips(crtc)) {
9217 if (IS_HASWELL(dev_priv))
9218 pipe_config->ips_enabled = I915_READ(IPS_CTL) & IPS_ENABLE;
9219 else {
9220 /*
9221 * We cannot readout IPS state on broadwell, set to
9222 * true so we can set it to a defined state on first
9223 * commit.
9224 */
9225 pipe_config->ips_enabled = true;
9226 }
9227 }
9228
9186 if (pipe_config->cpu_transcoder != TRANSCODER_EDP && 9229 if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
9187 !transcoder_is_dsi(pipe_config->cpu_transcoder)) { 9230 !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
9188 pipe_config->pixel_multiplier = 9231 pipe_config->pixel_multiplier =
@@ -10435,6 +10478,9 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
10435 pipe_config); 10478 pipe_config);
10436 } 10479 }
10437 10480
10481 if (HAS_IPS(dev_priv))
10482 pipe_config->ips_enabled = hsw_compute_ips_config(pipe_config);
10483
10438 return ret; 10484 return ret;
10439} 10485}
10440 10486
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c679df99d530..64426d3e078e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1488,6 +1488,7 @@ bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, int target_clock,
1488int chv_calc_dpll_params(int refclk, struct dpll *pll_clock); 1488int chv_calc_dpll_params(int refclk, struct dpll *pll_clock);
1489 1489
1490bool intel_crtc_active(struct intel_crtc *crtc); 1490bool intel_crtc_active(struct intel_crtc *crtc);
1491bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state);
1491void hsw_enable_ips(const struct intel_crtc_state *crtc_state); 1492void hsw_enable_ips(const struct intel_crtc_state *crtc_state);
1492void hsw_disable_ips(const struct intel_crtc_state *crtc_state); 1493void hsw_disable_ips(const struct intel_crtc_state *crtc_state);
1493enum intel_display_power_domain intel_port_to_power_domain(enum port port); 1494enum intel_display_power_domain intel_port_to_power_domain(enum port port);
diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c b/drivers/gpu/drm/i915/intel_pipe_crc.c
index 61641d479b93..1f5cd572a7ff 100644
--- a/drivers/gpu/drm/i915/intel_pipe_crc.c
+++ b/drivers/gpu/drm/i915/intel_pipe_crc.c
@@ -541,8 +541,6 @@ retry:
541 * completely disable it. 541 * completely disable it.
542 */ 542 */
543 pipe_config->ips_force_disable = enable; 543 pipe_config->ips_force_disable = enable;
544 if (pipe_config->ips_enabled == enable)
545 pipe_config->base.connectors_changed = true;
546 } 544 }
547 545
548 if (IS_HASWELL(dev_priv)) { 546 if (IS_HASWELL(dev_priv)) {