diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index 57828f2b7b5a..56c7e3318f01 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -4393,8 +4393,9 @@ EXPORT_SYMBOL(drm_panel_dp_aux_backlight); #endif /* See DP Standard v2.1 2.6.4.4.1.1, 2.8.4.4, 2.8.7 */ -static int drm_dp_link_symbol_cycles(int lane_count, int pixels, int bpp_x16, - int symbol_size, bool is_mst) +static int drm_dp_link_data_symbol_cycles(int lane_count, int pixels, + int bpp_x16, int symbol_size, + bool is_mst) { int cycles = DIV_ROUND_UP(pixels * bpp_x16, 16 * symbol_size * lane_count); int align = is_mst ? 4 / lane_count : 1; @@ -4402,22 +4403,42 @@ static int drm_dp_link_symbol_cycles(int lane_count, int pixels, int bpp_x16, return ALIGN(cycles, align); } -static int drm_dp_link_dsc_symbol_cycles(int lane_count, int pixels, int slice_count, - int bpp_x16, int symbol_size, bool is_mst) +/** + * drm_dp_link_symbol_cycles - calculate the link symbol count with/without dsc + * @lane_count: DP link lane count + * @pixels: number of pixels in a scanline + * @dsc_slice_count: number of slices for DSC or '0' for non-DSC + * @bpp_x16: bits per pixel in .4 binary fixed format + * @symbol_size: DP symbol size + * @is_mst: %true for MST and %false for SST + * + * Calculate the link symbol cycles for both DSC (@dsc_slice_count !=0) and + * non-DSC case (@dsc_slice_count == 0) and return the count. + */ +int drm_dp_link_symbol_cycles(int lane_count, int pixels, int dsc_slice_count, + int bpp_x16, int symbol_size, bool is_mst) { + int slice_count = dsc_slice_count ? : 1; int slice_pixels = DIV_ROUND_UP(pixels, slice_count); - int slice_data_cycles = drm_dp_link_symbol_cycles(lane_count, slice_pixels, - bpp_x16, symbol_size, is_mst); - int slice_eoc_cycles = is_mst ? 4 / lane_count : 1; + int slice_data_cycles = drm_dp_link_data_symbol_cycles(lane_count, + slice_pixels, + bpp_x16, + symbol_size, + is_mst); + int slice_eoc_cycles = 0; + + if (dsc_slice_count) + slice_eoc_cycles = is_mst ? 4 / lane_count : 1; return slice_count * (slice_data_cycles + slice_eoc_cycles); } +EXPORT_SYMBOL(drm_dp_link_symbol_cycles); /** * drm_dp_bw_overhead - Calculate the BW overhead of a DP link stream * @lane_count: DP link lane count * @hactive: pixel count of the active period in one scanline of the stream - * @dsc_slice_count: DSC slice count if @flags/DRM_DP_LINK_BW_OVERHEAD_DSC is set + * @dsc_slice_count: number of slices for DSC or '0' for non-DSC * @bpp_x16: bits per pixel in .4 binary fixed point * @flags: DRM_DP_OVERHEAD_x flags * @@ -4431,7 +4452,7 @@ static int drm_dp_link_dsc_symbol_cycles(int lane_count, int pixels, int slice_c * as well as the stream's * - @hactive timing * - @bpp_x16 color depth - * - compression mode (@flags / %DRM_DP_OVERHEAD_DSC). + * - compression mode (@dsc_slice_count != 0) * Note that this overhead doesn't account for the 8b/10b, 128b/132b * channel coding efficiency, for that see * @drm_dp_link_bw_channel_coding_efficiency(). @@ -4486,15 +4507,10 @@ int drm_dp_bw_overhead(int lane_count, int hactive, WARN_ON((flags & DRM_DP_BW_OVERHEAD_UHBR) && (flags & DRM_DP_BW_OVERHEAD_FEC)); - if (flags & DRM_DP_BW_OVERHEAD_DSC) - symbol_cycles = drm_dp_link_dsc_symbol_cycles(lane_count, hactive, - dsc_slice_count, - bpp_x16, symbol_size, - is_mst); - else - symbol_cycles = drm_dp_link_symbol_cycles(lane_count, hactive, - bpp_x16, symbol_size, - is_mst); + symbol_cycles = drm_dp_link_symbol_cycles(lane_count, hactive, + dsc_slice_count, + bpp_x16, symbol_size, + is_mst); return DIV_ROUND_UP_ULL(mul_u32_u32(symbol_cycles * symbol_size * lane_count, overhead * 16), diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index c8fc271b33b7..13d4a16f7d33 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -52,7 +52,6 @@ i915-y += \ i915-y += \ soc/intel_dram.o \ soc/intel_gmch.o \ - soc/intel_pch.o \ soc/intel_rom.o # core library code @@ -282,6 +281,7 @@ i915-y += \ display/intel_modeset_setup.o \ display/intel_modeset_verify.o \ display/intel_overlay.o \ + display/intel_pch.o \ display/intel_pch_display.o \ display/intel_pch_refclk.o \ display/intel_plane_initial.o \ diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index b39aae9165df..e0a98e6fd6d1 100644 --- a/drivers/gpu/drm/i915/display/g4x_dp.c +++ b/drivers/gpu/drm/i915/display/g4x_dp.c @@ -7,9 +7,11 @@ #include +#include + #include "g4x_dp.h" -#include "i915_drv.h" #include "i915_reg.h" +#include "i915_utils.h" #include "intel_audio.h" #include "intel_backlight.h" #include "intel_connector.h" @@ -28,7 +30,6 @@ #include "intel_hotplug.h" #include "intel_pch_display.h" #include "intel_pps.h" -#include "vlv_sideband.h" static const struct dpll g4x_dpll[] = { { .dot = 162000, .p1 = 2, .p2 = 10, .n = 2, .m1 = 23, .m2 = 8, }, @@ -60,14 +61,13 @@ static void g4x_dp_set_clock(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); const struct dpll *divisor = NULL; int i, count = 0; if (display->platform.g4x) { divisor = g4x_dpll; count = ARRAY_SIZE(g4x_dpll); - } else if (HAS_PCH_SPLIT(dev_priv)) { + } else if (HAS_PCH_SPLIT(display)) { divisor = pch_dpll; count = ARRAY_SIZE(pch_dpll); } else if (display->platform.cherryview) { @@ -93,7 +93,6 @@ static void intel_dp_prepare(struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); enum port port = encoder->port; struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); @@ -141,7 +140,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder, intel_dp->DP |= DP_ENHANCED_FRAMING; intel_dp->DP |= DP_PIPE_SEL_IVB(crtc->pipe); - } else if (HAS_PCH_CPT(dev_priv) && port != PORT_A) { + } else if (HAS_PCH_CPT(display) && port != PORT_A) { intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; intel_de_rmw(display, TRANS_DP_CTL(crtc->pipe), @@ -183,7 +182,7 @@ static void assert_dp_port(struct intel_dp *intel_dp, bool state) static void assert_edp_pll(struct intel_display *display, bool state) { - bool cur_state = intel_de_read(display, DP_A) & DP_PLL_ENABLE; + bool cur_state = intel_de_read(display, DP_A) & EDP_PLL_ENABLE; INTEL_DISPLAY_STATE_WARN(display, cur_state != state, "eDP PLL state assertion failure (expected %s, current %s)\n", @@ -205,12 +204,12 @@ static void ilk_edp_pll_on(struct intel_dp *intel_dp, drm_dbg_kms(display->drm, "enabling eDP PLL for clock %d\n", pipe_config->port_clock); - intel_dp->DP &= ~DP_PLL_FREQ_MASK; + intel_dp->DP &= ~EDP_PLL_FREQ_MASK; if (pipe_config->port_clock == 162000) - intel_dp->DP |= DP_PLL_FREQ_162MHZ; + intel_dp->DP |= EDP_PLL_FREQ_162MHZ; else - intel_dp->DP |= DP_PLL_FREQ_270MHZ; + intel_dp->DP |= EDP_PLL_FREQ_270MHZ; intel_de_write(display, DP_A, intel_dp->DP); intel_de_posting_read(display, DP_A); @@ -225,7 +224,7 @@ static void ilk_edp_pll_on(struct intel_dp *intel_dp, if (display->platform.ironlake) intel_wait_for_vblank_if_active(display, !crtc->pipe); - intel_dp->DP |= DP_PLL_ENABLE; + intel_dp->DP |= EDP_PLL_ENABLE; intel_de_write(display, DP_A, intel_dp->DP); intel_de_posting_read(display, DP_A); @@ -243,7 +242,7 @@ static void ilk_edp_pll_off(struct intel_dp *intel_dp, drm_dbg_kms(display->drm, "disabling eDP PLL\n"); - intel_dp->DP &= ~DP_PLL_ENABLE; + intel_dp->DP &= ~EDP_PLL_ENABLE; intel_de_write(display, DP_A, intel_dp->DP); intel_de_posting_read(display, DP_A); @@ -277,7 +276,6 @@ bool g4x_dp_port_enabled(struct intel_display *display, i915_reg_t dp_reg, enum port port, enum pipe *pipe) { - struct drm_i915_private *dev_priv = to_i915(display->drm); bool ret; u32 val; @@ -287,13 +285,13 @@ bool g4x_dp_port_enabled(struct intel_display *display, /* asserts want to know the pipe even if the port is disabled */ if (display->platform.ivybridge && port == PORT_A) - *pipe = (val & DP_PIPE_SEL_MASK_IVB) >> DP_PIPE_SEL_SHIFT_IVB; - else if (HAS_PCH_CPT(dev_priv) && port != PORT_A) + *pipe = REG_FIELD_GET(DP_PIPE_SEL_MASK_IVB, val); + else if (HAS_PCH_CPT(display) && port != PORT_A) ret &= cpt_dp_port_selected(display, port, pipe); else if (display->platform.cherryview) - *pipe = (val & DP_PIPE_SEL_MASK_CHV) >> DP_PIPE_SEL_SHIFT_CHV; + *pipe = REG_FIELD_GET(DP_PIPE_SEL_MASK_CHV, val); else - *pipe = (val & DP_PIPE_SEL_MASK) >> DP_PIPE_SEL_SHIFT; + *pipe = REG_FIELD_GET(DP_PIPE_SEL_MASK, val); return ret; } @@ -338,7 +336,6 @@ static void intel_dp_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); u32 tmp, flags = 0; enum port port = encoder->port; @@ -353,7 +350,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder, pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A; - if (HAS_PCH_CPT(dev_priv) && port != PORT_A) { + if (HAS_PCH_CPT(display) && port != PORT_A) { u32 trans_dp = intel_de_read(display, TRANS_DP_CTL(crtc->pipe)); @@ -389,13 +386,12 @@ static void intel_dp_get_config(struct intel_encoder *encoder, if (display->platform.g4x && tmp & DP_COLOR_RANGE_16_235) pipe_config->limited_color_range = true; - pipe_config->lane_count = - ((tmp & DP_PORT_WIDTH_MASK) >> DP_PORT_WIDTH_SHIFT) + 1; + pipe_config->lane_count = REG_FIELD_GET(DP_PORT_WIDTH_MASK, tmp) + 1; g4x_dp_get_m_n(pipe_config); if (port == PORT_A) { - if ((intel_de_read(display, DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_162MHZ) + if ((intel_de_read(display, DP_A) & EDP_PLL_FREQ_MASK) == EDP_PLL_FREQ_162MHZ) pipe_config->port_clock = 162000; else pipe_config->port_clock = 270000; @@ -416,7 +412,6 @@ intel_dp_link_down(struct intel_encoder *encoder, const struct intel_crtc_state *old_crtc_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); enum port port = encoder->port; @@ -429,7 +424,7 @@ intel_dp_link_down(struct intel_encoder *encoder, drm_dbg_kms(display->drm, "\n"); if ((display->platform.ivybridge && port == PORT_A) || - (HAS_PCH_CPT(dev_priv) && port != PORT_A)) { + (HAS_PCH_CPT(display) && port != PORT_A)) { intel_dp->DP &= ~DP_LINK_TRAIN_MASK_CPT; intel_dp->DP |= DP_LINK_TRAIN_PAT_IDLE_CPT; } else { @@ -448,7 +443,7 @@ intel_dp_link_down(struct intel_encoder *encoder, * to transcoder A after disabling it to allow the * matching HDMI port to be enabled on transcoder A. */ - if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B && port != PORT_A) { + if (HAS_PCH_IBX(display) && crtc->pipe == PIPE_B && port != PORT_A) { /* * We get CPU/PCH FIFO underruns on the other pipe when * doing the workaround. Sweep them under the rug. @@ -581,16 +576,10 @@ static void chv_post_disable_dp(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - intel_dp_link_down(encoder, old_crtc_state); - vlv_dpio_get(dev_priv); - /* Assert data lane reset */ chv_data_lane_soft_reset(encoder, old_crtc_state, true); - - vlv_dpio_put(dev_priv); } static void @@ -1223,10 +1212,10 @@ static int g4x_dp_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); int ret; - if (HAS_PCH_SPLIT(i915) && encoder->port != PORT_A) + if (HAS_PCH_SPLIT(display) && encoder->port != PORT_A) crtc_state->has_pch_encoder = true; ret = intel_dp_compute_config(encoder, crtc_state, conn_state); @@ -1279,7 +1268,6 @@ static const struct drm_encoder_funcs intel_dp_enc_funcs = { bool g4x_dp_init(struct intel_display *display, i915_reg_t output_reg, enum port port) { - struct drm_i915_private *dev_priv = to_i915(display->drm); const struct intel_bios_encoder_data *devdata; struct intel_digital_port *dig_port; struct intel_encoder *intel_encoder; @@ -1353,7 +1341,7 @@ bool g4x_dp_init(struct intel_display *display, intel_encoder->audio_disable = g4x_dp_audio_disable; if ((display->platform.ivybridge && port == PORT_A) || - (HAS_PCH_CPT(dev_priv) && port != PORT_A)) + (HAS_PCH_CPT(display) && port != PORT_A)) dig_port->dp.set_link_train = cpt_set_link_train; else dig_port->dp.set_link_train = g4x_set_link_train; @@ -1370,7 +1358,7 @@ bool g4x_dp_init(struct intel_display *display, intel_encoder->set_signal_levels = g4x_set_signal_levels; if (display->platform.valleyview || display->platform.cherryview || - (HAS_PCH_SPLIT(dev_priv) && port != PORT_A)) { + (HAS_PCH_SPLIT(display) && port != PORT_A)) { dig_port->dp.preemph_max = intel_dp_preemph_max_3; dig_port->dp.voltage_max = intel_dp_voltage_max_3; } else { diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.c b/drivers/gpu/drm/i915/display/g4x_hdmi.c index 3dc2c59a3df0..1d252432d729 100644 --- a/drivers/gpu/drm/i915/display/g4x_hdmi.c +++ b/drivers/gpu/drm/i915/display/g4x_hdmi.c @@ -5,8 +5,9 @@ * HDMI support for G4x,ILK,SNB,IVB,VLV,CHV (HSW+ handled by the DDI code). */ +#include + #include "g4x_hdmi.h" -#include "i915_drv.h" #include "i915_reg.h" #include "intel_atomic.h" #include "intel_audio.h" @@ -22,13 +23,11 @@ #include "intel_hdmi.h" #include "intel_hotplug.h" #include "intel_sdvo.h" -#include "vlv_sideband.h" static void intel_hdmi_prepare(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; @@ -37,7 +36,7 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder, intel_dp_dual_mode_set_tmds_output(intel_hdmi, true); hdmi_val = SDVO_ENCODING_HDMI; - if (!HAS_PCH_SPLIT(dev_priv) && crtc_state->limited_color_range) + if (!HAS_PCH_SPLIT(display) && crtc_state->limited_color_range) hdmi_val |= HDMI_COLOR_RANGE_16_235; if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) hdmi_val |= SDVO_VSYNC_ACTIVE_HIGH; @@ -52,7 +51,7 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder, if (crtc_state->has_hdmi_sink) hdmi_val |= HDMI_MODE_SELECT_HDMI; - if (HAS_PCH_CPT(dev_priv)) + if (HAS_PCH_CPT(display)) hdmi_val |= SDVO_PIPE_SEL_CPT(crtc->pipe); else if (display->platform.cherryview) hdmi_val |= SDVO_PIPE_SEL_CHV(crtc->pipe); @@ -134,9 +133,8 @@ static int g4x_hdmi_compute_config(struct intel_encoder *encoder, struct intel_display *display = to_intel_display(encoder); struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(encoder->base.dev); - if (HAS_PCH_SPLIT(i915)) { + if (HAS_PCH_SPLIT(display)) { crtc_state->has_pch_encoder = true; if (!intel_fdi_compute_pipe_bpp(crtc_state)) return -EINVAL; @@ -155,7 +153,6 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); u32 tmp, flags = 0; int dotclock; @@ -186,7 +183,7 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder, if (tmp & HDMI_AUDIO_ENABLE) pipe_config->has_audio = true; - if (!HAS_PCH_SPLIT(dev_priv) && + if (!HAS_PCH_SPLIT(display) && tmp & HDMI_COLOR_RANGE_16_235) pipe_config->limited_color_range = true; @@ -383,7 +380,6 @@ static void intel_disable_hdmi(struct intel_atomic_state *state, const struct drm_connector_state *old_conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); struct intel_digital_port *dig_port = hdmi_to_dig_port(intel_hdmi); @@ -401,7 +397,7 @@ static void intel_disable_hdmi(struct intel_atomic_state *state, * to transcoder A after disabling it to allow the * matching DP port to be enabled on transcoder A. */ - if (HAS_PCH_IBX(dev_priv) && crtc->pipe == PIPE_B) { + if (HAS_PCH_IBX(display) && crtc->pipe == PIPE_B) { /* * We get CPU/PCH FIFO underruns on the other pipe when * doing the workaround. Sweep them under the rug. @@ -539,15 +535,8 @@ static void chv_hdmi_post_disable(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { - struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(display->drm); - - vlv_dpio_get(dev_priv); - /* Assert data lane reset */ chv_data_lane_soft_reset(encoder, old_crtc_state, true); - - vlv_dpio_put(dev_priv); } static void chv_hdmi_pre_enable(struct intel_atomic_state *state, @@ -682,7 +671,6 @@ static bool assert_hdmi_port_valid(struct intel_display *display, enum port port bool g4x_hdmi_init(struct intel_display *display, i915_reg_t hdmi_reg, enum port port) { - struct drm_i915_private *dev_priv = to_i915(display->drm); const struct intel_bios_encoder_data *devdata; struct intel_digital_port *dig_port; struct intel_encoder *intel_encoder; @@ -724,7 +712,7 @@ bool g4x_hdmi_init(struct intel_display *display, intel_encoder->hotplug = intel_hdmi_hotplug; intel_encoder->compute_config = g4x_hdmi_compute_config; - if (HAS_PCH_SPLIT(dev_priv)) { + if (HAS_PCH_SPLIT(display)) { intel_encoder->disable = pch_disable_hdmi; intel_encoder->post_disable = pch_post_disable_hdmi; } else { @@ -745,9 +733,9 @@ bool g4x_hdmi_init(struct intel_display *display, intel_encoder->post_disable = vlv_hdmi_post_disable; } else { intel_encoder->pre_enable = intel_hdmi_pre_enable; - if (HAS_PCH_CPT(dev_priv)) + if (HAS_PCH_CPT(display)) intel_encoder->enable = cpt_enable_hdmi; - else if (HAS_PCH_IBX(dev_priv)) + else if (HAS_PCH_IBX(display)) intel_encoder->enable = ibx_enable_hdmi; else intel_encoder->enable = g4x_enable_hdmi; diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 5e8344fdfc28..83778a6ff007 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -7,9 +7,10 @@ #include #include #include +#include -#include "i915_drv.h" #include "i915_reg.h" +#include "i915_utils.h" #include "i9xx_plane.h" #include "i9xx_plane_regs.h" #include "intel_atomic.h" @@ -631,92 +632,84 @@ static void bdw_primary_enable_flip_done(struct intel_plane *plane) { struct intel_display *display = to_intel_display(plane); - struct drm_i915_private *i915 = to_i915(plane->base.dev); enum pipe pipe = plane->pipe; - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); bdw_enable_pipe_irq(display, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); } static void bdw_primary_disable_flip_done(struct intel_plane *plane) { struct intel_display *display = to_intel_display(plane); - struct drm_i915_private *i915 = to_i915(plane->base.dev); enum pipe pipe = plane->pipe; - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); bdw_disable_pipe_irq(display, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); } static void ivb_primary_enable_flip_done(struct intel_plane *plane) { struct intel_display *display = to_intel_display(plane); - struct drm_i915_private *i915 = to_i915(plane->base.dev); - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); ilk_enable_display_irq(display, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane)); - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); } static void ivb_primary_disable_flip_done(struct intel_plane *plane) { struct intel_display *display = to_intel_display(plane); - struct drm_i915_private *i915 = to_i915(plane->base.dev); - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); ilk_disable_display_irq(display, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane)); - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); } static void ilk_primary_enable_flip_done(struct intel_plane *plane) { struct intel_display *display = to_intel_display(plane); - struct drm_i915_private *i915 = to_i915(plane->base.dev); - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); ilk_enable_display_irq(display, DE_PLANE_FLIP_DONE(plane->i9xx_plane)); - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); } static void ilk_primary_disable_flip_done(struct intel_plane *plane) { struct intel_display *display = to_intel_display(plane); - struct drm_i915_private *i915 = to_i915(plane->base.dev); - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); ilk_disable_display_irq(display, DE_PLANE_FLIP_DONE(plane->i9xx_plane)); - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); } static void vlv_primary_enable_flip_done(struct intel_plane *plane) { struct intel_display *display = to_intel_display(plane); - struct drm_i915_private *i915 = to_i915(plane->base.dev); enum pipe pipe = plane->pipe; - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); i915_enable_pipestat(display, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); } static void vlv_primary_disable_flip_done(struct intel_plane *plane) { struct intel_display *display = to_intel_display(plane); - struct drm_i915_private *i915 = to_i915(plane->base.dev); enum pipe pipe = plane->pipe; - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); i915_disable_pipestat(display, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); } static bool i9xx_plane_can_async_flip(u64 modifier) diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index 40751f1547b7..77876ef735b7 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -4143,10 +4143,8 @@ static const struct intel_wm_funcs nop_funcs = { void i9xx_wm_init(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - /* For FIFO watermark updates */ - if (HAS_PCH_SPLIT(dev_priv)) { + if (HAS_PCH_SPLIT(display)) { ilk_setup_wm_latency(display); display->funcs.wm = &ilk_wm_funcs; } else if (display->platform.valleyview || display->platform.cherryview) { diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c index 55f3ae1e68c9..1bf08b80c23f 100644 --- a/drivers/gpu/drm/i915/display/intel_alpm.c +++ b/drivers/gpu/drm/i915/display/intel_alpm.c @@ -5,12 +5,15 @@ #include +#include + #include "intel_alpm.h" #include "intel_crtc.h" #include "intel_de.h" #include "intel_display_types.h" #include "intel_dp.h" #include "intel_dp_aux.h" +#include "intel_psr.h" #include "intel_psr_regs.h" bool intel_alpm_aux_wake_supported(struct intel_dp *intel_dp) @@ -23,7 +26,7 @@ bool intel_alpm_aux_less_wake_supported(struct intel_dp *intel_dp) return intel_dp->alpm_dpcd & DP_ALPM_AUX_LESS_CAP; } -void intel_alpm_init_dpcd(struct intel_dp *intel_dp) +void intel_alpm_init(struct intel_dp *intel_dp) { u8 dpcd; @@ -31,6 +34,7 @@ void intel_alpm_init_dpcd(struct intel_dp *intel_dp) return; intel_dp->alpm_dpcd = dpcd; + mutex_init(&intel_dp->alpm_parameters.lock); } /* @@ -276,6 +280,14 @@ void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp, int waketime_in_lines, first_sdp_position; int context_latency, guardband; + if (intel_dp->alpm_parameters.lobf_disable_debug) { + drm_dbg_kms(display->drm, "LOBF is disabled by debug flag\n"); + return; + } + + if (intel_dp->alpm_parameters.sink_alpm_error) + return; + if (!intel_dp_is_edp(intel_dp)) return; @@ -288,6 +300,10 @@ void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp, if (crtc_state->has_psr) return; + if (crtc_state->vrr.vmin != crtc_state->vrr.vmax || + crtc_state->vrr.vmin != crtc_state->vrr.flipline) + return; + if (!(intel_alpm_aux_wake_supported(intel_dp) || intel_alpm_aux_less_wake_supported(intel_dp))) return; @@ -316,15 +332,16 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp, enum port port = dp_to_dig_port(intel_dp)->base.port; u32 alpm_ctl; - if (DISPLAY_VER(display) < 20 || - (!intel_dp->psr.sel_update_enabled && !intel_dp_is_edp(intel_dp))) + if (DISPLAY_VER(display) < 20 || (!intel_psr_needs_alpm(intel_dp, crtc_state) && + !crtc_state->has_lobf)) return; + mutex_lock(&intel_dp->alpm_parameters.lock); /* * Panel Replay on eDP is always using ALPM aux less. I.e. no need to * check panel support at this point. */ - if ((intel_dp->psr.panel_replay_enabled && intel_dp_is_edp(intel_dp)) || + if ((crtc_state->has_panel_replay && intel_dp_is_edp(intel_dp)) || (crtc_state->has_lobf && intel_alpm_aux_less_wake_supported(intel_dp))) { alpm_ctl = ALPM_CTL_ALPM_ENABLE | ALPM_CTL_ALPM_AUX_LESS_ENABLE | @@ -353,18 +370,107 @@ static void lnl_alpm_configure(struct intel_dp *intel_dp, ALPM_CTL_EXTENDED_FAST_WAKE_TIME(intel_dp->alpm_parameters.fast_wake_lines); } - if (crtc_state->has_lobf) + if (crtc_state->has_lobf) { alpm_ctl |= ALPM_CTL_LOBF_ENABLE; + drm_dbg_kms(display->drm, "Link off between frames (LOBF) enabled\n"); + } alpm_ctl |= ALPM_CTL_ALPM_ENTRY_CHECK(intel_dp->alpm_parameters.check_entry_lines); intel_de_write(display, ALPM_CTL(display, cpu_transcoder), alpm_ctl); + mutex_unlock(&intel_dp->alpm_parameters.lock); } void intel_alpm_configure(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { lnl_alpm_configure(intel_dp, crtc_state); + intel_dp->alpm_parameters.transcoder = crtc_state->cpu_transcoder; +} + +void intel_alpm_pre_plane_update(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct intel_display *display = to_intel_display(state); + const struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + const struct intel_crtc_state *old_crtc_state = + intel_atomic_get_old_crtc_state(state, crtc); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + struct intel_encoder *encoder; + + if (DISPLAY_VER(display) < 20) + return; + + if (crtc_state->has_lobf || crtc_state->has_lobf == old_crtc_state->has_lobf) + return; + + for_each_intel_encoder_mask(display->drm, encoder, + crtc_state->uapi.encoder_mask) { + struct intel_dp *intel_dp; + + if (!intel_encoder_is_dp(encoder)) + continue; + + intel_dp = enc_to_intel_dp(encoder); + + if (!intel_dp_is_edp(intel_dp)) + continue; + + if (old_crtc_state->has_lobf) { + mutex_lock(&intel_dp->alpm_parameters.lock); + intel_de_write(display, ALPM_CTL(display, cpu_transcoder), 0); + drm_dbg_kms(display->drm, "Link off between frames (LOBF) disabled\n"); + mutex_unlock(&intel_dp->alpm_parameters.lock); + } + } +} + +static void intel_alpm_enable_sink(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + u8 val; + + if (!intel_psr_needs_alpm(intel_dp, crtc_state) && !crtc_state->has_lobf) + return; + + val = DP_ALPM_ENABLE | DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE; + + if (crtc_state->has_panel_replay || (crtc_state->has_lobf && + intel_alpm_aux_less_wake_supported(intel_dp))) + val |= DP_ALPM_MODE_AUX_LESS; + + drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, val); +} + +void intel_alpm_post_plane_update(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct intel_display *display = to_intel_display(state); + const struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + const struct intel_crtc_state *old_crtc_state = + intel_atomic_get_old_crtc_state(state, crtc); + struct intel_encoder *encoder; + + if ((!crtc_state->has_lobf || + crtc_state->has_lobf == old_crtc_state->has_lobf) && !crtc_state->has_psr) + return; + + for_each_intel_encoder_mask(display->drm, encoder, + crtc_state->uapi.encoder_mask) { + struct intel_dp *intel_dp; + + if (!intel_encoder_is_dp(encoder)) + continue; + + intel_dp = enc_to_intel_dp(encoder); + + if (intel_dp_is_edp(intel_dp)) { + intel_alpm_enable_sink(intel_dp, crtc_state); + intel_alpm_configure(intel_dp, crtc_state); + } + } } static int i915_edp_lobf_info_show(struct seq_file *m, void *data) @@ -403,6 +509,32 @@ out: DEFINE_SHOW_ATTRIBUTE(i915_edp_lobf_info); +static int +i915_edp_lobf_debug_get(void *data, u64 *val) +{ + struct intel_connector *connector = data; + struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); + + *val = intel_dp->alpm_parameters.lobf_disable_debug; + + return 0; +} + +static int +i915_edp_lobf_debug_set(void *data, u64 val) +{ + struct intel_connector *connector = data; + struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); + + intel_dp->alpm_parameters.lobf_disable_debug = val; + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(i915_edp_lobf_debug_fops, + i915_edp_lobf_debug_get, i915_edp_lobf_debug_set, + "%llu\n"); + void intel_alpm_lobf_debugfs_add(struct intel_connector *connector) { struct intel_display *display = to_intel_display(connector); @@ -412,6 +544,55 @@ void intel_alpm_lobf_debugfs_add(struct intel_connector *connector) connector->base.connector_type != DRM_MODE_CONNECTOR_eDP) return; + debugfs_create_file("i915_edp_lobf_debug", 0644, root, + connector, &i915_edp_lobf_debug_fops); + debugfs_create_file("i915_edp_lobf_info", 0444, root, connector, &i915_edp_lobf_info_fops); } + +void intel_alpm_disable(struct intel_dp *intel_dp) +{ + struct intel_display *display = to_intel_display(intel_dp); + enum transcoder cpu_transcoder = intel_dp->alpm_parameters.transcoder; + + if (DISPLAY_VER(display) < 20 || !intel_dp->alpm_dpcd) + return; + + mutex_lock(&intel_dp->alpm_parameters.lock); + + intel_de_rmw(display, ALPM_CTL(display, cpu_transcoder), + ALPM_CTL_ALPM_ENABLE | ALPM_CTL_LOBF_ENABLE | + ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0); + + intel_de_rmw(display, + PORT_ALPM_CTL(cpu_transcoder), + PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0); + + drm_dbg_kms(display->drm, "Disabling ALPM\n"); + mutex_unlock(&intel_dp->alpm_parameters.lock); +} + +bool intel_alpm_get_error(struct intel_dp *intel_dp) +{ + struct intel_display *display = to_intel_display(intel_dp); + struct drm_dp_aux *aux = &intel_dp->aux; + u8 val; + int r; + + r = drm_dp_dpcd_readb(aux, DP_RECEIVER_ALPM_STATUS, &val); + if (r != 1) { + drm_err(display->drm, "Error reading ALPM status\n"); + return true; + } + + if (val & DP_ALPM_LOCK_TIMEOUT_ERROR) { + drm_dbg_kms(display->drm, "ALPM lock timeout error\n"); + + /* Clearing error */ + drm_dp_dpcd_writeb(aux, DP_RECEIVER_ALPM_STATUS, val); + return true; + } + + return false; +} diff --git a/drivers/gpu/drm/i915/display/intel_alpm.h b/drivers/gpu/drm/i915/display/intel_alpm.h index 8c409b10dce6..d7126d65b60f 100644 --- a/drivers/gpu/drm/i915/display/intel_alpm.h +++ b/drivers/gpu/drm/i915/display/intel_alpm.h @@ -12,8 +12,10 @@ struct intel_dp; struct intel_crtc_state; struct drm_connector_state; struct intel_connector; +struct intel_atomic_state; +struct intel_crtc; -void intel_alpm_init_dpcd(struct intel_dp *intel_dp); +void intel_alpm_init(struct intel_dp *intel_dp); bool intel_alpm_compute_params(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state); void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp, @@ -21,7 +23,13 @@ void intel_alpm_lobf_compute_config(struct intel_dp *intel_dp, struct drm_connector_state *conn_state); void intel_alpm_configure(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state); +void intel_alpm_pre_plane_update(struct intel_atomic_state *state, + struct intel_crtc *crtc); +void intel_alpm_post_plane_update(struct intel_atomic_state *state, + struct intel_crtc *crtc); void intel_alpm_lobf_debugfs_add(struct intel_connector *connector); bool intel_alpm_aux_wake_supported(struct intel_dp *intel_dp); bool intel_alpm_aux_less_wake_supported(struct intel_dp *intel_dp); +void intel_alpm_disable(struct intel_dp *intel_dp); +bool intel_alpm_get_error(struct intel_dp *intel_dp); #endif diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c index ea935a5d94c8..40d8bbd8107d 100644 --- a/drivers/gpu/drm/i915/display/intel_audio.c +++ b/drivers/gpu/drm/i915/display/intel_audio.c @@ -27,9 +27,9 @@ #include #include #include +#include #include -#include "i915_drv.h" #include "intel_atomic.h" #include "intel_audio.h" #include "intel_audio_regs.h" @@ -587,19 +587,17 @@ static void ibx_audio_regs_init(struct intel_display *display, enum pipe pipe, struct ibx_audio_regs *regs) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (display->platform.valleyview || display->platform.cherryview) { regs->hdmiw_hdmiedid = VLV_HDMIW_HDMIEDID(pipe); regs->aud_config = VLV_AUD_CFG(pipe); regs->aud_cntl_st = VLV_AUD_CNTL_ST(pipe); regs->aud_cntrl_st2 = VLV_AUD_CNTL_ST2; - } else if (HAS_PCH_CPT(i915)) { + } else if (HAS_PCH_CPT(display)) { regs->hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID(pipe); regs->aud_config = CPT_AUD_CFG(pipe); regs->aud_cntl_st = CPT_AUD_CNTL_ST(pipe); regs->aud_cntrl_st2 = CPT_AUD_CNTRL_ST2; - } else if (HAS_PCH_IBX(i915)) { + } else if (HAS_PCH_IBX(display)) { regs->hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID(pipe); regs->aud_config = IBX_AUD_CFG(pipe); regs->aud_cntl_st = IBX_AUD_CNTL_ST(pipe); @@ -889,12 +887,10 @@ static const struct intel_audio_funcs hsw_audio_funcs = { */ void intel_audio_hooks_init(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (display->platform.g4x) display->funcs.audio = &g4x_audio_funcs; else if (display->platform.valleyview || display->platform.cherryview || - HAS_PCH_CPT(i915) || HAS_PCH_IBX(i915)) + HAS_PCH_CPT(display) || HAS_PCH_IBX(display)) display->funcs.audio = &ibx_audio_funcs; else if (display->platform.haswell || DISPLAY_VER(display) >= 8) display->funcs.audio = &hsw_audio_funcs; diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c b/drivers/gpu/drm/i915/display/intel_backlight.c index 4f3fa966c537..5827da586003 100644 --- a/drivers/gpu/drm/i915/display/intel_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_backlight.c @@ -10,8 +10,11 @@ #include -#include "i915_drv.h" +#include +#include + #include "i915_reg.h" +#include "i915_utils.h" #include "intel_backlight.h" #include "intel_backlight_regs.h" #include "intel_connector.h" @@ -473,7 +476,6 @@ static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state, { struct intel_connector *connector = to_intel_connector(conn_state->connector); struct intel_display *display = to_intel_display(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; u32 pch_ctl1, pch_ctl2; @@ -486,7 +488,7 @@ static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state, intel_de_write(display, BLC_PWM_PCH_CTL1, pch_ctl1); } - if (HAS_PCH_LPT(i915)) + if (HAS_PCH_LPT(display)) intel_de_rmw(display, SOUTH_CHICKEN2, LPT_PWM_GRANULARITY, panel->backlight.alternate_pwm_increment ? LPT_PWM_GRANULARITY : 0); @@ -503,7 +505,7 @@ static void lpt_enable_backlight(const struct intel_crtc_state *crtc_state, pch_ctl1 |= BLM_PCH_POLARITY; /* After LPT, override is the default. */ - if (HAS_PCH_LPT(i915)) + if (HAS_PCH_LPT(display)) pch_ctl1 |= BLM_PCH_OVERRIDE_ENABLE; intel_de_write(display, BLC_PWM_PCH_CTL1, pch_ctl1); @@ -1064,7 +1066,7 @@ static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) */ static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; u32 mul, clock; @@ -1073,7 +1075,7 @@ static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz) else mul = 128; - if (HAS_PCH_LPT_H(i915)) + if (HAS_PCH_LPT_H(display)) clock = MHz(135); /* LPT:H */ else clock = MHz(24); /* LPT:LP */ @@ -1230,12 +1232,11 @@ static u32 get_backlight_min_vbt(struct intel_connector *connector) static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unused) { struct intel_display *display = to_intel_display(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_panel *panel = &connector->panel; u32 cpu_ctl2, pch_ctl1, pch_ctl2, val; bool alt, cpu_mode; - if (HAS_PCH_LPT(i915)) + if (HAS_PCH_LPT(display)) alt = intel_de_read(display, SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY; else alt = intel_de_read(display, SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY; @@ -1259,7 +1260,7 @@ static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unus panel->backlight.pwm_enabled = pch_ctl1 & BLM_PCH_PWM_ENABLE; - cpu_mode = panel->backlight.pwm_enabled && HAS_PCH_LPT(i915) && + cpu_mode = panel->backlight.pwm_enabled && HAS_PCH_LPT(display) && !(pch_ctl1 & BLM_PCH_OVERRIDE_ENABLE) && (cpu_ctl2 & BLM_PWM_ENABLE); @@ -1466,15 +1467,13 @@ bxt_setup_backlight(struct intel_connector *connector, enum pipe unused) static int cnp_num_backlight_controllers(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - - if (INTEL_PCH_TYPE(i915) >= PCH_MTL) + if (INTEL_PCH_TYPE(display) >= PCH_MTL) return 2; - if (INTEL_PCH_TYPE(i915) >= PCH_DG1) + if (INTEL_PCH_TYPE(display) >= PCH_DG1) return 1; - if (INTEL_PCH_TYPE(i915) >= PCH_ICP) + if (INTEL_PCH_TYPE(display) >= PCH_ICP) return 2; return 1; @@ -1482,14 +1481,12 @@ static int cnp_num_backlight_controllers(struct intel_display *display) static bool cnp_backlight_controller_is_valid(struct intel_display *display, int controller) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (controller < 0 || controller >= cnp_num_backlight_controllers(display)) return false; if (controller == 1 && - INTEL_PCH_TYPE(i915) >= PCH_ICP && - INTEL_PCH_TYPE(i915) <= PCH_ADP) + INTEL_PCH_TYPE(display) >= PCH_ICP && + INTEL_PCH_TYPE(display) <= PCH_ADP) return intel_de_read(display, SOUTH_CHICKEN1) & ICP_SECOND_PPS_IO_SELECT; return true; @@ -1818,7 +1815,6 @@ void intel_backlight_init_funcs(struct intel_panel *panel) struct intel_connector *connector = container_of(panel, struct intel_connector, panel); struct intel_display *display = to_intel_display(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI && intel_dsi_dcs_init_backlight_funcs(connector) == 0) @@ -1826,14 +1822,14 @@ void intel_backlight_init_funcs(struct intel_panel *panel) if (display->platform.geminilake || display->platform.broxton) { panel->backlight.pwm_funcs = &bxt_pwm_funcs; - } else if (INTEL_PCH_TYPE(i915) >= PCH_CNP) { + } else if (INTEL_PCH_TYPE(display) >= PCH_CNP) { panel->backlight.pwm_funcs = &cnp_pwm_funcs; - } else if (INTEL_PCH_TYPE(i915) >= PCH_LPT_H) { - if (HAS_PCH_LPT(i915)) + } else if (INTEL_PCH_TYPE(display) >= PCH_LPT_H) { + if (HAS_PCH_LPT(display)) panel->backlight.pwm_funcs = &lpt_pwm_funcs; else panel->backlight.pwm_funcs = &spt_pwm_funcs; - } else if (HAS_PCH_SPLIT(i915)) { + } else if (HAS_PCH_SPLIT(display)) { panel->backlight.pwm_funcs = &pch_pwm_funcs; } else if (display->platform.valleyview || display->platform.cherryview) { if (connector->base.connector_type == DRM_MODE_CONNECTOR_DSI) { diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index fabfcf2caa69..ba7b8938b17c 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -2245,28 +2245,27 @@ static const u8 adlp_ddc_pin_map[] = { static u8 map_ddc_pin(struct intel_display *display, u8 vbt_pin) { - struct drm_i915_private *i915 = to_i915(display->drm); const u8 *ddc_pin_map; int i, n_entries; - if (INTEL_PCH_TYPE(i915) >= PCH_MTL || display->platform.alderlake_p) { + if (INTEL_PCH_TYPE(display) >= PCH_MTL || display->platform.alderlake_p) { ddc_pin_map = adlp_ddc_pin_map; n_entries = ARRAY_SIZE(adlp_ddc_pin_map); } else if (display->platform.alderlake_s) { ddc_pin_map = adls_ddc_pin_map; n_entries = ARRAY_SIZE(adls_ddc_pin_map); - } else if (INTEL_PCH_TYPE(i915) >= PCH_DG1) { + } else if (INTEL_PCH_TYPE(display) >= PCH_DG1) { return vbt_pin; - } else if (display->platform.rocketlake && INTEL_PCH_TYPE(i915) == PCH_TGP) { + } else if (display->platform.rocketlake && INTEL_PCH_TYPE(display) == PCH_TGP) { ddc_pin_map = rkl_pch_tgp_ddc_pin_map; n_entries = ARRAY_SIZE(rkl_pch_tgp_ddc_pin_map); - } else if (HAS_PCH_TGP(i915) && DISPLAY_VER(display) == 9) { + } else if (HAS_PCH_TGP(display) && DISPLAY_VER(display) == 9) { ddc_pin_map = gen9bc_tgp_ddc_pin_map; n_entries = ARRAY_SIZE(gen9bc_tgp_ddc_pin_map); - } else if (INTEL_PCH_TYPE(i915) >= PCH_ICP) { + } else if (INTEL_PCH_TYPE(display) >= PCH_ICP) { ddc_pin_map = icp_ddc_pin_map; n_entries = ARRAY_SIZE(icp_ddc_pin_map); - } else if (HAS_PCH_CNP(i915)) { + } else if (HAS_PCH_CNP(display)) { ddc_pin_map = cnp_ddc_pin_map; n_entries = ARRAY_SIZE(cnp_ddc_pin_map); } else { @@ -2865,8 +2864,6 @@ parse_general_definitions(struct intel_display *display) static void init_vbt_defaults(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - display->vbt.crt_ddc_pin = GMBUS_PIN_VGADDC; /* general features */ @@ -2883,7 +2880,7 @@ init_vbt_defaults(struct intel_display *display) * clock for LVDS. */ display->vbt.lvds_ssc_freq = intel_bios_ssc_frequency(display, - !HAS_PCH_SPLIT(i915)); + !HAS_PCH_SPLIT(display)); drm_dbg_kms(display->drm, "Set default to SSC at %d kHz\n", display->vbt.lvds_ssc_freq); } @@ -3126,7 +3123,7 @@ static const struct vbt_header *intel_bios_get_vbt(struct intel_display *display * If the OpRegion does not have VBT, look in SPI flash * through MMIO or PCI mapping */ - if (!vbt && IS_DGFX(i915)) + if (!vbt && display->platform.dgfx) with_intel_display_rpm(display) vbt = oprom_get_vbt(display, intel_rom_spi(i915), sizep, "SPI flash"); diff --git a/drivers/gpu/drm/i915/display/intel_bios.h b/drivers/gpu/drm/i915/display/intel_bios.h index f9841f0498c6..6cd7a011b8c4 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.h +++ b/drivers/gpu/drm/i915/display/intel_bios.h @@ -24,7 +24,7 @@ /* * Please use intel_vbt_defs.h for VBT private data, to hide and abstract away * the VBT from the rest of the driver. Add the parsed, clean data to struct - * intel_vbt_data within struct drm_i915_private. + * intel_vbt_data within struct intel_display. */ #ifndef _INTEL_BIOS_H_ diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 6830950aae3f..b1718b491ffd 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -3494,7 +3494,6 @@ static int dg1_rawclk(struct intel_display *display) static int cnp_rawclk(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); int divider, fraction; u32 rawclk; @@ -3514,7 +3513,7 @@ static int cnp_rawclk(struct intel_display *display) rawclk |= CNP_RAWCLK_DEN(DIV_ROUND_CLOSEST(numerator * 1000, fraction) - 1); - if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) + if (INTEL_PCH_TYPE(display) >= PCH_ICP) rawclk |= ICP_RAWCLK_NUM(numerator); } @@ -3553,21 +3552,20 @@ static int i9xx_hrawclk(struct intel_display *display) */ u32 intel_read_rawclk(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 freq; - if (INTEL_PCH_TYPE(dev_priv) >= PCH_MTL) + if (INTEL_PCH_TYPE(display) >= PCH_MTL) /* * MTL always uses a 38.4 MHz rawclk. The bspec tells us * "RAWCLK_FREQ defaults to the values for 38.4 and does * not need to be programmed." */ freq = 38400; - else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1) + else if (INTEL_PCH_TYPE(display) >= PCH_DG1) freq = dg1_rawclk(display); - else if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) + else if (INTEL_PCH_TYPE(display) >= PCH_CNP) freq = cnp_rawclk(display); - else if (HAS_PCH_SPLIT(dev_priv)) + else if (HAS_PCH_SPLIT(display)) freq = pch_rawclk(display); else if (display->platform.valleyview || display->platform.cherryview) freq = vlv_hrawclk(display); diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.c b/drivers/gpu/drm/i915/display/intel_cmtg.c index 07d7f4e8f60f..82606ebae1de 100644 --- a/drivers/gpu/drm/i915/display/intel_cmtg.c +++ b/drivers/gpu/drm/i915/display/intel_cmtg.c @@ -9,7 +9,6 @@ #include #include -#include "i915_drv.h" #include "i915_reg.h" #include "intel_crtc.h" #include "intel_cmtg.h" diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c index cca22d2402e8..38b50a779b6b 100644 --- a/drivers/gpu/drm/i915/display/intel_crt.c +++ b/drivers/gpu/drm/i915/display/intel_crt.c @@ -31,9 +31,9 @@ #include #include #include +#include #include -#include "i915_drv.h" #include "i915_irq.h" #include "i915_reg.h" #include "intel_connector.h" @@ -91,13 +91,12 @@ static struct intel_crt *intel_attached_crt(struct intel_connector *connector) bool intel_crt_port_enabled(struct intel_display *display, i915_reg_t adpa_reg, enum pipe *pipe) { - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 val; val = intel_de_read(display, adpa_reg); /* asserts want to know the pipe even if the port is disabled */ - if (HAS_PCH_CPT(dev_priv)) + if (HAS_PCH_CPT(display)) *pipe = REG_FIELD_GET(ADPA_PIPE_SEL_MASK_CPT, val); else *pipe = REG_FIELD_GET(ADPA_PIPE_SEL_MASK, val); @@ -177,7 +176,6 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_crt *crt = intel_encoder_to_crt(encoder); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; @@ -194,14 +192,14 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder, adpa |= ADPA_VSYNC_ACTIVE_HIGH; /* For CPT allow 3 pipe config, for others just use A or B */ - if (HAS_PCH_LPT(dev_priv)) + if (HAS_PCH_LPT(display)) ; /* Those bits don't exist here */ - else if (HAS_PCH_CPT(dev_priv)) + else if (HAS_PCH_CPT(display)) adpa |= ADPA_PIPE_SEL_CPT(crtc->pipe); else adpa |= ADPA_PIPE_SEL(crtc->pipe); - if (!HAS_PCH_SPLIT(dev_priv)) + if (!HAS_PCH_SPLIT(display)) intel_de_write(display, BCLRPAT(display, crtc->pipe), 0); switch (mode) { @@ -356,7 +354,6 @@ intel_crt_mode_valid(struct drm_connector *connector, const struct drm_display_mode *mode) { struct intel_display *display = to_intel_display(connector->dev); - struct drm_i915_private *dev_priv = to_i915(connector->dev); int max_dotclk = display->cdclk.max_dotclk_freq; enum drm_mode_status status; int max_clock; @@ -368,9 +365,9 @@ intel_crt_mode_valid(struct drm_connector *connector, if (mode->clock < 25000) return MODE_CLOCK_LOW; - if (HAS_PCH_LPT(dev_priv)) + if (HAS_PCH_LPT(display)) max_clock = 180000; - else if (IS_VALLEYVIEW(dev_priv)) + else if (display->platform.valleyview) /* * 270 MHz due to current DPLL limits, * DAC limit supposedly 355 MHz. @@ -387,7 +384,7 @@ intel_crt_mode_valid(struct drm_connector *connector, return MODE_CLOCK_HIGH; /* The FDI receiver on LPT only supports 8bpc and only has 2 lanes. */ - if (HAS_PCH_LPT(dev_priv) && + if (HAS_PCH_LPT(display) && ilk_get_lanes_required(mode->clock, 270000, 24) > 2) return MODE_CLOCK_HIGH; @@ -438,7 +435,6 @@ static int hsw_crt_compute_config(struct intel_encoder *encoder, struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; @@ -457,7 +453,7 @@ static int hsw_crt_compute_config(struct intel_encoder *encoder, crtc_state->output_format = INTEL_OUTPUT_FORMAT_RGB; /* LPT FDI RX only supports 8bpc. */ - if (HAS_PCH_LPT(dev_priv)) { + if (HAS_PCH_LPT(display)) { /* TODO: Check crtc_state->max_link_bpp_x16 instead of bw_constrained */ if (crtc_state->bw_constrained && crtc_state->pipe_bpp < 24) { drm_dbg_kms(display->drm, @@ -482,13 +478,12 @@ static bool ilk_crt_detect_hotplug(struct drm_connector *connector) { struct intel_display *display = to_intel_display(connector->dev); struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector)); - struct drm_i915_private *dev_priv = to_i915(connector->dev); u32 adpa; bool ret; /* The first time through, trigger an explicit detection cycle */ if (crt->force_hotplug_required) { - bool turn_off_dac = HAS_PCH_SPLIT(dev_priv); + bool turn_off_dac = HAS_PCH_SPLIT(display); u32 save_adpa; crt->force_hotplug_required = false; @@ -583,15 +578,14 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector) static bool intel_crt_detect_hotplug(struct drm_connector *connector) { struct intel_display *display = to_intel_display(connector->dev); - struct drm_i915_private *dev_priv = to_i915(connector->dev); u32 stat; bool ret = false; int i, tries = 0; - if (HAS_PCH_SPLIT(dev_priv)) + if (HAS_PCH_SPLIT(display)) return ilk_crt_detect_hotplug(connector); - if (IS_VALLEYVIEW(dev_priv)) + if (display->platform.valleyview) return valleyview_crt_detect_hotplug(connector); /* @@ -599,7 +593,7 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) * to get a reliable result. */ - if (IS_G45(dev_priv)) + if (display->platform.g45) tries = 2; else tries = 1; @@ -940,7 +934,6 @@ out: static int intel_crt_get_modes(struct drm_connector *connector) { struct intel_display *display = to_intel_display(connector->dev); - struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector)); struct intel_encoder *encoder = &crt->base; intel_wakeref_t wakeref; @@ -953,7 +946,7 @@ static int intel_crt_get_modes(struct drm_connector *connector) wakeref = intel_display_power_get(display, encoder->power_domain); ret = intel_crt_ddc_get_modes(connector, connector->ddc); - if (ret || !IS_G4X(dev_priv)) + if (ret || !display->platform.g4x) goto out; /* Try to probe digital port for output in DVI-I -> VGA mode. */ @@ -1012,16 +1005,15 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = { void intel_crt_init(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_connector *connector; struct intel_crt *crt; i915_reg_t adpa_reg; u8 ddc_pin; u32 adpa; - if (HAS_PCH_SPLIT(dev_priv)) + if (HAS_PCH_SPLIT(display)) adpa_reg = PCH_ADPA; - else if (IS_VALLEYVIEW(dev_priv)) + else if (display->platform.valleyview) adpa_reg = VLV_ADPA; else adpa_reg = ADPA; @@ -1069,7 +1061,7 @@ void intel_crt_init(struct intel_display *display) crt->base.type = INTEL_OUTPUT_ANALOG; crt->base.cloneable = BIT(INTEL_OUTPUT_DVO) | BIT(INTEL_OUTPUT_HDMI); - if (IS_I830(dev_priv)) + if (display->platform.i830) crt->base.pipe_mask = BIT(PIPE_A); else crt->base.pipe_mask = ~0; @@ -1109,7 +1101,7 @@ void intel_crt_init(struct intel_display *display) intel_ddi_buf_trans_init(&crt->base); } else { - if (HAS_PCH_SPLIT(dev_priv)) { + if (HAS_PCH_SPLIT(display)) { crt->base.compute_config = pch_crt_compute_config; crt->base.disable = pch_disable_crt; crt->base.post_disable = pch_post_disable_crt; @@ -1131,7 +1123,7 @@ void intel_crt_init(struct intel_display *display) * polarity and link reversal bits or not, instead of relying on the * BIOS. */ - if (HAS_PCH_LPT(dev_priv)) { + if (HAS_PCH_LPT(display)) { u32 fdi_config = FDI_RX_POLARITY_REVERSED_LPT | FDI_RX_LINK_REVERSAL_OVERRIDE; diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 5b2603ef2ff7..29cfc38f12e0 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -124,7 +124,7 @@ void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - crtc->block_dc_for_vblank = intel_psr_needs_block_dc_vblank(crtc_state); + crtc->vblank_psr_notify = intel_psr_needs_vblank_notification(crtc_state); assert_vblank_disabled(&crtc->base); drm_crtc_set_max_vblank_count(&crtc->base, @@ -154,9 +154,9 @@ void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state) drm_crtc_vblank_off(&crtc->base); assert_vblank_disabled(&crtc->base); - crtc->block_dc_for_vblank = false; + crtc->vblank_psr_notify = false; - flush_work(&display->irq.vblank_dc_work); + flush_work(&display->irq.vblank_notify_work); } struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc) @@ -305,7 +305,6 @@ static const struct drm_crtc_funcs i8xx_crtc_funcs = { int intel_crtc_init(struct intel_display *display, enum pipe pipe) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_plane *primary, *cursor; const struct drm_crtc_funcs *funcs; struct intel_crtc *crtc; @@ -333,7 +332,7 @@ int intel_crtc_init(struct intel_display *display, enum pipe pipe) for_each_sprite(display, pipe, sprite) { struct intel_plane *plane; - if (DISPLAY_VER(dev_priv) >= 9) + if (DISPLAY_VER(display) >= 9) plane = skl_universal_plane_create(display, pipe, PLANE_2 + sprite); else plane = intel_sprite_plane_create(display, pipe, sprite); diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c index 3276a5b4a9b0..2fec5ba58373 100644 --- a/drivers/gpu/drm/i915/display/intel_cursor.c +++ b/drivers/gpu/drm/i915/display/intel_cursor.c @@ -9,10 +9,11 @@ #include #include #include +#include #include -#include "i915_drv.h" #include "i915_reg.h" +#include "i915_utils.h" #include "intel_atomic.h" #include "intel_atomic_plane.h" #include "intel_cursor.h" diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index 22595766eac5..b09f724c3046 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -6,8 +6,10 @@ #include #include -#include "i915_drv.h" +#include + #include "i915_reg.h" +#include "i915_utils.h" #include "intel_cx0_phy.h" #include "intel_cx0_phy_regs.h" #include "intel_ddi.h" diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index b48ed5df7a96..74132c1d6385 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -30,11 +30,13 @@ #include #include +#include #include -#include "i915_drv.h" #include "i915_reg.h" +#include "i915_utils.h" #include "icl_dsi.h" +#include "intel_alpm.h" #include "intel_audio.h" #include "intel_audio_regs.h" #include "intel_backlight.h" @@ -3553,6 +3555,7 @@ static void intel_ddi_disable_dp(struct intel_atomic_state *state, intel_dp->link.active = false; intel_psr_disable(intel_dp, old_crtc_state); + intel_alpm_disable(intel_dp); intel_edp_backlight_off(old_conn_state); /* Disable the decompression in DP Sink */ intel_dp_sink_disable_decompression(state, @@ -4902,9 +4905,7 @@ static enum hpd_pin tgl_hpd_pin(struct intel_display *display, enum port port) static enum hpd_pin rkl_hpd_pin(struct intel_display *display, enum port port) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - - if (HAS_PCH_TGP(dev_priv)) + if (HAS_PCH_TGP(display)) return tgl_hpd_pin(display, port); if (port >= PORT_TC1) @@ -4923,12 +4924,10 @@ static enum hpd_pin icl_hpd_pin(struct intel_display *display, enum port port) static enum hpd_pin ehl_hpd_pin(struct intel_display *display, enum port port) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (port == PORT_D) return HPD_PORT_A; - if (HAS_PCH_TGP(dev_priv)) + if (HAS_PCH_TGP(display)) return icl_hpd_pin(display, port); return HPD_PORT_A + port - PORT_A; @@ -4936,9 +4935,7 @@ static enum hpd_pin ehl_hpd_pin(struct intel_display *display, enum port port) static enum hpd_pin skl_hpd_pin(struct intel_display *display, enum port port) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - - if (HAS_PCH_TGP(dev_priv)) + if (HAS_PCH_TGP(display)) return icl_hpd_pin(display, port); return HPD_PORT_A + port - PORT_A; diff --git a/drivers/gpu/drm/i915/display/intel_de.h b/drivers/gpu/drm/i915/display/intel_de.h index 655467a6ba87..54ce3e4f8fd9 100644 --- a/drivers/gpu/drm/i915/display/intel_de.h +++ b/drivers/gpu/drm/i915/display/intel_de.h @@ -6,7 +6,6 @@ #ifndef __INTEL_DE_H__ #define __INTEL_DE_H__ -#include "intel_display_conversion.h" #include "intel_display_core.h" #include "intel_dmc_wl.h" #include "intel_dsb.h" @@ -19,7 +18,7 @@ static inline struct intel_uncore *__to_uncore(struct intel_display *display) } static inline u32 -__intel_de_read(struct intel_display *display, i915_reg_t reg) +intel_de_read(struct intel_display *display, i915_reg_t reg) { u32 val; @@ -31,7 +30,6 @@ __intel_de_read(struct intel_display *display, i915_reg_t reg) return val; } -#define intel_de_read(p,...) __intel_de_read(__to_intel_display(p), __VA_ARGS__) static inline u8 intel_de_read8(struct intel_display *display, i915_reg_t reg) @@ -66,7 +64,7 @@ intel_de_read64_2x32(struct intel_display *display, } static inline void -__intel_de_posting_read(struct intel_display *display, i915_reg_t reg) +intel_de_posting_read(struct intel_display *display, i915_reg_t reg) { intel_dmc_wl_get(display, reg); @@ -74,10 +72,9 @@ __intel_de_posting_read(struct intel_display *display, i915_reg_t reg) intel_dmc_wl_put(display, reg); } -#define intel_de_posting_read(p,...) __intel_de_posting_read(__to_intel_display(p), __VA_ARGS__) static inline void -__intel_de_write(struct intel_display *display, i915_reg_t reg, u32 val) +intel_de_write(struct intel_display *display, i915_reg_t reg, u32 val) { intel_dmc_wl_get(display, reg); @@ -85,7 +82,6 @@ __intel_de_write(struct intel_display *display, i915_reg_t reg, u32 val) intel_dmc_wl_put(display, reg); } -#define intel_de_write(p,...) __intel_de_write(__to_intel_display(p), __VA_ARGS__) static inline u32 __intel_de_rmw_nowl(struct intel_display *display, i915_reg_t reg, @@ -95,8 +91,7 @@ __intel_de_rmw_nowl(struct intel_display *display, i915_reg_t reg, } static inline u32 -__intel_de_rmw(struct intel_display *display, i915_reg_t reg, u32 clear, - u32 set) +intel_de_rmw(struct intel_display *display, i915_reg_t reg, u32 clear, u32 set) { u32 val; @@ -108,7 +103,6 @@ __intel_de_rmw(struct intel_display *display, i915_reg_t reg, u32 clear, return val; } -#define intel_de_rmw(p,...) __intel_de_rmw(__to_intel_display(p), __VA_ARGS__) static inline int __intel_de_wait_for_register_nowl(struct intel_display *display, diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index db524d01e574..287110e4e435 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -55,6 +55,7 @@ #include "i9xx_plane.h" #include "i9xx_plane_regs.h" #include "i9xx_wm.h" +#include "intel_alpm.h" #include "intel_atomic.h" #include "intel_atomic_plane.h" #include "intel_audio.h" @@ -1043,14 +1044,13 @@ static void intel_post_plane_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(state->base.dev); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); enum pipe pipe = crtc->pipe; - intel_frontbuffer_flip(dev_priv, new_crtc_state->fb_bits); + intel_frontbuffer_flip(display, new_crtc_state->fb_bits); if (new_crtc_state->update_wm_post && new_crtc_state->hw.active) intel_update_watermarks(display); @@ -1079,6 +1079,8 @@ static void intel_post_plane_update(struct intel_atomic_state *state, if (audio_enabling(old_crtc_state, new_crtc_state)) intel_encoders_audio_enable(state, crtc); + intel_alpm_post_plane_update(state, crtc); + intel_psr_post_plane_update(state, crtc); } @@ -1174,6 +1176,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, intel_atomic_get_new_crtc_state(state, crtc); enum pipe pipe = crtc->pipe; + intel_alpm_pre_plane_update(state, crtc); intel_psr_pre_plane_update(state, crtc); if (intel_crtc_vrr_disabling(state, crtc)) { @@ -1281,7 +1284,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, static void intel_crtc_disable_planes(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); unsigned int update_mask = new_crtc_state->update_planes; @@ -1303,7 +1306,7 @@ static void intel_crtc_disable_planes(struct intel_atomic_state *state, fb_bits |= plane->frontbuffer_bit; } - intel_frontbuffer_flip(dev_priv, fb_bits); + intel_frontbuffer_flip(display, fb_bits); } static void intel_encoders_update_prepare(struct intel_atomic_state *state) @@ -1510,7 +1513,6 @@ static void ilk_crtc_enable(struct intel_atomic_state *state, struct intel_display *display = to_intel_display(crtc); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; if (drm_WARN_ON(display->drm, crtc->active)) @@ -1562,7 +1564,7 @@ static void ilk_crtc_enable(struct intel_atomic_state *state, intel_encoders_enable(state, crtc); - if (HAS_PCH_CPT(dev_priv)) + if (HAS_PCH_CPT(display)) intel_wait_for_pipe_scanline_moving(crtc); /* @@ -2404,14 +2406,6 @@ static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state) return 0; } -static bool intel_crtc_needs_wa_14015401596(const struct intel_crtc_state *crtc_state) -{ - struct intel_display *display = to_intel_display(crtc_state); - - return intel_vrr_possible(crtc_state) && crtc_state->has_psr && - IS_DISPLAY_VER(display, 13, 14); -} - static int intel_crtc_vblank_delay(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); @@ -2420,9 +2414,7 @@ static int intel_crtc_vblank_delay(const struct intel_crtc_state *crtc_state) if (!HAS_DSB(display)) return 0; - /* Wa_14015401596 */ - if (intel_crtc_needs_wa_14015401596(crtc_state)) - vblank_delay = max(vblank_delay, 1); + vblank_delay = max(vblank_delay, intel_psr_min_vblank_delay(crtc_state)); return vblank_delay; } @@ -2534,15 +2526,13 @@ intel_link_compute_m_n(u16 bits_per_pixel_x16, int nlanes, void intel_panel_sanitize_ssc(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - /* * There may be no VBT; and if the BIOS enabled SSC we can * just keep using it to avoid unnecessary flicker. Whereas if the * BIOS isn't using it, don't assume it will work even if the VBT * indicates as much. */ - if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)) { + if (HAS_PCH_IBX(display) || HAS_PCH_CPT(display)) { bool bios_lvds_use_ssc = intel_de_read(display, PCH_DREF_CONTROL) & DREF_SSC1_ENABLE; @@ -2724,6 +2714,19 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta intel_de_write(display, TRANS_VTOTAL(display, pipe), VACTIVE(crtc_vdisplay - 1) | VTOTAL(crtc_vtotal - 1)); + + if (DISPLAY_VER(display) >= 30) { + /* + * Address issues for resolutions with high refresh rate that + * have small Hblank, specifically where Hblank is smaller than + * one MTP. Simulations indicate this will address the + * jitter issues that currently causes BS to be immediately + * followed by BE which DPRX devices are unable to handle. + * https://groups.vesa.org/wg/DP/document/20494 + */ + intel_de_write(display, DP_MIN_HBLANK_CTL(cpu_transcoder), + crtc_state->min_hblank); + } } static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc_state) @@ -2867,6 +2870,10 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc, adjusted_mode->crtc_vdisplay + intel_de_read(display, TRANS_SET_CONTEXT_LATENCY(display, cpu_transcoder)); + + if (DISPLAY_VER(display) >= 30) + pipe_config->min_hblank = intel_de_read(display, + DP_MIN_HBLANK_CTL(cpu_transcoder)); } static void intel_joiner_adjust_pipe_src(struct intel_crtc_state *crtc_state) @@ -5217,6 +5224,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_I(lane_count); PIPE_CONF_CHECK_X(lane_lat_optim_mask); + PIPE_CONF_CHECK_I(min_hblank); + if (HAS_DOUBLE_BUFFERED_M_N(display)) { if (!fastset || !pipe_config->update_m_n) PIPE_CONF_CHECK_M_N(dp_m_n); @@ -6547,7 +6556,6 @@ static void intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state, { struct intel_display *display = to_intel_display(new_crtc_state); struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); /* * Update pipe size and adjust fitter if needed: the reason for this is @@ -6563,7 +6571,7 @@ static void intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state, if (DISPLAY_VER(display) >= 9) { if (new_crtc_state->pch_pfit.enabled) skl_pfit_enable(new_crtc_state); - } else if (HAS_PCH_SPLIT(dev_priv)) { + } else if (HAS_PCH_SPLIT(display)) { if (new_crtc_state->pch_pfit.enabled) ilk_pfit_enable(new_crtc_state); else if (old_crtc_state->pch_pfit.enabled) @@ -6664,6 +6672,8 @@ static void intel_enable_crtc(struct intel_atomic_state *state, intel_crtc_update_active_timings(pipe_crtc_state, false); } + intel_psr_notify_pipe_change(state, crtc, true); + display->funcs.display->crtc_enable(state, crtc); /* vblanks work again, re-enable pipe CRC. */ @@ -6783,6 +6793,8 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state, intel_crtc_joined_pipe_mask(old_crtc_state)) intel_crtc_disable_pipe_crc(pipe_crtc); + intel_psr_notify_pipe_change(state, crtc, false); + display->funcs.display->crtc_disable(state, crtc); for_each_intel_crtc_in_pipe_mask(display->drm, pipe_crtc, @@ -7639,15 +7651,13 @@ static bool ilk_has_edp_a(struct intel_display *display) static bool intel_ddi_crt_present(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (DISPLAY_VER(display) >= 9) return false; if (display->platform.haswell_ult || display->platform.broadwell_ult) return false; - if (HAS_PCH_LPT_H(dev_priv) && + if (HAS_PCH_LPT_H(display) && intel_de_read(display, SFUSE_STRAP) & SFUSE_STRAP_CRT_DISABLED) return false; @@ -7669,7 +7679,6 @@ bool assert_port_valid(struct intel_display *display, enum port port) void intel_setup_outputs(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_encoder *encoder; bool dpd_is_edp = false; @@ -7686,7 +7695,7 @@ void intel_setup_outputs(struct intel_display *display) if (display->platform.geminilake || display->platform.broxton) vlv_dsi_init(display); - } else if (HAS_PCH_SPLIT(dev_priv)) { + } else if (HAS_PCH_SPLIT(display)) { int found; /* @@ -8054,13 +8063,11 @@ static const struct intel_display_funcs i9xx_display_funcs = { */ void intel_init_display_hooks(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (DISPLAY_VER(display) >= 9) { display->funcs.display = &skl_display_funcs; } else if (HAS_DDI(display)) { display->funcs.display = &ddi_display_funcs; - } else if (HAS_PCH_SPLIT(dev_priv)) { + } else if (HAS_PCH_SPLIT(display)) { display->funcs.display = &pch_split_display_funcs; } else if (display->platform.cherryview || display->platform.valleyview) { diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index eb6d6f2d0f75..b4937e102360 100644 --- a/drivers/gpu/drm/i915/display/intel_display_core.h +++ b/drivers/gpu/drm/i915/display/intel_display_core.h @@ -21,17 +21,15 @@ #include "intel_display_limits.h" #include "intel_display_params.h" #include "intel_display_power.h" +#include "intel_dmc_wl.h" #include "intel_dpll_mgr.h" #include "intel_fbc.h" #include "intel_global_state.h" #include "intel_gmbus.h" #include "intel_opregion.h" -#include "intel_dmc_wl.h" +#include "intel_pch.h" #include "intel_wm_types.h" -struct task_struct; - -struct drm_i915_private; struct drm_property; struct drm_property_blob; struct i915_audio_component; @@ -52,6 +50,7 @@ struct intel_hotplug_funcs; struct intel_initial_plane_config; struct intel_opregion; struct intel_overlay; +struct task_struct; /* Amount of SAGV/QGV points, BSpec precisely defines this */ #define I915_NUM_QGV_POINTS 8 @@ -180,7 +179,7 @@ struct intel_hotplug { /* * Queuing of hotplug_work, reenable_work and poll_init_work is - * enabled. Protected by drm_i915_private::irq_lock. + * enabled. Protected by intel_display::irq::lock. */ bool detection_work_enabled; @@ -289,6 +288,9 @@ struct intel_display { /* Platform (and subplatform, if any) identification */ struct intel_display_platforms platform; + /* Intel PCH: where the south display engine lives */ + enum intel_pch pch_type; + /* Display functions */ struct { /* Top level crtc-ish functions */ @@ -426,7 +428,7 @@ struct intel_display { * reused when sending message to gsc cs. * this is only populated post Meteorlake */ - struct intel_hdcp_gsc_message *hdcp_message; + struct intel_hdcp_gsc_context *gsc_context; /* Mutex to protect the above hdcp related values. */ struct mutex hdcp_mutex; } hdcp; @@ -454,6 +456,9 @@ struct intel_display { } ips; struct { + /* protects the irq masks */ + spinlock_t lock; + /* * Most platforms treat the display irq block as an always-on * power domain. vlv/chv can disable it at runtime and need @@ -466,9 +471,9 @@ struct intel_display { /* For i915gm/i945gm vblank irq workaround */ u8 vblank_enabled; - int vblank_wa_num_pipes; + int vblank_enable_count; - struct work_struct vblank_dc_work; + struct work_struct vblank_notify_work; u32 de_irq_mask[I915_MAX_PIPES]; u32 pipestat_irq_mask[I915_MAX_PIPES]; @@ -575,6 +580,8 @@ struct intel_display { struct intel_vbt_data vbt; struct intel_dmc_wl wl; struct intel_wm wm; + + struct work_struct psr_dc5_dc6_wa_work; }; #endif /* __INTEL_DISPLAY_CORE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index 4c208fdb9137..8d0a1779dd19 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -7,11 +7,12 @@ #include #include +#include #include +#include #include #include "hsw_ips.h" -#include "i915_drv.h" #include "i915_irq.h" #include "i915_reg.h" #include "i9xx_wm_regs.h" @@ -53,10 +54,9 @@ static struct intel_display *node_to_intel_display(struct drm_info_node *node) static int intel_display_caps(struct seq_file *m, void *data) { struct intel_display *display = node_to_intel_display(m->private); - struct drm_i915_private *i915 = to_i915(display->drm); struct drm_printer p = drm_seq_file_printer(m); - drm_printf(&p, "PCH type: %d\n", INTEL_PCH_TYPE(i915)); + drm_printf(&p, "PCH type: %d\n", INTEL_PCH_TYPE(display)); intel_display_device_info_print(DISPLAY_INFO(display), DISPLAY_RUNTIME_INFO(display), &p); @@ -85,7 +85,6 @@ static int i915_frontbuffer_tracking(struct seq_file *m, void *unused) static int i915_sr_status(struct seq_file *m, void *unused) { struct intel_display *display = node_to_intel_display(m->private); - struct drm_i915_private *dev_priv = to_i915(display->drm); intel_wakeref_t wakeref; bool sr_enabled = false; @@ -93,7 +92,7 @@ static int i915_sr_status(struct seq_file *m, void *unused) if (DISPLAY_VER(display) >= 9) /* no global SR status; inspect per-plane WM */; - else if (HAS_PCH_SPLIT(dev_priv)) + else if (HAS_PCH_SPLIT(display)) sr_enabled = intel_de_read(display, WM1_LP_ILK) & WM_LP_ENABLE; else if (display->platform.i965gm || display->platform.g4x || display->platform.i945g || display->platform.i945gm) @@ -558,6 +557,8 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc) seq_printf(m, "\tpipe src=" DRM_RECT_FMT ", dither=%s, bpp=%d\n", DRM_RECT_ARG(&crtc_state->pipe_src), str_yes_no(crtc_state->dither), crtc_state->pipe_bpp); + seq_printf(m, "\tport_clock=%d, lane_count=%d\n", + crtc_state->port_clock, crtc_state->lane_count); intel_scaler_info(m, crtc); diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index 738ae522c8f4..90d714598664 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -3,11 +3,13 @@ * Copyright © 2023 Intel Corporation */ -#include -#include #include -#include "i915_drv.h" +#include +#include +#include +#include + #include "i915_reg.h" #include "intel_cx0_phy_regs.h" #include "intel_de.h" @@ -1711,7 +1713,6 @@ void intel_display_device_remove(struct intel_display *display) static void __intel_display_device_info_runtime_init(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_display_runtime_info *display_runtime = DISPLAY_RUNTIME_INFO(display); enum pipe pipe; @@ -1775,7 +1776,7 @@ static void __intel_display_device_info_runtime_init(struct intel_display *displ goto display_fused_off; } - if (IS_DISPLAY_VER(display, 7, 8) && HAS_PCH_SPLIT(i915)) { + if (IS_DISPLAY_VER(display, 7, 8) && HAS_PCH_SPLIT(display)) { u32 fuse_strap = intel_de_read(display, FUSE_STRAP); u32 sfuse_strap = intel_de_read(display, SFUSE_STRAP); @@ -1790,7 +1791,7 @@ static void __intel_display_device_info_runtime_init(struct intel_display *displ */ if (fuse_strap & ILK_INTERNAL_DISPLAY_DISABLE || sfuse_strap & SFUSE_STRAP_DISPLAY_DISABLED || - (HAS_PCH_CPT(i915) && + (HAS_PCH_CPT(display) && !(sfuse_strap & SFUSE_STRAP_FUSE_LOCK))) { drm_info(display->drm, "Display fused off, disabling\n"); diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index efee8925987e..5c74ab5fd1aa 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -54,6 +54,7 @@ #include "intel_plane_initial.h" #include "intel_pmdemand.h" #include "intel_pps.h" +#include "intel_psr.h" #include "intel_quirks.h" #include "intel_vga.h" #include "intel_wm.h" @@ -180,6 +181,9 @@ static void intel_plane_possible_crtcs_init(struct intel_display *display) void intel_display_driver_early_probe(struct intel_display *display) { + /* This must be called before any calls to HAS_PCH_* */ + intel_pch_detect(display); + if (!HAS_DISPLAY(display)) return; @@ -223,6 +227,8 @@ int intel_display_driver_probe_noirq(struct intel_display *display) if (ret) goto cleanup_bios; + intel_psr_dc5_dc6_wa_init(display); + /* FIXME: completely on the wrong abstraction layer */ ret = intel_power_domains_init(display); if (ret < 0) @@ -415,7 +421,6 @@ bool intel_display_driver_check_access(struct intel_display *display) /* part #2: call after irq install, but before gem init */ int intel_display_driver_probe_nogem(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); enum pipe pipe; int ret; @@ -453,8 +458,6 @@ int intel_display_driver_probe_nogem(struct intel_display *display) intel_hti_init(display); - /* Just disable it once at startup */ - intel_vga_disable(display); intel_setup_outputs(display); ret = intel_dp_tunnel_mgr_init(display); @@ -464,7 +467,7 @@ int intel_display_driver_probe_nogem(struct intel_display *display) intel_display_driver_disable_user_access(display); drm_modeset_lock_all(display->drm); - intel_modeset_setup_hw_state(i915, display->drm->mode_config.acquire_ctx); + intel_modeset_setup_hw_state(display, display->drm->mode_config.acquire_ctx); intel_acpi_assign_connector_fwnodes(display); drm_modeset_unlock_all(display->drm); @@ -525,7 +528,6 @@ int intel_display_driver_probe(struct intel_display *display) void intel_display_driver_register(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct drm_printer p = drm_dbg_printer(display->drm, DRM_UT_KMS, "i915 display info:"); @@ -552,7 +554,7 @@ void intel_display_driver_register(struct intel_display *display) drm_kms_helper_poll_init(display->drm); intel_hpd_poll_disable(display); - intel_fbdev_setup(i915); + intel_fbdev_setup(display); intel_display_device_info_print(DISPLAY_INFO(display), DISPLAY_RUNTIME_INFO(display), &p); @@ -687,13 +689,11 @@ __intel_display_driver_resume(struct intel_display *display, struct drm_atomic_state *state, struct drm_modeset_acquire_ctx *ctx) { - struct drm_i915_private *i915 = to_i915(display->drm); struct drm_crtc_state *crtc_state; struct drm_crtc *crtc; int ret, i; - intel_modeset_setup_hw_state(i915, ctx); - intel_vga_redisable(display); + intel_modeset_setup_hw_state(display, ctx); if (!state) return 0; diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index d2a35e3630b1..3e73832e5e81 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -5,7 +5,6 @@ #include -#include "gt/intel_rps.h" #include "i915_drv.h" #include "i915_irq.h" #include "i915_reg.h" @@ -15,6 +14,7 @@ #include "intel_de.h" #include "intel_display_irq.h" #include "intel_display_rpm.h" +#include "intel_display_rps.h" #include "intel_display_trace.h" #include "intel_display_types.h" #include "intel_dmc_wl.h" @@ -135,7 +135,7 @@ void ilk_update_display_irq(struct intel_display *display, struct drm_i915_private *dev_priv = to_i915(display->drm); u32 new_val; - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); drm_WARN_ON(display->drm, enabled_irq_mask & ~interrupt_mask); new_val = dev_priv->irq_mask; @@ -173,7 +173,7 @@ void bdw_update_port_irq(struct intel_display *display, u32 new_val; u32 old_val; - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); drm_WARN_ON(display->drm, enabled_irq_mask & ~interrupt_mask); @@ -206,7 +206,7 @@ static void bdw_update_pipe_irq(struct intel_display *display, struct drm_i915_private *dev_priv = to_i915(display->drm); u32 new_val; - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); drm_WARN_ON(display->drm, enabled_irq_mask & ~interrupt_mask); @@ -254,7 +254,7 @@ void ibx_display_interrupt_update(struct intel_display *display, drm_WARN_ON(display->drm, enabled_irq_mask & ~interrupt_mask); - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); if (drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv))) return; @@ -276,11 +276,10 @@ void ibx_disable_display_interrupt(struct intel_display *display, u32 bits) u32 i915_pipestat_enable_mask(struct intel_display *display, enum pipe pipe) { - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 status_mask = display->irq.pipestat_irq_mask[pipe]; u32 enable_mask = status_mask << 16; - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); if (DISPLAY_VER(display) < 5) goto out; @@ -329,7 +328,7 @@ void i915_enable_pipestat(struct intel_display *display, "pipe %c: status_mask=0x%x\n", pipe_name(pipe), status_mask); - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv)); if ((display->irq.pipestat_irq_mask[pipe] & status_mask) == status_mask) @@ -353,7 +352,7 @@ void i915_disable_pipestat(struct intel_display *display, "pipe %c: status_mask=0x%x\n", pipe_name(pipe), status_mask); - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv)); if ((display->irq.pipestat_irq_mask[pipe] & status_mask) == 0) @@ -377,28 +376,23 @@ static bool i915_has_legacy_blc_interrupt(struct intel_display *display) return IS_DISPLAY_VER(display, 3, 4) && display->platform.mobile; } -/** - * i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion - * @display: display device - */ -void i915_enable_asle_pipestat(struct intel_display *display) +/* enable ASLE pipestat for OpRegion */ +static void i915_enable_asle_pipestat(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (!intel_opregion_asle_present(display)) return; if (!i915_has_legacy_blc_interrupt(display)) return; - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); i915_enable_pipestat(display, PIPE_B, PIPE_LEGACY_BLC_EVENT_STATUS); if (DISPLAY_VER(display) >= 4) i915_enable_pipestat(display, PIPE_A, PIPE_LEGACY_BLC_EVENT_STATUS); - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); } #if IS_ENABLED(CONFIG_DEBUG_FS) @@ -517,14 +511,13 @@ static void i9xx_pipestat_irq_reset(struct intel_display *display) void i9xx_pipestat_irq_ack(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]) { - struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe; - spin_lock(&dev_priv->irq_lock); + spin_lock(&display->irq.lock); if ((display->platform.valleyview || display->platform.cherryview) && !display->irq.vlv_display_irqs_enabled) { - spin_unlock(&dev_priv->irq_lock); + spin_unlock(&display->irq.lock); return; } @@ -579,7 +572,7 @@ void i9xx_pipestat_irq_ack(struct intel_display *display, intel_de_write(display, reg, enable_mask); } } - spin_unlock(&dev_priv->irq_lock); + spin_unlock(&display->irq.lock); } void i915_pipestat_irq_handler(struct intel_display *display, @@ -879,7 +872,6 @@ static void ilk_gtt_fault_irq_handler(struct intel_display *display) void ilk_display_irq_handler(struct intel_display *display, u32 de_iir) { - struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe; u32 hotplug_trigger = de_iir & DE_DP_A_HOTPLUG; @@ -916,7 +908,7 @@ void ilk_display_irq_handler(struct intel_display *display, u32 de_iir) if (de_iir & DE_PCH_EVENT) { u32 pch_iir = intel_de_read(display, SDEIIR); - if (HAS_PCH_CPT(dev_priv)) + if (HAS_PCH_CPT(display)) cpt_irq_handler(display, pch_iir); else ibx_irq_handler(display, pch_iir); @@ -926,12 +918,11 @@ void ilk_display_irq_handler(struct intel_display *display, u32 de_iir) } if (DISPLAY_VER(display) == 5 && de_iir & DE_PCU_EVENT) - gen5_rps_irq_handler(&to_gt(dev_priv)->rps); + ilk_display_rps_irq_handler(display); } void ivb_display_irq_handler(struct intel_display *display, u32 de_iir) { - struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe; u32 hotplug_trigger = de_iir & DE_DP_A_HOTPLUG_IVB; @@ -969,7 +960,7 @@ void ivb_display_irq_handler(struct intel_display *display, u32 de_iir) } /* check event from PCH */ - if (!HAS_PCH_NOP(dev_priv) && (de_iir & DE_PCH_EVENT_IVB)) { + if (!HAS_PCH_NOP(display) && (de_iir & DE_PCH_EVENT_IVB)) { u32 pch_iir = intel_de_read(display, SDEIIR); cpt_irq_handler(display, pch_iir); @@ -1311,7 +1302,6 @@ static u32 gen8_de_pipe_flip_done_mask(struct intel_display *display) static void gen8_read_and_ack_pch_irqs(struct intel_display *display, u32 *pch_iir, u32 *pica_iir) { - struct drm_i915_private *i915 = to_i915(display->drm); u32 pica_ier = 0; *pica_iir = 0; @@ -1325,7 +1315,7 @@ static void gen8_read_and_ack_pch_irqs(struct intel_display *display, u32 *pch_i * their flags both in the PICA and SDE IIR. */ if (*pch_iir & SDE_PICAINTERRUPT) { - drm_WARN_ON(display->drm, INTEL_PCH_TYPE(i915) < PCH_MTL); + drm_WARN_ON(display->drm, INTEL_PCH_TYPE(display) < PCH_MTL); pica_ier = intel_de_rmw(display, PICAINTERRUPT_IER, ~0, 0); *pica_iir = intel_de_read(display, PICAINTERRUPT_IIR); @@ -1340,7 +1330,6 @@ static void gen8_read_and_ack_pch_irqs(struct intel_display *display, u32 *pch_i void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl) { - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 iir; enum pipe pipe; @@ -1465,7 +1454,7 @@ void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl) pipe, fault_errors); } - if (HAS_PCH_SPLIT(dev_priv) && !HAS_PCH_NOP(dev_priv) && + if (HAS_PCH_SPLIT(display) && !HAS_PCH_NOP(display) && master_ctl & GEN8_DE_PCH_IRQ) { u32 pica_iir; @@ -1479,9 +1468,9 @@ void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl) if (pica_iir) xelpdp_pica_irq_handler(display, pica_iir); - if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) + if (INTEL_PCH_TYPE(display) >= PCH_ICP) icp_irq_handler(display, iir); - else if (INTEL_PCH_TYPE(dev_priv) >= PCH_SPT) + else if (INTEL_PCH_TYPE(display) >= PCH_SPT) spt_irq_handler(display, iir); else cpt_irq_handler(display, iir); @@ -1573,13 +1562,12 @@ void i915gm_irq_cstate_wa(struct intel_display *display, bool enable) int i8xx_enable_vblank(struct drm_crtc *crtc) { struct intel_display *display = to_intel_display(crtc->dev); - struct drm_i915_private *dev_priv = to_i915(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irqsave(&display->irq.lock, irqflags); i915_enable_pipestat(display, pipe, PIPE_VBLANK_INTERRUPT_STATUS); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irqrestore(&display->irq.lock, irqflags); return 0; } @@ -1587,13 +1575,12 @@ int i8xx_enable_vblank(struct drm_crtc *crtc) void i8xx_disable_vblank(struct drm_crtc *crtc) { struct intel_display *display = to_intel_display(crtc->dev); - struct drm_i915_private *dev_priv = to_i915(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irqsave(&display->irq.lock, irqflags); i915_disable_pipestat(display, pipe, PIPE_VBLANK_INTERRUPT_STATUS); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irqrestore(&display->irq.lock, irqflags); } int i915gm_enable_vblank(struct drm_crtc *crtc) @@ -1617,14 +1604,13 @@ void i915gm_disable_vblank(struct drm_crtc *crtc) int i965_enable_vblank(struct drm_crtc *crtc) { struct intel_display *display = to_intel_display(crtc->dev); - struct drm_i915_private *dev_priv = to_i915(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irqsave(&display->irq.lock, irqflags); i915_enable_pipestat(display, pipe, PIPE_START_VBLANK_INTERRUPT_STATUS); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irqrestore(&display->irq.lock, irqflags); return 0; } @@ -1632,28 +1618,26 @@ int i965_enable_vblank(struct drm_crtc *crtc) void i965_disable_vblank(struct drm_crtc *crtc) { struct intel_display *display = to_intel_display(crtc->dev); - struct drm_i915_private *dev_priv = to_i915(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irqsave(&display->irq.lock, irqflags); i915_disable_pipestat(display, pipe, PIPE_START_VBLANK_INTERRUPT_STATUS); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irqrestore(&display->irq.lock, irqflags); } int ilk_enable_vblank(struct drm_crtc *crtc) { struct intel_display *display = to_intel_display(crtc->dev); - struct drm_i915_private *dev_priv = to_i915(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; u32 bit = DISPLAY_VER(display) >= 7 ? DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe); - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irqsave(&display->irq.lock, irqflags); ilk_enable_display_irq(display, bit); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irqrestore(&display->irq.lock, irqflags); /* Even though there is no DMC, frame counter can get stuck when * PSR is active as no frames are generated. @@ -1667,15 +1651,14 @@ int ilk_enable_vblank(struct drm_crtc *crtc) void ilk_disable_vblank(struct drm_crtc *crtc) { struct intel_display *display = to_intel_display(crtc->dev); - struct drm_i915_private *dev_priv = to_i915(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; u32 bit = DISPLAY_VER(display) >= 7 ? DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe); - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irqsave(&display->irq.lock, irqflags); ilk_disable_display_irq(display, bit); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irqrestore(&display->irq.lock, irqflags); } static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc, @@ -1701,39 +1684,31 @@ static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc, return true; } -static void intel_display_vblank_dc_work(struct work_struct *work) +static void intel_display_vblank_notify_work(struct work_struct *work) { struct intel_display *display = - container_of(work, typeof(*display), irq.vblank_dc_work); - int vblank_wa_num_pipes = READ_ONCE(display->irq.vblank_wa_num_pipes); + container_of(work, typeof(*display), irq.vblank_notify_work); + int vblank_enable_count = READ_ONCE(display->irq.vblank_enable_count); - /* - * NOTE: intel_display_power_set_target_dc_state is used only by PSR - * code for DC3CO handling. DC3CO target state is currently disabled in - * PSR code. If DC3CO is taken into use we need take that into account - * here as well. - */ - intel_display_power_set_target_dc_state(display, vblank_wa_num_pipes ? DC_STATE_DISABLE : - DC_STATE_EN_UPTO_DC6); + intel_psr_notify_vblank_enable_disable(display, vblank_enable_count); } int bdw_enable_vblank(struct drm_crtc *_crtc) { struct intel_crtc *crtc = to_intel_crtc(_crtc); struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; unsigned long irqflags; if (gen11_dsi_configure_te(crtc, true)) return 0; - if (crtc->block_dc_for_vblank && display->irq.vblank_wa_num_pipes++ == 0) - schedule_work(&display->irq.vblank_dc_work); + if (crtc->vblank_psr_notify && display->irq.vblank_enable_count++ == 0) + schedule_work(&display->irq.vblank_notify_work); - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irqsave(&display->irq.lock, irqflags); bdw_enable_pipe_irq(display, pipe, GEN8_PIPE_VBLANK); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irqrestore(&display->irq.lock, irqflags); /* Even if there is no DMC, frame counter can get stuck when * PSR is active as no frames are generated, so check only for PSR. @@ -1748,19 +1723,18 @@ void bdw_disable_vblank(struct drm_crtc *_crtc) { struct intel_crtc *crtc = to_intel_crtc(_crtc); struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; unsigned long irqflags; if (gen11_dsi_configure_te(crtc, false)) return; - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + spin_lock_irqsave(&display->irq.lock, irqflags); bdw_disable_pipe_irq(display, pipe, GEN8_PIPE_VBLANK); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_unlock_irqrestore(&display->irq.lock, irqflags); - if (crtc->block_dc_for_vblank && --display->irq.vblank_wa_num_pipes == 0) - schedule_work(&display->irq.vblank_dc_work); + if (crtc->vblank_psr_notify && --display->irq.vblank_enable_count == 0) + schedule_work(&display->irq.vblank_notify_work); } static u32 vlv_dpinvgtt_pipe_fault_mask(enum pipe pipe) @@ -1894,8 +1868,10 @@ static void _vlv_display_irq_reset(struct intel_display *display) void vlv_display_irq_reset(struct intel_display *display) { + spin_lock_irq(&display->irq.lock); if (display->irq.vlv_display_irqs_enabled) _vlv_display_irq_reset(display); + spin_unlock_irq(&display->irq.lock); } void i9xx_display_irq_reset(struct intel_display *display) @@ -1908,22 +1884,48 @@ void i9xx_display_irq_reset(struct intel_display *display) i9xx_pipestat_irq_reset(display); } +void i915_display_irq_postinstall(struct intel_display *display) +{ + /* + * Interrupt setup is already guaranteed to be single-threaded, this is + * just to make the assert_spin_locked check happy. + */ + spin_lock_irq(&display->irq.lock); + i915_enable_pipestat(display, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); + i915_enable_pipestat(display, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); + spin_unlock_irq(&display->irq.lock); + + i915_enable_asle_pipestat(display); +} + +void i965_display_irq_postinstall(struct intel_display *display) +{ + /* + * Interrupt setup is already guaranteed to be single-threaded, this is + * just to make the assert_spin_locked check happy. + */ + spin_lock_irq(&display->irq.lock); + i915_enable_pipestat(display, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); + i915_enable_pipestat(display, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); + i915_enable_pipestat(display, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); + spin_unlock_irq(&display->irq.lock); + + i915_enable_asle_pipestat(display); +} + static u32 vlv_error_mask(void) { /* TODO enable other errors too? */ return VLV_ERROR_PAGE_TABLE; } -void vlv_display_irq_postinstall(struct intel_display *display) +static void _vlv_display_irq_postinstall(struct intel_display *display) { struct drm_i915_private *dev_priv = to_i915(display->drm); u32 pipestat_mask; u32 enable_mask; enum pipe pipe; - if (!display->irq.vlv_display_irqs_enabled) - return; - if (display->platform.cherryview) intel_de_write(display, DPINVGTT, DPINVGTT_STATUS_MASK_CHV | @@ -1960,8 +1962,30 @@ void vlv_display_irq_postinstall(struct intel_display *display) intel_display_irq_regs_init(display, VLV_IRQ_REGS, dev_priv->irq_mask, enable_mask); } +void vlv_display_irq_postinstall(struct intel_display *display) +{ + spin_lock_irq(&display->irq.lock); + if (display->irq.vlv_display_irqs_enabled) + _vlv_display_irq_postinstall(display); + spin_unlock_irq(&display->irq.lock); +} + +void ibx_display_irq_reset(struct intel_display *display) +{ + struct drm_i915_private *i915 = to_i915(display->drm); + + if (HAS_PCH_NOP(i915)) + return; + + gen2_irq_reset(to_intel_uncore(display->drm), SDE_IRQ_REGS); + + if (HAS_PCH_CPT(i915) || HAS_PCH_LPT(i915)) + intel_de_write(display, SERR_INT, 0xffffffff); +} + void gen8_display_irq_reset(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); enum pipe pipe; if (!HAS_DISPLAY(display)) @@ -1977,11 +2001,13 @@ void gen8_display_irq_reset(struct intel_display *display) intel_display_irq_regs_reset(display, GEN8_DE_PORT_IRQ_REGS); intel_display_irq_regs_reset(display, GEN8_DE_MISC_IRQ_REGS); + + if (HAS_PCH_SPLIT(i915)) + ibx_display_irq_reset(display); } void gen11_display_irq_reset(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe; u32 trans_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C) | BIT(TRANSCODER_D); @@ -2026,7 +2052,7 @@ void gen11_display_irq_reset(struct intel_display *display) else intel_display_irq_regs_reset(display, GEN11_DE_HPD_IRQ_REGS); - if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) + if (INTEL_PCH_TYPE(display) >= PCH_ICP) intel_display_irq_regs_reset(display, SDE_IRQ_REGS); } @@ -2038,10 +2064,10 @@ void gen8_irq_power_well_post_enable(struct intel_display *display, gen8_de_pipe_flip_done_mask(display); enum pipe pipe; - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); if (!intel_irqs_enabled(dev_priv)) { - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); return; } @@ -2050,7 +2076,7 @@ void gen8_irq_power_well_post_enable(struct intel_display *display, display->irq.de_irq_mask[pipe], ~display->irq.de_irq_mask[pipe] | extra_ier); - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); } void gen8_irq_power_well_pre_disable(struct intel_display *display, @@ -2059,17 +2085,17 @@ void gen8_irq_power_well_pre_disable(struct intel_display *display, struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe; - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); if (!intel_irqs_enabled(dev_priv)) { - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); return; } for_each_pipe_masked(display, pipe, pipe_mask) intel_display_irq_regs_reset(display, GEN8_DE_PIPE_IRQ_REGS(pipe)); - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); /* make sure we're done processing display irqs */ intel_synchronize_irq(dev_priv); @@ -2088,15 +2114,14 @@ void gen8_irq_power_well_pre_disable(struct intel_display *display, */ static void ibx_irq_postinstall(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 mask; - if (HAS_PCH_NOP(dev_priv)) + if (HAS_PCH_NOP(display)) return; - if (HAS_PCH_IBX(dev_priv)) + if (HAS_PCH_IBX(display)) mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON; - else if (HAS_PCH_CPT(dev_priv) || HAS_PCH_LPT(dev_priv)) + else if (HAS_PCH_CPT(display) || HAS_PCH_LPT(display)) mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT; else mask = SDE_GMBUS_CPT; @@ -2108,32 +2133,37 @@ void valleyview_enable_display_irqs(struct intel_display *display) { struct drm_i915_private *dev_priv = to_i915(display->drm); - lockdep_assert_held(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); if (display->irq.vlv_display_irqs_enabled) - return; + goto out; display->irq.vlv_display_irqs_enabled = true; if (intel_irqs_enabled(dev_priv)) { _vlv_display_irq_reset(display); - vlv_display_irq_postinstall(display); + _vlv_display_irq_postinstall(display); } + +out: + spin_unlock_irq(&display->irq.lock); } void valleyview_disable_display_irqs(struct intel_display *display) { struct drm_i915_private *dev_priv = to_i915(display->drm); - lockdep_assert_held(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); if (!display->irq.vlv_display_irqs_enabled) - return; + goto out; display->irq.vlv_display_irqs_enabled = false; if (intel_irqs_enabled(dev_priv)) _vlv_display_irq_reset(display); +out: + spin_unlock_irq(&display->irq.lock); } void ilk_de_irq_postinstall(struct intel_display *display) @@ -2184,8 +2214,6 @@ static void icp_irq_postinstall(struct intel_display *display); void gen8_de_irq_postinstall(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - u32 de_pipe_masked = gen8_de_pipe_fault_mask(display) | GEN8_PIPE_CDCLK_CRC_DONE; u32 de_pipe_enables; @@ -2201,9 +2229,9 @@ void gen8_de_irq_postinstall(struct intel_display *display) if (DISPLAY_VER(display) >= 14) mtp_irq_postinstall(display); - else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) + else if (INTEL_PCH_TYPE(display) >= PCH_ICP) icp_irq_postinstall(display); - else if (HAS_PCH_SPLIT(dev_priv)) + else if (HAS_PCH_SPLIT(display)) ibx_irq_postinstall(display); if (DISPLAY_VER(display) < 11) @@ -2323,9 +2351,40 @@ void dg1_de_irq_postinstall(struct intel_display *display) void intel_display_irq_init(struct intel_display *display) { + spin_lock_init(&display->irq.lock); + display->drm->vblank_disable_immediate = true; intel_hotplug_irq_init(display); - INIT_WORK(&display->irq.vblank_dc_work, intel_display_vblank_dc_work); + INIT_WORK(&display->irq.vblank_notify_work, + intel_display_vblank_notify_work); +} + +struct intel_display_irq_snapshot { + u32 derrmr; +}; + +struct intel_display_irq_snapshot * +intel_display_irq_snapshot_capture(struct intel_display *display) +{ + struct intel_display_irq_snapshot *snapshot; + + snapshot = kzalloc(sizeof(*snapshot), GFP_ATOMIC); + if (!snapshot) + return NULL; + + if (DISPLAY_VER(display) >= 6 && DISPLAY_VER(display) < 20 && !HAS_GMCH(display)) + snapshot->derrmr = intel_de_read(display, DERRMR); + + return snapshot; +} + +void intel_display_irq_snapshot_print(const struct intel_display_irq_snapshot *snapshot, + struct drm_printer *p) +{ + if (!snapshot) + return; + + drm_printf(p, "DERRMR: 0x%08x\n", snapshot->derrmr); } diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h b/drivers/gpu/drm/i915/display/intel_display_irq.h index f72727768351..c66db3851da4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.h +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h @@ -12,7 +12,9 @@ enum pipe; struct drm_crtc; +struct drm_printer; struct intel_display; +struct intel_display_irq_snapshot; void valleyview_enable_display_irqs(struct intel_display *display); void valleyview_disable_display_irqs(struct intel_display *display); @@ -54,10 +56,13 @@ u32 gen11_gu_misc_irq_ack(struct intel_display *display, const u32 master_ctl); void gen11_gu_misc_irq_handler(struct intel_display *display, const u32 iir); void i9xx_display_irq_reset(struct intel_display *display); +void ibx_display_irq_reset(struct intel_display *display); void vlv_display_irq_reset(struct intel_display *display); void gen8_display_irq_reset(struct intel_display *display); void gen11_display_irq_reset(struct intel_display *display); +void i915_display_irq_postinstall(struct intel_display *display); +void i965_display_irq_postinstall(struct intel_display *display); void vlv_display_irq_postinstall(struct intel_display *display); void ilk_de_irq_postinstall(struct intel_display *display); void gen8_de_irq_postinstall(struct intel_display *display); @@ -67,7 +72,6 @@ void dg1_de_irq_postinstall(struct intel_display *display); u32 i915_pipestat_enable_mask(struct intel_display *display, enum pipe pipe); void i915_enable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask); void i915_disable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask); -void i915_enable_asle_pipestat(struct intel_display *display); void i9xx_pipestat_irq_ack(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); @@ -82,4 +86,7 @@ void intel_display_irq_init(struct intel_display *display); void i915gm_irq_cstate_wa(struct intel_display *display, bool enable); +struct intel_display_irq_snapshot *intel_display_irq_snapshot_capture(struct intel_display *display); +void intel_display_irq_snapshot_print(const struct intel_display_irq_snapshot *snapshot, struct drm_printer *p); + #endif /* __INTEL_DISPLAY_IRQ_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index c78315eb44fa..16356523816f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -323,6 +323,35 @@ unlock: mutex_unlock(&power_domains->lock); } +/** + * intel_display_power_get_current_dc_state - Set target dc state. + * @display: display device + * + * This function set the "DC off" power well target_dc_state, + * based upon this target_dc_stste, "DC off" power well will + * enable desired DC state. + */ +u32 intel_display_power_get_current_dc_state(struct intel_display *display) +{ + struct i915_power_well *power_well; + struct i915_power_domains *power_domains = &display->power.domains; + u32 current_dc_state = DC_STATE_DISABLE; + + mutex_lock(&power_domains->lock); + power_well = lookup_power_well(display, SKL_DISP_DC_OFF); + + if (drm_WARN_ON(display->drm, !power_well)) + goto unlock; + + current_dc_state = intel_power_well_is_enabled(display, power_well) ? + DC_STATE_DISABLE : power_domains->target_dc_state; + +unlock: + mutex_unlock(&power_domains->lock); + + return current_dc_state; +} + static void __async_put_domains_mask(struct i915_power_domains *power_domains, struct intel_power_domain_mask *mask) { @@ -1365,11 +1394,9 @@ static void hsw_restore_lcpll(struct intel_display *display) */ static void hsw_enable_pc8(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - drm_dbg_kms(display->drm, "Enabling package C8+\n"); - if (HAS_PCH_LPT_LP(dev_priv)) + if (HAS_PCH_LPT_LP(display)) intel_de_rmw(display, SOUTH_DSPCLK_GATE_D, PCH_LP_PARTITION_LEVEL_DISABLE, 0); @@ -1415,14 +1442,13 @@ static void intel_pch_reset_handshake(struct intel_display *display, static void skl_display_core_init(struct intel_display *display, bool resume) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; struct i915_power_well *well; gen9_set_dc_state(display, DC_STATE_DISABLE); /* enable PCH reset handshake */ - intel_pch_reset_handshake(display, !HAS_PCH_NOP(dev_priv)); + intel_pch_reset_handshake(display, !HAS_PCH_NOP(display)); if (!HAS_DISPLAY(display)) return; @@ -1624,20 +1650,19 @@ static void tgl_bw_buddy_init(struct intel_display *display) static void icl_display_core_init(struct intel_display *display, bool resume) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; struct i915_power_well *well; gen9_set_dc_state(display, DC_STATE_DISABLE); /* Wa_14011294188:ehl,jsl,tgl,rkl,adl-s */ - if (INTEL_PCH_TYPE(dev_priv) >= PCH_TGP && - INTEL_PCH_TYPE(dev_priv) < PCH_DG1) + if (INTEL_PCH_TYPE(display) >= PCH_TGP && + INTEL_PCH_TYPE(display) < PCH_DG1) intel_de_rmw(display, SOUTH_DSPCLK_GATE_D, 0, PCH_DPMGUNIT_CLOCK_GATE_DISABLE); /* 1. Enable PCH reset handshake. */ - intel_pch_reset_handshake(display, !HAS_PCH_NOP(dev_priv)); + intel_pch_reset_handshake(display, !HAS_PCH_NOP(display)); if (!HAS_DISPLAY(display)) return; @@ -1908,7 +1933,6 @@ static void intel_power_domains_verify_state(struct intel_display *display); */ void intel_power_domains_init_hw(struct intel_display *display, bool resume) { - struct drm_i915_private *i915 = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; power_domains->initializing = true; @@ -1932,9 +1956,9 @@ void intel_power_domains_init_hw(struct intel_display *display, bool resume) assert_isp_power_gated(display); } else if (display->platform.broadwell || display->platform.haswell) { hsw_assert_cdclk(display); - intel_pch_reset_handshake(display, !HAS_PCH_NOP(i915)); + intel_pch_reset_handshake(display, !HAS_PCH_NOP(display)); } else if (display->platform.ivybridge) { - intel_pch_reset_handshake(display, !HAS_PCH_NOP(i915)); + intel_pch_reset_handshake(display, !HAS_PCH_NOP(display)); } /* @@ -2229,8 +2253,6 @@ static void intel_power_domains_verify_state(struct intel_display *display) void intel_display_power_suspend_late(struct intel_display *display, bool s2idle) { - struct drm_i915_private *i915 = to_i915(display->drm); - intel_power_domains_suspend(display, s2idle); if (DISPLAY_VER(display) >= 11 || display->platform.geminilake || @@ -2241,14 +2263,12 @@ void intel_display_power_suspend_late(struct intel_display *display, bool s2idle } /* Tweaked Wa_14010685332:cnp,icp,jsp,mcc,tgp,adp */ - if (INTEL_PCH_TYPE(i915) >= PCH_CNP && INTEL_PCH_TYPE(i915) < PCH_DG1) - intel_de_rmw(i915, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, SBCLK_RUN_REFCLK_DIS); + if (INTEL_PCH_TYPE(display) >= PCH_CNP && INTEL_PCH_TYPE(display) < PCH_DG1) + intel_de_rmw(display, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, SBCLK_RUN_REFCLK_DIS); } void intel_display_power_resume_early(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (DISPLAY_VER(display) >= 11 || display->platform.geminilake || display->platform.broxton) { gen9_sanitize_dc_state(display); @@ -2258,8 +2278,8 @@ void intel_display_power_resume_early(struct intel_display *display) } /* Tweaked Wa_14010685332:cnp,icp,jsp,mcc,tgp,adp */ - if (INTEL_PCH_TYPE(i915) >= PCH_CNP && INTEL_PCH_TYPE(i915) < PCH_DG1) - intel_de_rmw(i915, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, 0); + if (INTEL_PCH_TYPE(display) >= PCH_CNP && INTEL_PCH_TYPE(display) < PCH_DG1) + intel_de_rmw(display, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, 0); intel_power_domains_resume(display); } diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 1b53d67f9b60..f8813b0e16df 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -183,6 +183,7 @@ void intel_display_power_suspend(struct intel_display *display); void intel_display_power_resume(struct intel_display *display); void intel_display_power_set_target_dc_state(struct intel_display *display, u32 state); +u32 intel_display_power_get_current_dc_state(struct intel_display *display); bool intel_display_power_is_enabled(struct intel_display *display, enum intel_display_power_domain domain); diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c index b9b4359751cc..b104bce0e14d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -25,6 +25,7 @@ #include "intel_hotplug.h" #include "intel_pcode.h" #include "intel_pps.h" +#include "intel_psr.h" #include "intel_tc.h" #include "intel_vga.h" #include "skl_watermark.h" @@ -760,6 +761,9 @@ void gen9_set_dc_state(struct intel_display *display, u32 state) state & ~power_domains->allowed_dc_mask)) state &= power_domains->allowed_dc_mask; + if (!power_domains->initializing) + intel_psr_notify_dc5_dc6(display); + val = intel_de_read(display, DC_STATE_EN); mask = gen9_dc_mask(display); drm_dbg_kms(display->drm, "Setting DC state from %02x to %02x\n", @@ -1208,7 +1212,6 @@ static void vlv_init_display_clock_gating(struct intel_display *display) static void vlv_display_power_well_init(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_encoder *encoder; enum pipe pipe; @@ -1232,9 +1235,7 @@ static void vlv_display_power_well_init(struct intel_display *display) vlv_init_display_clock_gating(display); - spin_lock_irq(&dev_priv->irq_lock); valleyview_enable_display_irqs(display); - spin_unlock_irq(&dev_priv->irq_lock); /* * During driver initialization/resume we can avoid restoring the @@ -1252,7 +1253,7 @@ static void vlv_display_power_well_init(struct intel_display *display) intel_crt_reset(&encoder->base); } - intel_vga_redisable_power_on(display); + intel_vga_disable(display); intel_pps_unlock_regs_wa(display); } @@ -1261,9 +1262,7 @@ static void vlv_display_power_well_deinit(struct intel_display *display) { struct drm_i915_private *dev_priv = to_i915(display->drm); - spin_lock_irq(&dev_priv->irq_lock); valleyview_disable_display_irqs(display); - spin_unlock_irq(&dev_priv->irq_lock); /* make sure we're done processing display irqs */ intel_synchronize_irq(dev_priv); diff --git a/drivers/gpu/drm/i915/display/intel_display_rps.c b/drivers/gpu/drm/i915/display/intel_display_rps.c index 4074a1879828..678b24115951 100644 --- a/drivers/gpu/drm/i915/display/intel_display_rps.c +++ b/drivers/gpu/drm/i915/display/intel_display_rps.c @@ -8,6 +8,8 @@ #include "gt/intel_rps.h" #include "i915_drv.h" +#include "i915_reg.h" +#include "intel_display_irq.h" #include "intel_display_rps.h" #include "intel_display_types.h" @@ -81,3 +83,24 @@ void intel_display_rps_mark_interactive(struct intel_display *display, intel_rps_mark_interactive(&to_gt(i915)->rps, interactive); state->rps_interactive = interactive; } + +void ilk_display_rps_enable(struct intel_display *display) +{ + spin_lock(&display->irq.lock); + ilk_enable_display_irq(display, DE_PCU_EVENT); + spin_unlock(&display->irq.lock); +} + +void ilk_display_rps_disable(struct intel_display *display) +{ + spin_lock(&display->irq.lock); + ilk_disable_display_irq(display, DE_PCU_EVENT); + spin_unlock(&display->irq.lock); +} + +void ilk_display_rps_irq_handler(struct intel_display *display) +{ + struct drm_i915_private *i915 = to_i915(display->drm); + + gen5_rps_irq_handler(&to_gt(i915)->rps); +} diff --git a/drivers/gpu/drm/i915/display/intel_display_rps.h b/drivers/gpu/drm/i915/display/intel_display_rps.h index 556891edb2dd..183d154f2c7c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_rps.h +++ b/drivers/gpu/drm/i915/display/intel_display_rps.h @@ -13,10 +13,34 @@ struct drm_crtc; struct intel_atomic_state; struct intel_display; +#ifdef I915 void intel_display_rps_boost_after_vblank(struct drm_crtc *crtc, struct dma_fence *fence); void intel_display_rps_mark_interactive(struct intel_display *display, struct intel_atomic_state *state, bool interactive); +void ilk_display_rps_enable(struct intel_display *display); +void ilk_display_rps_disable(struct intel_display *display); +void ilk_display_rps_irq_handler(struct intel_display *display); +#else +static inline void intel_display_rps_boost_after_vblank(struct drm_crtc *crtc, + struct dma_fence *fence) +{ +} +static inline void intel_display_rps_mark_interactive(struct intel_display *display, + struct intel_atomic_state *state, + bool interactive) +{ +} +static inline void ilk_display_rps_enable(struct intel_display *display) +{ +} +static inline void ilk_display_rps_disable(struct intel_display *display) +{ +} +static inline void ilk_display_rps_irq_handler(struct intel_display *display) +{ +} +#endif #endif /* __INTEL_DISPLAY_RPS_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display_snapshot.c b/drivers/gpu/drm/i915/display/intel_display_snapshot.c index 25ba043cbb65..66087302fdbc 100644 --- a/drivers/gpu/drm/i915/display/intel_display_snapshot.c +++ b/drivers/gpu/drm/i915/display/intel_display_snapshot.c @@ -7,6 +7,7 @@ #include "intel_display_core.h" #include "intel_display_device.h" +#include "intel_display_irq.h" #include "intel_display_params.h" #include "intel_display_snapshot.h" #include "intel_dmc.h" @@ -20,6 +21,7 @@ struct intel_display_snapshot { struct intel_display_params params; struct intel_overlay_snapshot *overlay; struct intel_dmc_snapshot *dmc; + struct intel_display_irq_snapshot *irq; }; struct intel_display_snapshot *intel_display_snapshot_capture(struct intel_display *display) @@ -38,6 +40,7 @@ struct intel_display_snapshot *intel_display_snapshot_capture(struct intel_displ intel_display_params_copy(&snapshot->params); + snapshot->irq = intel_display_irq_snapshot_capture(display); snapshot->overlay = intel_overlay_snapshot_capture(display); snapshot->dmc = intel_dmc_snapshot_capture(display); @@ -57,6 +60,7 @@ void intel_display_snapshot_print(const struct intel_display_snapshot *snapshot, intel_display_device_info_print(&snapshot->info, &snapshot->runtime_info, p); intel_display_params_dump(&snapshot->params, display->drm->driver->name, p); + intel_display_irq_snapshot_print(snapshot->irq, p); intel_overlay_snapshot_print(snapshot->overlay, p); intel_dmc_snapshot_print(snapshot->dmc, p); } @@ -68,6 +72,7 @@ void intel_display_snapshot_free(struct intel_display_snapshot *snapshot) intel_display_params_free(&snapshot->params); + kfree(snapshot->irq); kfree(snapshot->overlay); kfree(snapshot->dmc); kfree(snapshot); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 94468a9d2e0d..d6d0440dcee9 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1114,6 +1114,7 @@ struct intel_crtc_state { bool wm_level_disabled; u32 dc3co_exitline; u16 su_y_granularity; + u8 active_non_psr_pipes; /* * Frequency the dpll for the port should run at. Differs from the @@ -1387,7 +1388,7 @@ struct intel_crtc { /* armed event for DSB based updates */ struct drm_pending_vblank_event *dsb_event; - /* Access to these should be protected by dev_priv->irq_lock. */ + /* Access to these should be protected by display->irq.lock. */ bool cpu_fifo_underrun_disabled; bool pch_fifo_underrun_disabled; @@ -1439,7 +1440,7 @@ struct intel_crtc { struct intel_pipe_crc pipe_crc; #endif - bool block_dc_for_vblank; + bool vblank_psr_notify; }; struct intel_plane_error { @@ -1650,6 +1651,8 @@ struct intel_psr { u8 entry_setup_frames; bool link_ok; + + u8 active_non_psr_pipes; }; struct intel_dp { @@ -1805,12 +1808,16 @@ struct intel_dp { struct { u8 io_wake_lines; u8 fast_wake_lines; + enum transcoder transcoder; + struct mutex lock; /* LNL and beyond */ u8 check_entry_lines; u8 aux_less_wake_lines; u8 silence_period_sym_clocks; u8 lfps_half_cycle_num_of_syms; + bool lobf_disable_debug; + bool sink_alpm_error; } alpm_parameters; u8 alpm_dpcd; diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 98f80a6c63e8..b58189d24e7e 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -173,7 +173,6 @@ MODULE_FIRMWARE(BXT_DMC_PATH); static const char *dmc_firmware_default(struct intel_display *display, u32 *size) { - struct drm_i915_private *i915 = to_i915(display->drm); const char *fw_path = NULL; u32 max_fw_size = 0; @@ -189,39 +188,39 @@ static const char *dmc_firmware_default(struct intel_display *display, u32 *size } else if (DISPLAY_VERx100(display) == 1400) { fw_path = MTL_DMC_PATH; max_fw_size = XELPDP_DMC_MAX_FW_SIZE; - } else if (IS_DG2(i915)) { + } else if (display->platform.dg2) { fw_path = DG2_DMC_PATH; max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; - } else if (IS_ALDERLAKE_P(i915)) { + } else if (display->platform.alderlake_p) { fw_path = ADLP_DMC_PATH; max_fw_size = DISPLAY_VER13_DMC_MAX_FW_SIZE; - } else if (IS_ALDERLAKE_S(i915)) { + } else if (display->platform.alderlake_s) { fw_path = ADLS_DMC_PATH; max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; - } else if (IS_DG1(i915)) { + } else if (display->platform.dg1) { fw_path = DG1_DMC_PATH; max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; - } else if (IS_ROCKETLAKE(i915)) { + } else if (display->platform.rocketlake) { fw_path = RKL_DMC_PATH; max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; - } else if (IS_TIGERLAKE(i915)) { + } else if (display->platform.tigerlake) { fw_path = TGL_DMC_PATH; max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE; } else if (DISPLAY_VER(display) == 11) { fw_path = ICL_DMC_PATH; max_fw_size = ICL_DMC_MAX_FW_SIZE; - } else if (IS_GEMINILAKE(i915)) { + } else if (display->platform.geminilake) { fw_path = GLK_DMC_PATH; max_fw_size = GLK_DMC_MAX_FW_SIZE; - } else if (IS_KABYLAKE(i915) || - IS_COFFEELAKE(i915) || - IS_COMETLAKE(i915)) { + } else if (display->platform.kabylake || + display->platform.coffeelake || + display->platform.cometlake) { fw_path = KBL_DMC_PATH; max_fw_size = KBL_DMC_MAX_FW_SIZE; - } else if (IS_SKYLAKE(i915)) { + } else if (display->platform.skylake) { fw_path = SKL_DMC_PATH; max_fw_size = SKL_DMC_MAX_FW_SIZE; - } else if (IS_BROXTON(i915)) { + } else if (display->platform.broxton) { fw_path = BXT_DMC_PATH; max_fw_size = BXT_DMC_MAX_FW_SIZE; } @@ -517,6 +516,54 @@ void intel_dmc_disable_pipe(struct intel_display *display, enum pipe pipe) intel_de_rmw(display, PIPEDMC_CONTROL(pipe), PIPEDMC_ENABLE, 0); } +/** + * intel_dmc_block_pkgc() - block PKG C-state + * @display: display instance + * @pipe: pipe which register use to block + * @block: block/unblock + * + * This interface is target for Wa_16025596647 usage. I.e. to set/clear + * PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_ALWAYS bit in PIPEDMC_BLOCK_PKGC_SW register. + */ +void intel_dmc_block_pkgc(struct intel_display *display, enum pipe pipe, + bool block) +{ + intel_de_rmw(display, PIPEDMC_BLOCK_PKGC_SW(pipe), + PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_ALWAYS, block ? + PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_ALWAYS : 0); +} + +/** + * intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank() - start of PKG + * C-state exit + * @display: display instance + * @pipe: pipe which register use to block + * @enable: enable/disable + * + * This interface is target for Wa_16025596647 usage. I.e. start the package C + * exit at the start of the undelayed vblank + */ +void intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank(struct intel_display *display, + enum pipe pipe, bool enable) +{ + u32 val; + + if (enable) + val = DMC_EVT_CTL_ENABLE | DMC_EVT_CTL_RECURRING | + REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK, + DMC_EVT_CTL_TYPE_EDGE_0_1) | + REG_FIELD_PREP(DMC_EVT_CTL_EVENT_ID_MASK, + DMC_EVT_CTL_EVENT_ID_VBLANK_A); + else + val = REG_FIELD_PREP(DMC_EVT_CTL_EVENT_ID_MASK, + DMC_EVT_CTL_EVENT_ID_FALSE) | + REG_FIELD_PREP(DMC_EVT_CTL_TYPE_MASK, + DMC_EVT_CTL_TYPE_EDGE_0_1); + + intel_de_write(display, MTL_PIPEDMC_EVT_CTL_4(pipe), + val); +} + static bool is_dmc_evt_ctl_reg(struct intel_display *display, enum intel_dmc_id dmc_id, i915_reg_t reg) { @@ -541,8 +588,6 @@ static bool disable_dmc_evt(struct intel_display *display, enum intel_dmc_id dmc_id, i915_reg_t reg, u32 data) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (!is_dmc_evt_ctl_reg(display, dmc_id, reg)) return false; @@ -551,12 +596,12 @@ static bool disable_dmc_evt(struct intel_display *display, return true; /* also disable the flip queue event on the main DMC on TGL */ - if (IS_TIGERLAKE(i915) && + if (display->platform.tigerlake && REG_FIELD_GET(DMC_EVT_CTL_EVENT_ID_MASK, data) == DMC_EVT_CTL_EVENT_ID_CLK_MSEC) return true; /* also disable the HRR event on the main DMC on TGL/ADLS */ - if ((IS_TIGERLAKE(i915) || IS_ALDERLAKE_S(i915)) && + if ((display->platform.tigerlake || display->platform.alderlake_s) && REG_FIELD_GET(DMC_EVT_CTL_EVENT_ID_MASK, data) == DMC_EVT_CTL_EVENT_ID_VBLANK_A) return true; @@ -588,7 +633,6 @@ static u32 dmc_mmiodata(struct intel_display *display, */ void intel_dmc_load_program(struct intel_display *display) { - struct drm_i915_private *i915 __maybe_unused = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; struct intel_dmc *dmc = display_to_dmc(display); enum intel_dmc_id dmc_id; @@ -1012,9 +1056,7 @@ static void intel_dmc_runtime_pm_put(struct intel_display *display) static const char *dmc_fallback_path(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - - if (IS_ALDERLAKE_P(i915)) + if (display->platform.alderlake_p) return ADLP_DMC_FALLBACK_PATH; return NULL; @@ -1279,7 +1321,6 @@ static bool intel_dmc_get_dc6_allowed_count(struct intel_display *display, u32 * static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) { struct intel_display *display = m->private; - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_dmc *dmc = display_to_dmc(display); struct ref_tracker *wakeref; i915_reg_t dc5_reg, dc6_reg = INVALID_MMIO_REG; @@ -1299,7 +1340,7 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) seq_printf(m, "Pipe A fw loaded: %s\n", str_yes_no(has_dmc_id_fw(display, DMC_FW_PIPEA))); seq_printf(m, "Pipe B fw needed: %s\n", - str_yes_no(IS_ALDERLAKE_P(i915) || + str_yes_no(display->platform.alderlake_p || DISPLAY_VER(display) >= 14)); seq_printf(m, "Pipe B fw loaded: %s\n", str_yes_no(has_dmc_id_fw(display, DMC_FW_PIPEB))); @@ -1313,7 +1354,7 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) if (DISPLAY_VER(display) >= 12) { i915_reg_t dc3co_reg; - if (IS_DGFX(i915) || DISPLAY_VER(display) >= 14) { + if (display->platform.dgfx || DISPLAY_VER(display) >= 14) { dc3co_reg = DG1_DMC_DEBUG3; dc5_reg = DG1_DMC_DEBUG_DC5_COUNT; } else { @@ -1325,9 +1366,9 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused) seq_printf(m, "DC3CO count: %d\n", intel_de_read(display, dc3co_reg)); } else { - dc5_reg = IS_BROXTON(i915) ? BXT_DMC_DC3_DC5_COUNT : + dc5_reg = display->platform.broxton ? BXT_DMC_DC3_DC5_COUNT : SKL_DMC_DC3_DC5_COUNT; - if (!IS_GEMINILAKE(i915) && !IS_BROXTON(i915)) + if (!display->platform.geminilake && !display->platform.broxton) dc6_reg = SKL_DMC_DC5_DC6_COUNT; } diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h index c78426eb4cd5..bd1c459b0075 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.h +++ b/drivers/gpu/drm/i915/display/intel_dmc.h @@ -18,6 +18,10 @@ void intel_dmc_load_program(struct intel_display *display); void intel_dmc_disable_program(struct intel_display *display); void intel_dmc_enable_pipe(struct intel_display *display, enum pipe pipe); void intel_dmc_disable_pipe(struct intel_display *display, enum pipe pipe); +void intel_dmc_block_pkgc(struct intel_display *display, enum pipe pipe, + bool block); +void intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank(struct intel_display *display, + enum pipe pipe, bool enable); void intel_dmc_fini(struct intel_display *display); void intel_dmc_suspend(struct intel_display *display); void intel_dmc_resume(struct intel_display *display); diff --git a/drivers/gpu/drm/i915/display/intel_dmc_regs.h b/drivers/gpu/drm/i915/display/intel_dmc_regs.h index 1bf446f96a10..e16ea3f16ed8 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc_regs.h +++ b/drivers/gpu/drm/i915/display/intel_dmc_regs.h @@ -21,6 +21,20 @@ #define MTL_PIPEDMC_CONTROL _MMIO(0x45250) #define PIPEDMC_ENABLE_MTL(pipe) REG_BIT(((pipe) - PIPE_A) * 4) +#define _MTL_PIPEDMC_EVT_CTL_4_A 0x5f044 +#define _MTL_PIPEDMC_EVT_CTL_4_B 0x5f444 +#define MTL_PIPEDMC_EVT_CTL_4(pipe) _MMIO_PIPE(pipe, \ + _MTL_PIPEDMC_EVT_CTL_4_A, \ + _MTL_PIPEDMC_EVT_CTL_4_B) + +#define PIPEDMC_BLOCK_PKGC_SW_A 0x5f1d0 +#define PIPEDMC_BLOCK_PKGC_SW_B 0x5F5d0 +#define PIPEDMC_BLOCK_PKGC_SW(pipe) _MMIO_PIPE(pipe, \ + PIPEDMC_BLOCK_PKGC_SW_A, \ + PIPEDMC_BLOCK_PKGC_SW_B) +#define PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_ALWAYS BIT(31) +#define PIPEDMC_BLOCK_PKGC_SW_BLOCK_PKGC_UNTIL_NEXT_FRAMESTART BIT(15) + #define _ADLP_PIPEDMC_REG_MMIO_BASE_A 0x5f000 #define _TGL_PIPEDMC_REG_MMIO_BASE_A 0x92000 diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index d7a30d0992b7..593b29b56714 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -45,12 +45,13 @@ #include #include #include +#include #include #include "g4x_dp.h" -#include "i915_drv.h" #include "i915_irq.h" #include "i915_reg.h" +#include "i915_utils.h" #include "intel_alpm.h" #include "intel_atomic.h" #include "intel_audio.h" @@ -58,6 +59,7 @@ #include "intel_combo_phy_regs.h" #include "intel_connector.h" #include "intel_crtc.h" +#include "intel_crtc_state_dump.h" #include "intel_cx0_phy.h" #include "intel_ddi.h" #include "intel_de.h" @@ -92,7 +94,6 @@ #include "intel_tc.h" #include "intel_vdsc.h" #include "intel_vrr.h" -#include "intel_crtc_state_dump.h" /* DP DSC throughput values used for slice count calculations KPixels/s */ #define DP_DSC_PEAK_PIXEL_RATE 2720000 @@ -3104,6 +3105,76 @@ intel_dp_queue_modeset_retry_for_link(struct intel_atomic_state *state, } } +int intel_dp_compute_min_hblank(struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + const struct drm_display_mode *adjusted_mode = + &crtc_state->hw.adjusted_mode; + struct intel_connector *connector = to_intel_connector(conn_state->connector); + int symbol_size = intel_dp_is_uhbr(crtc_state) ? 32 : 8; + /* + * min symbol cycles is 3(BS,VBID, BE) for 128b/132b and + * 5(BS, VBID, MVID, MAUD, BE) for 8b/10b + */ + int min_sym_cycles = intel_dp_is_uhbr(crtc_state) ? 3 : 5; + bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); + int num_joined_pipes = intel_crtc_num_joined_pipes(crtc_state); + int min_hblank; + int max_lane_count = 4; + int hactive_sym_cycles, htotal_sym_cycles; + int dsc_slices = 0; + int link_bpp_x16; + + if (DISPLAY_VER(display) < 30) + return 0; + + /* MIN_HBLANK should be set only for 8b/10b MST or for 128b/132b SST/MST */ + if (!is_mst && !intel_dp_is_uhbr(crtc_state)) + return 0; + + if (crtc_state->dsc.compression_enable) { + dsc_slices = intel_dp_dsc_get_slice_count(connector, + adjusted_mode->crtc_clock, + adjusted_mode->crtc_hdisplay, + num_joined_pipes); + if (!dsc_slices) { + drm_dbg(display->drm, "failed to calculate dsc slice count\n"); + return -EINVAL; + } + } + + if (crtc_state->dsc.compression_enable) + link_bpp_x16 = crtc_state->dsc.compressed_bpp_x16; + else + link_bpp_x16 = fxp_q4_from_int(intel_dp_output_bpp(crtc_state->output_format, + crtc_state->pipe_bpp)); + + /* Calculate min Hblank Link Layer Symbol Cycle Count for 8b/10b MST & 128b/132b */ + hactive_sym_cycles = drm_dp_link_symbol_cycles(max_lane_count, + adjusted_mode->hdisplay, + dsc_slices, + link_bpp_x16, + symbol_size, is_mst); + htotal_sym_cycles = adjusted_mode->htotal * hactive_sym_cycles / + adjusted_mode->hdisplay; + + min_hblank = htotal_sym_cycles - hactive_sym_cycles; + /* minimum Hblank calculation: https://groups.vesa.org/wg/DP/document/20494 */ + min_hblank = max(min_hblank, min_sym_cycles); + + /* + * adjust the BlankingStart/BlankingEnd framing control from + * the calculated value + */ + min_hblank = min_hblank - 2; + + min_hblank = min(10, min_hblank); + crtc_state->min_hblank = min_hblank; + + return 0; +} + int intel_dp_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, @@ -3203,6 +3274,10 @@ intel_dp_compute_config(struct intel_encoder *encoder, &pipe_config->dp_m_n); } + ret = intel_dp_compute_min_hblank(pipe_config, conn_state); + if (ret) + return ret; + /* FIXME: abstract this better */ if (pipe_config->splitter.enable) pipe_config->dp_m_n.data_m *= pipe_config->splitter.link_count; @@ -5392,6 +5467,11 @@ intel_dp_short_pulse(struct intel_dp *intel_dp) intel_psr_short_pulse(intel_dp); + if (intel_alpm_get_error(intel_dp)) { + intel_alpm_disable(intel_dp); + intel_dp->alpm_parameters.sink_alpm_error = true; + } + if (intel_dp_test_short_pulse(intel_dp)) reprobe_needed = true; @@ -5827,20 +5907,21 @@ out_vdd_off: } static void -intel_dp_force(struct drm_connector *connector) +intel_dp_force(struct drm_connector *_connector) { - struct intel_display *display = to_intel_display(connector->dev); - struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector)); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n", - connector->base.id, connector->name); + connector->base.base.id, connector->base.name); if (!intel_display_driver_check_access(display)) return; intel_dp_unset_edid(intel_dp); - if (connector->status != connector_status_connected) + if (connector->base.status != connector_status_connected) return; intel_dp_set_edid(intel_dp); @@ -5879,24 +5960,25 @@ static int intel_dp_get_modes(struct drm_connector *_connector) } static int -intel_dp_connector_register(struct drm_connector *connector) +intel_dp_connector_register(struct drm_connector *_connector) { - struct intel_display *display = to_intel_display(connector->dev); - struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector)); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); int ret; - ret = intel_connector_register(connector); + ret = intel_connector_register(&connector->base); if (ret) return ret; drm_dbg_kms(display->drm, "registering %s bus for %s\n", - intel_dp->aux.name, connector->kdev->kobj.name); + intel_dp->aux.name, connector->base.kdev->kobj.name); - intel_dp->aux.dev = connector->kdev; + intel_dp->aux.dev = connector->base.kdev; ret = drm_dp_aux_register(&intel_dp->aux); if (!ret) - drm_dp_cec_register_connector(&intel_dp->aux, connector); + drm_dp_cec_register_connector(&intel_dp->aux, &connector->base); if (!intel_bios_encoder_is_lspcon(dig_port->base.devdata)) return ret; @@ -5907,20 +5989,21 @@ intel_dp_connector_register(struct drm_connector *connector) */ if (intel_lspcon_init(dig_port)) { if (intel_lspcon_detect_hdr_capability(dig_port)) - drm_connector_attach_hdr_output_metadata_property(connector); + drm_connector_attach_hdr_output_metadata_property(&connector->base); } return ret; } static void -intel_dp_connector_unregister(struct drm_connector *connector) +intel_dp_connector_unregister(struct drm_connector *_connector) { - struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector)); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_dp *intel_dp = intel_attached_dp(connector); drm_dp_cec_unregister_connector(&intel_dp->aux); drm_dp_aux_unregister(&intel_dp->aux); - intel_connector_unregister(connector); + intel_connector_unregister(&connector->base); } void intel_dp_connector_sync_state(struct intel_connector *connector, @@ -5981,21 +6064,21 @@ static int intel_modeset_tile_group(struct intel_atomic_state *state, { struct intel_display *display = to_intel_display(state); struct drm_connector_list_iter conn_iter; - struct drm_connector *connector; + struct intel_connector *connector; int ret = 0; drm_connector_list_iter_begin(display->drm, &conn_iter); - drm_for_each_connector_iter(connector, &conn_iter) { + for_each_intel_connector_iter(connector, &conn_iter) { struct drm_connector_state *conn_state; struct intel_crtc_state *crtc_state; struct intel_crtc *crtc; - if (!connector->has_tile || - connector->tile_group->id != tile_group_id) + if (!connector->base.has_tile || + connector->base.tile_group->id != tile_group_id) continue; conn_state = drm_atomic_get_connector_state(&state->base, - connector); + &connector->base); if (IS_ERR(conn_state)) { ret = PTR_ERR(conn_state); break; @@ -6059,10 +6142,11 @@ static int intel_modeset_affected_transcoders(struct intel_atomic_state *state, } static int intel_modeset_synced_crtcs(struct intel_atomic_state *state, - struct drm_connector *connector) + struct drm_connector *_connector) { + struct intel_connector *connector = to_intel_connector(_connector); const struct drm_connector_state *old_conn_state = - drm_atomic_get_old_connector_state(&state->base, connector); + drm_atomic_get_old_connector_state(&state->base, &connector->base); const struct intel_crtc_state *old_crtc_state; struct intel_crtc *crtc; u8 transcoders; @@ -6084,17 +6168,18 @@ static int intel_modeset_synced_crtcs(struct intel_atomic_state *state, transcoders); } -static int intel_dp_connector_atomic_check(struct drm_connector *conn, +static int intel_dp_connector_atomic_check(struct drm_connector *_connector, struct drm_atomic_state *_state) { - struct intel_display *display = to_intel_display(conn->dev); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector); struct intel_atomic_state *state = to_intel_atomic_state(_state); - struct drm_connector_state *conn_state = drm_atomic_get_new_connector_state(_state, conn); - struct intel_connector *intel_conn = to_intel_connector(conn); - struct intel_dp *intel_dp = enc_to_intel_dp(intel_conn->encoder); + struct drm_connector_state *conn_state = + drm_atomic_get_new_connector_state(_state, &connector->base); + struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder); int ret; - ret = intel_digital_connector_atomic_check(conn, &state->base); + ret = intel_digital_connector_atomic_check(&connector->base, &state->base); if (ret) return ret; @@ -6104,12 +6189,12 @@ static int intel_dp_connector_atomic_check(struct drm_connector *conn, return ret; } - if (!intel_connector_needs_modeset(state, conn)) + if (!intel_connector_needs_modeset(state, &connector->base)) return 0; ret = intel_dp_tunnel_atomic_check_state(state, intel_dp, - intel_conn); + connector); if (ret) return ret; @@ -6120,26 +6205,26 @@ static int intel_dp_connector_atomic_check(struct drm_connector *conn, if (DISPLAY_VER(display) < 9) return 0; - if (conn->has_tile) { - ret = intel_modeset_tile_group(state, conn->tile_group->id); + if (connector->base.has_tile) { + ret = intel_modeset_tile_group(state, connector->base.tile_group->id); if (ret) return ret; } - return intel_modeset_synced_crtcs(state, conn); + return intel_modeset_synced_crtcs(state, &connector->base); } -static void intel_dp_oob_hotplug_event(struct drm_connector *connector, +static void intel_dp_oob_hotplug_event(struct drm_connector *_connector, enum drm_connector_status hpd_state) { - struct intel_display *display = to_intel_display(connector->dev); - struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector)); - struct drm_i915_private *i915 = to_i915(connector->dev); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector); + struct intel_encoder *encoder = intel_attached_encoder(connector); bool hpd_high = hpd_state == connector_status_connected; unsigned int hpd_pin = encoder->hpd_pin; bool need_work = false; - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); if (hpd_high != test_bit(hpd_pin, &display->hotplug.oob_hotplug_last_state)) { display->hotplug.event_bits |= BIT(hpd_pin); @@ -6148,7 +6233,7 @@ static void intel_dp_oob_hotplug_event(struct drm_connector *connector, hpd_high); need_work = true; } - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); if (need_work) intel_hpd_schedule_detection(display); @@ -6280,36 +6365,37 @@ intel_dp_has_gamut_metadata_dip(struct intel_encoder *encoder) } static void -intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector) +intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *_connector) { + struct intel_connector *connector = to_intel_connector(_connector); struct intel_display *display = to_intel_display(intel_dp); enum port port = dp_to_dig_port(intel_dp)->base.port; if (!intel_dp_is_edp(intel_dp)) - drm_connector_attach_dp_subconnector_property(connector); + drm_connector_attach_dp_subconnector_property(&connector->base); if (!display->platform.g4x && port != PORT_A) - intel_attach_force_audio_property(connector); + intel_attach_force_audio_property(&connector->base); - intel_attach_broadcast_rgb_property(connector); + intel_attach_broadcast_rgb_property(&connector->base); if (HAS_GMCH(display)) - drm_connector_attach_max_bpc_property(connector, 6, 10); + drm_connector_attach_max_bpc_property(&connector->base, 6, 10); else if (DISPLAY_VER(display) >= 5) - drm_connector_attach_max_bpc_property(connector, 6, 12); + drm_connector_attach_max_bpc_property(&connector->base, 6, 12); /* Register HDMI colorspace for case of lspcon */ if (intel_bios_encoder_is_lspcon(dp_to_dig_port(intel_dp)->base.devdata)) { - drm_connector_attach_content_type_property(connector); - intel_attach_hdmi_colorspace_property(connector); + drm_connector_attach_content_type_property(&connector->base); + intel_attach_hdmi_colorspace_property(&connector->base); } else { - intel_attach_dp_colorspace_property(connector); + intel_attach_dp_colorspace_property(&connector->base); } if (intel_dp_has_gamut_metadata_dip(&dp_to_dig_port(intel_dp)->base)) - drm_connector_attach_hdr_output_metadata_property(connector); + drm_connector_attach_hdr_output_metadata_property(&connector->base); if (HAS_VRR(display)) - drm_connector_attach_vrr_capable_property(connector); + drm_connector_attach_vrr_capable_property(&connector->base); } static void @@ -6344,7 +6430,6 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, struct intel_connector *connector) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct drm_display_mode *fixed_mode; struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; bool has_dpcd; @@ -6361,7 +6446,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, */ if (intel_get_lvds_encoder(display)) { drm_WARN_ON(display->drm, - !(HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv))); + !(HAS_PCH_IBX(display) || HAS_PCH_CPT(display))); drm_info(display->drm, "LVDS was detected, not registering eDP\n"); @@ -6392,7 +6477,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, */ intel_hpd_enable_detection(encoder); - intel_alpm_init_dpcd(intel_dp); + intel_alpm_init(intel_dp); /* Cache DPCD and EDID for edp. */ has_dpcd = intel_edp_init_dpcd(intel_dp, connector); diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 9189db4c2594..a7cc10800e0b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -208,5 +208,7 @@ bool intel_dp_has_connector(struct intel_dp *intel_dp, const struct drm_connector_state *conn_state); int intel_dp_dsc_max_src_input_bpc(struct intel_display *display); int intel_dp_dsc_min_src_input_bpc(void); +int intel_dp_compute_min_hblank(struct intel_crtc_state *crtc_state, + const struct drm_connector_state *conn_state); #endif /* __INTEL_DP_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c index 0496061203fb..bf8e8e0cc19c 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c @@ -3,8 +3,10 @@ * Copyright © 2020-2021 Intel Corporation */ -#include "i915_drv.h" +#include + #include "i915_reg.h" +#include "i915_utils.h" #include "intel_de.h" #include "intel_display_types.h" #include "intel_dp.h" @@ -111,10 +113,9 @@ static u32 ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index) static u32 hsw_get_aux_clock_divider(struct intel_dp *intel_dp, int index) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - if (dig_port->aux_ch != AUX_CH_A && HAS_PCH_LPT_H(i915)) { + if (dig_port->aux_ch != AUX_CH_A && HAS_PCH_LPT_H(display)) { /* Workaround for non-ULT HSW */ switch (index) { case 0: return 63; @@ -177,12 +178,11 @@ static u32 g4x_get_aux_send_ctl(struct intel_dp *intel_dp, int send_bytes, u32 aux_clock_divider) { - struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(intel_dp); u32 timeout; /* Max timeout value on G4x-BDW: 1.6ms */ - if (IS_BROADWELL(i915)) + if (display->platform.broadwell) timeout = DP_AUX_CH_CTL_TIME_OUT_600us; else timeout = DP_AUX_CH_CTL_TIME_OUT_400us; @@ -786,7 +786,6 @@ void intel_dp_aux_fini(struct intel_dp *intel_dp) void intel_dp_aux_init(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *encoder = &dig_port->base; enum aux_ch aux_ch = dig_port->aux_ch; @@ -801,10 +800,10 @@ void intel_dp_aux_init(struct intel_dp *intel_dp) } else if (DISPLAY_VER(display) >= 9) { intel_dp->aux_ch_ctl_reg = skl_aux_ctl_reg; intel_dp->aux_ch_data_reg = skl_aux_data_reg; - } else if (HAS_PCH_SPLIT(i915)) { + } else if (HAS_PCH_SPLIT(display)) { intel_dp->aux_ch_ctl_reg = ilk_aux_ctl_reg; intel_dp->aux_ch_data_reg = ilk_aux_data_reg; - } else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) { + } else if (display->platform.valleyview || display->platform.cherryview) { intel_dp->aux_ch_ctl_reg = vlv_aux_ctl_reg; intel_dp->aux_ch_data_reg = vlv_aux_data_reg; } else { @@ -814,9 +813,9 @@ void intel_dp_aux_init(struct intel_dp *intel_dp) if (DISPLAY_VER(display) >= 9) intel_dp->get_aux_clock_divider = skl_get_aux_clock_divider; - else if (IS_BROADWELL(i915) || IS_HASWELL(i915)) + else if (display->platform.broadwell || display->platform.haswell) intel_dp->get_aux_clock_divider = hsw_get_aux_clock_divider; - else if (HAS_PCH_SPLIT(i915)) + else if (HAS_PCH_SPLIT(display)) intel_dp->get_aux_clock_divider = ilk_get_aux_clock_divider; else intel_dp->get_aux_clock_divider = g4x_get_aux_clock_divider; diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c index 20ab90acb351..271b27c9de51 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c @@ -36,7 +36,6 @@ #include -#include "i915_utils.h" #include "intel_backlight.h" #include "intel_display_core.h" #include "intel_display_types.h" @@ -149,7 +148,7 @@ intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector) !(connector->base.hdr_sink_metadata.hdmi_type1.metadata_type & BIT(HDMI_STATIC_METADATA_TYPE1))) { drm_info(display->drm, - "[CONNECTOR:%d:%s] Panel is missing HDR static metadata. Possible support for Intel HDR backlight interface is not used. If your backlight controls don't work try booting with i915.enable_dpcd_backlight=%d. needs this, please file a _new_ bug report on drm/i915, see " FDO_BUG_URL " for details.\n", + "[CONNECTOR:%d:%s] Panel is missing HDR static metadata. Possible support for Intel HDR backlight interface is not used. If your backlight controls don't work try booting with i915.enable_dpcd_backlight=%d.\n", connector->base.base.id, connector->base.name, INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL); return false; diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 4c15dcb103aa..aeda59f5fa7a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -27,10 +27,11 @@ #include #include #include +#include #include -#include "i915_drv.h" #include "i915_reg.h" +#include "i915_utils.h" #include "intel_atomic.h" #include "intel_audio.h" #include "intel_connector.h" @@ -51,6 +52,7 @@ #include "intel_link_bw.h" #include "intel_pfit.h" #include "intel_psr.h" +#include "intel_step.h" #include "intel_vdsc.h" #include "intel_vrr.h" #include "skl_scaler.h" @@ -239,26 +241,6 @@ static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connec num_joined_pipes); } -static void intel_dp_mst_compute_min_hblank(struct intel_crtc_state *crtc_state, - int bpp_x16) -{ - struct intel_display *display = to_intel_display(crtc_state); - const struct drm_display_mode *adjusted_mode = - &crtc_state->hw.adjusted_mode; - int symbol_size = intel_dp_is_uhbr(crtc_state) ? 32 : 8; - int hblank; - - if (DISPLAY_VER(display) < 20) - return; - - /* Calculate min Hblank Link Layer Symbol Cycle Count for 8b/10b MST & 128b/132b */ - hblank = DIV_ROUND_UP((DIV_ROUND_UP - (adjusted_mode->htotal - adjusted_mode->hdisplay, 4) * bpp_x16), - symbol_size); - - crtc_state->min_hblank = hblank; -} - int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state, @@ -329,8 +311,6 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, false, dsc_slice_count, link_bpp_x16); - intel_dp_mst_compute_min_hblank(crtc_state, link_bpp_x16); - intel_dp_mst_compute_m_n(crtc_state, local_bw_overhead, link_bpp_x16, @@ -739,6 +719,10 @@ static int mst_stream_compute_config(struct intel_encoder *encoder, pipe_config->lane_lat_optim_mask = bxt_dpio_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); + ret = intel_dp_compute_min_hblank(pipe_config, conn_state); + if (ret) + return ret; + intel_vrr_compute_config(pipe_config, conn_state); intel_dp_audio_compute_config(encoder, pipe_config, conn_state); @@ -1021,12 +1005,10 @@ static void mst_stream_disable(struct intel_atomic_state *state, const struct intel_crtc_state *old_crtc_state, const struct drm_connector_state *old_conn_state) { - struct intel_display *display = to_intel_display(state); struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); struct intel_dp *intel_dp = to_primary_dp(encoder); struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - enum transcoder trans = old_crtc_state->cpu_transcoder; if (intel_dp_mst_active_streams(intel_dp) == 1) intel_dp->link.active = false; @@ -1034,9 +1016,6 @@ static void mst_stream_disable(struct intel_atomic_state *state, intel_hdcp_disable(intel_mst->connector); intel_dp_sink_disable_decompression(state, connector, old_crtc_state); - - if (DISPLAY_VER(display) >= 20) - intel_de_write(display, DP_MIN_HBLANK_CTL(trans), 0); } static void mst_stream_post_disable(struct intel_atomic_state *state, @@ -1305,7 +1284,7 @@ static void mst_stream_enable(struct intel_atomic_state *state, enum transcoder trans = pipe_config->cpu_transcoder; bool first_mst_stream = intel_dp_mst_active_streams(intel_dp) == 1; struct intel_crtc *pipe_crtc; - int ret, i, min_hblank; + int ret, i; drm_WARN_ON(display->drm, pipe_config->has_pch_encoder); @@ -1320,29 +1299,6 @@ static void mst_stream_enable(struct intel_atomic_state *state, TRANS_DP2_VFREQ_PIXEL_CLOCK(crtc_clock_hz & 0xffffff)); } - if (DISPLAY_VER(display) >= 20) { - /* - * adjust the BlankingStart/BlankingEnd framing control from - * the calculated value - */ - min_hblank = pipe_config->min_hblank - 2; - - /* Maximum value to be programmed is limited to 0x10 */ - min_hblank = min(0x10, min_hblank); - - /* - * Minimum hblank accepted for 128b/132b would be 5 and for - * 8b/10b would be 3 symbol count - */ - if (intel_dp_is_uhbr(pipe_config)) - min_hblank = max(min_hblank, 5); - else - min_hblank = max(min_hblank, 3); - - intel_de_write(display, DP_MIN_HBLANK_CTL(trans), - min_hblank); - } - enable_bs_jitter_was(pipe_config); intel_ddi_enable_transcoder_func(encoder, pipe_config); diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c b/drivers/gpu/drm/i915/display/intel_dpio_phy.c index 429f89543789..69f242139420 100644 --- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c +++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c @@ -222,9 +222,7 @@ static const struct bxt_dpio_phy_info glk_dpio_phy_info[] = { static const struct bxt_dpio_phy_info * bxt_get_phy_list(struct intel_display *display, int *count) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - - if (IS_GEMINILAKE(dev_priv)) { + if (display->platform.geminilake) { *count = ARRAY_SIZE(glk_dpio_phy_info); return glk_dpio_phy_info; } else { @@ -808,9 +806,9 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder, vlv_dpio_put(dev_priv); } -void chv_data_lane_soft_reset(struct intel_encoder *encoder, - const struct intel_crtc_state *crtc_state, - bool reset) +static void __chv_data_lane_soft_reset(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + bool reset) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); @@ -853,6 +851,17 @@ void chv_data_lane_soft_reset(struct intel_encoder *encoder, } } +void chv_data_lane_soft_reset(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, + bool reset) +{ + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + + vlv_dpio_get(i915); + __chv_data_lane_soft_reset(encoder, crtc_state, reset); + vlv_dpio_put(i915); +} + void chv_phy_pre_pll_enable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { @@ -880,7 +889,7 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder, vlv_dpio_get(dev_priv); /* Assert data lane reset */ - chv_data_lane_soft_reset(encoder, crtc_state, true); + __chv_data_lane_soft_reset(encoder, crtc_state, true); /* program left/right clock distribution */ if (pipe != PIPE_B) { @@ -1008,7 +1017,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder, } /* Deassert data lane reset */ - chv_data_lane_soft_reset(encoder, crtc_state, false); + __chv_data_lane_soft_reset(encoder, crtc_state, false); vlv_dpio_put(dev_priv); } diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 0481b1365b85..a9e9b98d0bf9 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -374,12 +374,11 @@ int chv_calc_dpll_params(int refclk, struct dpll *clock) static int i9xx_pll_refclk(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; if ((hw_state->dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) return display->vbt.lvds_ssc_freq; - else if (HAS_PCH_SPLIT(i915)) + else if (HAS_PCH_SPLIT(display)) return 120000; else if (DISPLAY_VER(display) != 2) return 96000; @@ -1235,12 +1234,10 @@ static int mtl_crtc_compute_clock(struct intel_atomic_state *state, static int ilk_fb_cb_factor(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) && ((intel_panel_use_ssc(display) && display->vbt.lvds_ssc_freq == 100000) || - (HAS_PCH_IBX(i915) && intel_is_dual_link_lvds(display)))) + (HAS_PCH_IBX(display) && intel_is_dual_link_lvds(display)))) return 25; if (crtc_state->sdvo_tv_clock) @@ -1791,15 +1788,13 @@ int intel_dpll_crtc_get_shared_dpll(struct intel_atomic_state *state, void intel_dpll_init_clock_hook(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (DISPLAY_VER(display) >= 14) display->funcs.dpll = &mtl_dpll_funcs; else if (display->platform.dg2) display->funcs.dpll = &dg2_dpll_funcs; else if (DISPLAY_VER(display) >= 9 || HAS_DDI(display)) display->funcs.dpll = &hsw_dpll_funcs; - else if (HAS_PCH_SPLIT(dev_priv)) + else if (HAS_PCH_SPLIT(display)) display->funcs.dpll = &ilk_dpll_funcs; else if (display->platform.cherryview) display->funcs.dpll = &chv_dpll_funcs; diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index 84df41086a89..9da051a3f455 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -24,9 +24,11 @@ #include #include +#include + #include "bxt_dpio_phy_regs.h" -#include "i915_drv.h" #include "i915_reg.h" +#include "i915_utils.h" #include "intel_cx0_phy.h" #include "intel_de.h" #include "intel_display_types.h" @@ -38,6 +40,7 @@ #include "intel_hti.h" #include "intel_mg_phy_regs.h" #include "intel_pch_refclk.h" +#include "intel_step.h" #include "intel_tc.h" /** @@ -609,13 +612,12 @@ static int ibx_get_dpll(struct intel_atomic_state *state, struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_shared_dpll *pll; enum intel_dpll_id id; - if (HAS_PCH_IBX(i915)) { + if (HAS_PCH_IBX(display)) { /* Ironlake PCH has a fixed PLL->PCH pipe mapping. */ id = (enum intel_dpll_id) crtc->pipe; pll = intel_get_shared_dpll_by_id(display, id); @@ -4305,7 +4307,6 @@ static const struct intel_dpll_mgr adlp_pll_mgr = { */ void intel_shared_dpll_init(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); const struct intel_dpll_mgr *dpll_mgr = NULL; const struct dpll_info *dpll_info; int i; @@ -4335,7 +4336,7 @@ void intel_shared_dpll_init(struct intel_display *display) dpll_mgr = &skl_pll_mgr; else if (HAS_DDI(display)) dpll_mgr = &hsw_pll_mgr; - else if (HAS_PCH_IBX(i915) || HAS_PCH_CPT(i915)) + else if (HAS_PCH_IBX(display) || HAS_PCH_CPT(display)) dpll_mgr = &pch_pll_mgr; if (!dpll_mgr) diff --git a/drivers/gpu/drm/i915/display/intel_dpt_common.c b/drivers/gpu/drm/i915/display/intel_dpt_common.c index d2dede0a5229..ce5aa0ca0fa5 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt_common.c +++ b/drivers/gpu/drm/i915/display/intel_dpt_common.c @@ -3,7 +3,6 @@ * Copyright © 2023 Intel Corporation */ -#include "i915_drv.h" #include "i915_reg.h" #include "intel_de.h" #include "intel_display_types.h" @@ -12,9 +11,9 @@ void intel_dpt_configure(struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); - if (DISPLAY_VER(i915) == 14) { + if (DISPLAY_VER(display) == 14) { enum pipe pipe = crtc->pipe; enum plane_id plane_id; @@ -22,15 +21,15 @@ void intel_dpt_configure(struct intel_crtc *crtc) if (plane_id == PLANE_CURSOR) continue; - intel_de_rmw(i915, PLANE_CHICKEN(pipe, plane_id), + intel_de_rmw(display, PLANE_CHICKEN(pipe, plane_id), PLANE_CHICKEN_DISABLE_DPT, - i915->display.params.enable_dpt ? 0 : + display->params.enable_dpt ? 0 : PLANE_CHICKEN_DISABLE_DPT); } - } else if (DISPLAY_VER(i915) == 13) { - intel_de_rmw(i915, CHICKEN_MISC_2, + } else if (DISPLAY_VER(display) == 13) { + intel_de_rmw(display, CHICKEN_MISC_2, CHICKEN_MISC_DISABLE_DPT, - i915->display.params.enable_dpt ? 0 : + display->params.enable_dpt ? 0 : CHICKEN_MISC_DISABLE_DPT); } } diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 72fe390c5af2..481488d1fe67 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -4,11 +4,12 @@ * */ +#include #include -#include "i915_drv.h" #include "i915_irq.h" #include "i915_reg.h" +#include "i915_utils.h" #include "intel_crtc.h" #include "intel_de.h" #include "intel_display_rpm.h" diff --git a/drivers/gpu/drm/i915/display/intel_dsi.c b/drivers/gpu/drm/i915/display/intel_dsi.c index 403151175a87..a8f012119165 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi.c +++ b/drivers/gpu/drm/i915/display/intel_dsi.c @@ -4,8 +4,9 @@ */ #include +#include -#include "i915_drv.h" +#include "intel_display_core.h" #include "intel_dsi.h" #include "intel_panel.h" @@ -116,14 +117,14 @@ struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi, enum drm_panel_orientation intel_dsi_get_panel_orientation(struct intel_connector *connector) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); enum drm_panel_orientation orientation; orientation = connector->panel.vbt.dsi.orientation; if (orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN) return orientation; - orientation = dev_priv->display.vbt.orientation; + orientation = display->vbt.orientation; if (orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN) return orientation; diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c index 4e92504f5c14..29c920983413 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c @@ -31,16 +31,16 @@ #include #include #include - #include #include #include +#include #include