diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 42 |
1 files changed, 29 insertions, 13 deletions
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 | } |