aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2017-11-15 11:31:57 -0500
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2017-11-17 09:24:07 -0500
commit248c2435cbd75ad098130dda819b2973591d6f6d (patch)
tree5c2aaedcd13633f5f85784c1538816b1ab2b6e0b /drivers
parent5b9489cb8ee23b41ab5a4cca6652511fa252bad8 (diff)
drm/i915: Calculate g4x intermediate watermarks correctly
The watermarks it should calculate against are the old optimal watermarks. The currently active crtc watermarks are pure fiction, and are invalid in case of a nonblocking modeset, page flip enabling/disabling planes or any other reason. When the crtc is disabled or during a modeset the intermediate watermarks don't need to be programmed separately, and could be directly assigned to the optimal watermarks. CXSR must always be disabled in the intermediate case for modesets, else we get a WARN for vblank wait timeout. Also rename crtc_state to new_crtc_state, to distinguish it from the old state. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20171115163157.14372-2-maarten.lankhorst@linux.intel.com Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index f904bf73dbd6..3c55e4026331 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1406,17 +1406,29 @@ static int g4x_compute_pipe_wm(struct intel_crtc_state *crtc_state)
1406 1406
1407static int g4x_compute_intermediate_wm(struct drm_device *dev, 1407static int g4x_compute_intermediate_wm(struct drm_device *dev,
1408 struct intel_crtc *crtc, 1408 struct intel_crtc *crtc,
1409 struct intel_crtc_state *crtc_state) 1409 struct intel_crtc_state *new_crtc_state)
1410{ 1410{
1411 struct g4x_wm_state *intermediate = &crtc_state->wm.g4x.intermediate; 1411 struct g4x_wm_state *intermediate = &new_crtc_state->wm.g4x.intermediate;
1412 const struct g4x_wm_state *optimal = &crtc_state->wm.g4x.optimal; 1412 const struct g4x_wm_state *optimal = &new_crtc_state->wm.g4x.optimal;
1413 const struct g4x_wm_state *active = &crtc->wm.active.g4x; 1413 struct intel_atomic_state *intel_state =
1414 to_intel_atomic_state(new_crtc_state->base.state);
1415 const struct intel_crtc_state *old_crtc_state =
1416 intel_atomic_get_old_crtc_state(intel_state, crtc);
1417 const struct g4x_wm_state *active = &old_crtc_state->wm.g4x.optimal;
1414 enum plane_id plane_id; 1418 enum plane_id plane_id;
1415 1419
1420 if (!new_crtc_state->base.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->base)) {
1421 *intermediate = *optimal;
1422
1423 intermediate->cxsr = false;
1424 intermediate->hpll_en = false;
1425 goto out;
1426 }
1427
1416 intermediate->cxsr = optimal->cxsr && active->cxsr && 1428 intermediate->cxsr = optimal->cxsr && active->cxsr &&
1417 !crtc_state->disable_cxsr; 1429 !new_crtc_state->disable_cxsr;
1418 intermediate->hpll_en = optimal->hpll_en && active->hpll_en && 1430 intermediate->hpll_en = optimal->hpll_en && active->hpll_en &&
1419 !crtc_state->disable_cxsr; 1431 !new_crtc_state->disable_cxsr;
1420 intermediate->fbc_en = optimal->fbc_en && active->fbc_en; 1432 intermediate->fbc_en = optimal->fbc_en && active->fbc_en;
1421 1433
1422 for_each_plane_id_on_crtc(crtc, plane_id) { 1434 for_each_plane_id_on_crtc(crtc, plane_id) {
@@ -1458,12 +1470,13 @@ static int g4x_compute_intermediate_wm(struct drm_device *dev,
1458 WARN_ON(intermediate->hpll.fbc > g4x_fbc_fifo_size(2) && 1470 WARN_ON(intermediate->hpll.fbc > g4x_fbc_fifo_size(2) &&
1459 intermediate->fbc_en && intermediate->hpll_en); 1471 intermediate->fbc_en && intermediate->hpll_en);
1460 1472
1473out:
1461 /* 1474 /*
1462 * If our intermediate WM are identical to the final WM, then we can 1475 * If our intermediate WM are identical to the final WM, then we can
1463 * omit the post-vblank programming; only update if it's different. 1476 * omit the post-vblank programming; only update if it's different.
1464 */ 1477 */
1465 if (memcmp(intermediate, optimal, sizeof(*intermediate)) != 0) 1478 if (memcmp(intermediate, optimal, sizeof(*intermediate)) != 0)
1466 crtc_state->wm.need_postvbl_update = true; 1479 new_crtc_state->wm.need_postvbl_update = true;
1467 1480
1468 return 0; 1481 return 0;
1469} 1482}