diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9c435f905c8ecbc25b4eb48933cbaa52632b4cfa..1800ff3bc726cec4659828c8827d81e0dcdc27ae 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6944,6 +6944,16 @@ static void icl_pipe_mbus_enable(struct intel_crtc *crtc) intel_de_write(dev_priv, PIPE_MBUS_DBOX_CTL(pipe), val); } +static void hsw_set_linetime_wm(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + + intel_de_write(dev_priv, WM_LINETIME(crtc->pipe), + HSW_LINETIME(crtc_state->linetime) | + HSW_IPS_LINETIME(crtc_state->ips_linetime)); +} + static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); @@ -7025,6 +7035,8 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, if (INTEL_GEN(dev_priv) < 9) intel_disable_primary_plane(new_crtc_state); + hsw_set_linetime_wm(new_crtc_state); + if (INTEL_GEN(dev_priv) >= 11) icl_set_pipe_chicken(crtc); @@ -11064,6 +11076,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, enum intel_display_power_domain power_domain; u64 power_domain_mask; bool active; + u32 tmp; pipe_config->master_transcoder = INVALID_TRANSCODER; @@ -11130,8 +11143,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, PIPE_CSC_MODE(crtc->pipe)); if (INTEL_GEN(dev_priv) >= 9) { - u32 tmp = intel_de_read(dev_priv, - SKL_BOTTOM_COLOR(crtc->pipe)); + tmp = intel_de_read(dev_priv, SKL_BOTTOM_COLOR(crtc->pipe)); if (tmp & SKL_BOTTOM_COLOR_GAMMA_ENABLE) pipe_config->gamma_enable = true; @@ -11144,6 +11156,12 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, intel_color_get_config(pipe_config); + tmp = intel_de_read(dev_priv, WM_LINETIME(crtc->pipe)); + pipe_config->linetime = REG_FIELD_GET(HSW_LINETIME_MASK, tmp); + if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) + pipe_config->ips_linetime = + REG_FIELD_GET(HSW_IPS_LINETIME_MASK, tmp); + power_domain = POWER_DOMAIN_PIPE_PANEL_FITTER(crtc->pipe); WARN_ON(power_domain_mask & BIT_ULL(power_domain)); @@ -12652,6 +12670,53 @@ static int icl_compute_port_sync_crtc_state(struct drm_connector *connector, return 0; } +static u16 hsw_linetime_wm(const struct intel_crtc_state *crtc_state) +{ + const struct drm_display_mode *adjusted_mode = + &crtc_state->hw.adjusted_mode; + + if (!crtc_state->hw.enable) + return 0; + + return DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8, + adjusted_mode->crtc_clock); +} + +static u16 hsw_ips_linetime_wm(const struct intel_crtc_state *crtc_state) +{ + const struct intel_atomic_state *state = + to_intel_atomic_state(crtc_state->uapi.state); + const struct drm_display_mode *adjusted_mode = + &crtc_state->hw.adjusted_mode; + + if (!crtc_state->hw.enable) + return 0; + + return DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8, + state->cdclk.logical.cdclk); +} + +static u16 skl_linetime_wm(const struct intel_crtc_state *crtc_state) +{ + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + const struct drm_display_mode *adjusted_mode = + &crtc_state->hw.adjusted_mode; + u16 linetime_wm; + + if (!crtc_state->hw.enable) + return 0; + + linetime_wm = DIV_ROUND_UP(adjusted_mode->crtc_htotal * 1000 * 8, + crtc_state->pixel_rate); + + /* Display WA #1135: BXT:ALL GLK:ALL */ + if (IS_GEN9_LP(dev_priv) && dev_priv->ipc_enabled) + linetime_wm /= 2; + + return linetime_wm; +} + static int intel_crtc_atomic_check(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -12725,6 +12790,14 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state, if (HAS_IPS(dev_priv)) crtc_state->ips_enabled = hsw_compute_ips_config(crtc_state); + if (INTEL_GEN(dev_priv) >= 9) { + crtc_state->linetime = skl_linetime_wm(crtc_state); + } else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) { + crtc_state->linetime = hsw_linetime_wm(crtc_state); + if (hsw_crtc_supports_ips(crtc)) + crtc_state->ips_linetime = hsw_ips_linetime_wm(crtc_state); + } + return ret; } @@ -13029,6 +13102,9 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config, pipe_config->pipe_src_w, pipe_config->pipe_src_h, pipe_config->pixel_rate); + drm_dbg_kms(&dev_priv->drm, "linetime: %d, ips linetime: %d\n", + pipe_config->linetime, pipe_config->ips_linetime); + if (INTEL_GEN(dev_priv) >= 9) drm_dbg_kms(&dev_priv->drm, "num_scalers: %d, scaler_users: 0x%x, scaler_id: %d\n", @@ -13812,10 +13888,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_BOOL(gamma_enable); PIPE_CONF_CHECK_BOOL(csc_enable); + PIPE_CONF_CHECK_I(linetime); + PIPE_CONF_CHECK_I(ips_linetime); + bp_gamma = intel_color_get_gamma_bit_precision(pipe_config); if (bp_gamma) PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, hw.gamma_lut, bp_gamma); - } PIPE_CONF_CHECK_BOOL(double_wide); @@ -14986,6 +15064,18 @@ static void intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state, ilk_pfit_disable(old_crtc_state); } + /* + * The register is supposedly single buffered so perhaps + * not 100% correct to do this here. But SKL+ calculate + * this based on the adjust pixel rate so pfit changes do + * affect it and so it must be updated for fastsets. + * HSW/BDW only really need this here for fastboot, after + * that the value should not change without a full modeset. + */ + if (INTEL_GEN(dev_priv) >= 9 || + IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) + hsw_set_linetime_wm(new_crtc_state); + if (INTEL_GEN(dev_priv) >= 11) icl_set_pipe_chicken(crtc); } diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index baca171b74db2173868457bdd8677228e71b6e2f..a4ff025daa5a8c6c837773bc2d105c367a7b5049 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -663,8 +663,6 @@ struct intel_crtc_scaler_state { struct intel_pipe_wm { struct intel_wm_level wm[5]; - u16 linetime; - u16 ips_linetime; bool fbc_wm_enabled; bool pipe_enabled; bool sprites_enabled; @@ -680,7 +678,6 @@ struct skl_plane_wm { struct skl_pipe_wm { struct skl_plane_wm planes[I915_MAX_PLANES]; - u32 linetime; }; enum vlv_wm_level { @@ -1051,6 +1048,10 @@ struct intel_crtc_state { struct drm_dsc_config config; } dsc; + /* HSW+ linetime watermarks */ + u16 linetime; + u16 ips_linetime; + /* Forward Error correction State */ bool fec_enable; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a8a08c63278e0e3fdf303735c695228daef2c0cc..f837929039e82da15840fd109ef95165964b3ecc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -742,7 +742,6 @@ struct ilk_wm_values { u32 wm_pipe[3]; u32 wm_lp[3]; u32 wm_lp_spr[3]; - u32 wm_linetime[3]; bool enable_fbc_wm; enum intel_ddb_partitioning partitioning; }; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index c4adce6c1540e38bed53e1f40cd85f2d6848cec8..8e6763c1dccdcca2e92895f51437ce5885bf8a92 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2810,34 +2810,6 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, result->enable = true; } -static u32 -hsw_linetime_wm(const struct intel_crtc_state *crtc_state) -{ - const struct drm_display_mode *adjusted_mode = - &crtc_state->hw.adjusted_mode; - - if (!crtc_state->hw.active) - return 0; - - return DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8, - adjusted_mode->crtc_clock); -} - -static u32 -hsw_ips_linetime_wm(const struct intel_crtc_state *crtc_state) -{ - const struct intel_atomic_state *state = - to_intel_atomic_state(crtc_state->uapi.state); - const struct drm_display_mode *adjusted_mode = - &crtc_state->hw.adjusted_mode; - - if (!crtc_state->hw.active) - return 0; - - return DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8, - state->cdclk.logical.cdclk); -} - static void intel_read_wm_latency(struct drm_i915_private *dev_priv, u16 wm[8]) { @@ -3178,11 +3150,6 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state) ilk_compute_wm_level(dev_priv, intel_crtc, 0, crtc_state, pristate, sprstate, curstate, &pipe_wm->wm[0]); - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { - pipe_wm->linetime = hsw_linetime_wm(crtc_state); - pipe_wm->ips_linetime = hsw_ips_linetime_wm(crtc_state); - } - if (!ilk_validate_pipe_wm(dev_priv, pipe_wm)) return -EINVAL; @@ -3433,9 +3400,6 @@ static void ilk_compute_wm_results(struct drm_i915_private *dev_priv, if (drm_WARN_ON(&dev_priv->drm, !r->enable)) continue; - results->wm_linetime[pipe] = - HSW_LINETIME(pipe_wm->linetime) | - HSW_IPS_LINETIME(pipe_wm->ips_linetime); results->wm_pipe[pipe] = (r->pri_val << WM0_PIPE_PLANE_SHIFT) | @@ -3475,7 +3439,6 @@ ilk_find_best_result(struct drm_i915_private *dev_priv, /* dirty bits used to track which watermarks need changes */ #define WM_DIRTY_PIPE(pipe) (1 << (pipe)) -#define WM_DIRTY_LINETIME(pipe) (1 << (8 + (pipe))) #define WM_DIRTY_LP(wm_lp) (1 << (15 + (wm_lp))) #define WM_DIRTY_LP_ALL (WM_DIRTY_LP(1) | WM_DIRTY_LP(2) | WM_DIRTY_LP(3)) #define WM_DIRTY_FBC (1 << 24) @@ -3490,12 +3453,6 @@ static unsigned int ilk_compute_wm_dirty(struct drm_i915_private *dev_priv, int wm_lp; for_each_pipe(dev_priv, pipe) { - if (old->wm_linetime[pipe] != new->wm_linetime[pipe]) { - dirty |= WM_DIRTY_LINETIME(pipe); - /* Must disable LP1+ watermarks too */ - dirty |= WM_DIRTY_LP_ALL; - } - if (old->wm_pipe[pipe] != new->wm_pipe[pipe]) { dirty |= WM_DIRTY_PIPE(pipe); /* Must disable LP1+ watermarks too */ @@ -3587,13 +3544,6 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv, if (dirty & WM_DIRTY_PIPE(PIPE_C)) I915_WRITE(WM0_PIPEC_IVB, results->wm_pipe[2]); - if (dirty & WM_DIRTY_LINETIME(PIPE_A)) - I915_WRITE(WM_LINETIME(PIPE_A), results->wm_linetime[0]); - if (dirty & WM_DIRTY_LINETIME(PIPE_B)) - I915_WRITE(WM_LINETIME(PIPE_B), results->wm_linetime[1]); - if (dirty & WM_DIRTY_LINETIME(PIPE_C)) - I915_WRITE(WM_LINETIME(PIPE_C), results->wm_linetime[2]); - if (dirty & WM_DIRTY_DDB) { if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { val = I915_READ(WM_MISC); @@ -4849,24 +4799,6 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state, } } -static u32 -skl_compute_linetime_wm(const struct intel_crtc_state *crtc_state) -{ - struct drm_atomic_state *state = crtc_state->uapi.state; - struct drm_i915_private *dev_priv = to_i915(state->dev); - uint_fixed_16_16_t linetime_us; - u32 linetime_wm; - - linetime_us = intel_get_linetime_us(crtc_state); - linetime_wm = fixed16_to_u32_round_up(mul_u32_fixed16(8, linetime_us)); - - /* Display WA #1135: BXT:ALL GLK:ALL */ - if (IS_GEN9_LP(dev_priv) && dev_priv->ipc_enabled) - linetime_wm /= 2; - - return linetime_wm; -} - static void skl_compute_transition_wm(const struct intel_crtc_state *crtc_state, const struct skl_wm_params *wp, struct skl_plane_wm *wm) @@ -5054,8 +4986,6 @@ static int skl_build_pipe_wm(struct intel_crtc_state *crtc_state) return ret; } - pipe_wm->linetime = skl_compute_linetime_wm(crtc_state); - return 0; } @@ -5181,7 +5111,7 @@ static bool skl_pipe_wm_equals(struct intel_crtc *crtc, return false; } - return wm1->linetime == wm2->linetime; + return true; } static inline bool skl_ddb_entries_overlap(const struct skl_ddb_entry *a, @@ -5562,40 +5492,6 @@ skl_compute_wm(struct intel_atomic_state *state) return 0; } -static void skl_atomic_update_crtc_wm(struct intel_atomic_state *state, - struct intel_crtc *crtc) -{ - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - const struct intel_crtc_state *crtc_state = - intel_atomic_get_new_crtc_state(state, crtc); - const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal; - enum pipe pipe = crtc->pipe; - - if ((state->wm_results.dirty_pipes & BIT(crtc->pipe)) == 0) - return; - - I915_WRITE(WM_LINETIME(pipe), HSW_LINETIME(pipe_wm->linetime)); -} - -static void skl_initial_wm(struct intel_atomic_state *state, - struct intel_crtc *crtc) -{ - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - const struct intel_crtc_state *crtc_state = - intel_atomic_get_new_crtc_state(state, crtc); - struct skl_ddb_values *results = &state->wm_results; - - if ((results->dirty_pipes & BIT(crtc->pipe)) == 0) - return; - - mutex_lock(&dev_priv->wm.wm_mutex); - - if (crtc_state->uapi.active_changed) - skl_atomic_update_crtc_wm(state, crtc); - - mutex_unlock(&dev_priv->wm.wm_mutex); -} - static void ilk_compute_wm_config(struct drm_i915_private *dev_priv, struct intel_wm_config *config) { @@ -5718,9 +5614,6 @@ void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc, if (!crtc->active) return; - - val = I915_READ(WM_LINETIME(pipe)); - out->linetime = REG_FIELD_GET(HSW_LINETIME_MASK, val); } void skl_wm_get_hw_state(struct drm_i915_private *dev_priv) @@ -5761,8 +5654,6 @@ static void ilk_pipe_wm_get_hw_state(struct intel_crtc *crtc) }; hw->wm_pipe[pipe] = I915_READ(wm0_pipe_reg[pipe]); - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) - hw->wm_linetime[pipe] = I915_READ(WM_LINETIME(pipe)); memset(active, 0, sizeof(*active)); @@ -5781,10 +5672,6 @@ static void ilk_pipe_wm_get_hw_state(struct intel_crtc *crtc) active->wm[0].pri_val = (tmp & WM0_PIPE_PLANE_MASK) >> WM0_PIPE_PLANE_SHIFT; active->wm[0].spr_val = (tmp & WM0_PIPE_SPRITE_MASK) >> WM0_PIPE_SPRITE_SHIFT; active->wm[0].cur_val = tmp & WM0_PIPE_CURSOR_MASK; - active->linetime = REG_FIELD_GET(HSW_LINETIME_MASK, - hw->wm_linetime[pipe]); - active->ips_linetime = REG_FIELD_GET(HSW_IPS_LINETIME_MASK, - hw->wm_linetime[pipe]); } else { int level, max_level = ilk_wm_max_level(dev_priv); @@ -7267,8 +7154,6 @@ void intel_init_pm(struct drm_i915_private *dev_priv) /* For FIFO watermark updates */ if (INTEL_GEN(dev_priv) >= 9) { skl_setup_wm_latency(dev_priv); - dev_priv->display.initial_watermarks = skl_initial_wm; - dev_priv->display.atomic_update_watermarks = skl_atomic_update_crtc_wm; dev_priv->display.compute_global_watermarks = skl_compute_wm; } else if (HAS_PCH_SPLIT(dev_priv)) { ilk_setup_wm_latency(dev_priv);