diff options
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 6761717fe335..fe1992f2002b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2284,31 +2284,45 @@ static uint32_t ilk_compute_fbc_wm(struct hsw_pipe_wm_parameters *params, params->pri_bytes_per_pixel); } +static void ilk_compute_wm_level(struct drm_i915_private *dev_priv, + int level, + struct hsw_pipe_wm_parameters *p, + struct hsw_lp_wm_result *result) +{ + uint16_t pri_latency = dev_priv->wm.pri_latency[level]; + uint16_t spr_latency = dev_priv->wm.spr_latency[level]; + uint16_t cur_latency = dev_priv->wm.cur_latency[level]; + + /* WM1+ latency values stored in 0.5us units */ + if (level > 0) { + pri_latency *= 5; + spr_latency *= 5; + cur_latency *= 5; + } + + result->pri_val = ilk_compute_pri_wm(p, pri_latency, level); + result->spr_val = ilk_compute_spr_wm(p, spr_latency); + result->cur_val = ilk_compute_cur_wm(p, cur_latency); + result->fbc_val = ilk_compute_fbc_wm(p, result->pri_val); + result->enable = true; +} + static bool hsw_compute_lp_wm(struct drm_i915_private *dev_priv, int level, struct hsw_wm_maximums *max, struct hsw_pipe_wm_parameters *params, struct hsw_lp_wm_result *result) { enum pipe pipe; - uint32_t pri_val[3], spr_val[3], cur_val[3], fbc_val[3]; - - for (pipe = PIPE_A; pipe <= PIPE_C; pipe++) { - struct hsw_pipe_wm_parameters *p = ¶ms[pipe]; - /* WM1+ latency values stored in 0.5us units */ - uint16_t pri_latency = dev_priv->wm.pri_latency[level] * 5; - uint16_t spr_latency = dev_priv->wm.spr_latency[level] * 5; - uint16_t cur_latency = dev_priv->wm.cur_latency[level] * 5; + struct hsw_lp_wm_result res[3]; - pri_val[pipe] = ilk_compute_pri_wm(p, pri_latency, true); - spr_val[pipe] = ilk_compute_spr_wm(p, spr_latency); - cur_val[pipe] = ilk_compute_cur_wm(p, cur_latency); - fbc_val[pipe] = ilk_compute_fbc_wm(p, pri_val[pipe]); - } + for (pipe = PIPE_A; pipe <= PIPE_C; pipe++) + ilk_compute_wm_level(dev_priv, level, ¶ms[pipe], &res[pipe]); - result->pri_val = max3(pri_val[0], pri_val[1], pri_val[2]); - result->spr_val = max3(spr_val[0], spr_val[1], spr_val[2]); - result->cur_val = max3(cur_val[0], cur_val[1], cur_val[2]); - result->fbc_val = max3(fbc_val[0], fbc_val[1], fbc_val[2]); + result->pri_val = max3(res[0].pri_val, res[1].pri_val, res[2].pri_val); + result->spr_val = max3(res[0].spr_val, res[1].spr_val, res[2].spr_val); + result->cur_val = max3(res[0].cur_val, res[1].cur_val, res[2].cur_val); + result->fbc_val = max3(res[0].fbc_val, res[1].fbc_val, res[2].fbc_val); + result->enable = true; if (result->fbc_val > max->fbc) { result->fbc_enable = false; @@ -2317,6 +2331,9 @@ static bool hsw_compute_lp_wm(struct drm_i915_private *dev_priv, result->fbc_enable = true; } + if (!result->enable) + return false; + result->enable = result->pri_val <= max->pri && result->spr_val <= max->spr && result->cur_val <= max->cur; |