diff options
author | Maxime Ripard <maxime.ripard@bootlin.com> | 2019-01-24 11:03:16 +0100 |
---|---|---|
committer | Maxime Ripard <maxime.ripard@bootlin.com> | 2019-01-24 11:03:16 +0100 |
commit | d2c20b5d37820876a8beea4d8d0bc59147077dd5 (patch) | |
tree | ae032c4de299cb8f14275514c5cec634bc46b591 /drivers/gpu/drm/i915/intel_pm.c | |
parent | b30b61ff6b1dc37f276cf56a8328b80086a3ffca (diff) | |
parent | 8ca4fd0406b41a872055048d694f3702d8eddb76 (diff) |
Merge drm/drm-next into drm-misc-next
danvet needs a backmerge to ease the upcoming drmP.h rework
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 738 |
1 files changed, 300 insertions, 438 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index a26b4eddda25..83b01cde8113 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1399,10 +1399,9 @@ static int g4x_compute_pipe_wm(struct intel_crtc_state *crtc_state) return 0; } -static int g4x_compute_intermediate_wm(struct drm_device *dev, - struct intel_crtc *crtc, - struct intel_crtc_state *new_crtc_state) +static int g4x_compute_intermediate_wm(struct intel_crtc_state *new_crtc_state) { + struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc); struct g4x_wm_state *intermediate = &new_crtc_state->wm.g4x.intermediate; const struct g4x_wm_state *optimal = &new_crtc_state->wm.g4x.optimal; struct intel_atomic_state *intel_state = @@ -2032,10 +2031,9 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state, #undef VLV_FIFO -static int vlv_compute_intermediate_wm(struct drm_device *dev, - struct intel_crtc *crtc, - struct intel_crtc_state *new_crtc_state) +static int vlv_compute_intermediate_wm(struct intel_crtc_state *new_crtc_state) { + struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc); struct vlv_wm_state *intermediate = &new_crtc_state->wm.vlv.intermediate; const struct vlv_wm_state *optimal = &new_crtc_state->wm.vlv.optimal; struct intel_atomic_state *intel_state = @@ -2273,7 +2271,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc) if (IS_I945GM(dev_priv)) wm_info = &i945_wm_info; - else if (!IS_GEN2(dev_priv)) + else if (!IS_GEN(dev_priv, 2)) wm_info = &i915_wm_info; else wm_info = &i830_a_wm_info; @@ -2287,7 +2285,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc) crtc->base.primary->state->fb; int cpp; - if (IS_GEN2(dev_priv)) + if (IS_GEN(dev_priv, 2)) cpp = 4; else cpp = fb->format->cpp[0]; @@ -2302,7 +2300,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc) planea_wm = wm_info->max_wm; } - if (IS_GEN2(dev_priv)) + if (IS_GEN(dev_priv, 2)) wm_info = &i830_bc_wm_info; fifo_size = dev_priv->display.get_fifo_size(dev_priv, PLANE_B); @@ -2314,7 +2312,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc) crtc->base.primary->state->fb; int cpp; - if (IS_GEN2(dev_priv)) + if (IS_GEN(dev_priv, 2)) cpp = 4; else cpp = fb->format->cpp[0]; @@ -2626,13 +2624,12 @@ static unsigned int ilk_fbc_wm_reg_max(const struct drm_i915_private *dev_priv) } /* Calculate the maximum primary/sprite plane watermark */ -static unsigned int ilk_plane_wm_max(const struct drm_device *dev, +static unsigned int ilk_plane_wm_max(const struct drm_i915_private *dev_priv, int level, const struct intel_wm_config *config, enum intel_ddb_partitioning ddb_partitioning, bool is_sprite) { - struct drm_i915_private *dev_priv = to_i915(dev); unsigned int fifo_size = ilk_display_fifo_size(dev_priv); /* if sprites aren't enabled, sprites get nothing */ @@ -2668,7 +2665,7 @@ static unsigned int ilk_plane_wm_max(const struct drm_device *dev, } /* Calculate the maximum cursor plane watermark */ -static unsigned int ilk_cursor_wm_max(const struct drm_device *dev, +static unsigned int ilk_cursor_wm_max(const struct drm_i915_private *dev_priv, int level, const struct intel_wm_config *config) { @@ -2677,19 +2674,19 @@ static unsigned int ilk_cursor_wm_max(const struct drm_device *dev, return 64; /* otherwise just report max that registers can hold */ - return ilk_cursor_wm_reg_max(to_i915(dev), level); + return ilk_cursor_wm_reg_max(dev_priv, level); } -static void ilk_compute_wm_maximums(const struct drm_device *dev, +static void ilk_compute_wm_maximums(const struct drm_i915_private *dev_priv, int level, const struct intel_wm_config *config, enum intel_ddb_partitioning ddb_partitioning, struct ilk_wm_maximums *max) { - max->pri = ilk_plane_wm_max(dev, level, config, ddb_partitioning, false); - max->spr = ilk_plane_wm_max(dev, level, config, ddb_partitioning, true); - max->cur = ilk_cursor_wm_max(dev, level, config); - max->fbc = ilk_fbc_wm_reg_max(to_i915(dev)); + max->pri = ilk_plane_wm_max(dev_priv, level, config, ddb_partitioning, false); + max->spr = ilk_plane_wm_max(dev_priv, level, config, ddb_partitioning, true); + max->cur = ilk_cursor_wm_max(dev_priv, level, config); + max->fbc = ilk_fbc_wm_reg_max(dev_priv); } static void ilk_compute_wm_reg_maximums(const struct drm_i915_private *dev_priv, @@ -2926,7 +2923,7 @@ static void intel_fixup_spr_wm_latency(struct drm_i915_private *dev_priv, uint16_t wm[5]) { /* ILK sprite LP0 latency is 1300 ns */ - if (IS_GEN5(dev_priv)) + if (IS_GEN(dev_priv, 5)) wm[0] = 13; } @@ -2934,7 +2931,7 @@ static void intel_fixup_cur_wm_latency(struct drm_i915_private *dev_priv, uint16_t wm[5]) { /* ILK cursor LP0 latency is 1300 ns */ - if (IS_GEN5(dev_priv)) + if (IS_GEN(dev_priv, 5)) wm[0] = 13; } @@ -3061,7 +3058,7 @@ static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv) intel_print_wm_latency(dev_priv, "Sprite", dev_priv->wm.spr_latency); intel_print_wm_latency(dev_priv, "Cursor", dev_priv->wm.cur_latency); - if (IS_GEN6(dev_priv)) { + if (IS_GEN(dev_priv, 6)) { snb_wm_latency_quirk(dev_priv); snb_wm_lp3_irq_quirk(dev_priv); } @@ -3073,7 +3070,7 @@ static void skl_setup_wm_latency(struct drm_i915_private *dev_priv) intel_print_wm_latency(dev_priv, "Gen9 Plane", dev_priv->wm.skl_latency); } -static bool ilk_validate_pipe_wm(struct drm_device *dev, +static bool ilk_validate_pipe_wm(const struct drm_i915_private *dev_priv, struct intel_pipe_wm *pipe_wm) { /* LP0 watermark maximums depend on this pipe alone */ @@ -3085,7 +3082,7 @@ static bool ilk_validate_pipe_wm(struct drm_device *dev, struct ilk_wm_maximums max; /* LP0 watermarks always use 1/2 DDB partitioning */ - ilk_compute_wm_maximums(dev, 0, &config, INTEL_DDB_PART_1_2, &max); + ilk_compute_wm_maximums(dev_priv, 0, &config, INTEL_DDB_PART_1_2, &max); /* At least LP0 must be valid */ if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0])) { @@ -3150,7 +3147,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate) if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) pipe_wm->linetime = hsw_compute_linetime_wm(cstate); - if (!ilk_validate_pipe_wm(dev, pipe_wm)) + if (!ilk_validate_pipe_wm(dev_priv, pipe_wm)) return -EINVAL; ilk_compute_wm_reg_maximums(dev_priv, 1, &max); @@ -3180,17 +3177,17 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate) * state and the new state. These can be programmed to the hardware * immediately. */ -static int ilk_compute_intermediate_wm(struct drm_device *dev, - struct intel_crtc *intel_crtc, - struct intel_crtc_state *newstate) +static int ilk_compute_intermediate_wm(struct intel_crtc_state *newstate) { + struct intel_crtc *intel_crtc = to_intel_crtc(newstate->base.crtc); + struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); struct intel_pipe_wm *a = &newstate->wm.ilk.intermediate; struct intel_atomic_state *intel_state = to_intel_atomic_state(newstate->base.state); const struct intel_crtc_state *oldstate = intel_atomic_get_old_crtc_state(intel_state, intel_crtc); const struct intel_pipe_wm *b = &oldstate->wm.ilk.optimal; - int level, max_level = ilk_wm_max_level(to_i915(dev)); + int level, max_level = ilk_wm_max_level(dev_priv); /* * Start with the final, target watermarks, then combine with the @@ -3223,7 +3220,7 @@ static int ilk_compute_intermediate_wm(struct drm_device *dev, * there's no safe way to transition from the old state to * the new state, so we need to fail the atomic transaction. */ - if (!ilk_validate_pipe_wm(dev, a)) + if (!ilk_validate_pipe_wm(dev_priv, a)) return -EINVAL; /* @@ -3239,7 +3236,7 @@ static int ilk_compute_intermediate_wm(struct drm_device *dev, /* * Merge the watermarks from all active pipes for a specific level. */ -static void ilk_merge_wm_level(struct drm_device *dev, +static void ilk_merge_wm_level(struct drm_i915_private *dev_priv, int level, struct intel_wm_level *ret_wm) { @@ -3247,7 +3244,7 @@ static void ilk_merge_wm_level(struct drm_device *dev, ret_wm->enable = true; - for_each_intel_crtc(dev, intel_crtc) { + for_each_intel_crtc(&dev_priv->drm, intel_crtc) { const struct intel_pipe_wm *active = &intel_crtc->wm.active.ilk; const struct intel_wm_level *wm = &active->wm[level]; @@ -3272,12 +3269,11 @@ static void ilk_merge_wm_level(struct drm_device *dev, /* * Merge all low power watermarks for all active pipes. */ -static void ilk_wm_merge(struct drm_device *dev, +static void ilk_wm_merge(struct drm_i915_private *dev_priv, const struct intel_wm_config *config, const struct ilk_wm_maximums *max, struct intel_pipe_wm *merged) { - struct drm_i915_private *dev_priv = to_i915(dev); int level, max_level = ilk_wm_max_level(dev_priv); int last_enabled_level = max_level; @@ -3293,7 +3289,7 @@ static void ilk_wm_merge(struct drm_device *dev, for (level = 1; level <= max_level; level++) { struct intel_wm_level *wm = &merged->wm[level]; - ilk_merge_wm_level(dev, level, wm); + ilk_merge_wm_level(dev_priv, level, wm); if (level > last_enabled_level) wm->enable = false; @@ -3318,7 +3314,7 @@ static void ilk_wm_merge(struct drm_device *dev, * What we should check here is whether FBC can be * enabled sometime later. */ - if (IS_GEN5(dev_priv) && !merged->fbc_wm_enabled && + if (IS_GEN(dev_priv, 5) && !merged->fbc_wm_enabled && intel_fbc_is_active(dev_priv)) { for (level = 2; level <= max_level; level++) { struct intel_wm_level *wm = &merged->wm[level]; @@ -3335,22 +3331,20 @@ static int ilk_wm_lp_to_level(int wm_lp, const struct intel_pipe_wm *pipe_wm) } /* The value we need to program into the WM_LPx latency field */ -static unsigned int ilk_wm_lp_latency(struct drm_device *dev, int level) +static unsigned int ilk_wm_lp_latency(struct drm_i915_private *dev_priv, + int level) { - struct drm_i915_private *dev_priv = to_i915(dev); - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) return 2 * level; else return dev_priv->wm.pri_latency[level]; } -static void ilk_compute_wm_results(struct drm_device *dev, +static void ilk_compute_wm_results(struct drm_i915_private *dev_priv, const struct intel_pipe_wm *merged, enum intel_ddb_partitioning partitioning, struct ilk_wm_values *results) { - struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc; int level, wm_lp; @@ -3370,7 +3364,7 @@ static void ilk_compute_wm_results(struct drm_device *dev, * disabled. Doing otherwise could cause underruns. */ results->wm_lp[wm_lp - 1] = - (ilk_wm_lp_latency(dev, level) << WM1_LP_LATENCY_SHIFT) | + (ilk_wm_lp_latency(dev_priv, level) << WM1_LP_LATENCY_SHIFT) | (r->pri_val << WM1_LP_SR_SHIFT) | r->cur_val; @@ -3396,7 +3390,7 @@ static void ilk_compute_wm_results(struct drm_device *dev, } /* LP0 register values */ - for_each_intel_crtc(dev, intel_crtc) { + for_each_intel_crtc(&dev_priv->drm, intel_crtc) { enum pipe pipe = intel_crtc->pipe; const struct intel_wm_level *r = &intel_crtc->wm.active.ilk.wm[0]; @@ -3415,11 +3409,12 @@ static void ilk_compute_wm_results(struct drm_device *dev, /* Find the result with the highest level enabled. Check for enable_fbc_wm in * case both are at the same level. Prefer r1 in case they're the same. */ -static struct intel_pipe_wm *ilk_find_best_result(struct drm_device *dev, - struct intel_pipe_wm *r1, - struct intel_pipe_wm *r2) +static struct intel_pipe_wm * +ilk_find_best_result(struct drm_i915_private *dev_priv, + struct intel_pipe_wm *r1, + struct intel_pipe_wm *r2) { - int level, max_level = ilk_wm_max_level(to_i915(dev)); + int level, max_level = ilk_wm_max_level(dev_priv); int level1 = 0, level2 = 0; for (level = 1; level <= max_level; level++) { @@ -3756,9 +3751,9 @@ bool intel_can_enable_sagv(struct drm_atomic_state *state) if (!intel_has_sagv(dev_priv)) return false; - if (IS_GEN9(dev_priv)) + if (IS_GEN(dev_priv, 9)) sagv_block_time_us = 30; - else if (IS_GEN10(dev_priv)) + else if (IS_GEN(dev_priv, 10)) sagv_block_time_us = 20; else sagv_block_time_us = 10; @@ -4306,102 +4301,6 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate, return total_data_rate; } -static uint16_t -skl_ddb_min_alloc(const struct drm_plane_state *pstate, const int plane) -{ - struct drm_framebuffer *fb = pstate->fb; - struct intel_plane_state *intel_pstate = to_intel_plane_state(pstate); - uint32_t src_w, src_h; - uint32_t min_scanlines = 8; - uint8_t plane_bpp; - - if (WARN_ON(!fb)) - return 0; - - /* For packed formats, and uv-plane, return 0 */ - if (plane == 1 && fb->format->format != DRM_FORMAT_NV12) - return 0; - - /* For Non Y-tile return 8-blocks */ - if (fb->modifier != I915_FORMAT_MOD_Y_TILED && - fb->modifier != I915_FORMAT_MOD_Yf_TILED && - fb->modifier != I915_FORMAT_MOD_Y_TILED_CCS && - fb->modifier != I915_FORMAT_MOD_Yf_TILED_CCS) - return 8; - - /* - * Src coordinates are already rotated by 270 degrees for - * the 90/270 degree plane rotation cases (to match the - * GTT mapping), hence no need to account for rotation here. - */ - src_w = drm_rect_width(&intel_pstate->base.src) >> 16; - src_h = drm_rect_height(&intel_pstate->base.src) >> 16; - - /* Halve UV plane width and height for NV12 */ - if (plane == 1) { - src_w /= 2; - src_h /= 2; - } - - plane_bpp = fb->format->cpp[plane]; - - if (drm_rotation_90_or_270(pstate->rotation)) { - switch (plane_bpp) { - case 1: - min_scanlines = 32; - break; - case 2: - min_scanlines = 16; - break; - case 4: - min_scanlines = 8; - break; - case 8: - min_scanlines = 4; - break; - default: - WARN(1, "Unsupported pixel depth %u for rotation", - plane_bpp); - min_scanlines = 32; - } - } - - return DIV_ROUND_UP((4 * src_w * plane_bpp), 512) * min_scanlines/4 + 3; -} - -static void -skl_ddb_calc_min(const struct intel_crtc_state *cstate, int num_active, - uint16_t *minimum, uint16_t *uv_minimum) -{ - const struct drm_plane_state *pstate; - struct drm_plane *plane; - - drm_atomic_crtc_state_for_each_plane_state(plane, pstate, &cstate->base) { - enum plane_id plane_id = to_intel_plane(plane)->id; - struct intel_plane_state *plane_state = to_intel_plane_state(pstate); - - if (plane_id == PLANE_CURSOR) - continue; - - /* slave plane must be invisible and calculated from master */ - if (!pstate->visible || WARN_ON(plane_state->slave)) - continue; - - if (!plane_state->linked_plane) { - minimum[plane_id] = skl_ddb_min_alloc(pstate, 0); - uv_minimum[plane_id] = skl_ddb_min_alloc(pstate, 1); - } else { - enum plane_id y_plane_id = - plane_state->linked_plane->id; - - minimum[y_plane_id] = skl_ddb_min_alloc(pstate, 0); - minimum[plane_id] = skl_ddb_min_alloc(pstate, 1); - } - } - - minimum[PLANE_CURSOR] = skl_cursor_allocation(num_active); -} - static int skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, struct skl_ddb_allocation *ddb /* out */) @@ -4411,15 +4310,17 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, struct drm_i915_private *dev_priv = to_i915(crtc->dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct skl_ddb_entry *alloc = &cstate->wm.skl.ddb; - uint16_t alloc_size, start; - uint16_t minimum[I915_MAX_PLANES] = {}; - uint16_t uv_minimum[I915_MAX_PLANES] = {}; + struct skl_plane_wm *wm; + uint16_t alloc_size, start = 0; + uint16_t total[I915_MAX_PLANES] = {}; + uint16_t uv_total[I915_MAX_PLANES] = {}; u64 total_data_rate; enum plane_id plane_id; int num_active; u64 plane_data_rate[I915_MAX_PLANES] = {}; u64 uv_plane_data_rate[I915_MAX_PLANES] = {}; - uint16_t total_min_blocks = 0; + uint16_t blocks = 0; + int level; /* Clear the partitioning for disabled planes. */ memset(cstate->wm.skl.plane_ddb_y, 0, sizeof(cstate->wm.skl.plane_ddb_y)); @@ -4449,81 +4350,135 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate, if (alloc_size == 0) return 0; - skl_ddb_calc_min(cstate, num_active, minimum, uv_minimum); + /* Allocate fixed number of blocks for cursor. */ + total[PLANE_CURSOR] = skl_cursor_allocation(num_active); + alloc_size -= total[PLANE_CURSOR]; + cstate->wm.skl.plane_ddb_y[PLANE_CURSOR].start = + alloc->end - total[PLANE_CURSOR]; + cstate->wm.skl.plane_ddb_y[PLANE_CURSOR].end = alloc->end; + + if (total_data_rate == 0) + return 0; /* - * 1. Allocate the mininum required blocks for each active plane - * and allocate the cursor, it doesn't require extra allocation - * proportional to the data rate. + * Find the highest watermark level for which we can satisfy the block + * requirement of active planes. */ + for (level = ilk_wm_max_level(dev_priv); level >= 0; level--) { + blocks = 0; + for_each_plane_id_on_crtc(intel_crtc, plane_id) { + if (plane_id == PLANE_CURSOR) + continue; - for_each_plane_id_on_crtc(intel_crtc, plane_id) { - total_min_blocks += minimum[plane_id]; - total_min_blocks += uv_minimum[plane_id]; + wm = &cstate->wm.skl.optimal.planes[plane_id]; + blocks += wm->wm[level].plane_res_b; + blocks += wm->uv_wm[level].plane_res_b; + } + + if (blocks < alloc_size) { + alloc_size -= blocks; + break; + } } - if (total_min_blocks > alloc_size) { + if (level < 0) { DRM_DEBUG_KMS("Requested display configuration exceeds system DDB limitations"); - DRM_DEBUG_KMS("minimum required %d/%d\n", total_min_blocks, - alloc_size); + DRM_DEBUG_KMS("minimum required %d/%d\n", blocks, + alloc_size); return -EINVAL; } - alloc_size -= total_min_blocks; - cstate->wm.skl.plane_ddb_y[PLANE_CURSOR].start = alloc->end - minimum[PLANE_CURSOR]; - cstate->wm.skl.plane_ddb_y[PLANE_CURSOR].end = alloc->end; - /* - * 2. Distribute the remaining space in proportion to the amount of - * data each plane needs to fetch from memory. - * - * FIXME: we may not allocate every single block here. + * Grant each plane the blocks it requires at the highest achievable + * watermark level, plus an extra share of the leftover blocks + * proportional to its relative data rate. */ - if (total_data_rate == 0) - return 0; - - start = alloc->start; for_each_plane_id_on_crtc(intel_crtc, plane_id) { - u64 data_rate, uv_data_rate; - uint16_t plane_blocks, uv_plane_blocks; + u64 rate; + u16 extra; if (plane_id == PLANE_CURSOR) continue; - data_rate = plane_data_rate[plane_id]; - /* - * allocation for (packed formats) or (uv-plane part of planar format): - * promote the expression to 64 bits to avoid overflowing, the - * result is < available as data_rate / total_data_rate < 1 + * We've accounted for all active planes; remaining planes are + * all disabled. */ - plane_blocks = minimum[plane_id]; - plane_blocks += div64_u64(alloc_size * data_rate, total_data_rate); + if (total_data_rate == 0) + break; - /* Leave disabled planes at (0,0) */ - if (data_rate) { - cstate->wm.skl.plane_ddb_y[plane_id].start = start; - cstate->wm.skl.plane_ddb_y[plane_id].end = start + plane_blocks; - } + wm = &cstate->wm.skl.optimal.planes[plane_id]; - start += plane_blocks; + rate = plane_data_rate[plane_id]; + extra = min_t(u16, alloc_size, + DIV64_U64_ROUND_UP(alloc_size * rate, + total_data_rate)); + total[plane_id] = wm->wm[level].plane_res_b + extra; + alloc_size -= extra; + total_data_rate -= rate; - /* Allocate DDB for UV plane for planar format/NV12 */ - uv_data_rate = uv_plane_data_rate[plane_id]; + if (total_data_rate == 0) + break; - uv_plane_blocks = uv_minimum[plane_id]; - uv_plane_blocks += div64_u64(alloc_size * uv_data_rate, total_data_rate); + rate = uv_plane_data_rate[plane_id]; + extra = min_t(u16, alloc_size, + DIV64_U64_ROUND_UP(alloc_size * rate, + total_data_rate)); + uv_total[plane_id] = wm->uv_wm[level].plane_res_b + extra; + alloc_size -= extra; + total_data_rate -= rate; + } + WARN_ON(alloc_size != 0 || total_data_rate != 0); + + /* Set the actual DDB start/end points for each plane */ + start = alloc->start; + for_each_plane_id_on_crtc(intel_crtc, plane_id) { + struct skl_ddb_entry *plane_alloc, *uv_plane_alloc; + + if (plane_id == PLANE_CURSOR) + continue; + + plane_alloc = &cstate->wm.skl.plane_ddb_y[plane_id]; + uv_plane_alloc = &cstate->wm.skl.plane_ddb_uv[plane_id]; /* Gen11+ uses a separate plane for UV watermarks */ - WARN_ON(INTEL_GEN(dev_priv) >= 11 && uv_plane_blocks); + WARN_ON(INTEL_GEN(dev_priv) >= 11 && uv_total[plane_id]); + + /* Leave disabled planes at (0,0) */ + if (total[plane_id]) { + plane_alloc->start = start; + start += total[plane_id]; + plane_alloc->end = start; + } - if (uv_data_rate) { - cstate->wm.skl.plane_ddb_uv[plane_id].start = start; - cstate->wm.skl.plane_ddb_uv[plane_id].end = - start + uv_plane_blocks; + if (uv_total[plane_id]) { + uv_plane_alloc->start = start; + start += uv_total[plane_id]; + uv_plane_alloc->end = start; } + } - start += uv_plane_blocks; + /* + * When we calculated watermark values we didn't know how high + * of a level we'd actually be able to hit, so we just marked + * all levels as "enabled." Go back now and disable the ones + * that aren't actually possible. + */ + for (level++; level <= ilk_wm_max_level(dev_priv); level++) { + for_each_plane_id_on_crtc(intel_crtc, plane_id) { + wm = &cstate->wm.skl.optimal.planes[plane_id]; + memset(&wm->wm[level], 0, sizeof(wm->wm[level])); + } + } + + /* + * Go back and disable the transition watermark if it turns out we + * don't have enough DDB blocks for it. + */ + for_each_plane_id_on_crtc(intel_crtc, plane_id) { + wm = &cstate->wm.skl.optimal.planes[plane_id]; + if (wm->trans_wm.plane_res_b > total[plane_id]) + memset(&wm->trans_wm, 0, sizeof(wm->trans_wm)); } return 0; @@ -4702,7 +4657,7 @@ skl_compute_plane_wm_params(const struct intel_crtc_state *cstate, wp->plane_blocks_per_line = div_fixed16(interm_pbpl, wp->y_min_scanlines); - } else if (wp->x_tiled && IS_GEN9(dev_priv)) { + } else if (wp->x_tiled && IS_GEN(dev_priv, 9)) { interm_pbpl = DIV_ROUND_UP(wp->plane_bytes_per_line, wp->dbuf_block_size); wp->plane_blocks_per_line = u32_to_fixed16(interm_pbpl); @@ -4720,17 +4675,15 @@ skl_compute_plane_wm_params(const struct intel_crtc_state *cstate, return 0; } -static int skl_compute_plane_wm(const struct intel_crtc_state *cstate, - const struct intel_plane_state *intel_pstate, - uint16_t ddb_allocation, - int level, - const struct skl_wm_params *wp, - const struct skl_wm_level *result_prev, - struct skl_wm_level *result /* out */) +static void skl_compute_plane_wm(const struct intel_crtc_state *cstate, + const struct intel_plane_state *intel_pstate, + int level, + const struct skl_wm_params *wp, + const struct skl_wm_level *result_prev, + struct skl_wm_level *result /* out */) { struct drm_i915_private *dev_priv = to_i915(intel_pstate->base.plane->dev); - const struct drm_plane_state *pstate = &intel_pstate->base; uint32_t latency = dev_priv->wm.skl_latency[level]; uint_fixed_16_16_t method1, method2; uint_fixed_16_16_t selected_result; @@ -4738,10 +4691,6 @@ static int skl_compute_plane_wm(const struct intel_crtc_state *cstate, struct intel_atomic_state *state = to_intel_atomic_state(cstate->base.state); bool apply_memory_bw_wa = skl_needs_memory_bw_wa(state); - uint32_t min_disp_buf_needed; - - if (latency == 0) - return level == 0 ? -EINVAL : 0; /* Display WA #1141: kbl,cfl */ if ((IS_KABYLAKE(dev_priv) || IS_COFFEELAKE(dev_priv) || @@ -4766,15 +4715,8 @@ static int skl_compute_plane_wm(const struct intel_crtc_state *cstate, wp->dbuf_block_size < 1) && (wp->plane_bytes_per_line / wp->dbuf_block_size < 1)) { selected_result = method2; - } else if (ddb_allocation >= - fixed16_to_u32_round_up(wp->plane_blocks_per_line)) { - if (IS_GEN9(dev_priv) && - !IS_GEMINILAKE(dev_priv)) - selected_result = min_fixed16(method1, method2); - else - selected_result = method2; } else if (latency >= wp->linetime_us) { - if (IS_GEN9(dev_priv) && + if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv)) selected_result = min_fixed16(method1, method2); else @@ -4788,85 +4730,51 @@ static int skl_compute_plane_wm(const struct intel_crtc_state *cstate, res_lines = div_round_up_fixed16(selected_result, wp->plane_blocks_per_line); - /* Display WA #1125: skl,bxt,kbl,glk */ - if (level == 0 && wp->rc_surface) - res_blocks += fixed16_to_u32_round_up(wp->y_tile_minimum); - - /* Display WA #1126: skl,bxt,kbl,glk */ - if (level >= 1 && level <= 7) { - if (wp->y_tiled) { - res_blocks += fixed16_to_u32_round_up( - wp->y_tile_minimum); - res_lines += wp->y_min_scanlines; - } else { - res_blocks++; - } - - /* - * Make sure result blocks for higher latency levels are atleast - * as high as level below the current level. - * Assumption in DDB algorithm optimization for special cases. - * Also covers Display WA #1125 for RC. - */ - if (result_prev->plane_res_b > res_blocks) - res_blocks = result_prev->plane_res_b; - } - - if (INTEL_GEN(dev_priv) >= 11) { - if (wp->y_tiled) { - uint32_t extra_lines; - uint_fixed_16_16_t fp_min_disp_buf_needed; - - if (res_lines % wp->y_min_scanlines == 0) - extra_lines = wp->y_min_scanlines; - else - extra_lines = wp->y_min_scanlines * 2 - - res_lines % wp->y_min_scanlines; - - fp_min_disp_buf_needed = mul_u32_fixed16(res_lines + - extra_lines, - wp->plane_blocks_per_line); - min_disp_buf_needed = fixed16_to_u32_round_up( - fp_min_disp_buf_needed); - } else { - min_disp_buf_needed = DIV_ROUND_UP(res_blocks * 11, 10); - } - } else { - min_disp_buf_needed = res_blocks; - } - - if ((level > 0 && res_lines > 31) || - res_blocks >= ddb_allocation || - min_disp_buf_needed >= ddb_allocation) { - /* - * If there are no valid level 0 watermarks, then we can't - * support this display configuration. - */ - if (level) { - return 0; - } else { - struct drm_plane *plane = pstate->plane; + if (IS_GEN9_BC(dev_priv) || IS_BROXTON(dev_priv)) { + /* Display WA #1125: skl,bxt,kbl */ + if (level == 0 && wp->rc_surface) + res_blocks += + fixed16_to_u32_round_up(wp->y_tile_minimum); + + /* Display WA #1126: skl,bxt,kbl */ + if (level >= 1 && level <= 7) { + if (wp->y_tiled) { + res_blocks += + fixed16_to_u32_round_up(wp->y_tile_minimum); + res_lines += wp->y_min_scanlines; + } else { + res_blocks++; + } - DRM_DEBUG_KMS("Requested display configuration exceeds system watermark limitations\n"); - DRM_DEBUG_KMS("[PLANE:%d:%s] blocks required = %u/%u, lines required = %u/31\n", - plane->base.id, plane->name, - res_blocks, ddb_allocation, res_lines); - return -EINVAL; + /* + * Make sure result blocks for higher latency levels are + * atleast as high as level below the current level. + * Assumption in DDB algorithm optimization for special + * cases. Also covers Display WA #1125 for RC. + */ + if (result_prev->plane_res_b > res_blocks) + res_blocks = result_prev->plane_res_b; } } /* The number of lines are ignored for the level 0 watermark. */ + if (level > 0 && res_lines > 31) + return; + + /* + * If res_lines is valid, assume we can use this watermark level + * for now. We'll come back and disable it after we calculate the + * DDB allocation if it turns out we don't actually have enough + * blocks to satisfy it. + */ result->plane_res_b = res_blocks; result->plane_res_l = res_lines; result->plane_en = true; - - return 0; } -static int +static void skl_compute_wm_levels(const struct intel_crtc_state *cstate, const struct intel_plane_state *intel_pstate, - uint16_t ddb_blocks, const struct skl_wm_params *wm_params, struct skl_wm_level *levels) { @@ -4874,25 +4782,15 @@ skl_compute_wm_levels(const struct intel_crtc_state *cstate, to_i915(intel_pstate->base.plane->dev); int level, max_level = ilk_wm_max_level(dev_priv); struct skl_wm_level *result_prev = &levels[0]; - int ret; for (level = 0; level <= max_level; level++) { struct skl_wm_level *result = &levels[level]; - ret = skl_compute_plane_wm(cstate, - intel_pstate, - ddb_blocks, - level, - wm_params, - result_prev, - result); - if (ret) - return ret; + skl_compute_plane_wm(cstate, intel_pstate, level, wm_params, + result_prev, result); result_prev = result; } - - return 0; } static uint32_t @@ -4920,8 +4818,7 @@ skl_compute_linetime_wm(const struct intel_crtc_state *cstate) static void skl_compute_transition_wm(const struct intel_crtc_state *cstate, const struct skl_wm_params *wp, - struct skl_plane_wm *wm, - uint16_t ddb_allocation) + struct skl_plane_wm *wm) { struct drm_device *dev = cstate->base.crtc->dev; const struct drm_i915_private *dev_priv = to_i915(dev); @@ -4969,12 +4866,13 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *cstate, } - res_blocks += 1; - - if (res_blocks < ddb_allocation) { - wm->trans_wm.plane_res_b = res_blocks; - wm->trans_wm.plane_en = true; - } + /* + * Just assume we can enable the transition watermark. After + * computing the DDB we'll come back and disable it if that + * assumption turns out to be false. + */ + wm->trans_wm.plane_res_b = res_blocks + 1; + wm->trans_wm.plane_en = true; } static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state, @@ -4982,7 +4880,6 @@ static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state, enum plane_id plane_id, int color_plane) { struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id]; - u16 ddb_blocks = skl_ddb_entry_size(&crtc_state->wm.skl.plane_ddb_y[plane_id]); struct skl_wm_params wm_params; int ret; @@ -4991,12 +4888,8 @@ static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state, if (ret) return ret; - ret = skl_compute_wm_levels(crtc_state, plane_state, - ddb_blocks, &wm_params, wm->wm); - if (ret) - return ret; - - skl_compute_transition_wm(crtc_state, &wm_params, wm, ddb_blocks); + skl_compute_wm_levels(crtc_state, plane_state, &wm_params, wm->wm); + skl_compute_transition_wm(crtc_state, &wm_params, wm); return 0; } @@ -5006,7 +4899,6 @@ static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state, enum plane_id plane_id) { struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id]; - u16 ddb_blocks = skl_ddb_entry_size(&crtc_state->wm.skl.plane_ddb_uv[plane_id]); struct skl_wm_params wm_params; int ret; @@ -5018,10 +4910,7 @@ static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state, if (ret) return ret; - ret = skl_compute_wm_levels(crtc_state, plane_state, - ddb_blocks, &wm_params, wm->uv_wm); - if (ret) - return ret; + skl_compute_wm_levels(crtc_state, plane_state, &wm_params, wm->uv_wm); return 0; } @@ -5251,15 +5140,14 @@ bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb, return false; } -static int skl_update_pipe_wm(struct drm_crtc_state *cstate, +static int skl_update_pipe_wm(struct intel_crtc_state *cstate, const struct skl_pipe_wm *old_pipe_wm, struct skl_pipe_wm *pipe_wm, /* out */ bool *changed /* out */) { - struct intel_crtc_state *intel_cstate = to_intel_crtc_state(cstate); int ret; - ret = skl_build_pipe_wm(intel_cstate, pipe_wm); + ret = skl_build_pipe_wm(cstate, pipe_wm); if (ret) return ret; @@ -5272,14 +5160,14 @@ static int skl_update_pipe_wm(struct drm_crtc_state *cstate, } static uint32_t -pipes_modified(struct drm_atomic_state *state) +pipes_modified(struct intel_atomic_state *state) { - struct drm_crtc *crtc; - struct drm_crtc_state *cstate; + struct intel_crtc *crtc; + struct intel_crtc_state *cstate; uint32_t i, ret = 0; - for_each_new_crtc_in_state(state, crtc, cstate, i) - ret |= drm_crtc_mask(crtc); + for_each_new_intel_crtc_in_state(state, crtc, cstate, i) + ret |= drm_crtc_mask(&crtc->base); return ret; } @@ -5314,11 +5202,10 @@ skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state, } static int -skl_compute_ddb(struct drm_atomic_state *state) +skl_compute_ddb(struct intel_atomic_state *state) { - const struct drm_i915_private *dev_priv = to_i915(state->dev); - struct intel_atomic_state *intel_state = to_intel_atomic_state(state); - struct skl_ddb_allocation *ddb = &intel_state->wm_results.ddb; + const struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct skl_ddb_allocation *ddb = &state->wm_results.ddb; struct intel_crtc_state *old_crtc_state; struct intel_crtc_state *new_crtc_state; struct intel_crtc *crtc; @@ -5326,7 +5213,7 @@ skl_compute_ddb(struct drm_atomic_state *state) memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb)); - for_each_oldnew_intel_crtc_in_state(intel_state, crtc, old_crtc_state, + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { ret = skl_allocate_pipe_ddb(new_crtc_state, ddb); if (ret) @@ -5372,14 +5259,12 @@ skl_print_wm_changes(struct intel_atomic_state *state) } static int -skl_ddb_add_affected_pipes(struct drm_atomic_state *state, bool *changed) +skl_ddb_add_affected_pipes(struct intel_atomic_state *state, bool *changed) { - struct drm_device *dev = state->dev; + struct drm_device *dev = state->base.dev; const struct drm_i915_private *dev_priv = to_i915(dev); - const struct drm_crtc *crtc; - const struct drm_crtc_state *cstate; - struct intel_crtc *intel_crtc; - struct intel_atomic_state *intel_state = to_intel_atomic_state(state); + struct intel_crtc *crtc; + struct intel_crtc_state *crtc_state; uint32_t realloc_pipes = pipes_modified(state); int ret, i; @@ -5398,7 +5283,7 @@ skl_ddb_add_affected_pipes(struct drm_atomic_state *state, bool *changed) * since any racing commits that want to update them would need to * hold _all_ CRTC state mutexes. */ - for_each_new_crtc_in_state(state, crtc, cstate, i) + for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) (*changed) = true; if (!*changed) @@ -5412,20 +5297,20 @@ skl_ddb_add_affected_pipes(struct drm_atomic_state *state, bool *changed) */ if (dev_priv->wm.distrust_bios_wm) { ret = drm_modeset_lock(&dev->mode_config.connection_mutex, - state->acquire_ctx); + state->base.acquire_ctx); if (ret) return ret; - intel_state->active_pipe_changes = ~0; + state->active_pipe_changes = ~0; /* - * We usually only initialize intel_state->active_crtcs if we + * We usually only initialize state->active_crtcs if we * we're doing a modeset; make sure this field is always * initialized during the sanitization process that happens * on the first commit too. */ - if (!intel_state->modeset) - intel_state->active_crtcs = dev_priv->active_crtcs; + if (!state->modeset) + state->active_crtcs = dev_priv->active_crtcs; } /* @@ -5441,21 +5326,19 @@ skl_ddb_add_affected_pipes(struct drm_atomic_state *state, bool *changed) * any other display updates race with this transaction, so we need * to grab the lock on *all* CRTC's. */ - if (intel_state->active_pipe_changes || intel_state->modeset) { + if (state->active_pipe_changes || state->modeset) { realloc_pipes = ~0; - intel_state->wm_results.dirty_pipes = ~0; + state->wm_results.dirty_pipes = ~0; } /* * We're not recomputing for the pipes not included in the commit, so * make sure we start with the current state. */ - for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) { - struct intel_crtc_state *cstate; - - cstate = intel_atomic_get_crtc_state(state, intel_crtc); - if (IS_ERR(cstate)) - return PTR_ERR(cstate); + for_each_intel_crtc_mask(dev, crtc, realloc_pipes) { + crtc_state = intel_atomic_get_crtc_state(&state->base, crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); } return 0; @@ -5522,12 +5405,12 @@ static int skl_wm_add_affected_planes(struct intel_atomic_state *state, } static int -skl_compute_wm(struct drm_atomic_state *state) +skl_compute_wm(struct intel_atomic_state *state) { - struct drm_crtc *crtc; - struct drm_crtc_state *cstate; - struct intel_atomic_state *intel_state = to_intel_atomic_state(state); - struct skl_ddb_values *results = &intel_state->wm_results; + struct intel_crtc *crtc; + struct intel_crtc_state *cstate; + struct intel_crtc_state *old_crtc_state; + struct skl_ddb_values *results = &state->wm_results; struct skl_pipe_wm *pipe_wm; bool changed = false; int ret, i; @@ -5539,47 +5422,35 @@ skl_compute_wm(struct drm_atomic_state *state) if (ret || !changed) return ret; - ret = skl_compute_ddb(state); - if (ret) - return ret; - /* * Calculate WM's for all pipes that are part of this transaction. - * Note that the DDB allocation above may have added more CRTC's that + * Note that skl_ddb_add_affected_pipes may have added more CRTC's that * weren't otherwise being modified (and set bits in dirty_pipes) if * pipe allocations had to change. - * - * FIXME: Now that we're doing this in the atomic check phase, we - * should allow skl_update_pipe_wm() to return failure in cases where - * no suitable watermark values can be found. */ - for_each_new_crtc_in_state(state, crtc, cstate, i) { - struct intel_crtc_state *intel_cstate = - to_intel_crtc_state(cstate); + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, + cstate, i) { const struct skl_pipe_wm *old_pipe_wm = - &to_intel_crtc_state(crtc->state)->wm.skl.optimal; + &old_crtc_state->wm.skl.optimal; - pipe_wm = &intel_cstate->wm.skl.optimal; + pipe_wm = &cstate->wm.skl.optimal; ret = skl_update_pipe_wm(cstate, old_pipe_wm, pipe_wm, &changed); if (ret) return ret; - ret = skl_wm_add_affected_planes(intel_state, - to_intel_crtc(crtc)); + ret = skl_wm_add_affected_planes(state, crtc); if (ret) return ret; if (changed) - results->dirty_pipes |= drm_crtc_mask(crtc); - - if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0) - /* This pipe's WM's did not change */ - continue; - - intel_cstate->update_wm_pre = true; + results->dirty_pipes |= drm_crtc_mask(&crtc->base); } - skl_print_wm_changes(intel_state); + ret = skl_compute_ddb(state); + if (ret) + return ret; + + skl_print_wm_changes(state); return 0; } @@ -5617,13 +5488,13 @@ static void skl_initial_wm(struct intel_atomic_state *state, mutex_unlock(&dev_priv->wm.wm_mutex); } -static void ilk_compute_wm_config(struct drm_device *dev, +static void ilk_compute_wm_config(struct drm_i915_private *dev_priv, struct intel_wm_config *config) { struct intel_crtc *crtc; /* Compute the currently _active_ config */ - for_each_intel_crtc(dev, crtc) { + for_each_intel_crtc(&dev_priv->drm, crtc) { const struct intel_pipe_wm *wm = &crtc->wm.active.ilk; if (!wm->pipe_enabled) @@ -5637,25 +5508,24 @@ static void ilk_compute_wm_config(struct drm_device *dev, static void ilk_program_watermarks(struct drm_i915_private *dev_priv) { - struct drm_device *dev = &dev_priv->drm; struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; struct ilk_wm_maximums max; struct intel_wm_config config = {}; struct ilk_wm_values results = {}; enum intel_ddb_partitioning partitioning; - ilk_compute_wm_config(dev, &config); + ilk_compute_wm_config(dev_priv, &config); - ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_1_2, &max); - ilk_wm_merge(dev, &config, &max, &lp_wm_1_2); + ilk_compute_wm_maximums(dev_priv, 1, &config, INTEL_DDB_PART_1_2, &max); + ilk_wm_merge(dev_priv, &config, &max, &lp_wm_1_2); /* 5/6 split only in single pipe config on IVB+ */ if (INTEL_GEN(dev_priv) >= 7 && config.num_pipes_active == 1 && config.sprites_enabled) { - ilk_compute_wm_maximums(dev, 1, &config, INTEL_DDB_PART_5_6, &max); - ilk_wm_merge(dev, &config, &max, &lp_wm_5_6); + ilk_compute_wm_maximums(dev_priv, 1, &config, INTEL_DDB_PART_5_6, &max); + ilk_wm_merge(dev_priv, &config, &max, &lp_wm_5_6); - best_lp_wm = ilk_find_best_result(dev, &lp_wm_1_2, &lp_wm_5_6); + best_lp_wm = ilk_find_best_result(dev_priv, &lp_wm_1_2, &lp_wm_5_6); } else { best_lp_wm = &lp_wm_1_2; } @@ -5663,7 +5533,7 @@ static void ilk_program_watermarks(struct drm_i915_private *dev_priv) partitioning = (best_lp_wm == &lp_wm_1_2) ? INTEL_DDB_PART_1_2 : INTEL_DDB_PART_5_6; - ilk_compute_wm_results(dev, best_lp_wm, partitioning, &results); + ilk_compute_wm_results(dev_priv, best_lp_wm, partitioning, &results); ilk_write_wm_values(dev_priv, &results); } @@ -5703,19 +5573,18 @@ static inline void skl_wm_level_from_reg_val(uint32_t val, PLANE_WM_LINES_MASK; } -void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc, +void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc, struct skl_pipe_wm *out) { - struct drm_i915_private *dev_priv = to_i915(crtc->dev); - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - enum pipe pipe = intel_crtc->pipe; + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + enum pipe pipe = crtc->pipe; int level, max_level; enum plane_id plane_id; uint32_t val; max_level = ilk_wm_max_level(dev_priv); - for_each_plane_id_on_crtc(intel_crtc, plane_id) { + for_each_plane_id_on_crtc(crtc, plane_id) { struct skl_plane_wm *wm = &out->planes[plane_id]; for (level = 0; level <= max_level; level++) { @@ -5735,30 +5604,27 @@ void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc, skl_wm_level_from_reg_val(val, &wm->trans_wm); } - if (!intel_crtc->active) + if (!crtc->active) return; out->linetime = I915_READ(PIPE_WM_LINETIME(pipe)); } -void skl_wm_get_hw_state(struct drm_device *dev) +void skl_wm_get_hw_state(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = to_i915(dev); struct skl_ddb_values *hw = &dev_priv->wm.skl_hw; struct skl_ddb_allocation *ddb = &dev_priv->wm.skl_hw.ddb; - struct drm_crtc *crtc; - struct intel_crtc *intel_crtc; + struct intel_crtc *crtc; struct intel_crtc_state *cstate; skl_ddb_get_hw_state(dev_priv, ddb); - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - intel_crtc = to_intel_crtc(crtc); - cstate = to_intel_crtc_state(crtc->state); + for_each_intel_crtc(&dev_priv->drm, crtc) { + cstate = to_intel_crtc_state(crtc->base.state); skl_pipe_wm_get_hw_state(crtc, &cstate->wm.skl.optimal); - if (intel_crtc->active) - hw->dirty_pipes |= drm_crtc_mask(crtc); + if (crtc->active) + hw->dirty_pipes |= drm_crtc_mask(&crtc->base); } if (dev_priv->active_crtcs) { @@ -5767,15 +5633,14 @@ void skl_wm_get_hw_state(struct drm_device *dev) } } -static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc) +static void ilk_pipe_wm_get_hw_state(struct intel_crtc *crtc) { - struct drm_device *dev = crtc->dev; + struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = to_i915(dev); struct ilk_wm_values *hw = &dev_priv->wm.hw; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state); + struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->base.state); struct intel_pipe_wm *active = &cstate->wm.ilk.optimal; - enum pipe pipe = intel_crtc->pipe; + enum pipe pipe = crtc->pipe; static const i915_reg_t wm0_pipe_reg[] = { [PIPE_A] = WM0_PIPEA_ILK, [PIPE_B] = WM0_PIPEB_ILK, @@ -5788,7 +5653,7 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc) memset(active, 0, sizeof(*active)); - active->pipe_enabled = intel_crtc->active; + active->pipe_enabled = crtc->active; if (active->pipe_enabled) { u32 tmp = hw->wm_pipe[pipe]; @@ -5816,7 +5681,7 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc) active->wm[level].enable = true; } - intel_crtc->wm.active.ilk = *active; + crtc->wm.active.ilk = *active; } #define _FW_WM(value, plane) \ @@ -5926,9 +5791,8 @@ static void vlv_read_wm_values(struct drm_i915_private *dev_priv, #undef _FW_WM #undef _FW_WM_VLV -void g4x_wm_get_hw_state(struct drm_device *dev) +void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = to_i915(dev); struct g4x_wm_values *wm = &dev_priv->wm.g4x; struct intel_crtc *crtc; @@ -5936,7 +5800,7 @@ void g4x_wm_get_hw_state(struct drm_device *dev) wm->cxsr = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; - for_each_intel_crtc(dev, crtc) { + for_each_intel_crtc(&dev_priv->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct g4x_wm_state *active = &crtc->wm.active.g4x; @@ -6067,9 +5931,8 @@ void g4x_wm_sanitize(struct drm_i915_private *dev_priv) mutex_unlock(&dev_priv->wm.wm_mutex); } -void vlv_wm_get_hw_state(struct drm_device *dev) +void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = to_i915(dev); struct vlv_wm_values *wm = &dev_priv->wm.vlv; struct intel_crtc *crtc; u32 val; @@ -6113,7 +5976,7 @@ void vlv_wm_get_hw_state(struct drm_device *dev) mutex_unlock(&dev_priv->pcu_lock); } - for_each_intel_crtc(dev, crtc) { + for_each_intel_crtc(&dev_priv->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct vlv_wm_state *active = &crtc->wm.active.vlv; @@ -6230,15 +6093,14 @@ static void ilk_init_lp_watermarks(struct drm_i915_private *dev_priv) */ } -void ilk_wm_get_hw_state(struct drm_device *dev) +void ilk_wm_get_hw_state(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = to_i915(dev); struct ilk_wm_values *hw = &dev_priv->wm.hw; - struct drm_crtc *crtc; + struct intel_crtc *crtc; ilk_init_lp_watermarks(dev_priv); - for_each_crtc(dev, crtc) + for_each_intel_crtc(&dev_priv->drm, crtc) ilk_pipe_wm_get_hw_state(crtc); hw->wm_lp[0] = I915_READ(WM1_LP_ILK); @@ -7049,7 +6911,7 @@ static void gen9_enable_rps(struct drm_i915_private *dev_priv) intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL); /* Program defaults and thresholds for RPS */ - if (IS_GEN9(dev_priv)) + if (IS_GEN(dev_priv, 9)) I915_WRITE(GEN6_RC_VIDEO_FREQ, GEN9_FREQUENCY(dev_priv->gt_pm.rps.rp1_freq)); @@ -7285,9 +7147,9 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv) rc6vids = 0; ret = sandybridge_pcode_read(dev_priv, GEN6_PCODE_READ_RC6VIDS, &rc6vids); - if (IS_GEN6(dev_priv) && ret) { + if (IS_GEN(dev_priv, 6) && ret) { DRM_DEBUG_DRIVER("Couldn't check for BIOS workaround\n"); - } else if (IS_GEN6(dev_priv) && (GEN6_DECODE_RC6_VID(rc6vids & 0xff) < 450)) { + } else if (IS_GEN(dev_priv, 6) && (GEN6_DECODE_RC6_VID(rc6vids & 0xff) < 450)) { DRM_DEBUG_DRIVER("You should update your BIOS. Correcting minimum rc6 voltage (%dmV->%dmV)\n", GEN6_DECODE_RC6_VID(rc6vids & 0xff), 450); rc6vids &= 0xffff00; @@ -7412,7 +7274,7 @@ static int cherryview_rps_max_freq(struct drm_i915_private *dev_priv) val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE); - switch (INTEL_INFO(dev_priv)->sseu.eu_total) { + switch (RUNTIME_INFO(dev_priv)->sseu.eu_total) { case 8: /* (2 * 4) config */ rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS4EU_FUSE_SHIFT); @@ -7987,7 +7849,7 @@ unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) { unsigned long val; - if (!IS_GEN5(dev_priv)) + if (!IS_GEN(dev_priv, 5)) return 0; spin_lock_irq(&mchdev_lock); @@ -8071,7 +7933,7 @@ static void __i915_update_gfx_val(struct drm_i915_private *dev_priv) void i915_update_gfx_val(struct drm_i915_private *dev_priv) { - if (!IS_GEN5(dev_priv)) + if (!IS_GEN(dev_priv, 5)) return; spin_lock_irq(&mchdev_lock); @@ -8122,7 +7984,7 @@ unsigned long i915_gfx_val(struct drm_i915_private *dev_priv) { unsigned long val; - if (!IS_GEN5(dev_priv)) + if (!IS_GEN(dev_priv, 5)) return 0; spin_lock_irq(&mchdev_lock); @@ -8410,7 +8272,7 @@ void intel_init_gt_powersave(struct drm_i915_private *dev_priv) intel_freq_opcode(dev_priv, 450)); /* After setting max-softlimit, find the overclock max freq */ - if (IS_GEN6(dev_priv) || + if (IS_GEN(dev_priv, 6) || IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv)) { u32 params = 0; @@ -9480,9 +9342,9 @@ void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv) dev_priv->display.init_clock_gating = ivb_init_clock_gating; else if (IS_VALLEYVIEW(dev_priv)) dev_priv->display.init_clock_gating = vlv_init_clock_gating; - else if (IS_GEN6(dev_priv)) + else if (IS_GEN(dev_priv, 6)) dev_priv->display.init_clock_gating = gen6_init_clock_gating; - else if (IS_GEN5(dev_priv)) + else if (IS_GEN(dev_priv, 5)) dev_priv->display.init_clock_gating = ilk_init_clock_gating; else if (IS_G4X(dev_priv)) dev_priv->display.init_clock_gating = g4x_init_clock_gating; @@ -9490,11 +9352,11 @@ void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv) dev_priv->display.init_clock_gating = i965gm_init_clock_gating; else if (IS_I965G(dev_priv)) dev_priv->display.init_clock_gating = i965g_init_clock_gating; - else if (IS_GEN3(dev_priv)) + else if (IS_GEN(dev_priv, 3)) dev_priv->display.init_clock_gating = gen3_init_clock_gating; else if (IS_I85X(dev_priv) || IS_I865G(dev_priv)) dev_priv->display.init_clock_gating = i85x_init_clock_gating; - else if (IS_GEN2(dev_priv)) + else if (IS_GEN(dev_priv, 2)) dev_priv->display.init_clock_gating = i830_init_clock_gating; else { MISSING_CASE(INTEL_DEVID(dev_priv)); @@ -9508,7 +9370,7 @@ void intel_init_pm(struct drm_i915_private *dev_priv) /* For cxsr */ if (IS_PINEVIEW(dev_priv)) i915_pineview_get_mem_freq(dev_priv); - else if (IS_GEN5(dev_priv)) + else if (IS_GEN(dev_priv, 5)) i915_ironlake_get_mem_freq(dev_priv); /* For FIFO watermark updates */ @@ -9520,9 +9382,9 @@ void intel_init_pm(struct drm_i915_private *dev_priv) } else if (HAS_PCH_SPLIT(dev_priv)) { ilk_setup_wm_latency(dev_priv); - if ((IS_GEN5(dev_priv) && dev_priv->wm.pri_latency[1] && + if ((IS_GEN(dev_priv, 5) && dev_priv->wm.pri_latency[1] && dev_priv->wm.spr_latency[1] && dev_priv->wm.cur_latency[1]) || - (!IS_GEN5(dev_priv) && dev_priv->wm.pri_latency[0] && + (!IS_GEN(dev_priv, 5) && dev_priv->wm.pri_latency[0] && dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) { dev_priv->display.compute_pipe_wm = ilk_compute_pipe_wm; dev_priv->display.compute_intermediate_wm = @@ -9563,12 +9425,12 @@ void intel_init_pm(struct drm_i915_private *dev_priv) dev_priv->display.update_wm = NULL; } else dev_priv->display.update_wm = pineview_update_wm; - } else if (IS_GEN4(dev_priv)) { + } else if (IS_GEN(dev_priv, 4)) { dev_priv->display.update_wm = i965_update_wm; - } else if (IS_GEN3(dev_priv)) { + } else if (IS_GEN(dev_priv, 3)) { dev_priv->display.update_wm = i9xx_update_wm; dev_priv->display.get_fifo_size = i9xx_get_fifo_size; - } else if (IS_GEN2(dev_priv)) { + } else if (IS_GEN(dev_priv, 2)) { if (INTEL_INFO(dev_priv)->num_pipes == 1) { dev_priv->display.update_wm = i845_update_wm; dev_priv->display.get_fifo_size = i845_get_fifo_size; |