diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 60 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 49 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 232 |
4 files changed, 151 insertions, 202 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b39b5cc0c096..4feec193ff33 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -627,8 +627,6 @@ struct drm_i915_display_funcs { | |||
627 | int target, int refclk, | 627 | int target, int refclk, |
628 | struct dpll *match_clock, | 628 | struct dpll *match_clock, |
629 | struct dpll *best_clock); | 629 | struct dpll *best_clock); |
630 | int (*compute_pipe_wm)(struct intel_crtc *crtc, | ||
631 | struct drm_atomic_state *state); | ||
632 | void (*update_wm)(struct drm_crtc *crtc); | 630 | void (*update_wm)(struct drm_crtc *crtc); |
633 | int (*modeset_calc_cdclk)(struct drm_atomic_state *state); | 631 | int (*modeset_calc_cdclk)(struct drm_atomic_state *state); |
634 | void (*modeset_commit_cdclk)(struct drm_atomic_state *state); | 632 | void (*modeset_commit_cdclk)(struct drm_atomic_state *state); |
@@ -1692,13 +1690,6 @@ struct i915_execbuffer_params { | |||
1692 | struct drm_i915_gem_request *request; | 1690 | struct drm_i915_gem_request *request; |
1693 | }; | 1691 | }; |
1694 | 1692 | ||
1695 | /* used in computing the new watermarks state */ | ||
1696 | struct intel_wm_config { | ||
1697 | unsigned int num_pipes_active; | ||
1698 | bool sprites_enabled; | ||
1699 | bool sprites_scaled; | ||
1700 | }; | ||
1701 | |||
1702 | struct drm_i915_private { | 1693 | struct drm_i915_private { |
1703 | struct drm_device *dev; | 1694 | struct drm_device *dev; |
1704 | struct kmem_cache *objects; | 1695 | struct kmem_cache *objects; |
@@ -1924,9 +1915,6 @@ struct drm_i915_private { | |||
1924 | */ | 1915 | */ |
1925 | uint16_t skl_latency[8]; | 1916 | uint16_t skl_latency[8]; |
1926 | 1917 | ||
1927 | /* Committed wm config */ | ||
1928 | struct intel_wm_config config; | ||
1929 | |||
1930 | /* | 1918 | /* |
1931 | * The skl_wm_values structure is a bit too big for stack | 1919 | * The skl_wm_values structure is a bit too big for stack |
1932 | * allocation, so we keep the staging struct where we store | 1920 | * allocation, so we keep the staging struct where we store |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6b3b65e3b36b..cddb0c692334 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -11836,12 +11836,6 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, | |||
11836 | } | 11836 | } |
11837 | 11837 | ||
11838 | ret = 0; | 11838 | ret = 0; |
11839 | if (dev_priv->display.compute_pipe_wm) { | ||
11840 | ret = dev_priv->display.compute_pipe_wm(intel_crtc, state); | ||
11841 | if (ret) | ||
11842 | return ret; | ||
11843 | } | ||
11844 | |||
11845 | if (INTEL_INFO(dev)->gen >= 9) { | 11839 | if (INTEL_INFO(dev)->gen >= 9) { |
11846 | if (mode_changed) | 11840 | if (mode_changed) |
11847 | ret = skl_update_scaler_crtc(pipe_config); | 11841 | ret = skl_update_scaler_crtc(pipe_config); |
@@ -13047,45 +13041,6 @@ static int intel_modeset_checks(struct drm_atomic_state *state) | |||
13047 | return 0; | 13041 | return 0; |
13048 | } | 13042 | } |
13049 | 13043 | ||
13050 | /* | ||
13051 | * Handle calculation of various watermark data at the end of the atomic check | ||
13052 | * phase. The code here should be run after the per-crtc and per-plane 'check' | ||
13053 | * handlers to ensure that all derived state has been updated. | ||
13054 | */ | ||
13055 | static void calc_watermark_data(struct drm_atomic_state *state) | ||
13056 | { | ||
13057 | struct drm_device *dev = state->dev; | ||
13058 | struct intel_atomic_state *intel_state = to_intel_atomic_state(state); | ||
13059 | struct drm_crtc *crtc; | ||
13060 | struct drm_crtc_state *cstate; | ||
13061 | struct drm_plane *plane; | ||
13062 | struct drm_plane_state *pstate; | ||
13063 | |||
13064 | /* | ||
13065 | * Calculate watermark configuration details now that derived | ||
13066 | * plane/crtc state is all properly updated. | ||
13067 | */ | ||
13068 | drm_for_each_crtc(crtc, dev) { | ||
13069 | cstate = drm_atomic_get_existing_crtc_state(state, crtc) ?: | ||
13070 | crtc->state; | ||
13071 | |||
13072 | if (cstate->active) | ||
13073 | intel_state->wm_config.num_pipes_active++; | ||
13074 | } | ||
13075 | drm_for_each_legacy_plane(plane, dev) { | ||
13076 | pstate = drm_atomic_get_existing_plane_state(state, plane) ?: | ||
13077 | plane->state; | ||
13078 | |||
13079 | if (!to_intel_plane_state(pstate)->visible) | ||
13080 | continue; | ||
13081 | |||
13082 | intel_state->wm_config.sprites_enabled = true; | ||
13083 | if (pstate->crtc_w != pstate->src_w >> 16 || | ||
13084 | pstate->crtc_h != pstate->src_h >> 16) | ||
13085 | intel_state->wm_config.sprites_scaled = true; | ||
13086 | } | ||
13087 | } | ||
13088 | |||
13089 | /** | 13044 | /** |
13090 | * intel_atomic_check - validate state object | 13045 | * intel_atomic_check - validate state object |
13091 | * @dev: drm device | 13046 | * @dev: drm device |
@@ -13094,7 +13049,6 @@ static void calc_watermark_data(struct drm_atomic_state *state) | |||
13094 | static int intel_atomic_check(struct drm_device *dev, | 13049 | static int intel_atomic_check(struct drm_device *dev, |
13095 | struct drm_atomic_state *state) | 13050 | struct drm_atomic_state *state) |
13096 | { | 13051 | { |
13097 | struct intel_atomic_state *intel_state = to_intel_atomic_state(state); | ||
13098 | struct drm_crtc *crtc; | 13052 | struct drm_crtc *crtc; |
13099 | struct drm_crtc_state *crtc_state; | 13053 | struct drm_crtc_state *crtc_state; |
13100 | int ret, i; | 13054 | int ret, i; |
@@ -13158,15 +13112,10 @@ static int intel_atomic_check(struct drm_device *dev, | |||
13158 | if (ret) | 13112 | if (ret) |
13159 | return ret; | 13113 | return ret; |
13160 | } else | 13114 | } else |
13161 | intel_state->cdclk = to_i915(state->dev)->cdclk_freq; | 13115 | to_intel_atomic_state(state)->cdclk = |
13162 | 13116 | to_i915(state->dev)->cdclk_freq; | |
13163 | ret = drm_atomic_helper_check_planes(state->dev, state); | ||
13164 | if (ret) | ||
13165 | return ret; | ||
13166 | |||
13167 | calc_watermark_data(state); | ||
13168 | 13117 | ||
13169 | return 0; | 13118 | return drm_atomic_helper_check_planes(state->dev, state); |
13170 | } | 13119 | } |
13171 | 13120 | ||
13172 | /** | 13121 | /** |
@@ -13206,7 +13155,6 @@ static int intel_atomic_commit(struct drm_device *dev, | |||
13206 | return ret; | 13155 | return ret; |
13207 | 13156 | ||
13208 | drm_atomic_helper_swap_state(dev, state); | 13157 | drm_atomic_helper_swap_state(dev, state); |
13209 | dev_priv->wm.config = to_intel_atomic_state(state)->wm_config; | ||
13210 | 13158 | ||
13211 | for_each_crtc_in_state(state, crtc, crtc_state, i) { | 13159 | for_each_crtc_in_state(state, crtc, crtc_state, i) { |
13212 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 13160 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
@@ -15220,7 +15168,7 @@ static void readout_plane_state(struct intel_crtc *crtc) | |||
15220 | struct intel_plane_state *plane_state = | 15168 | struct intel_plane_state *plane_state = |
15221 | to_intel_plane_state(primary->state); | 15169 | to_intel_plane_state(primary->state); |
15222 | 15170 | ||
15223 | plane_state->visible = crtc->active && | 15171 | plane_state->visible = |
15224 | primary_get_hw_state(to_intel_plane(primary)); | 15172 | primary_get_hw_state(to_intel_plane(primary)); |
15225 | 15173 | ||
15226 | if (plane_state->visible) | 15174 | if (plane_state->visible) |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index e320825abd95..91b6b4060333 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -250,7 +250,6 @@ struct intel_atomic_state { | |||
250 | unsigned int cdclk; | 250 | unsigned int cdclk; |
251 | bool dpll_set; | 251 | bool dpll_set; |
252 | struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS]; | 252 | struct intel_shared_dpll_config shared_dpll[I915_NUM_PLLS]; |
253 | struct intel_wm_config wm_config; | ||
254 | }; | 253 | }; |
255 | 254 | ||
256 | struct intel_plane_state { | 255 | struct intel_plane_state { |
@@ -335,21 +334,6 @@ struct intel_crtc_scaler_state { | |||
335 | /* drm_mode->private_flags */ | 334 | /* drm_mode->private_flags */ |
336 | #define I915_MODE_FLAG_INHERITED 1 | 335 | #define I915_MODE_FLAG_INHERITED 1 |
337 | 336 | ||
338 | struct intel_pipe_wm { | ||
339 | struct intel_wm_level wm[5]; | ||
340 | uint32_t linetime; | ||
341 | bool fbc_wm_enabled; | ||
342 | bool pipe_enabled; | ||
343 | bool sprites_enabled; | ||
344 | bool sprites_scaled; | ||
345 | }; | ||
346 | |||
347 | struct skl_pipe_wm { | ||
348 | struct skl_wm_level wm[8]; | ||
349 | struct skl_wm_level trans_wm; | ||
350 | uint32_t linetime; | ||
351 | }; | ||
352 | |||
353 | struct intel_crtc_state { | 337 | struct intel_crtc_state { |
354 | struct drm_crtc_state base; | 338 | struct drm_crtc_state base; |
355 | 339 | ||
@@ -487,17 +471,6 @@ struct intel_crtc_state { | |||
487 | 471 | ||
488 | /* IVB sprite scaling w/a (WaCxSRDisabledForSpriteScaling:ivb) */ | 472 | /* IVB sprite scaling w/a (WaCxSRDisabledForSpriteScaling:ivb) */ |
489 | bool disable_lp_wm; | 473 | bool disable_lp_wm; |
490 | |||
491 | struct { | ||
492 | /* | ||
493 | * optimal watermarks, programmed post-vblank when this state | ||
494 | * is committed | ||
495 | */ | ||
496 | union { | ||
497 | struct intel_pipe_wm ilk; | ||
498 | struct skl_pipe_wm skl; | ||
499 | } optimal; | ||
500 | } wm; | ||
501 | }; | 474 | }; |
502 | 475 | ||
503 | struct vlv_wm_state { | 476 | struct vlv_wm_state { |
@@ -509,6 +482,15 @@ struct vlv_wm_state { | |||
509 | bool cxsr; | 482 | bool cxsr; |
510 | }; | 483 | }; |
511 | 484 | ||
485 | struct intel_pipe_wm { | ||
486 | struct intel_wm_level wm[5]; | ||
487 | uint32_t linetime; | ||
488 | bool fbc_wm_enabled; | ||
489 | bool pipe_enabled; | ||
490 | bool sprites_enabled; | ||
491 | bool sprites_scaled; | ||
492 | }; | ||
493 | |||
512 | struct intel_mmio_flip { | 494 | struct intel_mmio_flip { |
513 | struct work_struct work; | 495 | struct work_struct work; |
514 | struct drm_i915_private *i915; | 496 | struct drm_i915_private *i915; |
@@ -516,6 +498,12 @@ struct intel_mmio_flip { | |||
516 | struct intel_crtc *crtc; | 498 | struct intel_crtc *crtc; |
517 | }; | 499 | }; |
518 | 500 | ||
501 | struct skl_pipe_wm { | ||
502 | struct skl_wm_level wm[8]; | ||
503 | struct skl_wm_level trans_wm; | ||
504 | uint32_t linetime; | ||
505 | }; | ||
506 | |||
519 | /* | 507 | /* |
520 | * Tracking of operations that need to be performed at the beginning/end of an | 508 | * Tracking of operations that need to be performed at the beginning/end of an |
521 | * atomic commit, outside the atomic section where interrupts are disabled. | 509 | * atomic commit, outside the atomic section where interrupts are disabled. |
@@ -583,10 +571,9 @@ struct intel_crtc { | |||
583 | /* per-pipe watermark state */ | 571 | /* per-pipe watermark state */ |
584 | struct { | 572 | struct { |
585 | /* watermarks currently being used */ | 573 | /* watermarks currently being used */ |
586 | union { | 574 | struct intel_pipe_wm active; |
587 | struct intel_pipe_wm ilk; | 575 | /* SKL wm values currently in use */ |
588 | struct skl_pipe_wm skl; | 576 | struct skl_pipe_wm skl_active; |
589 | } active; | ||
590 | /* allow CxSR on this pipe */ | 577 | /* allow CxSR on this pipe */ |
591 | bool cxsr_allowed; | 578 | bool cxsr_allowed; |
592 | } wm; | 579 | } wm; |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 3f9b3c078223..d031d74abd27 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -1772,6 +1772,13 @@ struct ilk_wm_maximums { | |||
1772 | uint16_t fbc; | 1772 | uint16_t fbc; |
1773 | }; | 1773 | }; |
1774 | 1774 | ||
1775 | /* used in computing the new watermarks state */ | ||
1776 | struct intel_wm_config { | ||
1777 | unsigned int num_pipes_active; | ||
1778 | bool sprites_enabled; | ||
1779 | bool sprites_scaled; | ||
1780 | }; | ||
1781 | |||
1775 | /* | 1782 | /* |
1776 | * For both WM_PIPE and WM_LP. | 1783 | * For both WM_PIPE and WM_LP. |
1777 | * mem_value must be in 0.1us units. | 1784 | * mem_value must be in 0.1us units. |
@@ -2022,11 +2029,9 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, | |||
2022 | const struct intel_crtc *intel_crtc, | 2029 | const struct intel_crtc *intel_crtc, |
2023 | int level, | 2030 | int level, |
2024 | struct intel_crtc_state *cstate, | 2031 | struct intel_crtc_state *cstate, |
2025 | struct intel_plane_state *pristate, | ||
2026 | struct intel_plane_state *sprstate, | ||
2027 | struct intel_plane_state *curstate, | ||
2028 | struct intel_wm_level *result) | 2032 | struct intel_wm_level *result) |
2029 | { | 2033 | { |
2034 | struct intel_plane *intel_plane; | ||
2030 | uint16_t pri_latency = dev_priv->wm.pri_latency[level]; | 2035 | uint16_t pri_latency = dev_priv->wm.pri_latency[level]; |
2031 | uint16_t spr_latency = dev_priv->wm.spr_latency[level]; | 2036 | uint16_t spr_latency = dev_priv->wm.spr_latency[level]; |
2032 | uint16_t cur_latency = dev_priv->wm.cur_latency[level]; | 2037 | uint16_t cur_latency = dev_priv->wm.cur_latency[level]; |
@@ -2038,11 +2043,29 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, | |||
2038 | cur_latency *= 5; | 2043 | cur_latency *= 5; |
2039 | } | 2044 | } |
2040 | 2045 | ||
2041 | result->pri_val = ilk_compute_pri_wm(cstate, pristate, | 2046 | for_each_intel_plane_on_crtc(dev_priv->dev, intel_crtc, intel_plane) { |
2042 | pri_latency, level); | 2047 | struct intel_plane_state *pstate = |
2043 | result->spr_val = ilk_compute_spr_wm(cstate, sprstate, spr_latency); | 2048 | to_intel_plane_state(intel_plane->base.state); |
2044 | result->cur_val = ilk_compute_cur_wm(cstate, curstate, cur_latency); | 2049 | |
2045 | result->fbc_val = ilk_compute_fbc_wm(cstate, pristate, result->pri_val); | 2050 | switch (intel_plane->base.type) { |
2051 | case DRM_PLANE_TYPE_PRIMARY: | ||
2052 | result->pri_val = ilk_compute_pri_wm(cstate, pstate, | ||
2053 | pri_latency, | ||
2054 | level); | ||
2055 | result->fbc_val = ilk_compute_fbc_wm(cstate, pstate, | ||
2056 | result->pri_val); | ||
2057 | break; | ||
2058 | case DRM_PLANE_TYPE_OVERLAY: | ||
2059 | result->spr_val = ilk_compute_spr_wm(cstate, pstate, | ||
2060 | spr_latency); | ||
2061 | break; | ||
2062 | case DRM_PLANE_TYPE_CURSOR: | ||
2063 | result->cur_val = ilk_compute_cur_wm(cstate, pstate, | ||
2064 | cur_latency); | ||
2065 | break; | ||
2066 | } | ||
2067 | } | ||
2068 | |||
2046 | result->enable = true; | 2069 | result->enable = true; |
2047 | } | 2070 | } |
2048 | 2071 | ||
@@ -2301,19 +2324,34 @@ static void skl_setup_wm_latency(struct drm_device *dev) | |||
2301 | intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency); | 2324 | intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency); |
2302 | } | 2325 | } |
2303 | 2326 | ||
2327 | static void ilk_compute_wm_config(struct drm_device *dev, | ||
2328 | struct intel_wm_config *config) | ||
2329 | { | ||
2330 | struct intel_crtc *intel_crtc; | ||
2331 | |||
2332 | /* Compute the currently _active_ config */ | ||
2333 | for_each_intel_crtc(dev, intel_crtc) { | ||
2334 | const struct intel_pipe_wm *wm = &intel_crtc->wm.active; | ||
2335 | |||
2336 | if (!wm->pipe_enabled) | ||
2337 | continue; | ||
2338 | |||
2339 | config->sprites_enabled |= wm->sprites_enabled; | ||
2340 | config->sprites_scaled |= wm->sprites_scaled; | ||
2341 | config->num_pipes_active++; | ||
2342 | } | ||
2343 | } | ||
2344 | |||
2304 | /* Compute new watermarks for the pipe */ | 2345 | /* Compute new watermarks for the pipe */ |
2305 | static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, | 2346 | static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate, |
2306 | struct drm_atomic_state *state) | 2347 | struct intel_pipe_wm *pipe_wm) |
2307 | { | 2348 | { |
2308 | struct intel_pipe_wm *pipe_wm; | 2349 | struct drm_crtc *crtc = cstate->base.crtc; |
2309 | struct drm_device *dev = intel_crtc->base.dev; | 2350 | struct drm_device *dev = crtc->dev; |
2310 | const struct drm_i915_private *dev_priv = dev->dev_private; | 2351 | const struct drm_i915_private *dev_priv = dev->dev_private; |
2311 | struct intel_crtc_state *cstate = NULL; | 2352 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2312 | struct intel_plane *intel_plane; | 2353 | struct intel_plane *intel_plane; |
2313 | struct drm_plane_state *ps; | ||
2314 | struct intel_plane_state *pristate = NULL; | ||
2315 | struct intel_plane_state *sprstate = NULL; | 2354 | struct intel_plane_state *sprstate = NULL; |
2316 | struct intel_plane_state *curstate = NULL; | ||
2317 | int level, max_level = ilk_wm_max_level(dev); | 2355 | int level, max_level = ilk_wm_max_level(dev); |
2318 | /* LP0 watermark maximums depend on this pipe alone */ | 2356 | /* LP0 watermark maximums depend on this pipe alone */ |
2319 | struct intel_wm_config config = { | 2357 | struct intel_wm_config config = { |
@@ -2321,24 +2359,11 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, | |||
2321 | }; | 2359 | }; |
2322 | struct ilk_wm_maximums max; | 2360 | struct ilk_wm_maximums max; |
2323 | 2361 | ||
2324 | cstate = intel_atomic_get_crtc_state(state, intel_crtc); | ||
2325 | if (IS_ERR(cstate)) | ||
2326 | return PTR_ERR(cstate); | ||
2327 | |||
2328 | pipe_wm = &cstate->wm.optimal.ilk; | ||
2329 | |||
2330 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { | 2362 | for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { |
2331 | ps = drm_atomic_get_plane_state(state, | 2363 | if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) { |
2332 | &intel_plane->base); | 2364 | sprstate = to_intel_plane_state(intel_plane->base.state); |
2333 | if (IS_ERR(ps)) | 2365 | break; |
2334 | return PTR_ERR(ps); | 2366 | } |
2335 | |||
2336 | if (intel_plane->base.type == DRM_PLANE_TYPE_PRIMARY) | ||
2337 | pristate = to_intel_plane_state(ps); | ||
2338 | else if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) | ||
2339 | sprstate = to_intel_plane_state(ps); | ||
2340 | else if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR) | ||
2341 | curstate = to_intel_plane_state(ps); | ||
2342 | } | 2367 | } |
2343 | 2368 | ||
2344 | config.sprites_enabled = sprstate->visible; | 2369 | config.sprites_enabled = sprstate->visible; |
@@ -2347,7 +2372,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, | |||
2347 | drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16); | 2372 | drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16); |
2348 | 2373 | ||
2349 | pipe_wm->pipe_enabled = cstate->base.active; | 2374 | pipe_wm->pipe_enabled = cstate->base.active; |
2350 | pipe_wm->sprites_enabled = config.sprites_enabled; | 2375 | pipe_wm->sprites_enabled = sprstate->visible; |
2351 | pipe_wm->sprites_scaled = config.sprites_scaled; | 2376 | pipe_wm->sprites_scaled = config.sprites_scaled; |
2352 | 2377 | ||
2353 | /* ILK/SNB: LP2+ watermarks only w/o sprites */ | 2378 | /* ILK/SNB: LP2+ watermarks only w/o sprites */ |
@@ -2358,27 +2383,24 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, | |||
2358 | if (config.sprites_scaled) | 2383 | if (config.sprites_scaled) |
2359 | max_level = 0; | 2384 | max_level = 0; |
2360 | 2385 | ||
2361 | ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, | 2386 | ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, &pipe_wm->wm[0]); |
2362 | pristate, sprstate, curstate, &pipe_wm->wm[0]); | ||
2363 | 2387 | ||
2364 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) | 2388 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
2365 | pipe_wm->linetime = hsw_compute_linetime_wm(dev, | 2389 | pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc); |
2366 | &intel_crtc->base); | ||
2367 | 2390 | ||
2368 | /* LP0 watermarks always use 1/2 DDB partitioning */ | 2391 | /* LP0 watermarks always use 1/2 DDB partitioning */ |
2369 | ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max); | 2392 | ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max); |
2370 | 2393 | ||
2371 | /* At least LP0 must be valid */ | 2394 | /* At least LP0 must be valid */ |
2372 | if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0])) | 2395 | if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0])) |
2373 | return -EINVAL; | 2396 | return false; |
2374 | 2397 | ||
2375 | ilk_compute_wm_reg_maximums(dev, 1, &max); | 2398 | ilk_compute_wm_reg_maximums(dev, 1, &max); |
2376 | 2399 | ||
2377 | for (level = 1; level <= max_level; level++) { | 2400 | for (level = 1; level <= max_level; level++) { |
2378 | struct intel_wm_level wm = {}; | 2401 | struct intel_wm_level wm = {}; |
2379 | 2402 | ||
2380 | ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, | 2403 | ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, &wm); |
2381 | pristate, sprstate, curstate, &wm); | ||
2382 | 2404 | ||
2383 | /* | 2405 | /* |
2384 | * Disable any watermark level that exceeds the | 2406 | * Disable any watermark level that exceeds the |
@@ -2391,7 +2413,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, | |||
2391 | pipe_wm->wm[level] = wm; | 2413 | pipe_wm->wm[level] = wm; |
2392 | } | 2414 | } |
2393 | 2415 | ||
2394 | return 0; | 2416 | return true; |
2395 | } | 2417 | } |
2396 | 2418 | ||
2397 | /* | 2419 | /* |
@@ -2406,9 +2428,7 @@ static void ilk_merge_wm_level(struct drm_device *dev, | |||
2406 | ret_wm->enable = true; | 2428 | ret_wm->enable = true; |
2407 | 2429 | ||
2408 | for_each_intel_crtc(dev, intel_crtc) { | 2430 | for_each_intel_crtc(dev, intel_crtc) { |
2409 | const struct intel_crtc_state *cstate = | 2431 | const struct intel_pipe_wm *active = &intel_crtc->wm.active; |
2410 | to_intel_crtc_state(intel_crtc->base.state); | ||
2411 | const struct intel_pipe_wm *active = &cstate->wm.optimal.ilk; | ||
2412 | const struct intel_wm_level *wm = &active->wm[level]; | 2432 | const struct intel_wm_level *wm = &active->wm[level]; |
2413 | 2433 | ||
2414 | if (!active->pipe_enabled) | 2434 | if (!active->pipe_enabled) |
@@ -2556,15 +2576,14 @@ static void ilk_compute_wm_results(struct drm_device *dev, | |||
2556 | 2576 | ||
2557 | /* LP0 register values */ | 2577 | /* LP0 register values */ |
2558 | for_each_intel_crtc(dev, intel_crtc) { | 2578 | for_each_intel_crtc(dev, intel_crtc) { |
2559 | const struct intel_crtc_state *cstate = | ||
2560 | to_intel_crtc_state(intel_crtc->base.state); | ||
2561 | enum pipe pipe = intel_crtc->pipe; | 2579 | enum pipe pipe = intel_crtc->pipe; |
2562 | const struct intel_wm_level *r = &cstate->wm.optimal.ilk.wm[0]; | 2580 | const struct intel_wm_level *r = |
2581 | &intel_crtc->wm.active.wm[0]; | ||
2563 | 2582 | ||
2564 | if (WARN_ON(!r->enable)) | 2583 | if (WARN_ON(!r->enable)) |
2565 | continue; | 2584 | continue; |
2566 | 2585 | ||
2567 | results->wm_linetime[pipe] = cstate->wm.optimal.ilk.linetime; | 2586 | results->wm_linetime[pipe] = intel_crtc->wm.active.linetime; |
2568 | 2587 | ||
2569 | results->wm_pipe[pipe] = | 2588 | results->wm_pipe[pipe] = |
2570 | (r->pri_val << WM0_PIPE_PLANE_SHIFT) | | 2589 | (r->pri_val << WM0_PIPE_PLANE_SHIFT) | |
@@ -2946,12 +2965,11 @@ skl_get_total_relative_data_rate(const struct intel_crtc_state *cstate) | |||
2946 | 2965 | ||
2947 | static void | 2966 | static void |
2948 | skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, | 2967 | skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, |
2968 | const struct intel_wm_config *config, | ||
2949 | struct skl_ddb_allocation *ddb /* out */) | 2969 | struct skl_ddb_allocation *ddb /* out */) |
2950 | { | 2970 | { |
2951 | struct drm_crtc *crtc = cstate->base.crtc; | 2971 | struct drm_crtc *crtc = cstate->base.crtc; |
2952 | struct drm_device *dev = crtc->dev; | 2972 | struct drm_device *dev = crtc->dev; |
2953 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2954 | struct intel_wm_config *config = &dev_priv->wm.config; | ||
2955 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 2973 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
2956 | struct intel_plane *intel_plane; | 2974 | struct intel_plane *intel_plane; |
2957 | enum pipe pipe = intel_crtc->pipe; | 2975 | enum pipe pipe = intel_crtc->pipe; |
@@ -3126,6 +3144,15 @@ static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb, | |||
3126 | return false; | 3144 | return false; |
3127 | } | 3145 | } |
3128 | 3146 | ||
3147 | static void skl_compute_wm_global_parameters(struct drm_device *dev, | ||
3148 | struct intel_wm_config *config) | ||
3149 | { | ||
3150 | struct drm_crtc *crtc; | ||
3151 | |||
3152 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | ||
3153 | config->num_pipes_active += to_intel_crtc(crtc)->active; | ||
3154 | } | ||
3155 | |||
3129 | static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, | 3156 | static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv, |
3130 | struct intel_crtc_state *cstate, | 3157 | struct intel_crtc_state *cstate, |
3131 | struct intel_plane *intel_plane, | 3158 | struct intel_plane *intel_plane, |
@@ -3530,25 +3557,27 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv, | |||
3530 | } | 3557 | } |
3531 | 3558 | ||
3532 | static bool skl_update_pipe_wm(struct drm_crtc *crtc, | 3559 | static bool skl_update_pipe_wm(struct drm_crtc *crtc, |
3560 | struct intel_wm_config *config, | ||
3533 | struct skl_ddb_allocation *ddb, /* out */ | 3561 | struct skl_ddb_allocation *ddb, /* out */ |
3534 | struct skl_pipe_wm *pipe_wm /* out */) | 3562 | struct skl_pipe_wm *pipe_wm /* out */) |
3535 | { | 3563 | { |
3536 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3564 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3537 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); | 3565 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); |
3538 | 3566 | ||
3539 | skl_allocate_pipe_ddb(cstate, ddb); | 3567 | skl_allocate_pipe_ddb(cstate, config, ddb); |
3540 | skl_compute_pipe_wm(cstate, ddb, pipe_wm); | 3568 | skl_compute_pipe_wm(cstate, ddb, pipe_wm); |
3541 | 3569 | ||
3542 | if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm))) | 3570 | if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm))) |
3543 | return false; | 3571 | return false; |
3544 | 3572 | ||
3545 | intel_crtc->wm.active.skl = *pipe_wm; | 3573 | intel_crtc->wm.skl_active = *pipe_wm; |
3546 | 3574 | ||
3547 | return true; | 3575 | return true; |
3548 | } | 3576 | } |
3549 | 3577 | ||
3550 | static void skl_update_other_pipe_wm(struct drm_device *dev, | 3578 | static void skl_update_other_pipe_wm(struct drm_device *dev, |
3551 | struct drm_crtc *crtc, | 3579 | struct drm_crtc *crtc, |
3580 | struct intel_wm_config *config, | ||
3552 | struct skl_wm_values *r) | 3581 | struct skl_wm_values *r) |
3553 | { | 3582 | { |
3554 | struct intel_crtc *intel_crtc; | 3583 | struct intel_crtc *intel_crtc; |
@@ -3578,7 +3607,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev, | |||
3578 | if (!intel_crtc->active) | 3607 | if (!intel_crtc->active) |
3579 | continue; | 3608 | continue; |
3580 | 3609 | ||
3581 | wm_changed = skl_update_pipe_wm(&intel_crtc->base, | 3610 | wm_changed = skl_update_pipe_wm(&intel_crtc->base, config, |
3582 | &r->ddb, &pipe_wm); | 3611 | &r->ddb, &pipe_wm); |
3583 | 3612 | ||
3584 | /* | 3613 | /* |
@@ -3619,8 +3648,8 @@ static void skl_update_wm(struct drm_crtc *crtc) | |||
3619 | struct drm_device *dev = crtc->dev; | 3648 | struct drm_device *dev = crtc->dev; |
3620 | struct drm_i915_private *dev_priv = dev->dev_private; | 3649 | struct drm_i915_private *dev_priv = dev->dev_private; |
3621 | struct skl_wm_values *results = &dev_priv->wm.skl_results; | 3650 | struct skl_wm_values *results = &dev_priv->wm.skl_results; |
3622 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); | 3651 | struct skl_pipe_wm pipe_wm = {}; |
3623 | struct skl_pipe_wm *pipe_wm = &cstate->wm.optimal.skl; | 3652 | struct intel_wm_config config = {}; |
3624 | 3653 | ||
3625 | 3654 | ||
3626 | /* Clear all dirty flags */ | 3655 | /* Clear all dirty flags */ |
@@ -3628,13 +3657,15 @@ static void skl_update_wm(struct drm_crtc *crtc) | |||
3628 | 3657 | ||
3629 | skl_clear_wm(results, intel_crtc->pipe); | 3658 | skl_clear_wm(results, intel_crtc->pipe); |
3630 | 3659 | ||
3631 | if (!skl_update_pipe_wm(crtc, &results->ddb, pipe_wm)) | 3660 | skl_compute_wm_global_parameters(dev, &config); |
3661 | |||
3662 | if (!skl_update_pipe_wm(crtc, &config, &results->ddb, &pipe_wm)) | ||
3632 | return; | 3663 | return; |
3633 | 3664 | ||
3634 | skl_compute_wm_results(dev, pipe_wm, results, intel_crtc); | 3665 | skl_compute_wm_results(dev, &pipe_wm, results, intel_crtc); |
3635 | results->dirty[intel_crtc->pipe] = true; | 3666 | results->dirty[intel_crtc->pipe] = true; |
3636 | 3667 | ||
3637 | skl_update_other_pipe_wm(dev, crtc, results); | 3668 | skl_update_other_pipe_wm(dev, crtc, &config, results); |
3638 | skl_write_wm_values(dev_priv, results); | 3669 | skl_write_wm_values(dev_priv, results); |
3639 | skl_flush_wm_values(dev_priv, results); | 3670 | skl_flush_wm_values(dev_priv, results); |
3640 | 3671 | ||
@@ -3642,23 +3673,50 @@ static void skl_update_wm(struct drm_crtc *crtc) | |||
3642 | dev_priv->wm.skl_hw = *results; | 3673 | dev_priv->wm.skl_hw = *results; |
3643 | } | 3674 | } |
3644 | 3675 | ||
3645 | static void ilk_program_watermarks(struct drm_i915_private *dev_priv) | 3676 | static void ilk_update_wm(struct drm_crtc *crtc) |
3646 | { | 3677 | { |
3647 | struct drm_device *dev = dev_priv->dev; | 3678 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3648 | struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; | 3679 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); |
3680 | struct drm_device *dev = crtc->dev; | ||
3681 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3649 | struct ilk_wm_maximums max; | 3682 | struct ilk_wm_maximums max; |
3650 | struct intel_wm_config *config = &dev_priv->wm.config; | ||
3651 | struct ilk_wm_values results = {}; | 3683 | struct ilk_wm_values results = {}; |
3652 | enum intel_ddb_partitioning partitioning; | 3684 | enum intel_ddb_partitioning partitioning; |
3685 | struct intel_pipe_wm pipe_wm = {}; | ||
3686 | struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; | ||
3687 | struct intel_wm_config config = {}; | ||
3653 | 3688 | ||
3654 | ilk_compute_wm_maximums(dev, 1, config, INTEL_DDB_PART_1_2, &max); | 3689 | WARN_ON(cstate->base.active != intel_crtc->active); |
3655 | ilk_wm_merge(dev, config, &max, &lp_wm_1_2); | 3690 | |
3691 | /* | ||
3692 | * IVB workaround: must disable low power watermarks for at least | ||
3693 | * one frame before enabling scaling. LP watermarks can be re-enabled | ||
3694 | * when scaling is disabled. | ||
3695 | * | ||
3696 | * WaCxSRDisabledForSpriteScaling:ivb | ||
3697 | */ | ||
3698 | if (cstate->disable_lp_wm) { | ||
3699 | ilk_disable_lp_wm(dev); | ||
3700 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
3701 | } | ||
3702 | |||
3703 | intel_compute_pipe_wm(cstate, &pipe_wm); | ||
3704 | |||
3705 | if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm))) | ||
3706 | return; | ||
3707 | |||
3708 | intel_crtc->wm.active = pipe_wm; | ||
3709 | |||
3710 | ilk_compute_wm_config(dev, &config); | ||
3711 | |||
3712 | ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_1_2, &max); | ||
3713 | ilk_wm_merge(dev, &config, &max, &lp_wm_1_2); | ||
3656 | 3714 | ||
3657 | /* 5/6 split only in single pipe config on IVB+ */ | 3715 | /* 5/6 split only in single pipe config on IVB+ */ |
3658 | if (INTEL_INFO(dev)->gen >= 7 && | 3716 | if (INTEL_INFO(dev)->gen >= 7 && |
3659 | config->num_pipes_active == 1 && config->sprites_enabled) { | 3717 | config.num_pipes_active == 1 && config.sprites_enabled) { |
3660 | ilk_compute_wm_maximums(dev, 1, config, INTEL_DDB_PART_5_6, &max); | 3718 | ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_5_6, &max); |
3661 | ilk_wm_merge(dev, config, &max, &lp_wm_5_6); | 3719 | ilk_wm_merge(dev, &config, &max, &lp_wm_5_6); |
3662 | 3720 | ||
3663 | best_lp_wm = ilk_find_best_result(dev, &lp_wm_1_2, &lp_wm_5_6); | 3721 | best_lp_wm = ilk_find_best_result(dev, &lp_wm_1_2, &lp_wm_5_6); |
3664 | } else { | 3722 | } else { |
@@ -3673,31 +3731,6 @@ static void ilk_program_watermarks(struct drm_i915_private *dev_priv) | |||
3673 | ilk_write_wm_values(dev_priv, &results); | 3731 | ilk_write_wm_values(dev_priv, &results); |
3674 | } | 3732 | } |
3675 | 3733 | ||
3676 | static void ilk_update_wm(struct drm_crtc *crtc) | ||
3677 | { | ||
3678 | struct drm_i915_private *dev_priv = to_i915(crtc->dev); | ||
3679 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
3680 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); | ||
3681 | |||
3682 | WARN_ON(cstate->base.active != intel_crtc->active); | ||
3683 | |||
3684 | /* | ||
3685 | * IVB workaround: must disable low power watermarks for at least | ||
3686 | * one frame before enabling scaling. LP watermarks can be re-enabled | ||
3687 | * when scaling is disabled. | ||
3688 | * | ||
3689 | * WaCxSRDisabledForSpriteScaling:ivb | ||
3690 | */ | ||
3691 | if (cstate->disable_lp_wm) { | ||
3692 | ilk_disable_lp_wm(crtc->dev); | ||
3693 | intel_wait_for_vblank(crtc->dev, intel_crtc->pipe); | ||
3694 | } | ||
3695 | |||
3696 | intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk; | ||
3697 | |||
3698 | ilk_program_watermarks(dev_priv); | ||
3699 | } | ||
3700 | |||
3701 | static void skl_pipe_wm_active_state(uint32_t val, | 3734 | static void skl_pipe_wm_active_state(uint32_t val, |
3702 | struct skl_pipe_wm *active, | 3735 | struct skl_pipe_wm *active, |
3703 | bool is_transwm, | 3736 | bool is_transwm, |
@@ -3748,8 +3781,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc) | |||
3748 | struct drm_i915_private *dev_priv = dev->dev_private; | 3781 | struct drm_i915_private *dev_priv = dev->dev_private; |
3749 | struct skl_wm_values *hw = &dev_priv->wm.skl_hw; | 3782 | struct skl_wm_values *hw = &dev_priv->wm.skl_hw; |
3750 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3783 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3751 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); | 3784 | struct skl_pipe_wm *active = &intel_crtc->wm.skl_active; |
3752 | struct skl_pipe_wm *active = &cstate->wm.optimal.skl; | ||
3753 | enum pipe pipe = intel_crtc->pipe; | 3785 | enum pipe pipe = intel_crtc->pipe; |
3754 | int level, i, max_level; | 3786 | int level, i, max_level; |
3755 | uint32_t temp; | 3787 | uint32_t temp; |
@@ -3793,8 +3825,6 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc) | |||
3793 | 3825 | ||
3794 | temp = hw->plane_trans[pipe][PLANE_CURSOR]; | 3826 | temp = hw->plane_trans[pipe][PLANE_CURSOR]; |
3795 | skl_pipe_wm_active_state(temp, active, true, true, i, 0); | 3827 | skl_pipe_wm_active_state(temp, active, true, true, i, 0); |
3796 | |||
3797 | intel_crtc->wm.active.skl = *active; | ||
3798 | } | 3828 | } |
3799 | 3829 | ||
3800 | void skl_wm_get_hw_state(struct drm_device *dev) | 3830 | void skl_wm_get_hw_state(struct drm_device *dev) |
@@ -3814,8 +3844,7 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc) | |||
3814 | struct drm_i915_private *dev_priv = dev->dev_private; | 3844 | struct drm_i915_private *dev_priv = dev->dev_private; |
3815 | struct ilk_wm_values *hw = &dev_priv->wm.hw; | 3845 | struct ilk_wm_values *hw = &dev_priv->wm.hw; |
3816 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3846 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3817 | struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); | 3847 | struct intel_pipe_wm *active = &intel_crtc->wm.active; |
3818 | struct intel_pipe_wm *active = &cstate->wm.optimal.ilk; | ||
3819 | enum pipe pipe = intel_crtc->pipe; | 3848 | enum pipe pipe = intel_crtc->pipe; |
3820 | static const unsigned int wm0_pipe_reg[] = { | 3849 | static const unsigned int wm0_pipe_reg[] = { |
3821 | [PIPE_A] = WM0_PIPEA_ILK, | 3850 | [PIPE_A] = WM0_PIPEA_ILK, |
@@ -3854,8 +3883,6 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc) | |||
3854 | for (level = 0; level <= max_level; level++) | 3883 | for (level = 0; level <= max_level; level++) |
3855 | active->wm[level].enable = true; | 3884 | active->wm[level].enable = true; |
3856 | } | 3885 | } |
3857 | |||
3858 | intel_crtc->wm.active.ilk = *active; | ||
3859 | } | 3886 | } |
3860 | 3887 | ||
3861 | #define _FW_WM(value, plane) \ | 3888 | #define _FW_WM(value, plane) \ |
@@ -7003,7 +7030,6 @@ void intel_init_pm(struct drm_device *dev) | |||
7003 | (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] && | 7030 | (!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] && |
7004 | dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { | 7031 | dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { |
7005 | dev_priv->display.update_wm = ilk_update_wm; | 7032 | dev_priv->display.update_wm = ilk_update_wm; |
7006 | dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm; | ||
7007 | } else { | 7033 | } else { |
7008 | DRM_DEBUG_KMS("Failed to read display plane latency. " | 7034 | DRM_DEBUG_KMS("Failed to read display plane latency. " |
7009 | "Disable CxSR\n"); | 7035 | "Disable CxSR\n"); |