diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 232 |
1 files changed, 129 insertions, 103 deletions
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"); |