aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2015-09-08 14:05:12 -0400
committerJani Nikula <jani.nikula@intel.com>2015-09-10 08:40:02 -0400
commit58590c14d80defc94e900308a9d8fa55284de6f2 (patch)
tree13352d0a3e7ca6a49a25da6db2c310501b7db094
parent982b0b2dd590c00f089fc6fe915bd0cb302a7f5c (diff)
drm/i915: Don't try to use DDR DVFS on CHV when disabled in the BIOS
If one disables DDR DVFS in the BIOS, Punit will apparently ignores all DDR DVFS request. Currently we assume that DDR DVFS is always operational, which leads to errors in dmesg when the DDR DVFS requests time out. Fix the problem by gently prodding Punit during driver load to find out whether it will respond to DDR DVFS requests. If the request times out, we assume that DDR DVFS has been permanenly disabled in the BIOS and no longer perster the Punit about it. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=91629 Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Clint Taylor <Clinton.A.Taylor@intel.com> Tested-by: Clint Taylor <Clinton.A.Taylor@intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c42
2 files changed, 31 insertions, 13 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 522da7b12a88..b06e03080771 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1928,6 +1928,8 @@ struct drm_i915_private {
1928 struct skl_wm_values skl_hw; 1928 struct skl_wm_values skl_hw;
1929 struct vlv_wm_values vlv; 1929 struct vlv_wm_values vlv;
1930 }; 1930 };
1931
1932 uint8_t max_level;
1931 } wm; 1933 } wm;
1932 1934
1933 struct i915_runtime_pm pm; 1935 struct i915_runtime_pm pm;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index fff0c22682ee..ddbb7ed0a193 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -955,8 +955,6 @@ enum vlv_wm_level {
955 VLV_WM_LEVEL_PM2, 955 VLV_WM_LEVEL_PM2,
956 VLV_WM_LEVEL_PM5, 956 VLV_WM_LEVEL_PM5,
957 VLV_WM_LEVEL_DDR_DVFS, 957 VLV_WM_LEVEL_DDR_DVFS,
958 CHV_WM_NUM_LEVELS,
959 VLV_WM_NUM_LEVELS = 1,
960}; 958};
961 959
962/* latency must be in 0.1us units. */ 960/* latency must be in 0.1us units. */
@@ -982,9 +980,13 @@ static void vlv_setup_wm_latency(struct drm_device *dev)
982 /* all latencies in usec */ 980 /* all latencies in usec */
983 dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM2] = 3; 981 dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM2] = 3;
984 982
983 dev_priv->wm.max_level = VLV_WM_LEVEL_PM2;
984
985 if (IS_CHERRYVIEW(dev_priv)) { 985 if (IS_CHERRYVIEW(dev_priv)) {
986 dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM5] = 12; 986 dev_priv->wm.pri_latency[VLV_WM_LEVEL_PM5] = 12;
987 dev_priv->wm.pri_latency[VLV_WM_LEVEL_DDR_DVFS] = 33; 987 dev_priv->wm.pri_latency[VLV_WM_LEVEL_DDR_DVFS] = 33;
988
989 dev_priv->wm.max_level = VLV_WM_LEVEL_DDR_DVFS;
988 } 990 }
989} 991}
990 992
@@ -1137,10 +1139,7 @@ static void vlv_compute_wm(struct intel_crtc *crtc)
1137 memset(wm_state, 0, sizeof(*wm_state)); 1139 memset(wm_state, 0, sizeof(*wm_state));
1138 1140
1139 wm_state->cxsr = crtc->pipe != PIPE_C && crtc->wm.cxsr_allowed; 1141 wm_state->cxsr = crtc->pipe != PIPE_C && crtc->wm.cxsr_allowed;
1140 if (IS_CHERRYVIEW(dev)) 1142 wm_state->num_levels = to_i915(dev)->wm.max_level + 1;
1141 wm_state->num_levels = CHV_WM_NUM_LEVELS;
1142 else
1143 wm_state->num_levels = VLV_WM_NUM_LEVELS;
1144 1143
1145 wm_state->num_active_planes = 0; 1144 wm_state->num_active_planes = 0;
1146 1145
@@ -1220,7 +1219,7 @@ static void vlv_compute_wm(struct intel_crtc *crtc)
1220 } 1219 }
1221 1220
1222 /* clear any (partially) filled invalid levels */ 1221 /* clear any (partially) filled invalid levels */
1223 for (level = wm_state->num_levels; level < CHV_WM_NUM_LEVELS; level++) { 1222 for (level = wm_state->num_levels; level < to_i915(dev)->wm.max_level + 1; level++) {
1224 memset(&wm_state->wm[level], 0, sizeof(wm_state->wm[level])); 1223 memset(&wm_state->wm[level], 0, sizeof(wm_state->wm[level]));
1225 memset(&wm_state->sr[level], 0, sizeof(wm_state->sr[level])); 1224 memset(&wm_state->sr[level], 0, sizeof(wm_state->sr[level]));
1226 } 1225 }
@@ -1324,10 +1323,7 @@ static void vlv_merge_wm(struct drm_device *dev,
1324 struct intel_crtc *crtc; 1323 struct intel_crtc *crtc;
1325 int num_active_crtcs = 0; 1324 int num_active_crtcs = 0;
1326 1325
1327 if (IS_CHERRYVIEW(dev)) 1326 wm->level = to_i915(dev)->wm.max_level;
1328 wm->level = VLV_WM_LEVEL_DDR_DVFS;
1329 else
1330 wm->level = VLV_WM_LEVEL_PM2;
1331 wm->cxsr = true; 1327 wm->cxsr = true;
1332 1328
1333 for_each_intel_crtc(dev, crtc) { 1329 for_each_intel_crtc(dev, crtc) {
@@ -4083,9 +4079,29 @@ void vlv_wm_get_hw_state(struct drm_device *dev)
4083 if (val & DSP_MAXFIFO_PM5_ENABLE) 4079 if (val & DSP_MAXFIFO_PM5_ENABLE)
4084 wm->level = VLV_WM_LEVEL_PM5; 4080 wm->level = VLV_WM_LEVEL_PM5;
4085 4081
4082 /*
4083 * If DDR DVFS is disabled in the BIOS, Punit
4084 * will never ack the request. So if that happens
4085 * assume we don't have to enable/disable DDR DVFS
4086 * dynamically. To test that just set the REQ_ACK
4087 * bit to poke the Punit, but don't change the
4088 * HIGH/LOW bits so that we don't actually change
4089 * the current state.
4090 */
4086 val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2); 4091 val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2);
4087 if ((val & FORCE_DDR_HIGH_FREQ) == 0) 4092 val |= FORCE_DDR_FREQ_REQ_ACK;
4088 wm->level = VLV_WM_LEVEL_DDR_DVFS; 4093 vlv_punit_write(dev_priv, PUNIT_REG_DDR_SETUP2, val);
4094
4095 if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2) &
4096 FORCE_DDR_FREQ_REQ_ACK) == 0, 3)) {
4097 DRM_DEBUG_KMS("Punit not acking DDR DVFS request, "
4098 "assuming DDR DVFS is disabled\n");
4099 dev_priv->wm.max_level = VLV_WM_LEVEL_PM5;
4100 } else {
4101 val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2);
4102 if ((val & FORCE_DDR_HIGH_FREQ) == 0)
4103 wm->level = VLV_WM_LEVEL_DDR_DVFS;
4104 }
4089 4105
4090 mutex_unlock(&dev_priv->rps.hw_lock); 4106 mutex_unlock(&dev_priv->rps.hw_lock);
4091 } 4107 }