diff options
author | Dave Airlie <airlied@redhat.com> | 2025-05-09 23:10:04 +0300 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2025-05-09 23:12:18 +0300 |
commit | 806690425a5caa6ffc9c2460192b0d02947da863 (patch) | |
tree | ee0043d4938ab1192f982e6fb7d329f83b4e47ce | |
parent | 67322d35c39adbbf76737f706d05b727cf7eb7ac (diff) | |
parent | ecd9352cd92784717670e22a5ebd890ca0ae980e (diff) | |
download | linux-806690425a5caa6ffc9c2460192b0d02947da863.tar.xz |
Merge tag 'drm-intel-next-2025-05-08' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next
Non-display related:
- Fix undefined reference to `intel_pxp_gsccs_is_ready_for_sessions'
Display related:
- More work towards display separation (Jani)
- Stop writing VRR_CTL_IGN_MAX_SHIFT for MTL onwards (Jouni)
- DSC checks for 3 engines (Ankit)
- Add link rate and lane count to i915_display_info (Khaled)
- PSR fixes and workaround for underrun on idle (Jouni)
- LOBF enablement and ALMP fixes (Animesh)
- Clean up VGA plane handling (Ville)
- Use an intel_connector pointer everywhere (Imre)
- Fix warning for coffeelake on SunrisePoint PCH (Jiajia)
- Rework/Correction on minimum hblank calculation (Arun)
- Dmesg clean up (Jani)
- Add a couple of simple display workarounds (Ankit, Vinod)
- Refactor HDCP GSC (Jani)
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://lore.kernel.org/r/aByyL3bEufPu79OM@intel.com
118 files changed, 2636 insertions, 2317 deletions
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 <linux/string_helpers.h> +#include <drm/drm_print.h> + #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 <drm/drm_print.h> + #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 <drm/drm_atomic_helper.h> #include <drm/drm_blend.h> #include <drm/drm_fourcc.h> +#include <drm/drm_print.h> -#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 <linux/debugfs.h> +#include <drm/drm_print.h> + #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 <drm/drm_edid.h> #include <drm/drm_eld.h> #include <drm/drm_fixed.h> +#include <drm/drm_print.h> #include <drm/intel/i915_component.h> -#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 <acpi/video.h> -#include "i915_drv.h" +#include <drm/drm_file.h> +#include <drm/drm_print.h> + #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 <drm/drm_device.h> #include <drm/drm_print.h> -#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 <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> #include <drm/drm_edid.h> +#include <drm/drm_print.h> #include <drm/drm_probe_helper.h> -#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 <drm/drm_blend.h> #include <drm/drm_damage_helper.h> #include <drm/drm_fourcc.h> +#include <drm/drm_print.h> #include <drm/drm_vblank.h> -#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 <linux/log2.h> #include <linux/math64.h> -#include "i915_drv.h" +#include <drm/drm_print.h> + #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 <drm/display/drm_dp_helper.h> #include <drm/display/drm_scdc_helper.h> +#include <drm/drm_print.h> #include <drm/drm_privacy_screen_consumer.h> -#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 <linux/string_helpers.h> #include <drm/drm_debugfs.h> +#include <drm/drm_drv.h> #include <drm/drm_edid.h> +#include <drm/drm_file.h> #include <drm/drm_fourcc.h> #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 <drm/intel/pciids.h> -#include <drm/drm_color_mgmt.h> #include <linux/pci.h> -#include "i915_drv.h" +#include <drm/drm_color_mgmt.h> +#include <drm/drm_drv.h> +#include <drm/drm_print.h> +#include <drm/intel/pciids.h> + #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 <drm/drm_vblank.h> -#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 <drm/drm_crtc.h> #include <drm/drm_edid.h> #include <drm/drm_fixed.h> +#include <drm/drm_print.h> #include <drm/drm_probe_helper.h> #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 <drm/drm_print.h> + #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 <drm/drm_print.h> -#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 <drm/drm_atomic_helper.h> #include <drm/drm_edid.h> #include <drm/drm_fixed.h> +#include <drm/drm_print.h> #include <drm/drm_probe_helper.h> -#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 <linux/math.h> #include <linux/string_helpers.h> +#include <drm/drm_print.h> + #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 <drm/drm_print.h> #include <drm/drm_vblank.h> -#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 <drm/drm_mipi_dsi.h> +#include <drm/drm_print.h> -#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 <linux/pinctrl/machine.h> #include <linux/slab.h> #include <linux/string_helpers.h> - #include <linux/unaligned.h> #include <drm/drm_crtc.h> #include <drm/drm_edid.h> +#include <drm/drm_print.h> #include <video/mipi_display.h> -#include "i915_drv.h" #include "i915_reg.h" +#include "i915_utils.h" #include "intel_de.h" #include "intel_display_types.h" #include "intel_dsi.h" @@ -321,7 +321,6 @@ enum { static void icl_native_gpio_set_value(struct intel_display *display, int gpio, bool value) { - struct drm_i915_private *dev_priv = to_i915(display->drm); int index; if (drm_WARN_ON(display->drm, DISPLAY_VER(display) == 11 && gpio >= MIPI_RESET_2)) @@ -341,12 +340,12 @@ static void icl_native_gpio_set_value(struct intel_display *display, * The locking protects against concurrent SHOTPLUG_CTL_DDI * modifications in irq setup and handling. */ - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); intel_de_rmw(display, SHOTPLUG_CTL_DDI, SHOTPLUG_CTL_DDI_HPD_ENABLE(index) | SHOTPLUG_CTL_DDI_HPD_OUTPUT_DATA(index), value ? SHOTPLUG_CTL_DDI_HPD_OUTPUT_DATA(index) : 0); - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); break; case MIPI_AVDD_EN_1: case MIPI_AVDD_EN_2: diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 2b0e0f220442..05393bd60c98 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -560,11 +560,11 @@ static bool plane_has_modifier(struct intel_display *display, return false; if (md->modifier == I915_FORMAT_MOD_4_TILED_BMG_CCS && - (GRAPHICS_VER(i915) < 20 || !IS_DGFX(i915))) + (GRAPHICS_VER(i915) < 20 || !display->platform.dgfx)) return false; if (md->modifier == I915_FORMAT_MOD_4_TILED_LNL_CCS && - (GRAPHICS_VER(i915) < 20 || IS_DGFX(i915))) + (GRAPHICS_VER(i915) < 20 || display->platform.dgfx)) return false; return true; diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index ce5b1e3f1c20..bed2bba20b55 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -252,9 +252,12 @@ static u16 intel_fbc_override_cfb_stride(const struct intel_plane_state *plane_s * Gen9 hw miscalculates cfb stride for linear as * PLANE_STRIDE*512 instead of PLANE_STRIDE*64, so * we always need to use the override there. + * + * wa_14022269668 For bmg, always program the FBC_STRIDE before fbc enable */ if (stride != stride_aligned || - (DISPLAY_VER(display) == 9 && fb->modifier == DRM_FORMAT_MOD_LINEAR)) + (DISPLAY_VER(display) == 9 && fb->modifier == DRM_FORMAT_MOD_LINEAR) || + display->platform.battlemage) return stride_aligned * 4 / 64; return 0; diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 369f46286e95..2dc4029d71ed 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -47,9 +47,9 @@ #include <drm/drm_managed.h> #include <drm/drm_print.h> -#include "i915_drv.h" #include "i915_vma.h" #include "intel_bo.h" +#include "intel_display_core.h" #include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_fb.h" @@ -66,9 +66,9 @@ struct intel_fbdev { static struct intel_fbdev *to_intel_fbdev(struct drm_fb_helper *fb_helper) { - struct drm_i915_private *i915 = to_i915(fb_helper->client.dev); + struct intel_display *display = to_intel_display(fb_helper->client.dev); - return i915->display.fbdev.fbdev; + return display->fbdev.fbdev; } static struct intel_frontbuffer *to_frontbuffer(struct intel_fbdev *ifbdev) @@ -210,11 +210,9 @@ static const struct drm_fb_helper_funcs intel_fb_helper_funcs = { int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { + struct intel_display *display = to_intel_display(helper->dev); struct intel_fbdev *ifbdev = to_intel_fbdev(helper); struct intel_framebuffer *fb = ifbdev->fb; - struct drm_device *dev = helper->dev; - struct drm_i915_private *dev_priv = to_i915(dev); - struct intel_display *display = to_intel_display(dev); struct ref_tracker *wakeref; struct fb_info *info; struct i915_vma *vma; @@ -228,7 +226,7 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, if (fb && (sizes->fb_width > fb->base.width || sizes->fb_height > fb->base.height)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "BIOS fb too small (%dx%d), we require (%dx%d)," " releasing it\n", fb->base.width, fb->base.height, @@ -236,14 +234,14 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, drm_framebuffer_put(&fb->base); fb = NULL; } - if (!fb || drm_WARN_ON(dev, !intel_fb_bo(&fb->base))) { - drm_dbg_kms(&dev_priv->drm, + if (!fb || drm_WARN_ON(display->drm, !intel_fb_bo(&fb->base))) { + drm_dbg_kms(display->drm, "no BIOS fb, allocating a new one\n"); fb = intel_fbdev_fb_alloc(helper, sizes); if (IS_ERR(fb)) return PTR_ERR(fb); } else { - drm_dbg_kms(&dev_priv->drm, "re-using BIOS fb\n"); + drm_dbg_kms(display->drm, "re-using BIOS fb\n"); prealloc = true; sizes->fb_width = fb->base.width; sizes->fb_height = fb->base.height; @@ -267,7 +265,7 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, info = drm_fb_helper_alloc_info(helper); if (IS_ERR(info)) { - drm_err(&dev_priv->drm, "Failed to allocate fb_info (%pe)\n", info); + drm_err(display->drm, "Failed to allocate fb_info (%pe)\n", info); ret = PTR_ERR(info); goto out_unpin; } @@ -279,11 +277,11 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, obj = intel_fb_bo(&fb->base); - ret = intel_fbdev_fb_fill_info(dev_priv, info, obj, vma); + ret = intel_fbdev_fb_fill_info(display, info, obj, vma); if (ret) goto out_unpin; - drm_fb_helper_fill_info(info, dev->fb_helper, sizes); + drm_fb_helper_fill_info(info, display->drm->fb_helper, sizes); /* If the object is shmemfs backed, it will have given us zeroed pages. * If the object is stolen however, it will be full of whatever @@ -294,7 +292,7 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ - drm_dbg_kms(&dev_priv->drm, "allocated %dx%d fb: 0x%08x\n", + drm_dbg_kms(display->drm, "allocated %dx%d fb: 0x%08x\n", fb->base.width, fb->base.height, i915_ggtt_offset(vma)); ifbdev->fb = fb; @@ -322,16 +320,15 @@ out_unlock: * Note we only support a single fb shared across pipes for boot (mostly for * fbcon), so we just find the biggest and use that. */ -static bool intel_fbdev_init_bios(struct drm_device *dev, +static bool intel_fbdev_init_bios(struct intel_display *display, struct intel_fbdev *ifbdev) { - struct drm_i915_private *i915 = to_i915(dev); struct intel_framebuffer *fb = NULL; struct intel_crtc *crtc; unsigned int max_size = 0; /* Find the largest fb */ - for_each_intel_crtc(dev, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_plane *plane = @@ -341,21 +338,21 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, struct drm_gem_object *obj = intel_fb_bo(plane_state->uapi.fb); if (!crtc_state->uapi.active) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] not active, skipping\n", crtc->base.base.id, crtc->base.name); continue; } if (!obj) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] no fb, skipping\n", plane->base.base.id, plane->base.name); continue; } if (obj->size > max_size) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "found possible fb from [PLANE:%d:%s]\n", plane->base.base.id, plane->base.name); fb = to_intel_framebuffer(plane_state->uapi.fb); @@ -364,13 +361,13 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, } if (!fb) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "no active fbs found, not using BIOS config\n"); goto out; } /* Now make sure all the pipes will fit into it */ - for_each_intel_crtc(dev, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_plane *plane = @@ -378,13 +375,13 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, unsigned int cur_size; if (!crtc_state->uapi.active) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] not active, skipping\n", crtc->base.base.id, crtc->base.name); continue; } - drm_dbg_kms(&i915->drm, "checking [PLANE:%d:%s] for BIOS fb\n", + drm_dbg_kms(display->drm, "checking [PLANE:%d:%s] for BIOS fb\n", plane->base.base.id, plane->base.name); /* @@ -395,7 +392,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, cur_size = crtc_state->uapi.adjusted_mode.crtc_hdisplay; cur_size = cur_size * fb->base.format->cpp[0]; if (fb->base.pitches[0] < cur_size) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "fb not wide enough for [PLANE:%d:%s] (%d vs %d)\n", plane->base.base.id, plane->base.name, cur_size, fb->base.pitches[0]); @@ -406,7 +403,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, cur_size = crtc_state->uapi.adjusted_mode.crtc_vdisplay; cur_size = intel_fb_align_height(&fb->base, 0, cur_size); cur_size *= fb->base.pitches[0]; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] area: %dx%d, bpp: %d, size: %d\n", crtc->base.base.id, crtc->base.name, crtc_state->uapi.adjusted_mode.crtc_hdisplay, @@ -415,7 +412,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, cur_size); if (cur_size > max_size) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "fb not big enough for [PLANE:%d:%s] (%d vs %d)\n", plane->base.base.id, plane->base.name, cur_size, max_size); @@ -423,14 +420,14 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, break; } - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "fb big enough [PLANE:%d:%s] (%d >= %d)\n", plane->base.base.id, plane->base.name, max_size, cur_size); } if (!fb) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "BIOS fb not suitable for all pipes, not using\n"); goto out; } @@ -440,7 +437,7 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, drm_framebuffer_get(&ifbdev->fb->base); /* Final pass to check if any active pipes don't have fbs */ - for_each_intel_crtc(dev, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_plane *plane = @@ -451,13 +448,13 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, if (!crtc_state->uapi.active) continue; - drm_WARN(dev, !plane_state->uapi.fb, + drm_WARN(display->drm, !plane_state->uapi.fb, "re-used BIOS config but lost an fb on [PLANE:%d:%s]\n", plane->base.base.id, plane->base.name); } - drm_dbg_kms(&i915->drm, "using BIOS fb for initial console\n"); + drm_dbg_kms(display->drm, "using BIOS fb for initial console\n"); return true; out: @@ -482,26 +479,25 @@ static unsigned int intel_fbdev_color_mode(const struct drm_format_info *info) } } -void intel_fbdev_setup(struct drm_i915_private *i915) +void intel_fbdev_setup(struct intel_display *display) { - struct drm_device *dev = &i915->drm; struct intel_fbdev *ifbdev; unsigned int preferred_bpp = 0; - if (!HAS_DISPLAY(i915)) + if (!HAS_DISPLAY(display)) return; - ifbdev = drmm_kzalloc(dev, sizeof(*ifbdev), GFP_KERNEL); + ifbdev = drmm_kzalloc(display->drm, sizeof(*ifbdev), GFP_KERNEL); if (!ifbdev) return; - i915->display.fbdev.fbdev = ifbdev; - if (intel_fbdev_init_bios(dev, ifbdev)) + display->fbdev.fbdev = ifbdev; + if (intel_fbdev_init_bios(display, ifbdev)) preferred_bpp = intel_fbdev_color_mode(ifbdev->fb->base.format); if (!preferred_bpp) preferred_bpp = 32; - drm_client_setup_with_color_mode(dev, preferred_bpp); + drm_client_setup_with_color_mode(display->drm, preferred_bpp); } struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h b/drivers/gpu/drm/i915/display/intel_fbdev.h index 89bad3a2b01a..a15e3e222a0c 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.h +++ b/drivers/gpu/drm/i915/display/intel_fbdev.h @@ -10,7 +10,7 @@ struct drm_fb_helper; struct drm_fb_helper_surface_size; -struct drm_i915_private; +struct intel_display; struct intel_fbdev; struct intel_framebuffer; @@ -19,14 +19,14 @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes); #define INTEL_FBDEV_DRIVER_OPS \ .fbdev_probe = intel_fbdev_driver_fbdev_probe -void intel_fbdev_setup(struct drm_i915_private *dev_priv); +void intel_fbdev_setup(struct intel_display *display); struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev); struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev); #else #define INTEL_FBDEV_DRIVER_OPS \ .fbdev_probe = NULL -static inline void intel_fbdev_setup(struct drm_i915_private *dev_priv) +static inline void intel_fbdev_setup(struct intel_display *display) { } static inline struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) diff --git a/drivers/gpu/drm/i915/display/intel_fbdev_fb.c b/drivers/gpu/drm/i915/display/intel_fbdev_fb.c index 4991c35a2632..5f4cb3328265 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev_fb.c @@ -15,9 +15,9 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { + struct intel_display *display = to_intel_display(helper->dev); + struct drm_i915_private *dev_priv = to_i915(display->drm); struct drm_framebuffer *fb; - struct drm_device *dev = helper->dev; - struct drm_i915_private *dev_priv = to_i915(dev); struct drm_mode_fb_cmd2 mode_cmd = {}; struct drm_i915_gem_object *obj; int size; @@ -50,14 +50,14 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, * * Also skip stolen on MTL as Wa_22018444074 mitigation. */ - if (!(IS_METEORLAKE(dev_priv)) && size * 2 < dev_priv->dsm.usable_size) + if (!display->platform.meteorlake && size * 2 < dev_priv->dsm.usable_size) obj = i915_gem_object_create_stolen(dev_priv, size); if (IS_ERR(obj)) obj = i915_gem_object_create_shmem(dev_priv, size); } if (IS_ERR(obj)) { - drm_err(&dev_priv->drm, "failed to allocate framebuffer (%pe)\n", obj); + drm_err(display->drm, "failed to allocate framebuffer (%pe)\n", obj); return ERR_PTR(-ENOMEM); } @@ -67,9 +67,10 @@ struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, return to_intel_framebuffer(fb); } -int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info, +int intel_fbdev_fb_fill_info(struct intel_display *display, struct fb_info *info, struct drm_gem_object *_obj, struct i915_vma *vma) { + struct drm_i915_private *i915 = to_i915(display->drm); struct drm_i915_gem_object *obj = to_intel_bo(_obj); struct i915_gem_ww_ctx ww; void __iomem *vaddr; @@ -101,7 +102,7 @@ int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info vaddr = i915_vma_pin_iomap(vma); if (IS_ERR(vaddr)) { - drm_err(&i915->drm, + drm_err(display->drm, "Failed to remap framebuffer into virtual memory (%pe)\n", vaddr); ret = PTR_ERR(vaddr); continue; diff --git a/drivers/gpu/drm/i915/display/intel_fbdev_fb.h b/drivers/gpu/drm/i915/display/intel_fbdev_fb.h index e502ae375fc0..cb7957272715 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fbdev_fb.h @@ -9,13 +9,13 @@ struct drm_fb_helper; struct drm_fb_helper_surface_size; struct drm_gem_object; -struct drm_i915_private; struct fb_info; struct i915_vma; +struct intel_display; struct intel_framebuffer *intel_fbdev_fb_alloc(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes); -int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info, +int intel_fbdev_fb_fill_info(struct intel_display *display, struct fb_info *info, struct drm_gem_object *obj, struct i915_vma *vma); #endif diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index 40deee0769ae..169bbe154b5c 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -6,15 +6,16 @@ #include <linux/string_helpers.h> #include <drm/drm_fixed.h> +#include <drm/drm_print.h> -#include "i915_drv.h" #include "i915_reg.h" +#include "i915_utils.h" #include "intel_atomic.h" #include "intel_crtc.h" #include "intel_ddi.h" #include "intel_de.h" -#include "intel_dp.h" #include "intel_display_types.h" +#include "intel_dp.h" #include "intel_fdi.h" #include "intel_fdi_regs.h" #include "intel_link_bw.h" @@ -464,7 +465,6 @@ static void ivb_update_fdi_bc_bifurcation(const struct intel_crtc_state *crtc_st void intel_fdi_normal_train(struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe = crtc->pipe; i915_reg_t reg; u32 temp; @@ -483,7 +483,7 @@ void intel_fdi_normal_train(struct intel_crtc *crtc) reg = FDI_RX_CTL(pipe); temp = intel_de_read(display, reg); - if (HAS_PCH_CPT(dev_priv)) { + if (HAS_PCH_CPT(display)) { temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; temp |= FDI_LINK_TRAIN_NORMAL_CPT; } else { @@ -607,7 +607,6 @@ static void gen6_fdi_link_train(struct intel_crtc *crtc, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe = crtc->pipe; i915_reg_t reg; u32 temp, i, retry; @@ -647,7 +646,7 @@ static void gen6_fdi_link_train(struct intel_crtc *crtc, reg = FDI_RX_CTL(pipe); temp = intel_de_read(display, reg); - if (HAS_PCH_CPT(dev_priv)) { + if (HAS_PCH_CPT(display)) { temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; } else { @@ -698,7 +697,7 @@ static void gen6_fdi_link_train(struct intel_crtc *crtc, reg = FDI_RX_CTL(pipe); temp = intel_de_read(display, reg); - if (HAS_PCH_CPT(dev_priv)) { + if (HAS_PCH_CPT(display)) { temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; temp |= FDI_LINK_TRAIN_PATTERN_2_CPT; } else { @@ -1077,7 +1076,6 @@ void ilk_fdi_pll_disable(struct intel_crtc *crtc) void ilk_fdi_disable(struct 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; i915_reg_t reg; u32 temp; @@ -1096,7 +1094,7 @@ void ilk_fdi_disable(struct intel_crtc *crtc) udelay(100); /* Ironlake workaround, disable clock pointer after downing FDI */ - if (HAS_PCH_IBX(dev_priv)) + if (HAS_PCH_IBX(display)) intel_de_write(display, FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR); @@ -1106,7 +1104,7 @@ void ilk_fdi_disable(struct intel_crtc *crtc) reg = FDI_RX_CTL(pipe); temp = intel_de_read(display, reg); - if (HAS_PCH_CPT(dev_priv)) { + if (HAS_PCH_CPT(display)) { temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT; temp |= FDI_LINK_TRAIN_PATTERN_1_CPT; } else { diff --git a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c index 451cd26024f7..2a787897b2d3 100644 --- a/drivers/gpu/drm/i915/display/intel_fifo_underrun.c +++ b/drivers/gpu/drm/i915/display/intel_fifo_underrun.c @@ -25,7 +25,8 @@ * */ -#include "i915_drv.h" +#include <drm/drm_print.h> + #include "i915_reg.h" #include "intel_de.h" #include "intel_display_irq.h" @@ -57,11 +58,10 @@ static bool ivb_can_enable_err_int(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc *crtc; enum pipe pipe; - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); for_each_pipe(display, pipe) { crtc = intel_crtc_for_pipe(display, pipe); @@ -75,11 +75,10 @@ static bool ivb_can_enable_err_int(struct intel_display *display) static bool cpt_can_enable_serr_int(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe pipe; struct intel_crtc *crtc; - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); for_each_pipe(display, pipe) { crtc = intel_crtc_for_pipe(display, pipe); @@ -94,11 +93,10 @@ static bool cpt_can_enable_serr_int(struct intel_display *display) static void i9xx_check_fifo_underruns(struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); i915_reg_t reg = PIPESTAT(display, crtc->pipe); u32 enable_mask; - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); if ((intel_de_read(display, reg) & PIPE_FIFO_UNDERRUN_STATUS) == 0) return; @@ -115,10 +113,9 @@ static void i9xx_set_fifo_underrun_reporting(struct intel_display *display, enum pipe pipe, bool enable, bool old) { - struct drm_i915_private *dev_priv = to_i915(display->drm); i915_reg_t reg = PIPESTAT(display, pipe); - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); if (enable) { u32 enable_mask = i915_pipestat_enable_mask(display, pipe); @@ -148,11 +145,10 @@ static void ilk_set_fifo_underrun_reporting(struct intel_display *display, static void ivb_check_fifo_underruns(struct 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; u32 err_int = intel_de_read(display, GEN7_ERR_INT); - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); if ((err_int & ERR_INT_FIFO_UNDERRUN(pipe)) == 0) return; @@ -213,11 +209,10 @@ static void ibx_set_fifo_underrun_reporting(struct intel_display *display, static void cpt_check_pch_fifo_underruns(struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pch_transcoder = crtc->pipe; u32 serr_int = intel_de_read(display, SERR_INT); - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); if ((serr_int & SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) == 0) return; @@ -258,11 +253,10 @@ static void cpt_set_fifo_underrun_reporting(struct intel_display *display, static bool __intel_set_cpu_fifo_underrun_reporting(struct intel_display *display, enum pipe pipe, bool enable) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); bool old; - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); old = !crtc->cpu_fifo_underrun_disabled; crtc->cpu_fifo_underrun_disabled = !enable; @@ -298,13 +292,12 @@ static bool __intel_set_cpu_fifo_underrun_reporting(struct intel_display *displa bool intel_set_cpu_fifo_underrun_reporting(struct intel_display *display, enum pipe pipe, bool enable) { - struct drm_i915_private *dev_priv = to_i915(display->drm); unsigned long flags; bool ret; - spin_lock_irqsave(&dev_priv->irq_lock, flags); + spin_lock_irqsave(&display->irq.lock, flags); ret = __intel_set_cpu_fifo_underrun_reporting(display, pipe, enable); - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + spin_unlock_irqrestore(&display->irq.lock, flags); return ret; } @@ -327,7 +320,6 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display, enum pipe pch_transcoder, bool enable) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc *crtc = intel_crtc_for_pipe(display, pch_transcoder); unsigned long flags; bool old; @@ -341,12 +333,12 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display, * crtc on LPT won't cause issues. */ - spin_lock_irqsave(&dev_priv->irq_lock, flags); + spin_lock_irqsave(&display->irq.lock, flags); old = !crtc->pch_fifo_underrun_disabled; crtc->pch_fifo_underrun_disabled = !enable; - if (HAS_PCH_IBX(dev_priv)) + if (HAS_PCH_IBX(display)) ibx_set_fifo_underrun_reporting(display, pch_transcoder, enable); @@ -355,7 +347,7 @@ bool intel_set_pch_fifo_underrun_reporting(struct intel_display *display, pch_transcoder, enable, old); - spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + spin_unlock_irqrestore(&display->irq.lock, flags); return old; } @@ -422,10 +414,9 @@ void intel_pch_fifo_underrun_irq_handler(struct intel_display *display, */ void intel_check_cpu_fifo_underruns(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc *crtc; - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); for_each_intel_crtc(display->drm, crtc) { if (crtc->cpu_fifo_underrun_disabled) @@ -437,7 +428,7 @@ void intel_check_cpu_fifo_underruns(struct intel_display *display) ivb_check_fifo_underruns(crtc); } - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); } /** @@ -450,20 +441,19 @@ void intel_check_cpu_fifo_underruns(struct intel_display *display) */ void intel_check_pch_fifo_underruns(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_crtc *crtc; - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); for_each_intel_crtc(display->drm, crtc) { if (crtc->pch_fifo_underrun_disabled) continue; - if (HAS_PCH_CPT(dev_priv)) + if (HAS_PCH_CPT(display)) cpt_check_pch_fifo_underruns(crtc); } - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); } void intel_init_fifo_underrun_reporting(struct intel_display *display, diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c index ba2f88ca6117..43be5377ddc1 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c @@ -58,7 +58,6 @@ #include <drm/drm_gem.h> #include "i915_active.h" -#include "i915_drv.h" #include "i915_vma.h" #include "intel_bo.h" #include "intel_display_trace.h" @@ -72,7 +71,7 @@ /** * frontbuffer_flush - flush frontbuffer - * @i915: i915 device + * @display: display device * @frontbuffer_bits: frontbuffer plane tracking bits * @origin: which operation caused the flush * @@ -82,16 +81,14 @@ * * Can be called without any locks held. */ -static void frontbuffer_flush(struct drm_i915_private *i915, +static void frontbuffer_flush(struct intel_display *display, unsigned int frontbuffer_bits, enum fb_op_origin origin) { - struct intel_display *display = &i915->display; - /* Delay flushing when rings are still busy.*/ - spin_lock(&i915->display.fb_tracking.lock); - frontbuffer_bits &= ~i915->display.fb_tracking.busy_bits; - spin_unlock(&i915->display.fb_tracking.lock); + spin_lock(&display->fb_tracking.lock); + frontbuffer_bits &= ~display->fb_tracking.busy_bits; + spin_unlock(&display->fb_tracking.lock); if (!frontbuffer_bits) return; @@ -107,7 +104,7 @@ static void frontbuffer_flush(struct drm_i915_private *i915, /** * intel_frontbuffer_flip_prepare - prepare asynchronous frontbuffer flip - * @i915: i915 device + * @display: display device * @frontbuffer_bits: frontbuffer plane tracking bits * * This function gets called after scheduling a flip on @obj. The actual @@ -117,19 +114,19 @@ static void frontbuffer_flush(struct drm_i915_private *i915, * * Can be called without any locks held. */ -void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915, +void intel_frontbuffer_flip_prepare(struct intel_display *display, unsigned frontbuffer_bits) { - spin_lock(&i915->display.fb_tracking.lock); - i915->display.fb_tracking.flip_bits |= frontbuffer_bits; + spin_lock(&display->fb_tracking.lock); + display->fb_tracking.flip_bits |= frontbuffer_bits; /* Remove stale busy bits due to the old buffer. */ - i915->display.fb_tracking.busy_bits &= ~frontbuffer_bits; - spin_unlock(&i915->display.fb_tracking.lock); + display->fb_tracking.busy_bits &= ~frontbuffer_bits; + spin_unlock(&display->fb_tracking.lock); } /** * intel_frontbuffer_flip_complete - complete asynchronous frontbuffer flip - * @i915: i915 device + * @display: display device * @frontbuffer_bits: frontbuffer plane tracking bits * * This function gets called after the flip has been latched and will complete @@ -137,22 +134,22 @@ void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915, * * Can be called without any locks held. */ -void intel_frontbuffer_flip_complete(struct drm_i915_private *i915, +void intel_frontbuffer_flip_complete(struct intel_display *display, unsigned frontbuffer_bits) { - spin_lock(&i915->display.fb_tracking.lock); + spin_lock(&display->fb_tracking.lock); /* Mask any cancelled flips. */ - frontbuffer_bits &= i915->display.fb_tracking.flip_bits; - i915->display.fb_tracking.flip_bits &= ~frontbuffer_bits; - spin_unlock(&i915->display.fb_tracking.lock); + frontbuffer_bits &= display->fb_tracking.flip_bits; + display->fb_tracking.flip_bits &= ~frontbuffer_bits; + spin_unlock(&display->fb_tracking.lock); if (frontbuffer_bits) - frontbuffer_flush(i915, frontbuffer_bits, ORIGIN_FLIP); + frontbuffer_flush(display, frontbuffer_bits, ORIGIN_FLIP); } /** * intel_frontbuffer_flip - synchronous frontbuffer flip - * @i915: i915 device + * @display: display device * @frontbuffer_bits: frontbuffer plane tracking bits * * This function gets called after scheduling a flip on @obj. This is for @@ -161,15 +158,15 @@ void intel_frontbuffer_flip_complete(struct drm_i915_private *i915, * * Can be called without any locks held. */ -void intel_frontbuffer_flip(struct drm_i915_private *i915, +void intel_frontbuffer_flip(struct intel_display *display, unsigned frontbuffer_bits) { - spin_lock(&i915->display.fb_tracking.lock); + spin_lock(&display->fb_tracking.lock); /* Remove stale busy bits due to the old buffer. */ - i915->display.fb_tracking.busy_bits &= ~frontbuffer_bits; - spin_unlock(&i915->display.fb_tracking.lock); + display->fb_tracking.busy_bits &= ~frontbuffer_bits; + spin_unlock(&display->fb_tracking.lock); - frontbuffer_flush(i915, frontbuffer_bits, ORIGIN_FLIP); + frontbuffer_flush(display, frontbuffer_bits, ORIGIN_FLIP); } void __intel_fb_invalidate(struct intel_frontbuffer *front, @@ -198,7 +195,6 @@ void __intel_fb_flush(struct intel_frontbuffer *front, unsigned int frontbuffer_bits) { struct intel_display *display = to_intel_display(front->obj->dev); - struct drm_i915_private *i915 = to_i915(display->drm); if (origin == ORIGIN_CS) { spin_lock(&display->fb_tracking.lock); @@ -209,7 +205,7 @@ void __intel_fb_flush(struct intel_frontbuffer *front, } if (frontbuffer_bits) - frontbuffer_flush(i915, frontbuffer_bits, origin); + frontbuffer_flush(display, frontbuffer_bits, origin); } static void intel_frontbuffer_flush_work(struct work_struct *work) @@ -280,7 +276,7 @@ static void frontbuffer_release(struct kref *ref) struct intel_frontbuffer * intel_frontbuffer_get(struct drm_gem_object *obj) { - struct drm_i915_private *i915 = to_i915(obj->dev); + struct intel_display *display = to_intel_display(obj->dev); struct intel_frontbuffer *front, *cur; front = intel_bo_get_frontbuffer(obj); @@ -300,9 +296,9 @@ intel_frontbuffer_get(struct drm_gem_object *obj) I915_ACTIVE_RETIRE_SLEEPS); INIT_WORK(&front->flush_work, intel_frontbuffer_flush_work); - spin_lock(&i915->display.fb_tracking.lock); + spin_lock(&display->fb_tracking.lock); cur = intel_bo_set_frontbuffer(obj, front); - spin_unlock(&i915->display.fb_tracking.lock); + spin_unlock(&display->fb_tracking.lock); if (cur != front) kfree(front); return cur; diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.h b/drivers/gpu/drm/i915/display/intel_frontbuffer.h index 6237780a9f68..2fee12eaf9b6 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.h +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.h @@ -31,7 +31,7 @@ #include "i915_active_types.h" struct drm_gem_object; -struct drm_i915_private; +struct intel_display; enum fb_op_origin { ORIGIN_CPU = 0, @@ -68,11 +68,11 @@ struct intel_frontbuffer { GENMASK(INTEL_FRONTBUFFER_BITS_PER_PIPE * ((pipe) + 1) - 1, \ INTEL_FRONTBUFFER_BITS_PER_PIPE * (pipe)) -void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915, +void intel_frontbuffer_flip_prepare(struct intel_display *display, unsigned frontbuffer_bits); -void intel_frontbuffer_flip_complete(struct drm_i915_private *i915, +void intel_frontbuffer_flip_complete(struct intel_display *display, unsigned frontbuffer_bits); -void intel_frontbuffer_flip(struct drm_i915_private *i915, +void intel_frontbuffer_flip(struct intel_display *display, unsigned frontbuffer_bits); void intel_frontbuffer_put(struct intel_frontbuffer *front); diff --git a/drivers/gpu/drm/i915/display/intel_global_state.c b/drivers/gpu/drm/i915/display/intel_global_state.c index 8a49e2bb37fa..000a898c9480 100644 --- a/drivers/gpu/drm/i915/display/intel_global_state.c +++ b/drivers/gpu/drm/i915/display/intel_global_state.c @@ -3,10 +3,13 @@ * Copyright © 2020 Intel Corporation */ +#include <linux/pci.h> #include <linux/string.h> -#include "i915_drv.h" +#include <drm/drm_print.h> + #include "intel_atomic.h" +#include "intel_display_core.h" #include "intel_display_types.h" #include "intel_global_state.h" diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c b/drivers/gpu/drm/i915/display/intel_gmbus.c index abf457e68ee9..d55cc77650b7 100644 --- a/drivers/gpu/drm/i915/display/intel_gmbus.c +++ b/drivers/gpu/drm/i915/display/intel_gmbus.c @@ -152,32 +152,31 @@ static const struct gmbus_pin gmbus_pins_mtp[] = { static const struct gmbus_pin *get_gmbus_pin(struct intel_display *display, unsigned int pin) { - struct drm_i915_private *i915 = to_i915(display->drm); const struct gmbus_pin *pins; size_t size; - if (INTEL_PCH_TYPE(i915) >= PCH_MTL) { + if (INTEL_PCH_TYPE(display) >= PCH_MTL) { pins = gmbus_pins_mtp; size = ARRAY_SIZE(gmbus_pins_mtp); - } else if (INTEL_PCH_TYPE(i915) >= PCH_DG2) { + } else if (INTEL_PCH_TYPE(display) >= PCH_DG2) { pins = gmbus_pins_dg2; size = ARRAY_SIZE(gmbus_pins_dg2); - } else if (INTEL_PCH_TYPE(i915) >= PCH_DG1) { + } else if (INTEL_PCH_TYPE(display) >= PCH_DG1) { pins = gmbus_pins_dg1; size = ARRAY_SIZE(gmbus_pins_dg1); - } else if (INTEL_PCH_TYPE(i915) >= PCH_ICP) { + } else if (INTEL_PCH_TYPE(display) >= PCH_ICP) { pins = gmbus_pins_icp; size = ARRAY_SIZE(gmbus_pins_icp); - } else if (HAS_PCH_CNP(i915)) { + } else if (HAS_PCH_CNP(display)) { pins = gmbus_pins_cnp; size = ARRAY_SIZE(gmbus_pins_cnp); - } else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) { + } else if (display->platform.geminilake || display->platform.broxton) { pins = gmbus_pins_bxt; size = ARRAY_SIZE(gmbus_pins_bxt); } else if (DISPLAY_VER(display) == 9) { pins = gmbus_pins_skl; size = ARRAY_SIZE(gmbus_pins_skl); - } else if (IS_BROADWELL(i915)) { + } else if (display->platform.broadwell) { pins = gmbus_pins_bdw; size = ARRAY_SIZE(gmbus_pins_bdw); } else { @@ -240,11 +239,10 @@ static void bxt_gmbus_clock_gating(struct intel_display *display, static u32 get_reserved(struct intel_gmbus *bus) { struct intel_display *display = bus->display; - struct drm_i915_private *i915 = to_i915(display->drm); u32 reserved = 0; /* On most chips, these bits must be preserved in software. */ - if (!IS_I830(i915) && !IS_I845G(i915)) + if (!display->platform.i830 && !display->platform.i845g) reserved = intel_de_read_notrace(display, bus->gpio_reg) & (GPIO_DATA_PULLUP_DISABLE | GPIO_CLOCK_PULLUP_DISABLE); @@ -314,11 +312,10 @@ intel_gpio_pre_xfer(struct i2c_adapter *adapter) { struct intel_gmbus *bus = to_intel_gmbus(adapter); struct intel_display *display = bus->display; - struct drm_i915_private *i915 = to_i915(display->drm); intel_gmbus_reset(display); - if (IS_PINEVIEW(i915)) + if (display->platform.pineview) pnv_gmbus_clock_gating(display, false); set_data(bus, 1); @@ -332,12 +329,11 @@ intel_gpio_post_xfer(struct i2c_adapter *adapter) { struct intel_gmbus *bus = to_intel_gmbus(adapter); struct intel_display *display = bus->display; - struct drm_i915_private *i915 = to_i915(display->drm); set_data(bus, 1); set_clock(bus, 1); - if (IS_PINEVIEW(i915)) + if (display->platform.pineview) pnv_gmbus_clock_gating(display, true); } @@ -630,14 +626,13 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num, { struct intel_gmbus *bus = to_intel_gmbus(adapter); struct intel_display *display = bus->display; - struct drm_i915_private *i915 = to_i915(display->drm); int i = 0, inc, try = 0; int ret = 0; /* Display WA #0868: skl,bxt,kbl,cfl,glk */ - if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) + if (display->platform.geminilake || display->platform.broxton) bxt_gmbus_clock_gating(display, false); - else if (HAS_PCH_SPT(i915) || HAS_PCH_CNP(i915)) + else if (HAS_PCH_SPT(display) || HAS_PCH_CNP(display)) pch_gmbus_clock_gating(display, false); retry: @@ -748,9 +743,9 @@ timeout: out: /* Display WA #0868: skl,bxt,kbl,cfl,glk */ - if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) + if (display->platform.geminilake || display->platform.broxton) bxt_gmbus_clock_gating(display, true); - else if (HAS_PCH_SPT(i915) || HAS_PCH_CNP(i915)) + else if (HAS_PCH_SPT(display) || HAS_PCH_CNP(display)) pch_gmbus_clock_gating(display, true); return ret; @@ -873,12 +868,11 @@ static const struct i2c_lock_operations gmbus_lock_ops = { */ int intel_gmbus_setup(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct pci_dev *pdev = to_pci_dev(display->drm->dev); unsigned int pin; int ret; - if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) + if (display->platform.valleyview || display->platform.cherryview) display->gmbus.mmio_base = VLV_DISPLAY_BASE; else if (!HAS_GMCH(display)) /* @@ -925,7 +919,7 @@ int intel_gmbus_setup(struct intel_display *display) bus->reg0 = pin | GMBUS_RATE_100KHZ; /* gmbus seems to be broken on i830 */ - if (IS_I830(i915)) + if (display->platform.i830) bus->force_bit = 1; intel_gpio_setup(bus, GPIO(display, gmbus_pin->gpio)); diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 411f17655f89..3e3038f4ee1f 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -27,10 +27,13 @@ #include "intel_dp_mst.h" #include "intel_hdcp.h" #include "intel_hdcp_gsc.h" +#include "intel_hdcp_gsc_message.h" #include "intel_hdcp_regs.h" #include "intel_hdcp_shim.h" #include "intel_pcode.h" +#define USE_HDCP_GSC(__display) (DISPLAY_VER(__display) >= 14) + #define KEY_LOAD_TRIES 5 #define HDCP2_LC_RETRY_CNT 3 @@ -250,8 +253,8 @@ static bool intel_hdcp2_prerequisite(struct intel_connector *connector) return false; /* If MTL+ make sure gsc is loaded and proxy is setup */ - if (intel_hdcp_gsc_cs_required(display)) { - if (!intel_hdcp_gsc_check_status(display)) + if (USE_HDCP_GSC(display)) { + if (!intel_hdcp_gsc_check_status(display->drm)) return false; } @@ -2339,7 +2342,7 @@ static int initialize_hdcp_port_data(struct intel_connector *connector, static bool is_hdcp2_supported(struct intel_display *display) { - if (intel_hdcp_gsc_cs_required(display)) + if (USE_HDCP_GSC(display)) return true; if (!IS_ENABLED(CONFIG_INTEL_MEI_HDCP)) @@ -2363,7 +2366,7 @@ void intel_hdcp_component_init(struct intel_display *display) display->hdcp.comp_added = true; mutex_unlock(&display->hdcp.hdcp_mutex); - if (intel_hdcp_gsc_cs_required(display)) + if (USE_HDCP_GSC(display)) ret = intel_hdcp_gsc_init(display); else ret = component_add_typed(display->drm->dev, &i915_hdcp_ops, @@ -2638,7 +2641,7 @@ void intel_hdcp_component_fini(struct intel_display *display) display->hdcp.comp_added = false; mutex_unlock(&display->hdcp.hdcp_mutex); - if (intel_hdcp_gsc_cs_required(display)) + if (USE_HDCP_GSC(display)) intel_hdcp_gsc_fini(display); else component_del(display->drm->dev, &i915_hdcp_ops); diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c index 55965844d829..6a22862d6be1 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.c @@ -11,27 +11,22 @@ #include "i915_drv.h" #include "i915_utils.h" #include "intel_hdcp_gsc.h" -#include "intel_hdcp_gsc_message.h" -struct intel_hdcp_gsc_message { +struct intel_hdcp_gsc_context { + struct drm_i915_private *i915; struct i915_vma *vma; void *hdcp_cmd_in; void *hdcp_cmd_out; }; -bool intel_hdcp_gsc_cs_required(struct intel_display *display) +bool intel_hdcp_gsc_check_status(struct drm_device *drm) { - return DISPLAY_VER(display) >= 14; -} - -bool intel_hdcp_gsc_check_status(struct intel_display *display) -{ - struct drm_i915_private *i915 = to_i915(display->drm); + struct drm_i915_private *i915 = to_i915(drm); struct intel_gt *gt = i915->media_gt; struct intel_gsc_uc *gsc = gt ? >->uc.gsc : NULL; if (!gsc || !intel_uc_fw_is_running(&gsc->fw)) { - drm_dbg_kms(display->drm, + drm_dbg_kms(&i915->drm, "GSC components required for HDCP2.2 are not ready\n"); return false; } @@ -41,7 +36,7 @@ bool intel_hdcp_gsc_check_status(struct intel_display *display) /*This function helps allocate memory for the command that we will send to gsc cs */ static int intel_hdcp_gsc_initialize_message(struct drm_i915_private *i915, - struct intel_hdcp_gsc_message *hdcp_message) + struct intel_hdcp_gsc_context *gsc_context) { struct intel_gt *gt = i915->media_gt; struct drm_i915_gem_object *obj = NULL; @@ -78,9 +73,10 @@ static int intel_hdcp_gsc_initialize_message(struct drm_i915_private *i915, memset(cmd_in, 0, obj->base.size); - hdcp_message->hdcp_cmd_in = cmd_in; - hdcp_message->hdcp_cmd_out = cmd_out; - hdcp_message->vma = vma; + gsc_context->hdcp_cmd_in = cmd_in; + gsc_context->hdcp_cmd_out = cmd_out; + gsc_context->vma = vma; + gsc_context->i915 = i915; return 0; @@ -91,80 +87,37 @@ out_unpin: return err; } -static const struct i915_hdcp_ops gsc_hdcp_ops = { - .initiate_hdcp2_session = intel_hdcp_gsc_initiate_session, - .verify_receiver_cert_prepare_km = - intel_hdcp_gsc_verify_receiver_cert_prepare_km, - .verify_hprime = intel_hdcp_gsc_verify_hprime, - .store_pairing_info = intel_hdcp_gsc_store_pairing_info, - .initiate_locality_check = intel_hdcp_gsc_initiate_locality_check, - .verify_lprime = intel_hdcp_gsc_verify_lprime, - .get_session_key = intel_hdcp_gsc_get_session_key, - .repeater_check_flow_prepare_ack = - intel_hdcp_gsc_repeater_check_flow_prepare_ack, - .verify_mprime = intel_hdcp_gsc_verify_mprime, - .enable_hdcp_authentication = intel_hdcp_gsc_enable_authentication, - .close_hdcp_session = intel_hdcp_gsc_close_session, -}; - -static int intel_hdcp_gsc_hdcp2_init(struct intel_display *display) +struct intel_hdcp_gsc_context *intel_hdcp_gsc_context_alloc(struct drm_device *drm) { - struct drm_i915_private *i915 = to_i915(display->drm); - struct intel_hdcp_gsc_message *hdcp_message; + struct drm_i915_private *i915 = to_i915(drm); + struct intel_hdcp_gsc_context *gsc_context; int ret; - hdcp_message = kzalloc(sizeof(*hdcp_message), GFP_KERNEL); - - if (!hdcp_message) - return -ENOMEM; + gsc_context = kzalloc(sizeof(*gsc_context), GFP_KERNEL); + if (!gsc_context) + return ERR_PTR(-ENOMEM); /* * NOTE: No need to lock the comp mutex here as it is already * going to be taken before this function called */ - display->hdcp.hdcp_message = hdcp_message; - ret = intel_hdcp_gsc_initialize_message(i915, hdcp_message); - - if (ret) - drm_err(display->drm, "Could not initialize hdcp_message\n"); - - return ret; -} - -static void intel_hdcp_gsc_free_message(struct intel_display *display) -{ - struct intel_hdcp_gsc_message *hdcp_message = - display->hdcp.hdcp_message; + ret = intel_hdcp_gsc_initialize_message(i915, gsc_context); + if (ret) { + drm_err(&i915->drm, "Could not initialize gsc_context\n"); + kfree(gsc_context); + gsc_context = ERR_PTR(ret); + } - hdcp_message->hdcp_cmd_in = NULL; - hdcp_message->hdcp_cmd_out = NULL; - i915_vma_unpin_and_release(&hdcp_message->vma, I915_VMA_RELEASE_MAP); - kfree(hdcp_message); + return gsc_context; } -int intel_hdcp_gsc_init(struct intel_display *display) +void intel_hdcp_gsc_context_free(struct intel_hdcp_gsc_context *gsc_context) { - struct i915_hdcp_arbiter *data; - int ret; - - data = kzalloc(sizeof(struct i915_hdcp_arbiter), GFP_KERNEL); - if (!data) - return -ENOMEM; + if (!gsc_context) + return; - mutex_lock(&display->hdcp.hdcp_mutex); - display->hdcp.arbiter = data; - display->hdcp.arbiter->hdcp_dev = display->drm->dev; - display->hdcp.arbiter->ops = &gsc_hdcp_ops; - ret = intel_hdcp_gsc_hdcp2_init(display); - mutex_unlock(&display->hdcp.hdcp_mutex); - - return ret; -} - -void intel_hdcp_gsc_fini(struct intel_display *display) -{ - intel_hdcp_gsc_free_message(display); - kfree(display->hdcp.arbiter); + i915_vma_unpin_and_release(&gsc_context->vma, I915_VMA_RELEASE_MAP); + kfree(gsc_context); } static int intel_gsc_send_sync(struct drm_i915_private *i915, @@ -211,18 +164,18 @@ static int intel_gsc_send_sync(struct drm_i915_private *i915, /* * This function can now be used for sending requests and will also handle * receipt of reply messages hence no different function of message retrieval - * is required. We will initialize intel_hdcp_gsc_message structure then add + * is required. We will initialize intel_hdcp_gsc_context structure then add * gsc cs memory header as stated in specs after which the normal HDCP payload * will follow */ -ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in, - size_t msg_in_len, u8 *msg_out, - size_t msg_out_len) +ssize_t intel_hdcp_gsc_msg_send(struct intel_hdcp_gsc_context *gsc_context, + void *msg_in, size_t msg_in_len, + void *msg_out, size_t msg_out_len) { + struct drm_i915_private *i915 = gsc_context->i915; struct intel_gt *gt = i915->media_gt; struct intel_gsc_mtl_header *header_in, *header_out; const size_t max_msg_size = PAGE_SIZE - sizeof(*header_in); - struct intel_hdcp_gsc_message *hdcp_message; u64 addr_in, addr_out, host_session_id; u32 reply_size, msg_size_in, msg_size_out; int ret, tries = 0; @@ -235,10 +188,9 @@ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in, msg_size_in = msg_in_len + sizeof(*header_in); msg_size_out = msg_out_len + sizeof(*header_out); - hdcp_message = i915->display.hdcp.hdcp_message; - header_in = hdcp_message->hdcp_cmd_in; - header_out = hdcp_message->hdcp_cmd_out; - addr_in = i915_ggtt_offset(hdcp_message->vma); + header_in = gsc_context->hdcp_cmd_in; + header_out = gsc_context->hdcp_cmd_out; + addr_in = i915_ggtt_offset(gsc_context->vma); addr_out = addr_in + PAGE_SIZE; memset(header_in, 0, msg_size_in); @@ -246,7 +198,7 @@ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in, get_random_bytes(&host_session_id, sizeof(u64)); intel_gsc_uc_heci_cmd_emit_mtl_header(header_in, HECI_MEADDRESS_HDCP, msg_size_in, host_session_id); - memcpy(hdcp_message->hdcp_cmd_in + sizeof(*header_in), msg_in, msg_in_len); + memcpy(gsc_context->hdcp_cmd_in + sizeof(*header_in), msg_in, msg_in_len); /* * Keep sending request in case the pending bit is set no need to add @@ -280,7 +232,7 @@ ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in, reply_size, (u32)msg_out_len); } - memcpy(msg_out, hdcp_message->hdcp_cmd_out + sizeof(*header_out), msg_out_len); + memcpy(msg_out, gsc_context->hdcp_cmd_out + sizeof(*header_out), msg_out_len); err: return ret; diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h index 5695a5e4f609..9305c14aaffe 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h +++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc.h @@ -6,19 +6,17 @@ #ifndef __INTEL_HDCP_GSC_H__ #define __INTEL_HDCP_GSC_H__ -#include <linux/err.h> #include <linux/types.h> -struct drm_i915_private; -struct intel_display; -struct intel_hdcp_gsc_message; +struct drm_device; +struct intel_hdcp_gsc_context; -bool intel_hdcp_gsc_cs_required(struct intel_display *display); -ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in, - size_t msg_in_len, u8 *msg_out, - size_t msg_out_len); -int intel_hdcp_gsc_init(struct intel_display *display); -void intel_hdcp_gsc_fini(struct intel_display *display); -bool intel_hdcp_gsc_check_status(struct intel_display *display); +ssize_t intel_hdcp_gsc_msg_send(struct intel_hdcp_gsc_context *gsc_context, + void *msg_in, size_t msg_in_len, + void *msg_out, size_t msg_out_len); +bool intel_hdcp_gsc_check_status(struct drm_device *drm); + +struct intel_hdcp_gsc_context *intel_hdcp_gsc_context_alloc(struct drm_device *drm); +void intel_hdcp_gsc_context_free(struct intel_hdcp_gsc_context *gsc_context); #endif /* __INTEL_HDCP_GCS_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c index 129104fa9b16..98967bb148e3 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c @@ -4,20 +4,23 @@ */ #include <linux/err.h> + +#include <drm/drm_print.h> #include <drm/intel/i915_hdcp_interface.h> -#include "i915_drv.h" +#include "intel_display_core.h" #include "intel_display_types.h" +#include "intel_hdcp_gsc.h" #include "intel_hdcp_gsc_message.h" -int +static int intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data, struct hdcp2_ake_init *ake_data) { struct wired_cmd_initiate_hdcp2_session_in session_init_in = {}; struct wired_cmd_initiate_hdcp2_session_out session_init_out = {}; + struct intel_hdcp_gsc_context *gsc_context; struct intel_display *display; - struct drm_i915_private *i915; ssize_t byte; if (!dev || !data || !ake_data) @@ -28,7 +31,7 @@ intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data, dev_err(dev, "DRM not initialized, aborting HDCP.\n"); return -ENODEV; } - i915 = to_i915(display->drm); + gsc_context = display->hdcp.gsc_context; session_init_in.header.api_version = HDCP_API_VERSION; session_init_in.header.command_id = WIRED_INITIATE_HDCP2_SESSION; @@ -41,9 +44,9 @@ intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data, session_init_in.port.attached_transcoder = (u8)data->hdcp_transcoder; session_init_in.protocol = data->protocol; - byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&session_init_in, + byte = intel_hdcp_gsc_msg_send(gsc_context, &session_init_in, sizeof(session_init_in), - (u8 *)&session_init_out, + &session_init_out, sizeof(session_init_out)); if (byte < 0) { drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); @@ -64,7 +67,7 @@ intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data, return 0; } -int +static int intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev, struct hdcp_port_data *data, struct hdcp2_ake_send_cert *rx_cert, @@ -75,8 +78,8 @@ intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev, { struct wired_cmd_verify_receiver_cert_in verify_rxcert_in = {}; struct wired_cmd_verify_receiver_cert_out verify_rxcert_out = {}; + struct intel_hdcp_gsc_context *gsc_context; struct intel_display *display; - struct drm_i915_private *i915; ssize_t byte; if (!dev || !data || !rx_cert || !km_stored || !ek_pub_km || !msg_sz) @@ -87,7 +90,7 @@ intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev, dev_err(dev, "DRM not initialized, aborting HDCP.\n"); return -ENODEV; } - i915 = to_i915(display->drm); + gsc_context = display->hdcp.gsc_context; verify_rxcert_in.header.api_version = HDCP_API_VERSION; verify_rxcert_in.header.command_id = WIRED_VERIFY_RECEIVER_CERT; @@ -103,9 +106,9 @@ intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev, memcpy(verify_rxcert_in.r_rx, &rx_cert->r_rx, HDCP_2_2_RRX_LEN); memcpy(verify_rxcert_in.rx_caps, rx_cert->rx_caps, HDCP_2_2_RXCAPS_LEN); - byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&verify_rxcert_in, + byte = intel_hdcp_gsc_msg_send(gsc_context, &verify_rxcert_in, sizeof(verify_rxcert_in), - (u8 *)&verify_rxcert_out, + &verify_rxcert_out, sizeof(verify_rxcert_out)); if (byte < 0) { drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed: %zd\n", byte); @@ -134,14 +137,14 @@ intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev, return 0; } -int +static int intel_hdcp_gsc_verify_hprime(struct device *dev, struct hdcp_port_data *data, struct hdcp2_ake_send_hprime *rx_hprime) { struct wired_cmd_ake_send_hprime_in send_hprime_in = {}; struct wired_cmd_ake_send_hprime_out send_hprime_out = {}; + struct intel_hdcp_gsc_context *gsc_context; struct intel_display *display; - struct drm_i915_private *i915; ssize_t byte; if (!dev || !data || !rx_hprime) @@ -152,7 +155,7 @@ intel_hdcp_gsc_verify_hprime(struct device *dev, struct hdcp_port_data *data, dev_err(dev, "DRM not initialized, aborting HDCP.\n"); return -ENODEV; } - i915 = to_i915(display->drm); + gsc_context = display->hdcp.gsc_context; send_hprime_in.header.api_version = HDCP_API_VERSION; send_hprime_in.header.command_id = WIRED_AKE_SEND_HPRIME; @@ -166,9 +169,9 @@ intel_hdcp_gsc_verify_hprime(struct device *dev, struct hdcp_port_data *data, memcpy(send_hprime_in.h_prime, rx_hprime->h_prime, HDCP_2_2_H_PRIME_LEN); - byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&send_hprime_in, + byte = intel_hdcp_gsc_msg_send(gsc_context, &send_hprime_in, sizeof(send_hprime_in), - (u8 *)&send_hprime_out, + &send_hprime_out, sizeof(send_hprime_out)); if (byte < 0) { drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); @@ -184,14 +187,14 @@ intel_hdcp_gsc_verify_hprime(struct device *dev, struct hdcp_port_data *data, return 0; } -int +static int intel_hdcp_gsc_store_pairing_info(struct device *dev, struct hdcp_port_data *data, struct hdcp2_ake_send_pairing_info *pairing_info) { struct wired_cmd_ake_send_pairing_info_in pairing_info_in = {}; struct wired_cmd_ake_send_pairing_info_out pairing_info_out = {}; + struct intel_hdcp_gsc_context *gsc_context; struct intel_display *display; - struct drm_i915_private *i915; ssize_t byte; if (!dev || !data || !pairing_info) @@ -202,7 +205,7 @@ intel_hdcp_gsc_store_pairing_info(struct device *dev, struct hdcp_port_data *dat dev_err(dev, "DRM not initialized, aborting HDCP.\n"); return -ENODEV; } - i915 = to_i915(display->drm); + gsc_context = display->hdcp.gsc_context; pairing_info_in.header.api_version = HDCP_API_VERSION; pairing_info_in.header.command_id = WIRED_AKE_SEND_PAIRING_INFO; @@ -217,9 +220,9 @@ intel_hdcp_gsc_store_pairing_info(struct device *dev, struct hdcp_port_data *dat memcpy(pairing_info_in.e_kh_km, pairing_info->e_kh_km, HDCP_2_2_E_KH_KM_LEN); - byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&pairing_info_in, + byte = intel_hdcp_gsc_msg_send(gsc_context, &pairing_info_in, sizeof(pairing_info_in), - (u8 *)&pairing_info_out, + &pairing_info_out, sizeof(pairing_info_out)); if (byte < 0) { drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); @@ -236,15 +239,15 @@ intel_hdcp_gsc_store_pairing_info(struct device *dev, struct hdcp_port_data *dat return 0; } -int +static int intel_hdcp_gsc_initiate_locality_check(struct device *dev, struct hdcp_port_data *data, struct hdcp2_lc_init *lc_init_data) { struct wired_cmd_init_locality_check_in lc_init_in = {}; struct wired_cmd_init_locality_check_out lc_init_out = {}; + struct intel_hdcp_gsc_context *gsc_context; struct intel_display *display; - struct drm_i915_private *i915; ssize_t byte; if (!dev || !data || !lc_init_data) @@ -255,7 +258,7 @@ intel_hdcp_gsc_initiate_locality_check(struct device *dev, dev_err(dev, "DRM not initialized, aborting HDCP.\n"); return -ENODEV; } - i915 = to_i915(display->drm); + gsc_context = display->hdcp.gsc_context; lc_init_in.header.api_version = HDCP_API_VERSION; lc_init_in.header.command_id = WIRED_INIT_LOCALITY_CHECK; @@ -266,8 +269,8 @@ intel_hdcp_gsc_initiate_locality_check(struct device *dev, lc_init_in.port.physical_port = (u8)data->hdcp_ddi; lc_init_in.port.attached_transcoder = (u8)data->hdcp_transcoder; - byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&lc_init_in, sizeof(lc_init_in), - (u8 *)&lc_init_out, sizeof(lc_init_out)); + byte = intel_hdcp_gsc_msg_send(gsc_context, &lc_init_in, sizeof(lc_init_in), + &lc_init_out, sizeof(lc_init_out)); if (byte < 0) { drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); return byte; @@ -285,14 +288,14 @@ intel_hdcp_gsc_initiate_locality_check(struct device *dev, return 0; } -int +static int intel_hdcp_gsc_verify_lprime(struct device *dev, struct hdcp_port_data *data, struct hdcp2_lc_send_lprime *rx_lprime) { struct wired_cmd_validate_locality_in verify_lprime_in = {}; struct wired_cmd_validate_locality_out verify_lprime_out = {}; + struct intel_hdcp_gsc_context *gsc_context; struct intel_display *display; - struct drm_i915_private *i915; ssize_t byte; if (!dev || !data || !rx_lprime) @@ -303,7 +306,7 @@ intel_hdcp_gsc_verify_lprime(struct device *dev, struct hdcp_port_data *data, dev_err(dev, "DRM not initialized, aborting HDCP.\n"); return -ENODEV; } - i915 = to_i915(display->drm); + gsc_context = display->hdcp.gsc_context; verify_lprime_in.header.api_version = HDCP_API_VERSION; verify_lprime_in.header.command_id = WIRED_VALIDATE_LOCALITY; @@ -318,9 +321,9 @@ intel_hdcp_gsc_verify_lprime(struct device *dev, struct hdcp_port_data *data, memcpy(verify_lprime_in.l_prime, rx_lprime->l_prime, HDCP_2_2_L_PRIME_LEN); - byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&verify_lprime_in, + byte = intel_hdcp_gsc_msg_send(gsc_context, &verify_lprime_in, sizeof(verify_lprime_in), - (u8 *)&verify_lprime_out, + &verify_lprime_out, sizeof(verify_lprime_out)); if (byte < 0) { drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); @@ -337,14 +340,15 @@ intel_hdcp_gsc_verify_lprime(struct device *dev, struct hdcp_port_data *data, return 0; } -int intel_hdcp_gsc_get_session_key(struct device *dev, - struct hdcp_port_data *data, - struct hdcp2_ske_send_eks *ske_data) +static int +intel_hdcp_gsc_get_session_key(struct device *dev, + struct hdcp_port_data *data, + struct hdcp2_ske_send_eks *ske_data) { struct wired_cmd_get_session_key_in get_skey_in = {}; struct wired_cmd_get_session_key_out get_skey_out = {}; + struct intel_hdcp_gsc_context *gsc_context; struct intel_display *display; - struct drm_i915_private *i915; ssize_t byte; if (!dev || !data || !ske_data) @@ -355,7 +359,7 @@ int intel_hdcp_gsc_get_session_key(struct device *dev, dev_err(dev, "DRM not initialized, aborting HDCP.\n"); return -ENODEV; } - i915 = to_i915(display->drm); + gsc_context = display->hdcp.gsc_context; get_skey_in.header.api_version = HDCP_API_VERSION; get_skey_in.header.command_id = WIRED_GET_SESSION_KEY; @@ -366,8 +370,8 @@ int intel_hdcp_gsc_get_session_key(struct device *dev, get_skey_in.port.physical_port = (u8)data->hdcp_ddi; get_skey_in.port.attached_transcoder = (u8)data->hdcp_transcoder; - byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&get_skey_in, sizeof(get_skey_in), - (u8 *)&get_skey_out, sizeof(get_skey_out)); + byte = intel_hdcp_gsc_msg_send(gsc_context, &get_skey_in, sizeof(get_skey_in), + &get_skey_out, sizeof(get_skey_out)); if (byte < 0) { drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); return byte; @@ -387,7 +391,7 @@ int intel_hdcp_gsc_get_session_key(struct device *dev, return 0; } -int +static int intel_hdcp_gsc_repeater_check_flow_prepare_ack(struct device *dev, struct hdcp_port_data *data, struct hdcp2_rep_send_receiverid_list @@ -397,8 +401,8 @@ intel_hdcp_gsc_repeater_check_flow_prepare_ack(struct device *dev, { struct wired_cmd_verify_repeater_in verify_repeater_in = {}; struct wired_cmd_verify_repeater_out verify_repeater_out = {}; + struct intel_hdcp_gsc_context *gsc_context; struct intel_display *display; - struct drm_i915_private *i915; ssize_t byte; if (!dev || !rep_topology || !rep_send_ack || !data) @@ -409,7 +413,7 @@ intel_hdcp_gsc_repeater_check_flow_prepare_ack(struct device *dev, dev_err(dev, "DRM not initialized, aborting HDCP.\n"); return -ENODEV; } - i915 = to_i915(display->drm); + gsc_context = display->hdcp.gsc_context; verify_repeater_in.header.api_version = HDCP_API_VERSION; verify_repeater_in.header.command_id = WIRED_VERIFY_REPEATER; @@ -430,9 +434,9 @@ intel_hdcp_gsc_repeater_check_flow_prepare_ack(struct device *dev, memcpy(verify_repeater_in.receiver_ids, rep_topology->receiver_ids, HDCP_2_2_RECEIVER_IDS_MAX_LEN); - byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&verify_repeater_in, + byte = intel_hdcp_gsc_msg_send(gsc_context, &verify_repeater_in, sizeof(verify_repeater_in), - (u8 *)&verify_repeater_out, + &verify_repeater_out, sizeof(verify_repeater_out)); if (byte < 0) { drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); @@ -453,14 +457,15 @@ intel_hdcp_gsc_repeater_check_flow_prepare_ack(struct device *dev, return 0; } -int intel_hdcp_gsc_verify_mprime(struct device *dev, - struct hdcp_port_data *data, - struct hdcp2_rep_stream_ready *stream_ready) +static int +intel_hdcp_gsc_verify_mprime(struct device *dev, + struct hdcp_port_data *data, + struct hdcp2_rep_stream_ready *stream_ready) { struct wired_cmd_repeater_auth_stream_req_in *verify_mprime_in; struct wired_cmd_repeater_auth_stream_req_out verify_mprime_out = {}; + struct intel_hdcp_gsc_context *gsc_context; struct intel_display *display; - struct drm_i915_private *i915; ssize_t byte; size_t cmd_size; @@ -472,7 +477,7 @@ int intel_hdcp_gsc_verify_mprime(struct device *dev, dev_err(dev, "DRM not initialized, aborting HDCP.\n"); return -ENODEV; } - i915 = to_i915(display->drm); + gsc_context = display->hdcp.gsc_context; cmd_size = struct_size(verify_mprime_in, streams, data->k); if (cmd_size == SIZE_MAX) @@ -499,8 +504,8 @@ int intel_hdcp_gsc_verify_mprime(struct device *dev, verify_mprime_in->k = cpu_to_be16(data->k); - byte = intel_hdcp_gsc_msg_send(i915, (u8 *)verify_mprime_in, cmd_size, - (u8 *)&verify_mprime_out, + byte = intel_hdcp_gsc_msg_send(gsc_context, verify_mprime_in, cmd_size, + &verify_mprime_out, sizeof(verify_mprime_out)); kfree(verify_mprime_in); if (byte < 0) { @@ -518,13 +523,13 @@ int intel_hdcp_gsc_verify_mprime(struct device *dev, return 0; } -int intel_hdcp_gsc_enable_authentication(struct device *dev, - struct hdcp_port_data *data) +static int intel_hdcp_gsc_enable_authentication(struct device *dev, + struct hdcp_port_data *data) { struct wired_cmd_enable_auth_in enable_auth_in = {}; struct wired_cmd_enable_auth_out enable_auth_out = {}; + struct intel_hdcp_gsc_context *gsc_context; struct intel_display *display; - struct drm_i915_private *i915; ssize_t byte; if (!dev || !data) @@ -535,7 +540,7 @@ int intel_hdcp_gsc_enable_authentication(struct device *dev, dev_err(dev, "DRM not initialized, aborting HDCP.\n"); return -ENODEV; } - i915 = to_i915(display->drm); + gsc_context = display->hdcp.gsc_context; enable_auth_in.header.api_version = HDCP_API_VERSION; enable_auth_in.header.command_id = WIRED_ENABLE_AUTH; @@ -547,9 +552,9 @@ int intel_hdcp_gsc_enable_authentication(struct device *dev, enable_auth_in.port.attached_transcoder = (u8)data->hdcp_transcoder; enable_auth_in.stream_type = data->streams[0].stream_type; - byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&enable_auth_in, + byte = intel_hdcp_gsc_msg_send(gsc_context, &enable_auth_in, sizeof(enable_auth_in), - (u8 *)&enable_auth_out, + &enable_auth_out, sizeof(enable_auth_out)); if (byte < 0) { drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); @@ -565,13 +570,13 @@ int intel_hdcp_gsc_enable_authentication(struct device *dev, return 0; } -int +static int intel_hdcp_gsc_close_session(struct device *dev, struct hdcp_port_data *data) { struct wired_cmd_close_session_in session_close_in = {}; struct wired_cmd_close_session_out session_close_out = {}; + struct intel_hdcp_gsc_context *gsc_context; struct intel_display *display; - struct drm_i915_private *i915; ssize_t byte; if (!dev || !data) @@ -582,7 +587,7 @@ intel_hdcp_gsc_close_session(struct device *dev, struct hdcp_port_data *data) dev_err(dev, "DRM not initialized, aborting HDCP.\n"); return -ENODEV; } - i915 = to_i915(display->drm); + gsc_context = display->hdcp.gsc_context; session_close_in.header.api_version = HDCP_API_VERSION; session_close_in.header.command_id = WIRED_CLOSE_SESSION; @@ -594,9 +599,9 @@ intel_hdcp_gsc_close_session(struct device *dev, struct hdcp_port_data *data) session_close_in.port.physical_port = (u8)data->hdcp_ddi; session_close_in.port.attached_transcoder = (u8)data->hdcp_transcoder; - byte = intel_hdcp_gsc_msg_send(i915, (u8 *)&session_close_in, + byte = intel_hdcp_gsc_msg_send(gsc_context, &session_close_in, sizeof(session_close_in), - (u8 *)&session_close_out, + &session_close_out, sizeof(session_close_out)); if (byte < 0) { drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); @@ -611,3 +616,57 @@ intel_hdcp_gsc_close_session(struct device *dev, struct hdcp_port_data *data) return 0; } + +static const struct i915_hdcp_ops gsc_hdcp_ops = { + .initiate_hdcp2_session = intel_hdcp_gsc_initiate_session, + .verify_receiver_cert_prepare_km = + intel_hdcp_gsc_verify_receiver_cert_prepare_km, + .verify_hprime = intel_hdcp_gsc_verify_hprime, + .store_pairing_info = intel_hdcp_gsc_store_pairing_info, + .initiate_locality_check = intel_hdcp_gsc_initiate_locality_check, + .verify_lprime = intel_hdcp_gsc_verify_lprime, + .get_session_key = intel_hdcp_gsc_get_session_key, + .repeater_check_flow_prepare_ack = + intel_hdcp_gsc_repeater_check_flow_prepare_ack, + .verify_mprime = intel_hdcp_gsc_verify_mprime, + .enable_hdcp_authentication = intel_hdcp_gsc_enable_authentication, + .close_hdcp_session = intel_hdcp_gsc_close_session, +}; + +int intel_hdcp_gsc_init(struct intel_display *display) +{ + struct intel_hdcp_gsc_context *gsc_context; + struct i915_hdcp_arbiter *arbiter; + int ret = 0; + + arbiter = kzalloc(sizeof(*arbiter), GFP_KERNEL); + if (!arbiter) + return -ENOMEM; + + mutex_lock(&display->hdcp.hdcp_mutex); + + gsc_context = intel_hdcp_gsc_context_alloc(display->drm); + if (IS_ERR(gsc_context)) { + ret = PTR_ERR(gsc_context); + kfree(arbiter); + goto out; + } + + display->hdcp.arbiter = arbiter; + display->hdcp.arbiter->hdcp_dev = display->drm->dev; + display->hdcp.arbiter->ops = &gsc_hdcp_ops; + display->hdcp.gsc_context = gsc_context; + +out: + mutex_unlock(&display->hdcp.hdcp_mutex); + + return ret; +} + +void intel_hdcp_gsc_fini(struct intel_display *display) +{ + intel_hdcp_gsc_context_free(display->hdcp.gsc_context); + display->hdcp.gsc_context = NULL; + kfree(display->hdcp.arbiter); + display->hdcp.arbiter = NULL; +} diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h index 2d597f27e931..9f54157a4a3e 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h +++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.h @@ -6,68 +6,9 @@ #ifndef __INTEL_HDCP_GSC_MESSAGE_H__ #define __INTEL_HDCP_GSC_MESSAGE_H__ -#include <linux/types.h> - -struct device; -struct drm_i915_private; -struct hdcp_port_data; -struct hdcp2_ake_init; -struct hdcp2_ake_send_cert; -struct hdcp2_ake_no_stored_km; -struct hdcp2_ake_send_hprime; -struct hdcp2_ake_send_pairing_info; -struct hdcp2_lc_init; -struct hdcp2_lc_send_lprime; -struct hdcp2_ske_send_eks; -struct hdcp2_rep_send_receiverid_list; -struct hdcp2_rep_send_ack; -struct hdcp2_rep_stream_ready; struct intel_display; -ssize_t intel_hdcp_gsc_msg_send(struct drm_i915_private *i915, u8 *msg_in, - size_t msg_in_len, u8 *msg_out, - size_t msg_out_len); -bool intel_hdcp_gsc_check_status(struct intel_display *display); -int -intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data, - struct hdcp2_ake_init *ake_data); -int -intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev, - struct hdcp_port_data *data, - struct hdcp2_ake_send_cert *rx_cert, - bool *km_stored, - struct hdcp2_ake_no_stored_km - *ek_pub_km, - size_t *msg_sz); -int -intel_hdcp_gsc_verify_hprime(struct device *dev, struct hdcp_port_data *data, - struct hdcp2_ake_send_hprime *rx_hprime); -int -intel_hdcp_gsc_store_pairing_info(struct device *dev, struct hdcp_port_data *data, - struct hdcp2_ake_send_pairing_info *pairing_info); -int -intel_hdcp_gsc_initiate_locality_check(struct device *dev, - struct hdcp_port_data *data, - struct hdcp2_lc_init *lc_init_data); -int -intel_hdcp_gsc_verify_lprime(struct device *dev, struct hdcp_port_data *data, - struct hdcp2_lc_send_lprime *rx_lprime); -int intel_hdcp_gsc_get_session_key(struct device *dev, - struct hdcp_port_data *data, - struct hdcp2_ske_send_eks *ske_data); -int -intel_hdcp_gsc_repeater_check_flow_prepare_ack(struct device *dev, - struct hdcp_port_data *data, - struct hdcp2_rep_send_receiverid_list - *rep_topology, - struct hdcp2_rep_send_ack - *rep_send_ack); -int intel_hdcp_gsc_verify_mprime(struct device *dev, - struct hdcp_port_data *data, - struct hdcp2_rep_stream_ready *stream_ready); -int intel_hdcp_gsc_enable_authentication(struct device *dev, - struct hdcp_port_data *data); -int -intel_hdcp_gsc_close_session(struct device *dev, struct hdcp_port_data *data); +int intel_hdcp_gsc_init(struct intel_display *display); +void intel_hdcp_gsc_fini(struct intel_display *display); #endif /* __INTEL_HDCP_GSC_MESSAGE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index f9fa17e1f584..98033471902c 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -38,14 +38,15 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> #include <drm/drm_edid.h> +#include <drm/drm_print.h> #include <drm/drm_probe_helper.h> #include <drm/intel/intel_lpe_audio.h> #include <media/cec-notifier.h> #include "g4x_hdmi.h" -#include "i915_drv.h" #include "i915_reg.h" +#include "i915_utils.h" #include "intel_atomic.h" #include "intel_audio.h" #include "intel_connector.h" @@ -715,7 +716,7 @@ intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder, struct hdmi_avi_infoframe *frame = &crtc_state->infoframes.avi.avi; const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - struct drm_connector *connector = conn_state->connector; + struct intel_connector *connector = to_intel_connector(conn_state->connector); int ret; if (!crtc_state->has_infoframe) @@ -724,7 +725,7 @@ intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder, crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_AVI); - ret = drm_hdmi_avi_infoframe_from_display_mode(frame, connector, + ret = drm_hdmi_avi_infoframe_from_display_mode(frame, &connector->base, adjusted_mode); if (ret) return false; @@ -743,7 +744,7 @@ intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder, crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB); if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_RGB) { - drm_hdmi_avi_infoframe_quant_range(frame, connector, + drm_hdmi_avi_infoframe_quant_range(frame, &connector->base, adjusted_mode, crtc_state->limited_color_range ? HDMI_QUANTIZATION_RANGE_LIMITED : @@ -769,7 +770,7 @@ intel_hdmi_compute_spd_infoframe(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(crtc_state); struct hdmi_spd_infoframe *frame = &crtc_state->infoframes.spd.spd; int ret; @@ -779,7 +780,7 @@ intel_hdmi_compute_spd_infoframe(struct intel_encoder *encoder, crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_SPD); - if (IS_DGFX(i915)) + if (display->platform.dgfx) ret = hdmi_spd_infoframe_init(frame, "Intel", "Discrete gfx"); else ret = hdmi_spd_infoframe_init(frame, "Intel", "Integrated gfx"); @@ -979,7 +980,6 @@ static bool intel_hdmi_set_gcp_infoframe(struct intel_encoder *encoder, const 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 intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); i915_reg_t reg; @@ -989,9 +989,9 @@ static bool intel_hdmi_set_gcp_infoframe(struct intel_encoder *encoder, if (HAS_DDI(display)) reg = HSW_TVIDEO_DIP_GCP(display, crtc_state->cpu_transcoder); - else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + else if (display->platform.valleyview || display->platform.cherryview) reg = VLV_TVIDEO_DIP_GCP(crtc->pipe); - else if (HAS_PCH_SPLIT(dev_priv)) + else if (HAS_PCH_SPLIT(display)) reg = TVIDEO_DIP_GCP(crtc->pipe); else return false; @@ -1005,7 +1005,6 @@ void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); i915_reg_t reg; @@ -1015,9 +1014,9 @@ void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder, if (HAS_DDI(display)) reg = HSW_TVIDEO_DIP_GCP(display, crtc_state->cpu_transcoder); - else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + else if (display->platform.valleyview || display->platform.cherryview) reg = VLV_TVIDEO_DIP_GCP(crtc->pipe); - else if (HAS_PCH_SPLIT(dev_priv)) + else if (HAS_PCH_SPLIT(display)) reg = TVIDEO_DIP_GCP(crtc->pipe); else return; @@ -1029,9 +1028,9 @@ static void intel_hdmi_compute_gcp_infoframe(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - if (IS_G4X(dev_priv) || !crtc_state->has_infoframe) + if (display->platform.g4x || !crtc_state->has_infoframe) return; crtc_state->infoframes.enable |= @@ -1539,7 +1538,6 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *dig_port, struct intel_display *display = to_intel_display(dig_port); struct intel_hdmi *hdmi = &dig_port->hdmi; struct intel_connector *connector = hdmi->attached_connector; - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); int ret; if (!enable) @@ -1558,7 +1556,7 @@ int intel_hdmi_hdcp_toggle_signalling(struct intel_digital_port *dig_port, * WA: To fix incorrect positioning of the window of * opportunity and enc_en signalling in KABYLAKE. */ - if (IS_KABYLAKE(dev_priv) && enable) + if (display->platform.kabylake && enable) return kbl_repositioning_enc_en_signal(connector, cpu_transcoder); @@ -1570,7 +1568,6 @@ bool intel_hdmi_hdcp_check_link_once(struct intel_digital_port *dig_port, struct intel_connector *connector) { struct intel_display *display = to_intel_display(dig_port); - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); enum port port = dig_port->base.port; enum transcoder cpu_transcoder = connector->hdcp.cpu_transcoder; int ret; @@ -1583,15 +1580,15 @@ bool intel_hdmi_hdcp_check_link_once(struct intel_digital_port *dig_port, if (ret) return false; - intel_de_write(i915, HDCP_RPRIME(i915, cpu_transcoder, port), ri.reg); + intel_de_write(display, HDCP_RPRIME(display, cpu_transcoder, port), ri.reg); /* Wait for Ri prime match */ - if (wait_for((intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)) & + if (wait_for((intel_de_read(display, HDCP_STATUS(display, cpu_transcoder, port)) & (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC)) == (HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1)) { drm_dbg_kms(display->drm, "Ri' mismatch detected (%x)\n", - intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, - port))); + intel_de_read(display, HDCP_STATUS(display, cpu_transcoder, + port))); return false; } return true; @@ -1814,14 +1811,13 @@ static const struct intel_hdcp_shim intel_hdmi_hdcp_shim = { static int intel_hdmi_source_max_tmds_clock(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); int max_tmds_clock, vbt_max_tmds_clock; - if (DISPLAY_VER(display) >= 13 || IS_ALDERLAKE_S(dev_priv)) + if (DISPLAY_VER(display) >= 13 || display->platform.alderlake_s) max_tmds_clock = 600000; else if (DISPLAY_VER(display) >= 10) max_tmds_clock = 594000; - else if (DISPLAY_VER(display) >= 8 || IS_HASWELL(dev_priv)) + else if (DISPLAY_VER(display) >= 8 || display->platform.haswell) max_tmds_clock = 300000; else if (DISPLAY_VER(display) >= 5) max_tmds_clock = 225000; @@ -1880,7 +1876,6 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, bool has_hdmi_sink) { struct intel_display *display = to_intel_display(hdmi); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_encoder *encoder = &hdmi_to_dig_port(hdmi)->base; if (clock < 25000) @@ -1890,16 +1885,16 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi, return MODE_CLOCK_HIGH; /* GLK DPLL can't generate 446-480 MHz */ - if (IS_GEMINILAKE(dev_priv) && clock > 446666 && clock < 480000) + if (display->platform.geminilake && clock > 446666 && clock < 480000) return MODE_CLOCK_RANGE; /* BXT/GLK DPLL can't generate 223-240 MHz */ - if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) && + if ((display->platform.geminilake || display->platform.broxton) && clock > 223333 && clock < 240000) return MODE_CLOCK_RANGE; /* CHV DPLL can't generate 216-240 MHz */ - if (IS_CHERRYVIEW(dev_priv) && clock > 216000 && clock < 240000) + if (display->platform.cherryview && clock > 216000 && clock < 240000) return MODE_CLOCK_RANGE; /* ICL+ combo PHY PLL can't generate 500-533.2 MHz */ @@ -1943,11 +1938,12 @@ static bool intel_hdmi_source_bpc_possible(struct intel_display *display, int bp } } -static bool intel_hdmi_sink_bpc_possible(struct drm_connector *connector, +static bool intel_hdmi_sink_bpc_possible(struct drm_connector *_connector, int bpc, bool has_hdmi_sink, enum intel_output_format sink_format) { - const struct drm_display_info *info = &connector->display_info; + struct intel_connector *connector = to_intel_connector(_connector); + const struct drm_display_info *info = &connector->base.display_info; const struct drm_hdmi_info *hdmi = &info->hdmi; switch (bpc) { @@ -1976,12 +1972,13 @@ static bool intel_hdmi_sink_bpc_possible(struct drm_connector *connector, } static enum drm_mode_status -intel_hdmi_mode_clock_valid(struct drm_connector *connector, int clock, +intel_hdmi_mode_clock_valid(struct drm_connector *_connector, int clock, bool has_hdmi_sink, enum intel_output_format sink_format) { - struct intel_display *display = to_intel_display(connector->dev); - struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector)); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector); + struct intel_hdmi *hdmi = intel_attached_hdmi(connector); enum drm_mode_status status = MODE_OK; int bpc; @@ -1996,7 +1993,8 @@ intel_hdmi_mode_clock_valid(struct drm_connector *connector, int clock, if (!intel_hdmi_source_bpc_possible(display, bpc)) continue; - if (!intel_hdmi_sink_bpc_possible(connector, bpc, has_hdmi_sink, sink_format)) + if (!intel_hdmi_sink_bpc_possible(&connector->base, bpc, has_hdmi_sink, + sink_format)) continue; status = hdmi_port_clock_valid(hdmi, tmds_clock, true, has_hdmi_sink); @@ -2011,15 +2009,16 @@ intel_hdmi_mode_clock_valid(struct drm_connector *connector, int clock, } static enum drm_mode_status -intel_hdmi_mode_valid(struct drm_connector *connector, +intel_hdmi_mode_valid(struct drm_connector *_connector, const struct drm_display_mode *mode) { - struct intel_display *display = to_intel_display(connector->dev); - struct intel_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector)); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector); + struct intel_hdmi *hdmi = intel_attached_hdmi(connector); enum drm_mode_status status; int clock = mode->clock; - int max_dotclk = to_i915(connector->dev)->display.cdclk.max_dotclk_freq; - bool has_hdmi_sink = intel_has_hdmi_sink(hdmi, connector->state); + int max_dotclk = display->cdclk.max_dotclk_freq; + bool has_hdmi_sink = intel_has_hdmi_sink(hdmi, connector->base.state); bool ycbcr_420_only; enum intel_output_format sink_format; @@ -2048,22 +2047,23 @@ intel_hdmi_mode_valid(struct drm_connector *connector, if (clock > 600000) return MODE_CLOCK_HIGH; - ycbcr_420_only = drm_mode_is_420_only(&connector->display_info, mode); + ycbcr_420_only = drm_mode_is_420_only(&connector->base.display_info, mode); if (ycbcr_420_only) sink_format = INTEL_OUTPUT_FORMAT_YCBCR420; else sink_format = INTEL_OUTPUT_FORMAT_RGB; - status = intel_hdmi_mode_clock_valid(connector, clock, has_hdmi_sink, sink_format); + status = intel_hdmi_mode_clock_valid(&connector->base, clock, has_hdmi_sink, sink_format); if (status != MODE_OK) { if (ycbcr_420_only || - !connector->ycbcr_420_allowed || - !drm_mode_is_420_also(&connector->display_info, mode)) + !connector->base.ycbcr_420_allowed || + !drm_mode_is_420_also(&connector->base.display_info, mode)) return status; sink_format = INTEL_OUTPUT_FORMAT_YCBCR420; - status = intel_hdmi_mode_clock_valid(connector, clock, has_hdmi_sink, sink_format); + status = intel_hdmi_mode_clock_valid(&connector->base, clock, has_hdmi_sink, + sink_format); if (status != MODE_OK) return status; } @@ -2074,16 +2074,16 @@ intel_hdmi_mode_valid(struct drm_connector *connector, bool intel_hdmi_bpc_possible(const struct intel_crtc_state *crtc_state, int bpc, bool has_hdmi_sink) { - struct drm_atomic_state *state = crtc_state->uapi.state; - struct drm_connector_state *connector_state; - struct drm_connector *connector; + struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state); + struct intel_digital_connector_state *connector_state; + struct intel_connector *connector; int i; - for_each_new_connector_in_state(state, connector, connector_state, i) { - if (connector_state->crtc != crtc_state->uapi.crtc) + for_each_new_intel_connector_in_state(state, connector, connector_state, i) { + if (connector_state->base.crtc != crtc_state->uapi.crtc) continue; - if (!intel_hdmi_sink_bpc_possible(connector, bpc, has_hdmi_sink, + if (!intel_hdmi_sink_bpc_possible(&connector->base, bpc, has_hdmi_sink, crtc_state->sink_format)) return false; } @@ -2211,7 +2211,7 @@ static bool intel_hdmi_has_audio(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { - struct drm_connector *connector = conn_state->connector; + struct intel_connector *connector = to_intel_connector(conn_state->connector); const struct intel_digital_connector_state *intel_conn_state = to_intel_digital_connector_state(conn_state); @@ -2219,7 +2219,7 @@ static bool intel_hdmi_has_audio(struct intel_encoder *encoder, return false; if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO) - return connector->display_info.has_audio; + return connector->base.display_info.has_audio; else return intel_conn_state->force_audio == HDMI_AUDIO_ON; } @@ -2323,14 +2323,14 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder, { struct intel_display *display = to_intel_display(encoder); struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; - struct drm_connector *connector = conn_state->connector; - struct drm_scdc *scdc = &connector->display_info.hdmi.scdc; + struct intel_connector *connector = to_intel_connector(conn_state->connector); + struct drm_scdc *scdc = &connector->base.display_info.hdmi.scdc; int ret; if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) return -EINVAL; - if (!connector->interlace_allowed && + if (!connector->base.interlace_allowed && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) return -EINVAL; @@ -2425,25 +2425,26 @@ void intel_hdmi_encoder_shutdown(struct intel_encoder *encoder) } static void -intel_hdmi_unset_edid(struct drm_connector *connector) +intel_hdmi_unset_edid(struct drm_connector *_connector) { - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector)); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE; intel_hdmi->dp_dual_mode.max_tmds_clock = 0; - drm_edid_free(to_intel_connector(connector)->detect_edid); - to_intel_connector(connector)->detect_edid = NULL; + drm_edid_free(connector->detect_edid); + connector->detect_edid = NULL; } static void -intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector) +intel_hdmi_dp_dual_mode_detect(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_hdmi *hdmi = intel_attached_hdmi(to_intel_connector(connector)); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector); + struct intel_hdmi *hdmi = intel_attached_hdmi(connector); struct intel_encoder *encoder = &hdmi_to_dig_port(hdmi)->base; - struct i2c_adapter *ddc = connector->ddc; + struct i2c_adapter *ddc = connector->base.ddc; enum drm_dp_dual_mode_type type; type = drm_dp_dual_mode_detect(display->drm, ddc); @@ -2458,7 +2459,7 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector) * if the port is a dual mode capable DP port. */ if (type == DRM_DP_DUAL_MODE_UNKNOWN) { - if (!connector->force && + if (!connector->base.force && intel_bios_encoder_supports_dp_dual_mode(encoder->devdata)) { drm_dbg_kms(display->drm, "Assuming DP dual mode adaptor presence based on VBT\n"); @@ -2481,7 +2482,7 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector) hdmi->dp_dual_mode.max_tmds_clock); /* Older VBTs are often buggy and can't be trusted :( Play it safe. */ - if ((DISPLAY_VER(display) >= 8 || IS_HASWELL(dev_priv)) && + if ((DISPLAY_VER(display) >= 8 || display->platform.haswell) && !intel_bios_encoder_supports_dp_dual_mode(encoder->devdata)) { drm_dbg_kms(display->drm, "Ignoring DP dual mode adaptor max TMDS clock for native HDMI port\n"); @@ -2490,34 +2491,35 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector) } static bool -intel_hdmi_set_edid(struct drm_connector *connector) +intel_hdmi_set_edid(struct drm_connector *_connector) { - struct intel_display *display = to_intel_display(connector->dev); - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector)); - struct i2c_adapter *ddc = connector->ddc; + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector); + struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); + struct i2c_adapter *ddc = connector->base.ddc; intel_wakeref_t wakeref; const struct drm_edid *drm_edid; bool connected = false; wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS); - drm_edid = drm_edid_read_ddc(connector, ddc); + drm_edid = drm_edid_read_ddc(&connector->base, ddc); if (!drm_edid && !intel_gmbus_is_forced_bit(ddc)) { drm_dbg_kms(display->drm, "HDMI GMBUS EDID read failed, retry using GPIO bit-banging\n"); intel_gmbus_force_bit(ddc, true); - drm_edid = drm_edid_read_ddc(connector, ddc); + drm_edid = drm_edid_read_ddc(&connector->base, ddc); intel_gmbus_force_bit(ddc, false); } /* Below we depend on display info having been updated */ - drm_edid_connector_update(connector, drm_edid); + drm_edid_connector_update(&connector->base, drm_edid); - to_intel_connector(connector)->detect_edid = drm_edid; + connector->detect_edid = drm_edid; if (drm_edid_is_digital(drm_edid)) { - intel_hdmi_dp_dual_mode_detect(connector); + intel_hdmi_dp_dual_mode_detect(&connector->base); connected = true; } @@ -2525,28 +2527,29 @@ intel_hdmi_set_edid(struct drm_connector *connector) intel_display_power_put(display, POWER_DOMAIN_GMBUS, wakeref); cec_notifier_set_phys_addr(intel_hdmi->cec_notifier, - connector->display_info.source_physical_address); + connector->base.display_info.source_physical_address); return connected; } static enum drm_connector_status -intel_hdmi_detect(struct drm_connector *connector, bool force) +intel_hdmi_detect(struct drm_connector *_connector, bool force) { - struct intel_display *display = to_intel_display(connector->dev); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector); enum drm_connector_status status = connector_status_disconnected; - struct intel_hdmi *intel_hdmi = intel_attached_hdmi(to_intel_connector(connector)); + struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); struct intel_encoder *encoder = &hdmi_to_dig_port(intel_hdmi)->base; intel_wakeref_t wakeref; drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n", - connector->base.id, connector->name); + connector->base.base.id, connector->base.name); if (!intel_display_device_enabled(display)) return connector_status_disconnected; if (!intel_display_driver_check_access(display)) - return connector->status; + return connector->base.status; wakeref = intel_display_power_get(display, POWER_DOMAIN_GMBUS); @@ -2554,9 +2557,9 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) !intel_digital_port_connected(encoder)) goto out; - intel_hdmi_unset_edid(connector); + intel_hdmi_unset_edid(&connector->base); - if (intel_hdmi_set_edid(connector)) + if (intel_hdmi_set_edid(&connector->base)) status = connector_status_connected; out: @@ -2569,49 +2572,54 @@ out: } static void -intel_hdmi_force(struct drm_connector *connector) +intel_hdmi_force(struct drm_connector *_connector) { - struct intel_display *display = to_intel_display(connector->dev); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(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_hdmi_unset_edid(connector); + intel_hdmi_unset_edid(&connector->base); - if (connector->status != connector_status_connected) + if (connector->base.status != connector_status_connected) return; - intel_hdmi_set_edid(connector); + intel_hdmi_set_edid(&connector->base); } -static int intel_hdmi_get_modes(struct drm_connector *connector) +static int intel_hdmi_get_modes(struct drm_connector *_connector) { + struct intel_connector *connector = to_intel_connector(_connector); + /* drm_edid_connector_update() done in ->detect() or ->force() */ - return drm_edid_connector_add_modes(connector); + return drm_edid_connector_add_modes(&connector->base); } static int -intel_hdmi_connector_register(struct drm_connector *connector) +intel_hdmi_connector_register(struct drm_connector *_connector) { + struct intel_connector *connector = to_intel_connector(_connector); int ret; - ret = intel_connector_register(connector); + ret = intel_connector_register(&connector->base); if (ret) return ret; return ret; } -static void intel_hdmi_connector_unregister(struct drm_connector *connector) +static void intel_hdmi_connector_unregister(struct drm_connector *_connector) { - struct cec_notifier *n = intel_attached_hdmi(to_intel_connector(connector))->cec_notifier; + struct intel_connector *connector = to_intel_connector(_connector); + struct cec_notifier *n = intel_attached_hdmi(connector)->cec_notifier; cec_notifier_conn_unregister(n); - intel_connector_unregister(connector); + intel_connector_unregister(&connector->base); } static const struct drm_connector_funcs intel_hdmi_connector_funcs = { @@ -2627,15 +2635,16 @@ static const struct drm_connector_funcs intel_hdmi_connector_funcs = { .atomic_duplicate_state = intel_digital_connector_duplicate_state, }; -static int intel_hdmi_connector_atomic_check(struct drm_connector *connector, +static int intel_hdmi_connector_atomic_check(struct drm_connector *_connector, struct drm_atomic_state *state) { - struct intel_display *display = to_intel_display(connector->dev); + struct intel_connector *connector = to_intel_connector(_connector); + struct intel_display *display = to_intel_display(connector); if (HAS_DDI(display)) - return intel_digital_connector_atomic_check(connector, state); + return intel_digital_connector_atomic_check(&connector->base, state); else - return g4x_hdmi_connector_atomic_check(connector, state); + return g4x_hdmi_connector_atomic_check(&connector->base, state); } static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs = { @@ -2645,22 +2654,23 @@ static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs }; static void -intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector) +intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *_connector) { + struct intel_connector *connector = to_intel_connector(_connector); struct intel_display *display = to_intel_display(intel_hdmi); - intel_attach_force_audio_property(connector); - intel_attach_broadcast_rgb_property(connector); - intel_attach_aspect_ratio_property(connector); + intel_attach_force_audio_property(&connector->base); + intel_attach_broadcast_rgb_property(&connector->base); + intel_attach_aspect_ratio_property(&connector->base); - intel_attach_hdmi_colorspace_property(connector); - drm_connector_attach_content_type_property(connector); + intel_attach_hdmi_colorspace_property(&connector->base); + drm_connector_attach_content_type_property(&connector->base); if (DISPLAY_VER(display) >= 10) - drm_connector_attach_hdr_output_metadata_property(connector); + drm_connector_attach_hdr_output_metadata_property(&connector->base); if (!HAS_GMCH(display)) - drm_connector_attach_max_bpc_property(connector, 8, 12); + drm_connector_attach_max_bpc_property(&connector->base, 8, 12); } /* @@ -2682,25 +2692,26 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c * True on success, false on failure. */ bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder, - struct drm_connector *connector, + struct drm_connector *_connector, bool high_tmds_clock_ratio, bool scrambling) { + struct intel_connector *connector = to_intel_connector(_connector); struct intel_display *display = to_intel_display(encoder); struct drm_scrambling *sink_scrambling = - &connector->display_info.hdmi.scdc.scrambling; + &connector->base.display_info.hdmi.scdc.scrambling; if (!sink_scrambling->supported) return true; drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] scrambling=%s, TMDS bit clock ratio=1/%d\n", - connector->base.id, connector->name, + connector->base.base.id, connector->base.name, str_yes_no(scrambling), high_tmds_clock_ratio ? 40 : 10); /* Set TMDS bit clock ratio to 1/40 or 1/10, and enable/disable scrambling */ - return drm_scdc_set_high_tmds_clock_ratio(connector, high_tmds_clock_ratio) && - drm_scdc_set_scrambling(connector, scrambling); + return drm_scdc_set_high_tmds_clock_ratio(&connector->base, high_tmds_clock_ratio) && + drm_scdc_set_scrambling(&connector->base, scrambling); } static u8 chv_encoder_to_ddc_pin(struct intel_encoder *encoder) @@ -2811,7 +2822,7 @@ static u8 mcc_encoder_to_ddc_pin(struct intel_encoder *encoder) static u8 rkl_encoder_to_ddc_pin(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); WARN_ON(encoder->port == PORT_C); @@ -2822,7 +2833,7 @@ static u8 rkl_encoder_to_ddc_pin(struct intel_encoder *encoder) * combo outputs. With CMP, the traditional DDI A-D pins are used for * all outputs. */ - if (INTEL_PCH_TYPE(dev_priv) >= PCH_TGP && phy >= PHY_C) + if (INTEL_PCH_TYPE(display) >= PCH_TGP && phy >= PHY_C) return GMBUS_PIN_9_TC1_ICP + phy - PHY_C; return GMBUS_PIN_1_BXT + phy; @@ -2831,7 +2842,6 @@ static u8 rkl_encoder_to_ddc_pin(struct intel_encoder *encoder) static u8 gen9bc_tgp_encoder_to_ddc_pin(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *i915 = to_i915(encoder->base.dev); enum phy phy = intel_encoder_to_phy(encoder); drm_WARN_ON(display->drm, encoder->port == PORT_A); @@ -2842,7 +2852,7 @@ static u8 gen9bc_tgp_encoder_to_ddc_pin(struct intel_encoder *encoder) * combo outputs. With CMP, the traditional DDI A-D pins are used for * all outputs. */ - if (INTEL_PCH_TYPE(i915) >= PCH_TGP && phy >= PHY_C) + if (INTEL_PCH_TYPE(display) >= PCH_TGP && phy >= PHY_C) return GMBUS_PIN_9_TC1_ICP + phy - PHY_C; return GMBUS_PIN_1_BXT + phy; @@ -2895,27 +2905,26 @@ static u8 g4x_encoder_to_ddc_pin(struct intel_encoder *encoder) static u8 intel_hdmi_default_ddc_pin(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u8 ddc_pin; - if (IS_ALDERLAKE_S(dev_priv)) + if (display->platform.alderlake_s) ddc_pin = adls_encoder_to_ddc_pin(encoder); - else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1) + else if (INTEL_PCH_TYPE(display) >= PCH_DG1) ddc_pin = dg1_encoder_to_ddc_pin(encoder); - else if (IS_ROCKETLAKE(dev_priv)) + else if (display->platform.rocketlake) ddc_pin = rkl_encoder_to_ddc_pin(encoder); - else if (DISPLAY_VER(display) == 9 && HAS_PCH_TGP(dev_priv)) + else if (DISPLAY_VER(display) == 9 && HAS_PCH_TGP(display)) ddc_pin = gen9bc_tgp_encoder_to_ddc_pin(encoder); - else if ((IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) && - HAS_PCH_TGP(dev_priv)) + else if ((display->platform.jasperlake || display->platform.elkhartlake) && + HAS_PCH_TGP(display)) ddc_pin = mcc_encoder_to_ddc_pin(encoder); - else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) + else if (INTEL_PCH_TYPE(display) >= PCH_ICP) ddc_pin = icl_encoder_to_ddc_pin(encoder); - else if (HAS_PCH_CNP(dev_priv)) + else if (HAS_PCH_CNP(display)) ddc_pin = cnp_encoder_to_ddc_pin(encoder); - else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + else if (display->platform.geminilake || display->platform.broxton) ddc_pin = bxt_encoder_to_ddc_pin(encoder); - else if (IS_CHERRYVIEW(dev_priv)) + else if (display->platform.cherryview) ddc_pin = chv_encoder_to_ddc_pin(encoder); else ddc_pin = g4x_encoder_to_ddc_pin(encoder); @@ -2989,15 +2998,13 @@ static u8 intel_hdmi_ddc_pin(struct intel_encoder *encoder) void intel_infoframe_init(struct intel_digital_port *dig_port) { struct intel_display *display = to_intel_display(dig_port); - struct drm_i915_private *dev_priv = - to_i915(dig_port->base.base.dev); - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + if (display->platform.valleyview || display->platform.cherryview) { dig_port->write_infoframe = vlv_write_infoframe; dig_port->read_infoframe = vlv_read_infoframe; dig_port->set_infoframes = vlv_set_infoframes; dig_port->infoframes_enabled = vlv_infoframes_enabled; - } else if (IS_G4X(dev_priv)) { + } else if (display->platform.g4x) { dig_port->write_infoframe = g4x_write_infoframe; dig_port->read_infoframe = g4x_read_infoframe; dig_port->set_infoframes = g4x_set_infoframes; @@ -3014,7 +3021,7 @@ void intel_infoframe_init(struct intel_digital_port *dig_port) dig_port->set_infoframes = hsw_set_infoframes; dig_port->infoframes_enabled = hsw_infoframes_enabled; } - } else if (HAS_PCH_IBX(dev_priv)) { + } else if (HAS_PCH_IBX(display)) { dig_port->write_infoframe = ibx_write_infoframe; dig_port->read_infoframe = ibx_read_infoframe; dig_port->set_infoframes = ibx_set_infoframes; diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c index 6885e5a09079..fc5d8928c37e 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -183,9 +183,7 @@ static bool intel_hpd_irq_storm_detect(struct intel_display *display, static bool detection_work_enabled(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - - lockdep_assert_held(&i915->irq_lock); + lockdep_assert_held(&display->irq.lock); return display->hotplug.detection_work_enabled; } @@ -195,7 +193,7 @@ mod_delayed_detection_work(struct intel_display *display, struct delayed_work *w { struct drm_i915_private *i915 = to_i915(display->drm); - lockdep_assert_held(&i915->irq_lock); + lockdep_assert_held(&display->irq.lock); if (!detection_work_enabled(display)) return false; @@ -208,7 +206,7 @@ queue_delayed_detection_work(struct intel_display *display, struct delayed_work { struct drm_i915_private *i915 = to_i915(display->drm); - lockdep_assert_held(&i915->irq_lock); + lockdep_assert_held(&display->irq.lock); if (!detection_work_enabled(display)) return false; @@ -221,7 +219,7 @@ queue_detection_work(struct intel_display *display, struct work_struct *work) { struct drm_i915_private *i915 = to_i915(display->drm); - lockdep_assert_held(&i915->irq_lock); + lockdep_assert_held(&display->irq.lock); if (!detection_work_enabled(display)) return false; @@ -232,12 +230,11 @@ queue_detection_work(struct intel_display *display, struct work_struct *work) static void intel_hpd_irq_storm_switch_to_polling(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct drm_connector_list_iter conn_iter; struct intel_connector *connector; bool hpd_disabled = false; - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); drm_connector_list_iter_begin(display->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { @@ -276,7 +273,6 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work) { struct intel_display *display = container_of(work, typeof(*display), hotplug.reenable_work.work); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct drm_connector_list_iter conn_iter; struct intel_connector *connector; struct ref_tracker *wakeref; @@ -284,7 +280,7 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work) wakeref = intel_display_rpm_get(display); - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); drm_connector_list_iter_begin(display->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { @@ -308,7 +304,7 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work) intel_hpd_irq_setup(display); - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); intel_display_rpm_put(display, wakeref); } @@ -376,9 +372,7 @@ static bool hpd_pin_has_pulse(struct intel_display *display, enum hpd_pin pin) static bool hpd_pin_is_blocked(struct intel_display *display, enum hpd_pin pin) { - struct drm_i915_private *i915 = to_i915(display->drm); - - lockdep_assert_held(&i915->irq_lock); + lockdep_assert_held(&display->irq.lock); return display->hotplug.stats[pin].blocked_count; } @@ -400,14 +394,13 @@ static void i915_digport_work_func(struct work_struct *work) { struct intel_display *display = container_of(work, struct intel_display, hotplug.dig_port_work); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_hotplug *hotplug = &display->hotplug; u32 long_hpd_pin_mask, short_hpd_pin_mask; struct intel_encoder *encoder; u32 blocked_hpd_pin_mask; u32 old_bits = 0; - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); blocked_hpd_pin_mask = get_blocked_hpd_pin_mask(display); long_hpd_pin_mask = hotplug->long_hpd_pin_mask & ~blocked_hpd_pin_mask; @@ -415,7 +408,7 @@ static void i915_digport_work_func(struct work_struct *work) short_hpd_pin_mask = hotplug->short_hpd_pin_mask & ~blocked_hpd_pin_mask; hotplug->short_hpd_pin_mask &= ~short_hpd_pin_mask; - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); for_each_intel_encoder(display->drm, encoder) { struct intel_digital_port *dig_port; @@ -442,11 +435,11 @@ static void i915_digport_work_func(struct work_struct *work) } if (old_bits) { - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); display->hotplug.event_bits |= old_bits; queue_delayed_detection_work(display, &display->hotplug.hotplug_work, 0); - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); } } @@ -460,17 +453,16 @@ static void i915_digport_work_func(struct work_struct *work) void intel_hpd_trigger_irq(struct intel_digital_port *dig_port) { struct intel_display *display = to_intel_display(dig_port); - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_hotplug *hotplug = &display->hotplug; struct intel_encoder *encoder = &dig_port->base; - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); hotplug->short_hpd_pin_mask |= BIT(encoder->hpd_pin); if (!hpd_pin_is_blocked(display, encoder->hpd_pin)) queue_work(hotplug->dp_wq, &hotplug->dig_port_work); - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); } /* @@ -480,7 +472,6 @@ static void i915_hotplug_work_func(struct work_struct *work) { struct intel_display *display = container_of(work, struct intel_display, hotplug.hotplug_work.work); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_hotplug *hotplug = &display->hotplug; struct drm_connector_list_iter conn_iter; struct intel_connector *connector; @@ -494,7 +485,7 @@ static void i915_hotplug_work_func(struct work_struct *work) mutex_lock(&display->drm->mode_config.mutex); drm_dbg_kms(display->drm, "running encoder hotplug functions\n"); - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); blocked_hpd_pin_mask = get_blocked_hpd_pin_mask(display); hpd_event_bits = hotplug->event_bits & ~blocked_hpd_pin_mask; @@ -505,7 +496,7 @@ static void i915_hotplug_work_func(struct work_struct *work) /* Enable polling for connectors which had HPD IRQ storms */ intel_hpd_irq_storm_switch_to_polling(display); - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); /* Skip calling encode hotplug handlers if ignore long HPD set*/ if (display->hotplug.ignore_long_hpd) { @@ -569,13 +560,13 @@ static void i915_hotplug_work_func(struct work_struct *work) /* Remove shared HPD pins that have changed */ retry &= ~changed; if (retry) { - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); display->hotplug.retry_bits |= retry; mod_delayed_detection_work(display, &display->hotplug.hotplug_work, msecs_to_jiffies(HPD_RETRY_DELAY)); - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); } } @@ -599,7 +590,6 @@ static void i915_hotplug_work_func(struct work_struct *work) void intel_hpd_irq_handler(struct intel_display *display, u32 pin_mask, u32 long_mask) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_encoder *encoder; bool storm_detected = false; bool queue_dig = false, queue_hp = false; @@ -610,7 +600,7 @@ void intel_hpd_irq_handler(struct intel_display *display, if (!pin_mask) return; - spin_lock(&dev_priv->irq_lock); + spin_lock(&display->irq.lock); /* * Determine whether ->hpd_pulse() exists for each pin, and @@ -711,7 +701,7 @@ void intel_hpd_irq_handler(struct intel_display *display, queue_delayed_detection_work(display, &display->hotplug.hotplug_work, 0); - spin_unlock(&dev_priv->irq_lock); + spin_unlock(&display->irq.lock); } /** @@ -730,7 +720,6 @@ void intel_hpd_irq_handler(struct intel_display *display, */ void intel_hpd_init(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); int i; if (!HAS_DISPLAY(display)) @@ -745,9 +734,9 @@ void intel_hpd_init(struct intel_display *display) * Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked checks happy. */ - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); intel_hpd_irq_setup(display); - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); } static void i915_hpd_poll_detect_connectors(struct intel_display *display) @@ -797,7 +786,6 @@ static void i915_hpd_poll_init_work(struct work_struct *work) { struct intel_display *display = container_of(work, typeof(*display), hotplug.poll_init_work); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct drm_connector_list_iter conn_iter; struct intel_connector *connector; intel_wakeref_t wakeref; @@ -820,7 +808,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work) cancel_work(&display->hotplug.poll_init_work); } - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); drm_connector_list_iter_begin(display->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { @@ -841,7 +829,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work) } drm_connector_list_iter_end(&conn_iter); - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); if (enabled) drm_kms_helper_poll_reschedule(display->drm); @@ -879,8 +867,6 @@ static void i915_hpd_poll_init_work(struct work_struct *work) */ void intel_hpd_poll_enable(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (!HAS_DISPLAY(display) || !intel_display_device_enabled(display)) return; @@ -892,10 +878,10 @@ void intel_hpd_poll_enable(struct intel_display *display) * As well, there's no issue if we race here since we always reschedule * this worker anyway */ - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); queue_detection_work(display, &display->hotplug.poll_init_work); - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); } /** @@ -919,17 +905,15 @@ void intel_hpd_poll_enable(struct intel_display *display) */ void intel_hpd_poll_disable(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (!HAS_DISPLAY(display)) return; WRITE_ONCE(display->hotplug.poll_enabled, false); - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); queue_detection_work(display, &display->hotplug.poll_init_work); - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); } void intel_hpd_poll_fini(struct intel_display *display) @@ -981,12 +965,10 @@ static bool cancel_all_detection_work(struct intel_display *display) void intel_hpd_cancel_work(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (!HAS_DISPLAY(display)) return; - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); drm_WARN_ON(display->drm, get_blocked_hpd_pin_mask(display)); @@ -995,7 +977,7 @@ void intel_hpd_cancel_work(struct intel_display *display) display->hotplug.event_bits = 0; display->hotplug.retry_bits = 0; - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); cancel_work_sync(&display->hotplug.dig_port_work); @@ -1009,13 +991,12 @@ void intel_hpd_cancel_work(struct intel_display *display) static void queue_work_for_missed_irqs(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_hotplug *hotplug = &display->hotplug; bool queue_hp_work = false; u32 blocked_hpd_pin_mask; enum hpd_pin pin; - lockdep_assert_held(&i915->irq_lock); + lockdep_assert_held(&display->irq.lock); blocked_hpd_pin_mask = get_blocked_hpd_pin_mask(display); if ((hotplug->event_bits | hotplug->retry_bits) & ~blocked_hpd_pin_mask) @@ -1043,10 +1024,9 @@ static void queue_work_for_missed_irqs(struct intel_display *display) static bool block_hpd_pin(struct intel_display *display, enum hpd_pin pin) { - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_hotplug *hotplug = &display->hotplug; - lockdep_assert_held(&i915->irq_lock); + lockdep_assert_held(&display->irq.lock); hotplug->stats[pin].blocked_count++; @@ -1055,10 +1035,9 @@ static bool block_hpd_pin(struct intel_display *display, enum hpd_pin pin) static bool unblock_hpd_pin(struct intel_display *display, enum hpd_pin pin) { - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_hotplug *hotplug = &display->hotplug; - lockdep_assert_held(&i915->irq_lock); + lockdep_assert_held(&display->irq.lock); if (drm_WARN_ON(display->drm, hotplug->stats[pin].blocked_count == 0)) return true; @@ -1095,19 +1074,18 @@ static bool unblock_hpd_pin(struct intel_display *display, enum hpd_pin pin) void intel_hpd_block(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_hotplug *hotplug = &display->hotplug; bool do_flush = false; if (encoder->hpd_pin == HPD_NONE) return; - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); if (block_hpd_pin(display, encoder->hpd_pin)) do_flush = true; - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); if (do_flush && hpd_pin_has_pulse(display, encoder->hpd_pin)) flush_work(&hotplug->dig_port_work); @@ -1125,17 +1103,16 @@ void intel_hpd_block(struct intel_encoder *encoder) void intel_hpd_unblock(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *i915 = to_i915(display->drm); if (encoder->hpd_pin == HPD_NONE) return; - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); if (unblock_hpd_pin(display, encoder->hpd_pin)) queue_work_for_missed_irqs(display); - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); } /** @@ -1149,14 +1126,13 @@ void intel_hpd_unblock(struct intel_encoder *encoder) void intel_hpd_clear_and_unblock(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_hotplug *hotplug = &display->hotplug; enum hpd_pin pin = encoder->hpd_pin; if (pin == HPD_NONE) return; - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); if (unblock_hpd_pin(display, pin)) { hotplug->event_bits &= ~BIT(pin); @@ -1165,39 +1141,34 @@ void intel_hpd_clear_and_unblock(struct intel_encoder *encoder) hotplug->long_hpd_pin_mask &= ~BIT(pin); } - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); } void intel_hpd_enable_detection_work(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); display->hotplug.detection_work_enabled = true; queue_work_for_missed_irqs(display); - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); } void intel_hpd_disable_detection_work(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - - spin_lock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); display->hotplug.detection_work_enabled = false; - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); cancel_all_detection_work(display); } bool intel_hpd_schedule_detection(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); unsigned long flags; bool ret; - spin_lock_irqsave(&i915->irq_lock, flags); + spin_lock_irqsave(&display->irq.lock, flags); ret = queue_delayed_detection_work(display, &display->hotplug.hotplug_work, 0); - spin_unlock_irqrestore(&i915->irq_lock, flags); + spin_unlock_irqrestore(&display->irq.lock, flags); return ret; } @@ -1228,7 +1199,6 @@ static ssize_t i915_hpd_storm_ctl_write(struct file *file, { struct seq_file *m = file->private_data; struct intel_display *display = m->private; - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_hotplug *hotplug = &display->hotplug; unsigned int new_threshold; int i; @@ -1260,12 +1230,12 @@ static ssize_t i915_hpd_storm_ctl_write(struct file *file, else drm_dbg_kms(display->drm, "Disabling HPD storm detection\n"); - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); hotplug->hpd_storm_threshold = new_threshold; /* Reset the HPD storm stats so we don't accidentally trigger a storm */ for_each_hpd_pin(i) hotplug->stats[i].count = 0; - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); /* Re-enable hpd immediately if we were in an irq storm */ flush_delayed_work(&display->hotplug.reenable_work); @@ -1310,7 +1280,6 @@ static ssize_t i915_hpd_short_storm_ctl_write(struct file *file, { struct seq_file *m = file->private_data; struct intel_display *display = m->private; - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_hotplug *hotplug = &display->hotplug; char *newline; char tmp[16]; @@ -1339,12 +1308,12 @@ static ssize_t i915_hpd_short_storm_ctl_write(struct file *file, drm_dbg_kms(display->drm, "%sabling HPD short storm detection\n", new_state ? "En" : "Dis"); - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); hotplug->hpd_short_storm_enabled = new_state; /* Reset the HPD storm stats so we don't accidentally trigger a storm */ for_each_hpd_pin(i) hotplug->stats[i].count = 0; - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); /* Re-enable hpd immediately if we were in an irq storm */ flush_delayed_work(&display->hotplug.reenable_work); diff --git a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c index 2463e61e7802..c024b42369c8 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c @@ -3,8 +3,10 @@ * Copyright © 2023 Intel Corporation */ -#include "i915_drv.h" +#include <drm/drm_print.h> + #include "i915_reg.h" +#include "i915_utils.h" #include "intel_de.h" #include "intel_display_irq.h" #include "intel_display_types.h" @@ -133,7 +135,6 @@ static const u32 hpd_mtp[HPD_NUM_PINS] = { static void intel_hpd_init_pins(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_hotplug *hpd = &display->hotplug; if (HAS_GMCH(display)) { @@ -160,33 +161,31 @@ static void intel_hpd_init_pins(struct intel_display *display) else hpd->hpd = hpd_ilk; - if ((INTEL_PCH_TYPE(dev_priv) < PCH_DG1) && - (!HAS_PCH_SPLIT(dev_priv) || HAS_PCH_NOP(dev_priv))) + if ((INTEL_PCH_TYPE(display) < PCH_DG1) && + (!HAS_PCH_SPLIT(display) || HAS_PCH_NOP(display))) return; - if (INTEL_PCH_TYPE(dev_priv) >= PCH_MTL) + if (INTEL_PCH_TYPE(display) >= PCH_MTL) hpd->pch_hpd = hpd_mtp; - else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1) + else if (INTEL_PCH_TYPE(display) >= PCH_DG1) hpd->pch_hpd = hpd_sde_dg1; - else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) + else if (INTEL_PCH_TYPE(display) >= PCH_ICP) hpd->pch_hpd = hpd_icp; - else if (HAS_PCH_CNP(dev_priv) || HAS_PCH_SPT(dev_priv)) + else if (HAS_PCH_CNP(display) || HAS_PCH_SPT(display)) hpd->pch_hpd = hpd_spt; - else if (HAS_PCH_LPT(dev_priv) || HAS_PCH_CPT(dev_priv)) + else if (HAS_PCH_LPT(display) || HAS_PCH_CPT(display)) hpd->pch_hpd = hpd_cpt; - else if (HAS_PCH_IBX(dev_priv)) + else if (HAS_PCH_IBX(display)) hpd->pch_hpd = hpd_ibx; else - MISSING_CASE(INTEL_PCH_TYPE(dev_priv)); + MISSING_CASE(INTEL_PCH_TYPE(display)); } /* For display hotplug interrupt */ void i915_hotplug_interrupt_update_locked(struct intel_display *display, u32 mask, u32 bits) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); drm_WARN_ON(display->drm, bits & ~mask); intel_de_rmw(display, PORT_HOTPLUG_EN(display), mask, bits); @@ -208,11 +207,9 @@ void i915_hotplug_interrupt_update(struct intel_display *display, u32 mask, u32 bits) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); i915_hotplug_interrupt_update_locked(display, mask, bits); - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); } static bool gen11_port_hotplug_long_detect(enum hpd_pin pin, u32 val) @@ -557,7 +554,6 @@ void xelpdp_pica_irq_handler(struct intel_display *display, u32 iir) void icp_irq_handler(struct intel_display *display, u32 pch_iir) { - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 ddi_hotplug_trigger = pch_iir & SDE_DDI_HOTPLUG_MASK_ICP; u32 tc_hotplug_trigger = pch_iir & SDE_TC_HOTPLUG_MASK_ICP; u32 pin_mask = 0, long_mask = 0; @@ -566,9 +562,9 @@ void icp_irq_handler(struct intel_display *display, u32 pch_iir) u32 dig_hotplug_reg; /* Locking due to DSI native GPIO sequences */ - spin_lock(&dev_priv->irq_lock); + spin_lock(&display->irq.lock); dig_hotplug_reg = intel_de_rmw(display, SHOTPLUG_CTL_DDI, 0, 0); - spin_unlock(&dev_priv->irq_lock); + spin_unlock(&display->irq.lock); intel_get_hpd_pins(display, &pin_mask, &long_mask, ddi_hotplug_trigger, dig_hotplug_reg, @@ -711,7 +707,7 @@ static u32 ibx_hotplug_mask(enum hpd_pin hpd_pin) static u32 ibx_hotplug_enables(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); switch (encoder->hpd_pin) { case HPD_PORT_A: @@ -719,7 +715,7 @@ static u32 ibx_hotplug_enables(struct intel_encoder *encoder) * When CPU and PCH are on the same package, port A * HPD must be enabled in both north and south. */ - return HAS_PCH_LPT_LP(i915) ? + return HAS_PCH_LPT_LP(display) ? PORTA_HOTPLUG_ENABLE : 0; case HPD_PORT_B: return PORTB_HOTPLUG_ENABLE | @@ -940,18 +936,17 @@ static void gen11_tbt_hpd_enable_detection(struct intel_encoder *encoder) static void gen11_hpd_enable_detection(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); gen11_tc_hpd_enable_detection(encoder); gen11_tbt_hpd_enable_detection(encoder); - if (INTEL_PCH_TYPE(i915) >= PCH_ICP) + if (INTEL_PCH_TYPE(display) >= PCH_ICP) icp_hpd_enable_detection(encoder); } static void gen11_hpd_irq_setup(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 hotplug_irqs, enabled_irqs; enabled_irqs = intel_hpd_enabled_irqs(display, display->hotplug.hpd); @@ -964,7 +959,7 @@ static void gen11_hpd_irq_setup(struct intel_display *display) gen11_tc_hpd_detection_setup(display); gen11_tbt_hpd_detection_setup(display); - if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) + if (INTEL_PCH_TYPE(display) >= PCH_ICP) icp_hpd_irq_setup(display); } @@ -1138,7 +1133,6 @@ static void xelpdp_hpd_enable_detection(struct intel_encoder *encoder) static void xelpdp_hpd_irq_setup(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); u32 hotplug_irqs, enabled_irqs; enabled_irqs = intel_hpd_enabled_irqs(display, display->hotplug.hpd); @@ -1150,9 +1144,9 @@ static void xelpdp_hpd_irq_setup(struct intel_display *display) xelpdp_pica_hpd_detection_setup(display); - if (INTEL_PCH_TYPE(i915) >= PCH_LNL) + if (INTEL_PCH_TYPE(display) >= PCH_LNL) xe2lpd_sde_hpd_irq_setup(display); - else if (INTEL_PCH_TYPE(i915) >= PCH_MTL) + else if (INTEL_PCH_TYPE(display) >= PCH_MTL) mtp_hpd_irq_setup(display); } @@ -1194,10 +1188,8 @@ static u32 spt_hotplug2_enables(struct intel_encoder *encoder) static void spt_hpd_detection_setup(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - /* Display WA #1179 WaHardHangonHotPlug: cnp */ - if (HAS_PCH_CNP(dev_priv)) { + if (HAS_PCH_CNP(display)) { intel_de_rmw(display, SOUTH_CHICKEN1, CHASSIS_CLK_REQ_DURATION_MASK, CHASSIS_CLK_REQ_DURATION(0xf)); } @@ -1215,10 +1207,9 @@ static void spt_hpd_detection_setup(struct intel_display *display) static void spt_hpd_enable_detection(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *i915 = to_i915(encoder->base.dev); /* Display WA #1179 WaHardHangonHotPlug: cnp */ - if (HAS_PCH_CNP(i915)) { + if (HAS_PCH_CNP(display)) { intel_de_rmw(display, SOUTH_CHICKEN1, CHASSIS_CLK_REQ_DURATION_MASK, CHASSIS_CLK_REQ_DURATION(0xf)); @@ -1235,10 +1226,9 @@ static void spt_hpd_enable_detection(struct intel_encoder *encoder) static void spt_hpd_irq_setup(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 hotplug_irqs, enabled_irqs; - if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) + if (INTEL_PCH_TYPE(display) >= PCH_CNP) intel_de_write(display, SHPD_FILTER_CNT, SHPD_FILTER_CNT_500_ADJ); enabled_irqs = intel_hpd_enabled_irqs(display, display->hotplug.pch_hpd); @@ -1402,10 +1392,9 @@ static void i915_hpd_enable_detection(struct intel_encoder *encoder) static void i915_hpd_irq_setup(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 hotplug_en; - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); /* * Note HDMI and DP share hotplug bits. Enable bits are the same for all @@ -1474,8 +1463,6 @@ void intel_hpd_irq_setup(struct intel_display *display) void intel_hotplug_irq_init(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - intel_hpd_init_pins(display); intel_hpd_init_early(display); @@ -1484,9 +1471,9 @@ void intel_hotplug_irq_init(struct intel_display *display) if (HAS_HOTPLUG(display)) display->funcs.hotplug = &i915_hpd_funcs; } else { - if (HAS_PCH_DG2(i915)) + if (HAS_PCH_DG2(display)) display->funcs.hotplug = &icp_hpd_funcs; - else if (HAS_PCH_DG1(i915)) + else if (HAS_PCH_DG1(display)) display->funcs.hotplug = &dg1_hpd_funcs; else if (DISPLAY_VER(display) >= 14) display->funcs.hotplug = &xelpdp_hpd_funcs; @@ -1494,9 +1481,9 @@ void intel_hotplug_irq_init(struct intel_display *display) display->funcs.hotplug = &gen11_hpd_funcs; else if (display->platform.geminilake || display->platform.broxton) display->funcs.hotplug = &bxt_hpd_funcs; - else if (INTEL_PCH_TYPE(i915) >= PCH_ICP) + else if (INTEL_PCH_TYPE(display) >= PCH_ICP) display->funcs.hotplug = &icp_hpd_funcs; - else if (INTEL_PCH_TYPE(i915) >= PCH_SPT) + else if (INTEL_PCH_TYPE(display) >= PCH_SPT) display->funcs.hotplug = &spt_hpd_funcs; else display->funcs.hotplug = &ilk_hpd_funcs; diff --git a/drivers/gpu/drm/i915/display/intel_lpe_audio.c b/drivers/gpu/drm/i915/display/intel_lpe_audio.c index 59551c8414c2..666148a14522 100644 --- a/drivers/gpu/drm/i915/display/intel_lpe_audio.c +++ b/drivers/gpu/drm/i915/display/intel_lpe_audio.c @@ -179,7 +179,7 @@ static int lpe_audio_irq_init(struct intel_display *display) handle_simple_irq, "hdmi_lpe_audio_irq_handler"); - return irq_set_chip_data(irq, dev_priv); + return 0; } static bool lpe_audio_detect(struct intel_display *display) diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index 89d26913e253..8ce7c630da52 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -37,9 +37,9 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> #include <drm/drm_edid.h> +#include <drm/drm_print.h> #include <drm/drm_probe_helper.h> -#include "i915_drv.h" #include "i915_reg.h" #include "intel_atomic.h" #include "intel_backlight.h" @@ -87,13 +87,12 @@ static struct intel_lvds_encoder *to_lvds_encoder(struct intel_encoder *encoder) bool intel_lvds_port_enabled(struct intel_display *display, i915_reg_t lvds_reg, enum pipe *pipe) { - struct drm_i915_private *i915 = to_i915(display->drm); u32 val; val = intel_de_read(display, lvds_reg); /* asserts want to know the pipe even if the port is disabled */ - if (HAS_PCH_CPT(i915)) + if (HAS_PCH_CPT(display)) *pipe = REG_FIELD_GET(LVDS_PIPE_SEL_MASK_CPT, val); else *pipe = REG_FIELD_GET(LVDS_PIPE_SEL_MASK, val); @@ -243,13 +242,12 @@ static void intel_pre_enable_lvds(struct intel_atomic_state *state, { struct intel_display *display = to_intel_display(state); struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder); - struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; enum pipe pipe = crtc->pipe; u32 temp; - if (HAS_PCH_SPLIT(i915)) { + if (HAS_PCH_SPLIT(display)) { assert_fdi_rx_pll_disabled(display, pipe); assert_shared_dpll_disabled(display, crtc_state->shared_dpll); } else { @@ -261,7 +259,7 @@ static void intel_pre_enable_lvds(struct intel_atomic_state *state, temp = lvds_encoder->init_lvds_val; temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; - if (HAS_PCH_CPT(i915)) { + if (HAS_PCH_CPT(display)) { temp &= ~LVDS_PIPE_SEL_MASK_CPT; temp |= LVDS_PIPE_SEL_CPT(pipe); } else { @@ -421,7 +419,6 @@ static int intel_lvds_compute_config(struct intel_encoder *encoder, struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder); struct intel_connector *connector = lvds_encoder->attached_connector; struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; @@ -435,7 +432,7 @@ static int intel_lvds_compute_config(struct intel_encoder *encoder, return -EINVAL; } - 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; @@ -798,7 +795,6 @@ bool intel_is_dual_link_lvds(struct intel_display *display) static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder) { struct intel_display *display = to_intel_display(&lvds_encoder->base); - struct drm_i915_private *i915 = to_i915(lvds_encoder->base.base.dev); struct intel_connector *connector = lvds_encoder->attached_connector; const struct drm_display_mode *fixed_mode = intel_panel_preferred_fixed_mode(connector); @@ -822,7 +818,7 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder) * register is uninitialized. */ val = intel_de_read(display, lvds_encoder->reg); - if (HAS_PCH_CPT(i915)) + if (HAS_PCH_CPT(display)) val &= ~(LVDS_DETECTED | LVDS_PIPE_SEL_MASK_CPT); else val &= ~(LVDS_DETECTED | LVDS_PIPE_SEL_MASK); @@ -846,7 +842,6 @@ static void intel_lvds_add_properties(struct drm_connector *connector) */ void intel_lvds_init(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_lvds_encoder *lvds_encoder; struct intel_connector *connector; const struct drm_edid *drm_edid; @@ -868,14 +863,14 @@ void intel_lvds_init(struct intel_display *display) return; } - if (HAS_PCH_SPLIT(i915)) + if (HAS_PCH_SPLIT(display)) lvds_reg = PCH_LVDS; else lvds_reg = LVDS; lvds = intel_de_read(display, lvds_reg); - if (HAS_PCH_SPLIT(i915)) { + if (HAS_PCH_SPLIT(display)) { if ((lvds & LVDS_DETECTED) == 0) return; } @@ -915,7 +910,7 @@ void intel_lvds_init(struct intel_display *display) encoder->enable = intel_enable_lvds; encoder->pre_enable = intel_pre_enable_lvds; encoder->compute_config = intel_lvds_compute_config; - if (HAS_PCH_SPLIT(i915)) { + if (HAS_PCH_SPLIT(display)) { encoder->disable = pch_disable_lvds; encoder->post_disable = pch_post_disable_lvds; } else { diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 9e963bce340f..0325b0c9506d 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -6,11 +6,11 @@ * state. */ -#include <drm/drm_atomic_uapi.h> #include <drm/drm_atomic_state_helper.h> +#include <drm/drm_atomic_uapi.h> +#include <drm/drm_print.h> #include <drm/drm_vblank.h> -#include "i915_drv.h" #include "i915_reg.h" #include "i9xx_wm.h" #include "intel_atomic.h" @@ -31,13 +31,14 @@ #include "intel_pmdemand.h" #include "intel_tc.h" #include "intel_vblank.h" +#include "intel_vga.h" #include "intel_wm.h" #include "skl_watermark.h" static void intel_crtc_disable_noatomic_begin(struct intel_crtc *crtc, struct drm_modeset_acquire_ctx *ctx) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_plane *plane; @@ -48,7 +49,7 @@ static void intel_crtc_disable_noatomic_begin(struct intel_crtc *crtc, if (!crtc_state->hw.active) return; - for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) { + for_each_intel_plane_on_crtc(display->drm, crtc, plane) { const struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); @@ -56,9 +57,9 @@ static void intel_crtc_disable_noatomic_begin(struct intel_crtc *crtc, intel_plane_disable_noatomic(crtc, plane); } - state = drm_atomic_state_alloc(&i915->drm); + state = drm_atomic_state_alloc(display->drm); if (!state) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "failed to disable [CRTC:%d:%s], out of memory", crtc->base.base.id, crtc->base.name); return; @@ -68,7 +69,7 @@ static void intel_crtc_disable_noatomic_begin(struct intel_crtc *crtc, to_intel_atomic_state(state)->internal = true; /* Everything's already locked, -EDEADLK can't happen. */ - for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc, + for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc, BIT(pipe) | intel_crtc_joiner_secondary_pipes(crtc_state)) { struct intel_crtc_state *temp_crtc_state = @@ -77,14 +78,14 @@ static void intel_crtc_disable_noatomic_begin(struct intel_crtc *crtc, ret = drm_atomic_add_affected_connectors(state, &temp_crtc->base); - drm_WARN_ON(&i915->drm, IS_ERR(temp_crtc_state) || ret); + drm_WARN_ON(display->drm, IS_ERR(temp_crtc_state) || ret); } - i915->display.funcs.display->crtc_disable(to_intel_atomic_state(state), crtc); + display->funcs.display->crtc_disable(to_intel_atomic_state(state), crtc); drm_atomic_state_put(state); - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] hw state adjusted, was enabled, now disabled\n", crtc->base.base.id, crtc->base.name); @@ -118,13 +119,12 @@ static void set_encoder_for_connector(struct intel_connector *connector, static void reset_encoder_connector_state(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct intel_pmdemand_state *pmdemand_state = - to_intel_pmdemand_state(i915->display.pmdemand.obj.state); + to_intel_pmdemand_state(display->pmdemand.obj.state); struct intel_connector *connector; struct drm_connector_list_iter conn_iter; - drm_connector_list_iter_begin(&i915->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { if (connector->base.encoder != &encoder->base) continue; @@ -143,10 +143,10 @@ static void reset_encoder_connector_state(struct intel_encoder *encoder) static void reset_crtc_encoder_state(struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_encoder *encoder; - for_each_encoder_on_crtc(&i915->drm, &crtc->base, encoder) { + for_each_encoder_on_crtc(display->drm, &crtc->base, encoder) { reset_encoder_connector_state(encoder); encoder->base.crtc = NULL; } @@ -183,13 +183,13 @@ static void intel_crtc_disable_noatomic_complete(struct intel_crtc *crtc) * Return all the pipes using a transcoder in @transcoder_mask. * For joiner configs return only the joiner primary. */ -static u8 get_transcoder_pipes(struct drm_i915_private *i915, +static u8 get_transcoder_pipes(struct intel_display *display, u8 transcoder_mask) { struct intel_crtc *temp_crtc; u8 pipes = 0; - for_each_intel_crtc(&i915->drm, temp_crtc) { + for_each_intel_crtc(display->drm, temp_crtc) { struct intel_crtc_state *temp_crtc_state = to_intel_crtc_state(temp_crtc->base.state); @@ -214,7 +214,6 @@ static void get_portsync_pipes(struct intel_crtc *crtc, u8 *master_pipe_mask, u8 *slave_pipes_mask) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_crtc *master_crtc; @@ -233,20 +232,20 @@ static void get_portsync_pipes(struct intel_crtc *crtc, else master_transcoder = crtc_state->master_transcoder; - *master_pipe_mask = get_transcoder_pipes(i915, BIT(master_transcoder)); - drm_WARN_ON(&i915->drm, !is_power_of_2(*master_pipe_mask)); + *master_pipe_mask = get_transcoder_pipes(display, BIT(master_transcoder)); + drm_WARN_ON(display->drm, !is_power_of_2(*master_pipe_mask)); master_crtc = intel_crtc_for_pipe(display, ffs(*master_pipe_mask) - 1); master_crtc_state = to_intel_crtc_state(master_crtc->base.state); - *slave_pipes_mask = get_transcoder_pipes(i915, master_crtc_state->sync_mode_slaves_mask); + *slave_pipes_mask = get_transcoder_pipes(display, master_crtc_state->sync_mode_slaves_mask); } -static u8 get_joiner_secondary_pipes(struct drm_i915_private *i915, u8 primary_pipes_mask) +static u8 get_joiner_secondary_pipes(struct intel_display *display, u8 primary_pipes_mask) { struct intel_crtc *primary_crtc; u8 pipes = 0; - for_each_intel_crtc_in_pipe_mask(&i915->drm, primary_crtc, primary_pipes_mask) { + for_each_intel_crtc_in_pipe_mask(display->drm, primary_crtc, primary_pipes_mask) { struct intel_crtc_state *primary_crtc_state = to_intel_crtc_state(primary_crtc->base.state); @@ -259,45 +258,45 @@ static u8 get_joiner_secondary_pipes(struct drm_i915_private *i915, u8 primary_p static void intel_crtc_disable_noatomic(struct intel_crtc *crtc, struct drm_modeset_acquire_ctx *ctx) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); + struct intel_crtc *temp_crtc; u8 portsync_master_mask; u8 portsync_slaves_mask; u8 joiner_secondaries_mask; - struct intel_crtc *temp_crtc; /* TODO: Add support for MST */ get_portsync_pipes(crtc, &portsync_master_mask, &portsync_slaves_mask); - joiner_secondaries_mask = get_joiner_secondary_pipes(i915, + joiner_secondaries_mask = get_joiner_secondary_pipes(display, portsync_master_mask | portsync_slaves_mask); - drm_WARN_ON(&i915->drm, + drm_WARN_ON(display->drm, portsync_master_mask & portsync_slaves_mask || portsync_master_mask & joiner_secondaries_mask || portsync_slaves_mask & joiner_secondaries_mask); - for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc, joiner_secondaries_mask) + for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc, joiner_secondaries_mask) intel_crtc_disable_noatomic_begin(temp_crtc, ctx); - for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc, portsync_slaves_mask) + for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc, portsync_slaves_mask) intel_crtc_disable_noatomic_begin(temp_crtc, ctx); - for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc, portsync_master_mask) + for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc, portsync_master_mask) intel_crtc_disable_noatomic_begin(temp_crtc, ctx); - for_each_intel_crtc_in_pipe_mask(&i915->drm, temp_crtc, + for_each_intel_crtc_in_pipe_mask(display->drm, temp_crtc, joiner_secondaries_mask | portsync_slaves_mask | portsync_master_mask) intel_crtc_disable_noatomic_complete(temp_crtc); } -static void intel_modeset_update_connector_atomic_state(struct drm_i915_private *i915) +static void intel_modeset_update_connector_atomic_state(struct intel_display *display) { struct intel_connector *connector; struct drm_connector_list_iter conn_iter; - drm_connector_list_iter_begin(&i915->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { struct drm_connector_state *conn_state = connector->base.state; struct intel_encoder *encoder = @@ -319,7 +318,7 @@ static void intel_modeset_update_connector_atomic_state(struct drm_i915_private static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); if (intel_crtc_is_joiner_secondary(crtc_state)) return; @@ -332,7 +331,7 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode; crtc_state->uapi.scaling_filter = crtc_state->hw.scaling_filter; - if (DISPLAY_INFO(i915)->color.degamma_lut_size) { + if (DISPLAY_INFO(display)->color.degamma_lut_size) { /* assume 1:1 mapping */ drm_property_replace_blob(&crtc_state->hw.degamma_lut, crtc_state->pre_csc_lut); @@ -347,7 +346,7 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state * to gamma_lut as that is the only valid source of LUTs * in the uapi. */ - drm_WARN_ON(&i915->drm, crtc_state->post_csc_lut && + drm_WARN_ON(display->drm, crtc_state->post_csc_lut && crtc_state->pre_csc_lut); drm_property_replace_blob(&crtc_state->hw.degamma_lut, @@ -366,15 +365,14 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state } static void -intel_sanitize_plane_mapping(struct drm_i915_private *i915) +intel_sanitize_plane_mapping(struct intel_display *display) { - struct intel_display *display = &i915->display; struct intel_crtc *crtc; - if (DISPLAY_VER(i915) >= 4) + if (DISPLAY_VER(display) >= 4) return; - for_each_intel_crtc(&i915->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_plane *plane = to_intel_plane(crtc->base.primary); struct intel_crtc *plane_crtc; @@ -386,7 +384,7 @@ intel_sanitize_plane_mapping(struct drm_i915_private *i915) if (pipe == crtc->pipe) continue; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] attached to the wrong pipe, disabling plane\n", plane->base.base.id, plane->base.name); @@ -423,12 +421,12 @@ static bool intel_crtc_needs_link_reset(struct intel_crtc *crtc) static struct intel_connector *intel_encoder_find_connector(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct drm_connector_list_iter conn_iter; struct intel_connector *connector; struct intel_connector *found_connector = NULL; - drm_connector_list_iter_begin(&i915->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { if (&encoder->base == connector->base.encoder) { found_connector = connector; @@ -466,7 +464,7 @@ static void intel_sanitize_fifo_underrun_reporting(const struct intel_crtc_state static bool intel_sanitize_crtc(struct intel_crtc *crtc, struct drm_modeset_acquire_ctx *ctx) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); bool needs_link_reset; @@ -474,7 +472,7 @@ static bool intel_sanitize_crtc(struct intel_crtc *crtc, struct intel_plane *plane; /* Disable everything but the primary plane */ - for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) { + for_each_intel_plane_on_crtc(display->drm, crtc, plane) { const struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); @@ -515,7 +513,7 @@ static bool intel_sanitize_crtc(struct intel_crtc *crtc, return true; } -static void intel_sanitize_all_crtcs(struct drm_i915_private *i915, +static void intel_sanitize_all_crtcs(struct intel_display *display, struct drm_modeset_acquire_ctx *ctx) { struct intel_crtc *crtc; @@ -530,7 +528,7 @@ static void intel_sanitize_all_crtcs(struct drm_i915_private *i915, for (;;) { u32 old_mask = crtcs_forced_off; - for_each_intel_crtc(&i915->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { u32 crtc_mask = drm_crtc_mask(&crtc->base); if (crtcs_forced_off & crtc_mask) @@ -543,7 +541,7 @@ static void intel_sanitize_all_crtcs(struct drm_i915_private *i915, break; } - for_each_intel_crtc(&i915->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); @@ -553,7 +551,7 @@ static void intel_sanitize_all_crtcs(struct drm_i915_private *i915, static bool has_bogus_dpll_config(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); /* * Some SNB BIOSen (eg. ASUS K53SV) are known to misprogram @@ -565,7 +563,7 @@ static bool has_bogus_dpll_config(const struct intel_crtc_state *crtc_state) * without several WARNs, but for now let's take the easy * road. */ - return IS_SANDYBRIDGE(i915) && + return display->platform.sandybridge && crtc_state->hw.active && crtc_state->shared_dpll && crtc_state->port_clock == 0; @@ -574,13 +572,12 @@ static bool has_bogus_dpll_config(const struct intel_crtc_state *crtc_state) static void intel_sanitize_encoder(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct intel_connector *connector; struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); struct intel_crtc_state *crtc_state = crtc ? to_intel_crtc_state(crtc->base.state) : NULL; struct intel_pmdemand_state *pmdemand_state = - to_intel_pmdemand_state(i915->display.pmdemand.obj.state); + to_intel_pmdemand_state(display->pmdemand.obj.state); /* * We need to check both for a crtc link (meaning that the encoder is @@ -591,7 +588,7 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder) crtc_state->hw.active; if (crtc_state && has_bogus_dpll_config(crtc_state)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "BIOS has misprogrammed the hardware. Disabling pipe %c\n", pipe_name(crtc->pipe)); has_active_crtc = false; @@ -599,7 +596,7 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder) connector = intel_encoder_find_connector(encoder); if (connector && !has_active_crtc) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[ENCODER:%d:%s] has active connectors but no active pipe!\n", encoder->base.base.id, encoder->base.name); @@ -616,7 +613,7 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder) if (crtc_state) { struct drm_encoder *best_encoder; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[ENCODER:%d:%s] manually disabled\n", encoder->base.base.id, encoder->base.name); @@ -650,18 +647,17 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder) /* notify opregion of the sanitized encoder state */ intel_opregion_notify_encoder(encoder, connector && has_active_crtc); - if (HAS_DDI(i915)) + if (HAS_DDI(display)) intel_ddi_sanitize_encoder_pll_mapping(encoder); } /* FIXME read out full plane state for all planes */ -static void readout_plane_state(struct drm_i915_private *i915) +static void readout_plane_state(struct intel_display *display) { - struct intel_display *display = &i915->display; struct intel_plane *plane; struct intel_crtc *crtc; - for_each_intel_plane(&i915->drm, plane) { + for_each_intel_plane(display->drm, plane) { struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); struct intel_crtc_state *crtc_state; @@ -675,13 +671,13 @@ static void readout_plane_state(struct drm_i915_private *i915) intel_set_plane_visible(crtc_state, plane_state, visible); - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] hw state readout: %s, pipe %c\n", plane->base.base.id, plane->base.name, str_enabled_disabled(visible), pipe_name(pipe)); } - for_each_intel_crtc(&i915->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); @@ -689,18 +685,17 @@ static void readout_plane_state(struct drm_i915_private *i915) } } -static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) +static void intel_modeset_readout_hw_state(struct intel_display *display) { - struct intel_display *display = &i915->display; struct intel_pmdemand_state *pmdemand_state = - to_intel_pmdemand_state(i915->display.pmdemand.obj.state); + to_intel_pmdemand_state(display->pmdemand.obj.state); enum pipe pipe; struct intel_crtc *crtc; struct intel_encoder *encoder; struct intel_connector *connector; struct drm_connector_list_iter conn_iter; - for_each_intel_crtc(&i915->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); @@ -715,15 +710,15 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) crtc->base.enabled = crtc_state->hw.enable; crtc->active = crtc_state->hw.active; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] hw state readout: %s\n", crtc->base.base.id, crtc->base.name, str_enabled_disabled(crtc_state->hw.active)); } - readout_plane_state(i915); + readout_plane_state(display); - for_each_intel_encoder(&i915->drm, encoder) { + for_each_intel_encoder(display->drm, encoder) { struct intel_crtc_state *crtc_state = NULL; pipe = 0; @@ -742,7 +737,7 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) /* encoder should read be linked to joiner primary */ WARN_ON(intel_crtc_is_joiner_secondary(crtc_state)); - for_each_intel_crtc_in_pipe_mask(&i915->drm, secondary_crtc, + for_each_intel_crtc_in_pipe_mask(display->drm, secondary_crtc, intel_crtc_joiner_secondary_pipes(crtc_state)) { struct intel_crtc_state *secondary_crtc_state; @@ -765,7 +760,7 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) if (encoder->sync_state) encoder->sync_state(encoder, crtc_state); - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[ENCODER:%d:%s] hw state readout: %s, pipe %c\n", encoder->base.base.id, encoder->base.name, str_enabled_disabled(encoder->base.crtc), @@ -774,7 +769,7 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) intel_dpll_readout_hw_state(display); - drm_connector_list_iter_begin(&i915->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { struct intel_crtc_state *crtc_state = NULL; @@ -808,14 +803,14 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) if (connector->sync_state) connector->sync_state(connector, crtc_state); - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] hw state readout: %s\n", connector->base.base.id, connector->base.name, str_enabled_disabled(connector->base.encoder)); } drm_connector_list_iter_end(&conn_iter); - for_each_intel_crtc(&i915->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_plane *plane; @@ -838,7 +833,7 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) intel_crtc_copy_hw_to_uapi_state(crtc_state); } - for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) { + for_each_intel_plane_on_crtc(display->drm, crtc, plane) { const struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); @@ -854,14 +849,14 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) * use plane->min_cdclk() :( */ if (plane_state->uapi.visible && plane->min_cdclk) { - if (crtc_state->double_wide || DISPLAY_VER(i915) >= 10) + if (crtc_state->double_wide || DISPLAY_VER(display) >= 10) crtc_state->min_cdclk[plane->id] = DIV_ROUND_UP(crtc_state->pixel_rate, 2); else crtc_state->min_cdclk[plane->id] = crtc_state->pixel_rate; } - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] min_cdclk %d kHz\n", plane->base.base.id, plane->base.name, crtc_state->min_cdclk[plane->id]); @@ -882,11 +877,11 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) } static void -get_encoder_power_domains(struct drm_i915_private *i915) +get_encoder_power_domains(struct intel_display *display) { struct intel_encoder *encoder; - for_each_intel_encoder(&i915->drm, encoder) { + for_each_intel_encoder(display->drm, encoder) { struct intel_crtc_state *crtc_state; if (!encoder->get_power_domains) @@ -904,47 +899,49 @@ get_encoder_power_domains(struct drm_i915_private *i915) } } -static void intel_early_display_was(struct drm_i915_private *i915) +static void intel_early_display_was(struct intel_display *display) { /* * Display WA #1185 WaDisableDARBFClkGating:glk,icl,ehl,tgl * Also known as Wa_14010480278. */ - if (IS_DISPLAY_VER(i915, 10, 12)) - intel_de_rmw(i915, GEN9_CLKGATE_DIS_0, 0, DARBF_GATING_DIS); + if (IS_DISPLAY_VER(display, 10, 12)) + intel_de_rmw(display, GEN9_CLKGATE_DIS_0, 0, DARBF_GATING_DIS); /* * WaRsPkgCStateDisplayPMReq:hsw * System hang if this isn't done before disabling all planes! */ - if (IS_HASWELL(i915)) - intel_de_rmw(i915, CHICKEN_PAR1_1, 0, FORCE_ARB_IDLE_PLANES); + if (display->platform.haswell) + intel_de_rmw(display, CHICKEN_PAR1_1, 0, FORCE_ARB_IDLE_PLANES); - if (IS_KABYLAKE(i915) || IS_COFFEELAKE(i915) || IS_COMETLAKE(i915)) { + if (display->platform.kabylake || display->platform.coffeelake || + display->platform.cometlake) { /* Display WA #1142:kbl,cfl,cml */ - intel_de_rmw(i915, CHICKEN_PAR1_1, + intel_de_rmw(display, CHICKEN_PAR1_1, KBL_ARB_FILL_SPARE_22, KBL_ARB_FILL_SPARE_22); - intel_de_rmw(i915, CHICKEN_MISC_2, + intel_de_rmw(display, CHICKEN_MISC_2, KBL_ARB_FILL_SPARE_13 | KBL_ARB_FILL_SPARE_14, KBL_ARB_FILL_SPARE_14); } } -void intel_modeset_setup_hw_state(struct drm_i915_private *i915, +void intel_modeset_setup_hw_state(struct intel_display *display, struct drm_modeset_acquire_ctx *ctx) { - struct intel_display *display = &i915->display; struct intel_encoder *encoder; struct intel_crtc *crtc; intel_wakeref_t wakeref; wakeref = intel_display_power_get(display, POWER_DOMAIN_INIT); - intel_early_display_was(i915); - intel_modeset_readout_hw_state(i915); + intel_early_display_was(display); + intel_vga_disable(display); + + intel_modeset_readout_hw_state(display); /* HW state is read out, now we need to sanitize this mess. */ - get_encoder_power_domains(i915); + get_encoder_power_domains(display); intel_pch_sanitize(display); @@ -954,7 +951,7 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915, * intel_sanitize_plane_mapping() may need to do vblank * waits, so we need vblank interrupts restored beforehand. */ - for_each_intel_crtc(&i915->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); @@ -968,20 +965,20 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915, } } - intel_fbc_sanitize(&i915->display); + intel_fbc_sanitize(display); - intel_sanitize_plane_mapping(i915); + intel_sanitize_plane_mapping(display); - for_each_intel_encoder(&i915->drm, encoder) + for_each_intel_encoder(display->drm, encoder) intel_sanitize_encoder(encoder); /* * Sanitizing CRTCs needs their connector atomic state to be * up-to-date, so ensure that already here. */ - intel_modeset_update_connector_atomic_state(i915); + intel_modeset_update_connector_atomic_state(display); - intel_sanitize_all_crtcs(i915, ctx); + intel_sanitize_all_crtcs(display, ctx); intel_dpll_sanitize_state(display); @@ -990,13 +987,13 @@ void intel_modeset_setup_hw_state(struct drm_i915_private *i915, intel_wm_get_hw_state(display); intel_wm_sanitize(display); - for_each_intel_crtc(&i915->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_power_domain_mask put_domains; intel_modeset_get_crtc_power_domains(crtc_state, &put_domains); - if (drm_WARN_ON(&i915->drm, !bitmap_empty(put_domains.bits, POWER_DOMAIN_NUM))) + if (drm_WARN_ON(display->drm, !bitmap_empty(put_domains.bits, POWER_DOMAIN_NUM))) intel_modeset_put_crtc_power_domains(crtc, &put_domains); } diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.h b/drivers/gpu/drm/i915/display/intel_modeset_setup.h index 3beff67b33d0..f5e6f3ae9572 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.h +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.h @@ -6,10 +6,10 @@ #ifndef __INTEL_MODESET_SETUP_H__ #define __INTEL_MODESET_SETUP_H__ -struct drm_i915_private; struct drm_modeset_acquire_ctx; +struct intel_display; -void intel_modeset_setup_hw_state(struct drm_i915_private *i915, +void intel_modeset_setup_hw_state(struct intel_display *display, struct drm_modeset_acquire_ctx *ctx); #endif /* __INTEL_MODESET_SETUP_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_modeset_verify.c b/drivers/gpu/drm/i915/display/intel_modeset_verify.c index a008412fdd04..766a9983665a 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_verify.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_verify.c @@ -6,13 +6,14 @@ */ #include <drm/drm_atomic_state_helper.h> +#include <drm/drm_print.h> -#include "i915_drv.h" #include "intel_atomic.h" #include "intel_crtc.h" #include "intel_crtc_state_dump.h" #include "intel_cx0_phy.h" #include "intel_display.h" +#include "intel_display_core.h" #include "intel_display_types.h" #include "intel_fdi.h" #include "intel_modeset_verify.h" @@ -28,9 +29,8 @@ static void intel_connector_verify_state(const struct intel_crtc_state *crtc_sta { 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); - drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s]\n", + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s]\n", connector->base.base.id, connector->base.name); if (connector->get_hw_state(connector)) { @@ -91,7 +91,6 @@ verify_connector_state(struct intel_atomic_state *state, static void intel_pipe_config_sanity_check(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); if (crtc_state->has_pch_encoder) { int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(display, crtc_state), @@ -103,7 +102,7 @@ static void intel_pipe_config_sanity_check(const struct intel_crtc_state *crtc_s * Yell if the encoder disagrees. Allow for slight * rounding differences. */ - drm_WARN(&i915->drm, abs(fdi_dotclock - dotclock) > 1, + drm_WARN(display->drm, abs(fdi_dotclock - dotclock) > 1, "FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n", fdi_dotclock, dotclock); } @@ -113,17 +112,16 @@ static void verify_encoder_state(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_encoder *encoder; struct drm_connector *connector; const struct drm_connector_state *old_conn_state, *new_conn_state; int i; - for_each_intel_encoder(&i915->drm, encoder) { + for_each_intel_encoder(display->drm, encoder) { bool enabled = false, found = false; enum pipe pipe; - drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s]\n", + drm_dbg_kms(display->drm, "[ENCODER:%d:%s]\n", encoder->base.base.id, encoder->base.name); @@ -166,7 +164,6 @@ verify_crtc_state(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(display->drm); const struct intel_crtc_state *sw_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_crtc_state *hw_crtc_state; @@ -185,7 +182,7 @@ verify_crtc_state(struct intel_atomic_state *state, intel_crtc_get_pipe_config(hw_crtc_state); /* we keep both pipes enabled on 830 */ - if (IS_I830(i915) && hw_crtc_state->hw.active) + if (display->platform.i830 && hw_crtc_state->hw.active) hw_crtc_state->hw.active = sw_crtc_state->hw.active; INTEL_DISPLAY_STATE_WARN(display, diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c index aff9a3455c1b..12308495afa5 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.c +++ b/drivers/gpu/drm/i915/display/intel_overlay.c @@ -291,7 +291,6 @@ static void intel_overlay_flip_prepare(struct intel_overlay *overlay, struct i915_vma *vma) { struct intel_display *display = overlay->display; - struct drm_i915_private *i915 = to_i915(display->drm); enum pipe pipe = overlay->crtc->pipe; struct intel_frontbuffer *frontbuffer = NULL; @@ -307,7 +306,7 @@ static void intel_overlay_flip_prepare(struct intel_overlay *overlay, intel_frontbuffer_put(overlay->frontbuffer); overlay->frontbuffer = frontbuffer; - intel_frontbuffer_flip_prepare(i915, INTEL_FRONTBUFFER_OVERLAY(pipe)); + intel_frontbuffer_flip_prepare(display, INTEL_FRONTBUFFER_OVERLAY(pipe)); overlay->old_vma = overlay->vma; if (vma) @@ -359,14 +358,13 @@ static int intel_overlay_continue(struct intel_overlay *overlay, static void intel_overlay_release_old_vma(struct intel_overlay *overlay) { struct intel_display *display = overlay->display; - struct drm_i915_private *i915 = to_i915(display->drm); struct i915_vma *vma; vma = fetch_and_zero(&overlay->old_vma); if (drm_WARN_ON(display->drm, !vma)) return; - intel_frontbuffer_flip_complete(i915, INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe)); + intel_frontbuffer_flip_complete(display, INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe)); i915_vma_unpin(vma); i915_vma_put(vma); diff --git a/drivers/gpu/drm/i915/display/intel_pch.c b/drivers/gpu/drm/i915/display/intel_pch.c new file mode 100644 index 000000000000..469e8a3cfb49 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_pch.c @@ -0,0 +1,340 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright 2025 Intel Corporation. + */ + +#include <drm/drm_print.h> + +#include "i915_utils.h" +#include "intel_display_core.h" +#include "intel_pch.h" + +#define INTEL_PCH_DEVICE_ID_MASK 0xff80 +#define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 +#define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 +#define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00 +#define INTEL_PCH_LPT_DEVICE_ID_TYPE 0x8c00 +#define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE 0x9c00 +#define INTEL_PCH_WPT_DEVICE_ID_TYPE 0x8c80 +#define INTEL_PCH_WPT_LP_DEVICE_ID_TYPE 0x9c80 +#define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100 +#define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00 +#define INTEL_PCH_KBP_DEVICE_ID_TYPE 0xA280 +#define INTEL_PCH_CNP_DEVICE_ID_TYPE 0xA300 +#define INTEL_PCH_CNP_LP_DEVICE_ID_TYPE 0x9D80 +#define INTEL_PCH_CMP_DEVICE_ID_TYPE 0x0280 +#define INTEL_PCH_CMP2_DEVICE_ID_TYPE 0x0680 +#define INTEL_PCH_CMP_V_DEVICE_ID_TYPE 0xA380 +#define INTEL_PCH_ICP_DEVICE_ID_TYPE 0x3480 +#define INTEL_PCH_ICP2_DEVICE_ID_TYPE 0x3880 +#define INTEL_PCH_MCC_DEVICE_ID_TYPE 0x4B00 +#define INTEL_PCH_TGP_DEVICE_ID_TYPE 0xA080 +#define INTEL_PCH_TGP2_DEVICE_ID_TYPE 0x4380 +#define INTEL_PCH_JSP_DEVICE_ID_TYPE 0x4D80 +#define INTEL_PCH_ADP_DEVICE_ID_TYPE 0x7A80 +#define INTEL_PCH_ADP2_DEVICE_ID_TYPE 0x5180 +#define INTEL_PCH_ADP3_DEVICE_ID_TYPE 0x7A00 +#define INTEL_PCH_ADP4_DEVICE_ID_TYPE 0x5480 +#define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100 +#define INTEL_PCH_P3X_DEVICE_ID_TYPE 0x7000 +#define INTEL_PCH_QEMU_DEVICE_ID_TYPE 0x2900 /* qemu q35 has 2918 */ + +/* + * Check for platforms where the south display is on the same PCI device or SoC + * die as the north display. The PCH (if it even exists) is not involved in + * display. Return a fake PCH type for south display handling on these + * platforms, without actually detecting the PCH, and PCH_NONE otherwise. + */ +static enum intel_pch intel_pch_fake_for_south_display(struct intel_display *display) +{ + enum intel_pch pch_type = PCH_NONE; + + if (DISPLAY_VER(display) >= 20) + pch_type = PCH_LNL; + else if (display->platform.battlemage || display->platform.meteorlake) + pch_type = PCH_MTL; + else if (display->platform.dg2) + pch_type = PCH_DG2; + else if (display->platform.dg1) + pch_type = PCH_DG1; + + return pch_type; +} + +/* Map PCH device id to PCH type, or PCH_NONE if unknown. */ +static enum intel_pch +intel_pch_type(const struct intel_display *display, unsigned short id) +{ + switch (id) { + case INTEL_PCH_IBX_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found Ibex Peak PCH\n"); + drm_WARN_ON(display->drm, DISPLAY_VER(display) != 5); + return PCH_IBX; + case INTEL_PCH_CPT_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found CougarPoint PCH\n"); + drm_WARN_ON(display->drm, + DISPLAY_VER(display) != 6 && + !display->platform.ivybridge); + return PCH_CPT; + case INTEL_PCH_PPT_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found PantherPoint PCH\n"); + drm_WARN_ON(display->drm, + DISPLAY_VER(display) != 6 && + !display->platform.ivybridge); + /* PPT is CPT compatible */ + return PCH_CPT; + case INTEL_PCH_LPT_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found LynxPoint PCH\n"); + drm_WARN_ON(display->drm, + !display->platform.haswell && + !display->platform.broadwell); + drm_WARN_ON(display->drm, + display->platform.haswell_ult || + display->platform.broadwell_ult); + return PCH_LPT_H; + case INTEL_PCH_LPT_LP_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found LynxPoint LP PCH\n"); + drm_WARN_ON(display->drm, + !display->platform.haswell && + !display->platform.broadwell); + drm_WARN_ON(display->drm, + !display->platform.haswell_ult && + !display->platform.broadwell_ult); + return PCH_LPT_LP; + case INTEL_PCH_WPT_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found WildcatPoint PCH\n"); + drm_WARN_ON(display->drm, + !display->platform.haswell && + !display->platform.broadwell); + drm_WARN_ON(display->drm, + display->platform.haswell_ult || + display->platform.broadwell_ult); + /* WPT is LPT compatible */ + return PCH_LPT_H; + case INTEL_PCH_WPT_LP_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found WildcatPoint LP PCH\n"); + drm_WARN_ON(display->drm, + !display->platform.haswell && + !display->platform.broadwell); + drm_WARN_ON(display->drm, + !display->platform.haswell_ult && + !display->platform.broadwell_ult); + /* WPT is LPT compatible */ + return PCH_LPT_LP; + case INTEL_PCH_SPT_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found SunrisePoint PCH\n"); + drm_WARN_ON(display->drm, + !display->platform.skylake && + !display->platform.kabylake && + !display->platform.coffeelake); + return PCH_SPT; + case INTEL_PCH_SPT_LP_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found SunrisePoint LP PCH\n"); + drm_WARN_ON(display->drm, + !display->platform.skylake && + !display->platform.kabylake && + !display->platform.coffeelake && + !display->platform.cometlake); + return PCH_SPT; + case INTEL_PCH_KBP_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found Kaby Lake PCH (KBP)\n"); + drm_WARN_ON(display->drm, + !display->platform.skylake && + !display->platform.kabylake && + !display->platform.coffeelake && + !display->platform.cometlake); + /* KBP is SPT compatible */ + return PCH_SPT; + case INTEL_PCH_CNP_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found Cannon Lake PCH (CNP)\n"); + drm_WARN_ON(display->drm, + !display->platform.coffeelake && + !display->platform.cometlake); + return PCH_CNP; + case INTEL_PCH_CNP_LP_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, + "Found Cannon Lake LP PCH (CNP-LP)\n"); + drm_WARN_ON(display->drm, + !display->platform.coffeelake && + !display->platform.cometlake); + return PCH_CNP; + case INTEL_PCH_CMP_DEVICE_ID_TYPE: + case INTEL_PCH_CMP2_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found Comet Lake PCH (CMP)\n"); + drm_WARN_ON(display->drm, + !display->platform.coffeelake && + !display->platform.cometlake && + !display->platform.rocketlake); + /* CMP is CNP compatible */ + return PCH_CNP; + case INTEL_PCH_CMP_V_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found Comet Lake V PCH (CMP-V)\n"); + drm_WARN_ON(display->drm, + !display->platform.coffeelake && + !display->platform.cometlake); + /* CMP-V is based on KBP, which is SPT compatible */ + return PCH_SPT; + case INTEL_PCH_ICP_DEVICE_ID_TYPE: + case INTEL_PCH_ICP2_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found Ice Lake PCH\n"); + drm_WARN_ON(display->drm, !display->platform.icelake); + return PCH_ICP; + case INTEL_PCH_MCC_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found Mule Creek Canyon PCH\n"); + drm_WARN_ON(display->drm, !(display->platform.jasperlake || + display->platform.elkhartlake)); + /* MCC is TGP compatible */ + return PCH_TGP; + case INTEL_PCH_TGP_DEVICE_ID_TYPE: + case INTEL_PCH_TGP2_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found Tiger Lake LP PCH\n"); + drm_WARN_ON(display->drm, !display->platform.tigerlake && + !display->platform.rocketlake && + !display->platform.skylake && + !display->platform.kabylake && + !display->platform.coffeelake && + !display->platform.cometlake); + return PCH_TGP; + case INTEL_PCH_JSP_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found Jasper Lake PCH\n"); + drm_WARN_ON(display->drm, !(display->platform.jasperlake || + display->platform.elkhartlake)); + /* JSP is ICP compatible */ + return PCH_ICP; + case INTEL_PCH_ADP_DEVICE_ID_TYPE: + case INTEL_PCH_ADP2_DEVICE_ID_TYPE: + case INTEL_PCH_ADP3_DEVICE_ID_TYPE: + case INTEL_PCH_ADP4_DEVICE_ID_TYPE: + drm_dbg_kms(display->drm, "Found Alder Lake PCH\n"); + drm_WARN_ON(display->drm, !display->platform.alderlake_s && + !display->platform.alderlake_p); + return PCH_ADP; + default: + return PCH_NONE; + } +} + +static bool intel_is_virt_pch(unsigned short id, + unsigned short svendor, unsigned short sdevice) +{ + return (id == INTEL_PCH_P2X_DEVICE_ID_TYPE || + id == INTEL_PCH_P3X_DEVICE_ID_TYPE || + (id == INTEL_PCH_QEMU_DEVICE_ID_TYPE && + svendor == PCI_SUBVENDOR_ID_REDHAT_QUMRANET && + sdevice == PCI_SUBDEVICE_ID_QEMU)); +} + +static void +intel_virt_detect_pch(const struct intel_display *display, + unsigned short *pch_id, enum intel_pch *pch_type) +{ + unsigned short id = 0; + + /* + * In a virtualized passthrough environment we can be in a + * setup where the ISA bridge is not able to be passed through. + * In this case, a south bridge can be emulated and we have to + * make an educated guess as to which PCH is really there. + */ + + if (display->platform.alderlake_s || display->platform.alderlake_p) + id = INTEL_PCH_ADP_DEVICE_ID_TYPE; + else if (display->platform.tigerlake || display->platform.rocketlake) + id = INTEL_PCH_TGP_DEVICE_ID_TYPE; + else if (display->platform.jasperlake || display->platform.elkhartlake) + id = INTEL_PCH_MCC_DEVICE_ID_TYPE; + else if (display->platform.icelake) + id = INTEL_PCH_ICP_DEVICE_ID_TYPE; + else if (display->platform.coffeelake || + display->platform.cometlake) + id = INTEL_PCH_CNP_DEVICE_ID_TYPE; + else if (display->platform.kabylake || display->platform.skylake) + id = INTEL_PCH_SPT_DEVICE_ID_TYPE; + else if (display->platform.haswell_ult || + display->platform.broadwell_ult) + id = INTEL_PCH_LPT_LP_DEVICE_ID_TYPE; + else if (display->platform.haswell || display->platform.broadwell) + id = INTEL_PCH_LPT_DEVICE_ID_TYPE; + else if (DISPLAY_VER(display) == 6 || display->platform.ivybridge) + id = INTEL_PCH_CPT_DEVICE_ID_TYPE; + else if (DISPLAY_VER(display) == 5) + id = INTEL_PCH_IBX_DEVICE_ID_TYPE; + + if (id) + drm_dbg_kms(display->drm, "Assuming PCH ID %04x\n", id); + else + drm_dbg_kms(display->drm, "Assuming no PCH\n"); + + *pch_type = intel_pch_type(display, id); + + /* Sanity check virtual PCH id */ + if (drm_WARN_ON(display->drm, + id && *pch_type == PCH_NONE)) + id = 0; + + *pch_id = id; +} + +void intel_pch_detect(struct intel_display *display) +{ + struct pci_dev *pch = NULL; + unsigned short id; + enum intel_pch pch_type; + + pch_type = intel_pch_fake_for_south_display(display); + if (pch_type != PCH_NONE) { + display->pch_type = pch_type; + drm_dbg_kms(display->drm, + "PCH not involved in display, using fake PCH type %d for south display\n", + pch_type); + return; + } + + /* + * The reason to probe ISA bridge instead of Dev31:Fun0 is to + * make graphics device passthrough work easy for VMM, that only + * need to expose ISA bridge to let driver know the real hardware + * underneath. This is a requirement from virtualization team. + * + * In some virtualized environments (e.g. XEN), there is irrelevant + * ISA bridge in the system. To work reliably, we should scan through + * all the ISA bridge devices and check for the first match, instead + * of only checking the first one. + */ + while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) { + if (pch->vendor != PCI_VENDOR_ID_INTEL) + continue; + + id = pch->device & INTEL_PCH_DEVICE_ID_MASK; + + pch_type = intel_pch_type(display, id); + if (pch_type != PCH_NONE) { + display->pch_type = pch_type; + break; + } else if (intel_is_virt_pch(id, pch->subsystem_vendor, + pch->subsystem_device)) { + intel_virt_detect_pch(display, &id, &pch_type); + display->pch_type = pch_type; + break; + } + } + + /* + * Use PCH_NOP (PCH but no South Display) for PCH platforms without + * display. + */ + if (pch && !HAS_DISPLAY(display)) { + drm_dbg_kms(display->drm, + "Display disabled, reverting to NOP PCH\n"); + display->pch_type = PCH_NOP; + } else if (!pch) { + if (i915_run_as_guest() && HAS_DISPLAY(display)) { + intel_virt_detect_pch(display, &id, &pch_type); + display->pch_type = pch_type; + } else { + drm_dbg_kms(display->drm, "No PCH found.\n"); + } + } + + pci_dev_put(pch); +} diff --git a/drivers/gpu/drm/i915/display/intel_pch.h b/drivers/gpu/drm/i915/display/intel_pch.h new file mode 100644 index 000000000000..cf4dab1b98bf --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_pch.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright 2025 Intel Corporation. + */ + +#ifndef __INTEL_PCH__ +#define __INTEL_PCH__ + +#include "intel_display_conversion.h" + +struct intel_display; + +/* + * Sorted by south display engine compatibility. + * If the new PCH comes with a south display engine that is not + * inherited from the latest item, please do not add it to the + * end. Instead, add it right after its "parent" PCH. + */ +enum intel_pch { + PCH_NOP = -1, /* PCH without south display */ + PCH_NONE = 0, /* No PCH present */ + PCH_IBX, /* Ibexpeak PCH */ + PCH_CPT, /* Cougarpoint/Pantherpoint PCH */ + PCH_LPT_H, /* Lynxpoint/Wildcatpoint H PCH */ + PCH_LPT_LP, /* Lynxpoint/Wildcatpoint LP PCH */ + PCH_SPT, /* Sunrisepoint/Kaby Lake PCH */ + PCH_CNP, /* Cannon/Comet Lake PCH */ + PCH_ICP, /* Ice Lake/Jasper Lake PCH */ + PCH_TGP, /* Tiger Lake/Mule Creek Canyon PCH */ + PCH_ADP, /* Alder Lake PCH */ + + /* Fake PCHs, functionality handled on the same PCI dev */ + PCH_DG1 = 1024, + PCH_DG2, + PCH_MTL, + PCH_LNL, +}; + +#define INTEL_PCH_TYPE(_display) (__to_intel_display(_display)->pch_type) +#define HAS_PCH_DG2(display) (INTEL_PCH_TYPE(display) == PCH_DG2) +#define HAS_PCH_ADP(display) (INTEL_PCH_TYPE(display) == PCH_ADP) +#define HAS_PCH_DG1(display) (INTEL_PCH_TYPE(display) == PCH_DG1) +#define HAS_PCH_TGP(display) (INTEL_PCH_TYPE(display) == PCH_TGP) +#define HAS_PCH_ICP(display) (INTEL_PCH_TYPE(display) == PCH_ICP) +#define HAS_PCH_CNP(display) (INTEL_PCH_TYPE(display) == PCH_CNP) +#define HAS_PCH_SPT(display) (INTEL_PCH_TYPE(display) == PCH_SPT) +#define HAS_PCH_LPT_H(display) (INTEL_PCH_TYPE(display) == PCH_LPT_H) +#define HAS_PCH_LPT_LP(display) (INTEL_PCH_TYPE(display) == PCH_LPT_LP) +#define HAS_PCH_LPT(display) (INTEL_PCH_TYPE(display) == PCH_LPT_H || \ + INTEL_PCH_TYPE(display) == PCH_LPT_LP) +#define HAS_PCH_CPT(display) (INTEL_PCH_TYPE(display) == PCH_CPT) +#define HAS_PCH_IBX(display) (INTEL_PCH_TYPE(display) == PCH_IBX) +#define HAS_PCH_NOP(display) (INTEL_PCH_TYPE(display) == PCH_NOP) +#define HAS_PCH_SPLIT(display) (INTEL_PCH_TYPE(display) != PCH_NONE) + +void intel_pch_detect(struct intel_display *display); + +#endif /* __INTEL_PCH__ */ diff --git a/drivers/gpu/drm/i915/display/intel_pch_display.c b/drivers/gpu/drm/i915/display/intel_pch_display.c index b909ed18a5b2..1743ebf551cb 100644 --- a/drivers/gpu/drm/i915/display/intel_pch_display.c +++ b/drivers/gpu/drm/i915/display/intel_pch_display.c @@ -3,8 +3,9 @@ * Copyright © 2021 Intel Corporation */ +#include <drm/drm_print.h> + #include "g4x_dp.h" -#include "i915_drv.h" #include "i915_reg.h" #include "intel_crt.h" #include "intel_crt_regs.h" @@ -23,17 +24,15 @@ bool intel_has_pch_trancoder(struct intel_display *display, enum pipe pch_transcoder) { - struct drm_i915_private *i915 = to_i915(display->drm); - - return HAS_PCH_IBX(i915) || HAS_PCH_CPT(i915) || - (HAS_PCH_LPT_H(i915) && pch_transcoder == PIPE_A); + return HAS_PCH_IBX(display) || HAS_PCH_CPT(display) || + (HAS_PCH_LPT_H(display) && pch_transcoder == PIPE_A); } enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); - if (HAS_PCH_LPT(i915)) + if (HAS_PCH_LPT(display)) return PIPE_A; else return crtc->pipe; @@ -43,7 +42,6 @@ static void assert_pch_dp_disabled(struct intel_display *display, enum pipe pipe, enum port port, i915_reg_t dp_reg) { - struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe port_pipe; bool state; @@ -54,7 +52,7 @@ static void assert_pch_dp_disabled(struct intel_display *display, port_name(port), pipe_name(pipe)); INTEL_DISPLAY_STATE_WARN(display, - HAS_PCH_IBX(dev_priv) && !state && port_pipe == PIPE_B, + HAS_PCH_IBX(display) && !state && port_pipe == PIPE_B, "IBX PCH DP %c still using transcoder B\n", port_name(port)); } @@ -63,7 +61,6 @@ static void assert_pch_hdmi_disabled(struct intel_display *display, enum pipe pipe, enum port port, i915_reg_t hdmi_reg) { - struct drm_i915_private *dev_priv = to_i915(display->drm); enum pipe port_pipe; bool state; @@ -74,7 +71,7 @@ static void assert_pch_hdmi_disabled(struct intel_display *display, port_name(port), pipe_name(pipe)); INTEL_DISPLAY_STATE_WARN(display, - HAS_PCH_IBX(dev_priv) && !state && port_pipe == PIPE_B, + HAS_PCH_IBX(display) && !state && port_pipe == PIPE_B, "IBX PCH HDMI %c still using transcoder B\n", port_name(port)); } @@ -249,7 +246,6 @@ static void ilk_enable_pch_transcoder(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 *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; i915_reg_t reg; u32 val, pipeconf_val; @@ -261,7 +257,7 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state) assert_fdi_tx_enabled(display, pipe); assert_fdi_rx_enabled(display, pipe); - if (HAS_PCH_CPT(dev_priv)) { + if (HAS_PCH_CPT(display)) { reg = TRANS_CHICKEN2(pipe); val = intel_de_read(display, reg); /* @@ -279,7 +275,7 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state) val = intel_de_read(display, reg); pipeconf_val = intel_de_read(display, TRANSCONF(display, pipe)); - if (HAS_PCH_IBX(dev_priv)) { + if (HAS_PCH_IBX(display)) { /* Configure frame start delay to match the CPU */ val &= ~TRANS_FRAME_START_DELAY_MASK; val |= TRANS_FRAME_START_DELAY(crtc_state->framestart_delay - 1); @@ -298,7 +294,7 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state) val &= ~TRANS_INTERLACE_MASK; if ((pipeconf_val & TRANSCONF_INTERLACE_MASK_ILK) == TRANSCONF_INTERLACE_IF_ID_ILK) { - if (HAS_PCH_IBX(dev_priv) && + if (HAS_PCH_IBX(display) && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO)) val |= TRANS_INTERLACE_LEGACY_VSYNC_IBX; else @@ -316,7 +312,6 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state) static void ilk_disable_pch_transcoder(struct 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; i915_reg_t reg; @@ -334,7 +329,7 @@ static void ilk_disable_pch_transcoder(struct intel_crtc *crtc) drm_err(display->drm, "failed to disable transcoder %c\n", pipe_name(pipe)); - if (HAS_PCH_CPT(dev_priv)) + if (HAS_PCH_CPT(display)) /* Workaround: Clear the timing override chicken bit again. */ intel_de_rmw(display, TRANS_CHICKEN2(pipe), TRANS_CHICKEN2_TIMING_OVERRIDE, 0); @@ -366,7 +361,6 @@ void ilk_pch_enable(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); enum pipe pipe = crtc->pipe; @@ -381,7 +375,7 @@ void ilk_pch_enable(struct intel_atomic_state *state, * We need to program the right clock selection * before writing the pixel multiplier into the DPLL. */ - if (HAS_PCH_CPT(dev_priv)) { + if (HAS_PCH_CPT(display)) { u32 sel; temp = intel_de_read(display, PCH_DPLL_SEL); @@ -417,7 +411,7 @@ void ilk_pch_enable(struct intel_atomic_state *state, intel_fdi_normal_train(crtc); /* For PCH DP, enable TRANS_DP_CTL */ - if (HAS_PCH_CPT(dev_priv) && + if (HAS_PCH_CPT(display) && intel_crtc_has_dp_encoder(crtc_state)) { const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; @@ -459,14 +453,13 @@ void ilk_pch_post_disable(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); enum pipe pipe = crtc->pipe; ilk_disable_pch_transcoder(crtc); - if (HAS_PCH_CPT(dev_priv)) { + if (HAS_PCH_CPT(display)) { /* disable TRANS_DP_CTL */ intel_de_rmw(display, TRANS_DP_CTL(pipe), TRANS_DP_OUTPUT_ENABLE | TRANS_DP_PORT_SEL_MASK, @@ -503,7 +496,6 @@ void ilk_pch_get_config(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 *dev_priv = to_i915(crtc->base.dev); struct intel_shared_dpll *pll; enum pipe pipe = crtc->pipe; enum intel_dpll_id pll_id; @@ -522,7 +514,7 @@ void ilk_pch_get_config(struct intel_crtc_state *crtc_state) intel_cpu_transcoder_get_m1_n1(crtc, crtc_state->cpu_transcoder, &crtc_state->fdi_m_n); - if (HAS_PCH_IBX(dev_priv)) { + if (HAS_PCH_IBX(display)) { /* * The pipe->pch transcoder and pch transcoder->pll * mapping is fixed. @@ -646,8 +638,6 @@ void lpt_pch_get_config(struct intel_crtc_state *crtc_state) void intel_pch_sanitize(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - - if (HAS_PCH_IBX(i915)) + if (HAS_PCH_IBX(display)) ibx_sanitize_pch_ports(display); } diff --git a/drivers/gpu/drm/i915/display/intel_pch_refclk.c b/drivers/gpu/drm/i915/display/intel_pch_refclk.c index 1307a478861a..693b90e3dfc3 100644 --- a/drivers/gpu/drm/i915/display/intel_pch_refclk.c +++ b/drivers/gpu/drm/i915/display/intel_pch_refclk.c @@ -281,7 +281,7 @@ static void lpt_enable_clkout_dp(struct intel_display *display, if (drm_WARN(display->drm, with_fdi && !with_spread, "FDI requires downspread\n")) with_spread = true; - if (drm_WARN(display->drm, HAS_PCH_LPT_LP(dev_priv) && + if (drm_WARN(display->drm, HAS_PCH_LPT_LP(display) && with_fdi, "LP PCH doesn't have FDI\n")) with_fdi = false; @@ -303,7 +303,7 @@ static void lpt_enable_clkout_dp(struct intel_display *display, lpt_fdi_program_mphy(display); } - reg = HAS_PCH_LPT_LP(dev_priv) ? SBI_GEN0 : SBI_DBUFF0; + reg = HAS_PCH_LPT_LP(display) ? SBI_GEN0 : SBI_DBUFF0; tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK); tmp |= SBI_GEN0_CFG_BUFFENABLE_DISABLE; intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK); @@ -319,7 +319,7 @@ void lpt_disable_clkout_dp(struct intel_display *display) intel_sbi_lock(dev_priv); - reg = HAS_PCH_LPT_LP(dev_priv) ? SBI_GEN0 : SBI_DBUFF0; + reg = HAS_PCH_LPT_LP(display) ? SBI_GEN0 : SBI_DBUFF0; tmp = intel_sbi_read(dev_priv, reg, SBI_ICLK); tmp &= ~SBI_GEN0_CFG_BUFFENABLE_DISABLE; intel_sbi_write(dev_priv, reg, tmp, SBI_ICLK); @@ -498,7 +498,6 @@ static void lpt_init_pch_refclk(struct intel_display *display) static void ilk_init_pch_refclk(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_encoder *encoder; struct intel_shared_dpll *pll; int i; @@ -527,7 +526,7 @@ static void ilk_init_pch_refclk(struct intel_display *display) } } - if (HAS_PCH_IBX(dev_priv)) { + if (HAS_PCH_IBX(display)) { has_ck505 = display->vbt.display_clock_mode; can_ssc = has_ck505; } else { @@ -678,10 +677,8 @@ static void ilk_init_pch_refclk(struct intel_display *display) */ void intel_init_pch_refclk(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - - if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)) + if (HAS_PCH_IBX(display) || HAS_PCH_CPT(display)) ilk_init_pch_refclk(display); - else if (HAS_PCH_LPT(dev_priv)) + else if (HAS_PCH_LPT(display)) lpt_init_pch_refclk(display); } diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c b/drivers/gpu/drm/i915/display/intel_plane_initial.c index b0c4892775ce..c00d9184c586 100644 --- a/drivers/gpu/drm/i915/display/intel_plane_initial.c +++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c @@ -53,9 +53,11 @@ intel_reuse_initial_plane_obj(struct intel_crtc *this, } static enum intel_memory_type -initial_plane_memory_type(struct drm_i915_private *i915) +initial_plane_memory_type(struct intel_display *display) { - if (IS_DGFX(i915)) + struct drm_i915_private *i915 = to_i915(display->drm); + + if (display->platform.dgfx) return INTEL_MEMORY_LOCAL; else if (HAS_LMEMBAR_SMEM_STOLEN(i915)) return INTEL_MEMORY_STOLEN_LOCAL; @@ -75,7 +77,7 @@ initial_plane_phys(struct intel_display *display, dma_addr_t dma_addr; u32 base; - mem_type = initial_plane_memory_type(i915); + mem_type = initial_plane_memory_type(display); mem = intel_memory_region_by_type(i915, mem_type); if (!mem) { drm_dbg_kms(display->drm, diff --git a/drivers/gpu/drm/i915/display/intel_pmdemand.c b/drivers/gpu/drm/i915/display/intel_pmdemand.c index d22b5469672d..1253376c7654 100644 --- a/drivers/gpu/drm/i915/display/intel_pmdemand.c +++ b/drivers/gpu/drm/i915/display/intel_pmdemand.c @@ -478,13 +478,34 @@ static bool intel_pmdemand_req_complete(struct intel_display *display) XELPDP_PMDEMAND_REQ_ENABLE); } -static void intel_pmdemand_wait(struct intel_display *display) +static void intel_pmdemand_poll(struct intel_display *display) { - if (!wait_event_timeout(display->pmdemand.waitqueue, - intel_pmdemand_req_complete(display), - msecs_to_jiffies_timeout(10))) + const unsigned int timeout_ms = 10; + u32 status; + int ret; + + ret = intel_de_wait_custom(display, XELPDP_INITIATE_PMDEMAND_REQUEST(1), + XELPDP_PMDEMAND_REQ_ENABLE, 0, + 50, timeout_ms, &status); + + if (ret == -ETIMEDOUT) drm_err(display->drm, - "timed out waiting for Punit PM Demand Response\n"); + "timed out waiting for Punit PM Demand Response within %ums (status 0x%08x)\n", + timeout_ms, status); +} + +static void intel_pmdemand_wait(struct intel_display *display) +{ + /* Wa_14024400148 For lnl use polling method */ + if (DISPLAY_VER(display) == 20) { + intel_pmdemand_poll(display); + } else { + if (!wait_event_timeout(display->pmdemand.waitqueue, + intel_pmdemand_req_complete(display), + msecs_to_jiffies_timeout(10))) + drm_err(display->drm, + "timed out waiting for Punit PM Demand Response\n"); + } } /* Required to be programmed during Display Init Sequences. */ diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index 4d4e2b9f5f2d..05e1e5c7e8b7 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -350,21 +350,19 @@ vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp) static int intel_num_pps(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (display->platform.valleyview || display->platform.cherryview) return 2; if (display->platform.geminilake || display->platform.broxton) return 2; - 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; @@ -373,11 +371,10 @@ static int intel_num_pps(struct intel_display *display) static bool intel_pps_is_valid(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *i915 = to_i915(display->drm); if (intel_dp->pps.pps_idx == 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; @@ -499,7 +496,6 @@ static void intel_pps_get_registers(struct intel_dp *intel_dp, struct pps_registers *regs) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); int pps_idx; memset(regs, 0, sizeof(*regs)); @@ -518,7 +514,7 @@ static void intel_pps_get_registers(struct intel_dp *intel_dp, /* Cycle delay moved from PP_DIVISOR to PP_CONTROL */ if (display->platform.geminilake || display->platform.broxton || - INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) + INTEL_PCH_TYPE(display) >= PCH_CNP) regs->pp_div = INVALID_MMIO_REG; else regs->pp_div = PP_DIVISOR(display, pps_idx); @@ -1591,7 +1587,6 @@ static void pps_init_delays(struct intel_dp *intel_dp) static void pps_init_registers(struct intel_dp *intel_dp, bool force_disable_vdd) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 pp_on, pp_off, port_sel = 0; int div = DISPLAY_RUNTIME_INFO(display)->rawclk_freq / 1000; struct pps_registers regs; @@ -1638,7 +1633,7 @@ static void pps_init_registers(struct intel_dp *intel_dp, bool force_disable_vdd * power sequencer any more. */ if (display->platform.valleyview || display->platform.cherryview) { port_sel = PANEL_PORT_SELECT_VLV(port); - } else if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)) { + } else if (HAS_PCH_IBX(display) || HAS_PCH_CPT(display)) { switch (port) { case PORT_A: port_sel = PANEL_PORT_SELECT_DPA; @@ -1791,9 +1786,7 @@ void intel_pps_unlock_regs_wa(struct intel_display *display) void intel_pps_setup(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - - if (HAS_PCH_SPLIT(i915) || display->platform.geminilake || display->platform.broxton) + if (HAS_PCH_SPLIT(display) || display->platform.geminilake || display->platform.broxton) display->pps.mmio_base = PCH_PPS_BASE; else if (display->platform.valleyview || display->platform.cherryview) display->pps.mmio_base = VLV_PPS_BASE; @@ -1836,7 +1829,6 @@ void intel_pps_connector_debugfs_add(struct intel_connector *connector) void assert_pps_unlocked(struct intel_display *display, enum pipe pipe) { - struct drm_i915_private *dev_priv = to_i915(display->drm); i915_reg_t pp_reg; u32 val; enum pipe panel_pipe = INVALID_PIPE; @@ -1845,7 +1837,7 @@ void assert_pps_unlocked(struct intel_display *display, enum pipe pipe) if (drm_WARN_ON(display->drm, HAS_DDI(display))) return; - if (HAS_PCH_SPLIT(dev_priv)) { + if (HAS_PCH_SPLIT(display)) { u32 port_sel; pp_reg = PP_CONTROL(display, 0); diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index eef48c014112..ccd66bbc72f7 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -26,6 +26,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_damage_helper.h> #include <drm/drm_debugfs.h> +#include <drm/drm_vblank.h> #include "i915_drv.h" #include "i915_reg.h" @@ -38,6 +39,7 @@ #include "intel_display_irq.h" #include "intel_display_rpm.h" #include "intel_display_types.h" +#include "intel_dmc.h" #include "intel_dp.h" #include "intel_dp_aux.h" #include "intel_frontbuffer.h" @@ -46,6 +48,7 @@ #include "intel_psr_regs.h" #include "intel_snps_phy.h" #include "intel_vblank.h" +#include "intel_vrr.h" #include "skl_universal_plane.h" /** @@ -794,32 +797,9 @@ static void _psr_enable_sink(struct intel_dp *intel_dp, drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, val); } -static void intel_psr_enable_sink_alpm(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state) -{ - u8 val; - - /* - * eDP Panel Replay uses always ALPM - * PSR2 uses ALPM but PSR1 doesn't - */ - if (!intel_dp_is_edp(intel_dp) || (!crtc_state->has_panel_replay && - !crtc_state->has_sel_update)) - return; - - val = DP_ALPM_ENABLE | DP_ALPM_LOCK_ERROR_IRQ_HPD_ENABLE; - - if (crtc_state->has_panel_replay) - val |= DP_ALPM_MODE_AUX_LESS; - - drm_dp_dpcd_writeb(&intel_dp->aux, DP_RECEIVER_ALPM_CONFIG, val); -} - static void intel_psr_enable_sink(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { - intel_psr_enable_sink_alpm(intel_dp, crtc_state); - crtc_state->has_panel_replay ? _panel_replay_enable_sink(intel_dp, crtc_state) : _psr_enable_sink(intel_dp, crtc_state); @@ -905,6 +885,18 @@ static u8 psr_compute_idle_frames(struct intel_dp *intel_dp) return idle_frames; } +static bool is_dc5_dc6_blocked(struct intel_dp *intel_dp) +{ + struct intel_display *display = to_intel_display(intel_dp); + u32 current_dc_state = intel_display_power_get_current_dc_state(display); + struct drm_vblank_crtc *vblank = &display->drm->vblank[intel_dp->psr.pipe]; + + return (current_dc_state != DC_STATE_EN_UPTO_DC5 && + current_dc_state != DC_STATE_EN_UPTO_DC6) || + intel_dp->psr.active_non_psr_pipes || + READ_ONCE(vblank->enabled); +} + static void hsw_activate_psr1(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); @@ -933,6 +925,14 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp) intel_de_rmw(display, psr_ctl_reg(display, cpu_transcoder), ~EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK, val); + + /* Wa_16025596647 */ + if ((DISPLAY_VER(display) == 20 || + IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) && + is_dc5_dc6_blocked(intel_dp)) + intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank(display, + intel_dp->psr.pipe, + true); } static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp) @@ -1014,8 +1014,16 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) enum transcoder cpu_transcoder = intel_dp->psr.transcoder; u32 val = EDP_PSR2_ENABLE; u32 psr_val = 0; + u8 idle_frames; - val |= EDP_PSR2_IDLE_FRAMES(psr_compute_idle_frames(intel_dp)); + /* Wa_16025596647 */ + if ((DISPLAY_VER(display) == 20 || + IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) && + is_dc5_dc6_blocked(intel_dp)) + idle_frames = 0; + else + idle_frames = psr_compute_idle_frames(intel_dp); + val |= EDP_PSR2_IDLE_FRAMES(idle_frames); if (DISPLAY_VER(display) < 14 && !display->platform.alderlake_p) val |= EDP_SU_TRACK_ENABLE; @@ -1649,6 +1657,9 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, { struct intel_display *display = to_intel_display(intel_dp); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; + struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state); + struct intel_crtc *crtc; + u8 active_pipes = 0; if (!psr_global_enabled(intel_dp)) { drm_dbg_kms(display->drm, "PSR disabled by flag\n"); @@ -1702,6 +1713,24 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, drm_dbg_kms(display->drm, "PSR disabled to workaround PSR FSM hang issue\n"); } + + /* Rest is for Wa_16025596647 */ + if (DISPLAY_VER(display) != 20 && + !IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) + return; + + /* Not needed by Panel Replay */ + if (crtc_state->has_panel_replay) + return; + + /* We ignore possible secondary PSR/Panel Replay capable eDP */ + for_each_intel_crtc(display->drm, crtc) + active_pipes |= crtc->active ? BIT(crtc->pipe) : 0; + + active_pipes = intel_calc_active_pipes(state, active_pipes); + + crtc_state->active_non_psr_pipes = active_pipes & + ~BIT(to_intel_crtc(crtc_state->uapi.crtc)->pipe); } void intel_psr_get_config(struct intel_encoder *encoder, @@ -1893,9 +1922,6 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, intel_dp->psr.psr2_sel_fetch_enabled ? IGNORE_PSR2_HW_TRACKING : 0); - if (intel_dp_is_edp(intel_dp)) - intel_alpm_configure(intel_dp, crtc_state); - /* * Wa_16013835468 * Wa_14015648006 @@ -1930,6 +1956,12 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, intel_de_rmw(display, CLKGATE_DIS_MISC, 0, CLKGATE_DIS_MISC_DMASC_GATING_DIS); } + + /* Wa_16025596647 */ + if ((DISPLAY_VER(display) == 20 || + IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) && + !intel_dp->psr.panel_replay_enabled) + intel_dmc_block_pkgc(display, intel_dp->psr.pipe, true); } static bool psr_interrupt_error_check(struct intel_dp *intel_dp) @@ -1985,6 +2017,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp, intel_dp->psr.psr2_sel_fetch_cff_enabled = false; intel_dp->psr.req_psr2_sdp_prior_scanline = crtc_state->req_psr2_sdp_prior_scanline; + intel_dp->psr.active_non_psr_pipes = crtc_state->active_non_psr_pipes; if (!psr_interrupt_error_check(intel_dp)) return; @@ -2060,6 +2093,12 @@ static void intel_psr_exit(struct intel_dp *intel_dp) drm_WARN_ON(display->drm, !(val & EDP_PSR2_ENABLE)); } else { + if (DISPLAY_VER(display) == 20 || + IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) + intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank(display, + intel_dp->psr.pipe, + false); + val = intel_de_rmw(display, psr_ctl_reg(display, cpu_transcoder), EDP_PSR_ENABLE, 0); @@ -2133,17 +2172,6 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) if (intel_dp_is_edp(intel_dp)) intel_snps_phy_update_psr_power_state(&dp_to_dig_port(intel_dp)->base, false); - /* Panel Replay on eDP is always using ALPM aux less. */ - if (intel_dp->psr.panel_replay_enabled && intel_dp_is_edp(intel_dp)) { - intel_de_rmw(display, ALPM_CTL(display, cpu_transcoder), - ALPM_CTL_ALPM_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); - } - /* Disable PSR on Sink */ if (!intel_dp->psr.panel_replay_enabled) { drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0); @@ -2153,12 +2181,19 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) DP_RECEIVER_ALPM_CONFIG, 0); } + /* Wa_16025596647 */ + if ((DISPLAY_VER(display) == 20 || + IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) && + !intel_dp->psr.panel_replay_enabled) + intel_dmc_block_pkgc(display, intel_dp->psr.pipe, false); + intel_dp->psr.enabled = false; intel_dp->psr.panel_replay_enabled = false; intel_dp->psr.sel_update_enabled = false; intel_dp->psr.psr2_sel_fetch_enabled = false; intel_dp->psr.su_region_et_enabled = false; intel_dp->psr.psr2_sel_fetch_cff_enabled = false; + intel_dp->psr.active_non_psr_pipes = 0; } /** @@ -2254,17 +2289,20 @@ out: } /** - * intel_psr_needs_block_dc_vblank - Check if block dc entry is needed + * intel_psr_needs_vblank_notification - Check if PSR need vblank enable/disable + * notification. * @crtc_state: CRTC status * * We need to block DC6 entry in case of Panel Replay as enabling VBI doesn't * prevent it in case of Panel Replay. Panel Replay switches main link off on * DC entry. This means vblank interrupts are not fired and is a problem if - * user-space is polling for vblank events. + * user-space is polling for vblank events. Also Wa_16025596647 needs + * information when vblank is enabled/disabled. */ -bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state) +bool intel_psr_needs_vblank_notification(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + struct intel_display *display = to_intel_display(crtc_state); struct intel_encoder *encoder; for_each_encoder_on_crtc(crtc->base.dev, &crtc->base, encoder) { @@ -2275,8 +2313,15 @@ bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state) intel_dp = enc_to_intel_dp(encoder); - if (intel_dp_is_edp(intel_dp) && - CAN_PANEL_REPLAY(intel_dp)) + if (!intel_dp_is_edp(intel_dp)) + continue; + + if (CAN_PANEL_REPLAY(intel_dp)) + return true; + + if ((DISPLAY_VER(display) == 20 || + IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) && + CAN_PSR(intel_dp)) return true; } @@ -2304,6 +2349,53 @@ void intel_psr_trigger_frame_change_event(struct intel_dsb *dsb, CURSURFLIVE(display, crtc->pipe), 0); } +/** + * intel_psr_min_vblank_delay - Minimum vblank delay needed by PSR + * @crtc_state: the crtc state + * + * Return minimum vblank delay needed by PSR. + */ +int intel_psr_min_vblank_delay(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + + if (!crtc_state->has_psr) + return 0; + + /* Wa_14015401596 */ + if (intel_vrr_possible(crtc_state) && IS_DISPLAY_VER(display, 13, 14)) + return 1; + + /* Rest is for SRD_STATUS needed on LunarLake and onwards */ + if (DISPLAY_VER(display) < 20) + return 0; + + /* + * Comment on SRD_STATUS register in Bspec for LunarLake and onwards: + * + * To deterministically capture the transition of the state machine + * going from SRDOFFACK to IDLE, the delayed V. Blank should be at least + * one line after the non-delayed V. Blank. + * + * Legacy TG: TRANS_SET_CONTEXT_LATENCY > 0 + * VRR TG: TRANS_VRR_CTL[ VRR Guardband ] < (TRANS_VRR_VMAX[ VRR Vmax ] + * - TRANS_VTOTAL[ Vertical Active ]) + * + * SRD_STATUS is used only by PSR1 on PantherLake. + * SRD_STATUS is used by PSR1 and Panel Replay DP on LunarLake. + */ + + if (DISPLAY_VER(display) >= 30 && (crtc_state->has_panel_replay || + crtc_state->has_sel_update)) + return 0; + else if (DISPLAY_VER(display) < 30 && (crtc_state->has_sel_update || + intel_crtc_has_type(crtc_state, + INTEL_OUTPUT_EDP))) + return 0; + else + return 1; +} + static u32 man_trk_ctl_enable_bit_get(struct intel_display *display) { return display->platform.alderlake_p || DISPLAY_VER(display) >= 14 ? 0 : @@ -3398,29 +3490,15 @@ static int psr_get_status_and_error_status(struct intel_dp *intel_dp, static void psr_alpm_check(struct intel_dp *intel_dp) { - struct intel_display *display = to_intel_display(intel_dp); - struct drm_dp_aux *aux = &intel_dp->aux; struct intel_psr *psr = &intel_dp->psr; - u8 val; - int r; if (!psr->sel_update_enabled) return; - r = drm_dp_dpcd_readb(aux, DP_RECEIVER_ALPM_STATUS, &val); - if (r != 1) { - drm_err(display->drm, "Error reading ALPM status\n"); - return; - } - - if (val & DP_ALPM_LOCK_TIMEOUT_ERROR) { + if (intel_alpm_get_error(intel_dp)) { intel_psr_disable_locked(intel_dp); psr->sink_not_reliable = true; - drm_dbg_kms(display->drm, - "ALPM lock timeout error, disabling PSR\n"); - - /* Clearing error */ - drm_dp_dpcd_writeb(aux, DP_RECEIVER_ALPM_STATUS, val); + intel_alpm_disable(intel_dp); } } @@ -3605,6 +3683,168 @@ void intel_psr_unlock(const struct intel_crtc_state *crtc_state) } } +/* Wa_16025596647 */ +static void intel_psr_apply_underrun_on_idle_wa_locked(struct intel_dp *intel_dp) +{ + struct intel_display *display = to_intel_display(intel_dp); + bool dc5_dc6_blocked; + + if (!intel_dp->psr.active) + return; + + dc5_dc6_blocked = is_dc5_dc6_blocked(intel_dp); + + if (intel_dp->psr.sel_update_enabled) + psr2_program_idle_frames(intel_dp, dc5_dc6_blocked ? 0 : + psr_compute_idle_frames(intel_dp)); + else + intel_dmc_start_pkgc_exit_at_start_of_undelayed_vblank(display, + intel_dp->psr.pipe, + dc5_dc6_blocked); +} + +static void psr_dc5_dc6_wa_work(struct work_struct *work) +{ + struct intel_display *display = container_of(work, typeof(*display), + psr_dc5_dc6_wa_work); + struct intel_encoder *encoder; + + for_each_intel_encoder_with_psr(display->drm, encoder) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + + mutex_lock(&intel_dp->psr.lock); + + if (intel_dp->psr.enabled && !intel_dp->psr.panel_replay_enabled) + intel_psr_apply_underrun_on_idle_wa_locked(intel_dp); + + mutex_unlock(&intel_dp->psr.lock); + } +} + +/** + * intel_psr_notify_dc5_dc6 - Notify PSR about enable/disable dc5/dc6 + * @display: intel atomic state + * + * This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to schedule + * psr_dc5_dc6_wa_work used for applying/removing the workaround. + */ +void intel_psr_notify_dc5_dc6(struct intel_display *display) +{ + if (DISPLAY_VER(display) != 20 && + !IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) + return; + + schedule_work(&display->psr_dc5_dc6_wa_work); +} + +/** + * intel_psr_dc5_dc6_wa_init - Init work for underrun on idle PSR HW bug wa + * @display: intel atomic state + * + * This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to init + * psr_dc5_dc6_wa_work used for applying the workaround. + */ +void intel_psr_dc5_dc6_wa_init(struct intel_display *display) +{ + if (DISPLAY_VER(display) != 20 && + !IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) + return; + + INIT_WORK(&display->psr_dc5_dc6_wa_work, psr_dc5_dc6_wa_work); +} + +/** + * intel_psr_notify_pipe_change - Notify PSR about enable/disable of a pipe + * @state: intel atomic state + * @crtc: intel crtc + * @enable: enable/disable + * + * This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to apply + * remove the workaround when pipe is getting enabled/disabled + */ +void intel_psr_notify_pipe_change(struct intel_atomic_state *state, + struct intel_crtc *crtc, bool enable) +{ + struct intel_display *display = to_intel_display(state); + struct intel_encoder *encoder; + + if (DISPLAY_VER(display) != 20 && + !IS_DISPLAY_VERx100_STEP(display, 3000, STEP_A0, STEP_B0)) + return; + + for_each_intel_encoder_with_psr(display->drm, encoder) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + u8 active_non_psr_pipes; + + mutex_lock(&intel_dp->psr.lock); + + if (!intel_dp->psr.enabled || intel_dp->psr.panel_replay_enabled) + goto unlock; + + active_non_psr_pipes = intel_dp->psr.active_non_psr_pipes; + + if (enable) + active_non_psr_pipes |= BIT(crtc->pipe); + else + active_non_psr_pipes &= ~BIT(crtc->pipe); + + if (active_non_psr_pipes == intel_dp->psr.active_non_psr_pipes) + goto unlock; + + if ((enable && intel_dp->psr.active_non_psr_pipes) || + (!enable && !intel_dp->psr.active_non_psr_pipes)) { + intel_dp->psr.active_non_psr_pipes = active_non_psr_pipes; + goto unlock; + } + + intel_dp->psr.active_non_psr_pipes = active_non_psr_pipes; + + intel_psr_apply_underrun_on_idle_wa_locked(intel_dp); +unlock: + mutex_unlock(&intel_dp->psr.lock); + } +} + +/** + * intel_psr_notify_vblank_enable_disable - Notify PSR about enable/disable of vblank + * @display: intel display struct + * @enable: enable/disable + * + * This is targeted for underrun on idle PSR HW bug (Wa_16025596647) to apply + * remove the workaround when vblank is getting enabled/disabled + */ +void intel_psr_notify_vblank_enable_disable(struct intel_display *display, + bool enable) +{ + struct intel_encoder *encoder; + + for_each_intel_encoder_with_psr(display->drm, encoder) { + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + + mutex_lock(&intel_dp->psr.lock); + if (intel_dp->psr.panel_replay_enabled) { + mutex_unlock(&intel_dp->psr.lock); + break; + } + + if (intel_dp->psr.enabled) + intel_psr_apply_underrun_on_idle_wa_locked(intel_dp); + + mutex_unlock(&intel_dp->psr.lock); + return; + } + + /* + * 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, enable ? DC_STATE_DISABLE : + DC_STATE_EN_UPTO_DC6); +} + static void psr_source_status(struct intel_dp *intel_dp, struct seq_file *m) { @@ -3977,3 +4217,13 @@ void intel_psr_connector_debugfs_add(struct intel_connector *connector) debugfs_create_file("i915_psr_status", 0444, root, connector, &i915_psr_status_fops); } + +bool intel_psr_needs_alpm(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) +{ + /* + * eDP Panel Replay uses always ALPM + * PSR2 uses ALPM but PSR1 doesn't + */ + return intel_dp_is_edp(intel_dp) && (crtc_state->has_sel_update || + crtc_state->has_panel_replay); +} diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h index a43a374cff55..73c3fa40844b 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.h +++ b/drivers/gpu/drm/i915/display/intel_psr.h @@ -59,7 +59,13 @@ void intel_psr2_program_trans_man_trk_ctl(struct intel_dsb *dsb, const struct intel_crtc_state *crtc_state); void intel_psr_pause(struct intel_dp *intel_dp); void intel_psr_resume(struct intel_dp *intel_dp); -bool intel_psr_needs_block_dc_vblank(const struct intel_crtc_state *crtc_state); +bool intel_psr_needs_vblank_notification(const struct intel_crtc_state *crtc_state); +void intel_psr_notify_pipe_change(struct intel_atomic_state *state, + struct intel_crtc *crtc, bool enable); +void intel_psr_notify_dc5_dc6(struct intel_display *display); +void intel_psr_dc5_dc6_wa_init(struct intel_display *display); +void intel_psr_notify_vblank_enable_disable(struct intel_display *display, + bool enable); bool intel_psr_link_ok(struct intel_dp *intel_dp); void intel_psr_lock(const struct intel_crtc_state *crtc_state); @@ -67,7 +73,9 @@ void intel_psr_unlock(const struct intel_crtc_state *crtc_state); void intel_psr_trigger_frame_change_event(struct intel_dsb *dsb, struct intel_atomic_state *state, struct intel_crtc *crtc); +int intel_psr_min_vblank_delay(const struct intel_crtc_state *crtc_state); void intel_psr_connector_debugfs_add(struct intel_connector *connector); void intel_psr_debugfs_register(struct intel_display *display); +bool intel_psr_needs_alpm(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state); #endif /* __INTEL_PSR_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c index 757b9ce7e3b1..8a38df2c0283 100644 --- a/drivers/gpu/drm/i915/display/intel_sdvo.c +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c @@ -36,9 +36,9 @@ #include <drm/drm_crtc.h> #include <drm/drm_edid.h> #include <drm/drm_eld.h> +#include <drm/drm_print.h> #include <drm/drm_probe_helper.h> -#include "i915_drv.h" #include "i915_reg.h" #include "intel_atomic.h" #include "intel_audio.h" @@ -214,18 +214,17 @@ intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val) { struct intel_display *display = to_intel_display(&intel_sdvo->base); - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 bval = val, cval = val; int i; - if (HAS_PCH_SPLIT(dev_priv)) { + if (HAS_PCH_SPLIT(display)) { intel_de_write(display, intel_sdvo->sdvo_reg, val); intel_de_posting_read(display, intel_sdvo->sdvo_reg); /* * HW workaround, need to write this twice for issue * that may result in first write getting masked. */ - if (HAS_PCH_IBX(dev_priv)) { + if (HAS_PCH_IBX(display)) { intel_de_write(display, intel_sdvo->sdvo_reg, val); intel_de_posting_read(display, intel_sdvo->sdvo_reg); } @@ -1360,14 +1359,13 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder, struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct intel_sdvo *intel_sdvo = to_sdvo(encoder); struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(conn_state->connector); struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; struct drm_display_mode *mode = &pipe_config->hw.mode; - if (HAS_PCH_SPLIT(i915)) { + if (HAS_PCH_SPLIT(display)) { pipe_config->has_pch_encoder = true; if (!intel_fdi_compute_pipe_bpp(pipe_config)) return -EINVAL; @@ -1527,7 +1525,6 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state, const struct drm_connector_state *conn_state) { struct intel_display *display = to_intel_display(intel_encoder); - struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; const struct intel_sdvo_connector_state *sdvo_state = @@ -1634,7 +1631,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state, sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; } - if (HAS_PCH_CPT(dev_priv)) + if (HAS_PCH_CPT(display)) sdvox |= SDVO_PIPE_SEL_CPT(crtc->pipe); else sdvox |= SDVO_PIPE_SEL(crtc->pipe); @@ -1670,13 +1667,12 @@ static bool intel_sdvo_connector_get_hw_state(struct intel_connector *connector) bool intel_sdvo_port_enabled(struct intel_display *display, i915_reg_t sdvo_reg, enum pipe *pipe) { - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 val; val = intel_de_read(display, sdvo_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 = (val & SDVO_PIPE_SEL_MASK_CPT) >> SDVO_PIPE_SEL_SHIFT_CPT; else if (display->platform.cherryview) *pipe = (val & SDVO_PIPE_SEL_MASK_CHV) >> SDVO_PIPE_SEL_SHIFT_CHV; @@ -1841,7 +1837,6 @@ static void intel_disable_sdvo(struct intel_atomic_state *state, const 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 intel_sdvo *intel_sdvo = to_sdvo(encoder); struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc); u32 temp; @@ -1861,7 +1856,7 @@ static void intel_disable_sdvo(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. @@ -3367,9 +3362,7 @@ intel_sdvo_init_ddc_proxy(struct intel_sdvo_ddc *ddc, static bool is_sdvo_port_valid(struct intel_display *display, enum port port) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - - if (HAS_PCH_SPLIT(dev_priv)) + if (HAS_PCH_SPLIT(display)) return port == PORT_B; else return port == PORT_B || port == PORT_C; @@ -3384,7 +3377,6 @@ static bool assert_sdvo_port_valid(struct intel_display *display, enum port port bool intel_sdvo_init(struct intel_display *display, i915_reg_t sdvo_reg, enum port port) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_encoder *intel_encoder; struct intel_sdvo *intel_sdvo; int i; @@ -3427,7 +3419,7 @@ bool intel_sdvo_init(struct intel_display *display, } intel_encoder->compute_config = intel_sdvo_compute_config; - if (HAS_PCH_SPLIT(dev_priv)) { + if (HAS_PCH_SPLIT(display)) { intel_encoder->disable = pch_disable_sdvo; intel_encoder->post_disable = pch_post_disable_sdvo; } else { diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index 1ad6c8a94b3d..fd92e6b89b43 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -36,9 +36,10 @@ #include <drm/drm_blend.h> #include <drm/drm_color_mgmt.h> #include <drm/drm_fourcc.h> +#include <drm/drm_print.h> #include <drm/drm_rect.h> -#include "i915_drv.h" +#include "i915_utils.h" #include "i9xx_plane.h" #include "intel_atomic_plane.h" #include "intel_de.h" diff --git a/drivers/gpu/drm/i915/display/intel_sprite_uapi.c b/drivers/gpu/drm/i915/display/intel_sprite_uapi.c index 1d0b84b464c1..4981cc34da05 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite_uapi.c +++ b/drivers/gpu/drm/i915/display/intel_sprite_uapi.c @@ -3,21 +3,21 @@ * Copyright © 2023 Intel Corporation */ -#include "i915_drv.h" #include "intel_crtc.h" +#include "intel_display_core.h" #include "intel_display_types.h" #include "intel_sprite_uapi.h" -static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv) +static bool has_dst_key_in_primary_plane(struct intel_display *display) { - return DISPLAY_VER(dev_priv) >= 9; + return DISPLAY_VER(display) >= 9; } static void intel_plane_set_ckey(struct intel_plane_state *plane_state, const struct drm_intel_sprite_colorkey *set) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(plane->base.dev); struct drm_intel_sprite_colorkey *key = &plane_state->ckey; *key = *set; @@ -34,7 +34,7 @@ static void intel_plane_set_ckey(struct intel_plane_state *plane_state, * On SKL+ we want dst key enabled on * the primary and not on the sprite. */ - if (DISPLAY_VER(dev_priv) >= 9 && plane->id != PLANE_PRIMARY && + if (DISPLAY_VER(display) >= 9 && plane->id != PLANE_PRIMARY && set->flags & I915_SET_COLORKEY_DESTINATION) key->flags = 0; } @@ -43,7 +43,6 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct intel_display *display = to_intel_display(dev); - struct drm_i915_private *dev_priv = to_i915(dev); struct drm_intel_sprite_colorkey *set = data; struct drm_plane *plane; struct drm_plane_state *plane_state; @@ -61,7 +60,7 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data, if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) return -EINVAL; - if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && + if ((display->platform.valleyview || display->platform.cherryview) && set->flags & I915_SET_COLORKEY_DESTINATION) return -EINVAL; @@ -74,7 +73,7 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data, * Also multiple planes can't do destination keying on the same * pipe simultaneously. */ - if (DISPLAY_VER(dev_priv) >= 9 && + if (DISPLAY_VER(display) >= 9 && to_intel_plane(plane)->id >= PLANE_3 && set->flags & I915_SET_COLORKEY_DESTINATION) return -EINVAL; @@ -99,7 +98,7 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data, * On some platforms we have to configure * the dst colorkey on the primary plane. */ - if (!ret && has_dst_key_in_primary_plane(dev_priv)) { + if (!ret && has_dst_key_in_primary_plane(display)) { struct intel_crtc *crtc = intel_crtc_for_pipe(display, to_intel_plane(plane)->pipe); diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c index 2e3f3f0207e8..acf0b3733908 100644 --- a/drivers/gpu/drm/i915/display/intel_tv.c +++ b/drivers/gpu/drm/i915/display/intel_tv.c @@ -33,15 +33,15 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> #include <drm/drm_edid.h> +#include <drm/drm_print.h> #include <drm/drm_probe_helper.h> -#include "i915_drv.h" #include "i915_reg.h" #include "intel_connector.h" #include "intel_crtc.h" #include "intel_de.h" -#include "intel_display_irq.h" #include "intel_display_driver.h" +#include "intel_display_irq.h" #include "intel_display_types.h" #include "intel_dpll.h" #include "intel_hotplug.h" @@ -1585,19 +1585,17 @@ intel_tv_detect_type(struct intel_tv *intel_tv, { struct intel_display *display = to_intel_display(connector->dev); struct intel_crtc *crtc = to_intel_crtc(connector->state->crtc); - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = to_i915(dev); u32 tv_ctl, save_tv_ctl; u32 tv_dac, save_tv_dac; int type; /* Disable TV interrupts around load detect or we'll recurse */ if (connector->polled & DRM_CONNECTOR_POLL_HPD) { - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); i915_disable_pipestat(display, 0, PIPE_HOTPLUG_INTERRUPT_STATUS | PIPE_HOTPLUG_TV_INTERRUPT_STATUS); - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); } save_tv_dac = tv_dac = intel_de_read(display, TV_DAC); @@ -1668,11 +1666,11 @@ intel_tv_detect_type(struct intel_tv *intel_tv, /* Restore interrupt config */ if (connector->polled & DRM_CONNECTOR_POLL_HPD) { - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); i915_enable_pipestat(display, 0, PIPE_HOTPLUG_INTERRUPT_STATUS | PIPE_HOTPLUG_TV_INTERRUPT_STATUS); - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); } return type; diff --git a/drivers/gpu/drm/i915/display/intel_vga.c b/drivers/gpu/drm/i915/display/intel_vga.c index 684b5d1bc87c..05d140c8032d 100644 --- a/drivers/gpu/drm/i915/display/intel_vga.c +++ b/drivers/gpu/drm/i915/display/intel_vga.c @@ -4,15 +4,20 @@ */ #include <linux/delay.h> +#include <linux/pci.h> #include <linux/vgaarb.h> +#include <drm/drm_device.h> +#include <drm/drm_print.h> #include <video/vga.h> + #include "soc/intel_gmch.h" -#include "i915_drv.h" #include "i915_reg.h" #include "intel_de.h" +#include "intel_display.h" #include "intel_vga.h" +#include "intel_vga_regs.h" static i915_reg_t intel_vga_cntrl_reg(struct intel_display *display) { @@ -24,16 +29,42 @@ static i915_reg_t intel_vga_cntrl_reg(struct intel_display *display) return VGACNTRL; } +static bool has_vga_pipe_sel(struct intel_display *display) +{ + if (display->platform.i845g || + display->platform.i865g) + return false; + + if (display->platform.valleyview || + display->platform.cherryview) + return true; + + return DISPLAY_VER(display) < 7; +} + /* Disable the VGA plane that we never use */ void intel_vga_disable(struct intel_display *display) { struct pci_dev *pdev = to_pci_dev(display->drm->dev); i915_reg_t vga_reg = intel_vga_cntrl_reg(display); + enum pipe pipe; + u32 tmp; u8 sr1; - if (intel_de_read(display, vga_reg) & VGA_DISP_DISABLE) + tmp = intel_de_read(display, vga_reg); + if (tmp & VGA_DISP_DISABLE) return; + if (display->platform.cherryview) + pipe = REG_FIELD_GET(VGA_PIPE_SEL_MASK_CHV, tmp); + else if (has_vga_pipe_sel(display)) + pipe = REG_FIELD_GET(VGA_PIPE_SEL_MASK, tmp); + else + pipe = PIPE_A; + + drm_dbg_kms(display->drm, "Disabling VGA plane on pipe %c\n", + pipe_name(pipe)); + /* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */ vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO); outb(0x01, VGA_SEQ_I); @@ -46,39 +77,6 @@ void intel_vga_disable(struct intel_display *display) intel_de_posting_read(display, vga_reg); } -void intel_vga_redisable_power_on(struct intel_display *display) -{ - i915_reg_t vga_reg = intel_vga_cntrl_reg(display); - - if (!(intel_de_read(display, vga_reg) & VGA_DISP_DISABLE)) { - drm_dbg_kms(display->drm, - "Something enabled VGA plane, disabling it\n"); - intel_vga_disable(display); - } -} - -void intel_vga_redisable(struct intel_display *display) -{ - intel_wakeref_t wakeref; - - /* - * This function can be called both from intel_modeset_setup_hw_state or - * at a very early point in our resume sequence, where the power well - * structures are not yet restored. Since this function is at a very - * paranoid "someone might have enabled VGA while we were not looking" - * level, just check if the power well is enabled instead of trying to - * follow the "don't touch the power well if we don't need it" policy - * the rest of the driver uses. - */ - wakeref = intel_display_power_get_if_enabled(display, POWER_DOMAIN_VGA); - if (!wakeref) - return; - - intel_vga_redisable_power_on(display); - - intel_display_power_put(display, POWER_DOMAIN_VGA, wakeref); -} - void intel_vga_reset_io_mem(struct intel_display *display) { struct pci_dev *pdev = to_pci_dev(display->drm->dev); diff --git a/drivers/gpu/drm/i915/display/intel_vga.h b/drivers/gpu/drm/i915/display/intel_vga.h index 824dfc32a199..16d699f3b641 100644 --- a/drivers/gpu/drm/i915/display/intel_vga.h +++ b/drivers/gpu/drm/i915/display/intel_vga.h @@ -10,8 +10,6 @@ struct intel_display; void intel_vga_reset_io_mem(struct intel_display *display); void intel_vga_disable(struct intel_display *display); -void intel_vga_redisable(struct intel_display *display); -void intel_vga_redisable_power_on(struct intel_display *display); int intel_vga_register(struct intel_display *display); void intel_vga_unregister(struct intel_display *display); diff --git a/drivers/gpu/drm/i915/display/intel_vga_regs.h b/drivers/gpu/drm/i915/display/intel_vga_regs.h new file mode 100644 index 000000000000..cbacced1a69f --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_vga_regs.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2025 Intel Corporation + */ + +#ifndef __INTEL_VGA_REGS_H__ +#define __INTEL_VGA_REGS_H__ + +#include "intel_display_reg_defs.h" + +#define VGACNTRL _MMIO(0x71400) +#define VLV_VGACNTRL _MMIO(VLV_DISPLAY_BASE + 0x71400) +#define CPU_VGACNTRL _MMIO(0x41000) +#define VGA_DISP_DISABLE REG_BIT(31) +#define VGA_2X_MODE REG_BIT(30) /* pre-ilk */ +#define VGA_PIPE_SEL_MASK REG_BIT(29) /* pre-ivb */ +#define VGA_PIPE_SEL(pipe) REG_FIELD_PREP(VGA_PIPE_SEL_MASK, (pipe)) +#define VGA_PIPE_SEL_MASK_CHV REG_GENMASK(29, 28) /* chv */ +#define VGA_PIPE_SEL_CHV(pipe) REG_FIELD_PREP(VGA_PIPE_SEL_MASK_CHV, (pipe)) +#define VGA_BORDER_ENABLE REG_BIT(26) +#define VGA_PIPE_CSC_ENABLE REG_BIT(24) /* ilk+ */ +#define VGA_CENTERING_ENABLE_MASK REG_GENMASK(25, 24) /* pre-ilk */ +#define VGA_PALETTE_READ_SEL REG_BIT(23) /* pre-ivb */ +#define VGA_PALETTE_A_WRITE_DISABLE REG_BIT(22) /* pre-ivb */ +#define VGA_PALETTE_B_WRITE_DISABLE REG_BIT(21) /* pre-ivb */ +#define VGA_LEGACY_8BIT_PALETTE_ENABLE REG_BIT(20) +#define VGA_PALETTE_BYPASS REG_BIT(19) +#define VGA_NINE_DOT_DISABLE REG_BIT(18) +#define VGA_PALETTE_READ_SEL_HI_CHV REG_BIT(15) /* chv */ +#define VGA_PALETTE_C_WRITE_DISABLE_CHV REG_BIT(14) /* chv */ +#define VGA_ACTIVE_THROTTLING_MASK REG_GENMASK(15, 12) /* ilk+ */ +#define VGA_BLANK_THROTTLING_MASK REG_GENMASK(11, 8) /* ilk+ */ +#define VGA_BLINK_DUTY_CYCLE_MASK REG_GENMASK(7, 6) +#define VGA_VSYNC_BLINK_RATE_MASK REG_GENMASK(5, 0) + +#endif /* __INTEL_VGA_REGS_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index 633a66f6b73b..c6565baf815a 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -444,7 +444,10 @@ static u32 trans_vrr_ctl(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - if (DISPLAY_VER(display) >= 13) + if (DISPLAY_VER(display) >= 14) + return VRR_CTL_FLIP_LINE_EN | + XELPD_VRR_CTL_VRR_GUARDBAND(crtc_state->vrr.guardband); + else if (DISPLAY_VER(display) >= 13) return VRR_CTL_IGN_MAX_SHIFT | VRR_CTL_FLIP_LINE_EN | XELPD_VRR_CTL_VRR_GUARDBAND(crtc_state->vrr.guardband); else diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c index ee81220a7c88..c855426544cf 100644 --- a/drivers/gpu/drm/i915/display/skl_scaler.c +++ b/drivers/gpu/drm/i915/display/skl_scaler.c @@ -3,8 +3,10 @@ * Copyright © 2020 Intel Corporation */ -#include "i915_drv.h" +#include <drm/drm_print.h> + #include "i915_reg.h" +#include "i915_utils.h" #include "intel_de.h" #include "intel_display_trace.h" #include "intel_display_types.h" diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 8739195aba69..844519286b1c 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2690,24 +2690,22 @@ static void skl_plane_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, GEN9_PIPE_PLANE_FLIP_DONE(plane->id)); - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); } static void skl_plane_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, GEN9_PIPE_PLANE_FLIP_DONE(plane->id)); - spin_unlock_irq(&i915->irq_lock); + spin_unlock_irq(&display->irq.lock); } static bool skl_plane_has_rc_ccs(struct intel_display *display, diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c b/drivers/gpu/drm/i915/gt/intel_rps.c index b609e3aa2122..5abc5fcc2514 100644 --- a/drivers/gpu/drm/i915/gt/intel_rps.c +++ b/drivers/gpu/drm/i915/gt/intel_rps.c @@ -8,7 +8,7 @@ #include <drm/intel/i915_drm.h> #include "display/intel_display.h" -#include "display/intel_display_irq.h" +#include "display/intel_display_rps.h" #include "i915_drv.h" #include "i915_irq.h" #include "i915_reg.h" @@ -608,9 +608,7 @@ static bool gen5_rps_enable(struct intel_rps *rps) rps->ips.last_count2 = intel_uncore_read(uncore, GFXEC); rps->ips.last_time2 = ktime_get_raw_ns(); - spin_lock(&i915->irq_lock); - ilk_enable_display_irq(display, DE_PCU_EVENT); - spin_unlock(&i915->irq_lock); + ilk_display_rps_enable(display); spin_unlock_irq(&mchdev_lock); @@ -628,9 +626,7 @@ static void gen5_rps_disable(struct intel_rps *rps) spin_lock_irq(&mchdev_lock); - spin_lock(&i915->irq_lock); - ilk_disable_display_irq(display, DE_PCU_EVENT); - spin_unlock(&i915->irq_lock); + ilk_display_rps_disable(display); rgvswctl = intel_uncore_read16(uncore, MEMSWCTL); diff --git a/drivers/gpu/drm/i915/gt/intel_rps_types.h b/drivers/gpu/drm/i915/gt/intel_rps_types.h index 5135b90a2a40..ece445109305 100644 --- a/drivers/gpu/drm/i915/gt/intel_rps_types.h +++ b/drivers/gpu/drm/i915/gt/intel_rps_types.h @@ -57,7 +57,7 @@ struct intel_rps { /* * work, interrupts_enabled and pm_iir are protected by - * i915->irq_lock + * gt->irq_lock */ struct timer_list timer; struct work_struct work; diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index e6e9010462e3..1344e6d20a34 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -56,6 +56,7 @@ #include "display/intel_pps_regs.h" #include "display/intel_psr_regs.h" #include "display/intel_sprite_regs.h" +#include "display/intel_vga_regs.h" #include "display/skl_universal_plane_regs.h" #include "display/skl_watermark_regs.h" #include "display/vlv_dsi_pll_regs.h" diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index f5262b8ad237..273bc43468a0 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -62,7 +62,6 @@ #include "display/intel_pch_refclk.h" #include "display/intel_pps.h" #include "display/intel_sprite_uapi.h" -#include "display/intel_vga.h" #include "display/skl_watermark.h" #include "gem/i915_gem_context.h" @@ -235,7 +234,6 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv) intel_uncore_mmio_debug_init_early(dev_priv); - spin_lock_init(&dev_priv->irq_lock); spin_lock_init(&dev_priv->gpu_error.lock); intel_sbi_init(dev_priv); @@ -263,9 +261,6 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv) i915_gem_init_early(dev_priv); - /* This must be called before any calls to HAS_PCH_* */ - intel_detect_pch(dev_priv); - intel_irq_init(dev_priv); intel_display_driver_early_probe(display); intel_clock_gating_hooks_init(dev_priv); @@ -1205,8 +1200,6 @@ static int i915_drm_resume(struct drm_device *dev) i9xx_display_sr_restore(display); - intel_vga_redisable(display); - intel_gmbus_reset(display); intel_pps_unlock_regs_wa(display); diff --git a/drivers/gpu/drm/i915/i915_driver.h b/drivers/gpu/drm/i915/i915_driver.h index 4b67ad9a61cd..1e95ecb2a163 100644 --- a/drivers/gpu/drm/i915/i915_driver.h +++ b/drivers/gpu/drm/i915/i915_driver.h @@ -15,7 +15,6 @@ struct drm_printer; #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_TIMESTAMP 1695980603 extern const struct dev_pm_ops i915_pm_ops; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 236c48d282e4..d0e1980dcba2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -49,8 +49,6 @@ #include "gt/intel_workarounds.h" #include "gt/uc/intel_uc.h" -#include "soc/intel_pch.h" - #include "i915_drm_client.h" #include "i915_gem.h" #include "i915_gpu_error.h" @@ -224,8 +222,6 @@ struct drm_i915_private { }; unsigned int engine_uabi_class_count[I915_LAST_UABI_ENGINE_CLASS + 1]; - /* protects the irq masks */ - spinlock_t irq_lock; bool irqs_enabled; /* LPT/WPT IOSF sideband protection */ @@ -272,9 +268,6 @@ struct drm_i915_private { /* pm private clock gating functions */ const struct drm_i915_clock_gating_funcs *clock_gating_funcs; - /* PCH chipset type */ - enum intel_pch pch_type; - unsigned long gem_quirks; struct i915_gem_mm mm; diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index a6613eed3398..4f785cdbd155 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -726,13 +726,6 @@ static void err_print_gt_info(struct drm_i915_error_state_buf *m, intel_sseu_print_topology(gt->_gt->i915, >->info.sseu, &p); } -static void err_print_gt_display(struct drm_i915_error_state_buf *m, - struct intel_gt_coredump *gt) -{ - err_printf(m, "IER: 0x%08x\n", gt->ier); - err_printf(m, "DERRMR: 0x%08x\n", gt->derrmr); -} - static void err_print_gt_global_nonguc(struct drm_i915_error_state_buf *m, struct intel_gt_coredump *gt) { @@ -878,7 +871,6 @@ static void __err_print_to_sgl(struct drm_i915_error_state_buf *m, if (error->gt->uc && error->gt->uc->guc.is_guc_capture) print_guc_capture = true; - err_print_gt_display(m, error->gt); err_print_gt_global_nonguc(m, error->gt); err_print_gt_fences(m, error->gt); @@ -1767,27 +1759,6 @@ gt_record_uc(struct intel_gt_coredump *gt, return error_uc; } -/* Capture display registers. */ -static void gt_record_display_regs(struct intel_gt_coredump *gt) -{ - struct intel_uncore *uncore = gt->_gt->uncore; - struct drm_i915_private *i915 = uncore->i915; - - if (DISPLAY_VER(i915) >= 6 && DISPLAY_VER(i915) < 20) - gt->derrmr = intel_uncore_read(uncore, DERRMR); - - if (GRAPHICS_VER(i915) >= 8) - gt->ier = intel_uncore_read(uncore, GEN8_DE_MISC_IER); - else if (IS_VALLEYVIEW(i915)) - gt->ier = intel_uncore_read(uncore, VLV_IER); - else if (HAS_PCH_SPLIT(i915)) - gt->ier = intel_uncore_read(uncore, DEIER); - else if (GRAPHICS_VER(i915) == 2) - gt->ier = intel_uncore_read16(uncore, GEN2_IER); - else - gt->ier = intel_uncore_read(uncore, GEN2_IER); -} - /* Capture all other registers that GuC doesn't capture. */ static void gt_record_global_nonguc_regs(struct intel_gt_coredump *gt) { @@ -1821,9 +1792,12 @@ static void gt_record_global_nonguc_regs(struct intel_gt_coredump *gt) gt->gtier[i] = intel_uncore_read(uncore, GEN8_GT_IER(i)); gt->ngtier = 4; - } else if (HAS_PCH_SPLIT(i915)) { + } else if (GRAPHICS_VER(i915) >= 5) { gt->gtier[0] = intel_uncore_read(uncore, GTIER); gt->ngtier = 1; + } else { + gt->gtier[0] = intel_uncore_read(uncore, GEN2_IER); + gt->ngtier = 1; } gt->eir = intel_uncore_read(uncore, EIR); @@ -2043,7 +2017,6 @@ intel_gt_coredump_alloc(struct intel_gt *gt, gfp_t gfp, u32 dump_flags) gc->_gt = gt; gc->awake = intel_gt_pm_is_awake(gt); - gt_record_display_regs(gc); gt_record_global_nonguc_regs(gc); /* @@ -2160,7 +2133,6 @@ i915_gpu_coredump(struct intel_gt *gt, intel_engine_mask_t engine_mask, u32 dump void i915_error_state_store(struct i915_gpu_coredump *error) { struct drm_i915_private *i915; - static bool warned; if (IS_ERR_OR_NULL(error)) return; @@ -2174,16 +2146,8 @@ void i915_error_state_store(struct i915_gpu_coredump *error) i915_gpu_coredump_get(error); - if (!xchg(&warned, true) && - ktime_get_real_seconds() - DRIVER_TIMESTAMP < DAY_AS_SECONDS(180)) { - pr_info("GPU hangs can indicate a bug anywhere in the entire gfx stack, including userspace.\n"); - pr_info("Please file a _new_ bug report at https://gitlab.freedesktop.org/drm/intel/issues/new.\n"); - pr_info("Please see https://drm.pages.freedesktop.org/intel-docs/how-to-file-i915-bugs.html for details.\n"); - pr_info("drm/i915 developers can then reassign to the right component if it's not a kernel issue.\n"); - pr_info("The GPU crash dump is required to analyze GPU hangs, so please always attach it.\n"); - pr_info("GPU crash dump saved to /sys/class/drm/card%d/error\n", - i915->drm.primary->index); - } + drm_info(&i915->drm, "GPU error state saved to /sys/class/drm/card%d/error\n", + i915->drm.primary->index); } /** diff --git a/drivers/gpu/drm/i915/i915_gpu_error.h b/drivers/gpu/drm/i915/i915_gpu_error.h index 749e1c55613e..182324979278 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.h +++ b/drivers/gpu/drm/i915/i915_gpu_error.h @@ -146,7 +146,6 @@ struct intel_gt_coredump { /* Generic register state */ u32 eir; u32 pgtbl_er; - u32 ier; u32 gtier[6], ngtier; u32 forcewake; u32 error; /* gen6+ */ @@ -164,8 +163,6 @@ struct intel_gt_coredump { u32 clock_frequency; u32 clock_period_ns; - /* Display related */ - u32 derrmr; u32 sfc_done[I915_MAX_SFC]; /* gen12 */ u32 nfence; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index c1f938a1da44..95042879bec4 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -658,23 +658,9 @@ static irqreturn_t dg1_irq_handler(int irq, void *arg) return IRQ_HANDLED; } -static void ibx_irq_reset(struct drm_i915_private *dev_priv) -{ - struct intel_uncore *uncore = &dev_priv->uncore; - - if (HAS_PCH_NOP(dev_priv)) - return; - - gen2_irq_reset(uncore, SDE_IRQ_REGS); - - if (HAS_PCH_CPT(dev_priv) || HAS_PCH_LPT(dev_priv)) - intel_uncore_write(&dev_priv->uncore, SERR_INT, 0xffffffff); -} - -/* drm_dma.h hooks -*/ static void ilk_irq_reset(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct intel_uncore *uncore = &dev_priv->uncore; gen2_irq_reset(uncore, DE_IRQ_REGS); @@ -690,7 +676,7 @@ static void ilk_irq_reset(struct drm_i915_private *dev_priv) gen5_gt_irq_reset(to_gt(dev_priv)); - ibx_irq_reset(dev_priv); + ibx_display_irq_reset(display); } static void valleyview_irq_reset(struct drm_i915_private *dev_priv) @@ -702,9 +688,7 @@ static void valleyview_irq_reset(struct drm_i915_private *dev_priv) gen5_gt_irq_reset(to_gt(dev_priv)); - spin_lock_irq(&dev_priv->irq_lock); vlv_display_irq_reset(display); - spin_unlock_irq(&dev_priv->irq_lock); } static void gen8_irq_reset(struct drm_i915_private *dev_priv) @@ -717,10 +701,6 @@ static void gen8_irq_reset(struct drm_i915_private *dev_priv) gen8_gt_irq_reset(to_gt(dev_priv)); gen8_display_irq_reset(display); gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS); - - if (HAS_PCH_SPLIT(dev_priv)) - ibx_irq_reset(dev_priv); - } static void gen11_irq_reset(struct drm_i915_private *dev_priv) @@ -770,9 +750,7 @@ static void cherryview_irq_reset(struct drm_i915_private *dev_priv) gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS); - spin_lock_irq(&dev_priv->irq_lock); vlv_display_irq_reset(display); - spin_unlock_irq(&dev_priv->irq_lock); } static void ilk_irq_postinstall(struct drm_i915_private *dev_priv) @@ -790,9 +768,7 @@ static void valleyview_irq_postinstall(struct drm_i915_private *dev_priv) gen5_gt_irq_postinstall(to_gt(dev_priv)); - spin_lock_irq(&dev_priv->irq_lock); vlv_display_irq_postinstall(display); - spin_unlock_irq(&dev_priv->irq_lock); intel_uncore_write(&dev_priv->uncore, VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE); intel_uncore_posting_read(&dev_priv->uncore, VLV_MASTER_IER); @@ -849,9 +825,7 @@ static void cherryview_irq_postinstall(struct drm_i915_private *dev_priv) gen8_gt_irq_postinstall(to_gt(dev_priv)); - spin_lock_irq(&dev_priv->irq_lock); vlv_display_irq_postinstall(display); - spin_unlock_irq(&dev_priv->irq_lock); intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); intel_uncore_posting_read(&dev_priv->uncore, GEN8_MASTER_IRQ); @@ -961,14 +935,7 @@ static void i915_irq_postinstall(struct drm_i915_private *dev_priv) gen2_irq_init(uncore, GEN2_IRQ_REGS, dev_priv->irq_mask, enable_mask); - /* Interrupt setup is already guaranteed to be single-threaded, this is - * just to make the assert_spin_locked check happy. */ - spin_lock_irq(&dev_priv->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(&dev_priv->irq_lock); - - i915_enable_asle_pipestat(display); + i915_display_irq_postinstall(display); } static irqreturn_t i915_irq_handler(int irq, void *arg) @@ -1086,15 +1053,7 @@ static void i965_irq_postinstall(struct drm_i915_private *dev_priv) gen2_irq_init(uncore, GEN2_IRQ_REGS, dev_priv->irq_mask, enable_mask); - /* Interrupt setup is already guaranteed to be single-threaded, this is - * just to make the assert_spin_locked check happy. */ - spin_lock_irq(&dev_priv->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(&dev_priv->irq_lock); - - i915_enable_asle_pipestat(display); + i965_display_irq_postinstall(display); } static irqreturn_t i965_irq_handler(int irq, void *arg) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 49beab8e324d..2e4190da3e0d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -866,6 +866,7 @@ #define FP_M2_DIV_MASK 0x0000003f #define FP_M2_PINEVIEW_DIV_MASK 0x000000ff #define FP_M2_DIV_SHIFT 0 + #define DPLL_TEST _MMIO(0x606c) #define DPLLB_TEST_SDVO_DIV_1 (0 << 22) #define DPLLB_TEST_SDVO_DIV_2 (1 << 22) @@ -877,11 +878,13 @@ #define DPLLA_TEST_N_BYPASS (1 << 3) #define DPLLA_TEST_M_BYPASS (1 << 2) #define DPLLA_INPUT_BUFFER_ENABLE (1 << 0) + #define D_STATE _MMIO(0x6104) #define DSTATE_GFX_RESET_I830 (1 << 6) #define DSTATE_PLL_D3_OFF (1 << 3) #define DSTATE_GFX_CLOCK_GATING (1 << 1) #define DSTATE_DOT_CLOCK_GATING (1 << 0) + #define DSPCLK_GATE_D(__i915) _MMIO(DISPLAY_MMIO_BASE(__i915) + 0x6200) # define DPUNIT_B_CLOCK_GATE_DISABLE (1 << 30) /* 965 */ # define VSUNIT_CLOCK_GATE_DISABLE (1 << 29) /* 965 */ @@ -1050,7 +1053,6 @@ /* * Overlay regs */ - #define OVADD _MMIO(0x30000) #define DOVSTA _MMIO(0x30008) #define OC_BUF (0x3 << 20) @@ -1106,7 +1108,6 @@ /* * Display engine regs */ - /* Pipe/transcoder A timing regs */ #define _TRANS_HTOTAL_A 0x60000 #define _TRANS_HTOTAL_B 0x61000 @@ -1397,88 +1398,50 @@ #define VLV_DP_B _MMIO(VLV_DISPLAY_BASE + 0x64100) #define VLV_DP_C _MMIO(VLV_DISPLAY_BASE + 0x64200) #define CHV_DP_D _MMIO(VLV_DISPLAY_BASE + 0x64300) -#define DP_PORT_EN (1 << 31) -#define DP_PIPE_SEL_SHIFT 30 -#define DP_PIPE_SEL_MASK (1 << 30) -#define DP_PIPE_SEL(pipe) ((pipe) << 30) -#define DP_PIPE_SEL_SHIFT_IVB 29 -#define DP_PIPE_SEL_MASK_IVB (3 << 29) -#define DP_PIPE_SEL_IVB(pipe) ((pipe) << 29) +#define DP_PORT_EN REG_BIT(31) +#define DP_PIPE_SEL_MASK REG_GENMASK(30, 30) +#define DP_PIPE_SEL(pipe) REG_FIELD_PREP(DP_PIPE_SEL_MASK, (pipe)) +#define DP_PIPE_SEL_MASK_IVB REG_GENMASK(30, 29) +#define DP_PIPE_SEL_IVB(pipe) REG_FIELD_PREP(DP_PIPE_SEL_MASK_IVB, (pipe)) #define DP_PIPE_SEL_SHIFT_CHV 16 -#define DP_PIPE_SEL_MASK_CHV (3 << 16) -#define DP_PIPE_SEL_CHV(pipe) ((pipe) << 16) - -/* Link training mode - select a suitable mode for each stage */ -#define DP_LINK_TRAIN_PAT_1 (0 << 28) -#define DP_LINK_TRAIN_PAT_2 (1 << 28) -#define DP_LINK_TRAIN_PAT_IDLE (2 << 28) -#define DP_LINK_TRAIN_OFF (3 << 28) -#define DP_LINK_TRAIN_MASK (3 << 28) -#define DP_LINK_TRAIN_SHIFT 28 - -/* CPT Link training mode */ -#define DP_LINK_TRAIN_PAT_1_CPT (0 << 8) -#define DP_LINK_TRAIN_PAT_2_CPT (1 << 8) -#define DP_LINK_TRAIN_PAT_IDLE_CPT (2 << 8) -#define DP_LINK_TRAIN_OFF_CPT (3 << 8) -#define DP_LINK_TRAIN_MASK_CPT (7 << 8) -#define DP_LINK_TRAIN_SHIFT_CPT 8 - -/* Signal voltages. These are mostly controlled by the other end */ -#define DP_VOLTAGE_0_4 (0 << 25) -#define DP_VOLTAGE_0_6 (1 << 25) -#define DP_VOLTAGE_0_8 (2 << 25) -#define DP_VOLTAGE_1_2 (3 << 25) -#define DP_VOLTAGE_MASK (7 << 25) -#define DP_VOLTAGE_SHIFT 25 - -/* Signal pre-emphasis levels, like voltages, the other end tells us what - * they want - */ -#define DP_PRE_EMPHASIS_0 (0 << 22) -#define DP_PRE_EMPHASIS_3_5 (1 << 22) -#define DP_PRE_EMPHASIS_6 (2 << 22) -#define DP_PRE_EMPHASIS_9_5 (3 << 22) -#define DP_PRE_EMPHASIS_MASK (7 << 22) -#define DP_PRE_EMPHASIS_SHIFT 22 - -/* How many wires to use. I guess 3 was too hard */ -#define DP_PORT_WIDTH(width) (((width) - 1) << 19) -#define DP_PORT_WIDTH_MASK (7 << 19) -#define DP_PORT_WIDTH_SHIFT 19 - -/* Mystic DPCD version 1.1 special mode */ -#define DP_ENHANCED_FRAMING (1 << 18) - -/* eDP */ -#define DP_PLL_FREQ_270MHZ (0 << 16) -#define DP_PLL_FREQ_162MHZ (1 << 16) -#define DP_PLL_FREQ_MASK (3 << 16) - -/* locked once port is enabled */ -#define DP_PORT_REVERSAL (1 << 15) - -/* eDP */ -#define DP_PLL_ENABLE (1 << 14) - -/* sends the clock on lane 15 of the PEG for debug */ -#define DP_CLOCK_OUTPUT_ENABLE (1 << 13) - -#define DP_SCRAMBLING_DISABLE (1 << 12) -#define DP_SCRAMBLING_DISABLE_IRONLAKE (1 << 7) - -/* limit RGB values to avoid confusing TVs */ -#define DP_COLOR_RANGE_16_235 (1 << 8) - -/* Turn on the audio link */ -#define DP_AUDIO_OUTPUT_ENABLE (1 << 6) - -/* vs and hs sync polarity */ -#define DP_SYNC_VS_HIGH (1 << 4) -#define DP_SYNC_HS_HIGH (1 << 3) - -/* A fantasy */ -#define DP_DETECTED (1 << 2) +#define DP_PIPE_SEL_MASK_CHV REG_GENMASK(17, 16) +#define DP_PIPE_SEL_CHV(pipe) REG_FIELD_PREP(DP_PIPE_SEL_MASK_CHV, (pipe)) +#define DP_LINK_TRAIN_MASK REG_GENMASK(29, 28) +#define DP_LINK_TRAIN_PAT_1 REG_FIELD_PREP(DP_LINK_TRAIN_MASK, 0) +#define DP_LINK_TRAIN_PAT_2 REG_FIELD_PREP(DP_LINK_TRAIN_MASK, 1) +#define DP_LINK_TRAIN_PAT_IDLE REG_FIELD_PREP(DP_LINK_TRAIN_MASK, 2) +#define DP_LINK_TRAIN_OFF REG_FIELD_PREP(DP_LINK_TRAIN_MASK, 3) +#define DP_LINK_TRAIN_MASK_CPT REG_GENMASK(10, 8) +#define DP_LINK_TRAIN_PAT_1_CPT REG_FIELD_PREP(DP_LINK_TRAIN_MASK_CPT, 0) +#define DP_LINK_TRAIN_PAT_2_CPT REG_FIELD_PREP(DP_LINK_TRAIN_MASK_CPT, 1) +#define DP_LINK_TRAIN_PAT_IDLE_CPT REG_FIELD_PREP(DP_LINK_TRAIN_MASK_CPT, 2) +#define DP_LINK_TRAIN_OFF_CPT REG_FIELD_PREP(DP_LINK_TRAIN_MASK_CPT, 3) +#define DP_VOLTAGE_MASK REG_GENMASK(27, 25) +#define DP_VOLTAGE_0_4 REG_FIELD_PREP(DP_VOLTAGE_MASK, 0) +#define DP_VOLTAGE_0_6 REG_FIELD_PREP(DP_VOLTAGE_MASK, 1) +#define DP_VOLTAGE_0_8 REG_FIELD_PREP(DP_VOLTAGE_MASK, 2) +#define DP_VOLTAGE_1_2 REG_FIELD_PREP(DP_VOLTAGE_MASK, 3) +#define DP_PRE_EMPHASIS_MASK REG_GENMASK(24, 22) +#define DP_PRE_EMPHASIS_0 REG_FIELD_PREP(DP_PRE_EMPHASIS_MASK, 0) +#define DP_PRE_EMPHASIS_3_5 REG_FIELD_PREP(DP_PRE_EMPHASIS_MASK, 1) +#define DP_PRE_EMPHASIS_6 REG_FIELD_PREP(DP_PRE_EMPHASIS_MASK, 2) +#define DP_PRE_EMPHASIS_9_5 REG_FIELD_PREP(DP_PRE_EMPHASIS_MASK, 3) +#define DP_PORT_WIDTH_MASK REG_GENMASK(21, 19) +#define DP_PORT_WIDTH(width) REG_FIELD_PREP(DP_PORT_WIDTH_MASK, (width) - 1) +#define DP_ENHANCED_FRAMING REG_BIT(18) +#define EDP_PLL_FREQ_MASK REG_GENMASK(17, 16) +#define EDP_PLL_FREQ_270MHZ REG_FIELD_PREP(EDP_PLL_FREQ_MASK, 0) +#define EDP_PLL_FREQ_162MHZ REG_FIELD_PREP(EDP_PLL_FREQ_MASK, 1) +#define DP_PORT_REVERSAL REG_BIT(15) +#define EDP_PLL_ENABLE REG_BIT(14) +#define DP_CLOCK_OUTPUT_ENABLE REG_BIT(13) +#define DP_SCRAMBLING_DISABLE REG_BIT(12) +#define DP_SCRAMBLING_DISABLE_ILK REG_BIT(7) +#define DP_COLOR_RANGE_16_235 REG_BIT(8) +#define DP_AUDIO_OUTPUT_ENABLE REG_BIT(6) +#define DP_SYNC_VS_HIGH REG_BIT(4) +#define DP_SYNC_HS_HIGH REG_BIT(3) +#define DP_DETECTED REG_BIT(2) /* * Computing GMCH M and N values for the Display Port link @@ -1812,18 +1775,6 @@ #define SWF3(dev_priv, i) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x72414 + (i) * 4) #define SWF_ILK(i) _MMIO(0x4F000 + (i) * 4) -/* VBIOS regs */ -#define VGACNTRL _MMIO(0x71400) -# define VGA_DISP_DISABLE (1 << 31) -# define VGA_2X_MODE (1 << 30) -# define VGA_PIPE_B_SELECT (1 << 29) - -#define VLV_VGACNTRL _MMIO(VLV_DISPLAY_BASE + 0x71400) - -/* Ironlake */ - -#define CPU_VGACNTRL _MMIO(0x41000) - #define DIGITAL_PORT_HOTPLUG_CNTRL _MMIO(0x44030) #define DIGITAL_PORTA_HOTPLUG_ENABLE (1 << 4) #define DIGITAL_PORTA_PULSE_DURATION_2ms (0 << 2) /* pre-HSW */ @@ -2784,7 +2735,6 @@ * functionality covered in PCH_PORT_HOTPLUG is split into * SHOTPLUG_CTL_DDI and SHOTPLUG_CTL_TC. */ - #define SHOTPLUG_CTL_DDI _MMIO(0xc4030) #define SHOTPLUG_CTL_DDI_HPD_ENABLE(hpd_pin) (0x8 << (_HPD_PIN_DDI(hpd_pin) * 4)) #define SHOTPLUG_CTL_DDI_HPD_OUTPUT_DATA(hpd_pin) (0x4 << (_HPD_PIN_DDI(hpd_pin) * 4)) @@ -2864,7 +2814,6 @@ #define TRANS_DPLL_ENABLE(pipe) (1 << ((pipe) * 4 + 3)) /* transcoder */ - #define _PCH_TRANS_HTOTAL_A 0xe0000 #define _PCH_TRANS_HTOTAL_B 0xe1000 #define PCH_TRANS_HTOTAL(pipe) _MMIO_PIPE(pipe, _PCH_TRANS_HTOTAL_A, _PCH_TRANS_HTOTAL_B) @@ -3795,7 +3744,6 @@ enum skl_power_gate { /* * SKL Clocks */ - /* CDCLK_CTL */ #define CDCLK_CTL _MMIO(0x46000) #define CDCLK_FREQ_SEL_MASK REG_GENMASK(27, 26) diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index 609214231ffc..f7fb40cfdb70 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -40,8 +40,6 @@ struct drm_i915_private; struct timer_list; -#define FDO_BUG_URL "https://drm.pages.freedesktop.org/intel-docs/how-to-file-i915-bugs.html" - #define MISSING_CASE(x) WARN(1, "Missing case (%s == %ld)\n", \ __stringify(x), (long)(x)) diff --git a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c index 76d84cbb8361..d581a9d2c063 100644 --- a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c +++ b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c @@ -21,6 +21,7 @@ #include "display/intel_pfit_regs.h" #include "display/intel_psr_regs.h" #include "display/intel_sprite_regs.h" +#include "display/intel_vga_regs.h" #include "display/skl_universal_plane_regs.h" #include "display/skl_watermark_regs.h" #include "display/vlv_dsi_pll_regs.h" diff --git a/drivers/gpu/drm/i915/soc/intel_pch.c b/drivers/gpu/drm/i915/soc/intel_pch.c deleted file mode 100644 index 82dc7fbd1a3e..000000000000 --- a/drivers/gpu/drm/i915/soc/intel_pch.c +++ /dev/null @@ -1,316 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * Copyright 2019 Intel Corporation. - */ - -#include "i915_drv.h" -#include "i915_utils.h" -#include "intel_pch.h" - -#define INTEL_PCH_DEVICE_ID_MASK 0xff80 -#define INTEL_PCH_IBX_DEVICE_ID_TYPE 0x3b00 -#define INTEL_PCH_CPT_DEVICE_ID_TYPE 0x1c00 -#define INTEL_PCH_PPT_DEVICE_ID_TYPE 0x1e00 -#define INTEL_PCH_LPT_DEVICE_ID_TYPE 0x8c00 -#define INTEL_PCH_LPT_LP_DEVICE_ID_TYPE 0x9c00 -#define INTEL_PCH_WPT_DEVICE_ID_TYPE 0x8c80 -#define INTEL_PCH_WPT_LP_DEVICE_ID_TYPE 0x9c80 -#define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100 -#define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00 -#define INTEL_PCH_KBP_DEVICE_ID_TYPE 0xA280 -#define INTEL_PCH_CNP_DEVICE_ID_TYPE 0xA300 -#define INTEL_PCH_CNP_LP_DEVICE_ID_TYPE 0x9D80 -#define INTEL_PCH_CMP_DEVICE_ID_TYPE 0x0280 -#define INTEL_PCH_CMP2_DEVICE_ID_TYPE 0x0680 -#define INTEL_PCH_CMP_V_DEVICE_ID_TYPE 0xA380 -#define INTEL_PCH_ICP_DEVICE_ID_TYPE 0x3480 -#define INTEL_PCH_ICP2_DEVICE_ID_TYPE 0x3880 -#define INTEL_PCH_MCC_DEVICE_ID_TYPE 0x4B00 -#define INTEL_PCH_TGP_DEVICE_ID_TYPE 0xA080 -#define INTEL_PCH_TGP2_DEVICE_ID_TYPE 0x4380 -#define INTEL_PCH_JSP_DEVICE_ID_TYPE 0x4D80 -#define INTEL_PCH_ADP_DEVICE_ID_TYPE 0x7A80 -#define INTEL_PCH_ADP2_DEVICE_ID_TYPE 0x5180 -#define INTEL_PCH_ADP3_DEVICE_ID_TYPE 0x7A00 -#define INTEL_PCH_ADP4_DEVICE_ID_TYPE 0x5480 -#define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100 -#define INTEL_PCH_P3X_DEVICE_ID_TYPE 0x7000 -#define INTEL_PCH_QEMU_DEVICE_ID_TYPE 0x2900 /* qemu q35 has 2918 */ - -/* Map PCH device id to PCH type, or PCH_NONE if unknown. */ -static enum intel_pch -intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id) -{ - switch (id) { - case INTEL_PCH_IBX_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found Ibex Peak PCH\n"); - drm_WARN_ON(&dev_priv->drm, GRAPHICS_VER(dev_priv) != 5); - return PCH_IBX; - case INTEL_PCH_CPT_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found CougarPoint PCH\n"); - drm_WARN_ON(&dev_priv->drm, - GRAPHICS_VER(dev_priv) != 6 && !IS_IVYBRIDGE(dev_priv)); - return PCH_CPT; - case INTEL_PCH_PPT_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found PantherPoint PCH\n"); - drm_WARN_ON(&dev_priv->drm, - GRAPHICS_VER(dev_priv) != 6 && !IS_IVYBRIDGE(dev_priv)); - /* PPT is CPT compatible */ - return PCH_CPT; - case INTEL_PCH_LPT_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found LynxPoint PCH\n"); - drm_WARN_ON(&dev_priv->drm, - !IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)); - drm_WARN_ON(&dev_priv->drm, - IS_HASWELL_ULT(dev_priv) || IS_BROADWELL_ULT(dev_priv)); - return PCH_LPT_H; - case INTEL_PCH_LPT_LP_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found LynxPoint LP PCH\n"); - drm_WARN_ON(&dev_priv->drm, - !IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)); - drm_WARN_ON(&dev_priv->drm, - !IS_HASWELL_ULT(dev_priv) && !IS_BROADWELL_ULT(dev_priv)); - return PCH_LPT_LP; - case INTEL_PCH_WPT_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found WildcatPoint PCH\n"); - drm_WARN_ON(&dev_priv->drm, - !IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)); - drm_WARN_ON(&dev_priv->drm, - IS_HASWELL_ULT(dev_priv) || IS_BROADWELL_ULT(dev_priv)); - /* WPT is LPT compatible */ - return PCH_LPT_H; - case INTEL_PCH_WPT_LP_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found WildcatPoint LP PCH\n"); - drm_WARN_ON(&dev_priv->drm, - !IS_HASWELL(dev_priv) && !IS_BROADWELL(dev_priv)); - drm_WARN_ON(&dev_priv->drm, - !IS_HASWELL_ULT(dev_priv) && !IS_BROADWELL_ULT(dev_priv)); - /* WPT is LPT compatible */ - return PCH_LPT_LP; - case INTEL_PCH_SPT_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found SunrisePoint PCH\n"); - drm_WARN_ON(&dev_priv->drm, - !IS_SKYLAKE(dev_priv) && !IS_KABYLAKE(dev_priv)); - return PCH_SPT; - case INTEL_PCH_SPT_LP_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found SunrisePoint LP PCH\n"); - drm_WARN_ON(&dev_priv->drm, - !IS_SKYLAKE(dev_priv) && - !IS_KABYLAKE(dev_priv) && - !IS_COFFEELAKE(dev_priv) && - !IS_COMETLAKE(dev_priv)); - return PCH_SPT; - case INTEL_PCH_KBP_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found Kaby Lake PCH (KBP)\n"); - drm_WARN_ON(&dev_priv->drm, - !IS_SKYLAKE(dev_priv) && - !IS_KABYLAKE(dev_priv) && - !IS_COFFEELAKE(dev_priv) && - !IS_COMETLAKE(dev_priv)); - /* KBP is SPT compatible */ - return PCH_SPT; - case INTEL_PCH_CNP_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found Cannon Lake PCH (CNP)\n"); - drm_WARN_ON(&dev_priv->drm, - !IS_COFFEELAKE(dev_priv) && - !IS_COMETLAKE(dev_priv)); - return PCH_CNP; - case INTEL_PCH_CNP_LP_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, - "Found Cannon Lake LP PCH (CNP-LP)\n"); - drm_WARN_ON(&dev_priv->drm, - !IS_COFFEELAKE(dev_priv) && - !IS_COMETLAKE(dev_priv)); - return PCH_CNP; - case INTEL_PCH_CMP_DEVICE_ID_TYPE: - case INTEL_PCH_CMP2_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found Comet Lake PCH (CMP)\n"); - drm_WARN_ON(&dev_priv->drm, - !IS_COFFEELAKE(dev_priv) && - !IS_COMETLAKE(dev_priv) && - !IS_ROCKETLAKE(dev_priv)); - /* CMP is CNP compatible */ - return PCH_CNP; - case INTEL_PCH_CMP_V_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found Comet Lake V PCH (CMP-V)\n"); - drm_WARN_ON(&dev_priv->drm, - !IS_COFFEELAKE(dev_priv) && - !IS_COMETLAKE(dev_priv)); - /* CMP-V is based on KBP, which is SPT compatible */ - return PCH_SPT; - case INTEL_PCH_ICP_DEVICE_ID_TYPE: - case INTEL_PCH_ICP2_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found Ice Lake PCH\n"); - drm_WARN_ON(&dev_priv->drm, !IS_ICELAKE(dev_priv)); - return PCH_ICP; - case INTEL_PCH_MCC_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found Mule Creek Canyon PCH\n"); - drm_WARN_ON(&dev_priv->drm, !(IS_JASPERLAKE(dev_priv) || - IS_ELKHARTLAKE(dev_priv))); - /* MCC is TGP compatible */ - return PCH_TGP; - case INTEL_PCH_TGP_DEVICE_ID_TYPE: - case INTEL_PCH_TGP2_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found Tiger Lake LP PCH\n"); - drm_WARN_ON(&dev_priv->drm, !IS_TIGERLAKE(dev_priv) && - !IS_ROCKETLAKE(dev_priv) && - !IS_SKYLAKE(dev_priv) && - !IS_KABYLAKE(dev_priv) && - !IS_COFFEELAKE(dev_priv) && - !IS_COMETLAKE(dev_priv)); - return PCH_TGP; - case INTEL_PCH_JSP_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found Jasper Lake PCH\n"); - drm_WARN_ON(&dev_priv->drm, !(IS_JASPERLAKE(dev_priv) || - IS_ELKHARTLAKE(dev_priv))); - /* JSP is ICP compatible */ - return PCH_ICP; - case INTEL_PCH_ADP_DEVICE_ID_TYPE: - case INTEL_PCH_ADP2_DEVICE_ID_TYPE: - case INTEL_PCH_ADP3_DEVICE_ID_TYPE: - case INTEL_PCH_ADP4_DEVICE_ID_TYPE: - drm_dbg_kms(&dev_priv->drm, "Found Alder Lake PCH\n"); - drm_WARN_ON(&dev_priv->drm, !IS_ALDERLAKE_S(dev_priv) && - !IS_ALDERLAKE_P(dev_priv)); - return PCH_ADP; - default: - return PCH_NONE; - } -} - -static bool intel_is_virt_pch(unsigned short id, - unsigned short svendor, unsigned short sdevice) -{ - return (id == INTEL_PCH_P2X_DEVICE_ID_TYPE || - id == INTEL_PCH_P3X_DEVICE_ID_TYPE || - (id == INTEL_PCH_QEMU_DEVICE_ID_TYPE && - svendor == PCI_SUBVENDOR_ID_REDHAT_QUMRANET && - sdevice == PCI_SUBDEVICE_ID_QEMU)); -} - -static void -intel_virt_detect_pch(const struct drm_i915_private *dev_priv, - unsigned short *pch_id, enum intel_pch *pch_type) -{ - unsigned short id = 0; - - /* - * In a virtualized passthrough environment we can be in a - * setup where the ISA bridge is not able to be passed through. - * In this case, a south bridge can be emulated and we have to - * make an educated guess as to which PCH is really there. - */ - - if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv)) - id = INTEL_PCH_ADP_DEVICE_ID_TYPE; - else if (IS_TIGERLAKE(dev_priv) || IS_ROCKETLAKE(dev_priv)) - id = INTEL_PCH_TGP_DEVICE_ID_TYPE; - else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) - id = INTEL_PCH_MCC_DEVICE_ID_TYPE; - else if (IS_ICELAKE(dev_priv)) - id = INTEL_PCH_ICP_DEVICE_ID_TYPE; - else if (IS_COFFEELAKE(dev_priv) || - IS_COMETLAKE(dev_priv)) - id = INTEL_PCH_CNP_DEVICE_ID_TYPE; - else if (IS_KABYLAKE(dev_priv) || IS_SKYLAKE(dev_priv)) - id = INTEL_PCH_SPT_DEVICE_ID_TYPE; - else if (IS_HASWELL_ULT(dev_priv) || IS_BROADWELL_ULT(dev_priv)) - id = INTEL_PCH_LPT_LP_DEVICE_ID_TYPE; - else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) - id = INTEL_PCH_LPT_DEVICE_ID_TYPE; - else if (GRAPHICS_VER(dev_priv) == 6 || IS_IVYBRIDGE(dev_priv)) - id = INTEL_PCH_CPT_DEVICE_ID_TYPE; - else if (GRAPHICS_VER(dev_priv) == 5) - id = INTEL_PCH_IBX_DEVICE_ID_TYPE; - - if (id) - drm_dbg_kms(&dev_priv->drm, "Assuming PCH ID %04x\n", id); - else - drm_dbg_kms(&dev_priv->drm, "Assuming no PCH\n"); - - *pch_type = intel_pch_type(dev_priv, id); - - /* Sanity check virtual PCH id */ - if (drm_WARN_ON(&dev_priv->drm, - id && *pch_type == PCH_NONE)) - id = 0; - - *pch_id = id; -} - -void intel_detect_pch(struct drm_i915_private *dev_priv) -{ - struct pci_dev *pch = NULL; - unsigned short id; - enum intel_pch pch_type; - - /* - * South display engine on the same PCI device: just assign the fake - * PCH. - */ - if (DISPLAY_VER(dev_priv) >= 20) { - dev_priv->pch_type = PCH_LNL; - return; - } else if (IS_BATTLEMAGE(dev_priv) || IS_METEORLAKE(dev_priv)) { - /* - * Both north display and south display are on the SoC die. - * The real PCH (if it even exists) is uninvolved in display. - */ - dev_priv->pch_type = PCH_MTL; - return; - } else if (IS_DG2(dev_priv)) { - dev_priv->pch_type = PCH_DG2; - return; - } else if (IS_DG1(dev_priv)) { - dev_priv->pch_type = PCH_DG1; - return; - } - - /* - * The reason to probe ISA bridge instead of Dev31:Fun0 is to - * make graphics device passthrough work easy for VMM, that only - * need to expose ISA bridge to let driver know the real hardware - * underneath. This is a requirement from virtualization team. - * - * In some virtualized environments (e.g. XEN), there is irrelevant - * ISA bridge in the system. To work reliably, we should scan through - * all the ISA bridge devices and check for the first match, instead - * of only checking the first one. - */ - while ((pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, pch))) { - if (pch->vendor != PCI_VENDOR_ID_INTEL) - continue; - - id = pch->device & INTEL_PCH_DEVICE_ID_MASK; - - pch_type = intel_pch_type(dev_priv, id); - if (pch_type != PCH_NONE) { - dev_priv->pch_type = pch_type; - break; - } else if (intel_is_virt_pch(id, pch->subsystem_vendor, - pch->subsystem_device)) { - intel_virt_detect_pch(dev_priv, &id, &pch_type); - dev_priv->pch_type = pch_type; - break; - } - } - - /* - * Use PCH_NOP (PCH but no South Display) for PCH platforms without - * display. - */ - if (pch && !HAS_DISPLAY(dev_priv)) { - drm_dbg_kms(&dev_priv->drm, - "Display disabled, reverting to NOP PCH\n"); - dev_priv->pch_type = PCH_NOP; - } else if (!pch) { - if (i915_run_as_guest() && HAS_DISPLAY(dev_priv)) { - intel_virt_detect_pch(dev_priv, &id, &pch_type); - dev_priv->pch_type = pch_type; - } else { - drm_dbg_kms(&dev_priv->drm, "No PCH found.\n"); - } - } - - pci_dev_put(pch); -} diff --git a/drivers/gpu/drm/i915/soc/intel_pch.h b/drivers/gpu/drm/i915/soc/intel_pch.h deleted file mode 100644 index 635aea7a5539..000000000000 --- a/drivers/gpu/drm/i915/soc/intel_pch.h +++ /dev/null @@ -1,56 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright 2019 Intel Corporation. - */ - -#ifndef __INTEL_PCH__ -#define __INTEL_PCH__ - -struct drm_i915_private; - -/* - * Sorted by south display engine compatibility. - * If the new PCH comes with a south display engine that is not - * inherited from the latest item, please do not add it to the - * end. Instead, add it right after its "parent" PCH. - */ -enum intel_pch { - PCH_NOP = -1, /* PCH without south display */ - PCH_NONE = 0, /* No PCH present */ - PCH_IBX, /* Ibexpeak PCH */ - PCH_CPT, /* Cougarpoint/Pantherpoint PCH */ - PCH_LPT_H, /* Lynxpoint/Wildcatpoint H PCH */ - PCH_LPT_LP, /* Lynxpoint/Wildcatpoint LP PCH */ - PCH_SPT, /* Sunrisepoint/Kaby Lake PCH */ - PCH_CNP, /* Cannon/Comet Lake PCH */ - PCH_ICP, /* Ice Lake/Jasper Lake PCH */ - PCH_TGP, /* Tiger Lake/Mule Creek Canyon PCH */ - PCH_ADP, /* Alder Lake PCH */ - - /* Fake PCHs, functionality handled on the same PCI dev */ - PCH_DG1 = 1024, - PCH_DG2, - PCH_MTL, - PCH_LNL, -}; - -#define INTEL_PCH_TYPE(dev_priv) ((dev_priv)->pch_type) -#define HAS_PCH_DG2(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_DG2) -#define HAS_PCH_ADP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_ADP) -#define HAS_PCH_DG1(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_DG1) -#define HAS_PCH_TGP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_TGP) -#define HAS_PCH_ICP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_ICP) -#define HAS_PCH_CNP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_CNP) -#define HAS_PCH_SPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_SPT) -#define HAS_PCH_LPT_H(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_LPT_H) -#define HAS_PCH_LPT_LP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_LPT_LP) -#define HAS_PCH_LPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_LPT_H || \ - INTEL_PCH_TYPE(dev_priv) == PCH_LPT_LP) -#define HAS_PCH_CPT(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_CPT) -#define HAS_PCH_IBX(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_IBX) -#define HAS_PCH_NOP(dev_priv) (INTEL_PCH_TYPE(dev_priv) == PCH_NOP) -#define HAS_PCH_SPLIT(dev_priv) (INTEL_PCH_TYPE(dev_priv) != PCH_NONE) - -void intel_detect_pch(struct drm_i915_private *dev_priv); - -#endif /* __INTEL_PCH__ */ diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index c5d6681645ed..e4bf484d4121 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -187,7 +187,6 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ display/xe_display.o \ display/xe_display_misc.o \ display/xe_display_rpm.o \ - display/xe_display_rps.o \ display/xe_display_wa.o \ display/xe_dsb_buffer.o \ display/xe_fb_pin.o \ @@ -198,7 +197,6 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ # SOC code shared with i915 xe-$(CONFIG_DRM_XE_DISPLAY) += \ i915-soc/intel_dram.o \ - i915-soc/intel_pch.o \ i915-soc/intel_rom.o # Display code shared with i915 @@ -273,6 +271,7 @@ xe-$(CONFIG_DRM_XE_DISPLAY) += \ i915-display/intel_panel.o \ i915-display/intel_pfit.o \ i915-display/intel_pmdemand.o \ + i915-display/intel_pch.o \ i915-display/intel_pps.o \ i915-display/intel_psr.o \ i915-display/intel_qp_tables.o \ diff --git a/drivers/gpu/drm/xe/compat-i915-headers/gt/intel_rps.h b/drivers/gpu/drm/xe/compat-i915-headers/gt/intel_rps.h deleted file mode 100644 index 21fec9cc837c..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/gt/intel_rps.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023 Intel Corporation - */ - -#ifndef __INTEL_RPS_H__ -#define __INTEL_RPS_H__ - -#define gen5_rps_irq_handler(x) ({}) - -#endif /* __INTEL_RPS_H__ */ diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h index f89bd5e3520d..9b7572e06f34 100644 --- a/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h +++ b/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h @@ -21,28 +21,12 @@ static inline struct drm_i915_private *to_i915(const struct drm_device *dev) return container_of(dev, struct drm_i915_private, drm); } +/* compat platform checks only for soc/ usage */ #define IS_PLATFORM(xe, x) ((xe)->info.platform == x) -#define INTEL_INFO(dev_priv) (&((dev_priv)->info)) -#define IS_I830(dev_priv) (dev_priv && 0) -#define IS_I845G(dev_priv) (dev_priv && 0) -#define IS_I85X(dev_priv) (dev_priv && 0) -#define IS_I865G(dev_priv) (dev_priv && 0) #define IS_I915G(dev_priv) (dev_priv && 0) #define IS_I915GM(dev_priv) (dev_priv && 0) -#define IS_I945G(dev_priv) (dev_priv && 0) -#define IS_I945GM(dev_priv) (dev_priv && 0) -#define IS_I965G(dev_priv) (dev_priv && 0) -#define IS_I965GM(dev_priv) (dev_priv && 0) -#define IS_G45(dev_priv) (dev_priv && 0) -#define IS_GM45(dev_priv) (dev_priv && 0) -#define IS_G4X(dev_priv) (dev_priv && 0) #define IS_PINEVIEW(dev_priv) (dev_priv && 0) -#define IS_G33(dev_priv) (dev_priv && 0) -#define IS_IRONLAKE(dev_priv) (dev_priv && 0) -#define IS_IRONLAKE_M(dev_priv) (dev_priv && 0) -#define IS_SANDYBRIDGE(dev_priv) (dev_priv && 0) #define IS_IVYBRIDGE(dev_priv) (dev_priv && 0) -#define IS_IVB_GT1(dev_priv) (dev_priv && 0) #define IS_VALLEYVIEW(dev_priv) (dev_priv && 0) #define IS_CHERRYVIEW(dev_priv) (dev_priv && 0) #define IS_HASWELL(dev_priv) (dev_priv && 0) @@ -70,39 +54,10 @@ static inline struct drm_i915_private *to_i915(const struct drm_device *dev) #define IS_HASWELL_ULT(dev_priv) (dev_priv && 0) #define IS_BROADWELL_ULT(dev_priv) (dev_priv && 0) -#define IS_BROADWELL_ULX(dev_priv) (dev_priv && 0) #define IS_MOBILE(xe) (xe && 0) -#define IS_TIGERLAKE_UY(xe) (xe && 0) -#define IS_COMETLAKE_ULX(xe) (xe && 0) -#define IS_COFFEELAKE_ULX(xe) (xe && 0) -#define IS_KABYLAKE_ULX(xe) (xe && 0) -#define IS_SKYLAKE_ULX(xe) (xe && 0) -#define IS_HASWELL_ULX(xe) (xe && 0) -#define IS_COMETLAKE_ULT(xe) (xe && 0) -#define IS_COFFEELAKE_ULT(xe) (xe && 0) -#define IS_KABYLAKE_ULT(xe) (xe && 0) -#define IS_SKYLAKE_ULT(xe) (xe && 0) - -#define IS_DG2_G10(xe) ((xe)->info.subplatform == XE_SUBPLATFORM_DG2_G10) -#define IS_DG2_G11(xe) ((xe)->info.subplatform == XE_SUBPLATFORM_DG2_G11) -#define IS_DG2_G12(xe) ((xe)->info.subplatform == XE_SUBPLATFORM_DG2_G12) -#define IS_RAPTORLAKE_U(xe) ((xe)->info.subplatform == XE_SUBPLATFORM_ALDERLAKE_P_RPLU) -#define IS_ICL_WITH_PORT_F(xe) (xe && 0) #define HAS_FLAT_CCS(xe) (xe_device_has_flat_ccs(xe)) - #define HAS_128_BYTE_Y_TILING(xe) (xe || 1) -#ifdef CONFIG_ARM64 -/* - * arm64 indirectly includes linux/rtc.h, - * which defines a irq_lock, so include it - * here before #define-ing it - */ -#include <linux/rtc.h> -#endif - -#define irq_lock irq.lock - #endif diff --git a/drivers/gpu/drm/xe/compat-i915-headers/soc/intel_pch.h b/drivers/gpu/drm/xe/compat-i915-headers/soc/intel_pch.h deleted file mode 100644 index 9c46556d33a4..000000000000 --- a/drivers/gpu/drm/xe/compat-i915-headers/soc/intel_pch.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2023 Intel Corporation - */ - -#include "../../../i915/soc/intel_pch.h" diff --git a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c index 267f31697343..e8191562d122 100644 --- a/drivers/gpu/drm/xe/display/intel_fbdev_fb.c +++ b/drivers/gpu/drm/xe/display/intel_fbdev_fb.c @@ -79,11 +79,11 @@ err: return ERR_CAST(fb); } -int intel_fbdev_fb_fill_info(struct drm_i915_private *i915, struct fb_info *info, - struct drm_gem_object *_obj, struct i915_vma *vma) +int intel_fbdev_fb_fill_info(struct intel_display *display, struct fb_info *info, + struct drm_gem_object *_obj, struct i915_vma *vma) { struct xe_bo *obj = gem_to_xe_bo(_obj); - struct pci_dev *pdev = to_pci_dev(i915->drm.dev); + struct pci_dev *pdev = to_pci_dev(display->drm->dev); if (!(obj->flags & XE_BO_FLAG_SYSTEM)) { if (obj->flags & XE_BO_FLAG_STOLEN) diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 20c3bcd953b7..68f064f33d4b 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -133,9 +133,6 @@ int xe_display_init_early(struct xe_device *xe) /* Fake uncore lock */ spin_lock_init(&xe->uncore.lock); - /* This must be called before any calls to HAS_PCH_* */ - intel_detect_pch(xe); - intel_display_driver_early_probe(display); /* Early display init.. */ diff --git a/drivers/gpu/drm/xe/display/xe_display_rps.c b/drivers/gpu/drm/xe/display/xe_display_rps.c deleted file mode 100644 index fa616f9688a5..000000000000 --- a/drivers/gpu/drm/xe/display/xe_display_rps.c +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * Copyright © 2023 Intel Corporation - */ - -#include "intel_display_rps.h" - -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) -{ -} diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c index 7c02323e9531..b35a6f201d4a 100644 --- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c +++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c @@ -9,7 +9,6 @@ #include "abi/gsc_command_header_abi.h" #include "intel_hdcp_gsc.h" -#include "intel_hdcp_gsc_message.h" #include "xe_bo.h" #include "xe_device.h" #include "xe_device_types.h" @@ -22,7 +21,8 @@ #define HECI_MEADDRESS_HDCP 18 -struct intel_hdcp_gsc_message { +struct intel_hdcp_gsc_context { + struct xe_device *xe; struct xe_bo *hdcp_bo; u64 hdcp_cmd_in; u64 hdcp_cmd_out; @@ -30,14 +30,9 @@ struct intel_hdcp_gsc_message { #define HDCP_GSC_HEADER_SIZE sizeof(struct intel_gsc_mtl_header) -bool intel_hdcp_gsc_cs_required(struct intel_display *display) +bool intel_hdcp_gsc_check_status(struct drm_device *drm) { - return DISPLAY_VER(display) >= 14; -} - -bool intel_hdcp_gsc_check_status(struct intel_display *display) -{ - struct xe_device *xe = to_xe_device(display->drm); + struct xe_device *xe = to_xe_device(drm); struct xe_tile *tile = xe_device_get_root_tile(xe); struct xe_gt *gt = tile->media_gt; struct xe_gsc *gsc = >->uc.gsc; @@ -69,10 +64,9 @@ out: } /*This function helps allocate memory for the command that we will send to gsc cs */ -static int intel_hdcp_gsc_initialize_message(struct intel_display *display, - struct intel_hdcp_gsc_message *hdcp_message) +static int intel_hdcp_gsc_initialize_message(struct xe_device *xe, + struct intel_hdcp_gsc_context *gsc_context) { - struct xe_device *xe = to_xe_device(display->drm); struct xe_bo *bo = NULL; u64 cmd_in, cmd_out; int ret = 0; @@ -84,7 +78,7 @@ static int intel_hdcp_gsc_initialize_message(struct intel_display *display, XE_BO_FLAG_GGTT); if (IS_ERR(bo)) { - drm_err(display->drm, "Failed to allocate bo for HDCP streaming command!\n"); + drm_err(&xe->drm, "Failed to allocate bo for HDCP streaming command!\n"); ret = PTR_ERR(bo); goto out; } @@ -93,104 +87,60 @@ static int intel_hdcp_gsc_initialize_message(struct intel_display *display, cmd_out = cmd_in + PAGE_SIZE; xe_map_memset(xe, &bo->vmap, 0, 0, bo->size); - hdcp_message->hdcp_bo = bo; - hdcp_message->hdcp_cmd_in = cmd_in; - hdcp_message->hdcp_cmd_out = cmd_out; + gsc_context->hdcp_bo = bo; + gsc_context->hdcp_cmd_in = cmd_in; + gsc_context->hdcp_cmd_out = cmd_out; + gsc_context->xe = xe; + out: return ret; } -static int intel_hdcp_gsc_hdcp2_init(struct intel_display *display) +struct intel_hdcp_gsc_context *intel_hdcp_gsc_context_alloc(struct drm_device *drm) { - struct intel_hdcp_gsc_message *hdcp_message; + struct xe_device *xe = to_xe_device(drm); + struct intel_hdcp_gsc_context *gsc_context; int ret; - hdcp_message = kzalloc(sizeof(*hdcp_message), GFP_KERNEL); - - if (!hdcp_message) - return -ENOMEM; + gsc_context = kzalloc(sizeof(*gsc_context), GFP_KERNEL); + if (!gsc_context) + return ERR_PTR(-ENOMEM); /* * NOTE: No need to lock the comp mutex here as it is already * going to be taken before this function called */ - ret = intel_hdcp_gsc_initialize_message(display, hdcp_message); + ret = intel_hdcp_gsc_initialize_message(xe, gsc_context); if (ret) { - drm_err(display->drm, "Could not initialize hdcp_message\n"); - kfree(hdcp_message); - return ret; + drm_err(&xe->drm, "Could not initialize gsc_context\n"); + kfree(gsc_context); + gsc_context = ERR_PTR(ret); } - display->hdcp.hdcp_message = hdcp_message; - return ret; -} - -static const struct i915_hdcp_ops gsc_hdcp_ops = { - .initiate_hdcp2_session = intel_hdcp_gsc_initiate_session, - .verify_receiver_cert_prepare_km = - intel_hdcp_gsc_verify_receiver_cert_prepare_km, - .verify_hprime = intel_hdcp_gsc_verify_hprime, - .store_pairing_info = intel_hdcp_gsc_store_pairing_info, - .initiate_locality_check = intel_hdcp_gsc_initiate_locality_check, - .verify_lprime = intel_hdcp_gsc_verify_lprime, - .get_session_key = intel_hdcp_gsc_get_session_key, - .repeater_check_flow_prepare_ack = - intel_hdcp_gsc_repeater_check_flow_prepare_ack, - .verify_mprime = intel_hdcp_gsc_verify_mprime, - .enable_hdcp_authentication = intel_hdcp_gsc_enable_authentication, - .close_hdcp_session = intel_hdcp_gsc_close_session, -}; - -int intel_hdcp_gsc_init(struct intel_display *display) -{ - struct i915_hdcp_arbiter *data; - int ret; - - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - mutex_lock(&display->hdcp.hdcp_mutex); - display->hdcp.arbiter = data; - display->hdcp.arbiter->hdcp_dev = display->drm->dev; - display->hdcp.arbiter->ops = &gsc_hdcp_ops; - ret = intel_hdcp_gsc_hdcp2_init(display); - if (ret) - kfree(data); - - mutex_unlock(&display->hdcp.hdcp_mutex); - - return ret; + return gsc_context; } -void intel_hdcp_gsc_fini(struct intel_display *display) +void intel_hdcp_gsc_context_free(struct intel_hdcp_gsc_context *gsc_context) { - struct intel_hdcp_gsc_message *hdcp_message = - display->hdcp.hdcp_message; - struct i915_hdcp_arbiter *arb = display->hdcp.arbiter; - - if (hdcp_message) { - xe_bo_unpin_map_no_vm(hdcp_message->hdcp_bo); - kfree(hdcp_message); - display->hdcp.hdcp_message = NULL; - } + if (!gsc_context) + return; - kfree(arb); - display->hdcp.arbiter = NULL; + xe_bo_unpin_map_no_vm(gsc_context->hdcp_bo); + kfree(gsc_context); } static int xe_gsc_send_sync(struct xe_device *xe, - struct intel_hdcp_gsc_message *hdcp_message, + struct intel_hdcp_gsc_context *gsc_context, u32 msg_size_in, u32 msg_size_out, u32 addr_out_off) { - struct xe_gt *gt = hdcp_message->hdcp_bo->tile->media_gt; - struct iosys_map *map = &hdcp_message->hdcp_bo->vmap; + struct xe_gt *gt = gsc_context->hdcp_bo->tile->media_gt; + struct iosys_map *map = &gsc_context->hdcp_bo->vmap; struct xe_gsc *gsc = >->uc.gsc; int ret; - ret = xe_gsc_pkt_submit_kernel(gsc, hdcp_message->hdcp_cmd_in, msg_size_in, - hdcp_message->hdcp_cmd_out, msg_size_out); + ret = xe_gsc_pkt_submit_kernel(gsc, gsc_context->hdcp_cmd_in, msg_size_in, + gsc_context->hdcp_cmd_out, msg_size_out); if (ret) { drm_err(&xe->drm, "failed to send gsc HDCP msg (%d)\n", ret); return ret; @@ -205,12 +155,12 @@ static int xe_gsc_send_sync(struct xe_device *xe, return ret; } -ssize_t intel_hdcp_gsc_msg_send(struct xe_device *xe, u8 *msg_in, - size_t msg_in_len, u8 *msg_out, - size_t msg_out_len) +ssize_t intel_hdcp_gsc_msg_send(struct intel_hdcp_gsc_context *gsc_context, + void *msg_in, size_t msg_in_len, + void *msg_out, size_t msg_out_len) { + struct xe_device *xe = gsc_context->xe; const size_t max_msg_size = PAGE_SIZE - HDCP_GSC_HEADER_SIZE; - struct intel_hdcp_gsc_message *hdcp_message; u64 host_session_id; u32 msg_size_in, msg_size_out; u32 addr_out_off, addr_in_wr_off = 0; @@ -223,15 +173,14 @@ ssize_t intel_hdcp_gsc_msg_send(struct xe_device *xe, u8 *msg_in, msg_size_in = msg_in_len + HDCP_GSC_HEADER_SIZE; msg_size_out = msg_out_len + HDCP_GSC_HEADER_SIZE; - hdcp_message = xe->display.hdcp.hdcp_message; addr_out_off = PAGE_SIZE; host_session_id = xe_gsc_create_host_session_id(); xe_pm_runtime_get_noresume(xe); - addr_in_wr_off = xe_gsc_emit_header(xe, &hdcp_message->hdcp_bo->vmap, + addr_in_wr_off = xe_gsc_emit_header(xe, &gsc_context->hdcp_bo->vmap, addr_in_wr_off, HECI_MEADDRESS_HDCP, host_session_id, msg_in_len); - xe_map_memcpy_to(xe, &hdcp_message->hdcp_bo->vmap, addr_in_wr_off, + xe_map_memcpy_to(xe, &gsc_context->hdcp_bo->vmap, addr_in_wr_off, msg_in, msg_in_len); /* * Keep sending request in case the pending bit is set no need to add @@ -240,7 +189,7 @@ ssize_t intel_hdcp_gsc_msg_send(struct xe_device *xe, u8 *msg_in, * 20 times each message 50 ms apart */ do { - ret = xe_gsc_send_sync(xe, hdcp_message, msg_size_in, msg_size_out, + ret = xe_gsc_send_sync(xe, gsc_context, msg_size_in, msg_size_out, addr_out_off); /* Only try again if gsc says so */ @@ -254,7 +203,7 @@ ssize_t intel_hdcp_gsc_msg_send(struct xe_device *xe, u8 *msg_in, if (ret) goto out; - xe_map_memcpy_from(xe, msg_out, &hdcp_message->hdcp_bo->vmap, + xe_map_memcpy_from(xe, msg_out, &gsc_context->hdcp_bo->vmap, addr_out_off + HDCP_GSC_HEADER_SIZE, msg_out_len); diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index 495bc00ebed4..06c65dace026 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -31,7 +31,6 @@ #endif #if IS_ENABLED(CONFIG_DRM_XE_DISPLAY) -#include "soc/intel_pch.h" #include "intel_display_core.h" #include "intel_display_device.h" #endif @@ -589,7 +588,6 @@ struct xe_device { * migrating to the right sub-structs */ struct intel_display display; - enum intel_pch pch_type; struct dram_info { bool wm_lv_0_adjust_needed; diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index d9614e2c8939..7b19192c7031 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -971,5 +971,7 @@ int drm_dp_bw_channel_coding_efficiency(bool is_uhbr); int drm_dp_max_dprx_data_rate(int max_link_rate, int max_lanes); ssize_t drm_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc, struct dp_sdp *sdp); +int drm_dp_link_symbol_cycles(int lane_count, int pixels, int dsc_slice_count, + int bpp_x16, int symbol_size, bool is_mst); #endif /* _DRM_DP_HELPER_H_ */ |