diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_display.c')
| -rw-r--r-- | drivers/gpu/drm/i915/display/intel_display.c | 148 |
1 files changed, 81 insertions, 67 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 095a319f8bc9..81b3a6692ca2 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -50,7 +50,6 @@ #include "g4x_hdmi.h" #include "hsw_ips.h" #include "i915_config.h" -#include "i915_drv.h" #include "i915_reg.h" #include "i9xx_plane.h" #include "i9xx_plane_regs.h" @@ -100,6 +99,7 @@ #include "intel_frontbuffer.h" #include "intel_hdmi.h" #include "intel_hotplug.h" +#include "intel_initial_plane.h" #include "intel_link_bw.h" #include "intel_lt_phy.h" #include "intel_lvds.h" @@ -113,7 +113,6 @@ #include "intel_pfit.h" #include "intel_pipe_crc.h" #include "intel_plane.h" -#include "intel_plane_initial.h" #include "intel_pmdemand.h" #include "intel_pps.h" #include "intel_psr.h" @@ -372,7 +371,7 @@ void assert_transcoder(struct intel_display *display, { bool cur_state; enum intel_display_power_domain power_domain; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; /* we keep both pipes enabled on 830 */ if (display->platform.i830) @@ -639,7 +638,7 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, if ((crtc_state->active_planes & ~BIT(PLANE_CURSOR)) == 0 && hsw_ips_disable(crtc_state)) { crtc_state->ips_enabled = false; - intel_plane_initial_vblank_wait(crtc); + intel_initial_plane_vblank_wait(crtc); } /* @@ -653,7 +652,7 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, */ if (HAS_GMCH(display) && intel_set_memory_cxsr(display, false)) - intel_plane_initial_vblank_wait(crtc); + intel_initial_plane_vblank_wait(crtc); /* * Gen2 reports pipe underruns whenever all planes are disabled. @@ -663,7 +662,7 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, intel_set_cpu_fifo_underrun_reporting(display, crtc->pipe, false); intel_plane_disable_arm(NULL, plane, crtc_state); - intel_plane_initial_vblank_wait(crtc); + intel_initial_plane_vblank_wait(crtc); } unsigned int @@ -1158,6 +1157,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, if (intel_crtc_vrr_disabling(state, crtc)) { intel_vrr_disable(old_crtc_state); + intel_vrr_dcb_reset(old_crtc_state, crtc); intel_crtc_update_active_timings(old_crtc_state, false); } @@ -1810,7 +1810,17 @@ bool intel_phy_is_combo(struct intel_display *display, enum phy phy) return false; } -/* Prefer intel_encoder_is_tc() */ +/* + * This function returns true if the DDI port respective to the PHY enumeration + * is a Type-C capable port. + * + * Depending on the VBT, the port might be configured + * as a "dedicated external" port, meaning that actual physical PHY is outside + * of the Type-C subsystem and, as such, not really a "Type-C PHY". + * + * Prefer intel_encoder_is_tc(), especially if you really need to know if we + * are dealing with Type-C connections. + */ bool intel_phy_is_tc(struct intel_display *display, enum phy phy) { /* @@ -1859,17 +1869,32 @@ enum phy intel_port_to_phy(struct intel_display *display, enum port port) } /* Prefer intel_encoder_to_tc() */ +/* + * Return TC_PORT_1..I915_MAX_TC_PORTS for any TypeC DDI port. The function + * can be also called for TypeC DDI ports not connected to a TypeC PHY such as + * the PORT_TC1..4 ports on RKL/ADLS/BMG. + */ enum tc_port intel_port_to_tc(struct intel_display *display, enum port port) { - if (!intel_phy_is_tc(display, intel_port_to_phy(display, port))) - return TC_PORT_NONE; - if (DISPLAY_VER(display) >= 12) return TC_PORT_1 + port - PORT_TC1; else return TC_PORT_1 + port - PORT_C; } +/* + * Return TC_PORT_1..I915_MAX_TC_PORTS for TypeC DDI ports connected to a TypeC PHY. + * Note that on RKL, ADLS, BMG the PORT_TC1..4 ports are connected to a non-TypeC + * PHY, so on those platforms the function returns TC_PORT_NONE. + */ +enum tc_port intel_tc_phy_port_to_tc(struct intel_display *display, enum port port) +{ + if (!intel_phy_is_tc(display, intel_port_to_phy(display, port))) + return TC_PORT_NONE; + + return intel_port_to_tc(display, port); +} + enum phy intel_encoder_to_phy(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); @@ -1894,6 +1919,10 @@ bool intel_encoder_is_snps(struct intel_encoder *encoder) bool intel_encoder_is_tc(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); + struct intel_digital_port *dig_port = enc_to_dig_port(encoder); + + if (dig_port && dig_port->dedicated_external) + return false; return intel_phy_is_tc(display, intel_encoder_to_phy(encoder)); } @@ -1902,7 +1931,7 @@ enum tc_port intel_encoder_to_tc(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - return intel_port_to_tc(display, encoder->port); + return intel_tc_phy_port_to_tc(display, encoder->port); } enum intel_display_power_domain @@ -3020,7 +3049,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, struct intel_display *display = to_intel_display(crtc); enum intel_display_power_domain power_domain; enum transcoder cpu_transcoder = (enum transcoder)crtc->pipe; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; bool ret = false; u32 tmp; @@ -3364,7 +3393,7 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc, struct intel_display *display = to_intel_display(crtc); enum intel_display_power_domain power_domain; enum transcoder cpu_transcoder = (enum transcoder)crtc->pipe; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; bool ret = false; u32 tmp; @@ -3454,12 +3483,11 @@ static bool transcoder_ddi_func_is_enabled(struct intel_display *display, enum transcoder cpu_transcoder) { enum intel_display_power_domain power_domain; - intel_wakeref_t wakeref; u32 tmp = 0; power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); - with_intel_display_power_if_enabled(display, power_domain, wakeref) + with_intel_display_power_if_enabled(display, power_domain) tmp = intel_de_read(display, TRANS_DDI_FUNC_CTL(display, cpu_transcoder)); @@ -3481,10 +3509,9 @@ static void enabled_uncompressed_joiner_pipes(struct intel_display *display, joiner_pipes(display)) { enum intel_display_power_domain power_domain; enum pipe pipe = crtc->pipe; - intel_wakeref_t wakeref; power_domain = POWER_DOMAIN_PIPE(pipe); - with_intel_display_power_if_enabled(display, power_domain, wakeref) { + with_intel_display_power_if_enabled(display, power_domain) { u32 tmp = intel_de_read(display, ICL_PIPE_DSS_CTL1(pipe)); if (tmp & UNCOMPRESSED_JOINER_PRIMARY) @@ -3510,10 +3537,9 @@ static void enabled_bigjoiner_pipes(struct intel_display *display, joiner_pipes(display)) { enum intel_display_power_domain power_domain; enum pipe pipe = crtc->pipe; - intel_wakeref_t wakeref; power_domain = intel_dsc_power_domain(crtc, (enum transcoder)pipe); - with_intel_display_power_if_enabled(display, power_domain, wakeref) { + with_intel_display_power_if_enabled(display, power_domain) { u32 tmp = intel_de_read(display, ICL_PIPE_DSS_CTL1(pipe)); if (!(tmp & BIG_JOINER_ENABLE)) @@ -3580,10 +3606,9 @@ static void enabled_ultrajoiner_pipes(struct intel_display *display, joiner_pipes(display)) { enum intel_display_power_domain power_domain; enum pipe pipe = crtc->pipe; - intel_wakeref_t wakeref; power_domain = intel_dsc_power_domain(crtc, (enum transcoder)pipe); - with_intel_display_power_if_enabled(display, power_domain, wakeref) { + with_intel_display_power_if_enabled(display, power_domain) { u32 tmp = intel_de_read(display, ICL_PIPE_DSS_CTL1(pipe)); if (!(tmp & ULTRA_JOINER_ENABLE)) @@ -3741,12 +3766,11 @@ static u8 hsw_enabled_transcoders(struct intel_crtc *crtc) for_each_cpu_transcoder_masked(display, cpu_transcoder, panel_transcoder_mask) { enum intel_display_power_domain power_domain; - intel_wakeref_t wakeref; enum pipe trans_pipe; u32 tmp = 0; power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); - with_intel_display_power_if_enabled(display, power_domain, wakeref) + with_intel_display_power_if_enabled(display, power_domain) tmp = intel_de_read(display, TRANS_DDI_FUNC_CTL(display, cpu_transcoder)); @@ -4977,24 +5001,6 @@ pipe_config_pll_mismatch(struct drm_printer *p, bool fastset, intel_dpll_dump_hw_state(display, p, b); } -static void -pipe_config_cx0pll_mismatch(struct drm_printer *p, bool fastset, - const struct intel_crtc *crtc, - const char *name, - const struct intel_cx0pll_state *a, - const struct intel_cx0pll_state *b) -{ - struct intel_display *display = to_intel_display(crtc); - char *chipname = a->use_c10 ? "C10" : "C20"; - - pipe_config_mismatch(p, fastset, crtc, name, chipname); - - drm_printf(p, "expected:\n"); - intel_cx0pll_dump_hw_state(display, a); - drm_printf(p, "found:\n"); - intel_cx0pll_dump_hw_state(display, b); -} - static bool allow_vblank_delay_fastset(const struct intel_crtc_state *old_crtc_state) { struct intel_display *display = to_intel_display(old_crtc_state); @@ -5146,16 +5152,6 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, } \ } while (0) -#define PIPE_CONF_CHECK_PLL_CX0(name) do { \ - if (!intel_cx0pll_compare_hw_state(¤t_config->name, \ - &pipe_config->name)) { \ - pipe_config_cx0pll_mismatch(&p, fastset, crtc, __stringify(name), \ - ¤t_config->name, \ - &pipe_config->name); \ - ret = false; \ - } \ -} while (0) - #define PIPE_CONF_CHECK_PLL_LT(name) do { \ if (!intel_lt_phy_pll_compare_hw_state(¤t_config->name, \ &pipe_config->name)) { \ @@ -5395,8 +5391,6 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, /* FIXME convert MTL+ platforms over to dpll_mgr */ if (HAS_LT_PHY(display)) PIPE_CONF_CHECK_PLL_LT(dpll_hw_state.ltpll); - else if (DISPLAY_VER(display) >= 14) - PIPE_CONF_CHECK_PLL_CX0(dpll_hw_state.cx0pll); PIPE_CONF_CHECK_X(dsi_pll.ctrl); PIPE_CONF_CHECK_X(dsi_pll.div); @@ -5482,6 +5476,13 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_LLI(cmrr.cmrr_m); PIPE_CONF_CHECK_LLI(cmrr.cmrr_n); PIPE_CONF_CHECK_BOOL(cmrr.enable); + PIPE_CONF_CHECK_I(vrr.dc_balance.vmin); + PIPE_CONF_CHECK_I(vrr.dc_balance.vmax); + PIPE_CONF_CHECK_I(vrr.dc_balance.guardband); + PIPE_CONF_CHECK_I(vrr.dc_balance.slope); + PIPE_CONF_CHECK_I(vrr.dc_balance.max_increase); + PIPE_CONF_CHECK_I(vrr.dc_balance.max_decrease); + PIPE_CONF_CHECK_I(vrr.dc_balance.vblank_target); } if (!fastset || intel_vrr_always_use_vrr_tg(display)) { @@ -6032,14 +6033,6 @@ static int intel_async_flip_check_uapi(struct intel_atomic_state *state, return -EINVAL; } - /* FIXME: selective fetch should be disabled for async flips */ - if (new_crtc_state->enable_psr2_sel_fetch) { - drm_dbg_kms(display->drm, - "[CRTC:%d:%s] async flip disallowed with PSR2 selective fetch\n", - crtc->base.base.id, crtc->base.name); - return -EINVAL; - } - for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { if (plane->pipe != crtc->pipe) @@ -6130,7 +6123,7 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in if (!plane->async_flip) continue; - if (!intel_plane_can_async_flip(plane, new_plane_state->hw.fb->format->format, + if (!intel_plane_can_async_flip(plane, new_plane_state->hw.fb->format, new_plane_state->hw.fb->modifier)) { drm_dbg_kms(display->drm, "[PLANE:%d:%s] pixel format %p4cc / modifier 0x%llx does not support async flip\n", @@ -6870,6 +6863,9 @@ static void intel_update_crtc(struct intel_atomic_state *state, intel_crtc_update_active_timings(new_crtc_state, new_crtc_state->vrr.enable); + if (new_crtc_state->vrr.dc_balance.enable) + intel_vrr_dcb_increment_flip_count(new_crtc_state, crtc); + /* * We usually enable FIFO underrun interrupts as part of the * CRTC enable sequence during modesets. But when we inherit a @@ -7168,7 +7164,6 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state) static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_state) { - struct drm_i915_private *i915 = to_i915(intel_state->base.dev); struct drm_plane *plane; struct drm_plane_state *new_plane_state; long ret; @@ -7177,7 +7172,7 @@ static void intel_atomic_commit_fence_wait(struct intel_atomic_state *intel_stat for_each_new_plane_in_state(&intel_state->base, plane, new_plane_state, i) { if (new_plane_state->fence) { ret = dma_fence_wait_timeout(new_plane_state->fence, false, - i915_fence_timeout(i915)); + i915_fence_timeout()); if (ret <= 0) break; @@ -7333,6 +7328,21 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, if (new_crtc_state->use_flipq) intel_flipq_wait_dmc_halt(new_crtc_state->dsb_commit, crtc); + if (new_crtc_state->vrr.dc_balance.enable) { + /* + * Pause the DMC DC balancing for the remainder of + * the commit so that vmin/vmax won't change after + * we've baked them into the DSB vblank evasion + * commands. + * + * FIXME maybe need a small delay here to make sure + * DMC has finished updating the values? Or we need + * a better DMC<->driver protocol that gives is real + * guarantees about that... + */ + intel_pipedmc_dcb_disable(NULL, crtc); + } + if (intel_crtc_needs_color_update(new_crtc_state)) intel_color_commit_noarm(new_crtc_state->dsb_commit, new_crtc_state); @@ -7386,6 +7396,10 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, intel_dsb_wait_for_delayed_vblank(state, new_crtc_state->dsb_commit); intel_vrr_check_push_sent(new_crtc_state->dsb_commit, new_crtc_state); + + if (new_crtc_state->vrr.dc_balance.enable) + intel_pipedmc_dcb_enable(new_crtc_state->dsb_commit, crtc); + intel_dsb_interrupt(new_crtc_state->dsb_commit); } @@ -7395,11 +7409,11 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, static void intel_atomic_commit_tail(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private __maybe_unused *dev_priv = to_i915(display->drm); + struct intel_uncore *uncore = to_intel_uncore(display->drm); struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {}; - intel_wakeref_t wakeref = NULL; + struct ref_tracker *wakeref = NULL; int i; for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) @@ -7605,7 +7619,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * so enable debugging for the next modeset - and hope we catch * the culprit. */ - intel_uncore_arm_unclaimed_mmio_detection(&dev_priv->uncore); + intel_uncore_arm_unclaimed_mmio_detection(uncore); } /* * Delay re-enabling DC states by 17 ms to avoid the off->on->off |
