diff options
Diffstat (limited to 'drivers/gpu/drm/i915')
222 files changed, 7983 insertions, 6799 deletions
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index ed05b131ed3a..e153686256c9 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 @@ -247,6 +246,7 @@ i915-y += \ display/intel_display_power_map.o \ display/intel_display_power_well.o \ display/intel_display_reset.o \ + display/intel_display_rpm.o \ display/intel_display_rps.o \ display/intel_display_snapshot.o \ display/intel_display_wa.o \ @@ -281,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 \ @@ -408,7 +409,7 @@ obj-$(CONFIG_DRM_I915_GVT_KVMGT) += kvmgt.o # # Enable locally for CONFIG_DRM_I915_WERROR=y. See also scripts/Makefile.build ifdef CONFIG_DRM_I915_WERROR - cmd_checkdoc = $(srctree)/scripts/kernel-doc -none -Werror $< + cmd_checkdoc = PYTHONDONTWRITEBYTECODE=1 $(KERNELDOC) -none -Werror $< endif # header test diff --git a/drivers/gpu/drm/i915/display/dvo_ch7017.c b/drivers/gpu/drm/i915/display/dvo_ch7017.c index 206818f9ad49..f10c0fb8d2c8 100644 --- a/drivers/gpu/drm/i915/display/dvo_ch7017.c +++ b/drivers/gpu/drm/i915/display/dvo_ch7017.c @@ -25,6 +25,8 @@ * */ +#include <drm/drm_print.h> + #include "intel_display_types.h" #include "intel_dvo_dev.h" diff --git a/drivers/gpu/drm/i915/display/dvo_ch7xxx.c b/drivers/gpu/drm/i915/display/dvo_ch7xxx.c index 10ab3cc73e58..49f02aca818b 100644 --- a/drivers/gpu/drm/i915/display/dvo_ch7xxx.c +++ b/drivers/gpu/drm/i915/display/dvo_ch7xxx.c @@ -26,6 +26,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +#include <drm/drm_print.h> + #include "intel_display_types.h" #include "intel_dvo_dev.h" diff --git a/drivers/gpu/drm/i915/display/dvo_ivch.c b/drivers/gpu/drm/i915/display/dvo_ivch.c index d9c3152d4338..0713b2709412 100644 --- a/drivers/gpu/drm/i915/display/dvo_ivch.c +++ b/drivers/gpu/drm/i915/display/dvo_ivch.c @@ -29,6 +29,8 @@ * */ +#include <drm/drm_print.h> + #include "intel_display_types.h" #include "intel_dvo_dev.h" diff --git a/drivers/gpu/drm/i915/display/dvo_ns2501.c b/drivers/gpu/drm/i915/display/dvo_ns2501.c index 92d32d6b5bce..80b71bd6a837 100644 --- a/drivers/gpu/drm/i915/display/dvo_ns2501.c +++ b/drivers/gpu/drm/i915/display/dvo_ns2501.c @@ -26,6 +26,8 @@ * */ +#include <drm/drm_print.h> + #include "intel_display_types.h" #include "intel_dvo_dev.h" diff --git a/drivers/gpu/drm/i915/display/dvo_sil164.c b/drivers/gpu/drm/i915/display/dvo_sil164.c index b42c717085f3..017b617a8069 100644 --- a/drivers/gpu/drm/i915/display/dvo_sil164.c +++ b/drivers/gpu/drm/i915/display/dvo_sil164.c @@ -26,6 +26,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ +#include <drm/drm_print.h> + #include "intel_display_types.h" #include "intel_dvo_dev.h" diff --git a/drivers/gpu/drm/i915/display/dvo_tfp410.c b/drivers/gpu/drm/i915/display/dvo_tfp410.c index 280699438526..ed560e3438db 100644 --- a/drivers/gpu/drm/i915/display/dvo_tfp410.c +++ b/drivers/gpu/drm/i915/display/dvo_tfp410.c @@ -25,6 +25,8 @@ * */ +#include <drm/drm_print.h> + #include "intel_display_types.h" #include "intel_dvo_dev.h" diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c index 55b9e9bfcc4d..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. @@ -519,7 +514,7 @@ static void intel_disable_dp(struct intel_atomic_state *state, { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - intel_dp->link_trained = false; + intel_dp->link.active = false; /* * Make sure the panel is off before trying to change the mode. @@ -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/hsw_ips.c b/drivers/gpu/drm/i915/display/hsw_ips.c index 674a0e5f0858..4307e2ed03d9 100644 --- a/drivers/gpu/drm/i915/display/hsw_ips.c +++ b/drivers/gpu/drm/i915/display/hsw_ips.c @@ -10,6 +10,7 @@ #include "i915_reg.h" #include "intel_color_regs.h" #include "intel_de.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_pcode.h" @@ -344,10 +345,9 @@ static int hsw_ips_debugfs_status_show(struct seq_file *m, void *unused) { struct intel_crtc *crtc = m->private; struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); + wakeref = intel_display_rpm_get(display); seq_printf(m, "Enabled by kernel parameter: %s\n", str_yes_no(display->params.enable_ips)); @@ -361,7 +361,7 @@ static int hsw_ips_debugfs_status_show(struct seq_file *m, void *unused) seq_puts(m, "Currently: disabled\n"); } - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); return 0; } diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 013295f66d56..a2a6d52be0a5 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" @@ -630,85 +631,85 @@ vlv_primary_async_flip(struct intel_dsb *dsb, static void bdw_primary_enable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; - spin_lock_irq(&i915->irq_lock); - bdw_enable_pipe_irq(i915, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); - spin_unlock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); + bdw_enable_pipe_irq(display, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); + spin_unlock_irq(&display->irq.lock); } static void bdw_primary_disable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; - spin_lock_irq(&i915->irq_lock); - bdw_disable_pipe_irq(i915, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); - spin_unlock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); + bdw_disable_pipe_irq(display, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); + spin_unlock_irq(&display->irq.lock); } static void ivb_primary_enable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); - spin_lock_irq(&i915->irq_lock); - ilk_enable_display_irq(i915, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane)); - spin_unlock_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(&display->irq.lock); } static void ivb_primary_disable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); - spin_lock_irq(&i915->irq_lock); - ilk_disable_display_irq(i915, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane)); - spin_unlock_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(&display->irq.lock); } static void ilk_primary_enable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); - spin_lock_irq(&i915->irq_lock); - ilk_enable_display_irq(i915, DE_PLANE_FLIP_DONE(plane->i9xx_plane)); - spin_unlock_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(&display->irq.lock); } static void ilk_primary_disable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); - spin_lock_irq(&i915->irq_lock); - ilk_disable_display_irq(i915, DE_PLANE_FLIP_DONE(plane->i9xx_plane)); - spin_unlock_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(&display->irq.lock); } static void vlv_primary_enable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; - spin_lock_irq(&i915->irq_lock); - i915_enable_pipestat(i915, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); - spin_unlock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); + i915_enable_pipestat(display, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); + spin_unlock_irq(&display->irq.lock); } static void vlv_primary_disable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; - spin_lock_irq(&i915->irq_lock); - i915_disable_pipestat(i915, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); - spin_unlock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); + i915_disable_pipestat(display, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); + spin_unlock_irq(&display->irq.lock); } static bool i9xx_plane_can_async_flip(u64 modifier) @@ -820,7 +821,7 @@ unsigned int vlv_plane_min_alignment(struct intel_plane *plane, { struct intel_display *display = to_intel_display(plane); - if (intel_plane_can_async_flip(plane, fb->modifier)) + if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier)) return 256 * 1024; /* FIXME undocumented so not sure what's actually needed */ @@ -844,7 +845,7 @@ static unsigned int g4x_primary_min_alignment(struct intel_plane *plane, { struct intel_display *display = to_intel_display(plane); - if (intel_plane_can_async_flip(plane, fb->modifier)) + if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier)) return 256 * 1024; if (intel_scanout_needs_vtd_wa(display)) @@ -889,6 +890,7 @@ static const struct drm_plane_funcs i965_plane_funcs = { .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = i965_plane_format_mod_supported, + .format_mod_supported_async = intel_plane_format_mod_supported_async, }; static const struct drm_plane_funcs i8xx_plane_funcs = { @@ -898,6 +900,7 @@ static const struct drm_plane_funcs i8xx_plane_funcs = { .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = i8xx_plane_format_mod_supported, + .format_mod_supported_async = intel_plane_format_mod_supported_async, }; struct intel_plane * diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.c b/drivers/gpu/drm/i915/display/i9xx_wm.c index 7c80e37c1c5f..77876ef735b7 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.c +++ b/drivers/gpu/drm/i915/display/i9xx_wm.c @@ -9,6 +9,7 @@ #include "i9xx_wm_regs.h" #include "intel_atomic.h" #include "intel_bo.h" +#include "intel_de.h" #include "intel_display.h" #include "intel_display_trace.h" #include "intel_fb.h" @@ -81,13 +82,14 @@ static const struct cxsr_latency cxsr_latency_table[] = { {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ }; -static const struct cxsr_latency *pnv_get_cxsr_latency(struct drm_i915_private *i915) +static const struct cxsr_latency *pnv_get_cxsr_latency(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); int i; for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) { const struct cxsr_latency *latency = &cxsr_latency_table[i]; - bool is_desktop = !IS_MOBILE(i915); + bool is_desktop = !display->platform.mobile; if (is_desktop == latency->is_desktop && i915->is_ddr3 == latency->is_ddr3 && @@ -96,15 +98,16 @@ static const struct cxsr_latency *pnv_get_cxsr_latency(struct drm_i915_private * return latency; } - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Could not find CxSR latency for DDR%s, FSB %u kHz, MEM %u kHz\n", i915->is_ddr3 ? "3" : "2", i915->fsb_freq, i915->mem_freq); return NULL; } -static void chv_set_memory_dvfs(struct drm_i915_private *dev_priv, bool enable) +static void chv_set_memory_dvfs(struct intel_display *display, bool enable) { + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 val; vlv_punit_get(dev_priv); @@ -120,14 +123,15 @@ static void chv_set_memory_dvfs(struct drm_i915_private *dev_priv, bool enable) if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2) & FORCE_DDR_FREQ_REQ_ACK) == 0, 3)) - drm_err(&dev_priv->drm, + drm_err(display->drm, "timed out waiting for Punit DDR DVFS request\n"); vlv_punit_put(dev_priv); } -static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable) +static void chv_set_memory_pm5(struct intel_display *display, bool enable) { + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 val; vlv_punit_get(dev_priv); @@ -145,53 +149,52 @@ static void chv_set_memory_pm5(struct drm_i915_private *dev_priv, bool enable) #define FW_WM(value, plane) \ (((value) << DSPFW_ ## plane ## _SHIFT) & DSPFW_ ## plane ## _MASK) -static bool _intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable) +static bool _intel_set_memory_cxsr(struct intel_display *display, bool enable) { - struct intel_display *display = &dev_priv->display; bool was_enabled; u32 val; - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { - was_enabled = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; - intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF_VLV, enable ? FW_CSPWRDWNEN : 0); - intel_uncore_posting_read(&dev_priv->uncore, FW_BLC_SELF_VLV); - } else if (IS_G4X(dev_priv) || IS_I965GM(dev_priv)) { - was_enabled = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF) & FW_BLC_SELF_EN; - intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF, enable ? FW_BLC_SELF_EN : 0); - intel_uncore_posting_read(&dev_priv->uncore, FW_BLC_SELF); - } else if (IS_PINEVIEW(dev_priv)) { - val = intel_uncore_read(&dev_priv->uncore, DSPFW3(dev_priv)); + if (display->platform.valleyview || display->platform.cherryview) { + was_enabled = intel_de_read(display, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; + intel_de_write(display, FW_BLC_SELF_VLV, enable ? FW_CSPWRDWNEN : 0); + intel_de_posting_read(display, FW_BLC_SELF_VLV); + } else if (display->platform.g4x || display->platform.i965gm) { + was_enabled = intel_de_read(display, FW_BLC_SELF) & FW_BLC_SELF_EN; + intel_de_write(display, FW_BLC_SELF, enable ? FW_BLC_SELF_EN : 0); + intel_de_posting_read(display, FW_BLC_SELF); + } else if (display->platform.pineview) { + val = intel_de_read(display, DSPFW3(display)); was_enabled = val & PINEVIEW_SELF_REFRESH_EN; if (enable) val |= PINEVIEW_SELF_REFRESH_EN; else val &= ~PINEVIEW_SELF_REFRESH_EN; - intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv), val); - intel_uncore_posting_read(&dev_priv->uncore, DSPFW3(dev_priv)); - } else if (IS_I945G(dev_priv) || IS_I945GM(dev_priv)) { - was_enabled = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF) & FW_BLC_SELF_EN; + intel_de_write(display, DSPFW3(display), val); + intel_de_posting_read(display, DSPFW3(display)); + } else if (display->platform.i945g || display->platform.i945gm) { + was_enabled = intel_de_read(display, FW_BLC_SELF) & FW_BLC_SELF_EN; val = enable ? _MASKED_BIT_ENABLE(FW_BLC_SELF_EN) : _MASKED_BIT_DISABLE(FW_BLC_SELF_EN); - intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF, val); - intel_uncore_posting_read(&dev_priv->uncore, FW_BLC_SELF); - } else if (IS_I915GM(dev_priv)) { + intel_de_write(display, FW_BLC_SELF, val); + intel_de_posting_read(display, FW_BLC_SELF); + } else if (display->platform.i915gm) { /* * FIXME can't find a bit like this for 915G, and * yet it does have the related watermark in * FW_BLC_SELF. What's going on? */ - was_enabled = intel_uncore_read(&dev_priv->uncore, INSTPM) & INSTPM_SELF_EN; + was_enabled = intel_de_read(display, INSTPM) & INSTPM_SELF_EN; val = enable ? _MASKED_BIT_ENABLE(INSTPM_SELF_EN) : _MASKED_BIT_DISABLE(INSTPM_SELF_EN); - intel_uncore_write(&dev_priv->uncore, INSTPM, val); - intel_uncore_posting_read(&dev_priv->uncore, INSTPM); + intel_de_write(display, INSTPM, val); + intel_de_posting_read(display, INSTPM); } else { return false; } trace_intel_memory_cxsr(display, was_enabled, enable); - drm_dbg_kms(&dev_priv->drm, "memory self-refresh is %s (was %s)\n", + drm_dbg_kms(display->drm, "memory self-refresh is %s (was %s)\n", str_enabled_disabled(enable), str_enabled_disabled(was_enabled)); @@ -200,7 +203,7 @@ static bool _intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enabl /** * intel_set_memory_cxsr - Configure CxSR state - * @dev_priv: i915 device + * @display: display device * @enable: Allow vs. disallow CxSR * * Allow or disallow the system to enter a special CxSR @@ -235,17 +238,17 @@ static bool _intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enabl * the hardware w.r.t. HPLL SR when writing to plane registers. * Disallowing just CxSR is sufficient. */ -bool intel_set_memory_cxsr(struct drm_i915_private *dev_priv, bool enable) +bool intel_set_memory_cxsr(struct intel_display *display, bool enable) { bool ret; - mutex_lock(&dev_priv->display.wm.wm_mutex); - ret = _intel_set_memory_cxsr(dev_priv, enable); - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - dev_priv->display.wm.vlv.cxsr = enable; - else if (IS_G4X(dev_priv)) - dev_priv->display.wm.g4x.cxsr = enable; - mutex_unlock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); + ret = _intel_set_memory_cxsr(display, enable); + if (display->platform.valleyview || display->platform.cherryview) + display->wm.vlv.cxsr = enable; + else if (display->platform.g4x) + display->wm.g4x.cxsr = enable; + mutex_unlock(&display->wm.wm_mutex); return ret; } @@ -271,8 +274,8 @@ static const int pessimal_latency_ns = 5000; static void vlv_get_fifo_size(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 vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state; enum pipe pipe = crtc->pipe; int sprite0_start, sprite1_start; @@ -280,22 +283,20 @@ static void vlv_get_fifo_size(struct intel_crtc_state *crtc_state) switch (pipe) { case PIPE_A: - dsparb = intel_uncore_read(&dev_priv->uncore, - DSPARB(dev_priv)); - dsparb2 = intel_uncore_read(&dev_priv->uncore, DSPARB2); + dsparb = intel_de_read(display, DSPARB(display)); + dsparb2 = intel_de_read(display, DSPARB2); sprite0_start = VLV_FIFO_START(dsparb, dsparb2, 0, 0); sprite1_start = VLV_FIFO_START(dsparb, dsparb2, 8, 4); break; case PIPE_B: - dsparb = intel_uncore_read(&dev_priv->uncore, - DSPARB(dev_priv)); - dsparb2 = intel_uncore_read(&dev_priv->uncore, DSPARB2); + dsparb = intel_de_read(display, DSPARB(display)); + dsparb2 = intel_de_read(display, DSPARB2); sprite0_start = VLV_FIFO_START(dsparb, dsparb2, 16, 8); sprite1_start = VLV_FIFO_START(dsparb, dsparb2, 24, 12); break; case PIPE_C: - dsparb2 = intel_uncore_read(&dev_priv->uncore, DSPARB2); - dsparb3 = intel_uncore_read(&dev_priv->uncore, DSPARB3); + dsparb2 = intel_de_read(display, DSPARB2); + dsparb3 = intel_de_read(display, DSPARB3); sprite0_start = VLV_FIFO_START(dsparb3, dsparb2, 0, 16); sprite1_start = VLV_FIFO_START(dsparb3, dsparb2, 8, 20); break; @@ -310,26 +311,26 @@ static void vlv_get_fifo_size(struct intel_crtc_state *crtc_state) fifo_state->plane[PLANE_CURSOR] = 63; } -static int i9xx_get_fifo_size(struct drm_i915_private *dev_priv, +static int i9xx_get_fifo_size(struct intel_display *display, enum i9xx_plane_id i9xx_plane) { - u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB(dev_priv)); + u32 dsparb = intel_de_read(display, DSPARB(display)); int size; size = dsparb & 0x7f; if (i9xx_plane == PLANE_B) size = ((dsparb >> DSPARB_CSTART_SHIFT) & 0x7f) - size; - drm_dbg_kms(&dev_priv->drm, "FIFO size - (0x%08x) %c: %d\n", + drm_dbg_kms(display->drm, "FIFO size - (0x%08x) %c: %d\n", dsparb, plane_name(i9xx_plane), size); return size; } -static int i830_get_fifo_size(struct drm_i915_private *dev_priv, +static int i830_get_fifo_size(struct intel_display *display, enum i9xx_plane_id i9xx_plane) { - u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB(dev_priv)); + u32 dsparb = intel_de_read(display, DSPARB(display)); int size; size = dsparb & 0x1ff; @@ -337,22 +338,22 @@ static int i830_get_fifo_size(struct drm_i915_private *dev_priv, size = ((dsparb >> DSPARB_BEND_SHIFT) & 0x1ff) - size; size >>= 1; /* Convert to cachelines */ - drm_dbg_kms(&dev_priv->drm, "FIFO size - (0x%08x) %c: %d\n", + drm_dbg_kms(display->drm, "FIFO size - (0x%08x) %c: %d\n", dsparb, plane_name(i9xx_plane), size); return size; } -static int i845_get_fifo_size(struct drm_i915_private *dev_priv, +static int i845_get_fifo_size(struct intel_display *display, enum i9xx_plane_id i9xx_plane) { - u32 dsparb = intel_uncore_read(&dev_priv->uncore, DSPARB(dev_priv)); + u32 dsparb = intel_de_read(display, DSPARB(display)); int size; size = dsparb & 0x7f; size >>= 2; /* Convert to cachelines */ - drm_dbg_kms(&dev_priv->drm, "FIFO size - (0x%08x) %c: %d\n", + drm_dbg_kms(display->drm, "FIFO size - (0x%08x) %c: %d\n", dsparb, plane_name(i9xx_plane), size); return size; @@ -537,7 +538,7 @@ static unsigned int intel_wm_method2(unsigned int pixel_rate, /** * intel_calculate_wm - calculate watermark level - * @i915: the device + * @display: display device * @pixel_rate: pixel clock * @wm: chip FIFO params * @fifo_size: size of the FIFO buffer @@ -555,7 +556,7 @@ static unsigned int intel_wm_method2(unsigned int pixel_rate, * past the watermark point. If the FIFO drains completely, a FIFO underrun * will occur, and a display engine hang could result. */ -static unsigned int intel_calculate_wm(struct drm_i915_private *i915, +static unsigned int intel_calculate_wm(struct intel_display *display, int pixel_rate, const struct intel_watermark_params *wm, int fifo_size, int cpp, @@ -573,10 +574,10 @@ static unsigned int intel_calculate_wm(struct drm_i915_private *i915, latency_ns / 100); entries = DIV_ROUND_UP(entries, wm->cacheline_size) + wm->guard_size; - drm_dbg_kms(&i915->drm, "FIFO entries required for mode: %d\n", entries); + drm_dbg_kms(display->drm, "FIFO entries required for mode: %d\n", entries); wm_size = fifo_size - entries; - drm_dbg_kms(&i915->drm, "FIFO watermark level: %d\n", wm_size); + drm_dbg_kms(display->drm, "FIFO watermark level: %d\n", wm_size); /* Don't promote wm_size to unsigned... */ if (wm_size > wm->max_wm) @@ -626,11 +627,11 @@ static bool intel_crtc_active(struct intel_crtc *crtc) crtc->config->hw.adjusted_mode.crtc_clock; } -static struct intel_crtc *single_enabled_crtc(struct drm_i915_private *dev_priv) +static struct intel_crtc *single_enabled_crtc(struct intel_display *display) { struct intel_crtc *crtc, *enabled = NULL; - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { if (intel_crtc_active(crtc)) { if (enabled) return NULL; @@ -641,21 +642,21 @@ static struct intel_crtc *single_enabled_crtc(struct drm_i915_private *dev_priv) return enabled; } -static void pnv_update_wm(struct drm_i915_private *dev_priv) +static void pnv_update_wm(struct intel_display *display) { struct intel_crtc *crtc; const struct cxsr_latency *latency; u32 reg; unsigned int wm; - latency = pnv_get_cxsr_latency(dev_priv); + latency = pnv_get_cxsr_latency(display); if (!latency) { - drm_dbg_kms(&dev_priv->drm, "Unknown FSB/MEM, disabling CxSR\n"); - intel_set_memory_cxsr(dev_priv, false); + drm_dbg_kms(display->drm, "Unknown FSB/MEM, disabling CxSR\n"); + intel_set_memory_cxsr(display, false); return; } - crtc = single_enabled_crtc(dev_priv); + crtc = single_enabled_crtc(display); if (crtc) { const struct drm_framebuffer *fb = crtc->base.primary->state->fb; @@ -663,47 +664,46 @@ static void pnv_update_wm(struct drm_i915_private *dev_priv) int cpp = fb->format->cpp[0]; /* Display SR */ - wm = intel_calculate_wm(dev_priv, pixel_rate, + wm = intel_calculate_wm(display, pixel_rate, &pnv_display_wm, pnv_display_wm.fifo_size, cpp, latency->display_sr); - reg = intel_uncore_read(&dev_priv->uncore, DSPFW1(dev_priv)); + reg = intel_de_read(display, DSPFW1(display)); reg &= ~DSPFW_SR_MASK; reg |= FW_WM(wm, SR); - intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv), reg); - drm_dbg_kms(&dev_priv->drm, "DSPFW1 register is %x\n", reg); + intel_de_write(display, DSPFW1(display), reg); + drm_dbg_kms(display->drm, "DSPFW1 register is %x\n", reg); /* cursor SR */ - wm = intel_calculate_wm(dev_priv, pixel_rate, + wm = intel_calculate_wm(display, pixel_rate, &pnv_cursor_wm, pnv_display_wm.fifo_size, 4, latency->cursor_sr); - intel_uncore_rmw(&dev_priv->uncore, DSPFW3(dev_priv), - DSPFW_CURSOR_SR_MASK, - FW_WM(wm, CURSOR_SR)); + intel_de_rmw(display, DSPFW3(display), + DSPFW_CURSOR_SR_MASK, FW_WM(wm, CURSOR_SR)); /* Display HPLL off SR */ - wm = intel_calculate_wm(dev_priv, pixel_rate, + wm = intel_calculate_wm(display, pixel_rate, &pnv_display_hplloff_wm, pnv_display_hplloff_wm.fifo_size, cpp, latency->display_hpll_disable); - intel_uncore_rmw(&dev_priv->uncore, DSPFW3(dev_priv), - DSPFW_HPLL_SR_MASK, FW_WM(wm, HPLL_SR)); + intel_de_rmw(display, DSPFW3(display), + DSPFW_HPLL_SR_MASK, FW_WM(wm, HPLL_SR)); /* cursor HPLL off SR */ - wm = intel_calculate_wm(dev_priv, pixel_rate, + wm = intel_calculate_wm(display, pixel_rate, &pnv_cursor_hplloff_wm, pnv_display_hplloff_wm.fifo_size, 4, latency->cursor_hpll_disable); - reg = intel_uncore_read(&dev_priv->uncore, DSPFW3(dev_priv)); + reg = intel_de_read(display, DSPFW3(display)); reg &= ~DSPFW_HPLL_CURSOR_MASK; reg |= FW_WM(wm, HPLL_CURSOR); - intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv), reg); - drm_dbg_kms(&dev_priv->drm, "DSPFW3 register is %x\n", reg); + intel_de_write(display, DSPFW3(display), reg); + drm_dbg_kms(display->drm, "DSPFW3 register is %x\n", reg); - intel_set_memory_cxsr(dev_priv, true); + intel_set_memory_cxsr(display, true); } else { - intel_set_memory_cxsr(dev_priv, false); + intel_set_memory_cxsr(display, false); } } @@ -794,53 +794,51 @@ static unsigned int g4x_tlb_miss_wa(int fifo_size, int width, int cpp) return max(0, tlb_miss); } -static void g4x_write_wm_values(struct drm_i915_private *dev_priv, +static void g4x_write_wm_values(struct intel_display *display, const struct g4x_wm_values *wm) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; - for_each_pipe(dev_priv, pipe) + for_each_pipe(display, pipe) trace_g4x_wm(intel_crtc_for_pipe(display, pipe), wm); - intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv), - FW_WM(wm->sr.plane, SR) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_CURSOR], CURSORB) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_PRIMARY], PLANEB) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY], PLANEA)); - intel_uncore_write(&dev_priv->uncore, DSPFW2(dev_priv), - (wm->fbc_en ? DSPFW_FBC_SR_EN : 0) | - FW_WM(wm->sr.fbc, FBC_SR) | - FW_WM(wm->hpll.fbc, FBC_HPLL_SR) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEB) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_CURSOR], CURSORA) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE0], SPRITEA)); - intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv), - (wm->hpll_en ? DSPFW_HPLL_SR_EN : 0) | - FW_WM(wm->sr.cursor, CURSOR_SR) | - FW_WM(wm->hpll.cursor, HPLL_CURSOR) | - FW_WM(wm->hpll.plane, HPLL_SR)); - - intel_uncore_posting_read(&dev_priv->uncore, DSPFW1(dev_priv)); + intel_de_write(display, DSPFW1(display), + FW_WM(wm->sr.plane, SR) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_CURSOR], CURSORB) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_PRIMARY], PLANEB) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY], PLANEA)); + intel_de_write(display, DSPFW2(display), + (wm->fbc_en ? DSPFW_FBC_SR_EN : 0) | + FW_WM(wm->sr.fbc, FBC_SR) | + FW_WM(wm->hpll.fbc, FBC_HPLL_SR) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEB) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_CURSOR], CURSORA) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE0], SPRITEA)); + intel_de_write(display, DSPFW3(display), + (wm->hpll_en ? DSPFW_HPLL_SR_EN : 0) | + FW_WM(wm->sr.cursor, CURSOR_SR) | + FW_WM(wm->hpll.cursor, HPLL_CURSOR) | + FW_WM(wm->hpll.plane, HPLL_SR)); + + intel_de_posting_read(display, DSPFW1(display)); } #define FW_WM_VLV(value, plane) \ (((value) << DSPFW_ ## plane ## _SHIFT) & DSPFW_ ## plane ## _MASK_VLV) -static void vlv_write_wm_values(struct drm_i915_private *dev_priv, +static void vlv_write_wm_values(struct intel_display *display, const struct vlv_wm_values *wm) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { trace_vlv_wm(intel_crtc_for_pipe(display, pipe), wm); - intel_uncore_write(&dev_priv->uncore, VLV_DDL(pipe), - (wm->ddl[pipe].plane[PLANE_CURSOR] << DDL_CURSOR_SHIFT) | - (wm->ddl[pipe].plane[PLANE_SPRITE1] << DDL_SPRITE_SHIFT(1)) | - (wm->ddl[pipe].plane[PLANE_SPRITE0] << DDL_SPRITE_SHIFT(0)) | - (wm->ddl[pipe].plane[PLANE_PRIMARY] << DDL_PLANE_SHIFT)); + intel_de_write(display, VLV_DDL(pipe), + (wm->ddl[pipe].plane[PLANE_CURSOR] << DDL_CURSOR_SHIFT) | + (wm->ddl[pipe].plane[PLANE_SPRITE1] << DDL_SPRITE_SHIFT(1)) | + (wm->ddl[pipe].plane[PLANE_SPRITE0] << DDL_SPRITE_SHIFT(0)) | + (wm->ddl[pipe].plane[PLANE_PRIMARY] << DDL_PLANE_SHIFT)); } /* @@ -848,72 +846,72 @@ static void vlv_write_wm_values(struct drm_i915_private *dev_priv, * high order bits so that there are no out of bounds values * present in the registers during the reprogramming. */ - intel_uncore_write(&dev_priv->uncore, DSPHOWM, 0); - intel_uncore_write(&dev_priv->uncore, DSPHOWM1, 0); - intel_uncore_write(&dev_priv->uncore, DSPFW4, 0); - intel_uncore_write(&dev_priv->uncore, DSPFW5, 0); - intel_uncore_write(&dev_priv->uncore, DSPFW6, 0); - - intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv), - FW_WM(wm->sr.plane, SR) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_CURSOR], CURSORB) | - FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_PRIMARY], PLANEB) | - FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_PRIMARY], PLANEA)); - intel_uncore_write(&dev_priv->uncore, DSPFW2(dev_priv), - FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_SPRITE1], SPRITEB) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_CURSOR], CURSORA) | - FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_SPRITE0], SPRITEA)); - intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv), - FW_WM(wm->sr.cursor, CURSOR_SR)); - - if (IS_CHERRYVIEW(dev_priv)) { - intel_uncore_write(&dev_priv->uncore, DSPFW7_CHV, - FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE1], SPRITED) | - FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEC)); - intel_uncore_write(&dev_priv->uncore, DSPFW8_CHV, - FW_WM_VLV(wm->pipe[PIPE_C].plane[PLANE_SPRITE1], SPRITEF) | - FW_WM_VLV(wm->pipe[PIPE_C].plane[PLANE_SPRITE0], SPRITEE)); - intel_uncore_write(&dev_priv->uncore, DSPFW9_CHV, - FW_WM_VLV(wm->pipe[PIPE_C].plane[PLANE_PRIMARY], PLANEC) | - FW_WM(wm->pipe[PIPE_C].plane[PLANE_CURSOR], CURSORC)); - intel_uncore_write(&dev_priv->uncore, DSPHOWM, - FW_WM(wm->sr.plane >> 9, SR_HI) | - FW_WM(wm->pipe[PIPE_C].plane[PLANE_SPRITE1] >> 8, SPRITEF_HI) | - FW_WM(wm->pipe[PIPE_C].plane[PLANE_SPRITE0] >> 8, SPRITEE_HI) | - FW_WM(wm->pipe[PIPE_C].plane[PLANE_PRIMARY] >> 8, PLANEC_HI) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE1] >> 8, SPRITED_HI) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE0] >> 8, SPRITEC_HI) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_PRIMARY] >> 8, PLANEB_HI) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE1] >> 8, SPRITEB_HI) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE0] >> 8, SPRITEA_HI) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY] >> 8, PLANEA_HI)); + intel_de_write(display, DSPHOWM, 0); + intel_de_write(display, DSPHOWM1, 0); + intel_de_write(display, DSPFW4, 0); + intel_de_write(display, DSPFW5, 0); + intel_de_write(display, DSPFW6, 0); + + intel_de_write(display, DSPFW1(display), + FW_WM(wm->sr.plane, SR) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_CURSOR], CURSORB) | + FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_PRIMARY], PLANEB) | + FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_PRIMARY], PLANEA)); + intel_de_write(display, DSPFW2(display), + FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_SPRITE1], SPRITEB) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_CURSOR], CURSORA) | + FW_WM_VLV(wm->pipe[PIPE_A].plane[PLANE_SPRITE0], SPRITEA)); + intel_de_write(display, DSPFW3(display), + FW_WM(wm->sr.cursor, CURSOR_SR)); + + if (display->platform.cherryview) { + intel_de_write(display, DSPFW7_CHV, + FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE1], SPRITED) | + FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEC)); + intel_de_write(display, DSPFW8_CHV, + FW_WM_VLV(wm->pipe[PIPE_C].plane[PLANE_SPRITE1], SPRITEF) | + FW_WM_VLV(wm->pipe[PIPE_C].plane[PLANE_SPRITE0], SPRITEE)); + intel_de_write(display, DSPFW9_CHV, + FW_WM_VLV(wm->pipe[PIPE_C].plane[PLANE_PRIMARY], PLANEC) | + FW_WM(wm->pipe[PIPE_C].plane[PLANE_CURSOR], CURSORC)); + intel_de_write(display, DSPHOWM, + FW_WM(wm->sr.plane >> 9, SR_HI) | + FW_WM(wm->pipe[PIPE_C].plane[PLANE_SPRITE1] >> 8, SPRITEF_HI) | + FW_WM(wm->pipe[PIPE_C].plane[PLANE_SPRITE0] >> 8, SPRITEE_HI) | + FW_WM(wm->pipe[PIPE_C].plane[PLANE_PRIMARY] >> 8, PLANEC_HI) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE1] >> 8, SPRITED_HI) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE0] >> 8, SPRITEC_HI) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_PRIMARY] >> 8, PLANEB_HI) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE1] >> 8, SPRITEB_HI) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE0] >> 8, SPRITEA_HI) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY] >> 8, PLANEA_HI)); } else { - intel_uncore_write(&dev_priv->uncore, DSPFW7, - FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE1], SPRITED) | - FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEC)); - intel_uncore_write(&dev_priv->uncore, DSPHOWM, - FW_WM(wm->sr.plane >> 9, SR_HI) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE1] >> 8, SPRITED_HI) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE0] >> 8, SPRITEC_HI) | - FW_WM(wm->pipe[PIPE_B].plane[PLANE_PRIMARY] >> 8, PLANEB_HI) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE1] >> 8, SPRITEB_HI) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE0] >> 8, SPRITEA_HI) | - FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY] >> 8, PLANEA_HI)); + intel_de_write(display, DSPFW7, + FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE1], SPRITED) | + FW_WM_VLV(wm->pipe[PIPE_B].plane[PLANE_SPRITE0], SPRITEC)); + intel_de_write(display, DSPHOWM, + FW_WM(wm->sr.plane >> 9, SR_HI) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE1] >> 8, SPRITED_HI) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_SPRITE0] >> 8, SPRITEC_HI) | + FW_WM(wm->pipe[PIPE_B].plane[PLANE_PRIMARY] >> 8, PLANEB_HI) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE1] >> 8, SPRITEB_HI) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_SPRITE0] >> 8, SPRITEA_HI) | + FW_WM(wm->pipe[PIPE_A].plane[PLANE_PRIMARY] >> 8, PLANEA_HI)); } - intel_uncore_posting_read(&dev_priv->uncore, DSPFW1(dev_priv)); + intel_de_posting_read(display, DSPFW1(display)); } #undef FW_WM_VLV -static void g4x_setup_wm_latency(struct drm_i915_private *dev_priv) +static void g4x_setup_wm_latency(struct intel_display *display) { /* all latencies in usec */ - dev_priv->display.wm.pri_latency[G4X_WM_LEVEL_NORMAL] = 5; - dev_priv->display.wm.pri_latency[G4X_WM_LEVEL_SR] = 12; - dev_priv->display.wm.pri_latency[G4X_WM_LEVEL_HPLL] = 35; + display->wm.pri_latency[G4X_WM_LEVEL_NORMAL] = 5; + display->wm.pri_latency[G4X_WM_LEVEL_SR] = 12; + display->wm.pri_latency[G4X_WM_LEVEL_HPLL] = 35; - dev_priv->display.wm.num_levels = G4X_WM_LEVEL_HPLL + 1; + display->wm.num_levels = G4X_WM_LEVEL_HPLL + 1; } static int g4x_plane_fifo_size(enum plane_id plane_id, int level) @@ -962,11 +960,11 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state, int level) { + 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); const struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode; - unsigned int latency = dev_priv->display.wm.pri_latency[level] * 10; + unsigned int latency = display->wm.pri_latency[level] * 10; unsigned int pixel_rate, htotal, cpp, width, wm; if (latency == 0) @@ -1017,10 +1015,10 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state, static bool g4x_raw_plane_wm_set(struct intel_crtc_state *crtc_state, int level, enum plane_id plane_id, u16 value) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); bool dirty = false; - for (; level < dev_priv->display.wm.num_levels; level++) { + for (; level < display->wm.num_levels; level++) { struct g4x_pipe_wm *raw = &crtc_state->wm.g4x.raw[level]; dirty |= raw->plane[plane_id] != value; @@ -1033,13 +1031,13 @@ static bool g4x_raw_plane_wm_set(struct intel_crtc_state *crtc_state, static bool g4x_raw_fbc_wm_set(struct intel_crtc_state *crtc_state, int level, u16 value) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); bool dirty = false; /* NORMAL level doesn't have an FBC watermark */ level = max(level, G4X_WM_LEVEL_SR); - for (; level < dev_priv->display.wm.num_levels; level++) { + for (; level < display->wm.num_levels; level++) { struct g4x_pipe_wm *raw = &crtc_state->wm.g4x.raw[level]; dirty |= raw->fbc != value; @@ -1056,8 +1054,8 @@ static u32 ilk_compute_fbc_wm(const struct intel_crtc_state *crtc_state, static bool g4x_raw_plane_wm_compute(struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); enum plane_id plane_id = plane->id; bool dirty = false; int level; @@ -1069,7 +1067,7 @@ static bool g4x_raw_plane_wm_compute(struct intel_crtc_state *crtc_state, goto out; } - for (level = 0; level < dev_priv->display.wm.num_levels; level++) { + for (level = 0; level < display->wm.num_levels; level++) { struct g4x_pipe_wm *raw = &crtc_state->wm.g4x.raw[level]; int wm, max_wm; @@ -1109,7 +1107,7 @@ static bool g4x_raw_plane_wm_compute(struct intel_crtc_state *crtc_state, out: if (dirty) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "%s watermarks: normal=%d, SR=%d, HPLL=%d\n", plane->base.name, crtc_state->wm.g4x.raw[G4X_WM_LEVEL_NORMAL].plane[plane_id], @@ -1117,7 +1115,7 @@ static bool g4x_raw_plane_wm_compute(struct intel_crtc_state *crtc_state, crtc_state->wm.g4x.raw[G4X_WM_LEVEL_HPLL].plane[plane_id]); if (plane_id == PLANE_PRIMARY) - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "FBC watermarks: SR=%d, HPLL=%d\n", crtc_state->wm.g4x.raw[G4X_WM_LEVEL_SR].fbc, crtc_state->wm.g4x.raw[G4X_WM_LEVEL_HPLL].fbc); @@ -1137,9 +1135,9 @@ static bool g4x_raw_plane_wm_is_valid(const struct intel_crtc_state *crtc_state, static bool g4x_raw_crtc_wm_is_valid(const struct intel_crtc_state *crtc_state, int level) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); - if (level >= dev_priv->display.wm.num_levels) + if (level >= display->wm.num_levels) return false; return g4x_raw_plane_wm_is_valid(crtc_state, PLANE_PRIMARY, level) && @@ -1281,7 +1279,7 @@ static int g4x_compute_pipe_wm(struct intel_atomic_state *state, static int g4x_compute_intermediate_wm(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); struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_crtc_state *old_crtc_state = @@ -1311,7 +1309,7 @@ static int g4x_compute_intermediate_wm(struct intel_atomic_state *state, max(optimal->wm.plane[plane_id], active->wm.plane[plane_id]); - drm_WARN_ON(&dev_priv->drm, intermediate->wm.plane[plane_id] > + drm_WARN_ON(display->drm, intermediate->wm.plane[plane_id] > g4x_plane_fifo_size(plane_id, G4X_WM_LEVEL_NORMAL)); } @@ -1329,23 +1327,23 @@ static int g4x_compute_intermediate_wm(struct intel_atomic_state *state, intermediate->hpll.fbc = max(optimal->hpll.fbc, active->hpll.fbc); - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, (intermediate->sr.plane > g4x_plane_fifo_size(PLANE_PRIMARY, G4X_WM_LEVEL_SR) || intermediate->sr.cursor > g4x_plane_fifo_size(PLANE_CURSOR, G4X_WM_LEVEL_SR)) && intermediate->cxsr); - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, (intermediate->sr.plane > g4x_plane_fifo_size(PLANE_PRIMARY, G4X_WM_LEVEL_HPLL) || intermediate->sr.cursor > g4x_plane_fifo_size(PLANE_CURSOR, G4X_WM_LEVEL_HPLL)) && intermediate->hpll_en); - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, intermediate->sr.fbc > g4x_fbc_fifo_size(1) && intermediate->fbc_en && intermediate->cxsr); - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, intermediate->hpll.fbc > g4x_fbc_fifo_size(2) && intermediate->fbc_en && intermediate->hpll_en); @@ -1376,7 +1374,7 @@ static int g4x_compute_watermarks(struct intel_atomic_state *state, return 0; } -static void g4x_merge_wm(struct drm_i915_private *dev_priv, +static void g4x_merge_wm(struct intel_display *display, struct g4x_wm_values *wm) { struct intel_crtc *crtc; @@ -1386,7 +1384,7 @@ static void g4x_merge_wm(struct drm_i915_private *dev_priv, wm->hpll_en = true; wm->fbc_en = true; - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { const struct g4x_wm_state *wm_state = &crtc->wm.active.g4x; if (!crtc->active) @@ -1408,7 +1406,7 @@ static void g4x_merge_wm(struct drm_i915_private *dev_priv, wm->fbc_en = false; } - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { const struct g4x_wm_state *wm_state = &crtc->wm.active.g4x; enum pipe pipe = crtc->pipe; @@ -1420,23 +1418,23 @@ static void g4x_merge_wm(struct drm_i915_private *dev_priv, } } -static void g4x_program_watermarks(struct drm_i915_private *dev_priv) +static void g4x_program_watermarks(struct intel_display *display) { - struct g4x_wm_values *old_wm = &dev_priv->display.wm.g4x; + struct g4x_wm_values *old_wm = &display->wm.g4x; struct g4x_wm_values new_wm = {}; - g4x_merge_wm(dev_priv, &new_wm); + g4x_merge_wm(display, &new_wm); if (memcmp(old_wm, &new_wm, sizeof(new_wm)) == 0) return; if (is_disabling(old_wm->cxsr, new_wm.cxsr, true)) - _intel_set_memory_cxsr(dev_priv, false); + _intel_set_memory_cxsr(display, false); - g4x_write_wm_values(dev_priv, &new_wm); + g4x_write_wm_values(display, &new_wm); if (is_enabling(old_wm->cxsr, new_wm.cxsr, true)) - _intel_set_memory_cxsr(dev_priv, true); + _intel_set_memory_cxsr(display, true); *old_wm = new_wm; } @@ -1444,30 +1442,30 @@ static void g4x_program_watermarks(struct drm_i915_private *dev_priv) static void g4x_initial_watermarks(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(crtc); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - mutex_lock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); crtc->wm.active.g4x = crtc_state->wm.g4x.intermediate; - g4x_program_watermarks(dev_priv); - mutex_unlock(&dev_priv->display.wm.wm_mutex); + g4x_program_watermarks(display); + mutex_unlock(&display->wm.wm_mutex); } static void g4x_optimize_watermarks(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(crtc); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); if (!crtc_state->wm.need_postvbl_update) return; - mutex_lock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); crtc->wm.active.g4x = crtc_state->wm.g4x.optimal; - g4x_program_watermarks(dev_priv); - mutex_unlock(&dev_priv->display.wm.wm_mutex); + g4x_program_watermarks(display); + mutex_unlock(&display->wm.wm_mutex); } /* latency must be in 0.1us units. */ @@ -1486,18 +1484,18 @@ static unsigned int vlv_wm_method2(unsigned int pixel_rate, return ret; } -static void vlv_setup_wm_latency(struct drm_i915_private *dev_priv) +static void vlv_setup_wm_latency(struct intel_display *display) { /* all latencies in usec */ - dev_priv->display.wm.pri_latency[VLV_WM_LEVEL_PM2] = 3; + display->wm.pri_latency[VLV_WM_LEVEL_PM2] = 3; - dev_priv->display.wm.num_levels = VLV_WM_LEVEL_PM2 + 1; + display->wm.num_levels = VLV_WM_LEVEL_PM2 + 1; - if (IS_CHERRYVIEW(dev_priv)) { - dev_priv->display.wm.pri_latency[VLV_WM_LEVEL_PM5] = 12; - dev_priv->display.wm.pri_latency[VLV_WM_LEVEL_DDR_DVFS] = 33; + if (display->platform.cherryview) { + display->wm.pri_latency[VLV_WM_LEVEL_PM5] = 12; + display->wm.pri_latency[VLV_WM_LEVEL_DDR_DVFS] = 33; - dev_priv->display.wm.num_levels = VLV_WM_LEVEL_DDR_DVFS + 1; + display->wm.num_levels = VLV_WM_LEVEL_DDR_DVFS + 1; } } @@ -1505,13 +1503,13 @@ static u16 vlv_compute_wm_level(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state, int level) { + 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); const struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode; unsigned int pixel_rate, htotal, cpp, width, wm; - if (dev_priv->display.wm.pri_latency[level] == 0) + if (display->wm.pri_latency[level] == 0) return USHRT_MAX; if (!intel_wm_plane_visible(crtc_state, plane_state)) @@ -1532,7 +1530,7 @@ static u16 vlv_compute_wm_level(const struct intel_crtc_state *crtc_state, wm = 63; } else { wm = vlv_wm_method2(pixel_rate, htotal, width, cpp, - dev_priv->display.wm.pri_latency[level] * 10); + display->wm.pri_latency[level] * 10); } return min_t(unsigned int, wm, USHRT_MAX); @@ -1546,8 +1544,8 @@ static bool vlv_need_sprite0_fifo_workaround(unsigned int active_planes) static int vlv_compute_fifo(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); const struct g4x_pipe_wm *raw = &crtc_state->wm.vlv.raw[VLV_WM_LEVEL_PM2]; struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state; @@ -1616,11 +1614,11 @@ static int vlv_compute_fifo(struct intel_crtc_state *crtc_state) fifo_left -= plane_extra; } - drm_WARN_ON(&dev_priv->drm, active_planes != 0 && fifo_left != 0); + drm_WARN_ON(display->drm, active_planes != 0 && fifo_left != 0); /* give it all to the first plane if none are active */ if (active_planes == 0) { - drm_WARN_ON(&dev_priv->drm, fifo_left != fifo_size); + drm_WARN_ON(display->drm, fifo_left != fifo_size); fifo_state->plane[PLANE_PRIMARY] = fifo_left; } @@ -1631,9 +1629,9 @@ static int vlv_compute_fifo(struct intel_crtc_state *crtc_state) static void vlv_invalidate_wms(struct intel_crtc *crtc, struct vlv_wm_state *wm_state, int level) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); - for (; level < dev_priv->display.wm.num_levels; level++) { + for (; level < display->wm.num_levels; level++) { enum plane_id plane_id; for_each_plane_id_on_crtc(crtc, plane_id) @@ -1659,10 +1657,10 @@ static u16 vlv_invert_wm_value(u16 wm, u16 fifo_size) static bool vlv_raw_plane_wm_set(struct intel_crtc_state *crtc_state, int level, enum plane_id plane_id, u16 value) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); bool dirty = false; - for (; level < dev_priv->display.wm.num_levels; level++) { + for (; level < display->wm.num_levels; level++) { struct g4x_pipe_wm *raw = &crtc_state->wm.vlv.raw[level]; dirty |= raw->plane[plane_id] != value; @@ -1675,8 +1673,8 @@ static bool vlv_raw_plane_wm_set(struct intel_crtc_state *crtc_state, static bool vlv_raw_plane_wm_compute(struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); enum plane_id plane_id = plane->id; int level; bool dirty = false; @@ -1686,7 +1684,7 @@ static bool vlv_raw_plane_wm_compute(struct intel_crtc_state *crtc_state, goto out; } - for (level = 0; level < dev_priv->display.wm.num_levels; level++) { + for (level = 0; level < display->wm.num_levels; level++) { struct g4x_pipe_wm *raw = &crtc_state->wm.vlv.raw[level]; int wm = vlv_compute_wm_level(crtc_state, plane_state, level); int max_wm = plane_id == PLANE_CURSOR ? 63 : 511; @@ -1703,7 +1701,7 @@ static bool vlv_raw_plane_wm_compute(struct intel_crtc_state *crtc_state, out: if (dirty) - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "%s watermarks: PM2=%d, PM5=%d, DDR DVFS=%d\n", plane->base.name, crtc_state->wm.vlv.raw[VLV_WM_LEVEL_PM2].plane[plane_id], @@ -1734,8 +1732,8 @@ static bool vlv_raw_crtc_wm_is_valid(const struct intel_crtc_state *crtc_state, static int _vlv_compute_pipe_wm(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 vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal; const struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state; @@ -1745,7 +1743,7 @@ static int _vlv_compute_pipe_wm(struct intel_crtc_state *crtc_state) int level; /* initially allow all levels */ - wm_state->num_levels = dev_priv->display.wm.num_levels; + wm_state->num_levels = display->wm.num_levels; /* * Note that enabling cxsr with no primary/sprite planes * enabled can wedge the pipe. Hence we only allow cxsr @@ -1755,7 +1753,7 @@ static int _vlv_compute_pipe_wm(struct intel_crtc_state *crtc_state) for (level = 0; level < wm_state->num_levels; level++) { const struct g4x_pipe_wm *raw = &crtc_state->wm.vlv.raw[level]; - const int sr_fifo_size = INTEL_NUM_PIPES(dev_priv) * 512 - 1; + const int sr_fifo_size = INTEL_NUM_PIPES(display) * 512 - 1; if (!vlv_raw_crtc_wm_is_valid(crtc_state, level)) break; @@ -1855,6 +1853,7 @@ static int vlv_compute_pipe_wm(struct intel_atomic_state *state, static void vlv_atomic_update_fifo(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); struct intel_uncore *uncore = &dev_priv->uncore; const struct intel_crtc_state *crtc_state = @@ -1871,8 +1870,8 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state, sprite1_start = fifo_state->plane[PLANE_SPRITE0] + sprite0_start; fifo_size = fifo_state->plane[PLANE_SPRITE1] + sprite1_start; - drm_WARN_ON(&dev_priv->drm, fifo_state->plane[PLANE_CURSOR] != 63); - drm_WARN_ON(&dev_priv->drm, fifo_size != 511); + drm_WARN_ON(display->drm, fifo_state->plane[PLANE_CURSOR] != 63); + drm_WARN_ON(display->drm, fifo_size != 511); trace_vlv_fifo_size(crtc, sprite0_start, sprite1_start, fifo_size); @@ -1889,8 +1888,8 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state, switch (crtc->pipe) { case PIPE_A: - dsparb = intel_uncore_read_fw(uncore, DSPARB(dev_priv)); - dsparb2 = intel_uncore_read_fw(uncore, DSPARB2); + dsparb = intel_de_read_fw(display, DSPARB(display)); + dsparb2 = intel_de_read_fw(display, DSPARB2); dsparb &= ~(VLV_FIFO(SPRITEA, 0xff) | VLV_FIFO(SPRITEB, 0xff)); @@ -1902,12 +1901,12 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state, dsparb2 |= (VLV_FIFO(SPRITEA_HI, sprite0_start >> 8) | VLV_FIFO(SPRITEB_HI, sprite1_start >> 8)); - intel_uncore_write_fw(uncore, DSPARB(dev_priv), dsparb); - intel_uncore_write_fw(uncore, DSPARB2, dsparb2); + intel_de_write_fw(display, DSPARB(display), dsparb); + intel_de_write_fw(display, DSPARB2, dsparb2); break; case PIPE_B: - dsparb = intel_uncore_read_fw(uncore, DSPARB(dev_priv)); - dsparb2 = intel_uncore_read_fw(uncore, DSPARB2); + dsparb = intel_de_read_fw(display, DSPARB(display)); + dsparb2 = intel_de_read_fw(display, DSPARB2); dsparb &= ~(VLV_FIFO(SPRITEC, 0xff) | VLV_FIFO(SPRITED, 0xff)); @@ -1919,12 +1918,12 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state, dsparb2 |= (VLV_FIFO(SPRITEC_HI, sprite0_start >> 8) | VLV_FIFO(SPRITED_HI, sprite1_start >> 8)); - intel_uncore_write_fw(uncore, DSPARB(dev_priv), dsparb); - intel_uncore_write_fw(uncore, DSPARB2, dsparb2); + intel_de_write_fw(display, DSPARB(display), dsparb); + intel_de_write_fw(display, DSPARB2, dsparb2); break; case PIPE_C: - dsparb3 = intel_uncore_read_fw(uncore, DSPARB3); - dsparb2 = intel_uncore_read_fw(uncore, DSPARB2); + dsparb3 = intel_de_read_fw(display, DSPARB3); + dsparb2 = intel_de_read_fw(display, DSPARB2); dsparb3 &= ~(VLV_FIFO(SPRITEE, 0xff) | VLV_FIFO(SPRITEF, 0xff)); @@ -1936,14 +1935,14 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state, dsparb2 |= (VLV_FIFO(SPRITEE_HI, sprite0_start >> 8) | VLV_FIFO(SPRITEF_HI, sprite1_start >> 8)); - intel_uncore_write_fw(uncore, DSPARB3, dsparb3); - intel_uncore_write_fw(uncore, DSPARB2, dsparb2); + intel_de_write_fw(display, DSPARB3, dsparb3); + intel_de_write_fw(display, DSPARB2, dsparb2); break; default: break; } - intel_uncore_posting_read_fw(uncore, DSPARB(dev_priv)); + intel_de_read_fw(display, DSPARB(display)); spin_unlock(&uncore->lock); } @@ -2018,16 +2017,16 @@ static int vlv_compute_watermarks(struct intel_atomic_state *state, return 0; } -static void vlv_merge_wm(struct drm_i915_private *dev_priv, +static void vlv_merge_wm(struct intel_display *display, struct vlv_wm_values *wm) { struct intel_crtc *crtc; int num_active_pipes = 0; - wm->level = dev_priv->display.wm.num_levels - 1; + wm->level = display->wm.num_levels - 1; wm->cxsr = true; - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { const struct vlv_wm_state *wm_state = &crtc->wm.active.vlv; if (!crtc->active) @@ -2046,7 +2045,7 @@ static void vlv_merge_wm(struct drm_i915_private *dev_priv, if (num_active_pipes > 1) wm->level = VLV_WM_LEVEL_PM2; - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { const struct vlv_wm_state *wm_state = &crtc->wm.active.vlv; enum pipe pipe = crtc->pipe; @@ -2061,35 +2060,35 @@ static void vlv_merge_wm(struct drm_i915_private *dev_priv, } } -static void vlv_program_watermarks(struct drm_i915_private *dev_priv) +static void vlv_program_watermarks(struct intel_display *display) { - struct vlv_wm_values *old_wm = &dev_priv->display.wm.vlv; + struct vlv_wm_values *old_wm = &display->wm.vlv; struct vlv_wm_values new_wm = {}; - vlv_merge_wm(dev_priv, &new_wm); + vlv_merge_wm(display, &new_wm); if (memcmp(old_wm, &new_wm, sizeof(new_wm)) == 0) return; if (is_disabling(old_wm->level, new_wm.level, VLV_WM_LEVEL_DDR_DVFS)) - chv_set_memory_dvfs(dev_priv, false); + chv_set_memory_dvfs(display, false); if (is_disabling(old_wm->level, new_wm.level, VLV_WM_LEVEL_PM5)) - chv_set_memory_pm5(dev_priv, false); + chv_set_memory_pm5(display, false); if (is_disabling(old_wm->cxsr, new_wm.cxsr, true)) - _intel_set_memory_cxsr(dev_priv, false); + _intel_set_memory_cxsr(display, false); - vlv_write_wm_values(dev_priv, &new_wm); + vlv_write_wm_values(display, &new_wm); if (is_enabling(old_wm->cxsr, new_wm.cxsr, true)) - _intel_set_memory_cxsr(dev_priv, true); + _intel_set_memory_cxsr(display, true); if (is_enabling(old_wm->level, new_wm.level, VLV_WM_LEVEL_PM5)) - chv_set_memory_pm5(dev_priv, true); + chv_set_memory_pm5(display, true); if (is_enabling(old_wm->level, new_wm.level, VLV_WM_LEVEL_DDR_DVFS)) - chv_set_memory_dvfs(dev_priv, true); + chv_set_memory_dvfs(display, true); *old_wm = new_wm; } @@ -2097,33 +2096,33 @@ static void vlv_program_watermarks(struct drm_i915_private *dev_priv) static void vlv_initial_watermarks(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(crtc); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - mutex_lock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); crtc->wm.active.vlv = crtc_state->wm.vlv.intermediate; - vlv_program_watermarks(dev_priv); - mutex_unlock(&dev_priv->display.wm.wm_mutex); + vlv_program_watermarks(display); + mutex_unlock(&display->wm.wm_mutex); } static void vlv_optimize_watermarks(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(crtc); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); if (!crtc_state->wm.need_postvbl_update) return; - mutex_lock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); crtc->wm.active.vlv = crtc_state->wm.vlv.optimal; - vlv_program_watermarks(dev_priv); - mutex_unlock(&dev_priv->display.wm.wm_mutex); + vlv_program_watermarks(display); + mutex_unlock(&display->wm.wm_mutex); } -static void i965_update_wm(struct drm_i915_private *dev_priv) +static void i965_update_wm(struct intel_display *display) { struct intel_crtc *crtc; int srwm = 1; @@ -2131,7 +2130,7 @@ static void i965_update_wm(struct drm_i915_private *dev_priv) bool cxsr_enabled; /* Calc sr entries for one plane configs */ - crtc = single_enabled_crtc(dev_priv); + crtc = single_enabled_crtc(display); if (crtc) { /* self-refresh has much higher latency */ static const int sr_latency_ns = 12000; @@ -2152,7 +2151,7 @@ static void i965_update_wm(struct drm_i915_private *dev_priv) if (srwm < 0) srwm = 1; srwm &= 0x1ff; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "self-refresh entries: %d, wm: %d\n", entries, srwm); @@ -2167,7 +2166,7 @@ static void i965_update_wm(struct drm_i915_private *dev_priv) if (cursor_sr > i965_cursor_wm_info.max_wm) cursor_sr = i965_cursor_wm_info.max_wm; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "self-refresh watermark: display plane %d " "cursor %d\n", srwm, cursor_sr); @@ -2175,39 +2174,38 @@ static void i965_update_wm(struct drm_i915_private *dev_priv) } else { cxsr_enabled = false; /* Turn off self refresh if both pipes are enabled */ - intel_set_memory_cxsr(dev_priv, false); + intel_set_memory_cxsr(display, false); } - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n", srwm); /* 965 has limitations... */ - intel_uncore_write(&dev_priv->uncore, DSPFW1(dev_priv), - FW_WM(srwm, SR) | - FW_WM(8, CURSORB) | - FW_WM(8, PLANEB) | - FW_WM(8, PLANEA)); - intel_uncore_write(&dev_priv->uncore, DSPFW2(dev_priv), - FW_WM(8, CURSORA) | - FW_WM(8, PLANEC_OLD)); + intel_de_write(display, DSPFW1(display), + FW_WM(srwm, SR) | + FW_WM(8, CURSORB) | + FW_WM(8, PLANEB) | + FW_WM(8, PLANEA)); + intel_de_write(display, DSPFW2(display), + FW_WM(8, CURSORA) | + FW_WM(8, PLANEC_OLD)); /* update cursor SR watermark */ - intel_uncore_write(&dev_priv->uncore, DSPFW3(dev_priv), - FW_WM(cursor_sr, CURSOR_SR)); + intel_de_write(display, DSPFW3(display), + FW_WM(cursor_sr, CURSOR_SR)); if (cxsr_enabled) - intel_set_memory_cxsr(dev_priv, true); + intel_set_memory_cxsr(display, true); } #undef FW_WM -static struct intel_crtc *intel_crtc_for_plane(struct drm_i915_private *i915, +static struct intel_crtc *intel_crtc_for_plane(struct intel_display *display, enum i9xx_plane_id i9xx_plane) { - struct intel_display *display = &i915->display; struct intel_plane *plane; - for_each_intel_plane(&i915->drm, plane) { + for_each_intel_plane(display->drm, plane) { if (plane->id == PLANE_PRIMARY && plane->i9xx_plane == i9xx_plane) return intel_crtc_for_pipe(display, plane->pipe); @@ -2216,7 +2214,7 @@ static struct intel_crtc *intel_crtc_for_plane(struct drm_i915_private *i915, return NULL; } -static void i9xx_update_wm(struct drm_i915_private *dev_priv) +static void i9xx_update_wm(struct intel_display *display) { const struct intel_watermark_params *wm_info; u32 fwater_lo; @@ -2226,29 +2224,29 @@ static void i9xx_update_wm(struct drm_i915_private *dev_priv) int planea_wm, planeb_wm; struct intel_crtc *crtc; - if (IS_I945GM(dev_priv)) + if (display->platform.i945gm) wm_info = &i945_wm_info; - else if (DISPLAY_VER(dev_priv) != 2) + else if (DISPLAY_VER(display) != 2) wm_info = &i915_wm_info; else wm_info = &i830_a_wm_info; - if (DISPLAY_VER(dev_priv) == 2) - fifo_size = i830_get_fifo_size(dev_priv, PLANE_A); + if (DISPLAY_VER(display) == 2) + fifo_size = i830_get_fifo_size(display, PLANE_A); else - fifo_size = i9xx_get_fifo_size(dev_priv, PLANE_A); - crtc = intel_crtc_for_plane(dev_priv, PLANE_A); + fifo_size = i9xx_get_fifo_size(display, PLANE_A); + crtc = intel_crtc_for_plane(display, PLANE_A); if (intel_crtc_active(crtc)) { const struct drm_framebuffer *fb = crtc->base.primary->state->fb; int cpp; - if (DISPLAY_VER(dev_priv) == 2) + if (DISPLAY_VER(display) == 2) cpp = 4; else cpp = fb->format->cpp[0]; - planea_wm = intel_calculate_wm(dev_priv, crtc->config->pixel_rate, + planea_wm = intel_calculate_wm(display, crtc->config->pixel_rate, wm_info, fifo_size, cpp, pessimal_latency_ns); } else { @@ -2257,25 +2255,25 @@ static void i9xx_update_wm(struct drm_i915_private *dev_priv) planea_wm = wm_info->max_wm; } - if (DISPLAY_VER(dev_priv) == 2) + if (DISPLAY_VER(display) == 2) wm_info = &i830_bc_wm_info; - if (DISPLAY_VER(dev_priv) == 2) - fifo_size = i830_get_fifo_size(dev_priv, PLANE_B); + if (DISPLAY_VER(display) == 2) + fifo_size = i830_get_fifo_size(display, PLANE_B); else - fifo_size = i9xx_get_fifo_size(dev_priv, PLANE_B); - crtc = intel_crtc_for_plane(dev_priv, PLANE_B); + fifo_size = i9xx_get_fifo_size(display, PLANE_B); + crtc = intel_crtc_for_plane(display, PLANE_B); if (intel_crtc_active(crtc)) { const struct drm_framebuffer *fb = crtc->base.primary->state->fb; int cpp; - if (DISPLAY_VER(dev_priv) == 2) + if (DISPLAY_VER(display) == 2) cpp = 4; else cpp = fb->format->cpp[0]; - planeb_wm = intel_calculate_wm(dev_priv, crtc->config->pixel_rate, + planeb_wm = intel_calculate_wm(display, crtc->config->pixel_rate, wm_info, fifo_size, cpp, pessimal_latency_ns); } else { @@ -2284,11 +2282,11 @@ static void i9xx_update_wm(struct drm_i915_private *dev_priv) planeb_wm = wm_info->max_wm; } - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); - crtc = single_enabled_crtc(dev_priv); - if (IS_I915GM(dev_priv) && crtc) { + crtc = single_enabled_crtc(display); + if (display->platform.i915gm && crtc) { struct drm_gem_object *obj; obj = intel_fb_bo(crtc->base.primary->state->fb); @@ -2304,10 +2302,10 @@ static void i9xx_update_wm(struct drm_i915_private *dev_priv) cwm = 2; /* Play safe and disable self-refresh before adjusting watermarks. */ - intel_set_memory_cxsr(dev_priv, false); + intel_set_memory_cxsr(display, false); /* Calc sr entries for one plane configs */ - if (HAS_FW_BLC(dev_priv) && crtc) { + if (HAS_FW_BLC(display) && crtc) { /* self-refresh has much higher latency */ static const int sr_latency_ns = 6000; const struct drm_display_mode *pipe_mode = @@ -2320,7 +2318,7 @@ static void i9xx_update_wm(struct drm_i915_private *dev_priv) int cpp; int entries; - if (IS_I915GM(dev_priv) || IS_I945GM(dev_priv)) + if (display->platform.i915gm || display->platform.i945gm) cpp = 4; else cpp = fb->format->cpp[0]; @@ -2328,20 +2326,20 @@ static void i9xx_update_wm(struct drm_i915_private *dev_priv) entries = intel_wm_method2(pixel_rate, htotal, width, cpp, sr_latency_ns / 100); entries = DIV_ROUND_UP(entries, wm_info->cacheline_size); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "self-refresh entries: %d\n", entries); srwm = wm_info->fifo_size - entries; if (srwm < 0) srwm = 1; - if (IS_I945G(dev_priv) || IS_I945GM(dev_priv)) - intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF, - FW_BLC_SELF_FIFO_MASK | (srwm & 0xff)); + if (display->platform.i945g || display->platform.i945gm) + intel_de_write(display, FW_BLC_SELF, + FW_BLC_SELF_FIFO_MASK | (srwm & 0xff)); else - intel_uncore_write(&dev_priv->uncore, FW_BLC_SELF, srwm & 0x3f); + intel_de_write(display, FW_BLC_SELF, srwm & 0x3f); } - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Setting FIFO watermarks - A: %d, B: %d, C: %d, SR %d\n", planea_wm, planeb_wm, cwm, srwm); @@ -2352,34 +2350,34 @@ static void i9xx_update_wm(struct drm_i915_private *dev_priv) fwater_lo = fwater_lo | (1 << 24) | (1 << 8); fwater_hi = fwater_hi | (1 << 8); - intel_uncore_write(&dev_priv->uncore, FW_BLC, fwater_lo); - intel_uncore_write(&dev_priv->uncore, FW_BLC2, fwater_hi); + intel_de_write(display, FW_BLC, fwater_lo); + intel_de_write(display, FW_BLC2, fwater_hi); if (crtc) - intel_set_memory_cxsr(dev_priv, true); + intel_set_memory_cxsr(display, true); } -static void i845_update_wm(struct drm_i915_private *dev_priv) +static void i845_update_wm(struct intel_display *display) { struct intel_crtc *crtc; u32 fwater_lo; int planea_wm; - crtc = single_enabled_crtc(dev_priv); + crtc = single_enabled_crtc(display); if (crtc == NULL) return; - planea_wm = intel_calculate_wm(dev_priv, crtc->config->pixel_rate, + planea_wm = intel_calculate_wm(display, crtc->config->pixel_rate, &i845_wm_info, - i845_get_fifo_size(dev_priv, PLANE_A), + i845_get_fifo_size(display, PLANE_A), 4, pessimal_latency_ns); - fwater_lo = intel_uncore_read(&dev_priv->uncore, FW_BLC) & ~0xfff; + fwater_lo = intel_de_read(display, FW_BLC) & ~0xfff; fwater_lo |= (3<<8) | planea_wm; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Setting FIFO watermarks - A: %d\n", planea_wm); - intel_uncore_write(&dev_priv->uncore, FW_BLC, fwater_lo); + intel_de_write(display, FW_BLC, fwater_lo); } /* latency must be in 0.1us units. */ @@ -2534,24 +2532,24 @@ static u32 ilk_compute_fbc_wm(const struct intel_crtc_state *crtc_state, } static unsigned int -ilk_display_fifo_size(const struct drm_i915_private *dev_priv) +ilk_display_fifo_size(struct intel_display *display) { - if (DISPLAY_VER(dev_priv) >= 8) + if (DISPLAY_VER(display) >= 8) return 3072; - else if (DISPLAY_VER(dev_priv) >= 7) + else if (DISPLAY_VER(display) >= 7) return 768; else return 512; } static unsigned int -ilk_plane_wm_reg_max(const struct drm_i915_private *dev_priv, +ilk_plane_wm_reg_max(struct intel_display *display, int level, bool is_sprite) { - if (DISPLAY_VER(dev_priv) >= 8) + if (DISPLAY_VER(display) >= 8) /* BDW primary/sprite plane watermarks */ return level == 0 ? 255 : 2047; - else if (DISPLAY_VER(dev_priv) >= 7) + else if (DISPLAY_VER(display) >= 7) /* IVB/HSW primary/sprite plane watermarks */ return level == 0 ? 127 : 1023; else if (!is_sprite) @@ -2563,30 +2561,30 @@ ilk_plane_wm_reg_max(const struct drm_i915_private *dev_priv, } static unsigned int -ilk_cursor_wm_reg_max(const struct drm_i915_private *dev_priv, int level) +ilk_cursor_wm_reg_max(struct intel_display *display, int level) { - if (DISPLAY_VER(dev_priv) >= 7) + if (DISPLAY_VER(display) >= 7) return level == 0 ? 63 : 255; else return level == 0 ? 31 : 63; } -static unsigned int ilk_fbc_wm_reg_max(const struct drm_i915_private *dev_priv) +static unsigned int ilk_fbc_wm_reg_max(struct intel_display *display) { - if (DISPLAY_VER(dev_priv) >= 8) + if (DISPLAY_VER(display) >= 8) return 31; else return 15; } /* Calculate the maximum primary/sprite plane watermark */ -static unsigned int ilk_plane_wm_max(const struct drm_i915_private *dev_priv, +static unsigned int ilk_plane_wm_max(struct intel_display *display, int level, const struct intel_wm_config *config, enum intel_ddb_partitioning ddb_partitioning, bool is_sprite) { - unsigned int fifo_size = ilk_display_fifo_size(dev_priv); + unsigned int fifo_size = ilk_display_fifo_size(display); /* if sprites aren't enabled, sprites get nothing */ if (is_sprite && !config->sprites_enabled) @@ -2594,14 +2592,14 @@ static unsigned int ilk_plane_wm_max(const struct drm_i915_private *dev_priv, /* HSW allows LP1+ watermarks even with multiple pipes */ if (level == 0 || config->num_pipes_active > 1) { - fifo_size /= INTEL_NUM_PIPES(dev_priv); + fifo_size /= INTEL_NUM_PIPES(display); /* * For some reason the non self refresh * FIFO size is only half of the self * refresh FIFO size on ILK/SNB. */ - if (DISPLAY_VER(dev_priv) < 7) + if (DISPLAY_VER(display) < 7) fifo_size /= 2; } @@ -2617,11 +2615,11 @@ static unsigned int ilk_plane_wm_max(const struct drm_i915_private *dev_priv, } /* clamp to max that the registers can hold */ - return min(fifo_size, ilk_plane_wm_reg_max(dev_priv, level, is_sprite)); + return min(fifo_size, ilk_plane_wm_reg_max(display, level, is_sprite)); } /* Calculate the maximum cursor plane watermark */ -static unsigned int ilk_cursor_wm_max(const struct drm_i915_private *dev_priv, +static unsigned int ilk_cursor_wm_max(struct intel_display *display, int level, const struct intel_wm_config *config) { @@ -2630,32 +2628,32 @@ static unsigned int ilk_cursor_wm_max(const struct drm_i915_private *dev_priv, return 64; /* otherwise just report max that registers can hold */ - return ilk_cursor_wm_reg_max(dev_priv, level); + return ilk_cursor_wm_reg_max(display, level); } -static void ilk_compute_wm_maximums(const struct drm_i915_private *dev_priv, +static void ilk_compute_wm_maximums(struct intel_display *display, int level, const struct intel_wm_config *config, enum intel_ddb_partitioning ddb_partitioning, struct ilk_wm_maximums *max) { - max->pri = ilk_plane_wm_max(dev_priv, level, config, ddb_partitioning, false); - max->spr = ilk_plane_wm_max(dev_priv, level, config, ddb_partitioning, true); - max->cur = ilk_cursor_wm_max(dev_priv, level, config); - max->fbc = ilk_fbc_wm_reg_max(dev_priv); + max->pri = ilk_plane_wm_max(display, level, config, ddb_partitioning, false); + max->spr = ilk_plane_wm_max(display, level, config, ddb_partitioning, true); + max->cur = ilk_cursor_wm_max(display, level, config); + max->fbc = ilk_fbc_wm_reg_max(display); } -static void ilk_compute_wm_reg_maximums(const struct drm_i915_private *dev_priv, +static void ilk_compute_wm_reg_maximums(struct intel_display *display, int level, struct ilk_wm_maximums *max) { - max->pri = ilk_plane_wm_reg_max(dev_priv, level, false); - max->spr = ilk_plane_wm_reg_max(dev_priv, level, true); - max->cur = ilk_cursor_wm_reg_max(dev_priv, level); - max->fbc = ilk_fbc_wm_reg_max(dev_priv); + max->pri = ilk_plane_wm_reg_max(display, level, false); + max->spr = ilk_plane_wm_reg_max(display, level, true); + max->cur = ilk_cursor_wm_reg_max(display, level); + max->fbc = ilk_fbc_wm_reg_max(display); } -static bool ilk_validate_wm_level(struct drm_i915_private *i915, +static bool ilk_validate_wm_level(struct intel_display *display, int level, const struct ilk_wm_maximums *max, struct intel_wm_level *result) @@ -2679,15 +2677,15 @@ static bool ilk_validate_wm_level(struct drm_i915_private *i915, */ if (level == 0 && !result->enable) { if (result->pri_val > max->pri) - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Primary WM%d too large %u (max %u)\n", level, result->pri_val, max->pri); if (result->spr_val > max->spr) - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Sprite WM%d too large %u (max %u)\n", level, result->spr_val, max->spr); if (result->cur_val > max->cur) - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Cursor WM%d too large %u (max %u)\n", level, result->cur_val, max->cur); @@ -2700,7 +2698,7 @@ static bool ilk_validate_wm_level(struct drm_i915_private *i915, return ret; } -static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, +static void ilk_compute_wm_level(struct intel_display *display, const struct intel_crtc *crtc, int level, struct intel_crtc_state *crtc_state, @@ -2709,9 +2707,9 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, const struct intel_plane_state *curstate, struct intel_wm_level *result) { - u16 pri_latency = dev_priv->display.wm.pri_latency[level]; - u16 spr_latency = dev_priv->display.wm.spr_latency[level]; - u16 cur_latency = dev_priv->display.wm.cur_latency[level]; + u16 pri_latency = display->wm.pri_latency[level]; + u16 spr_latency = display->wm.spr_latency[level]; + u16 cur_latency = display->wm.cur_latency[level]; /* WM1+ latency values stored in 0.5us units */ if (level > 0) { @@ -2735,11 +2733,12 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, result->enable = true; } -static void hsw_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) +static void hsw_read_wm_latency(struct intel_display *display, u16 wm[]) { + struct drm_i915_private *i915 = to_i915(display->drm); u64 sskpd; - i915->display.wm.num_levels = 5; + display->wm.num_levels = 5; sskpd = intel_uncore_read64(&i915->uncore, MCH_SSKPD); @@ -2752,11 +2751,12 @@ static void hsw_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) wm[4] = REG_FIELD_GET64(SSKPD_WM4_MASK_HSW, sskpd); } -static void snb_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) +static void snb_read_wm_latency(struct intel_display *display, u16 wm[]) { + struct drm_i915_private *i915 = to_i915(display->drm); u32 sskpd; - i915->display.wm.num_levels = 4; + display->wm.num_levels = 4; sskpd = intel_uncore_read(&i915->uncore, MCH_SSKPD); @@ -2766,11 +2766,12 @@ static void snb_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) wm[3] = REG_FIELD_GET(SSKPD_WM3_MASK_SNB, sskpd); } -static void ilk_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) +static void ilk_read_wm_latency(struct intel_display *display, u16 wm[]) { + struct drm_i915_private *i915 = to_i915(display->drm); u32 mltr; - i915->display.wm.num_levels = 3; + display->wm.num_levels = 3; mltr = intel_uncore_read(&i915->uncore, MLTR_ILK); @@ -2780,24 +2781,21 @@ static void ilk_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) wm[2] = REG_FIELD_GET(MLTR_WM2_MASK, mltr); } -static void intel_fixup_spr_wm_latency(struct drm_i915_private *dev_priv, - u16 wm[5]) +static void intel_fixup_spr_wm_latency(struct intel_display *display, u16 wm[5]) { /* ILK sprite LP0 latency is 1300 ns */ - if (DISPLAY_VER(dev_priv) == 5) + if (DISPLAY_VER(display) == 5) wm[0] = 13; } -static void intel_fixup_cur_wm_latency(struct drm_i915_private *dev_priv, - u16 wm[5]) +static void intel_fixup_cur_wm_latency(struct intel_display *display, u16 wm[5]) { /* ILK cursor LP0 latency is 1300 ns */ - if (DISPLAY_VER(dev_priv) == 5) + if (DISPLAY_VER(display) == 5) wm[0] = 13; } -static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv, - u16 wm[5], u16 min) +static bool ilk_increase_wm_latency(struct intel_display *display, u16 wm[5], u16 min) { int level; @@ -2805,13 +2803,13 @@ static bool ilk_increase_wm_latency(struct drm_i915_private *dev_priv, return false; wm[0] = max(wm[0], min); - for (level = 1; level < dev_priv->display.wm.num_levels; level++) + for (level = 1; level < display->wm.num_levels; level++) wm[level] = max_t(u16, wm[level], DIV_ROUND_UP(min, 5)); return true; } -static void snb_wm_latency_quirk(struct drm_i915_private *dev_priv) +static void snb_wm_latency_quirk(struct intel_display *display) { bool changed; @@ -2819,21 +2817,21 @@ static void snb_wm_latency_quirk(struct drm_i915_private *dev_priv) * The BIOS provided WM memory latency values are often * inadequate for high resolution displays. Adjust them. */ - changed = ilk_increase_wm_latency(dev_priv, dev_priv->display.wm.pri_latency, 12); - changed |= ilk_increase_wm_latency(dev_priv, dev_priv->display.wm.spr_latency, 12); - changed |= ilk_increase_wm_latency(dev_priv, dev_priv->display.wm.cur_latency, 12); + changed = ilk_increase_wm_latency(display, display->wm.pri_latency, 12); + changed |= ilk_increase_wm_latency(display, display->wm.spr_latency, 12); + changed |= ilk_increase_wm_latency(display, display->wm.cur_latency, 12); if (!changed) return; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "WM latency values increased to avoid potential underruns\n"); - intel_print_wm_latency(dev_priv, "Primary", dev_priv->display.wm.pri_latency); - intel_print_wm_latency(dev_priv, "Sprite", dev_priv->display.wm.spr_latency); - intel_print_wm_latency(dev_priv, "Cursor", dev_priv->display.wm.cur_latency); + intel_print_wm_latency(display, "Primary", display->wm.pri_latency); + intel_print_wm_latency(display, "Sprite", display->wm.spr_latency); + intel_print_wm_latency(display, "Cursor", display->wm.cur_latency); } -static void snb_wm_lp3_irq_quirk(struct drm_i915_private *dev_priv) +static void snb_wm_lp3_irq_quirk(struct intel_display *display) { /* * On some SNB machines (Thinkpad X220 Tablet at least) @@ -2846,50 +2844,50 @@ static void snb_wm_lp3_irq_quirk(struct drm_i915_private *dev_priv) * interrupts only. To play it safe we disable LP3 * watermarks entirely. */ - if (dev_priv->display.wm.pri_latency[3] == 0 && - dev_priv->display.wm.spr_latency[3] == 0 && - dev_priv->display.wm.cur_latency[3] == 0) + if (display->wm.pri_latency[3] == 0 && + display->wm.spr_latency[3] == 0 && + display->wm.cur_latency[3] == 0) return; - dev_priv->display.wm.pri_latency[3] = 0; - dev_priv->display.wm.spr_latency[3] = 0; - dev_priv->display.wm.cur_latency[3] = 0; + display->wm.pri_latency[3] = 0; + display->wm.spr_latency[3] = 0; + display->wm.cur_latency[3] = 0; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "LP3 watermarks disabled due to potential for lost interrupts\n"); - intel_print_wm_latency(dev_priv, "Primary", dev_priv->display.wm.pri_latency); - intel_print_wm_latency(dev_priv, "Sprite", dev_priv->display.wm.spr_latency); - intel_print_wm_latency(dev_priv, "Cursor", dev_priv->display.wm.cur_latency); + intel_print_wm_latency(display, "Primary", display->wm.pri_latency); + intel_print_wm_latency(display, "Sprite", display->wm.spr_latency); + intel_print_wm_latency(display, "Cursor", display->wm.cur_latency); } -static void ilk_setup_wm_latency(struct drm_i915_private *dev_priv) +static void ilk_setup_wm_latency(struct intel_display *display) { - if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) - hsw_read_wm_latency(dev_priv, dev_priv->display.wm.pri_latency); - else if (DISPLAY_VER(dev_priv) >= 6) - snb_read_wm_latency(dev_priv, dev_priv->display.wm.pri_latency); + if (display->platform.broadwell || display->platform.haswell) + hsw_read_wm_latency(display, display->wm.pri_latency); + else if (DISPLAY_VER(display) >= 6) + snb_read_wm_latency(display, display->wm.pri_latency); else - ilk_read_wm_latency(dev_priv, dev_priv->display.wm.pri_latency); + ilk_read_wm_latency(display, display->wm.pri_latency); - memcpy(dev_priv->display.wm.spr_latency, dev_priv->display.wm.pri_latency, - sizeof(dev_priv->display.wm.pri_latency)); - memcpy(dev_priv->display.wm.cur_latency, dev_priv->display.wm.pri_latency, - sizeof(dev_priv->display.wm.pri_latency)); + memcpy(display->wm.spr_latency, display->wm.pri_latency, + sizeof(display->wm.pri_latency)); + memcpy(display->wm.cur_latency, display->wm.pri_latency, + sizeof(display->wm.pri_latency)); - intel_fixup_spr_wm_latency(dev_priv, dev_priv->display.wm.spr_latency); - intel_fixup_cur_wm_latency(dev_priv, dev_priv->display.wm.cur_latency); + intel_fixup_spr_wm_latency(display, display->wm.spr_latency); + intel_fixup_cur_wm_latency(display, display->wm.cur_latency); - intel_print_wm_latency(dev_priv, "Primary", dev_priv->display.wm.pri_latency); - intel_print_wm_latency(dev_priv, "Sprite", dev_priv->display.wm.spr_latency); - intel_print_wm_latency(dev_priv, "Cursor", dev_priv->display.wm.cur_latency); + intel_print_wm_latency(display, "Primary", display->wm.pri_latency); + intel_print_wm_latency(display, "Sprite", display->wm.spr_latency); + intel_print_wm_latency(display, "Cursor", display->wm.cur_latency); - if (DISPLAY_VER(dev_priv) == 6) { - snb_wm_latency_quirk(dev_priv); - snb_wm_lp3_irq_quirk(dev_priv); + if (DISPLAY_VER(display) == 6) { + snb_wm_latency_quirk(display); + snb_wm_lp3_irq_quirk(display); } } -static bool ilk_validate_pipe_wm(struct drm_i915_private *dev_priv, +static bool ilk_validate_pipe_wm(struct intel_display *display, struct intel_pipe_wm *pipe_wm) { /* LP0 watermark maximums depend on this pipe alone */ @@ -2901,11 +2899,11 @@ static bool ilk_validate_pipe_wm(struct drm_i915_private *dev_priv, struct ilk_wm_maximums max; /* LP0 watermarks always use 1/2 DDB partitioning */ - ilk_compute_wm_maximums(dev_priv, 0, &config, INTEL_DDB_PART_1_2, &max); + ilk_compute_wm_maximums(display, 0, &config, INTEL_DDB_PART_1_2, &max); /* At least LP0 must be valid */ - if (!ilk_validate_wm_level(dev_priv, 0, &max, &pipe_wm->wm[0])) { - drm_dbg_kms(&dev_priv->drm, "LP0 watermark invalid\n"); + if (!ilk_validate_wm_level(display, 0, &max, &pipe_wm->wm[0])) { + drm_dbg_kms(display->drm, "LP0 watermark invalid\n"); return false; } @@ -2916,7 +2914,7 @@ static bool ilk_validate_pipe_wm(struct drm_i915_private *dev_priv, static int ilk_compute_pipe_wm(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_pipe_wm *pipe_wm; @@ -2943,10 +2941,10 @@ static int ilk_compute_pipe_wm(struct intel_atomic_state *state, pipe_wm->sprites_enabled = crtc_state->active_planes & BIT(PLANE_SPRITE0); pipe_wm->sprites_scaled = crtc_state->scaled_planes & BIT(PLANE_SPRITE0); - usable_level = dev_priv->display.wm.num_levels - 1; + usable_level = display->wm.num_levels - 1; /* ILK/SNB: LP2+ watermarks only w/o sprites */ - if (DISPLAY_VER(dev_priv) < 7 && pipe_wm->sprites_enabled) + if (DISPLAY_VER(display) < 7 && pipe_wm->sprites_enabled) usable_level = 1; /* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */ @@ -2954,18 +2952,18 @@ static int ilk_compute_pipe_wm(struct intel_atomic_state *state, usable_level = 0; memset(&pipe_wm->wm, 0, sizeof(pipe_wm->wm)); - ilk_compute_wm_level(dev_priv, crtc, 0, crtc_state, + ilk_compute_wm_level(display, crtc, 0, crtc_state, pristate, sprstate, curstate, &pipe_wm->wm[0]); - if (!ilk_validate_pipe_wm(dev_priv, pipe_wm)) + if (!ilk_validate_pipe_wm(display, pipe_wm)) return -EINVAL; - ilk_compute_wm_reg_maximums(dev_priv, 1, &max); + ilk_compute_wm_reg_maximums(display, 1, &max); for (level = 1; level <= usable_level; level++) { struct intel_wm_level *wm = &pipe_wm->wm[level]; - ilk_compute_wm_level(dev_priv, crtc, level, crtc_state, + ilk_compute_wm_level(display, crtc, level, crtc_state, pristate, sprstate, curstate, wm); /* @@ -2973,7 +2971,7 @@ static int ilk_compute_pipe_wm(struct intel_atomic_state *state, * register maximums since such watermarks are * always invalid. */ - if (!ilk_validate_wm_level(dev_priv, level, &max, wm)) { + if (!ilk_validate_wm_level(display, level, &max, wm)) { memset(wm, 0, sizeof(*wm)); break; } @@ -2990,7 +2988,7 @@ static int ilk_compute_pipe_wm(struct intel_atomic_state *state, static int ilk_compute_intermediate_wm(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(crtc); struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_crtc_state *old_crtc_state = @@ -3015,7 +3013,7 @@ static int ilk_compute_intermediate_wm(struct intel_atomic_state *state, intermediate->sprites_enabled |= active->sprites_enabled; intermediate->sprites_scaled |= active->sprites_scaled; - for (level = 0; level < dev_priv->display.wm.num_levels; level++) { + for (level = 0; level < display->wm.num_levels; level++) { struct intel_wm_level *intermediate_wm = &intermediate->wm[level]; const struct intel_wm_level *active_wm = &active->wm[level]; @@ -3036,7 +3034,7 @@ static int ilk_compute_intermediate_wm(struct intel_atomic_state *state, * there's no safe way to transition from the old state to * the new state, so we need to fail the atomic transaction. */ - if (!ilk_validate_pipe_wm(dev_priv, intermediate)) + if (!ilk_validate_pipe_wm(display, intermediate)) return -EINVAL; /* @@ -3068,7 +3066,7 @@ static int ilk_compute_watermarks(struct intel_atomic_state *state, /* * Merge the watermarks from all active pipes for a specific level. */ -static void ilk_merge_wm_level(struct drm_i915_private *dev_priv, +static void ilk_merge_wm_level(struct intel_display *display, int level, struct intel_wm_level *ret_wm) { @@ -3076,7 +3074,7 @@ static void ilk_merge_wm_level(struct drm_i915_private *dev_priv, ret_wm->enable = true; - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { const struct intel_pipe_wm *active = &crtc->wm.active.ilk; const struct intel_wm_level *wm = &active->wm[level]; @@ -3101,31 +3099,31 @@ static void ilk_merge_wm_level(struct drm_i915_private *dev_priv, /* * Merge all low power watermarks for all active pipes. */ -static void ilk_wm_merge(struct drm_i915_private *dev_priv, +static void ilk_wm_merge(struct intel_display *display, const struct intel_wm_config *config, const struct ilk_wm_maximums *max, struct intel_pipe_wm *merged) { - int level, num_levels = dev_priv->display.wm.num_levels; + int level, num_levels = display->wm.num_levels; int last_enabled_level = num_levels - 1; /* ILK/SNB/IVB: LP1+ watermarks only w/ single pipe */ - if ((DISPLAY_VER(dev_priv) < 7 || IS_IVYBRIDGE(dev_priv)) && + if ((DISPLAY_VER(display) < 7 || display->platform.ivybridge) && config->num_pipes_active > 1) last_enabled_level = 0; /* ILK: FBC WM must be disabled always */ - merged->fbc_wm_enabled = DISPLAY_VER(dev_priv) >= 6; + merged->fbc_wm_enabled = DISPLAY_VER(display) >= 6; /* merge each WM1+ level */ for (level = 1; level < num_levels; level++) { struct intel_wm_level *wm = &merged->wm[level]; - ilk_merge_wm_level(dev_priv, level, wm); + ilk_merge_wm_level(display, level, wm); if (level > last_enabled_level) wm->enable = false; - else if (!ilk_validate_wm_level(dev_priv, level, max, wm)) + else if (!ilk_validate_wm_level(display, level, max, wm)) /* make sure all following levels get disabled */ last_enabled_level = level - 1; @@ -3141,8 +3139,8 @@ static void ilk_wm_merge(struct drm_i915_private *dev_priv, } /* ILK: LP2+ must be disabled when FBC WM is disabled but FBC enabled */ - if (DISPLAY_VER(dev_priv) == 5 && HAS_FBC(dev_priv) && - dev_priv->display.params.enable_fbc && !merged->fbc_wm_enabled) { + if (DISPLAY_VER(display) == 5 && HAS_FBC(display) && + display->params.enable_fbc && !merged->fbc_wm_enabled) { for (level = 2; level < num_levels; level++) { struct intel_wm_level *wm = &merged->wm[level]; @@ -3158,16 +3156,16 @@ static int ilk_wm_lp_to_level(int wm_lp, const struct intel_pipe_wm *pipe_wm) } /* The value we need to program into the WM_LPx latency field */ -static unsigned int ilk_wm_lp_latency(struct drm_i915_private *dev_priv, +static unsigned int ilk_wm_lp_latency(struct intel_display *display, int level) { - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) + if (display->platform.haswell || display->platform.broadwell) return 2 * level; else - return dev_priv->display.wm.pri_latency[level]; + return display->wm.pri_latency[level]; } -static void ilk_compute_wm_results(struct drm_i915_private *dev_priv, +static void ilk_compute_wm_results(struct intel_display *display, const struct intel_pipe_wm *merged, enum intel_ddb_partitioning partitioning, struct ilk_wm_values *results) @@ -3191,14 +3189,14 @@ static void ilk_compute_wm_results(struct drm_i915_private *dev_priv, * disabled. Doing otherwise could cause underruns. */ results->wm_lp[wm_lp - 1] = - WM_LP_LATENCY(ilk_wm_lp_latency(dev_priv, level)) | + WM_LP_LATENCY(ilk_wm_lp_latency(display, level)) | WM_LP_PRIMARY(r->pri_val) | WM_LP_CURSOR(r->cur_val); if (r->enable) results->wm_lp[wm_lp - 1] |= WM_LP_ENABLE; - if (DISPLAY_VER(dev_priv) >= 8) + if (DISPLAY_VER(display) >= 8) results->wm_lp[wm_lp - 1] |= WM_LP_FBC_BDW(r->fbc_val); else results->wm_lp[wm_lp - 1] |= WM_LP_FBC_ILK(r->fbc_val); @@ -3209,19 +3207,19 @@ static void ilk_compute_wm_results(struct drm_i915_private *dev_priv, * Always set WM_LP_SPRITE_EN when spr_val != 0, even if the * level is disabled. Doing otherwise could cause underruns. */ - if (DISPLAY_VER(dev_priv) < 7 && r->spr_val) { - drm_WARN_ON(&dev_priv->drm, wm_lp != 1); + if (DISPLAY_VER(display) < 7 && r->spr_val) { + drm_WARN_ON(display->drm, wm_lp != 1); results->wm_lp_spr[wm_lp - 1] |= WM_LP_SPRITE_ENABLE; } } /* LP0 register values */ - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { enum pipe pipe = crtc->pipe; const struct intel_pipe_wm *pipe_wm = &crtc->wm.active.ilk; const struct intel_wm_level *r = &pipe_wm->wm[0]; - if (drm_WARN_ON(&dev_priv->drm, !r->enable)) + if (drm_WARN_ON(display->drm, !r->enable)) continue; results->wm_pipe[pipe] = @@ -3236,13 +3234,13 @@ static void ilk_compute_wm_results(struct drm_i915_private *dev_priv, * case both are at the same level. Prefer r1 in case they're the same. */ static struct intel_pipe_wm * -ilk_find_best_result(struct drm_i915_private *dev_priv, +ilk_find_best_result(struct intel_display *display, struct intel_pipe_wm *r1, struct intel_pipe_wm *r2) { int level, level1 = 0, level2 = 0; - for (level = 1; level < dev_priv->display.wm.num_levels; level++) { + for (level = 1; level < display->wm.num_levels; level++) { if (r1->wm[level].enable) level1 = level; if (r2->wm[level].enable) @@ -3268,7 +3266,7 @@ ilk_find_best_result(struct drm_i915_private *dev_priv, #define WM_DIRTY_FBC (1 << 24) #define WM_DIRTY_DDB (1 << 25) -static unsigned int ilk_compute_wm_dirty(struct drm_i915_private *dev_priv, +static unsigned int ilk_compute_wm_dirty(struct intel_display *display, const struct ilk_wm_values *old, const struct ilk_wm_values *new) { @@ -3276,7 +3274,7 @@ static unsigned int ilk_compute_wm_dirty(struct drm_i915_private *dev_priv, enum pipe pipe; int wm_lp; - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { if (old->wm_pipe[pipe] != new->wm_pipe[pipe]) { dirty |= WM_DIRTY_PIPE(pipe); /* Must disable LP1+ watermarks too */ @@ -3314,25 +3312,25 @@ static unsigned int ilk_compute_wm_dirty(struct drm_i915_private *dev_priv, return dirty; } -static bool _ilk_disable_lp_wm(struct drm_i915_private *dev_priv, +static bool _ilk_disable_lp_wm(struct intel_display *display, unsigned int dirty) { - struct ilk_wm_values *previous = &dev_priv->display.wm.hw; + struct ilk_wm_values *previous = &display->wm.hw; bool changed = false; if (dirty & WM_DIRTY_LP(3) && previous->wm_lp[2] & WM_LP_ENABLE) { previous->wm_lp[2] &= ~WM_LP_ENABLE; - intel_uncore_write(&dev_priv->uncore, WM3_LP_ILK, previous->wm_lp[2]); + intel_de_write(display, WM3_LP_ILK, previous->wm_lp[2]); changed = true; } if (dirty & WM_DIRTY_LP(2) && previous->wm_lp[1] & WM_LP_ENABLE) { previous->wm_lp[1] &= ~WM_LP_ENABLE; - intel_uncore_write(&dev_priv->uncore, WM2_LP_ILK, previous->wm_lp[1]); + intel_de_write(display, WM2_LP_ILK, previous->wm_lp[1]); changed = true; } if (dirty & WM_DIRTY_LP(1) && previous->wm_lp[0] & WM_LP_ENABLE) { previous->wm_lp[0] &= ~WM_LP_ENABLE; - intel_uncore_write(&dev_priv->uncore, WM1_LP_ILK, previous->wm_lp[0]); + intel_de_write(display, WM1_LP_ILK, previous->wm_lp[0]); changed = true; } @@ -3348,73 +3346,73 @@ static bool _ilk_disable_lp_wm(struct drm_i915_private *dev_priv, * The spec says we shouldn't write when we don't need, because every write * causes WMs to be re-evaluated, expending some power. */ -static void ilk_write_wm_values(struct drm_i915_private *dev_priv, +static void ilk_write_wm_values(struct intel_display *display, struct ilk_wm_values *results) { - struct ilk_wm_values *previous = &dev_priv->display.wm.hw; + struct ilk_wm_values *previous = &display->wm.hw; unsigned int dirty; - dirty = ilk_compute_wm_dirty(dev_priv, previous, results); + dirty = ilk_compute_wm_dirty(display, previous, results); if (!dirty) return; - _ilk_disable_lp_wm(dev_priv, dirty); + _ilk_disable_lp_wm(display, dirty); if (dirty & WM_DIRTY_PIPE(PIPE_A)) - intel_uncore_write(&dev_priv->uncore, WM0_PIPE_ILK(PIPE_A), results->wm_pipe[0]); + intel_de_write(display, WM0_PIPE_ILK(PIPE_A), results->wm_pipe[0]); if (dirty & WM_DIRTY_PIPE(PIPE_B)) - intel_uncore_write(&dev_priv->uncore, WM0_PIPE_ILK(PIPE_B), results->wm_pipe[1]); + intel_de_write(display, WM0_PIPE_ILK(PIPE_B), results->wm_pipe[1]); if (dirty & WM_DIRTY_PIPE(PIPE_C)) - intel_uncore_write(&dev_priv->uncore, WM0_PIPE_ILK(PIPE_C), results->wm_pipe[2]); + intel_de_write(display, WM0_PIPE_ILK(PIPE_C), results->wm_pipe[2]); if (dirty & WM_DIRTY_DDB) { - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) - intel_uncore_rmw(&dev_priv->uncore, WM_MISC, WM_MISC_DATA_PARTITION_5_6, - results->partitioning == INTEL_DDB_PART_1_2 ? 0 : - WM_MISC_DATA_PARTITION_5_6); + if (display->platform.haswell || display->platform.broadwell) + intel_de_rmw(display, WM_MISC, WM_MISC_DATA_PARTITION_5_6, + results->partitioning == INTEL_DDB_PART_1_2 ? 0 : + WM_MISC_DATA_PARTITION_5_6); else - intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL2, DISP_DATA_PARTITION_5_6, - results->partitioning == INTEL_DDB_PART_1_2 ? 0 : - DISP_DATA_PARTITION_5_6); + intel_de_rmw(display, DISP_ARB_CTL2, DISP_DATA_PARTITION_5_6, + results->partitioning == INTEL_DDB_PART_1_2 ? 0 : + DISP_DATA_PARTITION_5_6); } if (dirty & WM_DIRTY_FBC) - intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, DISP_FBC_WM_DIS, - results->enable_fbc_wm ? 0 : DISP_FBC_WM_DIS); + intel_de_rmw(display, DISP_ARB_CTL, DISP_FBC_WM_DIS, + results->enable_fbc_wm ? 0 : DISP_FBC_WM_DIS); if (dirty & WM_DIRTY_LP(1) && previous->wm_lp_spr[0] != results->wm_lp_spr[0]) - intel_uncore_write(&dev_priv->uncore, WM1S_LP_ILK, results->wm_lp_spr[0]); + intel_de_write(display, WM1S_LP_ILK, results->wm_lp_spr[0]); - if (DISPLAY_VER(dev_priv) >= 7) { + if (DISPLAY_VER(display) >= 7) { if (dirty & WM_DIRTY_LP(2) && previous->wm_lp_spr[1] != results->wm_lp_spr[1]) - intel_uncore_write(&dev_priv->uncore, WM2S_LP_IVB, results->wm_lp_spr[1]); + intel_de_write(display, WM2S_LP_IVB, results->wm_lp_spr[1]); if (dirty & WM_DIRTY_LP(3) && previous->wm_lp_spr[2] != results->wm_lp_spr[2]) - intel_uncore_write(&dev_priv->uncore, WM3S_LP_IVB, results->wm_lp_spr[2]); + intel_de_write(display, WM3S_LP_IVB, results->wm_lp_spr[2]); } if (dirty & WM_DIRTY_LP(1) && previous->wm_lp[0] != results->wm_lp[0]) - intel_uncore_write(&dev_priv->uncore, WM1_LP_ILK, results->wm_lp[0]); + intel_de_write(display, WM1_LP_ILK, results->wm_lp[0]); if (dirty & WM_DIRTY_LP(2) && previous->wm_lp[1] != results->wm_lp[1]) - intel_uncore_write(&dev_priv->uncore, WM2_LP_ILK, results->wm_lp[1]); + intel_de_write(display, WM2_LP_ILK, results->wm_lp[1]); if (dirty & WM_DIRTY_LP(3) && previous->wm_lp[2] != results->wm_lp[2]) - intel_uncore_write(&dev_priv->uncore, WM3_LP_ILK, results->wm_lp[2]); + intel_de_write(display, WM3_LP_ILK, results->wm_lp[2]); - dev_priv->display.wm.hw = *results; + display->wm.hw = *results; } -bool ilk_disable_cxsr(struct drm_i915_private *dev_priv) +bool ilk_disable_cxsr(struct intel_display *display) { - return _ilk_disable_lp_wm(dev_priv, WM_DIRTY_LP_ALL); + return _ilk_disable_lp_wm(display, WM_DIRTY_LP_ALL); } -static void ilk_compute_wm_config(struct drm_i915_private *dev_priv, +static void ilk_compute_wm_config(struct intel_display *display, struct intel_wm_config *config) { struct intel_crtc *crtc; /* Compute the currently _active_ config */ - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { const struct intel_pipe_wm *wm = &crtc->wm.active.ilk; if (!wm->pipe_enabled) @@ -3426,7 +3424,7 @@ static void ilk_compute_wm_config(struct drm_i915_private *dev_priv, } } -static void ilk_program_watermarks(struct drm_i915_private *dev_priv) +static void ilk_program_watermarks(struct intel_display *display) { struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm; struct ilk_wm_maximums max; @@ -3434,18 +3432,18 @@ static void ilk_program_watermarks(struct drm_i915_private *dev_priv) struct ilk_wm_values results = {}; enum intel_ddb_partitioning partitioning; - ilk_compute_wm_config(dev_priv, &config); + ilk_compute_wm_config(display, &config); - ilk_compute_wm_maximums(dev_priv, 1, &config, INTEL_DDB_PART_1_2, &max); - ilk_wm_merge(dev_priv, &config, &max, &lp_wm_1_2); + ilk_compute_wm_maximums(display, 1, &config, INTEL_DDB_PART_1_2, &max); + ilk_wm_merge(display, &config, &max, &lp_wm_1_2); /* 5/6 split only in single pipe config on IVB+ */ - if (DISPLAY_VER(dev_priv) >= 7 && + if (DISPLAY_VER(display) >= 7 && config.num_pipes_active == 1 && config.sprites_enabled) { - ilk_compute_wm_maximums(dev_priv, 1, &config, INTEL_DDB_PART_5_6, &max); - ilk_wm_merge(dev_priv, &config, &max, &lp_wm_5_6); + ilk_compute_wm_maximums(display, 1, &config, INTEL_DDB_PART_5_6, &max); + ilk_wm_merge(display, &config, &max, &lp_wm_5_6); - best_lp_wm = ilk_find_best_result(dev_priv, &lp_wm_1_2, &lp_wm_5_6); + best_lp_wm = ilk_find_best_result(display, &lp_wm_1_2, &lp_wm_5_6); } else { best_lp_wm = &lp_wm_1_2; } @@ -3453,50 +3451,49 @@ static void ilk_program_watermarks(struct drm_i915_private *dev_priv) partitioning = (best_lp_wm == &lp_wm_1_2) ? INTEL_DDB_PART_1_2 : INTEL_DDB_PART_5_6; - ilk_compute_wm_results(dev_priv, best_lp_wm, partitioning, &results); + ilk_compute_wm_results(display, best_lp_wm, partitioning, &results); - ilk_write_wm_values(dev_priv, &results); + ilk_write_wm_values(display, &results); } static void ilk_initial_watermarks(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(crtc); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - mutex_lock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); crtc->wm.active.ilk = crtc_state->wm.ilk.intermediate; - ilk_program_watermarks(dev_priv); - mutex_unlock(&dev_priv->display.wm.wm_mutex); + ilk_program_watermarks(display); + mutex_unlock(&display->wm.wm_mutex); } static void ilk_optimize_watermarks(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(crtc); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); if (!crtc_state->wm.need_postvbl_update) return; - mutex_lock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); crtc->wm.active.ilk = crtc_state->wm.ilk.optimal; - ilk_program_watermarks(dev_priv); - mutex_unlock(&dev_priv->display.wm.wm_mutex); + ilk_program_watermarks(display); + mutex_unlock(&display->wm.wm_mutex); } static void ilk_pipe_wm_get_hw_state(struct intel_crtc *crtc) { - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); - struct ilk_wm_values *hw = &dev_priv->display.wm.hw; + struct intel_display *display = to_intel_display(crtc); + struct ilk_wm_values *hw = &display->wm.hw; struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_pipe_wm *active = &crtc_state->wm.ilk.optimal; enum pipe pipe = crtc->pipe; - hw->wm_pipe[pipe] = intel_uncore_read(&dev_priv->uncore, WM0_PIPE_ILK(pipe)); + hw->wm_pipe[pipe] = intel_de_read(display, WM0_PIPE_ILK(pipe)); memset(active, 0, sizeof(*active)); @@ -3523,7 +3520,7 @@ static void ilk_pipe_wm_get_hw_state(struct intel_crtc *crtc) * should be marked as enabled but zeroed, * which is what we'd compute them to. */ - for (level = 0; level < dev_priv->display.wm.num_levels; level++) + for (level = 0; level < display->wm.num_levels; level++) active->wm[level].enable = true; } @@ -3572,7 +3569,7 @@ static int ilk_sanitize_watermarks_add_affected(struct drm_atomic_state *state) * through the atomic check code to calculate new watermark values in the * state object. */ -void ilk_wm_sanitize(struct drm_i915_private *dev_priv) +void ilk_wm_sanitize(struct intel_display *display) { struct drm_atomic_state *state; struct intel_atomic_state *intel_state; @@ -3583,14 +3580,14 @@ void ilk_wm_sanitize(struct drm_i915_private *dev_priv) int i; /* Only supported on platforms that use atomic watermark design */ - if (!dev_priv->display.funcs.wm->optimize_watermarks) + if (!display->funcs.wm->optimize_watermarks) return; - if (drm_WARN_ON(&dev_priv->drm, DISPLAY_VER(dev_priv) >= 9)) + if (drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 9)) return; - state = drm_atomic_state_alloc(&dev_priv->drm); - if (drm_WARN_ON(&dev_priv->drm, !state)) + state = drm_atomic_state_alloc(display->drm); + if (drm_WARN_ON(display->drm, !state)) return; intel_state = to_intel_atomic_state(state); @@ -3606,14 +3603,14 @@ retry: * intermediate watermarks (since we don't trust the current * watermarks). */ - if (!HAS_GMCH(dev_priv)) + if (!HAS_GMCH(display)) intel_state->skip_intermediate_wm = true; ret = ilk_sanitize_watermarks_add_affected(state); if (ret) goto fail; - ret = intel_atomic_check(&dev_priv->drm, state); + ret = intel_atomic_check(display->drm, state); if (ret) goto fail; @@ -3643,7 +3640,7 @@ fail: * If this actually happens, we'll have to just leave the * BIOS-programmed watermarks untouched and hope for the best. */ - drm_WARN(&dev_priv->drm, ret, + drm_WARN(display->drm, ret, "Could not determine valid watermarks for inherited state\n"); drm_atomic_state_put(state); @@ -3657,18 +3654,18 @@ fail: #define _FW_WM_VLV(value, plane) \ (((value) & DSPFW_ ## plane ## _MASK_VLV) >> DSPFW_ ## plane ## _SHIFT) -static void g4x_read_wm_values(struct drm_i915_private *dev_priv, +static void g4x_read_wm_values(struct intel_display *display, struct g4x_wm_values *wm) { u32 tmp; - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW1(dev_priv)); + tmp = intel_de_read(display, DSPFW1(display)); wm->sr.plane = _FW_WM(tmp, SR); wm->pipe[PIPE_B].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORB); wm->pipe[PIPE_B].plane[PLANE_PRIMARY] = _FW_WM(tmp, PLANEB); wm->pipe[PIPE_A].plane[PLANE_PRIMARY] = _FW_WM(tmp, PLANEA); - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW2(dev_priv)); + tmp = intel_de_read(display, DSPFW2(display)); wm->fbc_en = tmp & DSPFW_FBC_SR_EN; wm->sr.fbc = _FW_WM(tmp, FBC_SR); wm->hpll.fbc = _FW_WM(tmp, FBC_HPLL_SR); @@ -3676,21 +3673,21 @@ static void g4x_read_wm_values(struct drm_i915_private *dev_priv, wm->pipe[PIPE_A].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORA); wm->pipe[PIPE_A].plane[PLANE_SPRITE0] = _FW_WM(tmp, SPRITEA); - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW3(dev_priv)); + tmp = intel_de_read(display, DSPFW3(display)); wm->hpll_en = tmp & DSPFW_HPLL_SR_EN; wm->sr.cursor = _FW_WM(tmp, CURSOR_SR); wm->hpll.cursor = _FW_WM(tmp, HPLL_CURSOR); wm->hpll.plane = _FW_WM(tmp, HPLL_SR); } -static void vlv_read_wm_values(struct drm_i915_private *dev_priv, +static void vlv_read_wm_values(struct intel_display *display, struct vlv_wm_values *wm) { enum pipe pipe; u32 tmp; - for_each_pipe(dev_priv, pipe) { - tmp = intel_uncore_read(&dev_priv->uncore, VLV_DDL(pipe)); + for_each_pipe(display, pipe) { + tmp = intel_de_read(display, VLV_DDL(pipe)); wm->ddl[pipe].plane[PLANE_PRIMARY] = (tmp >> DDL_PLANE_SHIFT) & (DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK); @@ -3702,34 +3699,34 @@ static void vlv_read_wm_values(struct drm_i915_private *dev_priv, (tmp >> DDL_SPRITE_SHIFT(1)) & (DDL_PRECISION_HIGH | DRAIN_LATENCY_MASK); } - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW1(dev_priv)); + tmp = intel_de_read(display, DSPFW1(display)); wm->sr.plane = _FW_WM(tmp, SR); wm->pipe[PIPE_B].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORB); wm->pipe[PIPE_B].plane[PLANE_PRIMARY] = _FW_WM_VLV(tmp, PLANEB); wm->pipe[PIPE_A].plane[PLANE_PRIMARY] = _FW_WM_VLV(tmp, PLANEA); - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW2(dev_priv)); + tmp = intel_de_read(display, DSPFW2(display)); wm->pipe[PIPE_A].plane[PLANE_SPRITE1] = _FW_WM_VLV(tmp, SPRITEB); wm->pipe[PIPE_A].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORA); wm->pipe[PIPE_A].plane[PLANE_SPRITE0] = _FW_WM_VLV(tmp, SPRITEA); - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW3(dev_priv)); + tmp = intel_de_read(display, DSPFW3(display)); wm->sr.cursor = _FW_WM(tmp, CURSOR_SR); - if (IS_CHERRYVIEW(dev_priv)) { - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW7_CHV); + if (display->platform.cherryview) { + tmp = intel_de_read(display, DSPFW7_CHV); wm->pipe[PIPE_B].plane[PLANE_SPRITE1] = _FW_WM_VLV(tmp, SPRITED); wm->pipe[PIPE_B].plane[PLANE_SPRITE0] = _FW_WM_VLV(tmp, SPRITEC); - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW8_CHV); + tmp = intel_de_read(display, DSPFW8_CHV); wm->pipe[PIPE_C].plane[PLANE_SPRITE1] = _FW_WM_VLV(tmp, SPRITEF); wm->pipe[PIPE_C].plane[PLANE_SPRITE0] = _FW_WM_VLV(tmp, SPRITEE); - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW9_CHV); + tmp = intel_de_read(display, DSPFW9_CHV); wm->pipe[PIPE_C].plane[PLANE_PRIMARY] = _FW_WM_VLV(tmp, PLANEC); wm->pipe[PIPE_C].plane[PLANE_CURSOR] = _FW_WM(tmp, CURSORC); - tmp = intel_uncore_read(&dev_priv->uncore, DSPHOWM); + tmp = intel_de_read(display, DSPHOWM); wm->sr.plane |= _FW_WM(tmp, SR_HI) << 9; wm->pipe[PIPE_C].plane[PLANE_SPRITE1] |= _FW_WM(tmp, SPRITEF_HI) << 8; wm->pipe[PIPE_C].plane[PLANE_SPRITE0] |= _FW_WM(tmp, SPRITEE_HI) << 8; @@ -3741,11 +3738,11 @@ static void vlv_read_wm_values(struct drm_i915_private *dev_priv, wm->pipe[PIPE_A].plane[PLANE_SPRITE0] |= _FW_WM(tmp, SPRITEA_HI) << 8; wm->pipe[PIPE_A].plane[PLANE_PRIMARY] |= _FW_WM(tmp, PLANEA_HI) << 8; } else { - tmp = intel_uncore_read(&dev_priv->uncore, DSPFW7); + tmp = intel_de_read(display, DSPFW7); wm->pipe[PIPE_B].plane[PLANE_SPRITE1] = _FW_WM_VLV(tmp, SPRITED); wm->pipe[PIPE_B].plane[PLANE_SPRITE0] = _FW_WM_VLV(tmp, SPRITEC); - tmp = intel_uncore_read(&dev_priv->uncore, DSPHOWM); + tmp = intel_de_read(display, DSPHOWM); wm->sr.plane |= _FW_WM(tmp, SR_HI) << 9; wm->pipe[PIPE_B].plane[PLANE_SPRITE1] |= _FW_WM(tmp, SPRITED_HI) << 8; wm->pipe[PIPE_B].plane[PLANE_SPRITE0] |= _FW_WM(tmp, SPRITEC_HI) << 8; @@ -3759,16 +3756,16 @@ static void vlv_read_wm_values(struct drm_i915_private *dev_priv, #undef _FW_WM #undef _FW_WM_VLV -static void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv) +static void g4x_wm_get_hw_state(struct intel_display *display) { - struct g4x_wm_values *wm = &dev_priv->display.wm.g4x; + struct g4x_wm_values *wm = &display->wm.g4x; struct intel_crtc *crtc; - g4x_read_wm_values(dev_priv, wm); + g4x_read_wm_values(display, wm); - wm->cxsr = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF) & FW_BLC_SELF_EN; + wm->cxsr = intel_de_read(display, FW_BLC_SELF) & FW_BLC_SELF_EN; - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct g4x_wm_state *active = &crtc->wm.active.g4x; @@ -3833,7 +3830,7 @@ static void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv) crtc_state->wm.g4x.optimal = *active; crtc_state->wm.g4x.intermediate = *active; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Initial watermarks: pipe %c, plane=%d, cursor=%d, sprite=%d\n", pipe_name(pipe), wm->pipe[pipe].plane[PLANE_PRIMARY], @@ -3841,26 +3838,25 @@ static void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv) wm->pipe[pipe].plane[PLANE_SPRITE0]); } - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Initial SR watermarks: plane=%d, cursor=%d fbc=%d\n", wm->sr.plane, wm->sr.cursor, wm->sr.fbc); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Initial HPLL watermarks: plane=%d, SR cursor=%d fbc=%d\n", wm->hpll.plane, wm->hpll.cursor, wm->hpll.fbc); - drm_dbg_kms(&dev_priv->drm, "Initial SR=%s HPLL=%s FBC=%s\n", + drm_dbg_kms(display->drm, "Initial SR=%s HPLL=%s FBC=%s\n", str_yes_no(wm->cxsr), str_yes_no(wm->hpll_en), str_yes_no(wm->fbc_en)); } -static void g4x_wm_sanitize(struct drm_i915_private *dev_priv) +static void g4x_wm_sanitize(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; struct intel_plane *plane; struct intel_crtc *crtc; - mutex_lock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); - for_each_intel_plane(&dev_priv->drm, plane) { + for_each_intel_plane(display->drm, plane) { struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe); struct intel_crtc_state *crtc_state = @@ -3873,7 +3869,7 @@ static void g4x_wm_sanitize(struct drm_i915_private *dev_priv) if (plane_state->uapi.visible) continue; - for (level = 0; level < dev_priv->display.wm.num_levels; level++) { + for (level = 0; level < display->wm.num_levels; level++) { struct g4x_pipe_wm *raw = &crtc_state->wm.g4x.raw[level]; @@ -3884,36 +3880,37 @@ static void g4x_wm_sanitize(struct drm_i915_private *dev_priv) } } - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); int ret; ret = _g4x_compute_pipe_wm(crtc_state); - drm_WARN_ON(&dev_priv->drm, ret); + drm_WARN_ON(display->drm, ret); crtc_state->wm.g4x.intermediate = crtc_state->wm.g4x.optimal; crtc->wm.active.g4x = crtc_state->wm.g4x.optimal; } - g4x_program_watermarks(dev_priv); + g4x_program_watermarks(display); - mutex_unlock(&dev_priv->display.wm.wm_mutex); + mutex_unlock(&display->wm.wm_mutex); } -static void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv) +static void vlv_wm_get_hw_state(struct intel_display *display) { - struct vlv_wm_values *wm = &dev_priv->display.wm.vlv; + struct drm_i915_private *dev_priv = to_i915(display->drm); + struct vlv_wm_values *wm = &display->wm.vlv; struct intel_crtc *crtc; u32 val; - vlv_read_wm_values(dev_priv, wm); + vlv_read_wm_values(display, wm); - wm->cxsr = intel_uncore_read(&dev_priv->uncore, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; + wm->cxsr = intel_de_read(display, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; wm->level = VLV_WM_LEVEL_PM2; - if (IS_CHERRYVIEW(dev_priv)) { + if (display->platform.cherryview) { vlv_punit_get(dev_priv); val = vlv_punit_read(dev_priv, PUNIT_REG_DSPSSPM); @@ -3935,10 +3932,10 @@ static void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv) if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2) & FORCE_DDR_FREQ_REQ_ACK) == 0, 3)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Punit not acking DDR DVFS request, " "assuming DDR DVFS is disabled\n"); - dev_priv->display.wm.num_levels = VLV_WM_LEVEL_PM5 + 1; + display->wm.num_levels = VLV_WM_LEVEL_PM5 + 1; } else { val = vlv_punit_read(dev_priv, PUNIT_REG_DDR_SETUP2); if ((val & FORCE_DDR_HIGH_FREQ) == 0) @@ -3948,7 +3945,7 @@ static void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv) vlv_punit_put(dev_priv); } - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct vlv_wm_state *active = &crtc->wm.active.vlv; @@ -3988,7 +3985,7 @@ static void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv) crtc_state->wm.vlv.optimal = *active; crtc_state->wm.vlv.intermediate = *active; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Initial watermarks: pipe %c, plane=%d, cursor=%d, sprite0=%d, sprite1=%d\n", pipe_name(pipe), wm->pipe[pipe].plane[PLANE_PRIMARY], @@ -3997,20 +3994,19 @@ static void vlv_wm_get_hw_state(struct drm_i915_private *dev_priv) wm->pipe[pipe].plane[PLANE_SPRITE1]); } - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Initial watermarks: SR plane=%d, SR cursor=%d level=%d cxsr=%d\n", wm->sr.plane, wm->sr.cursor, wm->level, wm->cxsr); } -static void vlv_wm_sanitize(struct drm_i915_private *dev_priv) +static void vlv_wm_sanitize(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; struct intel_plane *plane; struct intel_crtc *crtc; - mutex_lock(&dev_priv->display.wm.wm_mutex); + mutex_lock(&display->wm.wm_mutex); - for_each_intel_plane(&dev_priv->drm, plane) { + for_each_intel_plane(display->drm, plane) { struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe); struct intel_crtc_state *crtc_state = @@ -4023,7 +4019,7 @@ static void vlv_wm_sanitize(struct drm_i915_private *dev_priv) if (plane_state->uapi.visible) continue; - for (level = 0; level < dev_priv->display.wm.num_levels; level++) { + for (level = 0; level < display->wm.num_levels; level++) { struct g4x_pipe_wm *raw = &crtc_state->wm.vlv.raw[level]; @@ -4031,33 +4027,33 @@ static void vlv_wm_sanitize(struct drm_i915_private *dev_priv) } } - for_each_intel_crtc(&dev_priv->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); int ret; ret = _vlv_compute_pipe_wm(crtc_state); - drm_WARN_ON(&dev_priv->drm, ret); + drm_WARN_ON(display->drm, ret); crtc_state->wm.vlv.intermediate = crtc_state->wm.vlv.optimal; crtc->wm.active.vlv = crtc_state->wm.vlv.optimal; } - vlv_program_watermarks(dev_priv); + vlv_program_watermarks(display); - mutex_unlock(&dev_priv->display.wm.wm_mutex); + mutex_unlock(&display->wm.wm_mutex); } /* * FIXME should probably kill this and improve * the real watermark readout/sanitation instead */ -static void ilk_init_lp_watermarks(struct drm_i915_private *dev_priv) +static void ilk_init_lp_watermarks(struct intel_display *display) { - intel_uncore_rmw(&dev_priv->uncore, WM3_LP_ILK, WM_LP_ENABLE, 0); - intel_uncore_rmw(&dev_priv->uncore, WM2_LP_ILK, WM_LP_ENABLE, 0); - intel_uncore_rmw(&dev_priv->uncore, WM1_LP_ILK, WM_LP_ENABLE, 0); + intel_de_rmw(display, WM3_LP_ILK, WM_LP_ENABLE, 0); + intel_de_rmw(display, WM2_LP_ILK, WM_LP_ENABLE, 0); + intel_de_rmw(display, WM1_LP_ILK, WM_LP_ENABLE, 0); /* * Don't touch WM_LP_SPRITE_ENABLE here. @@ -4065,37 +4061,37 @@ static void ilk_init_lp_watermarks(struct drm_i915_private *dev_priv) */ } -static void ilk_wm_get_hw_state(struct drm_i915_private *dev_priv) +static void ilk_wm_get_hw_state(struct intel_display *display) { - struct ilk_wm_values *hw = &dev_priv->display.wm.hw; + struct ilk_wm_values *hw = &display->wm.hw; struct intel_crtc *crtc; - ilk_init_lp_watermarks(dev_priv); + ilk_init_lp_watermarks(display); - for_each_intel_crtc(&dev_priv->drm, crtc) + for_each_intel_crtc(display->drm, crtc) ilk_pipe_wm_get_hw_state(crtc); - hw->wm_lp[0] = intel_uncore_read(&dev_priv->uncore, WM1_LP_ILK); - hw->wm_lp[1] = intel_uncore_read(&dev_priv->uncore, WM2_LP_ILK); - hw->wm_lp[2] = intel_uncore_read(&dev_priv->uncore, WM3_LP_ILK); + hw->wm_lp[0] = intel_de_read(display, WM1_LP_ILK); + hw->wm_lp[1] = intel_de_read(display, WM2_LP_ILK); + hw->wm_lp[2] = intel_de_read(display, WM3_LP_ILK); - hw->wm_lp_spr[0] = intel_uncore_read(&dev_priv->uncore, WM1S_LP_ILK); - if (DISPLAY_VER(dev_priv) >= 7) { - hw->wm_lp_spr[1] = intel_uncore_read(&dev_priv->uncore, WM2S_LP_IVB); - hw->wm_lp_spr[2] = intel_uncore_read(&dev_priv->uncore, WM3S_LP_IVB); + hw->wm_lp_spr[0] = intel_de_read(display, WM1S_LP_ILK); + if (DISPLAY_VER(display) >= 7) { + hw->wm_lp_spr[1] = intel_de_read(display, WM2S_LP_IVB); + hw->wm_lp_spr[2] = intel_de_read(display, WM3S_LP_IVB); } - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) - hw->partitioning = (intel_uncore_read(&dev_priv->uncore, WM_MISC) & + if (display->platform.haswell || display->platform.broadwell) + hw->partitioning = (intel_de_read(display, WM_MISC) & WM_MISC_DATA_PARTITION_5_6) ? INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2; - else if (IS_IVYBRIDGE(dev_priv)) - hw->partitioning = (intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL2) & + else if (display->platform.ivybridge) + hw->partitioning = (intel_de_read(display, DISP_ARB_CTL2) & DISP_DATA_PARTITION_5_6) ? INTEL_DDB_PART_5_6 : INTEL_DDB_PART_1_2; hw->enable_fbc_wm = - !(intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL) & DISP_FBC_WM_DIS); + !(intel_de_read(display, DISP_ARB_CTL) & DISP_FBC_WM_DIS); } static const struct intel_wm_funcs ilk_wm_funcs = { @@ -4145,39 +4141,39 @@ static const struct intel_wm_funcs i845_wm_funcs = { static const struct intel_wm_funcs nop_funcs = { }; -void i9xx_wm_init(struct drm_i915_private *dev_priv) +void i9xx_wm_init(struct intel_display *display) { /* For FIFO watermark updates */ - if (HAS_PCH_SPLIT(dev_priv)) { - ilk_setup_wm_latency(dev_priv); - dev_priv->display.funcs.wm = &ilk_wm_funcs; - } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { - vlv_setup_wm_latency(dev_priv); - dev_priv->display.funcs.wm = &vlv_wm_funcs; - } else if (IS_G4X(dev_priv)) { - g4x_setup_wm_latency(dev_priv); - dev_priv->display.funcs.wm = &g4x_wm_funcs; - } else if (IS_PINEVIEW(dev_priv)) { - if (!pnv_get_cxsr_latency(dev_priv)) { - drm_info(&dev_priv->drm, "Unknown FSB/MEM, disabling CxSR\n"); + if (HAS_PCH_SPLIT(display)) { + ilk_setup_wm_latency(display); + display->funcs.wm = &ilk_wm_funcs; + } else if (display->platform.valleyview || display->platform.cherryview) { + vlv_setup_wm_latency(display); + display->funcs.wm = &vlv_wm_funcs; + } else if (display->platform.g4x) { + g4x_setup_wm_latency(display); + display->funcs.wm = &g4x_wm_funcs; + } else if (display->platform.pineview) { + if (!pnv_get_cxsr_latency(display)) { + drm_info(display->drm, "Unknown FSB/MEM, disabling CxSR\n"); /* Disable CxSR and never update its watermark again */ - intel_set_memory_cxsr(dev_priv, false); - dev_priv->display.funcs.wm = &nop_funcs; + intel_set_memory_cxsr(display, false); + display->funcs.wm = &nop_funcs; } else { - dev_priv->display.funcs.wm = &pnv_wm_funcs; + display->funcs.wm = &pnv_wm_funcs; } - } else if (DISPLAY_VER(dev_priv) == 4) { - dev_priv->display.funcs.wm = &i965_wm_funcs; - } else if (DISPLAY_VER(dev_priv) == 3) { - dev_priv->display.funcs.wm = &i9xx_wm_funcs; - } else if (DISPLAY_VER(dev_priv) == 2) { - if (INTEL_NUM_PIPES(dev_priv) == 1) - dev_priv->display.funcs.wm = &i845_wm_funcs; + } else if (DISPLAY_VER(display) == 4) { + display->funcs.wm = &i965_wm_funcs; + } else if (DISPLAY_VER(display) == 3) { + display->funcs.wm = &i9xx_wm_funcs; + } else if (DISPLAY_VER(display) == 2) { + if (INTEL_NUM_PIPES(display) == 1) + display->funcs.wm = &i845_wm_funcs; else - dev_priv->display.funcs.wm = &i9xx_wm_funcs; + display->funcs.wm = &i9xx_wm_funcs; } else { - drm_err(&dev_priv->drm, + drm_err(display->drm, "unexpected fall-through in %s\n", __func__); - dev_priv->display.funcs.wm = &nop_funcs; + display->funcs.wm = &nop_funcs; } } diff --git a/drivers/gpu/drm/i915/display/i9xx_wm.h b/drivers/gpu/drm/i915/display/i9xx_wm.h index 06ac37c6c94b..7bb363b2a756 100644 --- a/drivers/gpu/drm/i915/display/i9xx_wm.h +++ b/drivers/gpu/drm/i915/display/i9xx_wm.h @@ -8,28 +8,28 @@ #include <linux/types.h> -struct drm_i915_private; struct intel_crtc_state; +struct intel_display; struct intel_plane_state; #ifdef I915 -bool ilk_disable_cxsr(struct drm_i915_private *i915); -void ilk_wm_sanitize(struct drm_i915_private *i915); -bool intel_set_memory_cxsr(struct drm_i915_private *i915, bool enable); -void i9xx_wm_init(struct drm_i915_private *i915); +bool ilk_disable_cxsr(struct intel_display *display); +void ilk_wm_sanitize(struct intel_display *display); +bool intel_set_memory_cxsr(struct intel_display *display, bool enable); +void i9xx_wm_init(struct intel_display *display); #else -static inline bool ilk_disable_cxsr(struct drm_i915_private *i915) +static inline bool ilk_disable_cxsr(struct intel_display *display) { return false; } -static inline void ilk_wm_sanitize(struct drm_i915_private *i915) +static inline void ilk_wm_sanitize(struct intel_display *display) { } -static inline bool intel_set_memory_cxsr(struct drm_i915_private *i915, bool enable) +static inline bool intel_set_memory_cxsr(struct intel_display *display, bool enable) { return false; } -static inline void i9xx_wm_init(struct drm_i915_private *i915) +static inline void i9xx_wm_init(struct intel_display *display) { } #endif diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 402b7b2e1829..ca7033251e91 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -29,6 +29,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_fixed.h> #include <drm/drm_mipi_dsi.h> +#include <drm/drm_print.h> #include <drm/drm_probe_helper.h> #include "i915_reg.h" @@ -1826,107 +1827,56 @@ static const struct mipi_dsi_host_ops gen11_dsi_host_ops = { .transfer = gen11_dsi_host_transfer, }; -#define ICL_PREPARE_CNT_MAX 0x7 -#define ICL_CLK_ZERO_CNT_MAX 0xf -#define ICL_TRAIL_CNT_MAX 0x7 -#define ICL_TCLK_PRE_CNT_MAX 0x3 -#define ICL_TCLK_POST_CNT_MAX 0x7 -#define ICL_HS_ZERO_CNT_MAX 0xf -#define ICL_EXIT_ZERO_CNT_MAX 0x7 - static void icl_dphy_param_init(struct intel_dsi *intel_dsi) { - struct intel_display *display = to_intel_display(&intel_dsi->base); struct intel_connector *connector = intel_dsi->attached_connector; struct mipi_config *mipi_config = connector->panel.vbt.dsi.config; u32 tlpx_ns; - u32 prepare_cnt, exit_zero_cnt, clk_zero_cnt, trail_cnt; - u32 ths_prepare_ns, tclk_trail_ns; - u32 hs_zero_cnt; - u32 tclk_pre_cnt; + u32 tclk_prepare_esc_clk, tclk_zero_esc_clk, tclk_pre_esc_clk; + u32 ths_prepare_esc_clk, ths_zero_esc_clk, ths_exit_esc_clk; tlpx_ns = intel_dsi_tlpx_ns(intel_dsi); - tclk_trail_ns = max(mipi_config->tclk_trail, mipi_config->ths_trail); - ths_prepare_ns = max(mipi_config->ths_prepare, - mipi_config->tclk_prepare); - /* - * prepare cnt in escape clocks - * this field represents a hexadecimal value with a precision - * of 1.2 – i.e. the most significant bit is the integer - * and the least significant 2 bits are fraction bits. - * so, the field can represent a range of 0.25 to 1.75 + * The clock and data lane prepare timing parameters are in expressed in + * units of 1/4 escape clocks, and all the other timings parameters in + * escape clocks. */ - prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * 4, tlpx_ns); - if (prepare_cnt > ICL_PREPARE_CNT_MAX) { - drm_dbg_kms(display->drm, "prepare_cnt out of range (%d)\n", - prepare_cnt); - prepare_cnt = ICL_PREPARE_CNT_MAX; - } + tclk_prepare_esc_clk = DIV_ROUND_UP(mipi_config->tclk_prepare * 4, tlpx_ns); + tclk_prepare_esc_clk = min(tclk_prepare_esc_clk, 7); - /* clk zero count in escape clocks */ - clk_zero_cnt = DIV_ROUND_UP(mipi_config->tclk_prepare_clkzero - - ths_prepare_ns, tlpx_ns); - if (clk_zero_cnt > ICL_CLK_ZERO_CNT_MAX) { - drm_dbg_kms(display->drm, - "clk_zero_cnt out of range (%d)\n", clk_zero_cnt); - clk_zero_cnt = ICL_CLK_ZERO_CNT_MAX; - } + tclk_zero_esc_clk = DIV_ROUND_UP(mipi_config->tclk_prepare_clkzero - + mipi_config->tclk_prepare, tlpx_ns); + tclk_zero_esc_clk = min(tclk_zero_esc_clk, 15); - /* trail cnt in escape clocks*/ - trail_cnt = DIV_ROUND_UP(tclk_trail_ns, tlpx_ns); - if (trail_cnt > ICL_TRAIL_CNT_MAX) { - drm_dbg_kms(display->drm, "trail_cnt out of range (%d)\n", - trail_cnt); - trail_cnt = ICL_TRAIL_CNT_MAX; - } + tclk_pre_esc_clk = DIV_ROUND_UP(mipi_config->tclk_pre, tlpx_ns); + tclk_pre_esc_clk = min(tclk_pre_esc_clk, 3); - /* tclk pre count in escape clocks */ - tclk_pre_cnt = DIV_ROUND_UP(mipi_config->tclk_pre, tlpx_ns); - if (tclk_pre_cnt > ICL_TCLK_PRE_CNT_MAX) { - drm_dbg_kms(display->drm, - "tclk_pre_cnt out of range (%d)\n", tclk_pre_cnt); - tclk_pre_cnt = ICL_TCLK_PRE_CNT_MAX; - } + ths_prepare_esc_clk = DIV_ROUND_UP(mipi_config->ths_prepare * 4, tlpx_ns); + ths_prepare_esc_clk = min(ths_prepare_esc_clk, 7); - /* hs zero cnt in escape clocks */ - hs_zero_cnt = DIV_ROUND_UP(mipi_config->ths_prepare_hszero - - ths_prepare_ns, tlpx_ns); - if (hs_zero_cnt > ICL_HS_ZERO_CNT_MAX) { - drm_dbg_kms(display->drm, "hs_zero_cnt out of range (%d)\n", - hs_zero_cnt); - hs_zero_cnt = ICL_HS_ZERO_CNT_MAX; - } + ths_zero_esc_clk = DIV_ROUND_UP(mipi_config->ths_prepare_hszero - + mipi_config->ths_prepare, tlpx_ns); + ths_zero_esc_clk = min(ths_zero_esc_clk, 15); - /* hs exit zero cnt in escape clocks */ - exit_zero_cnt = DIV_ROUND_UP(mipi_config->ths_exit, tlpx_ns); - if (exit_zero_cnt > ICL_EXIT_ZERO_CNT_MAX) { - drm_dbg_kms(display->drm, - "exit_zero_cnt out of range (%d)\n", - exit_zero_cnt); - exit_zero_cnt = ICL_EXIT_ZERO_CNT_MAX; - } + ths_exit_esc_clk = DIV_ROUND_UP(mipi_config->ths_exit, tlpx_ns); + ths_exit_esc_clk = min(ths_exit_esc_clk, 7); /* clock lane dphy timings */ intel_dsi->dphy_reg = (CLK_PREPARE_OVERRIDE | - CLK_PREPARE(prepare_cnt) | + CLK_PREPARE(tclk_prepare_esc_clk) | CLK_ZERO_OVERRIDE | - CLK_ZERO(clk_zero_cnt) | + CLK_ZERO(tclk_zero_esc_clk) | CLK_PRE_OVERRIDE | - CLK_PRE(tclk_pre_cnt) | - CLK_TRAIL_OVERRIDE | - CLK_TRAIL(trail_cnt)); + CLK_PRE(tclk_pre_esc_clk)); /* data lanes dphy timings */ intel_dsi->dphy_data_lane_reg = (HS_PREPARE_OVERRIDE | - HS_PREPARE(prepare_cnt) | + HS_PREPARE(ths_prepare_esc_clk) | HS_ZERO_OVERRIDE | - HS_ZERO(hs_zero_cnt) | - HS_TRAIL_OVERRIDE | - HS_TRAIL(trail_cnt) | + HS_ZERO(ths_zero_esc_clk) | HS_EXIT_OVERRIDE | - HS_EXIT(exit_zero_cnt)); + HS_EXIT(ths_exit_esc_clk)); intel_dsi_log_params(intel_dsi); } diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c index 55f3ae1e68c9..c176bdbc19a3 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); + } + } +} + +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_psr || !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)) { + 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..c9fe21e3e72c 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,15 @@ 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_enable_sink(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_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index 03dc54c802d3..e83feca5c9c9 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -33,16 +33,17 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_fourcc.h> +#include <drm/drm_print.h> -#include "i915_drv.h" #include "intel_atomic.h" #include "intel_cdclk.h" +#include "intel_display_core.h" #include "intel_display_types.h" #include "intel_dp_tunnel.h" +#include "intel_fb.h" #include "intel_global_state.h" #include "intel_hdcp.h" #include "intel_psr.h" -#include "intel_fb.h" #include "skl_universal_plane.h" /** @@ -59,17 +60,16 @@ int intel_digital_connector_atomic_get_property(struct drm_connector *connector, struct drm_property *property, u64 *val) { - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(connector->dev); const struct intel_digital_connector_state *intel_conn_state = to_intel_digital_connector_state(state); - if (property == dev_priv->display.properties.force_audio) + if (property == display->properties.force_audio) *val = intel_conn_state->force_audio; - else if (property == dev_priv->display.properties.broadcast_rgb) + else if (property == display->properties.broadcast_rgb) *val = intel_conn_state->broadcast_rgb; else { - drm_dbg_atomic(&dev_priv->drm, + drm_dbg_atomic(display->drm, "Unknown property [PROP:%d:%s]\n", property->base.id, property->name); return -EINVAL; @@ -92,22 +92,21 @@ int intel_digital_connector_atomic_set_property(struct drm_connector *connector, struct drm_property *property, u64 val) { - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(connector->dev); struct intel_digital_connector_state *intel_conn_state = to_intel_digital_connector_state(state); - if (property == dev_priv->display.properties.force_audio) { + if (property == display->properties.force_audio) { intel_conn_state->force_audio = val; return 0; } - if (property == dev_priv->display.properties.broadcast_rgb) { + if (property == display->properties.broadcast_rgb) { intel_conn_state->broadcast_rgb = val; return 0; } - drm_dbg_atomic(&dev_priv->drm, "Unknown property [PROP:%d:%s]\n", + drm_dbg_atomic(display->drm, "Unknown property [PROP:%d:%s]\n", property->base.id, property->name); return -EINVAL; } diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c index 7276179df878..1bcfa5f4fd63 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c @@ -174,11 +174,27 @@ bool intel_plane_needs_physical(struct intel_plane *plane) DISPLAY_INFO(display)->cursor_needs_physical; } -bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier) +bool intel_plane_can_async_flip(struct intel_plane *plane, u32 format, + u64 modifier) { + if (intel_format_info_is_yuv_semiplanar(drm_format_info(format), modifier) || + format == DRM_FORMAT_C8) + return false; + return plane->can_async_flip && plane->can_async_flip(modifier); } +bool intel_plane_format_mod_supported_async(struct drm_plane *plane, + u32 format, + u64 modifier) +{ + if (!plane->funcs->format_mod_supported(plane, format, modifier)) + return false; + + return intel_plane_can_async_flip(to_intel_plane(plane), + format, modifier); +} + unsigned int intel_adjusted_rate(const struct drm_rect *src, const struct drm_rect *dst, unsigned int rate) diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h index 6efac923dcbc..317320c32285 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h @@ -21,7 +21,8 @@ enum plane_id; struct intel_plane * intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id); -bool intel_plane_can_async_flip(struct intel_plane *plane, u64 modifier); +bool intel_plane_can_async_flip(struct intel_plane *plane, u32 format, + u64 modifier); unsigned int intel_adjusted_rate(const struct drm_rect *src, const struct drm_rect *dst, unsigned int rate); @@ -89,5 +90,8 @@ int intel_atomic_add_affected_planes(struct intel_atomic_state *state, int intel_atomic_check_planes(struct intel_atomic_state *state); u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state); +bool intel_plane_format_mod_supported_async(struct drm_plane *plane, + u32 format, + u64 modifier); #endif /* __INTEL_ATOMIC_PLANE_H__ */ 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 178dc6c8de80..5827da586003 100644 --- a/drivers/gpu/drm/i915/display/intel_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_backlight.c @@ -10,12 +10,16 @@ #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" #include "intel_de.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dp_aux_backlight.h" #include "intel_dsi_dcs_backlight.h" @@ -472,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; @@ -485,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); @@ -502,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); @@ -901,11 +904,9 @@ static int intel_backlight_device_get_brightness(struct backlight_device *bd) { struct intel_connector *connector = bl_get_data(bd); struct intel_display *display = to_intel_display(connector); - struct drm_i915_private *i915 = to_i915(connector->base.dev); - intel_wakeref_t wakeref; int ret = 0; - with_intel_runtime_pm(&i915->runtime_pm, wakeref) { + with_intel_display_rpm(display) { u32 hw_level; drm_modeset_lock(&display->drm->mode_config.connection_mutex, NULL); @@ -1065,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; @@ -1074,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 */ @@ -1231,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; @@ -1260,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); @@ -1467,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; @@ -1483,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; @@ -1819,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) @@ -1827,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 a8d08d7d82b3..ba7b8938b17c 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -37,6 +37,7 @@ #include "i915_drv.h" #include "intel_display.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_gmbus.h" @@ -2244,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 { @@ -2864,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 */ @@ -2882,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); } @@ -3115,7 +3113,6 @@ static const struct vbt_header *intel_bios_get_vbt(struct intel_display *display { struct drm_i915_private *i915 = to_i915(display->drm); const struct vbt_header *vbt = NULL; - intel_wakeref_t wakeref; vbt = firmware_get_vbt(display, sizep); @@ -3126,12 +3123,12 @@ 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)) - with_intel_runtime_pm(&i915->runtime_pm, wakeref) + if (!vbt && display->platform.dgfx) + with_intel_display_rpm(display) vbt = oprom_get_vbt(display, intel_rom_spi(i915), sizep, "SPI flash"); if (!vbt) - with_intel_runtime_pm(&i915->runtime_pm, wakeref) + with_intel_display_rpm(display) vbt = oprom_get_vbt(display, intel_rom_pci(i915), sizep, "PCI ROM"); return vbt; 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_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 98b898a1de8f..a5dd2932b852 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -39,14 +39,15 @@ struct intel_qgv_info { u8 deinterleave; }; -static int dg1_mchbar_read_qgv_point_info(struct drm_i915_private *dev_priv, +static int dg1_mchbar_read_qgv_point_info(struct intel_display *display, struct intel_qgv_point *sp, int point) { + struct drm_i915_private *i915 = to_i915(display->drm); u32 dclk_ratio, dclk_reference; u32 val; - val = intel_uncore_read(&dev_priv->uncore, SA_PERF_STATUS_0_0_0_MCHBAR_PC); + val = intel_uncore_read(&i915->uncore, SA_PERF_STATUS_0_0_0_MCHBAR_PC); dclk_ratio = REG_FIELD_GET(DG1_QCLK_RATIO_MASK, val); if (val & DG1_QCLK_REFERENCE) dclk_reference = 6; /* 6 * 16.666 MHz = 100 MHz */ @@ -54,18 +55,18 @@ static int dg1_mchbar_read_qgv_point_info(struct drm_i915_private *dev_priv, dclk_reference = 8; /* 8 * 16.666 MHz = 133 MHz */ sp->dclk = DIV_ROUND_UP((16667 * dclk_ratio * dclk_reference) + 500, 1000); - val = intel_uncore_read(&dev_priv->uncore, SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU); + val = intel_uncore_read(&i915->uncore, SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU); if (val & DG1_GEAR_TYPE) sp->dclk *= 2; if (sp->dclk == 0) return -EINVAL; - val = intel_uncore_read(&dev_priv->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR); + val = intel_uncore_read(&i915->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR); sp->t_rp = REG_FIELD_GET(DG1_DRAM_T_RP_MASK, val); sp->t_rdpre = REG_FIELD_GET(DG1_DRAM_T_RDPRE_MASK, val); - val = intel_uncore_read(&dev_priv->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR_HIGH); + val = intel_uncore_read(&i915->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR_HIGH); sp->t_rcd = REG_FIELD_GET(DG1_DRAM_T_RCD_MASK, val); sp->t_ras = REG_FIELD_GET(DG1_DRAM_T_RAS_MASK, val); @@ -74,22 +75,23 @@ static int dg1_mchbar_read_qgv_point_info(struct drm_i915_private *dev_priv, return 0; } -static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv, +static int icl_pcode_read_qgv_point_info(struct intel_display *display, struct intel_qgv_point *sp, int point) { + struct drm_i915_private *i915 = to_i915(display->drm); u32 val = 0, val2 = 0; u16 dclk; int ret; - ret = snb_pcode_read(&dev_priv->uncore, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | + ret = snb_pcode_read(&i915->uncore, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | ICL_PCODE_MEM_SS_READ_QGV_POINT_INFO(point), &val, &val2); if (ret) return ret; dclk = val & 0xffff; - sp->dclk = DIV_ROUND_UP((16667 * dclk) + (DISPLAY_VER(dev_priv) >= 12 ? 500 : 0), + sp->dclk = DIV_ROUND_UP((16667 * dclk) + (DISPLAY_VER(display) >= 12 ? 500 : 0), 1000); sp->t_rp = (val & 0xff0000) >> 16; sp->t_rcd = (val & 0xff000000) >> 24; @@ -102,14 +104,15 @@ static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv, return 0; } -static int adls_pcode_read_psf_gv_point_info(struct drm_i915_private *dev_priv, - struct intel_psf_gv_point *points) +static int adls_pcode_read_psf_gv_point_info(struct intel_display *display, + struct intel_psf_gv_point *points) { + struct drm_i915_private *i915 = to_i915(display->drm); u32 val = 0; int ret; int i; - ret = snb_pcode_read(&dev_priv->uncore, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | + ret = snb_pcode_read(&i915->uncore, ICL_PCODE_MEM_SUBSYSYSTEM_INFO | ADL_PCODE_MEM_SS_READ_PSF_GV_INFO, &val, NULL); if (ret) return ret; @@ -122,10 +125,10 @@ static int adls_pcode_read_psf_gv_point_info(struct drm_i915_private *dev_priv, return 0; } -static u16 icl_qgv_points_mask(struct drm_i915_private *i915) +static u16 icl_qgv_points_mask(struct intel_display *display) { - unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; - unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; + unsigned int num_psf_gv_points = display->bw.max[0].num_psf_gv_points; + unsigned int num_qgv_points = display->bw.max[0].num_qgv_points; u16 qgv_points = 0, psf_points = 0; /* @@ -142,49 +145,51 @@ static u16 icl_qgv_points_mask(struct drm_i915_private *i915) return ICL_PCODE_REQ_QGV_PT(qgv_points) | ADLS_PCODE_REQ_PSF_PT(psf_points); } -static bool is_sagv_enabled(struct drm_i915_private *i915, u16 points_mask) +static bool is_sagv_enabled(struct intel_display *display, u16 points_mask) { - return !is_power_of_2(~points_mask & icl_qgv_points_mask(i915) & + return !is_power_of_2(~points_mask & icl_qgv_points_mask(display) & ICL_PCODE_REQ_QGV_PT_MASK); } -int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv, +int icl_pcode_restrict_qgv_points(struct intel_display *display, u32 points_mask) { + struct drm_i915_private *i915 = to_i915(display->drm); int ret; - if (DISPLAY_VER(dev_priv) >= 14) + if (DISPLAY_VER(display) >= 14) return 0; /* bspec says to keep retrying for at least 1 ms */ - ret = skl_pcode_request(&dev_priv->uncore, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG, + ret = skl_pcode_request(&i915->uncore, ICL_PCODE_SAGV_DE_MEM_SS_CONFIG, points_mask, ICL_PCODE_REP_QGV_MASK | ADLS_PCODE_REP_PSF_MASK, ICL_PCODE_REP_QGV_SAFE | ADLS_PCODE_REP_PSF_SAFE, 1); if (ret < 0) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "Failed to disable qgv points (0x%x) points: 0x%x\n", ret, points_mask); return ret; } - dev_priv->display.sagv.status = is_sagv_enabled(dev_priv, points_mask) ? + display->sagv.status = is_sagv_enabled(display, points_mask) ? I915_SAGV_ENABLED : I915_SAGV_DISABLED; return 0; } -static int mtl_read_qgv_point_info(struct drm_i915_private *dev_priv, +static int mtl_read_qgv_point_info(struct intel_display *display, struct intel_qgv_point *sp, int point) { + struct drm_i915_private *i915 = to_i915(display->drm); u32 val, val2; u16 dclk; - val = intel_uncore_read(&dev_priv->uncore, + val = intel_uncore_read(&i915->uncore, MTL_MEM_SS_INFO_QGV_POINT_LOW(point)); - val2 = intel_uncore_read(&dev_priv->uncore, + val2 = intel_uncore_read(&i915->uncore, MTL_MEM_SS_INFO_QGV_POINT_HIGH(point)); dclk = REG_FIELD_GET(MTL_DCLK_MASK, val); sp->dclk = DIV_ROUND_CLOSEST(16667 * dclk, 1000); @@ -200,29 +205,30 @@ static int mtl_read_qgv_point_info(struct drm_i915_private *dev_priv, } static int -intel_read_qgv_point_info(struct drm_i915_private *dev_priv, +intel_read_qgv_point_info(struct intel_display *display, struct intel_qgv_point *sp, int point) { - if (DISPLAY_VER(dev_priv) >= 14) - return mtl_read_qgv_point_info(dev_priv, sp, point); - else if (IS_DG1(dev_priv)) - return dg1_mchbar_read_qgv_point_info(dev_priv, sp, point); + if (DISPLAY_VER(display) >= 14) + return mtl_read_qgv_point_info(display, sp, point); + else if (display->platform.dg1) + return dg1_mchbar_read_qgv_point_info(display, sp, point); else - return icl_pcode_read_qgv_point_info(dev_priv, sp, point); + return icl_pcode_read_qgv_point_info(display, sp, point); } -static int icl_get_qgv_points(struct drm_i915_private *dev_priv, +static int icl_get_qgv_points(struct intel_display *display, struct intel_qgv_info *qi, bool is_y_tile) { - const struct dram_info *dram_info = &dev_priv->dram_info; + struct drm_i915_private *i915 = to_i915(display->drm); + const struct dram_info *dram_info = &i915->dram_info; int i, ret; qi->num_points = dram_info->num_qgv_points; qi->num_psf_points = dram_info->num_psf_gv_points; - if (DISPLAY_VER(dev_priv) >= 14) { + if (DISPLAY_VER(display) >= 14) { switch (dram_info->type) { case INTEL_DRAM_DDR4: qi->t_bl = 4; @@ -251,7 +257,7 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv, MISSING_CASE(dram_info->type); return -EINVAL; } - } else if (DISPLAY_VER(dev_priv) >= 12) { + } else if (DISPLAY_VER(display) >= 12) { switch (dram_info->type) { case INTEL_DRAM_DDR4: qi->t_bl = is_y_tile ? 8 : 4; @@ -266,7 +272,7 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv, qi->deinterleave = is_y_tile ? 1 : 2; break; case INTEL_DRAM_LPDDR4: - if (IS_ROCKETLAKE(dev_priv)) { + if (display->platform.rocketlake) { qi->t_bl = 8; qi->max_numchannels = 4; qi->channel_width = 32; @@ -285,39 +291,39 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv, qi->max_numchannels = 1; break; } - } else if (DISPLAY_VER(dev_priv) == 11) { - qi->t_bl = dev_priv->dram_info.type == INTEL_DRAM_DDR4 ? 4 : 8; + } else if (DISPLAY_VER(display) == 11) { + qi->t_bl = dram_info->type == INTEL_DRAM_DDR4 ? 4 : 8; qi->max_numchannels = 1; } - if (drm_WARN_ON(&dev_priv->drm, + if (drm_WARN_ON(display->drm, qi->num_points > ARRAY_SIZE(qi->points))) qi->num_points = ARRAY_SIZE(qi->points); for (i = 0; i < qi->num_points; i++) { struct intel_qgv_point *sp = &qi->points[i]; - ret = intel_read_qgv_point_info(dev_priv, sp, i); + ret = intel_read_qgv_point_info(display, sp, i); if (ret) { - drm_dbg_kms(&dev_priv->drm, "Could not read QGV %d info\n", i); + drm_dbg_kms(display->drm, "Could not read QGV %d info\n", i); return ret; } - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "QGV %d: DCLK=%d tRP=%d tRDPRE=%d tRAS=%d tRCD=%d tRC=%d\n", i, sp->dclk, sp->t_rp, sp->t_rdpre, sp->t_ras, sp->t_rcd, sp->t_rc); } if (qi->num_psf_points > 0) { - ret = adls_pcode_read_psf_gv_point_info(dev_priv, qi->psf_points); + ret = adls_pcode_read_psf_gv_point_info(display, qi->psf_points); if (ret) { - drm_err(&dev_priv->drm, "Failed to read PSF point data; PSF points will not be considered in bandwidth calculations.\n"); + drm_err(display->drm, "Failed to read PSF point data; PSF points will not be considered in bandwidth calculations.\n"); qi->num_psf_points = 0; } for (i = 0; i < qi->num_psf_points; i++) - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "PSF GV %d: CLK=%d \n", i, qi->psf_points[i].clk); } @@ -405,20 +411,28 @@ static const struct intel_sa_info xe2_hpd_ecc_sa_info = { /* Other values not used by simplified algorithm */ }; -static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel_sa_info *sa) +static const struct intel_sa_info xe3lpd_sa_info = { + .deburst = 32, + .deprogbwlimit = 65, /* GB/s */ + .displayrtids = 256, + .derating = 10, +}; + +static int icl_get_bw_info(struct intel_display *display, const struct intel_sa_info *sa) { + struct drm_i915_private *i915 = to_i915(display->drm); struct intel_qgv_info qi = {}; bool is_y_tile = true; /* assume y tile may be used */ - int num_channels = max_t(u8, 1, dev_priv->dram_info.num_channels); + int num_channels = max_t(u8, 1, i915->dram_info.num_channels); int ipqdepth, ipqdepthpch = 16; int dclk_max; int maxdebw; - int num_groups = ARRAY_SIZE(dev_priv->display.bw.max); + int num_groups = ARRAY_SIZE(display->bw.max); int i, ret; - ret = icl_get_qgv_points(dev_priv, &qi, is_y_tile); + ret = icl_get_qgv_points(display, &qi, is_y_tile); if (ret) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Failed to get memory subsystem information, ignoring bandwidth limits"); return ret; } @@ -429,7 +443,7 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel qi.deinterleave = DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2); for (i = 0; i < num_groups; i++) { - struct intel_bw_info *bi = &dev_priv->display.bw.max[i]; + struct intel_bw_info *bi = &display->bw.max[i]; int clpchgroup; int j; @@ -456,7 +470,7 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel bi->deratedbw[j] = min(maxdebw, bw * (100 - sa->derating) / 100); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "BW%d / QGV %d: num_planes=%d deratedbw=%u\n", i, j, bi->num_planes, bi->deratedbw[j]); } @@ -467,44 +481,45 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel * as it will fail and pointless anyway. */ if (qi.num_points == 1) - dev_priv->display.sagv.status = I915_SAGV_NOT_CONTROLLED; + display->sagv.status = I915_SAGV_NOT_CONTROLLED; else - dev_priv->display.sagv.status = I915_SAGV_ENABLED; + display->sagv.status = I915_SAGV_ENABLED; return 0; } -static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel_sa_info *sa) +static int tgl_get_bw_info(struct intel_display *display, const struct intel_sa_info *sa) { + struct drm_i915_private *i915 = to_i915(display->drm); struct intel_qgv_info qi = {}; - const struct dram_info *dram_info = &dev_priv->dram_info; + const struct dram_info *dram_info = &i915->dram_info; bool is_y_tile = true; /* assume y tile may be used */ - int num_channels = max_t(u8, 1, dev_priv->dram_info.num_channels); + int num_channels = max_t(u8, 1, dram_info->num_channels); int ipqdepth, ipqdepthpch = 16; int dclk_max; int maxdebw, peakbw; int clperchgroup; - int num_groups = ARRAY_SIZE(dev_priv->display.bw.max); + int num_groups = ARRAY_SIZE(display->bw.max); int i, ret; - ret = icl_get_qgv_points(dev_priv, &qi, is_y_tile); + ret = icl_get_qgv_points(display, &qi, is_y_tile); if (ret) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Failed to get memory subsystem information, ignoring bandwidth limits"); return ret; } - if (DISPLAY_VER(dev_priv) < 14 && + if (DISPLAY_VER(display) < 14 && (dram_info->type == INTEL_DRAM_LPDDR4 || dram_info->type == INTEL_DRAM_LPDDR5)) num_channels *= 2; qi.deinterleave = qi.deinterleave ? : DIV_ROUND_UP(num_channels, is_y_tile ? 4 : 2); - if (num_channels < qi.max_numchannels && DISPLAY_VER(dev_priv) >= 12) + if (num_channels < qi.max_numchannels && DISPLAY_VER(display) >= 12) qi.deinterleave = max(DIV_ROUND_UP(qi.deinterleave, 2), 1); - if (DISPLAY_VER(dev_priv) >= 12 && num_channels > qi.max_numchannels) - drm_warn(&dev_priv->drm, "Number of channels exceeds max number of channels."); + if (DISPLAY_VER(display) >= 12 && num_channels > qi.max_numchannels) + drm_warn(display->drm, "Number of channels exceeds max number of channels."); if (qi.max_numchannels != 0) num_channels = min_t(u8, num_channels, qi.max_numchannels); @@ -521,7 +536,7 @@ static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel clperchgroup = 4 * DIV_ROUND_UP(8, num_channels) * qi.deinterleave; for (i = 0; i < num_groups; i++) { - struct intel_bw_info *bi = &dev_priv->display.bw.max[i]; + struct intel_bw_info *bi = &display->bw.max[i]; struct intel_bw_info *bi_next; int clpchgroup; int j; @@ -529,7 +544,7 @@ static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel clpchgroup = (sa->deburst * qi.deinterleave / num_channels) << i; if (i < num_groups - 1) { - bi_next = &dev_priv->display.bw.max[i + 1]; + bi_next = &display->bw.max[i + 1]; if (clpchgroup < clperchgroup) bi_next->num_planes = (ipqdepth - clpchgroup) / @@ -561,7 +576,7 @@ static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel num_channels * qi.channel_width, 8); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "BW%d / QGV %d: num_planes=%d deratedbw=%u peakbw: %u\n", i, j, bi->num_planes, bi->deratedbw[j], bi->peakbw[j]); @@ -572,7 +587,7 @@ static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel bi->psf_bw[j] = adl_calc_psf_bw(sp->clk); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "BW%d / PSF GV %d: num_planes=%d bw=%u\n", i, j, bi->num_planes, bi->psf_bw[j]); } @@ -584,17 +599,17 @@ static int tgl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel * as it will fail and pointless anyway. */ if (qi.num_points == 1) - dev_priv->display.sagv.status = I915_SAGV_NOT_CONTROLLED; + display->sagv.status = I915_SAGV_NOT_CONTROLLED; else - dev_priv->display.sagv.status = I915_SAGV_ENABLED; + display->sagv.status = I915_SAGV_ENABLED; return 0; } -static void dg2_get_bw_info(struct drm_i915_private *i915) +static void dg2_get_bw_info(struct intel_display *display) { - unsigned int deratedbw = IS_DG2_G11(i915) ? 38000 : 50000; - int num_groups = ARRAY_SIZE(i915->display.bw.max); + unsigned int deratedbw = display->platform.dg2_g11 ? 38000 : 50000; + int num_groups = ARRAY_SIZE(display->bw.max); int i; /* @@ -605,7 +620,7 @@ static void dg2_get_bw_info(struct drm_i915_private *i915) * whereas DG2-G11 platforms have 38 GB/s. */ for (i = 0; i < num_groups; i++) { - struct intel_bw_info *bi = &i915->display.bw.max[i]; + struct intel_bw_info *bi = &display->bw.max[i]; bi->num_planes = 1; /* Need only one dummy QGV point per group */ @@ -613,20 +628,21 @@ static void dg2_get_bw_info(struct drm_i915_private *i915) bi->deratedbw[0] = deratedbw; } - i915->display.sagv.status = I915_SAGV_NOT_CONTROLLED; + display->sagv.status = I915_SAGV_NOT_CONTROLLED; } -static int xe2_hpd_get_bw_info(struct drm_i915_private *i915, +static int xe2_hpd_get_bw_info(struct intel_display *display, const struct intel_sa_info *sa) { + struct drm_i915_private *i915 = to_i915(display->drm); struct intel_qgv_info qi = {}; int num_channels = i915->dram_info.num_channels; int peakbw, maxdebw; int ret, i; - ret = icl_get_qgv_points(i915, &qi, true); + ret = icl_get_qgv_points(display, &qi, true); if (ret) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Failed to get memory subsystem information, ignoring bandwidth limits"); return ret; } @@ -638,33 +654,33 @@ static int xe2_hpd_get_bw_info(struct drm_i915_private *i915, const struct intel_qgv_point *point = &qi.points[i]; int bw = num_channels * (qi.channel_width / 8) * point->dclk; - i915->display.bw.max[0].deratedbw[i] = + display->bw.max[0].deratedbw[i] = min(maxdebw, (100 - sa->derating) * bw / 100); - i915->display.bw.max[0].peakbw[i] = bw; + display->bw.max[0].peakbw[i] = bw; - drm_dbg_kms(&i915->drm, "QGV %d: deratedbw=%u peakbw: %u\n", - i, i915->display.bw.max[0].deratedbw[i], - i915->display.bw.max[0].peakbw[i]); + drm_dbg_kms(display->drm, "QGV %d: deratedbw=%u peakbw: %u\n", + i, display->bw.max[0].deratedbw[i], + display->bw.max[0].peakbw[i]); } /* Bandwidth does not depend on # of planes; set all groups the same */ - i915->display.bw.max[0].num_planes = 1; - i915->display.bw.max[0].num_qgv_points = qi.num_points; - for (i = 1; i < ARRAY_SIZE(i915->display.bw.max); i++) - memcpy(&i915->display.bw.max[i], &i915->display.bw.max[0], - sizeof(i915->display.bw.max[0])); + display->bw.max[0].num_planes = 1; + display->bw.max[0].num_qgv_points = qi.num_points; + for (i = 1; i < ARRAY_SIZE(display->bw.max); i++) + memcpy(&display->bw.max[i], &display->bw.max[0], + sizeof(display->bw.max[0])); /* * Xe2_HPD should always have exactly two QGV points representing * battery and plugged-in operation. */ - drm_WARN_ON(&i915->drm, qi.num_points != 2); - i915->display.sagv.status = I915_SAGV_ENABLED; + drm_WARN_ON(display->drm, qi.num_points != 2); + display->sagv.status = I915_SAGV_ENABLED; return 0; } -static unsigned int icl_max_bw_index(struct drm_i915_private *dev_priv, +static unsigned int icl_max_bw_index(struct intel_display *display, int num_planes, int qgv_point) { int i; @@ -674,9 +690,9 @@ static unsigned int icl_max_bw_index(struct drm_i915_private *dev_priv, */ num_planes = max(1, num_planes); - for (i = 0; i < ARRAY_SIZE(dev_priv->display.bw.max); i++) { + for (i = 0; i < ARRAY_SIZE(display->bw.max); i++) { const struct intel_bw_info *bi = - &dev_priv->display.bw.max[i]; + &display->bw.max[i]; /* * Pcode will not expose all QGV points when @@ -692,7 +708,7 @@ static unsigned int icl_max_bw_index(struct drm_i915_private *dev_priv, return UINT_MAX; } -static unsigned int tgl_max_bw_index(struct drm_i915_private *dev_priv, +static unsigned int tgl_max_bw_index(struct intel_display *display, int num_planes, int qgv_point) { int i; @@ -702,9 +718,9 @@ static unsigned int tgl_max_bw_index(struct drm_i915_private *dev_priv, */ num_planes = max(1, num_planes); - for (i = ARRAY_SIZE(dev_priv->display.bw.max) - 1; i >= 0; i--) { + for (i = ARRAY_SIZE(display->bw.max) - 1; i >= 0; i--) { const struct intel_bw_info *bi = - &dev_priv->display.bw.max[i]; + &display->bw.max[i]; /* * Pcode will not expose all QGV points when @@ -720,57 +736,59 @@ static unsigned int tgl_max_bw_index(struct drm_i915_private *dev_priv, return 0; } -static unsigned int adl_psf_bw(struct drm_i915_private *dev_priv, +static unsigned int adl_psf_bw(struct intel_display *display, int psf_gv_point) { const struct intel_bw_info *bi = - &dev_priv->display.bw.max[0]; + &display->bw.max[0]; return bi->psf_bw[psf_gv_point]; } -static unsigned int icl_qgv_bw(struct drm_i915_private *i915, +static unsigned int icl_qgv_bw(struct intel_display *display, int num_active_planes, int qgv_point) { unsigned int idx; - if (DISPLAY_VER(i915) >= 12) - idx = tgl_max_bw_index(i915, num_active_planes, qgv_point); + if (DISPLAY_VER(display) >= 12) + idx = tgl_max_bw_index(display, num_active_planes, qgv_point); else - idx = icl_max_bw_index(i915, num_active_planes, qgv_point); + idx = icl_max_bw_index(display, num_active_planes, qgv_point); - if (idx >= ARRAY_SIZE(i915->display.bw.max)) + if (idx >= ARRAY_SIZE(display->bw.max)) return 0; - return i915->display.bw.max[idx].deratedbw[qgv_point]; + return display->bw.max[idx].deratedbw[qgv_point]; } -void intel_bw_init_hw(struct drm_i915_private *dev_priv) +void intel_bw_init_hw(struct intel_display *display) { - const struct dram_info *dram_info = &dev_priv->dram_info; + const struct dram_info *dram_info = &to_i915(display->drm)->dram_info; - if (!HAS_DISPLAY(dev_priv)) + if (!HAS_DISPLAY(display)) return; - if (DISPLAY_VERx100(dev_priv) >= 1401 && IS_DGFX(dev_priv) && + if (DISPLAY_VER(display) >= 30) + tgl_get_bw_info(display, &xe3lpd_sa_info); + else if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx && dram_info->type == INTEL_DRAM_GDDR_ECC) - xe2_hpd_get_bw_info(dev_priv, &xe2_hpd_ecc_sa_info); - else if (DISPLAY_VERx100(dev_priv) >= 1401 && IS_DGFX(dev_priv)) - xe2_hpd_get_bw_info(dev_priv, &xe2_hpd_sa_info); - else if (DISPLAY_VER(dev_priv) >= 14) - tgl_get_bw_info(dev_priv, &mtl_sa_info); - else if (IS_DG2(dev_priv)) - dg2_get_bw_info(dev_priv); - else if (IS_ALDERLAKE_P(dev_priv)) - tgl_get_bw_info(dev_priv, &adlp_sa_info); - else if (IS_ALDERLAKE_S(dev_priv)) - tgl_get_bw_info(dev_priv, &adls_sa_info); - else if (IS_ROCKETLAKE(dev_priv)) - tgl_get_bw_info(dev_priv, &rkl_sa_info); - else if (DISPLAY_VER(dev_priv) == 12) - tgl_get_bw_info(dev_priv, &tgl_sa_info); - else if (DISPLAY_VER(dev_priv) == 11) - icl_get_bw_info(dev_priv, &icl_sa_info); + xe2_hpd_get_bw_info(display, &xe2_hpd_ecc_sa_info); + else if (DISPLAY_VERx100(display) >= 1401 && display->platform.dgfx) + xe2_hpd_get_bw_info(display, &xe2_hpd_sa_info); + else if (DISPLAY_VER(display) >= 14) + tgl_get_bw_info(display, &mtl_sa_info); + else if (display->platform.dg2) + dg2_get_bw_info(display); + else if (display->platform.alderlake_p) + tgl_get_bw_info(display, &adlp_sa_info); + else if (display->platform.alderlake_s) + tgl_get_bw_info(display, &adls_sa_info); + else if (display->platform.rocketlake) + tgl_get_bw_info(display, &rkl_sa_info); + else if (DISPLAY_VER(display) == 12) + tgl_get_bw_info(display, &tgl_sa_info); + else if (DISPLAY_VER(display) == 11) + icl_get_bw_info(display, &icl_sa_info); } static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_state *crtc_state) @@ -784,8 +802,8 @@ static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_stat static unsigned int intel_bw_crtc_data_rate(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); unsigned int data_rate = 0; enum plane_id plane_id; @@ -799,7 +817,7 @@ static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_ data_rate += crtc_state->data_rate[plane_id]; - if (DISPLAY_VER(i915) < 11) + if (DISPLAY_VER(display) < 11) data_rate += crtc_state->data_rate_y[plane_id]; } @@ -807,39 +825,38 @@ static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_ } /* "Maximum Pipe Read Bandwidth" */ -static int intel_bw_crtc_min_cdclk(const struct intel_crtc_state *crtc_state) +static int intel_bw_crtc_min_cdclk(struct intel_display *display, + unsigned int data_rate) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); - - if (DISPLAY_VER(i915) < 12) + if (DISPLAY_VER(display) < 12) return 0; - return DIV_ROUND_UP_ULL(mul_u32_u32(intel_bw_crtc_data_rate(crtc_state), 10), 512); + return DIV_ROUND_UP_ULL(mul_u32_u32(data_rate, 10), 512); } -static unsigned int intel_bw_num_active_planes(struct drm_i915_private *dev_priv, +static unsigned int intel_bw_num_active_planes(struct intel_display *display, const struct intel_bw_state *bw_state) { unsigned int num_active_planes = 0; enum pipe pipe; - for_each_pipe(dev_priv, pipe) + for_each_pipe(display, pipe) num_active_planes += bw_state->num_active_planes[pipe]; return num_active_planes; } -static unsigned int intel_bw_data_rate(struct drm_i915_private *dev_priv, +static unsigned int intel_bw_data_rate(struct intel_display *display, const struct intel_bw_state *bw_state) { + struct drm_i915_private *i915 = to_i915(display->drm); unsigned int data_rate = 0; enum pipe pipe; - for_each_pipe(dev_priv, pipe) + for_each_pipe(display, pipe) data_rate += bw_state->data_rate[pipe]; - if (DISPLAY_VER(dev_priv) >= 13 && i915_vtd_active(dev_priv)) + if (DISPLAY_VER(display) >= 13 && i915_vtd_active(i915)) data_rate = DIV_ROUND_UP(data_rate * 105, 100); return data_rate; @@ -848,10 +865,10 @@ static unsigned int intel_bw_data_rate(struct drm_i915_private *dev_priv, struct intel_bw_state * intel_atomic_get_old_bw_state(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_global_state *bw_state; - bw_state = intel_atomic_get_old_global_obj_state(state, &dev_priv->display.bw.obj); + bw_state = intel_atomic_get_old_global_obj_state(state, &display->bw.obj); return to_intel_bw_state(bw_state); } @@ -859,10 +876,10 @@ intel_atomic_get_old_bw_state(struct intel_atomic_state *state) struct intel_bw_state * intel_atomic_get_new_bw_state(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_global_state *bw_state; - bw_state = intel_atomic_get_new_global_obj_state(state, &dev_priv->display.bw.obj); + bw_state = intel_atomic_get_new_global_obj_state(state, &display->bw.obj); return to_intel_bw_state(bw_state); } @@ -870,27 +887,27 @@ intel_atomic_get_new_bw_state(struct intel_atomic_state *state) struct intel_bw_state * intel_atomic_get_bw_state(struct intel_atomic_state *state) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_global_state *bw_state; - bw_state = intel_atomic_get_global_obj_state(state, &dev_priv->display.bw.obj); + bw_state = intel_atomic_get_global_obj_state(state, &display->bw.obj); if (IS_ERR(bw_state)) return ERR_CAST(bw_state); return to_intel_bw_state(bw_state); } -static unsigned int icl_max_bw_qgv_point_mask(struct drm_i915_private *i915, +static unsigned int icl_max_bw_qgv_point_mask(struct intel_display *display, int num_active_planes) { - unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; + unsigned int num_qgv_points = display->bw.max[0].num_qgv_points; unsigned int max_bw_point = 0; unsigned int max_bw = 0; int i; for (i = 0; i < num_qgv_points; i++) { unsigned int max_data_rate = - icl_qgv_bw(i915, num_active_planes, i); + icl_qgv_bw(display, num_active_planes, i); /* * We need to know which qgv point gives us @@ -909,23 +926,23 @@ static unsigned int icl_max_bw_qgv_point_mask(struct drm_i915_private *i915, return max_bw_point; } -static u16 icl_prepare_qgv_points_mask(struct drm_i915_private *i915, +static u16 icl_prepare_qgv_points_mask(struct intel_display *display, unsigned int qgv_points, unsigned int psf_points) { return ~(ICL_PCODE_REQ_QGV_PT(qgv_points) | - ADLS_PCODE_REQ_PSF_PT(psf_points)) & icl_qgv_points_mask(i915); + ADLS_PCODE_REQ_PSF_PT(psf_points)) & icl_qgv_points_mask(display); } -static unsigned int icl_max_bw_psf_gv_point_mask(struct drm_i915_private *i915) +static unsigned int icl_max_bw_psf_gv_point_mask(struct intel_display *display) { - unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; + unsigned int num_psf_gv_points = display->bw.max[0].num_psf_gv_points; unsigned int max_bw_point_mask = 0; unsigned int max_bw = 0; int i; for (i = 0; i < num_psf_gv_points; i++) { - unsigned int max_data_rate = adl_psf_bw(i915, i); + unsigned int max_data_rate = adl_psf_bw(display, i); if (max_data_rate > max_bw) { max_bw_point_mask = BIT(i); @@ -938,29 +955,29 @@ static unsigned int icl_max_bw_psf_gv_point_mask(struct drm_i915_private *i915) return max_bw_point_mask; } -static void icl_force_disable_sagv(struct drm_i915_private *i915, +static void icl_force_disable_sagv(struct intel_display *display, struct intel_bw_state *bw_state) { - unsigned int qgv_points = icl_max_bw_qgv_point_mask(i915, 0); - unsigned int psf_points = icl_max_bw_psf_gv_point_mask(i915); + unsigned int qgv_points = icl_max_bw_qgv_point_mask(display, 0); + unsigned int psf_points = icl_max_bw_psf_gv_point_mask(display); - bw_state->qgv_points_mask = icl_prepare_qgv_points_mask(i915, + bw_state->qgv_points_mask = icl_prepare_qgv_points_mask(display, qgv_points, psf_points); - drm_dbg_kms(&i915->drm, "Forcing SAGV disable: mask 0x%x\n", + drm_dbg_kms(display->drm, "Forcing SAGV disable: mask 0x%x\n", bw_state->qgv_points_mask); - icl_pcode_restrict_qgv_points(i915, bw_state->qgv_points_mask); + icl_pcode_restrict_qgv_points(display, bw_state->qgv_points_mask); } -static int mtl_find_qgv_points(struct drm_i915_private *i915, +static int mtl_find_qgv_points(struct intel_display *display, unsigned int data_rate, unsigned int num_active_planes, struct intel_bw_state *new_bw_state) { unsigned int best_rate = UINT_MAX; - unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; + unsigned int num_qgv_points = display->bw.max[0].num_qgv_points; unsigned int qgv_peak_bw = 0; int i; int ret; @@ -974,9 +991,9 @@ static int mtl_find_qgv_points(struct drm_i915_private *i915, * for qgv peak bw in PM Demand request. So assign UINT_MAX if SAGV is * not enabled. PM Demand code will clamp the value for the register */ - if (!intel_can_enable_sagv(i915, new_bw_state)) { + if (!intel_can_enable_sagv(display, new_bw_state)) { new_bw_state->qgv_point_peakbw = U16_MAX; - drm_dbg_kms(&i915->drm, "No SAGV, use UINT_MAX as peak bw."); + drm_dbg_kms(display->drm, "No SAGV, use UINT_MAX as peak bw."); return 0; } @@ -986,27 +1003,27 @@ static int mtl_find_qgv_points(struct drm_i915_private *i915, */ for (i = 0; i < num_qgv_points; i++) { unsigned int bw_index = - tgl_max_bw_index(i915, num_active_planes, i); + tgl_max_bw_index(display, num_active_planes, i); unsigned int max_data_rate; - if (bw_index >= ARRAY_SIZE(i915->display.bw.max)) + if (bw_index >= ARRAY_SIZE(display->bw.max)) continue; - max_data_rate = i915->display.bw.max[bw_index].deratedbw[i]; + max_data_rate = display->bw.max[bw_index].deratedbw[i]; if (max_data_rate < data_rate) continue; if (max_data_rate - data_rate < best_rate) { best_rate = max_data_rate - data_rate; - qgv_peak_bw = i915->display.bw.max[bw_index].peakbw[i]; + qgv_peak_bw = display->bw.max[bw_index].peakbw[i]; } - drm_dbg_kms(&i915->drm, "QGV point %d: max bw %d required %d qgv_peak_bw: %d\n", + drm_dbg_kms(display->drm, "QGV point %d: max bw %d required %d qgv_peak_bw: %d\n", i, max_data_rate, data_rate, qgv_peak_bw); } - drm_dbg_kms(&i915->drm, "Matching peaks QGV bw: %d for required data rate: %d\n", + drm_dbg_kms(display->drm, "Matching peaks QGV bw: %d for required data rate: %d\n", qgv_peak_bw, data_rate); /* @@ -1014,7 +1031,7 @@ static int mtl_find_qgv_points(struct drm_i915_private *i915, * satisfying the required data rate is found */ if (qgv_peak_bw == 0) { - drm_dbg_kms(&i915->drm, "No QGV points for bw %d for display configuration(%d active planes).\n", + drm_dbg_kms(display->drm, "No QGV points for bw %d for display configuration(%d active planes).\n", data_rate, num_active_planes); return -EINVAL; } @@ -1025,14 +1042,14 @@ static int mtl_find_qgv_points(struct drm_i915_private *i915, return 0; } -static int icl_find_qgv_points(struct drm_i915_private *i915, +static int icl_find_qgv_points(struct intel_display *display, unsigned int data_rate, unsigned int num_active_planes, const struct intel_bw_state *old_bw_state, struct intel_bw_state *new_bw_state) { - unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points; - unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points; + unsigned int num_psf_gv_points = display->bw.max[0].num_psf_gv_points; + unsigned int num_qgv_points = display->bw.max[0].num_qgv_points; u16 psf_points = 0; u16 qgv_points = 0; int i; @@ -1043,22 +1060,22 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, return ret; for (i = 0; i < num_qgv_points; i++) { - unsigned int max_data_rate = icl_qgv_bw(i915, + unsigned int max_data_rate = icl_qgv_bw(display, num_active_planes, i); if (max_data_rate >= data_rate) qgv_points |= BIT(i); - drm_dbg_kms(&i915->drm, "QGV point %d: max bw %d required %d\n", + drm_dbg_kms(display->drm, "QGV point %d: max bw %d required %d\n", i, max_data_rate, data_rate); } for (i = 0; i < num_psf_gv_points; i++) { - unsigned int max_data_rate = adl_psf_bw(i915, i); + unsigned int max_data_rate = adl_psf_bw(display, i); if (max_data_rate >= data_rate) psf_points |= BIT(i); - drm_dbg_kms(&i915->drm, "PSF GV point %d: max bw %d" + drm_dbg_kms(display->drm, "PSF GV point %d: max bw %d" " required %d\n", i, max_data_rate, data_rate); } @@ -1069,14 +1086,14 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, * reasons. */ if (qgv_points == 0) { - drm_dbg_kms(&i915->drm, "No QGV points provide sufficient memory" + drm_dbg_kms(display->drm, "No QGV points provide sufficient memory" " bandwidth %d for display configuration(%d active planes).\n", data_rate, num_active_planes); return -EINVAL; } if (num_psf_gv_points > 0 && psf_points == 0) { - drm_dbg_kms(&i915->drm, "No PSF GV points provide sufficient memory" + drm_dbg_kms(display->drm, "No PSF GV points provide sufficient memory" " bandwidth %d for display configuration(%d active planes).\n", data_rate, num_active_planes); return -EINVAL; @@ -1087,9 +1104,9 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, * we can't enable SAGV due to the increased memory latency it may * cause. */ - if (!intel_can_enable_sagv(i915, new_bw_state)) { - qgv_points = icl_max_bw_qgv_point_mask(i915, num_active_planes); - drm_dbg_kms(&i915->drm, "No SAGV, using single QGV point mask 0x%x\n", + if (!intel_can_enable_sagv(display, new_bw_state)) { + qgv_points = icl_max_bw_qgv_point_mask(display, num_active_planes); + drm_dbg_kms(display->drm, "No SAGV, using single QGV point mask 0x%x\n", qgv_points); } @@ -1097,7 +1114,7 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, * We store the ones which need to be masked as that is what PCode * actually accepts as a parameter. */ - new_bw_state->qgv_points_mask = icl_prepare_qgv_points_mask(i915, + new_bw_state->qgv_points_mask = icl_prepare_qgv_points_mask(display, qgv_points, psf_points); /* @@ -1113,80 +1130,90 @@ static int icl_find_qgv_points(struct drm_i915_private *i915, return 0; } -static int intel_bw_check_qgv_points(struct drm_i915_private *i915, +static int intel_bw_check_qgv_points(struct intel_display *display, const struct intel_bw_state *old_bw_state, struct intel_bw_state *new_bw_state) { - unsigned int data_rate = intel_bw_data_rate(i915, new_bw_state); + unsigned int data_rate = intel_bw_data_rate(display, new_bw_state); unsigned int num_active_planes = - intel_bw_num_active_planes(i915, new_bw_state); + intel_bw_num_active_planes(display, new_bw_state); data_rate = DIV_ROUND_UP(data_rate, 1000); - if (DISPLAY_VER(i915) >= 14) - return mtl_find_qgv_points(i915, data_rate, num_active_planes, + if (DISPLAY_VER(display) >= 14) + return mtl_find_qgv_points(display, data_rate, num_active_planes, new_bw_state); else - return icl_find_qgv_points(i915, data_rate, num_active_planes, + return icl_find_qgv_points(display, data_rate, num_active_planes, old_bw_state, new_bw_state); } -static bool intel_bw_state_changed(struct drm_i915_private *i915, +static bool intel_dbuf_bw_changed(struct intel_display *display, + const struct intel_dbuf_bw *old_dbuf_bw, + const struct intel_dbuf_bw *new_dbuf_bw) +{ + enum dbuf_slice slice; + + for_each_dbuf_slice(display, slice) { + if (old_dbuf_bw->max_bw[slice] != new_dbuf_bw->max_bw[slice] || + old_dbuf_bw->active_planes[slice] != new_dbuf_bw->active_planes[slice]) + return true; + } + + return false; +} + +static bool intel_bw_state_changed(struct intel_display *display, const struct intel_bw_state *old_bw_state, const struct intel_bw_state *new_bw_state) { enum pipe pipe; - for_each_pipe(i915, pipe) { - const struct intel_dbuf_bw *old_crtc_bw = + for_each_pipe(display, pipe) { + const struct intel_dbuf_bw *old_dbuf_bw = &old_bw_state->dbuf_bw[pipe]; - const struct intel_dbuf_bw *new_crtc_bw = + const struct intel_dbuf_bw *new_dbuf_bw = &new_bw_state->dbuf_bw[pipe]; - enum dbuf_slice slice; - for_each_dbuf_slice(i915, slice) { - if (old_crtc_bw->max_bw[slice] != new_crtc_bw->max_bw[slice] || - old_crtc_bw->active_planes[slice] != new_crtc_bw->active_planes[slice]) - return true; - } + if (intel_dbuf_bw_changed(display, old_dbuf_bw, new_dbuf_bw)) + return true; - if (old_bw_state->min_cdclk[pipe] != new_bw_state->min_cdclk[pipe]) + if (intel_bw_crtc_min_cdclk(display, old_bw_state->data_rate[pipe]) != + intel_bw_crtc_min_cdclk(display, new_bw_state->data_rate[pipe])) return true; } return false; } -static void skl_plane_calc_dbuf_bw(struct intel_bw_state *bw_state, +static void skl_plane_calc_dbuf_bw(struct intel_dbuf_bw *dbuf_bw, struct intel_crtc *crtc, enum plane_id plane_id, const struct skl_ddb_entry *ddb, unsigned int data_rate) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); - struct intel_dbuf_bw *crtc_bw = &bw_state->dbuf_bw[crtc->pipe]; - unsigned int dbuf_mask = skl_ddb_dbuf_slice_mask(i915, ddb); + struct intel_display *display = to_intel_display(crtc); + unsigned int dbuf_mask = skl_ddb_dbuf_slice_mask(display, ddb); enum dbuf_slice slice; /* * The arbiter can only really guarantee an * equal share of the total bw to each plane. */ - for_each_dbuf_slice_in_mask(i915, slice, dbuf_mask) { - crtc_bw->max_bw[slice] = max(crtc_bw->max_bw[slice], data_rate); - crtc_bw->active_planes[slice] |= BIT(plane_id); + for_each_dbuf_slice_in_mask(display, slice, dbuf_mask) { + dbuf_bw->max_bw[slice] = max(dbuf_bw->max_bw[slice], data_rate); + dbuf_bw->active_planes[slice] |= BIT(plane_id); } } -static void skl_crtc_calc_dbuf_bw(struct intel_bw_state *bw_state, +static void skl_crtc_calc_dbuf_bw(struct intel_dbuf_bw *dbuf_bw, 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); - struct intel_dbuf_bw *crtc_bw = &bw_state->dbuf_bw[crtc->pipe]; enum plane_id plane_id; - memset(crtc_bw, 0, sizeof(*crtc_bw)); + memset(dbuf_bw, 0, sizeof(*dbuf_bw)); if (!crtc_state->hw.active) return; @@ -1199,12 +1226,12 @@ static void skl_crtc_calc_dbuf_bw(struct intel_bw_state *bw_state, if (plane_id == PLANE_CURSOR) continue; - skl_plane_calc_dbuf_bw(bw_state, crtc, plane_id, + skl_plane_calc_dbuf_bw(dbuf_bw, crtc, plane_id, &crtc_state->wm.skl.plane_ddb[plane_id], crtc_state->data_rate[plane_id]); - if (DISPLAY_VER(i915) < 11) - skl_plane_calc_dbuf_bw(bw_state, crtc, plane_id, + if (DISPLAY_VER(display) < 11) + skl_plane_calc_dbuf_bw(dbuf_bw, crtc, plane_id, &crtc_state->wm.skl.plane_ddb_y[plane_id], crtc_state->data_rate[plane_id]); } @@ -1212,13 +1239,13 @@ static void skl_crtc_calc_dbuf_bw(struct intel_bw_state *bw_state, /* "Maximum Data Buffer Bandwidth" */ static int -intel_bw_dbuf_min_cdclk(struct drm_i915_private *i915, +intel_bw_dbuf_min_cdclk(struct intel_display *display, const struct intel_bw_state *bw_state) { unsigned int total_max_bw = 0; enum dbuf_slice slice; - for_each_dbuf_slice(i915, slice) { + for_each_dbuf_slice(display, slice) { int num_active_planes = 0; unsigned int max_bw = 0; enum pipe pipe; @@ -1227,11 +1254,11 @@ intel_bw_dbuf_min_cdclk(struct drm_i915_private *i915, * The arbiter can only really guarantee an * equal share of the total bw to each plane. */ - for_each_pipe(i915, pipe) { - const struct intel_dbuf_bw *crtc_bw = &bw_state->dbuf_bw[pipe]; + for_each_pipe(display, pipe) { + const struct intel_dbuf_bw *dbuf_bw = &bw_state->dbuf_bw[pipe]; - max_bw = max(crtc_bw->max_bw[slice], max_bw); - num_active_planes += hweight8(crtc_bw->active_planes[slice]); + max_bw = max(dbuf_bw->max_bw[slice], max_bw); + num_active_planes += hweight8(dbuf_bw->active_planes[slice]); } max_bw *= num_active_planes; @@ -1241,16 +1268,18 @@ intel_bw_dbuf_min_cdclk(struct drm_i915_private *i915, return DIV_ROUND_UP(total_max_bw, 64); } -int intel_bw_min_cdclk(struct drm_i915_private *i915, +int intel_bw_min_cdclk(struct intel_display *display, const struct intel_bw_state *bw_state) { enum pipe pipe; int min_cdclk; - min_cdclk = intel_bw_dbuf_min_cdclk(i915, bw_state); + min_cdclk = intel_bw_dbuf_min_cdclk(display, bw_state); - for_each_pipe(i915, pipe) - min_cdclk = max(min_cdclk, bw_state->min_cdclk[pipe]); + for_each_pipe(display, pipe) + min_cdclk = max(min_cdclk, + intel_bw_crtc_min_cdclk(display, + bw_state->data_rate[pipe])); return min_cdclk; } @@ -1258,42 +1287,49 @@ int intel_bw_min_cdclk(struct drm_i915_private *i915, int intel_bw_calc_min_cdclk(struct intel_atomic_state *state, bool *need_cdclk_calc) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_bw_state *new_bw_state = NULL; const struct intel_bw_state *old_bw_state = NULL; const struct intel_cdclk_state *cdclk_state; - const struct intel_crtc_state *crtc_state; + const struct intel_crtc_state *old_crtc_state; + const struct intel_crtc_state *new_crtc_state; int old_min_cdclk, new_min_cdclk; struct intel_crtc *crtc; int i; - if (DISPLAY_VER(dev_priv) < 9) + if (DISPLAY_VER(display) < 9) return 0; - for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) { + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, + new_crtc_state, i) { + struct intel_dbuf_bw old_dbuf_bw, new_dbuf_bw; + + skl_crtc_calc_dbuf_bw(&old_dbuf_bw, old_crtc_state); + skl_crtc_calc_dbuf_bw(&new_dbuf_bw, new_crtc_state); + + if (!intel_dbuf_bw_changed(display, &old_dbuf_bw, &new_dbuf_bw)) + continue; + new_bw_state = intel_atomic_get_bw_state(state); if (IS_ERR(new_bw_state)) return PTR_ERR(new_bw_state); old_bw_state = intel_atomic_get_old_bw_state(state); - skl_crtc_calc_dbuf_bw(new_bw_state, crtc_state); - - new_bw_state->min_cdclk[crtc->pipe] = - intel_bw_crtc_min_cdclk(crtc_state); + new_bw_state->dbuf_bw[crtc->pipe] = new_dbuf_bw; } if (!old_bw_state) return 0; - if (intel_bw_state_changed(dev_priv, old_bw_state, new_bw_state)) { + if (intel_bw_state_changed(display, old_bw_state, new_bw_state)) { int ret = intel_atomic_lock_global_state(&new_bw_state->base); if (ret) return ret; } - old_min_cdclk = intel_bw_min_cdclk(dev_priv, old_bw_state); - new_min_cdclk = intel_bw_min_cdclk(dev_priv, new_bw_state); + old_min_cdclk = intel_bw_min_cdclk(display, old_bw_state); + new_min_cdclk = intel_bw_min_cdclk(display, new_bw_state); /* * No need to check against the cdclk state if @@ -1321,7 +1357,7 @@ int intel_bw_calc_min_cdclk(struct intel_atomic_state *state, if (new_min_cdclk <= cdclk_state->bw_min_cdclk) return 0; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "new bandwidth min cdclk (%d kHz) > old min cdclk (%d kHz)\n", new_min_cdclk, cdclk_state->bw_min_cdclk); *need_cdclk_calc = true; @@ -1331,7 +1367,7 @@ int intel_bw_calc_min_cdclk(struct intel_atomic_state *state, static int intel_bw_check_data_rate(struct intel_atomic_state *state, bool *changed) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; int i; @@ -1365,7 +1401,7 @@ static int intel_bw_check_data_rate(struct intel_atomic_state *state, bool *chan *changed = true; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] data rate %u num active planes %u\n", crtc->base.base.id, crtc->base.name, new_bw_state->data_rate[crtc->pipe], @@ -1375,16 +1411,103 @@ static int intel_bw_check_data_rate(struct intel_atomic_state *state, bool *chan return 0; } -int intel_bw_atomic_check(struct intel_atomic_state *state) +static int intel_bw_modeset_checks(struct intel_atomic_state *state) +{ + struct intel_display *display = to_intel_display(state); + const struct intel_bw_state *old_bw_state; + struct intel_bw_state *new_bw_state; + + if (DISPLAY_VER(display) < 9) + return 0; + + new_bw_state = intel_atomic_get_bw_state(state); + if (IS_ERR(new_bw_state)) + return PTR_ERR(new_bw_state); + + old_bw_state = intel_atomic_get_old_bw_state(state); + + new_bw_state->active_pipes = + intel_calc_active_pipes(state, old_bw_state->active_pipes); + + if (new_bw_state->active_pipes != old_bw_state->active_pipes) { + int ret; + + ret = intel_atomic_lock_global_state(&new_bw_state->base); + if (ret) + return ret; + } + + return 0; +} + +static int intel_bw_check_sagv_mask(struct intel_atomic_state *state) { + struct intel_display *display = to_intel_display(state); + const struct intel_crtc_state *old_crtc_state; + const struct intel_crtc_state *new_crtc_state; + const struct intel_bw_state *old_bw_state = NULL; + struct intel_bw_state *new_bw_state = NULL; + struct intel_crtc *crtc; + int ret, i; + + for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, + new_crtc_state, i) { + if (intel_crtc_can_enable_sagv(old_crtc_state) == + intel_crtc_can_enable_sagv(new_crtc_state)) + continue; + + new_bw_state = intel_atomic_get_bw_state(state); + if (IS_ERR(new_bw_state)) + return PTR_ERR(new_bw_state); + + old_bw_state = intel_atomic_get_old_bw_state(state); + + if (intel_crtc_can_enable_sagv(new_crtc_state)) + new_bw_state->pipe_sagv_reject &= ~BIT(crtc->pipe); + else + new_bw_state->pipe_sagv_reject |= BIT(crtc->pipe); + } + + if (!new_bw_state) + return 0; + + if (intel_can_enable_sagv(display, new_bw_state) != + intel_can_enable_sagv(display, old_bw_state)) { + ret = intel_atomic_serialize_global_state(&new_bw_state->base); + if (ret) + return ret; + } else if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) { + ret = intel_atomic_lock_global_state(&new_bw_state->base); + if (ret) + return ret; + } + + return 0; +} + +int intel_bw_atomic_check(struct intel_atomic_state *state, bool any_ms) +{ + struct intel_display *display = to_intel_display(state); bool changed = false; - struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_bw_state *new_bw_state; const struct intel_bw_state *old_bw_state; int ret; + if (DISPLAY_VER(display) < 9) + return 0; + + if (any_ms) { + ret = intel_bw_modeset_checks(state); + if (ret) + return ret; + } + + ret = intel_bw_check_sagv_mask(state); + if (ret) + return ret; + /* FIXME earlier gens need some checks too */ - if (DISPLAY_VER(i915) < 11) + if (DISPLAY_VER(display) < 11) return 0; ret = intel_bw_check_data_rate(state, &changed); @@ -1395,9 +1518,8 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) new_bw_state = intel_atomic_get_new_bw_state(state); if (new_bw_state && - (intel_can_enable_sagv(i915, old_bw_state) != - intel_can_enable_sagv(i915, new_bw_state) || - new_bw_state->force_check_qgv)) + intel_can_enable_sagv(display, old_bw_state) != + intel_can_enable_sagv(display, new_bw_state)) changed = true; /* @@ -1407,28 +1529,25 @@ int intel_bw_atomic_check(struct intel_atomic_state *state) if (!changed) return 0; - ret = intel_bw_check_qgv_points(i915, old_bw_state, new_bw_state); + ret = intel_bw_check_qgv_points(display, old_bw_state, new_bw_state); if (ret) return ret; - new_bw_state->force_check_qgv = false; - return 0; } static void intel_bw_crtc_update(struct intel_bw_state *bw_state, 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); bw_state->data_rate[crtc->pipe] = intel_bw_crtc_data_rate(crtc_state); bw_state->num_active_planes[crtc->pipe] = intel_bw_crtc_num_active_planes(crtc_state); - bw_state->force_check_qgv = true; - drm_dbg_kms(&i915->drm, "pipe %c data rate %u num active planes %u\n", + drm_dbg_kms(display->drm, "pipe %c data rate %u num active planes %u\n", pipe_name(crtc->pipe), bw_state->data_rate[crtc->pipe], bw_state->num_active_planes[crtc->pipe]); @@ -1444,6 +1563,7 @@ void intel_bw_update_hw_state(struct intel_display *display) return; bw_state->active_pipes = 0; + bw_state->pipe_sagv_reject = 0; for_each_intel_crtc(display->drm, crtc) { const struct intel_crtc_state *crtc_state = @@ -1455,6 +1575,11 @@ void intel_bw_update_hw_state(struct intel_display *display) if (DISPLAY_VER(display) >= 11) intel_bw_crtc_update(bw_state, crtc_state); + + skl_crtc_calc_dbuf_bw(&bw_state->dbuf_bw[pipe], crtc_state); + + /* initially SAGV has been forced off */ + bw_state->pipe_sagv_reject |= BIT(pipe); } } @@ -1470,6 +1595,7 @@ void intel_bw_crtc_disable_noatomic(struct intel_crtc *crtc) bw_state->data_rate[pipe] = 0; bw_state->num_active_planes[pipe] = 0; + memset(&bw_state->dbuf_bw[pipe], 0, sizeof(bw_state->dbuf_bw[pipe])); } static struct intel_global_state * @@ -1495,9 +1621,8 @@ static const struct intel_global_state_funcs intel_bw_funcs = { .atomic_destroy_state = intel_bw_destroy_state, }; -int intel_bw_init(struct drm_i915_private *i915) +int intel_bw_init(struct intel_display *display) { - struct intel_display *display = &i915->display; struct intel_bw_state *state; state = kzalloc(sizeof(*state), GFP_KERNEL); @@ -1511,8 +1636,8 @@ int intel_bw_init(struct drm_i915_private *i915) * Limit this only if we have SAGV. And for Display version 14 onwards * sagv is handled though pmdemand requests */ - if (intel_has_sagv(i915) && IS_DISPLAY_VER(i915, 11, 13)) - icl_force_disable_sagv(i915, state); + if (intel_has_sagv(display) && IS_DISPLAY_VER(display, 11, 13)) + icl_force_disable_sagv(display, state); return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_bw.h b/drivers/gpu/drm/i915/display/intel_bw.h index 3313e4eac4f0..eb2cc883e9c1 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.h +++ b/drivers/gpu/drm/i915/display/intel_bw.h @@ -12,7 +12,6 @@ #include "intel_display_power.h" #include "intel_global_state.h" -struct drm_i915_private; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; @@ -49,13 +48,6 @@ struct intel_bw_state { */ u16 qgv_points_mask; - /* - * Flag to force the QGV comparison in atomic check right after the - * hw state readout - */ - bool force_check_qgv; - - int min_cdclk[I915_MAX_PIPES]; unsigned int data_rate[I915_MAX_PIPES]; u8 num_active_planes[I915_MAX_PIPES]; }; @@ -72,14 +64,14 @@ intel_atomic_get_new_bw_state(struct intel_atomic_state *state); struct intel_bw_state * intel_atomic_get_bw_state(struct intel_atomic_state *state); -void intel_bw_init_hw(struct drm_i915_private *dev_priv); -int intel_bw_init(struct drm_i915_private *dev_priv); -int intel_bw_atomic_check(struct intel_atomic_state *state); -int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv, +void intel_bw_init_hw(struct intel_display *display); +int intel_bw_init(struct intel_display *display); +int intel_bw_atomic_check(struct intel_atomic_state *state, bool any_ms); +int icl_pcode_restrict_qgv_points(struct intel_display *display, u32 points_mask); int intel_bw_calc_min_cdclk(struct intel_atomic_state *state, bool *need_cdclk_calc); -int intel_bw_min_cdclk(struct drm_i915_private *i915, +int intel_bw_min_cdclk(struct intel_display *display, const struct intel_bw_state *bw_state); void intel_bw_update_hw_state(struct intel_display *display); void intel_bw_crtc_disable_noatomic(struct intel_crtc *crtc); diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 2a8749a0213e..b1718b491ffd 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -1972,9 +1972,7 @@ int intel_mdclk_cdclk_ratio(struct intel_display *display, static void xe2lpd_mdclk_cdclk_ratio_program(struct intel_display *display, const struct intel_cdclk_config *cdclk_config) { - struct drm_i915_private *i915 = to_i915(display->drm); - - intel_dbuf_mdclk_cdclk_ratio_update(i915, + intel_dbuf_mdclk_cdclk_ratio_update(display, intel_mdclk_cdclk_ratio(display, cdclk_config), cdclk_config->joined_mbus); } @@ -2808,7 +2806,6 @@ static int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_stat static int intel_compute_min_cdclk(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_cdclk_state *cdclk_state = intel_atomic_get_new_cdclk_state(state); const struct intel_bw_state *bw_state; @@ -2836,7 +2833,7 @@ static int intel_compute_min_cdclk(struct intel_atomic_state *state) bw_state = intel_atomic_get_new_bw_state(state); if (bw_state) { - min_cdclk = intel_bw_min_cdclk(dev_priv, bw_state); + min_cdclk = intel_bw_min_cdclk(display, bw_state); if (cdclk_state->bw_min_cdclk != min_cdclk) { int ret; @@ -3342,6 +3339,8 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state) void intel_cdclk_update_hw_state(struct intel_display *display) { + const struct intel_bw_state *bw_state = + to_intel_bw_state(display->bw.obj.state); struct intel_cdclk_state *cdclk_state = to_intel_cdclk_state(display->cdclk.obj.state); struct intel_crtc *crtc; @@ -3359,6 +3358,8 @@ void intel_cdclk_update_hw_state(struct intel_display *display) cdclk_state->min_cdclk[pipe] = intel_crtc_compute_min_cdclk(crtc_state); cdclk_state->min_voltage_level[pipe] = crtc_state->min_voltage_level; } + + cdclk_state->bw_min_cdclk = intel_bw_min_cdclk(display, bw_state); } void intel_cdclk_crtc_disable_noatomic(struct intel_crtc *crtc) @@ -3493,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; @@ -3513,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); } @@ -3552,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_color.c b/drivers/gpu/drm/i915/display/intel_color.c index cfe14162231d..98dddf72c0eb 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -22,7 +22,9 @@ * */ -#include "i915_drv.h" +#include <drm/drm_print.h> + +#include "i915_utils.h" #include "i9xx_plane_regs.h" #include "intel_color.h" #include "intel_color_regs.h" @@ -405,14 +407,13 @@ static void icl_read_csc(struct intel_crtc_state *crtc_state) static bool ilk_limited_range(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - struct drm_i915_private *i915 = to_i915(display->drm); /* icl+ have dedicated output CSC */ if (DISPLAY_VER(display) >= 11) return false; /* pre-hsw have TRANSCONF_COLOR_RANGE_SELECT */ - if (DISPLAY_VER(display) < 7 || IS_IVYBRIDGE(i915)) + if (DISPLAY_VER(display) < 7 || display->platform.ivybridge) return false; return crtc_state->limited_color_range; @@ -516,7 +517,6 @@ static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state, static void ilk_assign_csc(struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - struct drm_i915_private *i915 = to_i915(display->drm); bool limited_color_range = ilk_csc_limited_range(crtc_state); if (crtc_state->hw.ctm) { @@ -538,7 +538,7 @@ static void ilk_assign_csc(struct intel_crtc_state *crtc_state) * LUT is needed but CSC is not we need to load an * identity matrix. */ - drm_WARN_ON(display->drm, !IS_GEMINILAKE(i915)); + drm_WARN_ON(display->drm, !display->platform.geminilake); ilk_csc_copy(display, &crtc_state->csc, &ilk_csc_matrix_identity); } else { @@ -3983,12 +3983,10 @@ int intel_color_init(struct intel_display *display) void intel_color_init_hooks(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (HAS_GMCH(display)) { - if (IS_CHERRYVIEW(i915)) + if (display->platform.cherryview) display->funcs.color = &chv_color_funcs; - else if (IS_VALLEYVIEW(i915)) + else if (display->platform.valleyview) display->funcs.color = &vlv_color_funcs; else if (DISPLAY_VER(display) >= 4) display->funcs.color = &i965_color_funcs; @@ -4005,7 +4003,7 @@ void intel_color_init_hooks(struct intel_display *display) display->funcs.color = &skl_color_funcs; else if (DISPLAY_VER(display) == 8) display->funcs.color = &bdw_color_funcs; - else if (IS_HASWELL(i915)) + else if (display->platform.haswell) display->funcs.color = &hsw_color_funcs; else if (DISPLAY_VER(display) == 7) display->funcs.color = &ivb_color_funcs; diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c b/drivers/gpu/drm/i915/display/intel_combo_phy.c index 17eea244cc83..f5cc38dbe559 100644 --- a/drivers/gpu/drm/i915/display/intel_combo_phy.c +++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c @@ -3,6 +3,8 @@ * Copyright © 2018 Intel Corporation */ +#include <drm/drm_print.h> + #include "i915_reg.h" #include "i915_utils.h" #include "intel_combo_phy.h" diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c index e42357bd9e80..6c81c9f2fd09 100644 --- a/drivers/gpu/drm/i915/display/intel_connector.c +++ b/drivers/gpu/drm/i915/display/intel_connector.c @@ -31,8 +31,10 @@ #include <drm/drm_probe_helper.h> #include "i915_drv.h" +#include "i915_utils.h" #include "intel_backlight.h" #include "intel_connector.h" +#include "intel_display_core.h" #include "intel_display_debugfs.h" #include "intel_display_types.h" #include "intel_hdcp.h" @@ -154,13 +156,14 @@ void intel_connector_destroy(struct drm_connector *connector) int intel_connector_register(struct drm_connector *connector) { struct intel_connector *intel_connector = to_intel_connector(connector); + struct drm_i915_private *i915 = to_i915(connector->dev); int ret; ret = intel_backlight_device_register(intel_connector); if (ret) goto err; - if (i915_inject_probe_failure(to_i915(connector->dev))) { + if (i915_inject_probe_failure(i915)) { ret = -EFAULT; goto err_backlight; } @@ -204,10 +207,10 @@ bool intel_connector_get_hw_state(struct intel_connector *connector) enum pipe intel_connector_get_pipe(struct intel_connector *connector) { - struct drm_device *dev = connector->base.dev; + struct intel_display *display = to_intel_display(connector); - drm_WARN_ON(dev, - !drm_modeset_is_locked(&dev->mode_config.connection_mutex)); + drm_WARN_ON(display->drm, + !drm_modeset_is_locked(&display->drm->mode_config.connection_mutex)); if (!connector->base.state->crtc) return INVALID_PIPE; @@ -264,20 +267,19 @@ static const struct drm_prop_enum_list force_audio_names[] = { void intel_attach_force_audio_property(struct drm_connector *connector) { - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(connector->dev); struct drm_property *prop; - prop = dev_priv->display.properties.force_audio; + prop = display->properties.force_audio; if (prop == NULL) { - prop = drm_property_create_enum(dev, 0, - "audio", - force_audio_names, - ARRAY_SIZE(force_audio_names)); + prop = drm_property_create_enum(display->drm, 0, + "audio", + force_audio_names, + ARRAY_SIZE(force_audio_names)); if (prop == NULL) return; - dev_priv->display.properties.force_audio = prop; + display->properties.force_audio = prop; } drm_object_attach_property(&connector->base, prop, 0); } @@ -291,20 +293,19 @@ static const struct drm_prop_enum_list broadcast_rgb_names[] = { void intel_attach_broadcast_rgb_property(struct drm_connector *connector) { - struct drm_device *dev = connector->dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(connector->dev); struct drm_property *prop; - prop = dev_priv->display.properties.broadcast_rgb; + prop = display->properties.broadcast_rgb; if (prop == NULL) { - prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, - "Broadcast RGB", - broadcast_rgb_names, - ARRAY_SIZE(broadcast_rgb_names)); + prop = drm_property_create_enum(display->drm, DRM_MODE_PROP_ENUM, + "Broadcast RGB", + broadcast_rgb_names, + ARRAY_SIZE(broadcast_rgb_names)); if (prop == NULL) return; - dev_priv->display.properties.broadcast_rgb = prop; + display->properties.broadcast_rgb = prop; } drm_object_attach_property(&connector->base, prop, 0); @@ -336,14 +337,14 @@ intel_attach_dp_colorspace_property(struct drm_connector *connector) void intel_attach_scaling_mode_property(struct drm_connector *connector) { - struct drm_i915_private *i915 = to_i915(connector->dev); + struct intel_display *display = to_intel_display(connector->dev); u32 scaling_modes; scaling_modes = BIT(DRM_MODE_SCALE_ASPECT) | BIT(DRM_MODE_SCALE_FULLSCREEN); /* On GMCH platforms borders are only possible on the LVDS port */ - if (!HAS_GMCH(i915) || connector->connector_type == DRM_MODE_CONNECTOR_LVDS) + if (!HAS_GMCH(display) || connector->connector_type == DRM_MODE_CONNECTOR_LVDS) scaling_modes |= BIT(DRM_MODE_SCALE_CENTER); drm_connector_attach_scaling_mode_property(connector, scaling_modes); diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c index 76ffb3f8467c..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; @@ -532,8 +527,6 @@ static bool valleyview_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); - bool reenable_hpd; u32 adpa; bool ret; u32 save_adpa; @@ -550,7 +543,7 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector) * * Just disable HPD interrupts here to prevent this */ - reenable_hpd = intel_hpd_disable(dev_priv, crt->base.hpd_pin); + intel_hpd_block(&crt->base); save_adpa = adpa = intel_de_read(display, crt->adpa_reg); drm_dbg_kms(display->drm, @@ -577,8 +570,7 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector) drm_dbg_kms(display->drm, "valleyview hotplug adpa=0x%x, result %d\n", adpa, ret); - if (reenable_hpd) - intel_hpd_enable(dev_priv, crt->base.hpd_pin); + intel_hpd_clear_and_unblock(&crt->base); return ret; } @@ -586,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); /* @@ -602,14 +593,14 @@ 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; for (i = 0; i < tries ; i++) { /* turn on the FORCE_DETECT */ - i915_hotplug_interrupt_update(dev_priv, + i915_hotplug_interrupt_update(display, CRT_HOTPLUG_FORCE_DETECT, CRT_HOTPLUG_FORCE_DETECT); /* wait for FORCE_DETECT to go off */ @@ -627,7 +618,7 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) intel_de_write(display, PORT_HOTPLUG_STAT(display), CRT_HOTPLUG_INT_STATUS); - i915_hotplug_interrupt_update(dev_priv, CRT_HOTPLUG_FORCE_DETECT, 0); + i915_hotplug_interrupt_update(display, CRT_HOTPLUG_FORCE_DETECT, 0); return ret; } @@ -880,7 +871,7 @@ intel_crt_detect(struct drm_connector *connector, wakeref = intel_display_power_get(display, encoder->power_domain); - if (I915_HAS_HOTPLUG(display)) { + if (HAS_HOTPLUG(display)) { /* We can not rely on the HPD pin always being correctly wired * up, for example many KVM do not pass it through, and so * only trust an assertion that the monitor is connected. @@ -904,7 +895,7 @@ intel_crt_detect(struct drm_connector *connector, * broken monitor (without edid) to work behind a broken kvm (that fails * to have the right resistors for HP detection) needs to fix this up. * For now just bail out. */ - if (I915_HAS_HOTPLUG(display)) { + if (HAS_HOTPLUG(display)) { status = connector_status_disconnected; goto out; } @@ -943,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; @@ -956,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. */ @@ -1015,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; @@ -1072,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; @@ -1084,7 +1073,7 @@ void intel_crt_init(struct intel_display *display) crt->base.power_domain = POWER_DOMAIN_PORT_CRT; - if (I915_HAS_HOTPLUG(display) && + if (HAS_HOTPLUG(display) && !dmi_check_system(intel_spurious_crt_detect)) { crt->base.hpd_pin = HPD_CRT; crt->base.hotplug = intel_encoder_hotplug; @@ -1112,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; @@ -1134,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_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c index 599ddce96371..0c7f91046996 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c @@ -5,9 +5,10 @@ #include <drm/drm_edid.h> #include <drm/drm_eld.h> +#include <drm/drm_print.h> -#include "i915_drv.h" #include "intel_crtc_state_dump.h" +#include "intel_display_core.h" #include "intel_display_types.h" #include "intel_hdmi.h" #include "intel_vblank.h" @@ -42,13 +43,13 @@ intel_dump_m_n_config(struct drm_printer *p, } static void -intel_dump_infoframe(struct drm_i915_private *i915, +intel_dump_infoframe(struct intel_display *display, const union hdmi_infoframe *frame) { if (!drm_debug_enabled(DRM_UT_KMS)) return; - hdmi_infoframe_log(KERN_DEBUG, i915->drm.dev, frame); + hdmi_infoframe_log(KERN_DEBUG, display->drm->dev, frame); } #define OUTPUT_TYPE(x) [INTEL_OUTPUT_ ## x] = #x @@ -136,7 +137,7 @@ static void intel_dump_plane_state(struct drm_printer *p, } static void -ilk_dump_csc(struct drm_i915_private *i915, +ilk_dump_csc(struct intel_display *display, struct drm_printer *p, const char *name, const struct intel_csc_matrix *csc) @@ -152,7 +153,7 @@ ilk_dump_csc(struct drm_i915_private *i915, csc->coeff[3 * i + 1], csc->coeff[3 * i + 2]); - if (DISPLAY_VER(i915) < 7) + if (DISPLAY_VER(display) < 7) return; drm_printf(p, "%s: post offsets: 0x%04x 0x%04x 0x%04x\n", name, @@ -178,7 +179,6 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, { struct intel_display *display = to_intel_display(pipe_config); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); const struct intel_plane_state *plane_state; struct intel_plane *plane; struct drm_printer p; @@ -188,7 +188,7 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, if (!drm_debug_enabled(DRM_UT_KMS)) return; - p = drm_dbg_printer(&i915->drm, DRM_UT_KMS, NULL); + p = drm_dbg_printer(display->drm, DRM_UT_KMS, NULL); drm_printf(&p, "[CRTC:%d:%s] enable: %s [%s]\n", crtc->base.base.id, crtc->base.name, @@ -262,19 +262,19 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, drm_printf(&p, "GCP: 0x%x\n", pipe_config->infoframes.gcp); if (pipe_config->infoframes.enable & intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_AVI)) - intel_dump_infoframe(i915, &pipe_config->infoframes.avi); + intel_dump_infoframe(display, &pipe_config->infoframes.avi); if (pipe_config->infoframes.enable & intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_SPD)) - intel_dump_infoframe(i915, &pipe_config->infoframes.spd); + intel_dump_infoframe(display, &pipe_config->infoframes.spd); if (pipe_config->infoframes.enable & intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_VENDOR)) - intel_dump_infoframe(i915, &pipe_config->infoframes.hdmi); + intel_dump_infoframe(display, &pipe_config->infoframes.hdmi); if (pipe_config->infoframes.enable & intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_DRM)) - intel_dump_infoframe(i915, &pipe_config->infoframes.drm); + intel_dump_infoframe(display, &pipe_config->infoframes.drm); if (pipe_config->infoframes.enable & intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA)) - intel_dump_infoframe(i915, &pipe_config->infoframes.drm); + intel_dump_infoframe(display, &pipe_config->infoframes.drm); if (pipe_config->infoframes.enable & intel_hdmi_infoframe_enable(DP_SDP_VSC)) drm_dp_vsc_sdp_log(&p, &pipe_config->infoframes.vsc); @@ -294,8 +294,9 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, pipe_config->hw.adjusted_mode.crtc_vdisplay, pipe_config->framestart_delay, pipe_config->msa_timing_delay); - drm_printf(&p, "vrr: %s, vmin: %d, vmax: %d, flipline: %d, pipeline full: %d, guardband: %d vsync start: %d, vsync end: %d\n", + drm_printf(&p, "vrr: %s, fixed rr: %s, vmin: %d, vmax: %d, flipline: %d, pipeline full: %d, guardband: %d vsync start: %d, vsync end: %d\n", str_yes_no(pipe_config->vrr.enable), + str_yes_no(intel_vrr_is_fixed_rr(pipe_config)), pipe_config->vrr.vmin, pipe_config->vrr.vmax, pipe_config->vrr.flipline, pipe_config->vrr.pipeline_full, pipe_config->vrr.guardband, pipe_config->vrr.vsync_start, pipe_config->vrr.vsync_end); @@ -319,14 +320,14 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, drm_printf(&p, "linetime: %d, ips linetime: %d\n", pipe_config->linetime, pipe_config->ips_linetime); - if (DISPLAY_VER(i915) >= 9) + if (DISPLAY_VER(display) >= 9) drm_printf(&p, "num_scalers: %d, scaler_users: 0x%x, scaler_id: %d, scaling_filter: %d\n", crtc->num_scalers, pipe_config->scaler_state.scaler_users, pipe_config->scaler_state.scaler_id, pipe_config->hw.scaling_filter); - if (HAS_GMCH(i915)) + if (HAS_GMCH(display)) drm_printf(&p, "gmch pfit: control: 0x%08x, ratios: 0x%08x, lvds border: 0x%08x\n", pipe_config->gmch_pfit.control, pipe_config->gmch_pfit.pgm_ratios, @@ -343,7 +344,7 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, intel_dpll_dump_hw_state(display, &p, &pipe_config->dpll_hw_state); - if (IS_CHERRYVIEW(i915)) + if (display->platform.cherryview) drm_printf(&p, "cgm_mode: 0x%x gamma_mode: 0x%x gamma_enable: %d csc_enable: %d\n", pipe_config->cgm_mode, pipe_config->gamma_mode, pipe_config->gamma_enable, pipe_config->csc_enable); @@ -354,20 +355,20 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, drm_printf(&p, "pre csc lut: %s%d entries, post csc lut: %d entries\n", pipe_config->pre_csc_lut && pipe_config->pre_csc_lut == - i915->display.color.glk_linear_degamma_lut ? "(linear) " : "", + display->color.glk_linear_degamma_lut ? "(linear) " : "", pipe_config->pre_csc_lut ? drm_color_lut_size(pipe_config->pre_csc_lut) : 0, pipe_config->post_csc_lut ? drm_color_lut_size(pipe_config->post_csc_lut) : 0); - if (DISPLAY_VER(i915) >= 11) - ilk_dump_csc(i915, &p, "output csc", &pipe_config->output_csc); + if (DISPLAY_VER(display) >= 11) + ilk_dump_csc(display, &p, "output csc", &pipe_config->output_csc); - if (!HAS_GMCH(i915)) - ilk_dump_csc(i915, &p, "pipe csc", &pipe_config->csc); - else if (IS_CHERRYVIEW(i915)) + if (!HAS_GMCH(display)) + ilk_dump_csc(display, &p, "pipe csc", &pipe_config->csc); + else if (display->platform.cherryview) vlv_dump_csc(&p, "cgm csc", &pipe_config->csc); - else if (IS_VALLEYVIEW(i915)) + else if (display->platform.valleyview) vlv_dump_csc(&p, "wgc csc", &pipe_config->csc); intel_vdsc_state_dump(&p, 0, pipe_config); 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..a82b93cbc81d 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" @@ -2761,9 +2763,9 @@ static void intel_program_port_clock_ctl(struct intel_encoder *encoder, val |= XELPDP_FORWARD_CLOCK_UNGATE; if (!is_dp && is_hdmi_frl(port_clock)) - val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_DIV18CLK); + val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_DIV18CLK); else - val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_MAXPCLK); + val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_MAXPCLK); /* TODO: HDMI FRL */ /* DP2.0 10G and 20G rates enable MPLLA*/ @@ -2774,7 +2776,7 @@ static void intel_program_port_clock_ctl(struct intel_encoder *encoder, intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), XELPDP_LANE1_PHY_CLOCK_SELECT | XELPDP_FORWARD_CLOCK_UNGATE | - XELPDP_DDI_CLOCK_SELECT_MASK | XELPDP_SSC_ENABLE_PLLA | + XELPDP_DDI_CLOCK_SELECT_MASK(display) | XELPDP_SSC_ENABLE_PLLA | XELPDP_SSC_ENABLE_PLLB, val); } @@ -3097,10 +3099,7 @@ int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder) val = intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port)); - if (DISPLAY_VER(display) >= 30) - clock = REG_FIELD_GET(XE3_DDI_CLOCK_SELECT_MASK, val); - else - clock = REG_FIELD_GET(XELPDP_DDI_CLOCK_SELECT_MASK, val); + clock = XELPDP_DDI_CLOCK_SELECT_GET(display, val); drm_WARN_ON(display->drm, !(val & XELPDP_FORWARD_CLOCK_UNGATE)); drm_WARN_ON(display->drm, !(val & XELPDP_TBT_CLOCK_REQUEST)); @@ -3168,13 +3167,9 @@ static void intel_mtl_tbt_pll_enable(struct intel_encoder *encoder, * clock muxes, gating and SSC */ - if (DISPLAY_VER(display) >= 30) { - mask = XE3_DDI_CLOCK_SELECT_MASK; - val |= XE3_DDI_CLOCK_SELECT(intel_mtl_tbt_clock_select(display, crtc_state->port_clock)); - } else { - mask = XELPDP_DDI_CLOCK_SELECT_MASK; - val |= XELPDP_DDI_CLOCK_SELECT(intel_mtl_tbt_clock_select(display, crtc_state->port_clock)); - } + mask = XELPDP_DDI_CLOCK_SELECT_MASK(display); + val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, + intel_mtl_tbt_clock_select(display, crtc_state->port_clock)); mask |= XELPDP_FORWARD_CLOCK_UNGATE; val |= XELPDP_FORWARD_CLOCK_UNGATE; @@ -3287,7 +3282,7 @@ static void intel_cx0pll_disable(struct intel_encoder *encoder) /* 7. Program PORT_CLOCK_CTL register to disable and gate clocks. */ intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), - XELPDP_DDI_CLOCK_SELECT_MASK, 0); + XELPDP_DDI_CLOCK_SELECT_MASK(display), 0); intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), XELPDP_FORWARD_CLOCK_UNGATE, 0); @@ -3336,7 +3331,7 @@ static void intel_mtl_tbt_pll_disable(struct intel_encoder *encoder) * 5. Program PORT CLOCK CTRL register to disable and gate clocks */ intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), - XELPDP_DDI_CLOCK_SELECT_MASK | + XELPDP_DDI_CLOCK_SELECT_MASK(display) | XELPDP_FORWARD_CLOCK_UNGATE, 0); /* 6. Program DDI_CLK_VALFREQ to 0. */ @@ -3365,7 +3360,7 @@ intel_mtl_port_pll_type(struct intel_encoder *encoder, * handling is done via the standard shared DPLL framework. */ val = intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port)); - clock = REG_FIELD_GET(XELPDP_DDI_CLOCK_SELECT_MASK, val); + clock = XELPDP_DDI_CLOCK_SELECT_GET(display, val); if (clock == XELPDP_DDI_CLOCK_SELECT_MAXPCLK || clock == XELPDP_DDI_CLOCK_SELECT_DIV18CLK) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h index 960f7f778fb8..59c22beaf1de 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h @@ -192,10 +192,17 @@ #define XELPDP_TBT_CLOCK_REQUEST REG_BIT(19) #define XELPDP_TBT_CLOCK_ACK REG_BIT(18) -#define XELPDP_DDI_CLOCK_SELECT_MASK REG_GENMASK(15, 12) -#define XE3_DDI_CLOCK_SELECT_MASK REG_GENMASK(16, 12) -#define XELPDP_DDI_CLOCK_SELECT(val) REG_FIELD_PREP(XELPDP_DDI_CLOCK_SELECT_MASK, val) -#define XE3_DDI_CLOCK_SELECT(val) REG_FIELD_PREP(XE3_DDI_CLOCK_SELECT_MASK, val) +#define _XELPDP_DDI_CLOCK_SELECT_MASK REG_GENMASK(15, 12) +#define _XE3_DDI_CLOCK_SELECT_MASK REG_GENMASK(16, 12) +#define XELPDP_DDI_CLOCK_SELECT_MASK(display) (DISPLAY_VER(display) >= 30 ? \ + _XE3_DDI_CLOCK_SELECT_MASK : _XELPDP_DDI_CLOCK_SELECT_MASK) +#define XELPDP_DDI_CLOCK_SELECT_PREP(display, val) (DISPLAY_VER(display) >= 30 ? \ + REG_FIELD_PREP(_XE3_DDI_CLOCK_SELECT_MASK, (val)) : \ + REG_FIELD_PREP(_XELPDP_DDI_CLOCK_SELECT_MASK, (val))) +#define XELPDP_DDI_CLOCK_SELECT_GET(display, val) (DISPLAY_VER(display) >= 30 ? \ + REG_FIELD_GET(_XE3_DDI_CLOCK_SELECT_MASK, (val)) : \ + REG_FIELD_GET(_XELPDP_DDI_CLOCK_SELECT_MASK, (val))) + #define XELPDP_DDI_CLOCK_SELECT_NONE 0x0 #define XELPDP_DDI_CLOCK_SELECT_MAXPCLK 0x8 #define XELPDP_DDI_CLOCK_SELECT_DIV18CLK 0x9 diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index f38c998935b9..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" @@ -78,6 +80,7 @@ #include "intel_tc.h" #include "intel_vdsc.h" #include "intel_vdsc_regs.h" +#include "intel_vrr.h" #include "skl_scaler.h" #include "skl_universal_plane.h" @@ -106,14 +109,14 @@ static int intel_ddi_hdmi_level(struct intel_encoder *encoder, return level; } -static bool has_buf_trans_select(struct drm_i915_private *i915) +static bool has_buf_trans_select(struct intel_display *display) { - return DISPLAY_VER(i915) < 10 && !IS_BROXTON(i915); + return DISPLAY_VER(display) < 10 && !display->platform.broxton; } -static bool has_iboost(struct drm_i915_private *i915) +static bool has_iboost(struct intel_display *display) { - return DISPLAY_VER(i915) == 9 && !IS_BROXTON(i915); + return DISPLAY_VER(display) == 9 && !display->platform.broxton; } /* @@ -124,25 +127,25 @@ static bool has_iboost(struct drm_i915_private *i915) void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); u32 iboost_bit = 0; int i, n_entries; enum port port = encoder->port; const struct intel_ddi_buf_trans *trans; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) + if (drm_WARN_ON_ONCE(display->drm, !trans)) return; /* If we're boosting the current, set bit 31 of trans1 */ - if (has_iboost(dev_priv) && + if (has_iboost(display) && intel_bios_dp_boost_level(encoder->devdata)) iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; for (i = 0; i < n_entries; i++) { - intel_de_write(dev_priv, DDI_BUF_TRANS_LO(port, i), + intel_de_write(display, DDI_BUF_TRANS_LO(port, i), trans->entries[i].hsw.trans1 | iboost_bit); - intel_de_write(dev_priv, DDI_BUF_TRANS_HI(port, i), + intel_de_write(display, DDI_BUF_TRANS_HI(port, i), trans->entries[i].hsw.trans2); } } @@ -155,7 +158,7 @@ void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder, static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); int level = intel_ddi_level(encoder, crtc_state, 0); u32 iboost_bit = 0; int n_entries; @@ -163,27 +166,25 @@ static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder, const struct intel_ddi_buf_trans *trans; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) + if (drm_WARN_ON_ONCE(display->drm, !trans)) return; /* If we're boosting the current, set bit 31 of trans1 */ - if (has_iboost(dev_priv) && + if (has_iboost(display) && intel_bios_hdmi_boost_level(encoder->devdata)) iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; /* Entry 9 is for HDMI: */ - intel_de_write(dev_priv, DDI_BUF_TRANS_LO(port, 9), + intel_de_write(display, DDI_BUF_TRANS_LO(port, 9), trans->entries[level].hsw.trans1 | iboost_bit); - intel_de_write(dev_priv, DDI_BUF_TRANS_HI(port, 9), + intel_de_write(display, DDI_BUF_TRANS_HI(port, 9), trans->entries[level].hsw.trans2); } static i915_reg_t intel_ddi_buf_status_reg(struct intel_display *display, enum port port) { - struct drm_i915_private *i915 = to_i915(display->drm); - if (DISPLAY_VER(display) >= 14) - return XELPDP_PORT_BUF_CTL1(i915, port); + return XELPDP_PORT_BUF_CTL1(display, port); else return DDI_BUF_CTL(port); } @@ -346,7 +347,6 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); @@ -359,14 +359,14 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, if (dig_port->ddi_a_4_lanes) intel_dp->DP |= DDI_A_4_LANES; - if (DISPLAY_VER(i915) >= 14) { + if (DISPLAY_VER(display) >= 14) { if (intel_dp_is_uhbr(crtc_state)) intel_dp->DP |= DDI_BUF_PORT_DATA_40BIT; else intel_dp->DP |= DDI_BUF_PORT_DATA_10BIT; } - if (IS_ALDERLAKE_P(i915) && intel_encoder_is_tc(encoder)) { + if (display->platform.alderlake_p && intel_encoder_is_tc(encoder)) { intel_dp->DP |= ddi_buf_phy_link_rate(crtc_state->port_clock); if (!intel_tc_port_in_tbt_alt_mode(dig_port)) intel_dp->DP |= DDI_BUF_CTL_TC_PHY_OWNERSHIP; @@ -379,8 +379,7 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder, } } -static int icl_calc_tbt_pll_link(struct intel_display *display, - enum port port) +static int icl_calc_tbt_pll_link(struct intel_display *display, enum port port) { u32 val = intel_de_read(display, DDI_CLK_SEL(port)) & DDI_CLK_SEL_MASK; @@ -414,15 +413,14 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config) void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_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_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 temp; if (!intel_crtc_has_dp_encoder(crtc_state)) return; - drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)); + drm_WARN_ON(display->drm, transcoder_is_dsi(cpu_transcoder)); temp = DP_MSA_MISC_SYNC_CLOCK; @@ -445,7 +443,7 @@ void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state, } /* nonsense combination */ - drm_WARN_ON(&dev_priv->drm, crtc_state->limited_color_range && + drm_WARN_ON(display->drm, crtc_state->limited_color_range && crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB); if (crtc_state->limited_color_range) @@ -468,7 +466,7 @@ void intel_ddi_set_dp_msa(const struct intel_crtc_state *crtc_state, if (intel_dp_needs_vsc_sdp(crtc_state, conn_state)) temp |= DP_MSA_MISC_COLOR_VSC_SDP; - intel_de_write(dev_priv, TRANS_MSA_MISC(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_MSA_MISC(display, cpu_transcoder), temp); } @@ -507,8 +505,8 @@ static u32 intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder, 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; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; enum port port = encoder->port; @@ -516,7 +514,7 @@ intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder, /* Enable TRANS_DDI_FUNC_CTL for the pipe to work in HDMI mode */ temp = TRANS_DDI_FUNC_ENABLE; - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) temp |= TGL_TRANS_DDI_SELECT_PORT(port); else temp |= TRANS_DDI_SELECT_PORT(port); @@ -578,7 +576,7 @@ intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder, temp |= TRANS_DDI_HDMI_SCRAMBLING; if (crtc_state->hdmi_high_tmds_clock_ratio) temp |= TRANS_DDI_HIGH_TMDS_CHAR_RATE; - if (DISPLAY_VER(dev_priv) >= 14) + if (DISPLAY_VER(display) >= 14) temp |= TRANS_DDI_PORT_WIDTH(crtc_state->lane_count); } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) { temp |= TRANS_DDI_MODE_SELECT_FDI_OR_128B132B; @@ -591,11 +589,11 @@ intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder, temp |= TRANS_DDI_MODE_SELECT_DP_MST; temp |= DDI_PORT_WIDTH(crtc_state->lane_count); - if (DISPLAY_VER(dev_priv) >= 12) { + if (DISPLAY_VER(display) >= 12) { enum transcoder master; master = crtc_state->mst_master_transcoder; - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, master == INVALID_TRANSCODER); temp |= TRANS_DDI_MST_TRANSPORT_SELECT(master); } @@ -604,7 +602,7 @@ intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder, temp |= DDI_PORT_WIDTH(crtc_state->lane_count); } - if (IS_DISPLAY_VER(dev_priv, 8, 10) && + if (IS_DISPLAY_VER(display, 8, 10) && crtc_state->master_transcoder != INVALID_TRANSCODER) { u8 master_select = bdw_trans_port_sync_master_select(crtc_state->master_transcoder); @@ -619,11 +617,10 @@ intel_ddi_transcoder_func_reg_val_get(struct intel_encoder *encoder, void intel_ddi_enable_transcoder_func(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; - if (DISPLAY_VER(dev_priv) >= 11) { + if (DISPLAY_VER(display) >= 11) { enum transcoder master_transcoder = crtc_state->master_transcoder; u32 ctl2 = 0; @@ -635,12 +632,12 @@ void intel_ddi_enable_transcoder_func(struct intel_encoder *encoder, PORT_SYNC_MODE_MASTER_SELECT(master_select); } - intel_de_write(dev_priv, - TRANS_DDI_FUNC_CTL2(dev_priv, cpu_transcoder), + intel_de_write(display, + TRANS_DDI_FUNC_CTL2(display, cpu_transcoder), ctl2); } - intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_DDI_FUNC_CTL(display, cpu_transcoder), intel_ddi_transcoder_func_reg_val_get(encoder, crtc_state)); } @@ -654,8 +651,7 @@ void intel_ddi_config_transcoder_func(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 ctl; @@ -663,7 +659,7 @@ intel_ddi_config_transcoder_func(struct intel_encoder *encoder, ctl = intel_ddi_transcoder_func_reg_val_get(encoder, crtc_state); ctl &= ~TRANS_DDI_FUNC_ENABLE; - intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_DDI_FUNC_CTL(display, cpu_transcoder), ctl); } @@ -677,27 +673,26 @@ void intel_ddi_disable_transcoder_func(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 transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 ctl; - if (DISPLAY_VER(dev_priv) >= 11) - intel_de_write(dev_priv, - TRANS_DDI_FUNC_CTL2(dev_priv, cpu_transcoder), + if (DISPLAY_VER(display) >= 11) + intel_de_write(display, + TRANS_DDI_FUNC_CTL2(display, cpu_transcoder), 0); - ctl = intel_de_read(dev_priv, - TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)); + ctl = intel_de_read(display, + TRANS_DDI_FUNC_CTL(display, cpu_transcoder)); drm_WARN_ON(crtc->base.dev, ctl & TRANS_DDI_HDCP_SIGNALLING); ctl &= ~TRANS_DDI_FUNC_ENABLE; - if (IS_DISPLAY_VER(dev_priv, 8, 10)) + if (IS_DISPLAY_VER(display, 8, 10)) ctl &= ~(TRANS_DDI_PORT_SYNC_ENABLE | TRANS_DDI_PORT_SYNC_MASTER_SELECT_MASK); - if (DISPLAY_VER(dev_priv) >= 12) { + if (DISPLAY_VER(display) >= 12) { if (!intel_dp_mst_is_master_trans(crtc_state)) { ctl &= ~(TGL_TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK); @@ -706,7 +701,7 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state ctl &= ~(TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK); } - intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder), + intel_de_write(display, TRANS_DDI_FUNC_CTL(display, cpu_transcoder), ctl); if (intel_dp_mst_is_slave_trans(crtc_state)) @@ -725,17 +720,15 @@ int intel_ddi_toggle_hdcp_bits(struct intel_encoder *intel_encoder, bool enable, u32 hdcp_mask) { struct intel_display *display = to_intel_display(intel_encoder); - struct drm_device *dev = intel_encoder->base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); intel_wakeref_t wakeref; int ret = 0; wakeref = intel_display_power_get_if_enabled(display, intel_encoder->power_domain); - if (drm_WARN_ON(dev, !wakeref)) + if (drm_WARN_ON(display->drm, !wakeref)) return -ENXIO; - intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder), + intel_de_rmw(display, TRANS_DDI_FUNC_CTL(display, cpu_transcoder), hdcp_mask, enable ? hdcp_mask : 0); intel_display_power_put(display, intel_encoder->power_domain, wakeref); return ret; @@ -744,7 +737,6 @@ int intel_ddi_toggle_hdcp_bits(struct intel_encoder *intel_encoder, bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) { struct intel_display *display = to_intel_display(intel_connector); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_encoder *encoder = intel_attached_encoder(intel_connector); int type = intel_connector->base.connector_type; enum port port = encoder->port; @@ -765,12 +757,12 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) goto out; } - if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A) + if (HAS_TRANSCODER(display, TRANSCODER_EDP) && port == PORT_A) cpu_transcoder = TRANSCODER_EDP; else cpu_transcoder = (enum transcoder) pipe; - ddi_mode = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)) & + ddi_mode = intel_de_read(display, TRANS_DDI_FUNC_CTL(display, cpu_transcoder)) & TRANS_DDI_MODE_SELECT_MASK; if (ddi_mode == TRANS_DDI_MODE_SELECT_HDMI || @@ -804,7 +796,6 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, u8 *pipe_mask, bool *is_dp_mst) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(display->drm); enum port port = encoder->port; intel_wakeref_t wakeref; enum pipe p; @@ -819,13 +810,13 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, if (!wakeref) return; - tmp = intel_de_read(dev_priv, DDI_BUF_CTL(port)); + tmp = intel_de_read(display, DDI_BUF_CTL(port)); if (!(tmp & DDI_BUF_CTL_ENABLE)) goto out; - if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A) { - tmp = intel_de_read(dev_priv, - TRANS_DDI_FUNC_CTL(dev_priv, TRANSCODER_EDP)); + if (HAS_TRANSCODER(display, TRANSCODER_EDP) && port == PORT_A) { + tmp = intel_de_read(display, + TRANS_DDI_FUNC_CTL(display, TRANSCODER_EDP)); switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { default: @@ -846,7 +837,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, goto out; } - for_each_pipe(dev_priv, p) { + for_each_pipe(display, p) { enum transcoder cpu_transcoder = (enum transcoder)p; u32 port_mask, ddi_select, ddi_mode; intel_wakeref_t trans_wakeref; @@ -856,7 +847,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, if (!trans_wakeref) continue; - if (DISPLAY_VER(dev_priv) >= 12) { + if (DISPLAY_VER(display) >= 12) { port_mask = TGL_TRANS_DDI_PORT_MASK; ddi_select = TGL_TRANS_DDI_SELECT_PORT(port); } else { @@ -864,8 +855,8 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, ddi_select = TRANS_DDI_SELECT_PORT(port); } - tmp = intel_de_read(dev_priv, - TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)); + tmp = intel_de_read(display, + TRANS_DDI_FUNC_CTL(display, cpu_transcoder)); intel_display_power_put(display, POWER_DOMAIN_TRANSCODER(cpu_transcoder), trans_wakeref); @@ -883,12 +874,12 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, } if (!*pipe_mask) - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "No pipe for [ENCODER:%d:%s] found\n", encoder->base.base.id, encoder->base.name); if (!mst_pipe_mask && dp128b132b_pipe_mask) { - struct intel_digital_port *dig_port = enc_to_dig_port(encoder); + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); /* * If we don't have 8b/10b MST, but have more than one @@ -901,12 +892,12 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, * can assume it's SST. */ if (hweight8(dp128b132b_pipe_mask) > 1 || - intel_dp_mst_encoder_active_links(dig_port)) + intel_dp_mst_active_streams(intel_dp)) mst_pipe_mask = dp128b132b_pipe_mask; } if (!mst_pipe_mask && hweight8(*pipe_mask) > 1) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Multiple pipes for [ENCODER:%d:%s] (pipe_mask %02x)\n", encoder->base.base.id, encoder->base.name, *pipe_mask); @@ -914,7 +905,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, } if (mst_pipe_mask && mst_pipe_mask != *pipe_mask) - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Conflicting MST and non-MST state for [ENCODER:%d:%s] (pipe masks: all %02x, MST %02x, 128b/132b %02x)\n", encoder->base.base.id, encoder->base.name, *pipe_mask, mst_pipe_mask, dp128b132b_pipe_mask); @@ -922,12 +913,12 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, *is_dp_mst = mst_pipe_mask; out: - if (*pipe_mask && (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))) { - tmp = intel_de_read(dev_priv, BXT_PHY_CTL(port)); + if (*pipe_mask && (display->platform.geminilake || display->platform.broxton)) { + tmp = intel_de_read(display, BXT_PHY_CTL(port)); if ((tmp & (BXT_PHY_CMNLANE_POWERDOWN_ACK | BXT_PHY_LANE_POWERDOWN_ACK | BXT_PHY_LANE_ENABLED)) != BXT_PHY_LANE_ENABLED) - drm_err(&dev_priv->drm, + drm_err(display->drm, "[ENCODER:%d:%s] enabled but PHY powered down? (PHY_CTL %08x)\n", encoder->base.base.id, encoder->base.name, tmp); } @@ -1041,8 +1032,7 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder, void intel_ddi_enable_transcoder_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; enum phy phy = intel_encoder_to_phy(encoder); u32 val; @@ -1050,53 +1040,53 @@ void intel_ddi_enable_transcoder_clock(struct intel_encoder *encoder, if (cpu_transcoder == TRANSCODER_EDP) return; - if (DISPLAY_VER(dev_priv) >= 13) + if (DISPLAY_VER(display) >= 13) val = TGL_TRANS_CLK_SEL_PORT(phy); - else if (DISPLAY_VER(dev_priv) >= 12) + else if (DISPLAY_VER(display) >= 12) val = TGL_TRANS_CLK_SEL_PORT(encoder->port); else val = TRANS_CLK_SEL_PORT(encoder->port); - intel_de_write(dev_priv, TRANS_CLK_SEL(cpu_transcoder), val); + intel_de_write(display, TRANS_CLK_SEL(cpu_transcoder), val); } void intel_ddi_disable_transcoder_clock(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 val; if (cpu_transcoder == TRANSCODER_EDP) return; - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) val = TGL_TRANS_CLK_SEL_DISABLED; else val = TRANS_CLK_SEL_DISABLED; - intel_de_write(dev_priv, TRANS_CLK_SEL(cpu_transcoder), val); + intel_de_write(display, TRANS_CLK_SEL(cpu_transcoder), val); } -static void _skl_ddi_set_iboost(struct drm_i915_private *dev_priv, +static void _skl_ddi_set_iboost(struct intel_display *display, enum port port, u8 iboost) { u32 tmp; - tmp = intel_de_read(dev_priv, DISPIO_CR_TX_BMU_CR0); + tmp = intel_de_read(display, DISPIO_CR_TX_BMU_CR0); tmp &= ~(BALANCE_LEG_MASK(port) | BALANCE_LEG_DISABLE(port)); if (iboost) tmp |= iboost << BALANCE_LEG_SHIFT(port); else tmp |= BALANCE_LEG_DISABLE(port); - intel_de_write(dev_priv, DISPIO_CR_TX_BMU_CR0, tmp); + intel_de_write(display, DISPIO_CR_TX_BMU_CR0, tmp); } static void skl_ddi_set_iboost(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, int level) { + struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u8 iboost; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) @@ -1109,7 +1099,7 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, int n_entries; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) + if (drm_WARN_ON_ONCE(display->drm, !trans)) return; iboost = trans->entries[level].hsw.i_boost; @@ -1117,28 +1107,28 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder, /* Make sure that the requested I_boost is valid */ if (iboost && iboost != 0x1 && iboost != 0x3 && iboost != 0x7) { - drm_err(&dev_priv->drm, "Invalid I_boost value %u\n", iboost); + drm_err(display->drm, "Invalid I_boost value %u\n", iboost); return; } - _skl_ddi_set_iboost(dev_priv, encoder->port, iboost); + _skl_ddi_set_iboost(display, encoder->port, iboost); if (encoder->port == PORT_A && dig_port->max_lanes == 4) - _skl_ddi_set_iboost(dev_priv, PORT_E, iboost); + _skl_ddi_set_iboost(display, PORT_E, iboost); } static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(intel_dp); struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); int n_entries; encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON(&dev_priv->drm, n_entries < 1)) + if (drm_WARN_ON(display->drm, n_entries < 1)) n_entries = 1; - if (drm_WARN_ON(&dev_priv->drm, + if (drm_WARN_ON(display->drm, n_entries > ARRAY_SIZE(index_to_dp_signal_levels))) n_entries = ARRAY_SIZE(index_to_dp_signal_levels); @@ -1171,14 +1161,14 @@ static u32 icl_combo_phy_loadgen_select(const struct intel_crtc_state *crtc_stat static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_ddi_buf_trans *trans; enum phy phy = intel_encoder_to_phy(encoder); int n_entries, ln; u32 val; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) + if (drm_WARN_ON_ONCE(display->drm, !trans)) return; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) { @@ -1186,25 +1176,25 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, val = EDP4K2K_MODE_OVRD_EN | EDP4K2K_MODE_OVRD_OPTIMIZED; intel_dp->hobl_active = is_hobl_buf_trans(trans); - intel_de_rmw(dev_priv, ICL_PORT_CL_DW10(phy), val, + intel_de_rmw(display, ICL_PORT_CL_DW10(phy), val, intel_dp->hobl_active ? val : 0); } /* Set PORT_TX_DW5 */ - val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy)); + val = intel_de_read(display, ICL_PORT_TX_DW5_LN(0, phy)); val &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK | COEFF_POLARITY | CURSOR_PROGRAM | TAP2_DISABLE | TAP3_DISABLE); val |= SCALING_MODE_SEL(0x2); val |= RTERM_SELECT(0x6); val |= TAP3_DISABLE; - intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); + intel_de_write(display, ICL_PORT_TX_DW5_GRP(phy), val); /* Program PORT_TX_DW2 */ for (ln = 0; ln < 4; ln++) { int level = intel_ddi_level(encoder, crtc_state, ln); - intel_de_rmw(dev_priv, ICL_PORT_TX_DW2_LN(ln, phy), + intel_de_rmw(display, ICL_PORT_TX_DW2_LN(ln, phy), SWING_SEL_UPPER_MASK | SWING_SEL_LOWER_MASK | RCOMP_SCALAR_MASK, SWING_SEL_UPPER(trans->entries[level].icl.dw2_swing_sel) | SWING_SEL_LOWER(trans->entries[level].icl.dw2_swing_sel) | @@ -1216,7 +1206,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, for (ln = 0; ln < 4; ln++) { int level = intel_ddi_level(encoder, crtc_state, ln); - intel_de_rmw(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy), + intel_de_rmw(display, ICL_PORT_TX_DW4_LN(ln, phy), POST_CURSOR_1_MASK | POST_CURSOR_2_MASK | CURSOR_COEFF_MASK, POST_CURSOR_1(trans->entries[level].icl.dw4_post_cursor_1) | POST_CURSOR_2(trans->entries[level].icl.dw4_post_cursor_2) | @@ -1227,7 +1217,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, for (ln = 0; ln < 4; ln++) { int level = intel_ddi_level(encoder, crtc_state, ln); - intel_de_rmw(dev_priv, ICL_PORT_TX_DW7_LN(ln, phy), + intel_de_rmw(display, ICL_PORT_TX_DW7_LN(ln, phy), N_SCALAR_MASK, N_SCALAR(trans->entries[level].icl.dw7_n_scalar)); } @@ -1236,7 +1226,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, static void icl_combo_phy_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - 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); u32 val; int ln; @@ -1246,12 +1236,12 @@ static void icl_combo_phy_set_signal_levels(struct intel_encoder *encoder, * set PORT_PCS_DW1 cmnkeeper_enable to 1b, * else clear to 0b. */ - val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN(0, phy)); + val = intel_de_read(display, ICL_PORT_PCS_DW1_LN(0, phy)); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) val &= ~COMMON_KEEPER_EN; else val |= COMMON_KEEPER_EN; - intel_de_write(dev_priv, ICL_PORT_PCS_DW1_GRP(phy), val); + intel_de_write(display, ICL_PORT_PCS_DW1_GRP(phy), val); /* 2. Program loadgen select */ /* @@ -1261,33 +1251,33 @@ static void icl_combo_phy_set_signal_levels(struct intel_encoder *encoder, * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0) */ for (ln = 0; ln < 4; ln++) { - intel_de_rmw(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy), + intel_de_rmw(display, ICL_PORT_TX_DW4_LN(ln, phy), LOADGEN_SELECT, icl_combo_phy_loadgen_select(crtc_state, ln)); } /* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */ - intel_de_rmw(dev_priv, ICL_PORT_CL_DW5(phy), + intel_de_rmw(display, ICL_PORT_CL_DW5(phy), 0, SUS_CLOCK_CONFIG); /* 4. Clear training enable to change swing values */ - val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy)); + val = intel_de_read(display, ICL_PORT_TX_DW5_LN(0, phy)); val &= ~TX_TRAINING_EN; - intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); + intel_de_write(display, ICL_PORT_TX_DW5_GRP(phy), val); /* 5. Program swing and de-emphasis */ icl_ddi_combo_vswing_program(encoder, crtc_state); /* 6. Set training enable to trigger update */ - val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN(0, phy)); + val = intel_de_read(display, ICL_PORT_TX_DW5_LN(0, phy)); val |= TX_TRAINING_EN; - intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val); + intel_de_write(display, ICL_PORT_TX_DW5_GRP(phy), val); } static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum tc_port tc_port = intel_encoder_to_tc(encoder); const struct intel_ddi_buf_trans *trans; int n_entries, ln; @@ -1296,13 +1286,13 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, return; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&dev_priv->drm, !trans)) + if (drm_WARN_ON_ONCE(display->drm, !trans)) return; for (ln = 0; ln < 2; ln++) { - intel_de_rmw(dev_priv, MG_TX1_LINK_PARAMS(ln, tc_port), + intel_de_rmw(display, MG_TX1_LINK_PARAMS(ln, tc_port), CRI_USE_FS32, 0); - intel_de_rmw(dev_priv, MG_TX2_LINK_PARAMS(ln, tc_port), + intel_de_rmw(display, MG_TX2_LINK_PARAMS(ln, tc_port), CRI_USE_FS32, 0); } @@ -1312,13 +1302,13 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, level = intel_ddi_level(encoder, crtc_state, 2*ln+0); - intel_de_rmw(dev_priv, MG_TX1_SWINGCTRL(ln, tc_port), + intel_de_rmw(display, MG_TX1_SWINGCTRL(ln, tc_port), CRI_TXDEEMPH_OVERRIDE_17_12_MASK, CRI_TXDEEMPH_OVERRIDE_17_12(trans->entries[level].mg.cri_txdeemph_override_17_12)); level = intel_ddi_level(encoder, crtc_state, 2*ln+1); - intel_de_rmw(dev_priv, MG_TX2_SWINGCTRL(ln, tc_port), + intel_de_rmw(display, MG_TX2_SWINGCTRL(ln, tc_port), CRI_TXDEEMPH_OVERRIDE_17_12_MASK, CRI_TXDEEMPH_OVERRIDE_17_12(trans->entries[level].mg.cri_txdeemph_override_17_12)); } @@ -1329,7 +1319,7 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, level = intel_ddi_level(encoder, crtc_state, 2*ln+0); - intel_de_rmw(dev_priv, MG_TX1_DRVCTRL(ln, tc_port), + intel_de_rmw(display, MG_TX1_DRVCTRL(ln, tc_port), CRI_TXDEEMPH_OVERRIDE_11_6_MASK | CRI_TXDEEMPH_OVERRIDE_5_0_MASK, CRI_TXDEEMPH_OVERRIDE_11_6(trans->entries[level].mg.cri_txdeemph_override_11_6) | @@ -1338,7 +1328,7 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, level = intel_ddi_level(encoder, crtc_state, 2*ln+1); - intel_de_rmw(dev_priv, MG_TX2_DRVCTRL(ln, tc_port), + intel_de_rmw(display, MG_TX2_DRVCTRL(ln, tc_port), CRI_TXDEEMPH_OVERRIDE_11_6_MASK | CRI_TXDEEMPH_OVERRIDE_5_0_MASK, CRI_TXDEEMPH_OVERRIDE_11_6(trans->entries[level].mg.cri_txdeemph_override_11_6) | @@ -1354,21 +1344,21 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, * values from table for which TX1 and TX2 enabled. */ for (ln = 0; ln < 2; ln++) { - intel_de_rmw(dev_priv, MG_CLKHUB(ln, tc_port), + intel_de_rmw(display, MG_CLKHUB(ln, tc_port), CFG_LOW_RATE_LKREN_EN, crtc_state->port_clock < 300000 ? CFG_LOW_RATE_LKREN_EN : 0); } /* Program the MG_TX_DCC<LN, port being used> based on the link frequency */ for (ln = 0; ln < 2; ln++) { - intel_de_rmw(dev_priv, MG_TX1_DCC(ln, tc_port), + intel_de_rmw(display, MG_TX1_DCC(ln, tc_port), CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK | CFG_AMI_CK_DIV_OVERRIDE_EN, crtc_state->port_clock > 500000 ? CFG_AMI_CK_DIV_OVERRIDE_VAL(1) | CFG_AMI_CK_DIV_OVERRIDE_EN : 0); - intel_de_rmw(dev_priv, MG_TX2_DCC(ln, tc_port), + intel_de_rmw(display, MG_TX2_DCC(ln, tc_port), CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK | CFG_AMI_CK_DIV_OVERRIDE_EN, crtc_state->port_clock > 500000 ? @@ -1378,9 +1368,9 @@ static void icl_mg_phy_set_signal_levels(struct intel_encoder *encoder, /* Program MG_TX_PISO_READLOAD with values from vswing table */ for (ln = 0; ln < 2; ln++) { - intel_de_rmw(dev_priv, MG_TX1_PISO_READLOAD(ln, tc_port), + intel_de_rmw(display, MG_TX1_PISO_READLOAD(ln, tc_port), 0, CRI_CALCINIT); - intel_de_rmw(dev_priv, MG_TX2_PISO_READLOAD(ln, tc_port), + intel_de_rmw(display, MG_TX2_PISO_READLOAD(ln, tc_port), 0, CRI_CALCINIT); } } @@ -1490,12 +1480,12 @@ int intel_ddi_level(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state, int lane) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_ddi_buf_trans *trans; int level, n_entries; trans = encoder->get_buf_trans(encoder, crtc_state, &n_entries); - if (drm_WARN_ON_ONCE(&i915->drm, !trans)) + if (drm_WARN_ON_ONCE(display->drm, !trans)) return 0; if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) @@ -1504,7 +1494,7 @@ int intel_ddi_level(struct intel_encoder *encoder, level = intel_ddi_dp_level(enc_to_intel_dp(encoder), crtc_state, lane); - if (drm_WARN_ON_ONCE(&i915->drm, level >= n_entries)) + if (drm_WARN_ON_ONCE(display->drm, level >= n_entries)) level = n_entries - 1; return level; @@ -1514,13 +1504,13 @@ static void hsw_set_signal_levels(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); int level = intel_ddi_level(encoder, crtc_state, 0); enum port port = encoder->port; u32 signal_levels; - if (has_iboost(dev_priv)) + if (has_iboost(display)) skl_ddi_set_iboost(encoder, crtc_state, level); /* HDMI ignores the rest */ @@ -1529,46 +1519,46 @@ hsw_set_signal_levels(struct intel_encoder *encoder, signal_levels = DDI_BUF_TRANS_SELECT(level); - drm_dbg_kms(&dev_priv->drm, "Using signal levels %08x\n", + drm_dbg_kms(display->drm, "Using signal levels %08x\n", signal_levels); intel_dp->DP &= ~DDI_BUF_EMP_MASK; intel_dp->DP |= signal_levels; - intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP); - intel_de_posting_read(dev_priv, DDI_BUF_CTL(port)); + intel_de_write(display, DDI_BUF_CTL(port), intel_dp->DP); + intel_de_posting_read(display, DDI_BUF_CTL(port)); } -static void _icl_ddi_enable_clock(struct drm_i915_private *i915, i915_reg_t reg, +static void _icl_ddi_enable_clock(struct intel_display *display, i915_reg_t reg, u32 clk_sel_mask, u32 clk_sel, u32 clk_off) { - mutex_lock(&i915->display.dpll.lock); + mutex_lock(&display->dpll.lock); - intel_de_rmw(i915, reg, clk_sel_mask, clk_sel); + intel_de_rmw(display, reg, clk_sel_mask, clk_sel); /* * "This step and the step before must be * done with separate register writes." */ - intel_de_rmw(i915, reg, clk_off, 0); + intel_de_rmw(display, reg, clk_off, 0); - mutex_unlock(&i915->display.dpll.lock); + mutex_unlock(&display->dpll.lock); } -static void _icl_ddi_disable_clock(struct drm_i915_private *i915, i915_reg_t reg, +static void _icl_ddi_disable_clock(struct intel_display *display, i915_reg_t reg, u32 clk_off) { - mutex_lock(&i915->display.dpll.lock); + mutex_lock(&display->dpll.lock); - intel_de_rmw(i915, reg, 0, clk_off); + intel_de_rmw(display, reg, 0, clk_off); - mutex_unlock(&i915->display.dpll.lock); + mutex_unlock(&display->dpll.lock); } -static bool _icl_ddi_is_clock_enabled(struct drm_i915_private *i915, i915_reg_t reg, +static bool _icl_ddi_is_clock_enabled(struct intel_display *display, i915_reg_t reg, u32 clk_off) { - return !(intel_de_read(i915, reg) & clk_off); + return !(intel_de_read(display, reg) & clk_off); } static struct intel_shared_dpll * @@ -1585,14 +1575,14 @@ _icl_ddi_get_pll(struct intel_display *display, i915_reg_t reg, static void adls_ddi_enable_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum phy phy = intel_encoder_to_phy(encoder); - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; - _icl_ddi_enable_clock(i915, ADLS_DPCLKA_CFGCR(phy), + _icl_ddi_enable_clock(display, ADLS_DPCLKA_CFGCR(phy), ADLS_DPCLKA_CFGCR_DDI_CLK_SEL_MASK(phy), pll->info->id << ADLS_DPCLKA_CFGCR_DDI_SHIFT(phy), ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); @@ -1600,19 +1590,19 @@ static void adls_ddi_enable_clock(struct intel_encoder *encoder, static void adls_ddi_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - _icl_ddi_disable_clock(i915, ADLS_DPCLKA_CFGCR(phy), + _icl_ddi_disable_clock(display, ADLS_DPCLKA_CFGCR(phy), ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); } static bool adls_ddi_is_clock_enabled(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - return _icl_ddi_is_clock_enabled(i915, ADLS_DPCLKA_CFGCR(phy), + return _icl_ddi_is_clock_enabled(display, ADLS_DPCLKA_CFGCR(phy), ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); } @@ -1629,14 +1619,14 @@ static struct intel_shared_dpll *adls_ddi_get_pll(struct intel_encoder *encoder) static void rkl_ddi_enable_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum phy phy = intel_encoder_to_phy(encoder); - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; - _icl_ddi_enable_clock(i915, ICL_DPCLKA_CFGCR0, + _icl_ddi_enable_clock(display, ICL_DPCLKA_CFGCR0, RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), RKL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy), RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); @@ -1644,19 +1634,19 @@ static void rkl_ddi_enable_clock(struct intel_encoder *encoder, static void rkl_ddi_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - _icl_ddi_disable_clock(i915, ICL_DPCLKA_CFGCR0, + _icl_ddi_disable_clock(display, ICL_DPCLKA_CFGCR0, RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); } static bool rkl_ddi_is_clock_enabled(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - return _icl_ddi_is_clock_enabled(i915, ICL_DPCLKA_CFGCR0, + return _icl_ddi_is_clock_enabled(display, ICL_DPCLKA_CFGCR0, RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); } @@ -1673,23 +1663,23 @@ static struct intel_shared_dpll *rkl_ddi_get_pll(struct intel_encoder *encoder) static void dg1_ddi_enable_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum phy phy = intel_encoder_to_phy(encoder); - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; /* * If we fail this, something went very wrong: first 2 PLLs should be * used by first 2 phys and last 2 PLLs by last phys */ - if (drm_WARN_ON(&i915->drm, + if (drm_WARN_ON(display->drm, (pll->info->id < DPLL_ID_DG1_DPLL2 && phy >= PHY_C) || (pll->info->id >= DPLL_ID_DG1_DPLL2 && phy < PHY_C))) return; - _icl_ddi_enable_clock(i915, DG1_DPCLKA_CFGCR0(phy), + _icl_ddi_enable_clock(display, DG1_DPCLKA_CFGCR0(phy), DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), DG1_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy), DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); @@ -1697,19 +1687,19 @@ static void dg1_ddi_enable_clock(struct intel_encoder *encoder, static void dg1_ddi_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - _icl_ddi_disable_clock(i915, DG1_DPCLKA_CFGCR0(phy), + _icl_ddi_disable_clock(display, DG1_DPCLKA_CFGCR0(phy), DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); } static bool dg1_ddi_is_clock_enabled(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - return _icl_ddi_is_clock_enabled(i915, DG1_DPCLKA_CFGCR0(phy), + return _icl_ddi_is_clock_enabled(display, DG1_DPCLKA_CFGCR0(phy), DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); } @@ -1739,14 +1729,14 @@ static struct intel_shared_dpll *dg1_ddi_get_pll(struct intel_encoder *encoder) static void icl_ddi_combo_enable_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum phy phy = intel_encoder_to_phy(encoder); - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; - _icl_ddi_enable_clock(i915, ICL_DPCLKA_CFGCR0, + _icl_ddi_enable_clock(display, ICL_DPCLKA_CFGCR0, ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy), ICL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy), ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); @@ -1754,19 +1744,19 @@ static void icl_ddi_combo_enable_clock(struct intel_encoder *encoder, static void icl_ddi_combo_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - _icl_ddi_disable_clock(i915, ICL_DPCLKA_CFGCR0, + _icl_ddi_disable_clock(display, ICL_DPCLKA_CFGCR0, ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); } static bool icl_ddi_combo_is_clock_enabled(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum phy phy = intel_encoder_to_phy(encoder); - return _icl_ddi_is_clock_enabled(i915, ICL_DPCLKA_CFGCR0, + return _icl_ddi_is_clock_enabled(display, ICL_DPCLKA_CFGCR0, ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)); } @@ -1783,39 +1773,39 @@ struct intel_shared_dpll *icl_ddi_combo_get_pll(struct intel_encoder *encoder) static void jsl_ddi_tc_enable_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum port port = encoder->port; - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; /* * "For DDIC and DDID, program DDI_CLK_SEL to map the MG clock to the port. * MG does not exist, but the programming is required to ungate DDIC and DDID." */ - intel_de_write(i915, DDI_CLK_SEL(port), DDI_CLK_SEL_MG); + intel_de_write(display, DDI_CLK_SEL(port), DDI_CLK_SEL_MG); icl_ddi_combo_enable_clock(encoder, crtc_state); } static void jsl_ddi_tc_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; icl_ddi_combo_disable_clock(encoder); - intel_de_write(i915, DDI_CLK_SEL(port), DDI_CLK_SEL_NONE); + intel_de_write(display, DDI_CLK_SEL(port), DDI_CLK_SEL_NONE); } static bool jsl_ddi_tc_is_clock_enabled(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; u32 tmp; - tmp = intel_de_read(i915, DDI_CLK_SEL(port)); + tmp = intel_de_read(display, DDI_CLK_SEL(port)); if ((tmp & DDI_CLK_SEL_MASK) == DDI_CLK_SEL_NONE) return false; @@ -1826,54 +1816,54 @@ static bool jsl_ddi_tc_is_clock_enabled(struct intel_encoder *encoder) static void icl_ddi_tc_enable_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum tc_port tc_port = intel_encoder_to_tc(encoder); enum port port = encoder->port; - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; - intel_de_write(i915, DDI_CLK_SEL(port), + intel_de_write(display, DDI_CLK_SEL(port), icl_pll_to_ddi_clk_sel(encoder, crtc_state)); - mutex_lock(&i915->display.dpll.lock); + mutex_lock(&display->dpll.lock); - intel_de_rmw(i915, ICL_DPCLKA_CFGCR0, + intel_de_rmw(display, ICL_DPCLKA_CFGCR0, ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port), 0); - mutex_unlock(&i915->display.dpll.lock); + mutex_unlock(&display->dpll.lock); } static void icl_ddi_tc_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum tc_port tc_port = intel_encoder_to_tc(encoder); enum port port = encoder->port; - mutex_lock(&i915->display.dpll.lock); + mutex_lock(&display->dpll.lock); - intel_de_rmw(i915, ICL_DPCLKA_CFGCR0, + intel_de_rmw(display, ICL_DPCLKA_CFGCR0, 0, ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port)); - mutex_unlock(&i915->display.dpll.lock); + mutex_unlock(&display->dpll.lock); - intel_de_write(i915, DDI_CLK_SEL(port), DDI_CLK_SEL_NONE); + intel_de_write(display, DDI_CLK_SEL(port), DDI_CLK_SEL_NONE); } static bool icl_ddi_tc_is_clock_enabled(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum tc_port tc_port = intel_encoder_to_tc(encoder); enum port port = encoder->port; u32 tmp; - tmp = intel_de_read(i915, DDI_CLK_SEL(port)); + tmp = intel_de_read(display, DDI_CLK_SEL(port)); if ((tmp & DDI_CLK_SEL_MASK) == DDI_CLK_SEL_NONE) return false; - tmp = intel_de_read(i915, ICL_DPCLKA_CFGCR0); + tmp = intel_de_read(display, ICL_DPCLKA_CFGCR0); return !(tmp & ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port)); } @@ -1934,47 +1924,47 @@ static struct intel_shared_dpll *bxt_ddi_get_pll(struct intel_encoder *encoder) static void skl_ddi_enable_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum port port = encoder->port; - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; - mutex_lock(&i915->display.dpll.lock); + mutex_lock(&display->dpll.lock); - intel_de_rmw(i915, DPLL_CTRL2, + intel_de_rmw(display, DPLL_CTRL2, DPLL_CTRL2_DDI_CLK_OFF(port) | DPLL_CTRL2_DDI_CLK_SEL_MASK(port), DPLL_CTRL2_DDI_CLK_SEL(pll->info->id, port) | DPLL_CTRL2_DDI_SEL_OVERRIDE(port)); - mutex_unlock(&i915->display.dpll.lock); + mutex_unlock(&display->dpll.lock); } static void skl_ddi_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; - mutex_lock(&i915->display.dpll.lock); + mutex_lock(&display->dpll.lock); - intel_de_rmw(i915, DPLL_CTRL2, + intel_de_rmw(display, DPLL_CTRL2, 0, DPLL_CTRL2_DDI_CLK_OFF(port)); - mutex_unlock(&i915->display.dpll.lock); + mutex_unlock(&display->dpll.lock); } static bool skl_ddi_is_clock_enabled(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; /* * FIXME Not sure if the override affects both * the PLL selection and the CLK_OFF bit. */ - return !(intel_de_read(i915, DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_OFF(port)); + return !(intel_de_read(display, DPLL_CTRL2) & DPLL_CTRL2_DDI_CLK_OFF(port)); } static struct intel_shared_dpll *skl_ddi_get_pll(struct intel_encoder *encoder) @@ -2002,30 +1992,30 @@ static struct intel_shared_dpll *skl_ddi_get_pll(struct intel_encoder *encoder) void hsw_ddi_enable_clock(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; enum port port = encoder->port; - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return; - intel_de_write(i915, PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll)); + intel_de_write(display, PORT_CLK_SEL(port), hsw_pll_to_ddi_pll_sel(pll)); } void hsw_ddi_disable_clock(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; - intel_de_write(i915, PORT_CLK_SEL(port), PORT_CLK_SEL_NONE); + intel_de_write(display, PORT_CLK_SEL(port), PORT_CLK_SEL_NONE); } bool hsw_ddi_is_clock_enabled(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; - return intel_de_read(i915, PORT_CLK_SEL(port)) != PORT_CLK_SEL_NONE; + return intel_de_read(display, PORT_CLK_SEL(port)) != PORT_CLK_SEL_NONE; } static struct intel_shared_dpll *hsw_ddi_get_pll(struct intel_encoder *encoder) @@ -2081,7 +2071,7 @@ void intel_ddi_disable_clock(struct intel_encoder *encoder) void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); u32 port_mask; bool ddi_clk_needed; @@ -2101,7 +2091,7 @@ void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) * In the unlikely case that BIOS enables DP in MST mode, just * warn since our MST HW readout is incomplete. */ - if (drm_WARN_ON(&i915->drm, is_mst)) + if (drm_WARN_ON(display->drm, is_mst)) return; } @@ -2116,11 +2106,11 @@ void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) * Sanity check that we haven't incorrectly registered another * encoder using any of the ports of this DSI encoder. */ - for_each_intel_encoder(&i915->drm, other_encoder) { + for_each_intel_encoder(display->drm, other_encoder) { if (other_encoder == encoder) continue; - if (drm_WARN_ON(&i915->drm, + if (drm_WARN_ON(display->drm, port_mask & BIT(other_encoder->port))) return; } @@ -2135,7 +2125,7 @@ void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder) !encoder->is_clock_enabled(encoder)) return; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[ENCODER:%d:%s] is disabled/in DSI mode with an ungated DDI clock, gate it\n", encoder->base.base.id, encoder->base.name); @@ -2255,10 +2245,10 @@ tgl_dp_tp_transcoder(const struct intel_crtc_state *crtc_state) i915_reg_t dp_tp_ctl_reg(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - if (DISPLAY_VER(dev_priv) >= 12) - return TGL_DP_TP_CTL(dev_priv, + if (DISPLAY_VER(display) >= 12) + return TGL_DP_TP_CTL(display, tgl_dp_tp_transcoder(crtc_state)); else return DP_TP_CTL(encoder->port); @@ -2267,10 +2257,10 @@ i915_reg_t dp_tp_ctl_reg(struct intel_encoder *encoder, static i915_reg_t dp_tp_status_reg(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - if (DISPLAY_VER(dev_priv) >= 12) - return TGL_DP_TP_STATUS(dev_priv, + if (DISPLAY_VER(display) >= 12) + return TGL_DP_TP_STATUS(display, tgl_dp_tp_transcoder(crtc_state)); else return DP_TP_STATUS(encoder->port); @@ -2445,14 +2435,14 @@ static void intel_ddi_enable_fec(struct intel_encoder *encoder, static void intel_ddi_disable_fec(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); if (!crtc_state->fec_enable) return; - intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), + intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state), DP_TP_CTL_FEC_ENABLE, 0); - intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); + intel_de_posting_read(display, dp_tp_ctl_reg(encoder, crtc_state)); } static void intel_ddi_power_up_lanes(struct intel_encoder *encoder, @@ -2474,11 +2464,11 @@ static void intel_ddi_power_up_lanes(struct intel_encoder *encoder, * Splitter enable for eDP MSO is limited to certain pipes, on certain * platforms. */ -static u8 intel_ddi_splitter_pipe_mask(struct drm_i915_private *i915) +static u8 intel_ddi_splitter_pipe_mask(struct intel_display *display) { - if (DISPLAY_VER(i915) > 20) + if (DISPLAY_VER(display) > 20) return ~0; - else if (IS_ALDERLAKE_P(i915)) + else if (display->platform.alderlake_p) return BIT(PIPE_A) | BIT(PIPE_B); else return BIT(PIPE_A); @@ -2487,28 +2477,28 @@ static u8 intel_ddi_splitter_pipe_mask(struct drm_i915_private *i915) static void intel_ddi_mso_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { + struct intel_display *display = to_intel_display(pipe_config); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; u32 dss1; - if (!HAS_MSO(i915)) + if (!HAS_MSO(display)) return; - dss1 = intel_de_read(i915, ICL_PIPE_DSS_CTL1(pipe)); + dss1 = intel_de_read(display, ICL_PIPE_DSS_CTL1(pipe)); pipe_config->splitter.enable = dss1 & SPLITTER_ENABLE; if (!pipe_config->splitter.enable) return; - if (drm_WARN_ON(&i915->drm, !(intel_ddi_splitter_pipe_mask(i915) & BIT(pipe)))) { + if (drm_WARN_ON(display->drm, !(intel_ddi_splitter_pipe_mask(display) & BIT(pipe)))) { pipe_config->splitter.enable = false; return; } switch (dss1 & SPLITTER_CONFIGURATION_MASK) { default: - drm_WARN(&i915->drm, true, + drm_WARN(display->drm, true, "Invalid splitter configuration, dss1=0x%08x\n", dss1); fallthrough; case SPLITTER_CONFIGURATION_2_SEGMENT: @@ -2524,12 +2514,12 @@ static void intel_ddi_mso_get_config(struct intel_encoder *encoder, static void intel_ddi_mso_configure(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); enum pipe pipe = crtc->pipe; u32 dss1 = 0; - if (!HAS_MSO(i915)) + if (!HAS_MSO(display)) return; if (crtc_state->splitter.enable) { @@ -2541,7 +2531,7 @@ static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state) dss1 |= SPLITTER_CONFIGURATION_4_SEGMENT; } - intel_de_rmw(i915, ICL_PIPE_DSS_CTL1(pipe), + intel_de_rmw(display, ICL_PIPE_DSS_CTL1(pipe), SPLITTER_ENABLE | SPLITTER_CONFIGURATION_MASK | OVERLAP_PIXELS_MASK, dss1); } @@ -2549,27 +2539,27 @@ static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state) static void mtl_ddi_enable_d2d(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; i915_reg_t reg; u32 set_bits, wait_bits; - if (DISPLAY_VER(dev_priv) < 14) + if (DISPLAY_VER(display) < 14) return; - if (DISPLAY_VER(dev_priv) >= 20) { + if (DISPLAY_VER(display) >= 20) { reg = DDI_BUF_CTL(port); set_bits = XE2LPD_DDI_BUF_D2D_LINK_ENABLE; wait_bits = XE2LPD_DDI_BUF_D2D_LINK_STATE; } else { - reg = XELPDP_PORT_BUF_CTL1(dev_priv, port); + reg = XELPDP_PORT_BUF_CTL1(display, port); set_bits = XELPDP_PORT_BUF_D2D_LINK_ENABLE; wait_bits = XELPDP_PORT_BUF_D2D_LINK_STATE; } - intel_de_rmw(dev_priv, reg, 0, set_bits); - if (wait_for_us(intel_de_read(dev_priv, reg) & wait_bits, 100)) { - drm_err(&dev_priv->drm, "Timeout waiting for D2D Link enable for DDI/PORT_BUF_CTL %c\n", + intel_de_rmw(display, reg, 0, set_bits); + if (wait_for_us(intel_de_read(display, reg) & wait_bits, 100)) { + drm_err(display->drm, "Timeout waiting for D2D Link enable for DDI/PORT_BUF_CTL %c\n", port_name(port)); } } @@ -2599,13 +2589,13 @@ static void mtl_port_buf_ctl_program(struct intel_encoder *encoder, static void mtl_port_buf_ctl_io_selection(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); u32 val; val = intel_tc_port_in_tbt_alt_mode(dig_port) ? XELPDP_PORT_BUF_IO_SELECT_TBT : 0; - intel_de_rmw(i915, XELPDP_PORT_BUF_CTL1(i915, encoder->port), + intel_de_rmw(display, XELPDP_PORT_BUF_CTL1(display, encoder->port), XELPDP_PORT_BUF_IO_SELECT_TBT, val); } @@ -2734,7 +2724,6 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, { struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); int ret; @@ -2778,7 +2767,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, /* 5. If IO power is controlled through PWR_WELL_CTL, Enable IO Power */ if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { - drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); + drm_WARN_ON(display->drm, dig_port->ddi_io_wakeref); dig_port->ddi_io_wakeref = intel_display_power_get(display, dig_port->ddi_io_power_domain); } @@ -2882,16 +2871,15 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, { struct intel_display *display = to_intel_display(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); - if (DISPLAY_VER(dev_priv) < 11) - drm_WARN_ON(&dev_priv->drm, + if (DISPLAY_VER(display) < 11) + drm_WARN_ON(display->drm, is_mst && (port == PORT_A || port == PORT_E)); else - drm_WARN_ON(&dev_priv->drm, is_mst && port == PORT_A); + drm_WARN_ON(display->drm, is_mst && port == PORT_A); intel_dp_set_link_params(intel_dp, crtc_state->port_clock, @@ -2908,14 +2896,14 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, intel_ddi_enable_clock(encoder, crtc_state); if (!intel_tc_port_in_tbt_alt_mode(dig_port)) { - drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); + drm_WARN_ON(display->drm, dig_port->ddi_io_wakeref); dig_port->ddi_io_wakeref = intel_display_power_get(display, dig_port->ddi_io_power_domain); } icl_program_mg_dp_mode(dig_port, crtc_state); - if (has_buf_trans_select(dev_priv)) + if (has_buf_trans_select(display)) hsw_prepare_dp_ddi_buffers(encoder, crtc_state); encoder->set_signal_levels(encoder, crtc_state); @@ -2931,7 +2919,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, crtc_state); intel_dp_sink_set_fec_ready(intel_dp, crtc_state, true); intel_dp_start_link_train(state, intel_dp, crtc_state); - if ((port != PORT_A || DISPLAY_VER(dev_priv) >= 9) && + if ((port != PORT_A || DISPLAY_VER(display) >= 9) && !is_trans_port_sync_mode(crtc_state)) intel_dp_stop_link_train(intel_dp, crtc_state); @@ -2979,12 +2967,11 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state, struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_hdmi *intel_hdmi = &dig_port->hdmi; - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); intel_dp_dual_mode_set_tmds_output(intel_hdmi, true); intel_ddi_enable_clock(encoder, crtc_state); - drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref); + drm_WARN_ON(display->drm, dig_port->ddi_io_wakeref); dig_port->ddi_io_wakeref = intel_display_power_get(display, dig_port->ddi_io_power_domain); @@ -3022,10 +3009,9 @@ static void intel_ddi_pre_enable(struct intel_atomic_state *state, { struct intel_display *display = to_intel_display(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; - drm_WARN_ON(&dev_priv->drm, crtc_state->has_pch_encoder); + drm_WARN_ON(display->drm, crtc_state->has_pch_encoder); intel_set_cpu_fifo_underrun_reporting(display, pipe, true); @@ -3050,27 +3036,27 @@ static void intel_ddi_pre_enable(struct intel_atomic_state *state, static void mtl_ddi_disable_d2d(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; i915_reg_t reg; u32 clr_bits, wait_bits; - if (DISPLAY_VER(dev_priv) < 14) + if (DISPLAY_VER(display) < 14) return; - if (DISPLAY_VER(dev_priv) >= 20) { + if (DISPLAY_VER(display) >= 20) { reg = DDI_BUF_CTL(port); clr_bits = XE2LPD_DDI_BUF_D2D_LINK_ENABLE; wait_bits = XE2LPD_DDI_BUF_D2D_LINK_STATE; } else { - reg = XELPDP_PORT_BUF_CTL1(dev_priv, port); + reg = XELPDP_PORT_BUF_CTL1(display, port); clr_bits = XELPDP_PORT_BUF_D2D_LINK_ENABLE; wait_bits = XELPDP_PORT_BUF_D2D_LINK_STATE; } - intel_de_rmw(dev_priv, reg, clr_bits, 0); - if (wait_for_us(!(intel_de_read(dev_priv, reg) & wait_bits), 100)) - drm_err(&dev_priv->drm, "Timeout waiting for D2D Link disable for DDI/PORT_BUF_CTL %c\n", + intel_de_rmw(display, reg, clr_bits, 0); + if (wait_for_us(!(intel_de_read(display, reg) & wait_bits), 100)) + drm_err(display->drm, "Timeout waiting for D2D Link disable for DDI/PORT_BUF_CTL %c\n", port_name(port)); } @@ -3089,10 +3075,9 @@ static void intel_ddi_buf_disable(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(encoder->base.dev); enum port port = encoder->port; - intel_de_rmw(dev_priv, DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE, 0); + intel_de_rmw(display, DDI_BUF_CTL(port), DDI_BUF_CTL_ENABLE, 0); if (DISPLAY_VER(display) >= 14) intel_wait_ddi_buf_idle(display, port); @@ -3100,7 +3085,7 @@ static void intel_ddi_buf_disable(struct intel_encoder *encoder, mtl_ddi_disable_d2d(encoder); if (intel_crtc_has_dp_encoder(crtc_state)) { - intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), + intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state), DP_TP_CTL_ENABLE, 0); } @@ -3118,7 +3103,6 @@ static void intel_ddi_post_disable_dp(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(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_dp *intel_dp = &dig_port->dp; intel_wakeref_t wakeref; @@ -3135,12 +3119,12 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, */ intel_dp_set_power(intel_dp, DP_SET_POWER_D3); - if (DISPLAY_VER(dev_priv) >= 12) { + if (DISPLAY_VER(display) >= 12) { if (is_mst || intel_dp_is_uhbr(old_crtc_state)) { enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder; - intel_de_rmw(dev_priv, - TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder), + intel_de_rmw(display, + TRANS_DDI_FUNC_CTL(display, cpu_transcoder), TGL_TRANS_DDI_PORT_MASK | TRANS_DDI_MODE_SELECT_MASK, 0); } @@ -3160,7 +3144,7 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, * Configure Transcoder Clock select to direct no clock to the * transcoder" */ - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) intel_ddi_disable_transcoder_clock(old_crtc_state); intel_pps_vdd_on(intel_dp); @@ -3176,8 +3160,8 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state, intel_ddi_disable_clock(encoder); /* De-select Thunderbolt */ - if (DISPLAY_VER(dev_priv) >= 14) - intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(dev_priv, encoder->port), + if (DISPLAY_VER(display) >= 14) + intel_de_rmw(display, XELPDP_PORT_BUF_CTL1(display, encoder->port), XELPDP_PORT_BUF_IO_SELECT_TBT, 0); } @@ -3187,7 +3171,6 @@ static void intel_ddi_post_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(encoder->base.dev); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct intel_hdmi *intel_hdmi = &dig_port->hdmi; intel_wakeref_t wakeref; @@ -3195,12 +3178,12 @@ static void intel_ddi_post_disable_hdmi(struct intel_atomic_state *state, dig_port->set_infoframes(encoder, false, old_crtc_state, old_conn_state); - if (DISPLAY_VER(dev_priv) < 12) + if (DISPLAY_VER(display) < 12) intel_ddi_disable_transcoder_clock(old_crtc_state); intel_ddi_buf_disable(encoder, old_crtc_state); - if (DISPLAY_VER(dev_priv) >= 12) + if (DISPLAY_VER(display) >= 12) intel_ddi_disable_transcoder_clock(old_crtc_state); wakeref = fetch_and_zero(&dig_port->ddi_io_wakeref); @@ -3220,7 +3203,6 @@ static void intel_ddi_post_disable_hdmi_or_sst(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(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_crtc *pipe_crtc; bool is_hdmi = intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI); @@ -3249,6 +3231,8 @@ static void intel_ddi_post_disable_hdmi_or_sst(struct intel_atomic_state *state, drm_dp_dpcd_poll_act_handled(&intel_dp->aux, 0); } + intel_vrr_transcoder_disable(old_crtc_state); + intel_ddi_disable_transcoder_func(old_crtc_state); for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { @@ -3257,7 +3241,7 @@ static void intel_ddi_post_disable_hdmi_or_sst(struct intel_atomic_state *state, intel_dsc_disable(old_pipe_crtc_state); - if (DISPLAY_VER(dev_priv) >= 9) + if (DISPLAY_VER(display) >= 9) skl_scaler_disable(old_pipe_crtc_state); else ilk_pfit_disable(old_pipe_crtc_state); @@ -3359,12 +3343,12 @@ static void intel_ddi_enable_dp(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const 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); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); enum port port = encoder->port; - if (port == PORT_A && DISPLAY_VER(dev_priv) < 9) + if (port == PORT_A && DISPLAY_VER(display) < 9) intel_dp_stop_link_train(intel_dp, crtc_state); drm_connector_update_privacy_screen(conn_state); @@ -3401,7 +3385,6 @@ static void intel_ddi_enable_hdmi(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_digital_port *dig_port = enc_to_dig_port(encoder); struct drm_connector *connector = conn_state->connector; enum port port = encoder->port; @@ -3410,11 +3393,11 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, if (!intel_hdmi_handle_sink_scrambling(encoder, connector, crtc_state->hdmi_high_tmds_clock_ratio, crtc_state->hdmi_scrambling)) - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] Failed to configure sink scrambling/TMDS bit clock ratio\n", connector->base.id, connector->name); - if (has_buf_trans_select(dev_priv)) + if (has_buf_trans_select(display)) hsw_prepare_hdmi_ddi_buffers(encoder, crtc_state); /* e. Enable D2D Link for C10/C20 Phy */ @@ -3423,7 +3406,7 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, encoder->set_signal_levels(encoder, crtc_state); /* Display WA #1143: skl,kbl,cfl */ - if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) { + if (DISPLAY_VER(display) == 9 && !display->platform.broxton) { /* * For some reason these chicken bits have been * stuffed into a transcoder register, event though @@ -3433,7 +3416,7 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, i915_reg_t reg = gen9_chicken_trans_reg_by_port(display, port); u32 val; - val = intel_de_read(dev_priv, reg); + val = intel_de_read(display, reg); if (port == PORT_E) val |= DDIE_TRAINING_OVERRIDE_ENABLE | @@ -3442,8 +3425,8 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, val |= DDI_TRAINING_OVERRIDE_ENABLE | DDI_TRAINING_OVERRIDE_VALUE; - intel_de_write(dev_priv, reg, val); - intel_de_posting_read(dev_priv, reg); + intel_de_write(display, reg, val); + intel_de_posting_read(display, reg); udelay(1); @@ -3454,7 +3437,7 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, val &= ~(DDI_TRAINING_OVERRIDE_ENABLE | DDI_TRAINING_OVERRIDE_VALUE); - intel_de_write(dev_priv, reg, val); + intel_de_write(display, reg, val); } intel_ddi_power_up_lanes(encoder, crtc_state); @@ -3475,7 +3458,7 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, if (dig_port->ddi_a_4_lanes) buf_ctl |= DDI_A_4_LANES; - if (DISPLAY_VER(dev_priv) >= 14) { + if (DISPLAY_VER(display) >= 14) { u32 port_buf = 0; port_buf |= XELPDP_PORT_WIDTH(crtc_state->lane_count); @@ -3483,15 +3466,15 @@ static void intel_ddi_enable_hdmi(struct intel_atomic_state *state, if (dig_port->lane_reversal) port_buf |= XELPDP_PORT_REVERSAL; - intel_de_rmw(dev_priv, XELPDP_PORT_BUF_CTL1(dev_priv, port), + intel_de_rmw(display, XELPDP_PORT_BUF_CTL1(display, port), XELPDP_PORT_WIDTH_MASK | XELPDP_PORT_REVERSAL, port_buf); buf_ctl |= DDI_PORT_WIDTH(crtc_state->lane_count); - if (DISPLAY_VER(dev_priv) >= 20) + if (DISPLAY_VER(display) >= 20) buf_ctl |= XE2LPD_DDI_BUF_D2D_LINK_ENABLE; - } else if (IS_ALDERLAKE_P(dev_priv) && intel_encoder_is_tc(encoder)) { - drm_WARN_ON(&dev_priv->drm, !intel_tc_port_in_legacy_mode(dig_port)); + } else if (display->platform.alderlake_p && intel_encoder_is_tc(encoder)) { + drm_WARN_ON(display->drm, !intel_tc_port_in_legacy_mode(dig_port)); buf_ctl |= DDI_BUF_CTL_TC_PHY_OWNERSHIP; } @@ -3522,6 +3505,8 @@ static void intel_ddi_enable(struct intel_atomic_state *state, intel_ddi_enable_transcoder_func(encoder, crtc_state); + intel_vrr_transcoder_enable(crtc_state); + /* Enable/Disable DP2.0 SDP split config before transcoder */ intel_audio_sdp_split_update(crtc_state); @@ -3567,9 +3552,10 @@ static void intel_ddi_disable_dp(struct intel_atomic_state *state, struct intel_connector *connector = to_intel_connector(old_conn_state->connector); - intel_dp->link_trained = false; + 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, @@ -3584,12 +3570,12 @@ static void intel_ddi_disable_hdmi(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 *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct drm_connector *connector = old_conn_state->connector; if (!intel_hdmi_handle_sink_scrambling(encoder, connector, false, false)) - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] Failed to reset sink scrambling/TMDS bit clock ratio\n", connector->base.id, connector->name); } @@ -3653,16 +3639,16 @@ void intel_ddi_update_active_dpll(struct intel_atomic_state *state, struct intel_encoder *encoder, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_crtc *pipe_crtc; /* FIXME: Add MTL pll_mgr */ - if (DISPLAY_VER(i915) >= 14 || !intel_encoder_is_tc(encoder)) + if (DISPLAY_VER(display) >= 14 || !intel_encoder_is_tc(encoder)) return; - for_each_intel_crtc_in_pipe_mask(&i915->drm, pipe_crtc, + for_each_intel_crtc_in_pipe_mask(display->drm, pipe_crtc, intel_crtc_joined_pipe_mask(crtc_state)) intel_update_active_dpll(state, pipe_crtc, encoder); } @@ -3678,7 +3664,7 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const 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); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); bool is_tc_port = intel_encoder_is_tc(encoder); @@ -3697,7 +3683,7 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state, * Type-C ports. Skip this step for TBT. */ intel_tc_port_set_fia_lane_count(dig_port, crtc_state->lane_count); - else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + else if (display->platform.geminilake || display->platform.broxton) bxt_dpio_phy_set_lane_optim_mask(encoder, crtc_state->lane_lat_optim_mask); } @@ -3765,10 +3751,9 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, struct intel_display *display = to_intel_display(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_encoder *encoder = &dig_port->base; - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u32 dp_tp_ctl; - dp_tp_ctl = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); + dp_tp_ctl = intel_de_read(display, dp_tp_ctl_reg(encoder, crtc_state)); drm_WARN_ON(display->drm, dp_tp_ctl & DP_TP_CTL_ENABLE); @@ -3781,10 +3766,10 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, if (crtc_state->enhanced_framing) dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE; } - intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl); - intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); + intel_de_write(display, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl); + intel_de_posting_read(display, dp_tp_ctl_reg(encoder, crtc_state)); - if (IS_ALDERLAKE_P(dev_priv) && + if (display->platform.alderlake_p && (intel_tc_port_in_dp_alt_mode(dig_port) || intel_tc_port_in_legacy_mode(dig_port))) adlp_tbt_to_dp_alt_switch_wa(encoder); @@ -3796,11 +3781,11 @@ static void intel_ddi_set_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, u8 dp_train_pat) { + struct intel_display *display = to_intel_display(intel_dp); struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u32 temp; - temp = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state)); + temp = intel_de_read(display, dp_tp_ctl_reg(encoder, crtc_state)); temp &= ~DP_TP_CTL_LINK_TRAIN_MASK; switch (intel_dp_training_pattern_symbol(dp_train_pat)) { @@ -3821,17 +3806,17 @@ static void intel_ddi_set_link_train(struct intel_dp *intel_dp, break; } - intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), temp); + intel_de_write(display, dp_tp_ctl_reg(encoder, crtc_state), temp); } static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(intel_dp); struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; - intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), + intel_de_rmw(display, dp_tp_ctl_reg(encoder, crtc_state), DP_TP_CTL_LINK_TRAIN_MASK, DP_TP_CTL_LINK_TRAIN_IDLE); /* @@ -3841,28 +3826,26 @@ static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp, * In this case there is requirement to wait for a minimum number of * idle patterns to be sent. */ - if (port == PORT_A && DISPLAY_VER(dev_priv) < 12) + if (port == PORT_A && DISPLAY_VER(display) < 12) return; - if (intel_de_wait_for_set(dev_priv, + if (intel_de_wait_for_set(display, dp_tp_status_reg(encoder, crtc_state), DP_TP_STATUS_IDLE_DONE, 2)) - drm_err(&dev_priv->drm, + drm_err(display->drm, "Timed out waiting for DP idle patterns\n"); } -static bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv, +static bool intel_ddi_is_audio_enabled(struct intel_display *display, enum transcoder cpu_transcoder) { - struct intel_display *display = &dev_priv->display; - if (cpu_transcoder == TRANSCODER_EDP) return false; if (!intel_display_power_is_enabled(display, POWER_DOMAIN_AUDIO_MMIO)) return false; - return intel_de_read(dev_priv, HSW_AUD_PIN_ELD_CP_VLD) & + return intel_de_read(display, HSW_AUD_PIN_ELD_CP_VLD) & AUDIO_OUTPUT_ENABLE(cpu_transcoder); } @@ -3892,34 +3875,34 @@ static int icl_ddi_min_voltage_level(const struct intel_crtc_state *crtc_state) void intel_ddi_compute_min_voltage_level(struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); - if (DISPLAY_VER(dev_priv) >= 14) + if (DISPLAY_VER(display) >= 14) crtc_state->min_voltage_level = icl_ddi_min_voltage_level(crtc_state); - else if (DISPLAY_VER(dev_priv) >= 12) + else if (DISPLAY_VER(display) >= 12) crtc_state->min_voltage_level = tgl_ddi_min_voltage_level(crtc_state); - else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) + else if (display->platform.jasperlake || display->platform.elkhartlake) crtc_state->min_voltage_level = jsl_ddi_min_voltage_level(crtc_state); - else if (DISPLAY_VER(dev_priv) >= 11) + else if (DISPLAY_VER(display) >= 11) crtc_state->min_voltage_level = icl_ddi_min_voltage_level(crtc_state); } -static enum transcoder bdw_transcoder_master_readout(struct drm_i915_private *dev_priv, +static enum transcoder bdw_transcoder_master_readout(struct intel_display *display, enum transcoder cpu_transcoder) { u32 master_select; - if (DISPLAY_VER(dev_priv) >= 11) { - u32 ctl2 = intel_de_read(dev_priv, - TRANS_DDI_FUNC_CTL2(dev_priv, cpu_transcoder)); + if (DISPLAY_VER(display) >= 11) { + u32 ctl2 = intel_de_read(display, + TRANS_DDI_FUNC_CTL2(display, cpu_transcoder)); if ((ctl2 & PORT_SYNC_MODE_ENABLE) == 0) return INVALID_TRANSCODER; master_select = REG_FIELD_GET(PORT_SYNC_MODE_MASTER_SELECT_MASK, ctl2); } else { - u32 ctl = intel_de_read(dev_priv, - TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)); + u32 ctl = intel_de_read(display, + TRANS_DDI_FUNC_CTL(display, cpu_transcoder)); if ((ctl & TRANS_DDI_PORT_SYNC_ENABLE) == 0) return INVALID_TRANSCODER; @@ -3936,15 +3919,14 @@ static enum transcoder bdw_transcoder_master_readout(struct drm_i915_private *de static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); u32 transcoders = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C) | BIT(TRANSCODER_D); enum transcoder cpu_transcoder; crtc_state->master_transcoder = - bdw_transcoder_master_readout(dev_priv, crtc_state->cpu_transcoder); + bdw_transcoder_master_readout(display, crtc_state->cpu_transcoder); - for_each_cpu_transcoder_masked(dev_priv, cpu_transcoder, transcoders) { + for_each_cpu_transcoder_masked(display, cpu_transcoder, transcoders) { enum intel_display_power_domain power_domain; intel_wakeref_t trans_wakeref; @@ -3955,14 +3937,14 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state) if (!trans_wakeref) continue; - if (bdw_transcoder_master_readout(dev_priv, cpu_transcoder) == + if (bdw_transcoder_master_readout(display, cpu_transcoder) == crtc_state->cpu_transcoder) crtc_state->sync_mode_slaves_mask |= BIT(cpu_transcoder); intel_display_power_put(display, power_domain, trans_wakeref); } - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, crtc_state->master_transcoder != INVALID_TRANSCODER && crtc_state->sync_mode_slaves_mask); } @@ -4085,11 +4067,10 @@ static void intel_ddi_read_func_ctl(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); enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; u32 ddi_func_ctl, ddi_mode, flags = 0; - ddi_func_ctl = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(dev_priv, cpu_transcoder)); + ddi_func_ctl = intel_de_read(display, TRANS_DDI_FUNC_CTL(display, cpu_transcoder)); if (ddi_func_ctl & TRANS_DDI_PHSYNC) flags |= DRM_MODE_FLAG_PHSYNC; else @@ -4131,13 +4112,13 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, } else if (ddi_mode == TRANS_DDI_MODE_SELECT_DP_MST) { intel_ddi_read_func_ctl_dp_mst(encoder, pipe_config, ddi_func_ctl); } else if (ddi_mode == TRANS_DDI_MODE_SELECT_FDI_OR_128B132B && HAS_DP20(display)) { - struct intel_digital_port *dig_port = enc_to_dig_port(encoder); + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); /* * If this is true, we know we're being called from mst stream * encoder's ->get_config(). */ - if (intel_dp_mst_encoder_active_links(dig_port)) + if (intel_dp_mst_active_streams(intel_dp)) intel_ddi_read_func_ctl_dp_mst(encoder, pipe_config, ddi_func_ctl); else intel_ddi_read_func_ctl_dp_sst(encoder, pipe_config, ddi_func_ctl); @@ -4152,11 +4133,11 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder, static void intel_ddi_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; /* XXX: DSI transcoder paranoia */ - if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder))) + if (drm_WARN_ON(display->drm, transcoder_is_dsi(cpu_transcoder))) return; intel_ddi_read_func_ctl(encoder, pipe_config); @@ -4164,14 +4145,14 @@ static void intel_ddi_get_config(struct intel_encoder *encoder, intel_ddi_mso_get_config(encoder, pipe_config); pipe_config->has_audio = - intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder); + intel_ddi_is_audio_enabled(display, cpu_transcoder); if (encoder->type == INTEL_OUTPUT_EDP) intel_edp_fixup_vbt_bpp(encoder, pipe_config->pipe_bpp); ddi_dotclock_get(pipe_config); - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) pipe_config->lane_lat_optim_mask = bxt_dpio_phy_get_lane_lat_optim_mask(encoder); @@ -4192,7 +4173,7 @@ static void intel_ddi_get_config(struct intel_encoder *encoder, HDMI_INFOFRAME_TYPE_DRM, &pipe_config->infoframes.drm); - if (DISPLAY_VER(dev_priv) >= 8) + if (DISPLAY_VER(display) >= 8) bdw_get_trans_port_sync_config(pipe_config); intel_psr_get_config(encoder, pipe_config); @@ -4285,10 +4266,10 @@ static enum icl_port_dpll_id icl_ddi_tc_port_pll_type(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); const struct intel_shared_dpll *pll = crtc_state->shared_dpll; - if (drm_WARN_ON(&i915->drm, !pll)) + if (drm_WARN_ON(display->drm, !pll)) return ICL_PORT_DPLL_DEFAULT; if (icl_ddi_tc_pll_is_tbt(pll)) @@ -4382,11 +4363,11 @@ static void intel_ddi_sync_state(struct intel_encoder *encoder, static bool intel_ddi_initial_fastset_check(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); bool fastset = true; if (intel_encoder_is_tc(encoder)) { - drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] Forcing full modeset to compute TC port DPLLs\n", + drm_dbg_kms(display->drm, "[ENCODER:%d:%s] Forcing full modeset to compute TC port DPLLs\n", encoder->base.base.id, encoder->base.name); crtc_state->uapi.mode_changed = true; fastset = false; @@ -4421,12 +4402,12 @@ static int intel_ddi_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(encoder); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = encoder->port; int ret; - if (HAS_TRANSCODER(dev_priv, TRANSCODER_EDP) && port == PORT_A) + if (HAS_TRANSCODER(display, TRANSCODER_EDP) && port == PORT_A) pipe_config->cpu_transcoder = TRANSCODER_EDP; if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI)) { @@ -4441,13 +4422,13 @@ static int intel_ddi_compute_config(struct intel_encoder *encoder, if (ret) return ret; - if (IS_HASWELL(dev_priv) && crtc->pipe == PIPE_A && + if (display->platform.haswell && crtc->pipe == PIPE_A && pipe_config->cpu_transcoder == TRANSCODER_EDP) pipe_config->pch_pfit.force_thru = pipe_config->pch_pfit.enabled || pipe_config->crc_enabled; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) pipe_config->lane_lat_optim_mask = bxt_dpio_phy_calc_lane_lat_optim_mask(pipe_config->lane_count); @@ -4498,9 +4479,9 @@ static u8 intel_ddi_port_sync_transcoders(const struct intel_crtc_state *ref_crtc_state, int tile_group_id) { + struct intel_display *display = to_intel_display(ref_crtc_state); struct drm_connector *connector; const struct drm_connector_state *conn_state; - struct drm_i915_private *dev_priv = to_i915(ref_crtc_state->uapi.crtc->dev); struct intel_atomic_state *state = to_intel_atomic_state(ref_crtc_state->uapi.state); u8 transcoders = 0; @@ -4510,7 +4491,7 @@ intel_ddi_port_sync_transcoders(const struct intel_crtc_state *ref_crtc_state, * We don't enable port sync on BDW due to missing w/as and * due to not having adjusted the modeset sequence appropriately. */ - if (DISPLAY_VER(dev_priv) < 9) + if (DISPLAY_VER(display) < 9) return 0; if (!intel_crtc_has_type(ref_crtc_state, INTEL_OUTPUT_DP)) @@ -4542,11 +4523,11 @@ static int intel_ddi_compute_config_late(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); struct drm_connector *connector = conn_state->connector; u8 port_sync_transcoders = 0; - drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] [CRTC:%d:%s]\n", + drm_dbg_kms(display->drm, "[ENCODER:%d:%s] [CRTC:%d:%s]\n", encoder->base.base.id, encoder->base.name, crtc_state->uapi.crtc->base.id, crtc_state->uapi.crtc->name); @@ -4618,7 +4599,7 @@ static const struct drm_encoder_funcs intel_ddi_funcs = { static int intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); struct intel_connector *connector; enum port port = dig_port->base.port; @@ -4627,7 +4608,7 @@ static int intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) return -ENOMEM; dig_port->dp.output_reg = DDI_BUF_CTL(port); - if (DISPLAY_VER(i915) >= 14) + if (DISPLAY_VER(display) >= 14) dig_port->dp.prepare_link_retrain = mtl_ddi_prepare_link_retrain; else dig_port->dp.prepare_link_retrain = intel_ddi_prepare_link_retrain; @@ -4643,15 +4624,14 @@ static int intel_ddi_init_dp_connector(struct intel_digital_port *dig_port) } if (dig_port->base.type == INTEL_OUTPUT_EDP) { - struct drm_device *dev = dig_port->base.base.dev; struct drm_privacy_screen *privacy_screen; - privacy_screen = drm_privacy_screen_get(dev->dev, NULL); + privacy_screen = drm_privacy_screen_get(display->drm->dev, NULL); if (!IS_ERR(privacy_screen)) { drm_connector_attach_privacy_screen_provider(&connector->base, privacy_screen); } else if (PTR_ERR(privacy_screen) != -ENODEV) { - drm_warn(dev, "Error getting privacy-screen\n"); + drm_warn(display->drm, "Error getting privacy-screen\n"); } } @@ -4662,7 +4642,6 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder, struct drm_modeset_acquire_ctx *ctx) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_hdmi *hdmi = enc_to_intel_hdmi(encoder); struct intel_connector *connector = hdmi->attached_connector; struct i2c_adapter *ddc = connector->base.ddc; @@ -4675,7 +4654,7 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder, if (connector->base.status != connector_status_connected) return 0; - ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, + ret = drm_modeset_lock(&display->drm->mode_config.connection_mutex, ctx); if (ret) return ret; @@ -4692,7 +4671,7 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder, crtc_state = to_intel_crtc_state(crtc->base.state); - drm_WARN_ON(&dev_priv->drm, + drm_WARN_ON(display->drm, !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)); if (!crtc_state->hw.active) @@ -4708,7 +4687,7 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder, ret = drm_scdc_readb(ddc, SCDC_TMDS_CONFIG, &config); if (ret < 0) { - drm_err(&dev_priv->drm, "[CONNECTOR:%d:%s] Failed to read TMDS config: %d\n", + drm_err(display->drm, "[CONNECTOR:%d:%s] Failed to read TMDS config: %d\n", connector->base.base.id, connector->base.name, ret); return 0; } @@ -4733,11 +4712,11 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder, static void intel_ddi_link_check(struct intel_encoder *encoder) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); /* TODO: Move checking the HDMI link state here as well. */ - drm_WARN_ON(&i915->drm, !dig_port->dp.attached_connector); + drm_WARN_ON(display->drm, !dig_port->dp.attached_connector); intel_dp_link_check(encoder); } @@ -4800,26 +4779,26 @@ intel_ddi_hotplug(struct intel_encoder *encoder, static bool lpt_digital_port_connected(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - u32 bit = dev_priv->display.hotplug.pch_hpd[encoder->hpd_pin]; + struct intel_display *display = to_intel_display(encoder); + u32 bit = display->hotplug.pch_hpd[encoder->hpd_pin]; - return intel_de_read(dev_priv, SDEISR) & bit; + return intel_de_read(display, SDEISR) & bit; } static bool hsw_digital_port_connected(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - u32 bit = dev_priv->display.hotplug.hpd[encoder->hpd_pin]; + struct intel_display *display = to_intel_display(encoder); + u32 bit = display->hotplug.hpd[encoder->hpd_pin]; - return intel_de_read(dev_priv, DEISR) & bit; + return intel_de_read(display, DEISR) & bit; } static bool bdw_digital_port_connected(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - u32 bit = dev_priv->display.hotplug.hpd[encoder->hpd_pin]; + struct intel_display *display = to_intel_display(encoder); + u32 bit = display->hotplug.hpd[encoder->hpd_pin]; - return intel_de_read(dev_priv, GEN8_DE_PORT_ISR) & bit; + return intel_de_read(display, GEN8_DE_PORT_ISR) & bit; } static int intel_ddi_init_hdmi_connector(struct intel_digital_port *dig_port) @@ -4848,7 +4827,7 @@ static int intel_ddi_init_hdmi_connector(struct intel_digital_port *dig_port) static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port) { - struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); if (dig_port->base.port != PORT_A) return false; @@ -4859,7 +4838,7 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port) /* Broxton/Geminilake: Bspec says that DDI_A_4_LANES is the only * supported configuration */ - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) return true; return false; @@ -4868,15 +4847,15 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port) static int intel_ddi_max_lanes(struct intel_digital_port *dig_port) { - struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); enum port port = dig_port->base.port; int max_lanes = 4; - if (DISPLAY_VER(dev_priv) >= 11) + if (DISPLAY_VER(display) >= 11) return max_lanes; if (port == PORT_A || port == PORT_E) { - if (intel_de_read(dev_priv, DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) + if (intel_de_read(display, DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES) max_lanes = port == PORT_A ? 4 : 0; else /* Both A and E share 2 lanes */ @@ -4889,7 +4868,7 @@ intel_ddi_max_lanes(struct intel_digital_port *dig_port) * so we use the proper lane count for our calculations. */ if (intel_ddi_a_force_4_lanes(dig_port)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Forcing DDI_A_4_LANES for port A\n"); dig_port->ddi_a_4_lanes = true; max_lanes = 4; @@ -4898,8 +4877,7 @@ intel_ddi_max_lanes(struct intel_digital_port *dig_port) return max_lanes; } -static enum hpd_pin xelpd_hpd_pin(struct drm_i915_private *dev_priv, - enum port port) +static enum hpd_pin xelpd_hpd_pin(struct intel_display *display, enum port port) { if (port >= PORT_D_XELPD) return HPD_PORT_D + port - PORT_D_XELPD; @@ -4909,8 +4887,7 @@ static enum hpd_pin xelpd_hpd_pin(struct drm_i915_private *dev_priv, return HPD_PORT_A + port - PORT_A; } -static enum hpd_pin dg1_hpd_pin(struct drm_i915_private *dev_priv, - enum port port) +static enum hpd_pin dg1_hpd_pin(struct intel_display *display, enum port port) { if (port >= PORT_TC1) return HPD_PORT_C + port - PORT_TC1; @@ -4918,8 +4895,7 @@ static enum hpd_pin dg1_hpd_pin(struct drm_i915_private *dev_priv, return HPD_PORT_A + port - PORT_A; } -static enum hpd_pin tgl_hpd_pin(struct drm_i915_private *dev_priv, - enum port port) +static enum hpd_pin tgl_hpd_pin(struct intel_display *display, enum port port) { if (port >= PORT_TC1) return HPD_PORT_TC1 + port - PORT_TC1; @@ -4927,11 +4903,10 @@ static enum hpd_pin tgl_hpd_pin(struct drm_i915_private *dev_priv, return HPD_PORT_A + port - PORT_A; } -static enum hpd_pin rkl_hpd_pin(struct drm_i915_private *dev_priv, - enum port port) +static enum hpd_pin rkl_hpd_pin(struct intel_display *display, enum port port) { - if (HAS_PCH_TGP(dev_priv)) - return tgl_hpd_pin(dev_priv, port); + if (HAS_PCH_TGP(display)) + return tgl_hpd_pin(display, port); if (port >= PORT_TC1) return HPD_PORT_C + port - PORT_TC1; @@ -4939,8 +4914,7 @@ static enum hpd_pin rkl_hpd_pin(struct drm_i915_private *dev_priv, return HPD_PORT_A + port - PORT_A; } -static enum hpd_pin icl_hpd_pin(struct drm_i915_private *dev_priv, - enum port port) +static enum hpd_pin icl_hpd_pin(struct intel_display *display, enum port port) { if (port >= PORT_C) return HPD_PORT_TC1 + port - PORT_C; @@ -4948,31 +4922,30 @@ static enum hpd_pin icl_hpd_pin(struct drm_i915_private *dev_priv, return HPD_PORT_A + port - PORT_A; } -static enum hpd_pin ehl_hpd_pin(struct drm_i915_private *dev_priv, - enum port port) +static enum hpd_pin ehl_hpd_pin(struct intel_display *display, enum port port) { if (port == PORT_D) return HPD_PORT_A; - if (HAS_PCH_TGP(dev_priv)) - return icl_hpd_pin(dev_priv, port); + if (HAS_PCH_TGP(display)) + return icl_hpd_pin(display, port); return HPD_PORT_A + port - PORT_A; } -static enum hpd_pin skl_hpd_pin(struct drm_i915_private *dev_priv, enum port port) +static enum hpd_pin skl_hpd_pin(struct intel_display *display, enum port port) { - if (HAS_PCH_TGP(dev_priv)) - return icl_hpd_pin(dev_priv, port); + if (HAS_PCH_TGP(display)) + return icl_hpd_pin(display, port); return HPD_PORT_A + port - PORT_A; } -static bool intel_ddi_is_tc(struct drm_i915_private *i915, enum port port) +static bool intel_ddi_is_tc(struct intel_display *display, enum port port) { - if (DISPLAY_VER(i915) >= 12) + if (DISPLAY_VER(display) >= 12) return port >= PORT_TC1; - else if (DISPLAY_VER(i915) >= 11) + else if (DISPLAY_VER(display) >= 11) return port >= PORT_C; else return false; @@ -5015,21 +4988,21 @@ static void intel_ddi_tc_encoder_shutdown_complete(struct intel_encoder *encoder #define port_tc_name(port) ((port) - PORT_TC1 + '1') #define tc_port_name(tc_port) ((tc_port) - TC_PORT_1 + '1') -static bool port_strap_detected(struct drm_i915_private *i915, enum port port) +static bool port_strap_detected(struct intel_display *display, enum port port) { /* straps not used on skl+ */ - if (DISPLAY_VER(i915) >= 9) + if (DISPLAY_VER(display) >= 9) return true; switch (port) { case PORT_A: - return intel_de_read(i915, DDI_BUF_CTL(PORT_A)) & DDI_INIT_DISPLAY_DETECTED; + return intel_de_read(display, DDI_BUF_CTL(PORT_A)) & DDI_INIT_DISPLAY_DETECTED; case PORT_B: - return intel_de_read(i915, SFUSE_STRAP) & SFUSE_STRAP_DDIB_DETECTED; + return intel_de_read(display, SFUSE_STRAP) & SFUSE_STRAP_DDIB_DETECTED; case PORT_C: - return intel_de_read(i915, SFUSE_STRAP) & SFUSE_STRAP_DDIC_DETECTED; + return intel_de_read(display, SFUSE_STRAP) & SFUSE_STRAP_DDIC_DETECTED; case PORT_D: - return intel_de_read(i915, SFUSE_STRAP) & SFUSE_STRAP_DDID_DETECTED; + return intel_de_read(display, SFUSE_STRAP) & SFUSE_STRAP_DDID_DETECTED; case PORT_E: return true; /* no strap for DDI-E */ default: @@ -5043,18 +5016,18 @@ static bool need_aux_ch(struct intel_encoder *encoder, bool init_dp) return init_dp || intel_encoder_is_tc(encoder); } -static bool assert_has_icl_dsi(struct drm_i915_private *i915) +static bool assert_has_icl_dsi(struct intel_display *display) { - return !drm_WARN(&i915->drm, !IS_ALDERLAKE_P(i915) && - !IS_TIGERLAKE(i915) && DISPLAY_VER(i915) != 11, + return !drm_WARN(display->drm, !display->platform.alderlake_p && + !display->platform.tigerlake && DISPLAY_VER(display) != 11, "Platform does not support DSI\n"); } -static bool port_in_use(struct drm_i915_private *i915, enum port port) +static bool port_in_use(struct intel_display *display, enum port port) { struct intel_encoder *encoder; - for_each_intel_encoder(&i915->drm, encoder) { + for_each_intel_encoder(display->drm, encoder) { /* FIXME what about second port for dual link DSI? */ if (encoder->port == port) return true; @@ -5066,7 +5039,6 @@ static bool port_in_use(struct drm_i915_private *i915, enum port port) void intel_ddi_init(struct intel_display *display, const struct intel_bios_encoder_data *devdata) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_digital_port *dig_port; struct intel_encoder *encoder; bool init_hdmi, init_dp; @@ -5078,8 +5050,8 @@ void intel_ddi_init(struct intel_display *display, if (port == PORT_NONE) return; - if (!port_strap_detected(dev_priv, port)) { - drm_dbg_kms(&dev_priv->drm, + if (!port_strap_detected(display, port)) { + drm_dbg_kms(display->drm, "Port %c strap not detected\n", port_name(port)); return; } @@ -5087,15 +5059,15 @@ void intel_ddi_init(struct intel_display *display, if (!assert_port_valid(display, port)) return; - if (port_in_use(dev_priv, port)) { - drm_dbg_kms(&dev_priv->drm, + if (port_in_use(display, port)) { + drm_dbg_kms(display->drm, "Port %c already claimed\n", port_name(port)); return; } if (intel_bios_encoder_supports_dsi(devdata)) { /* BXT/GLK handled elsewhere, for now at least */ - if (!assert_has_icl_dsi(dev_priv)) + if (!assert_has_icl_dsi(display)) return; icl_dsi_init(display, devdata); @@ -5111,7 +5083,7 @@ void intel_ddi_init(struct intel_display *display, * outputs. */ if (intel_hti_uses_phy(display, phy)) { - drm_dbg_kms(&dev_priv->drm, "PORT %c / PHY %c reserved by HTI\n", + drm_dbg_kms(display->drm, "PORT %c / PHY %c reserved by HTI\n", port_name(port), phy_name(phy)); return; } @@ -5128,20 +5100,20 @@ void intel_ddi_init(struct intel_display *display, */ init_dp = true; init_hdmi = false; - drm_dbg_kms(&dev_priv->drm, "VBT says port %c has lspcon\n", + drm_dbg_kms(display->drm, "VBT says port %c has lspcon\n", port_name(port)); } if (!init_dp && !init_hdmi) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "VBT says port %c is not DVI/HDMI/DP compatible, respect it\n", port_name(port)); return; } if (intel_phy_is_snps(display, phy) && - dev_priv->display.snps.phy_failed_calibration & BIT(phy)) { - drm_dbg_kms(&dev_priv->drm, + display->snps.phy_failed_calibration & BIT(phy)) { + drm_dbg_kms(display->drm, "SNPS PHY %c failed to calibrate, proceeding anyway\n", phy_name(phy)); } @@ -5155,26 +5127,26 @@ void intel_ddi_init(struct intel_display *display, encoder = &dig_port->base; encoder->devdata = devdata; - if (DISPLAY_VER(dev_priv) >= 13 && port >= PORT_D_XELPD) { - drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, + if (DISPLAY_VER(display) >= 13 && port >= PORT_D_XELPD) { + drm_encoder_init(display->drm, &encoder->base, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, "DDI %c/PHY %c", port_name(port - PORT_D_XELPD + PORT_D), phy_name(phy)); - } else if (DISPLAY_VER(dev_priv) >= 12) { + } else if (DISPLAY_VER(display) >= 12) { enum tc_port tc_port = intel_port_to_tc(display, port); - drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, + drm_encoder_init(display->drm, &encoder->base, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, "DDI %s%c/PHY %s%c", port >= PORT_TC1 ? "TC" : "", port >= PORT_TC1 ? port_tc_name(port) : port_name(port), tc_port != TC_PORT_NONE ? "TC" : "", tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy)); - } else if (DISPLAY_VER(dev_priv) >= 11) { + } else if (DISPLAY_VER(display) >= 11) { enum tc_port tc_port = intel_port_to_tc(display, port); - drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, + drm_encoder_init(display->drm, &encoder->base, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, "DDI %c%s/PHY %s%c", port_name(port), @@ -5182,7 +5154,7 @@ void intel_ddi_init(struct intel_display *display, tc_port != TC_PORT_NONE ? "TC" : "", tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy)); } else { - drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, + drm_encoder_init(display->drm, &encoder->base, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, "DDI %c/PHY %c", port_name(port), phy_name(phy)); } @@ -5218,32 +5190,32 @@ void intel_ddi_init(struct intel_display *display, encoder->cloneable = 0; encoder->pipe_mask = ~0; - if (DISPLAY_VER(dev_priv) >= 14) { + if (DISPLAY_VER(display) >= 14) { encoder->enable_clock = intel_mtl_pll_enable; encoder->disable_clock = intel_mtl_pll_disable; encoder->port_pll_type = intel_mtl_port_pll_type; encoder->get_config = mtl_ddi_get_config; - } else if (IS_DG2(dev_priv)) { + } else if (display->platform.dg2) { encoder->enable_clock = intel_mpllb_enable; encoder->disable_clock = intel_mpllb_disable; encoder->get_config = dg2_ddi_get_config; - } else if (IS_ALDERLAKE_S(dev_priv)) { + } else if (display->platform.alderlake_s) { encoder->enable_clock = adls_ddi_enable_clock; encoder->disable_clock = adls_ddi_disable_clock; encoder->is_clock_enabled = adls_ddi_is_clock_enabled; encoder->get_config = adls_ddi_get_config; - } else if (IS_ROCKETLAKE(dev_priv)) { + } else if (display->platform.rocketlake) { encoder->enable_clock = rkl_ddi_enable_clock; encoder->disable_clock = rkl_ddi_disable_clock; encoder->is_clock_enabled = rkl_ddi_is_clock_enabled; encoder->get_config = rkl_ddi_get_config; - } else if (IS_DG1(dev_priv)) { + } else if (display->platform.dg1) { encoder->enable_clock = dg1_ddi_enable_clock; encoder->disable_clock = dg1_ddi_disable_clock; encoder->is_clock_enabled = dg1_ddi_is_clock_enabled; encoder->get_config = dg1_ddi_get_config; - } else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) { - if (intel_ddi_is_tc(dev_priv, port)) { + } else if (display->platform.jasperlake || display->platform.elkhartlake) { + if (intel_ddi_is_tc(display, port)) { encoder->enable_clock = jsl_ddi_tc_enable_clock; encoder->disable_clock = jsl_ddi_tc_disable_clock; encoder->is_clock_enabled = jsl_ddi_tc_is_clock_enabled; @@ -5255,8 +5227,8 @@ void intel_ddi_init(struct intel_display *display, encoder->is_clock_enabled = icl_ddi_combo_is_clock_enabled; encoder->get_config = icl_ddi_combo_get_config; } - } else if (DISPLAY_VER(dev_priv) >= 11) { - if (intel_ddi_is_tc(dev_priv, port)) { + } else if (DISPLAY_VER(display) >= 11) { + if (intel_ddi_is_tc(display, port)) { encoder->enable_clock = icl_ddi_tc_enable_clock; encoder->disable_clock = icl_ddi_tc_disable_clock; encoder->is_clock_enabled = icl_ddi_tc_is_clock_enabled; @@ -5268,36 +5240,36 @@ void intel_ddi_init(struct intel_display *display, encoder->is_clock_enabled = icl_ddi_combo_is_clock_enabled; encoder->get_config = icl_ddi_combo_get_config; } - } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + } else if (display->platform.geminilake || display->platform.broxton) { /* BXT/GLK have fixed PLL->port mapping */ encoder->get_config = bxt_ddi_get_config; - } else if (DISPLAY_VER(dev_priv) == 9) { + } else if (DISPLAY_VER(display) == 9) { encoder->enable_clock = skl_ddi_enable_clock; encoder->disable_clock = skl_ddi_disable_clock; encoder->is_clock_enabled = skl_ddi_is_clock_enabled; encoder->get_config = skl_ddi_get_config; - } else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) { + } else if (display->platform.broadwell || display->platform.haswell) { encoder->enable_clock = hsw_ddi_enable_clock; encoder->disable_clock = hsw_ddi_disable_clock; encoder->is_clock_enabled = hsw_ddi_is_clock_enabled; encoder->get_config = hsw_ddi_get_config; } - if (DISPLAY_VER(dev_priv) >= 14) { + if (DISPLAY_VER(display) >= 14) { encoder->set_signal_levels = intel_cx0_phy_set_signal_levels; - } else if (IS_DG2(dev_priv)) { + } else if (display->platform.dg2) { encoder->set_signal_levels = intel_snps_phy_set_signal_levels; - } else if (DISPLAY_VER(dev_priv) >= 12) { + } else if (DISPLAY_VER(display) >= 12) { if (intel_encoder_is_combo(encoder)) encoder->set_signal_levels = icl_combo_phy_set_signal_levels; else encoder->set_signal_levels = tgl_dkl_phy_set_signal_levels; - } else if (DISPLAY_VER(dev_priv) >= 11) { + } else if (DISPLAY_VER(display) >= 11) { if (intel_encoder_is_combo(encoder)) encoder->set_signal_levels = icl_combo_phy_set_signal_levels; else encoder->set_signal_levels = icl_mg_phy_set_signal_levels; - } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + } else if (display->platform.geminilake || display->platform.broxton) { encoder->set_signal_levels = bxt_dpio_phy_set_signal_levels; } else { encoder->set_signal_levels = hsw_set_signal_levels; @@ -5305,29 +5277,29 @@ void intel_ddi_init(struct intel_display *display, intel_ddi_buf_trans_init(encoder); - if (DISPLAY_VER(dev_priv) >= 13) - encoder->hpd_pin = xelpd_hpd_pin(dev_priv, port); - else if (IS_DG1(dev_priv)) - encoder->hpd_pin = dg1_hpd_pin(dev_priv, port); - else if (IS_ROCKETLAKE(dev_priv)) - encoder->hpd_pin = rkl_hpd_pin(dev_priv, port); - else if (DISPLAY_VER(dev_priv) >= 12) - encoder->hpd_pin = tgl_hpd_pin(dev_priv, port); - else if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) - encoder->hpd_pin = ehl_hpd_pin(dev_priv, port); - else if (DISPLAY_VER(dev_priv) == 11) - encoder->hpd_pin = icl_hpd_pin(dev_priv, port); - else if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) - encoder->hpd_pin = skl_hpd_pin(dev_priv, port); + if (DISPLAY_VER(display) >= 13) + encoder->hpd_pin = xelpd_hpd_pin(display, port); + else if (display->platform.dg1) + encoder->hpd_pin = dg1_hpd_pin(display, port); + else if (display->platform.rocketlake) + encoder->hpd_pin = rkl_hpd_pin(display, port); + else if (DISPLAY_VER(display) >= 12) + encoder->hpd_pin = tgl_hpd_pin(display, port); + else if (display->platform.jasperlake || display->platform.elkhartlake) + encoder->hpd_pin = ehl_hpd_pin(display, port); + else if (DISPLAY_VER(display) == 11) + encoder->hpd_pin = icl_hpd_pin(display, port); + else if (DISPLAY_VER(display) == 9 && !display->platform.broxton) + encoder->hpd_pin = skl_hpd_pin(display, port); else encoder->hpd_pin = intel_hpd_pin_default(port); - ddi_buf_ctl = intel_de_read(dev_priv, DDI_BUF_CTL(port)); + ddi_buf_ctl = intel_de_read(display, DDI_BUF_CTL(port)); dig_port->lane_reversal = intel_bios_encoder_lane_reversal(devdata) || ddi_buf_ctl & DDI_BUF_PORT_REVERSAL; - dig_port->ddi_a_4_lanes = DISPLAY_VER(dev_priv) < 11 && ddi_buf_ctl & DDI_A_4_LANES; + dig_port->ddi_a_4_lanes = DISPLAY_VER(display) < 11 && ddi_buf_ctl & DDI_A_4_LANES; dig_port->dp.output_reg = INVALID_MMIO_REG; dig_port->max_lanes = intel_ddi_max_lanes(dig_port); @@ -5346,7 +5318,7 @@ void intel_ddi_init(struct intel_display *display, if (!is_legacy && init_hdmi) { is_legacy = !init_dp; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "VBT says port %c is non-legacy TC and has HDMI (with DP: %s), assume it's %s\n", port_name(port), str_yes_no(init_dp), @@ -5363,24 +5335,24 @@ void intel_ddi_init(struct intel_display *display, goto err; } - drm_WARN_ON(&dev_priv->drm, port > PORT_I); + drm_WARN_ON(display->drm, port > PORT_I); dig_port->ddi_io_power_domain = intel_display_power_ddi_io_domain(display, port); - if (DISPLAY_VER(dev_priv) >= 11) { + if (DISPLAY_VER(display) >= 11) { if (intel_encoder_is_tc(encoder)) dig_port->connected = intel_tc_port_connected; else dig_port->connected = lpt_digital_port_connected; - } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + } else if (display->platform.geminilake || display->platform.broxton) { dig_port->connected = bdw_digital_port_connected; - } else if (DISPLAY_VER(dev_priv) == 9) { + } else if (DISPLAY_VER(display) == 9) { dig_port->connected = lpt_digital_port_connected; - } else if (IS_BROADWELL(dev_priv)) { + } else if (display->platform.broadwell) { if (port == PORT_A) dig_port->connected = bdw_digital_port_connected; else dig_port->connected = lpt_digital_port_connected; - } else if (IS_HASWELL(dev_priv)) { + } else if (display->platform.haswell) { if (port == PORT_A) dig_port->connected = hsw_digital_port_connected; else @@ -5396,7 +5368,7 @@ void intel_ddi_init(struct intel_display *display, dig_port->hpd_pulse = intel_dp_hpd_pulse; if (dig_port->dp.mso_link_count) - encoder->pipe_mask = intel_ddi_splitter_pipe_mask(dev_priv); + encoder->pipe_mask = intel_ddi_splitter_pipe_mask(display); } /* diff --git a/drivers/gpu/drm/i915/display/intel_de.h b/drivers/gpu/drm/i915/display/intel_de.h index b7399e9d11cc..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, @@ -181,20 +175,18 @@ intel_de_wait_custom(struct intel_display *display, i915_reg_t reg, } static inline int -__intel_de_wait_for_set(struct intel_display *display, i915_reg_t reg, - u32 mask, unsigned int timeout) +intel_de_wait_for_set(struct intel_display *display, i915_reg_t reg, + u32 mask, unsigned int timeout) { return intel_de_wait(display, reg, mask, mask, timeout); } -#define intel_de_wait_for_set(p,...) __intel_de_wait_for_set(__to_intel_display(p), __VA_ARGS__) static inline int -__intel_de_wait_for_clear(struct intel_display *display, i915_reg_t reg, - u32 mask, unsigned int timeout) +intel_de_wait_for_clear(struct intel_display *display, i915_reg_t reg, + u32 mask, unsigned int timeout) { return intel_de_wait(display, reg, mask, 0, timeout); } -#define intel_de_wait_for_clear(p,...) __intel_de_wait_for_clear(__to_intel_display(p), __VA_ARGS__) /* * Unlocked mmio-accessors, think carefully before using these. @@ -205,7 +197,7 @@ __intel_de_wait_for_clear(struct intel_display *display, i915_reg_t reg, * a more localised lock guarding all access to that bank of registers. */ static inline u32 -__intel_de_read_fw(struct intel_display *display, i915_reg_t reg) +intel_de_read_fw(struct intel_display *display, i915_reg_t reg) { u32 val; @@ -214,15 +206,13 @@ __intel_de_read_fw(struct intel_display *display, i915_reg_t reg) return val; } -#define intel_de_read_fw(p,...) __intel_de_read_fw(__to_intel_display(p), __VA_ARGS__) static inline void -__intel_de_write_fw(struct intel_display *display, i915_reg_t reg, u32 val) +intel_de_write_fw(struct intel_display *display, i915_reg_t reg, u32 val) { trace_i915_reg_rw(true, reg, val, sizeof(val), true); intel_uncore_write_fw(__to_uncore(display), reg, val); } -#define intel_de_write_fw(p,...) __intel_de_write_fw(__to_intel_display(p), __VA_ARGS__) static inline u32 intel_de_read_notrace(struct intel_display *display, i915_reg_t reg) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 3b509c70fb58..6f0a0bc71b06 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" @@ -73,6 +74,7 @@ #include "intel_de.h" #include "intel_display_driver.h" #include "intel_display_power.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dmc.h" #include "intel_dp.h" @@ -663,7 +665,6 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, struct intel_plane *plane) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); struct intel_plane_state *plane_state = @@ -696,7 +697,7 @@ void intel_plane_disable_noatomic(struct intel_crtc *crtc, * wait-for-vblank between disabling the plane and the pipe. */ if (HAS_GMCH(display) && - intel_set_memory_cxsr(dev_priv, false)) + intel_set_memory_cxsr(display, false)) intel_plane_initial_vblank_wait(crtc); /* @@ -1043,19 +1044,16 @@ 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_psr_post_plane_update(state, crtc); - - 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(dev_priv); + intel_update_watermarks(display); intel_fbc_post_update(state, crtc); @@ -1080,6 +1078,10 @@ 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); } static void intel_post_plane_update_after_readout(struct intel_atomic_state *state, @@ -1168,13 +1170,15 @@ static void intel_pre_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_alpm_pre_plane_update(state, crtc); + intel_psr_pre_plane_update(state, crtc); + if (intel_crtc_vrr_disabling(state, crtc)) { intel_vrr_disable(old_crtc_state); intel_crtc_update_active_timings(old_crtc_state, false); @@ -1185,8 +1189,6 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, intel_drrs_deactivate(old_crtc_state); - intel_psr_pre_plane_update(state, crtc); - if (hsw_ips_pre_update(state, crtc)) intel_crtc_wait_for_next_vblank(crtc); @@ -1222,7 +1224,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, * wait-for-vblank between disabling the plane and the pipe. */ if (HAS_GMCH(display) && old_crtc_state->hw.active && - new_crtc_state->disable_cxsr && intel_set_memory_cxsr(dev_priv, false)) + new_crtc_state->disable_cxsr && intel_set_memory_cxsr(display, false)) intel_crtc_wait_for_next_vblank(crtc); /* @@ -1233,7 +1235,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, * WaCxSRDisabledForSpriteScaling:ivb */ if (!HAS_GMCH(display) && old_crtc_state->hw.active && - new_crtc_state->disable_cxsr && ilk_disable_cxsr(dev_priv)) + new_crtc_state->disable_cxsr && ilk_disable_cxsr(display)) intel_crtc_wait_for_next_vblank(crtc); /* @@ -1257,7 +1259,7 @@ static void intel_pre_plane_update(struct intel_atomic_state *state, */ if (!intel_initial_watermarks(state, crtc)) if (new_crtc_state->update_wm_pre) - intel_update_watermarks(dev_priv); + intel_update_watermarks(display); } /* @@ -1282,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; @@ -1304,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) @@ -1511,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)) @@ -1563,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); /* @@ -1662,13 +1663,8 @@ static void hsw_crtc_enable(struct intel_atomic_state *state, intel_encoders_pre_pll_enable(state, crtc); - for_each_pipe_crtc_modeset_enable(display, pipe_crtc, new_crtc_state, i) { - const struct intel_crtc_state *pipe_crtc_state = - intel_atomic_get_new_crtc_state(state, pipe_crtc); - - if (pipe_crtc_state->shared_dpll) - intel_enable_shared_dpll(pipe_crtc_state); - } + if (new_crtc_state->shared_dpll) + intel_enable_shared_dpll(new_crtc_state); intel_encoders_pre_enable(state, crtc); @@ -1779,8 +1775,6 @@ static void ilk_crtc_disable(struct intel_atomic_state *state, intel_set_cpu_fifo_underrun_reporting(display, pipe, true); intel_set_pch_fifo_underrun_reporting(display, pipe, true); - - intel_disable_shared_dpll(old_crtc_state); } static void hsw_crtc_disable(struct intel_atomic_state *state, @@ -1799,12 +1793,7 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, intel_encoders_disable(state, crtc); intel_encoders_post_disable(state, crtc); - for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { - const struct intel_crtc_state *old_pipe_crtc_state = - intel_atomic_get_old_crtc_state(state, pipe_crtc); - - intel_disable_shared_dpll(old_pipe_crtc_state); - } + intel_disable_shared_dpll(old_crtc_state); intel_encoders_post_pll_disable(state, crtc); @@ -2083,7 +2072,6 @@ static void i9xx_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)) @@ -2107,7 +2095,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state, intel_color_modeset(new_crtc_state); if (!intel_initial_watermarks(state, crtc)) - intel_update_watermarks(dev_priv); + intel_update_watermarks(display); intel_enable_transcoder(new_crtc_state); intel_crtc_vblank_on(new_crtc_state); @@ -2123,7 +2111,6 @@ static void i9xx_crtc_disable(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(display->drm); struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); enum pipe pipe = crtc->pipe; @@ -2147,9 +2134,9 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state, if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DSI)) { if (display->platform.cherryview) - chv_disable_pll(dev_priv, pipe); + chv_disable_pll(display, pipe); else if (display->platform.valleyview) - vlv_disable_pll(dev_priv, pipe); + vlv_disable_pll(display, pipe); else i9xx_disable_pll(old_crtc_state); } @@ -2160,7 +2147,7 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state, intel_set_cpu_fifo_underrun_reporting(display, pipe, false); if (!display->funcs.wm->initial_watermarks) - intel_update_watermarks(dev_priv); + intel_update_watermarks(display); /* clock the pipe down to 640x480@60 to potentially save power */ if (display->platform.i830) @@ -2343,7 +2330,6 @@ static int intel_crtc_compute_pipe_src(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); intel_joiner_compute_pipe_src(crtc_state); @@ -2362,7 +2348,7 @@ static int intel_crtc_compute_pipe_src(struct intel_crtc_state *crtc_state) } if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) && - intel_is_dual_link_lvds(i915)) { + intel_is_dual_link_lvds(display)) { drm_dbg_kms(display->drm, "[CRTC:%d:%s] Odd pipe source width not supported with dual link LVDS\n", crtc->base.base.id, crtc->base.name); @@ -2420,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); @@ -2436,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; } @@ -2550,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; @@ -2639,6 +2613,15 @@ void intel_cpu_transcoder_set_m2_n2(struct intel_crtc *crtc, PIPE_LINK_N2(display, transcoder)); } +static bool +transcoder_has_vrr(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + + return HAS_VRR(display) && !transcoder_is_dsi(cpu_transcoder); +} + static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); @@ -2703,6 +2686,15 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta HSYNC_START(adjusted_mode->crtc_hsync_start - 1) | HSYNC_END(adjusted_mode->crtc_hsync_end - 1)); + /* + * For platforms that always use VRR Timing Generator, the VTOTAL.Vtotal + * bits are not required. Since the support for these bits is going to + * be deprecated in upcoming platforms, avoid writing these bits for the + * platforms that do not use legacy Timing Generator. + */ + if (intel_vrr_always_use_vrr_tg(display)) + crtc_vtotal = 1; + intel_de_write(display, TRANS_VTOTAL(display, cpu_transcoder), VACTIVE(crtc_vdisplay - 1) | VTOTAL(crtc_vtotal - 1)); @@ -2722,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) @@ -2764,12 +2769,24 @@ static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc VBLANK_START(crtc_vblank_start - 1) | VBLANK_END(crtc_vblank_end - 1)); /* + * For platforms that always use VRR Timing Generator, the VTOTAL.Vtotal + * bits are not required. Since the support for these bits is going to + * be deprecated in upcoming platforms, avoid writing these bits for the + * platforms that do not use legacy Timing Generator. + */ + if (intel_vrr_always_use_vrr_tg(display)) + crtc_vtotal = 1; + + /* * The double buffer latch point for TRANS_VTOTAL * is the transcoder's undelayed vblank. */ intel_de_write(display, TRANS_VTOTAL(display, cpu_transcoder), VACTIVE(crtc_vdisplay - 1) | VTOTAL(crtc_vtotal - 1)); + + intel_vrr_set_fixed_rr_timings(crtc_state); + intel_vrr_transcoder_enable(crtc_state); } static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state) @@ -2853,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) @@ -3835,7 +3856,6 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, struct intel_display_power_domain_set *power_domain_set) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum transcoder cpu_transcoder; enum port port; u32 tmp; @@ -3857,7 +3877,7 @@ static bool bxt_get_dsi_transcoder_state(struct intel_crtc *crtc, * registers/MIPI[BXT]. We can break out here early, since we * need the same DSI PLL to be enabled for both DSI ports. */ - if (!bxt_dsi_pll_is_enabled(dev_priv)) + if (!bxt_dsi_pll_is_enabled(display)) break; /* XXX: this works for video mode only */ @@ -3920,7 +3940,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc, DISPLAY_VER(display) >= 11) intel_get_transcoder_timings(crtc, pipe_config); - if (HAS_VRR(display) && !transcoder_is_dsi(pipe_config->cpu_transcoder)) + if (transcoder_has_vrr(pipe_config)) intel_vrr_get_config(pipe_config); intel_get_pipe_src_size(crtc, pipe_config); @@ -4147,8 +4167,6 @@ static u16 hsw_ips_linetime_wm(const struct intel_crtc_state *crtc_state, static u16 skl_linetime_wm(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); const struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode; int linetime_wm; @@ -4161,7 +4179,7 @@ static u16 skl_linetime_wm(const struct intel_crtc_state *crtc_state) /* Display WA #1135: BXT:ALL GLK:ALL */ if ((display->platform.geminilake || display->platform.broxton) && - skl_watermark_ipc_enabled(dev_priv)) + skl_watermark_ipc_enabled(display)) linetime_wm /= 2; return min(linetime_wm, 0x1ff); @@ -5206,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); @@ -5387,8 +5407,6 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_I(vrr.vmin); PIPE_CONF_CHECK_I(vrr.vmax); PIPE_CONF_CHECK_I(vrr.flipline); - PIPE_CONF_CHECK_I(vrr.pipeline_full); - PIPE_CONF_CHECK_I(vrr.guardband); PIPE_CONF_CHECK_I(vrr.vsync_start); PIPE_CONF_CHECK_I(vrr.vsync_end); PIPE_CONF_CHECK_LLI(cmrr.cmrr_m); @@ -5396,6 +5414,11 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, PIPE_CONF_CHECK_BOOL(cmrr.enable); } + if (!fastset || intel_vrr_always_use_vrr_tg(display)) { + PIPE_CONF_CHECK_I(vrr.pipeline_full); + PIPE_CONF_CHECK_I(vrr.guardband); + } + #undef PIPE_CONF_CHECK_X #undef PIPE_CONF_CHECK_I #undef PIPE_CONF_CHECK_LLI @@ -6007,22 +6030,16 @@ static int intel_async_flip_check_hw(struct intel_atomic_state *state, struct in if (!plane->async_flip) continue; - if (!intel_plane_can_async_flip(plane, new_plane_state->hw.fb->modifier)) { + if (!intel_plane_can_async_flip(plane, new_plane_state->hw.fb->format->format, + new_plane_state->hw.fb->modifier)) { drm_dbg_kms(display->drm, - "[PLANE:%d:%s] Modifier 0x%llx does not support async flip\n", + "[PLANE:%d:%s] pixel format %p4cc / modifier 0x%llx does not support async flip\n", plane->base.base.id, plane->base.name, + &new_plane_state->hw.fb->format->format, new_plane_state->hw.fb->modifier); return -EINVAL; } - if (intel_format_info_is_yuv_semiplanar(new_plane_state->hw.fb->format, - new_plane_state->hw.fb->modifier)) { - drm_dbg_kms(display->drm, - "[PLANE:%d:%s] Planar formats do not support async flips\n", - plane->base.base.id, plane->base.name); - return -EINVAL; - } - /* * We turn the first async flip request into a sync flip * so that we can reconfigure the plane (eg. change modifier). @@ -6429,7 +6446,7 @@ int intel_atomic_check(struct drm_device *dev, if (ret) goto fail; - ret = intel_bw_atomic_check(state); + ret = intel_bw_atomic_check(state, any_ms); if (ret) goto fail; @@ -6533,7 +6550,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 @@ -6549,7 +6565,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) @@ -6650,6 +6666,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. */ @@ -6769,6 +6787,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, @@ -7231,7 +7251,7 @@ static void intel_atomic_dsb_finish(struct intel_atomic_state *state, static void intel_atomic_commit_tail(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *dev_priv = to_i915(display->drm); + struct drm_i915_private __maybe_unused *dev_priv = to_i915(display->drm); struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; struct intel_power_domain_mask put_domains[I915_MAX_PIPES] = {}; @@ -7445,7 +7465,7 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) * toggling overhead at and above 60 FPS. */ intel_display_power_put_async_delay(display, POWER_DOMAIN_DC_OFF, wakeref, 17); - intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref); + intel_display_rpm_put(display, state->wakeref); /* * Defer the cleanup of the old state to a separate worker to not @@ -7517,10 +7537,9 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, { struct intel_display *display = to_intel_display(dev); struct intel_atomic_state *state = to_intel_atomic_state(_state); - struct drm_i915_private *dev_priv = to_i915(dev); int ret = 0; - state->wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + state->wakeref = intel_display_rpm_get(display); /* * The intel_legacy_cursor_update() fast path takes care @@ -7554,7 +7573,7 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, if (ret) { drm_dbg_atomic(display->drm, "Preparing state failed with %i\n", ret); - intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref); + intel_display_rpm_put(display, state->wakeref); return ret; } @@ -7564,7 +7583,7 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, if (ret) { drm_atomic_helper_unprepare_planes(dev, &state->base); - intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref); + intel_display_rpm_put(display, state->wakeref); return ret; } @@ -7626,15 +7645,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; @@ -7656,7 +7673,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; @@ -7672,8 +7688,8 @@ void intel_setup_outputs(struct intel_display *display) intel_bios_for_each_encoder(display, intel_ddi_init); if (display->platform.geminilake || display->platform.broxton) - vlv_dsi_init(dev_priv); - } else if (HAS_PCH_SPLIT(dev_priv)) { + vlv_dsi_init(display); + } else if (HAS_PCH_SPLIT(display)) { int found; /* @@ -7681,7 +7697,7 @@ void intel_setup_outputs(struct intel_display *display) * to prevent the registration of both eDP and LVDS and the * incorrect sharing of the PPS. */ - intel_lvds_init(dev_priv); + intel_lvds_init(display); intel_crt_init(display); dpd_is_edp = intel_dp_is_port_edp(display, PORT_D); @@ -7756,15 +7772,15 @@ void intel_setup_outputs(struct intel_display *display) g4x_hdmi_init(display, CHV_HDMID, PORT_D); } - vlv_dsi_init(dev_priv); + vlv_dsi_init(display); } else if (display->platform.pineview) { - intel_lvds_init(dev_priv); + intel_lvds_init(display); intel_crt_init(display); } else if (IS_DISPLAY_VER(display, 3, 4)) { bool found = false; if (display->platform.mobile) - intel_lvds_init(dev_priv); + intel_lvds_init(display); intel_crt_init(display); @@ -7806,10 +7822,10 @@ void intel_setup_outputs(struct intel_display *display) intel_tv_init(display); } else if (DISPLAY_VER(display) == 2) { if (display->platform.i85x) - intel_lvds_init(dev_priv); + intel_lvds_init(display); intel_crt_init(display); - intel_dvo_init(dev_priv); + intel_dvo_init(display); } for_each_intel_encoder(display->drm, encoder) { @@ -7819,7 +7835,7 @@ void intel_setup_outputs(struct intel_display *display) intel_encoder_possible_clones(encoder); } - intel_init_pch_refclk(dev_priv); + intel_init_pch_refclk(display); drm_helper_move_panel_connectors_to_head(display->drm); } @@ -8041,13 +8057,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) { @@ -8083,6 +8097,9 @@ retry: goto out; } + if (!crtc_state->hw.active) + crtc_state->inherited = false; + if (crtc_state->hw.active) { struct intel_encoder *encoder; diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index eeb7ae3eaea8..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 @@ -80,7 +79,7 @@ struct intel_display_funcs { /* functions used for watermark calcs for display. */ struct intel_wm_funcs { /* update_wm is for legacy wm management */ - void (*update_wm)(struct drm_i915_private *dev_priv); + void (*update_wm)(struct intel_display *display); int (*compute_watermarks)(struct intel_atomic_state *state, struct intel_crtc *crtc); void (*initial_watermarks)(struct intel_atomic_state *state, @@ -90,8 +89,8 @@ struct intel_wm_funcs { void (*optimize_watermarks)(struct intel_atomic_state *state, struct intel_crtc *crtc); int (*compute_global_watermarks)(struct intel_atomic_state *state); - void (*get_hw_state)(struct drm_i915_private *i915); - void (*sanitize)(struct drm_i915_private *i915); + void (*get_hw_state)(struct intel_display *display); + void (*sanitize)(struct intel_display *display); }; struct intel_audio_state { @@ -160,6 +159,7 @@ struct intel_hotplug { struct { unsigned long last_jiffies; int count; + int blocked_count; enum { HPD_ENABLED = 0, HPD_DISABLED = 1, @@ -170,8 +170,8 @@ struct intel_hotplug { u32 retry_bits; struct delayed_work reenable_work; - u32 long_port_mask; - u32 short_port_mask; + u32 long_hpd_pin_mask; + u32 short_hpd_pin_mask; struct work_struct dig_port_work; struct work_struct poll_init_work; @@ -179,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; @@ -288,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 */ @@ -425,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; @@ -453,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 @@ -465,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]; @@ -574,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 fdedf65bee53..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" @@ -24,6 +25,7 @@ #include "intel_display_debugfs_params.h" #include "intel_display_power.h" #include "intel_display_power_well.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dmc.h" #include "intel_dp.h" @@ -54,6 +56,8 @@ static int intel_display_caps(struct seq_file *m, void *data) struct intel_display *display = node_to_intel_display(m->private); struct drm_printer p = drm_seq_file_printer(m); + drm_printf(&p, "PCH type: %d\n", INTEL_PCH_TYPE(display)); + intel_display_device_info_print(DISPLAY_INFO(display), DISPLAY_RUNTIME_INFO(display), &p); intel_display_params_dump(&display->params, display->drm->driver->name, &p); @@ -81,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; @@ -89,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) @@ -554,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); @@ -580,13 +585,12 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc) static int i915_display_info(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); struct intel_crtc *crtc; struct drm_connector *connector; struct drm_connector_list_iter conn_iter; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + wakeref = intel_display_rpm_get(display); drm_modeset_lock_all(display->drm); @@ -605,18 +609,7 @@ static int i915_display_info(struct seq_file *m, void *unused) drm_modeset_unlock_all(display->drm); - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); - - return 0; -} - -static int i915_display_capabilities(struct seq_file *m, void *unused) -{ - struct intel_display *display = node_to_intel_display(m->private); - struct drm_printer p = drm_seq_file_printer(m); - - intel_display_device_info_print(DISPLAY_INFO(display), - DISPLAY_RUNTIME_INFO(display), &p); + intel_display_rpm_put(display, wakeref); return 0; } @@ -690,14 +683,11 @@ static bool intel_lpsp_power_well_enabled(struct intel_display *display, enum i915_power_well_id power_well_id) { - struct drm_i915_private *i915 = to_i915(display->drm); - intel_wakeref_t wakeref; bool is_enabled; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); - is_enabled = intel_display_power_well_is_enabled(display, - power_well_id); - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + with_intel_display_rpm(display) + is_enabled = intel_display_power_well_is_enabled(display, + power_well_id); return is_enabled; } @@ -820,7 +810,6 @@ static const struct drm_info_list intel_display_debugfs_list[] = { {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, {"i915_power_domain_info", i915_power_domain_info, 0}, {"i915_display_info", i915_display_info, 0}, - {"i915_display_capabilities", i915_display_capabilities, 0}, {"i915_shared_dplls_info", i915_shared_dplls_info, 0}, {"i915_dp_mst_info", i915_dp_mst_info, 0}, {"i915_ddb_info", i915_ddb_info, 0}, @@ -829,7 +818,6 @@ static const struct drm_info_list intel_display_debugfs_list[] = { void intel_display_debugfs_register(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct drm_minor *minor = display->drm->primary; debugfs_create_file("i915_fifo_underrun_reset", 0644, minor->debugfs_root, @@ -844,10 +832,10 @@ void intel_display_debugfs_register(struct intel_display *display) intel_dmc_debugfs_register(display); intel_dp_test_debugfs_register(display); intel_fbc_debugfs_register(display); - intel_hpd_debugfs_register(i915); + intel_hpd_debugfs_register(display); intel_opregion_debugfs_register(display); intel_psr_debugfs_register(display); - intel_wm_debugfs_register(i915); + intel_wm_debugfs_register(display); intel_display_debugfs_params(display); } 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_device.h b/drivers/gpu/drm/i915/display/intel_display_device.h index 7a3bb77c7af7..87c666792c0d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.h +++ b/drivers/gpu/drm/i915/display/intel_display_device.h @@ -143,9 +143,11 @@ struct intel_display_platforms { #define HAS_4TILE(__display) ((__display)->platform.dg2 || DISPLAY_VER(__display) >= 14) #define HAS_ASYNC_FLIPS(__display) (DISPLAY_VER(__display) >= 5) +#define HAS_AS_SDP(__display) (DISPLAY_VER(__display) >= 13) #define HAS_BIGJOINER(__display) (DISPLAY_VER(__display) >= 11 && HAS_DSC(__display)) #define HAS_CDCLK_CRAWL(__display) (DISPLAY_INFO(__display)->has_cdclk_crawl) #define HAS_CDCLK_SQUASH(__display) (DISPLAY_INFO(__display)->has_cdclk_squash) +#define HAS_CMRR(__display) (DISPLAY_VER(__display) >= 20) #define HAS_CMTG(__display) (!(__display)->platform.dg2 && DISPLAY_VER(__display) >= 13) #define HAS_CUR_FBC(__display) (!HAS_GMCH(__display) && IS_DISPLAY_VER(__display, 7, 13)) #define HAS_D12_PLANE_MINIMIZATION(__display) ((__display)->platform.rocketlake || (__display)->platform.alderlake_s) @@ -156,9 +158,9 @@ struct intel_display_platforms { #define HAS_DMC_WAKELOCK(__display) (DISPLAY_VER(__display) >= 20) #define HAS_DOUBLE_BUFFERED_M_N(__display) (DISPLAY_VER(__display) >= 9 || (__display)->platform.broadwell) #define HAS_DOUBLE_WIDE(__display) (DISPLAY_VER(__display) < 4) -#define HAS_DP_MST(__display) (DISPLAY_INFO(__display)->has_dp_mst) #define HAS_DP20(__display) ((__display)->platform.dg2 || DISPLAY_VER(__display) >= 14) #define HAS_DPT(__display) (DISPLAY_VER(__display) >= 13) +#define HAS_DP_MST(__display) (DISPLAY_INFO(__display)->has_dp_mst) #define HAS_DSB(__display) (DISPLAY_INFO(__display)->has_dsb) #define HAS_DSC(__display) (DISPLAY_RUNTIME_INFO(__display)->has_dsc) #define HAS_DSC_3ENGINES(__display) (DISPLAY_VERx100(__display) == 1401 && HAS_DSC(__display)) @@ -167,9 +169,10 @@ struct intel_display_platforms { #define HAS_FBC_DIRTY_RECT(__display) (DISPLAY_VER(__display) >= 30) #define HAS_FPGA_DBG_UNCLAIMED(__display) (DISPLAY_INFO(__display)->has_fpga_dbg) #define HAS_FW_BLC(__display) (DISPLAY_VER(__display) >= 3) -#define HAS_GMBUS_IRQ(__display) (DISPLAY_VER(__display) >= 4) #define HAS_GMBUS_BURST_READ(__display) (DISPLAY_VER(__display) >= 10 || (__display)->platform.kabylake) +#define HAS_GMBUS_IRQ(__display) (DISPLAY_VER(__display) >= 4) #define HAS_GMCH(__display) (DISPLAY_INFO(__display)->has_gmch) +#define HAS_HOTPLUG(__display) (DISPLAY_INFO(__display)->has_hotplug) #define HAS_HW_SAGV_WM(__display) (DISPLAY_VER(__display) >= 13 && !(__display)->platform.dgfx) #define HAS_IPC(__display) (DISPLAY_INFO(__display)->has_ipc) #define HAS_IPS(__display) ((__display)->platform.haswell_ult || (__display)->platform.broadwell) @@ -190,10 +193,7 @@ struct intel_display_platforms { ((__display)->platform.dgfx && DISPLAY_VER(__display) == 14)) && \ HAS_DSC(__display)) #define HAS_VRR(__display) (DISPLAY_VER(__display) >= 11) -#define HAS_AS_SDP(__display) (DISPLAY_VER(__display) >= 13) -#define HAS_CMRR(__display) (DISPLAY_VER(__display) >= 20) #define INTEL_NUM_PIPES(__display) (hweight8(DISPLAY_RUNTIME_INFO(__display)->pipe_mask)) -#define I915_HAS_HOTPLUG(__display) (DISPLAY_INFO(__display)->has_hotplug) #define OVERLAY_NEEDS_PHYSICAL(__display) (DISPLAY_INFO(__display)->overlay_needs_physical) #define SUPPORTS_TV(__display) (DISPLAY_INFO(__display)->supports_tv) diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 31740a677dd8..411fe7b918a7 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" @@ -82,7 +83,6 @@ bool intel_display_driver_probe_defer(struct pci_dev *pdev) void intel_display_driver_init_hw(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_cdclk_state *cdclk_state; if (!HAS_DISPLAY(display)) @@ -94,7 +94,7 @@ void intel_display_driver_init_hw(struct intel_display *display) intel_cdclk_dump_config(display, &display->cdclk.hw, "Current CDCLK"); cdclk_state->logical = cdclk_state->actual = display->cdclk.hw; - intel_display_wa_apply(i915); + intel_display_wa_apply(display); } static const struct drm_mode_config_funcs intel_mode_funcs = { @@ -181,7 +181,8 @@ static void intel_plane_possible_crtcs_init(struct intel_display *display) void intel_display_driver_early_probe(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); + /* This must be called before any calls to HAS_PCH_* */ + intel_pch_detect(display); if (!HAS_DISPLAY(display)) return; @@ -193,12 +194,12 @@ void intel_display_driver_early_probe(struct intel_display *display) mutex_init(&display->pps.mutex); mutex_init(&display->hdcp.hdcp_mutex); - intel_display_irq_init(i915); + intel_display_irq_init(display); intel_dkl_phy_init(display); intel_color_init_hooks(display); intel_init_cdclk_hooks(display); intel_audio_hooks_init(display); - intel_dpll_init_clock_hook(i915); + intel_dpll_init_clock_hook(display); intel_init_display_hooks(display); intel_fdi_init_hook(display); intel_dmc_wl_init(display); @@ -226,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) @@ -241,31 +244,45 @@ int intel_display_driver_probe_noirq(struct intel_display *display) intel_dmc_init(display); display->wq.modeset = alloc_ordered_workqueue("i915_modeset", 0); + if (!display->wq.modeset) { + ret = -ENOMEM; + goto cleanup_vga_client_pw_domain_dmc; + } + display->wq.flip = alloc_workqueue("i915_flip", WQ_HIGHPRI | WQ_UNBOUND, WQ_UNBOUND_MAX_ACTIVE); + if (!display->wq.flip) { + ret = -ENOMEM; + goto cleanup_wq_modeset; + } + display->wq.cleanup = alloc_workqueue("i915_cleanup", WQ_HIGHPRI, 0); + if (!display->wq.cleanup) { + ret = -ENOMEM; + goto cleanup_wq_flip; + } intel_mode_config_init(display); ret = intel_cdclk_init(display); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_wq_cleanup; ret = intel_color_init(display); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_wq_cleanup; - ret = intel_dbuf_init(i915); + ret = intel_dbuf_init(display); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_wq_cleanup; - ret = intel_bw_init(i915); + ret = intel_bw_init(display); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_wq_cleanup; ret = intel_pmdemand_init(display); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_wq_cleanup; intel_init_quirks(display); @@ -273,6 +290,12 @@ int intel_display_driver_probe_noirq(struct intel_display *display) return 0; +cleanup_wq_cleanup: + destroy_workqueue(display->wq.cleanup); +cleanup_wq_flip: + destroy_workqueue(display->wq.flip); +cleanup_wq_modeset: + destroy_workqueue(display->wq.modeset); cleanup_vga_client_pw_domain_dmc: intel_dmc_fini(display); intel_power_domains_driver_remove(display); @@ -315,11 +338,9 @@ static void set_display_access(struct intel_display *display, */ void intel_display_driver_enable_user_access(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - set_display_access(display, true, NULL); - intel_hpd_enable_detection_work(i915); + intel_hpd_enable_detection_work(display); } /** @@ -341,9 +362,7 @@ void intel_display_driver_enable_user_access(struct intel_display *display) */ void intel_display_driver_disable_user_access(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - - intel_hpd_disable_detection_work(i915); + intel_hpd_disable_detection_work(display); set_display_access(display, false, current); } @@ -422,14 +441,13 @@ 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; if (!HAS_DISPLAY(display)) return 0; - intel_wm_init(i915); + intel_wm_init(display); intel_panel_sanitize_ssc(display); @@ -460,8 +478,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); @@ -471,7 +487,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); @@ -483,7 +499,7 @@ int intel_display_driver_probe_nogem(struct intel_display *display) * since the watermark calculation done here will use pstate->fb. */ if (!HAS_GMCH(display)) - ilk_wm_sanitize(i915); + ilk_wm_sanitize(display); return 0; @@ -498,7 +514,6 @@ err_mode_config: /* part #3: call after gem init */ int intel_display_driver_probe(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); int ret; if (!HAS_DISPLAY(display)) @@ -524,16 +539,15 @@ int intel_display_driver_probe(struct intel_display *display) intel_overlay_setup(display); /* Only enable hotplug handling once the fbdev is fully set up. */ - intel_hpd_init(i915); + intel_hpd_init(display); - skl_watermark_ipc_init(i915); + skl_watermark_ipc_init(display); return 0; } 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:"); @@ -558,9 +572,9 @@ void intel_display_driver_register(struct intel_display *display) * fbdev->async_cookie. */ drm_kms_helper_poll_init(display->drm); - intel_hpd_poll_disable(i915); + 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); @@ -600,7 +614,7 @@ void intel_display_driver_remove_noirq(struct intel_display *display) * Due to the hpd irq storm handling the hotplug work can re-arm the * poll handlers. Hence disable polling after hpd handling is shut down. */ - intel_hpd_poll_fini(i915); + intel_hpd_poll_fini(display); intel_unregister_dsm_handler(); @@ -695,13 +709,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; @@ -733,7 +745,6 @@ __intel_display_driver_resume(struct intel_display *display, void intel_display_driver_resume(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct drm_atomic_state *state = display->restore.modeset_state; struct drm_modeset_acquire_ctx ctx; int ret; @@ -761,7 +772,7 @@ void intel_display_driver_resume(struct intel_display *display) if (!ret) ret = __intel_display_driver_resume(display, state, &ctx); - skl_watermark_ipc_update(i915); + skl_watermark_ipc_update(display); drm_modeset_drop_locks(&ctx); drm_modeset_acquire_fini(&ctx); diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index aa23bb817805..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" @@ -14,6 +13,8 @@ #include "intel_crtc.h" #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" @@ -115,9 +116,8 @@ static void intel_pipe_fault_irq_handler(struct intel_display *display, } static void -intel_handle_vblank(struct drm_i915_private *dev_priv, enum pipe pipe) +intel_handle_vblank(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); drm_crtc_handle_vblank(&crtc->base); @@ -125,59 +125,59 @@ intel_handle_vblank(struct drm_i915_private *dev_priv, enum pipe pipe) /** * ilk_update_display_irq - update DEIMR - * @dev_priv: driver private + * @display: display device * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */ -void ilk_update_display_irq(struct drm_i915_private *dev_priv, +void ilk_update_display_irq(struct intel_display *display, u32 interrupt_mask, u32 enabled_irq_mask) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 new_val; - lockdep_assert_held(&dev_priv->irq_lock); - drm_WARN_ON(&dev_priv->drm, enabled_irq_mask & ~interrupt_mask); + lockdep_assert_held(&display->irq.lock); + drm_WARN_ON(display->drm, enabled_irq_mask & ~interrupt_mask); new_val = dev_priv->irq_mask; new_val &= ~interrupt_mask; new_val |= (~enabled_irq_mask & interrupt_mask); if (new_val != dev_priv->irq_mask && - !drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv))) { + !drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv))) { dev_priv->irq_mask = new_val; intel_de_write(display, DEIMR, dev_priv->irq_mask); intel_de_posting_read(display, DEIMR); } } -void ilk_enable_display_irq(struct drm_i915_private *i915, u32 bits) +void ilk_enable_display_irq(struct intel_display *display, u32 bits) { - ilk_update_display_irq(i915, bits, bits); + ilk_update_display_irq(display, bits, bits); } -void ilk_disable_display_irq(struct drm_i915_private *i915, u32 bits) +void ilk_disable_display_irq(struct intel_display *display, u32 bits) { - ilk_update_display_irq(i915, bits, 0); + ilk_update_display_irq(display, bits, 0); } /** * bdw_update_port_irq - update DE port interrupt - * @dev_priv: driver private + * @display: display device * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */ -void bdw_update_port_irq(struct drm_i915_private *dev_priv, +void bdw_update_port_irq(struct intel_display *display, u32 interrupt_mask, u32 enabled_irq_mask) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 new_val; u32 old_val; - lockdep_assert_held(&dev_priv->irq_lock); + lockdep_assert_held(&display->irq.lock); - drm_WARN_ON(&dev_priv->drm, enabled_irq_mask & ~interrupt_mask); + drm_WARN_ON(display->drm, enabled_irq_mask & ~interrupt_mask); - if (drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv))) + if (drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv))) return; old_val = intel_de_read(display, GEN8_DE_PORT_IMR); @@ -194,93 +194,92 @@ void bdw_update_port_irq(struct drm_i915_private *dev_priv, /** * bdw_update_pipe_irq - update DE pipe interrupt - * @dev_priv: driver private + * @display: display device * @pipe: pipe whose interrupt to update * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */ -static void bdw_update_pipe_irq(struct drm_i915_private *dev_priv, +static void bdw_update_pipe_irq(struct intel_display *display, enum pipe pipe, u32 interrupt_mask, u32 enabled_irq_mask) { - struct intel_display *display = &dev_priv->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(&dev_priv->drm, enabled_irq_mask & ~interrupt_mask); + drm_WARN_ON(display->drm, enabled_irq_mask & ~interrupt_mask); - if (drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv))) + if (drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv))) return; - new_val = dev_priv->display.irq.de_irq_mask[pipe]; + new_val = display->irq.de_irq_mask[pipe]; new_val &= ~interrupt_mask; new_val |= (~enabled_irq_mask & interrupt_mask); - if (new_val != dev_priv->display.irq.de_irq_mask[pipe]) { - dev_priv->display.irq.de_irq_mask[pipe] = new_val; + if (new_val != display->irq.de_irq_mask[pipe]) { + display->irq.de_irq_mask[pipe] = new_val; intel_de_write(display, GEN8_DE_PIPE_IMR(pipe), display->irq.de_irq_mask[pipe]); intel_de_posting_read(display, GEN8_DE_PIPE_IMR(pipe)); } } -void bdw_enable_pipe_irq(struct drm_i915_private *i915, +void bdw_enable_pipe_irq(struct intel_display *display, enum pipe pipe, u32 bits) { - bdw_update_pipe_irq(i915, pipe, bits, bits); + bdw_update_pipe_irq(display, pipe, bits, bits); } -void bdw_disable_pipe_irq(struct drm_i915_private *i915, +void bdw_disable_pipe_irq(struct intel_display *display, enum pipe pipe, u32 bits) { - bdw_update_pipe_irq(i915, pipe, bits, 0); + bdw_update_pipe_irq(display, pipe, bits, 0); } /** * ibx_display_interrupt_update - update SDEIMR - * @dev_priv: driver private + * @display: display device * @interrupt_mask: mask of interrupt bits to update * @enabled_irq_mask: mask of interrupt bits to enable */ -void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, +void ibx_display_interrupt_update(struct intel_display *display, u32 interrupt_mask, u32 enabled_irq_mask) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 sdeimr = intel_de_read(display, SDEIMR); sdeimr &= ~interrupt_mask; sdeimr |= (~enabled_irq_mask & interrupt_mask); - drm_WARN_ON(&dev_priv->drm, enabled_irq_mask & ~interrupt_mask); + 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(&dev_priv->drm, !intel_irqs_enabled(dev_priv))) + if (drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv))) return; intel_de_write(display, SDEIMR, sdeimr); intel_de_posting_read(display, SDEIMR); } -void ibx_enable_display_interrupt(struct drm_i915_private *i915, u32 bits) +void ibx_enable_display_interrupt(struct intel_display *display, u32 bits) { - ibx_display_interrupt_update(i915, bits, bits); + ibx_display_interrupt_update(display, bits, bits); } -void ibx_disable_display_interrupt(struct drm_i915_private *i915, u32 bits) +void ibx_disable_display_interrupt(struct intel_display *display, u32 bits) { - ibx_display_interrupt_update(i915, bits, 0); + ibx_display_interrupt_update(display, bits, 0); } 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; @@ -318,48 +317,48 @@ out: return enable_mask; } -void i915_enable_pipestat(struct drm_i915_private *dev_priv, +void i915_enable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask) { - struct intel_display *display = &dev_priv->display; - i915_reg_t reg = PIPESTAT(dev_priv, pipe); + struct drm_i915_private *dev_priv = to_i915(display->drm); + i915_reg_t reg = PIPESTAT(display, pipe); u32 enable_mask; - drm_WARN_ONCE(&dev_priv->drm, status_mask & ~PIPESTAT_INT_STATUS_MASK, + drm_WARN_ONCE(display->drm, status_mask & ~PIPESTAT_INT_STATUS_MASK, "pipe %c: status_mask=0x%x\n", pipe_name(pipe), status_mask); - lockdep_assert_held(&dev_priv->irq_lock); - drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv)); + lockdep_assert_held(&display->irq.lock); + drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv)); - if ((dev_priv->display.irq.pipestat_irq_mask[pipe] & status_mask) == status_mask) + if ((display->irq.pipestat_irq_mask[pipe] & status_mask) == status_mask) return; - dev_priv->display.irq.pipestat_irq_mask[pipe] |= status_mask; + display->irq.pipestat_irq_mask[pipe] |= status_mask; enable_mask = i915_pipestat_enable_mask(display, pipe); intel_de_write(display, reg, enable_mask | status_mask); intel_de_posting_read(display, reg); } -void i915_disable_pipestat(struct drm_i915_private *dev_priv, +void i915_disable_pipestat(struct intel_display *display, enum pipe pipe, u32 status_mask) { - struct intel_display *display = &dev_priv->display; - i915_reg_t reg = PIPESTAT(dev_priv, pipe); + struct drm_i915_private *dev_priv = to_i915(display->drm); + i915_reg_t reg = PIPESTAT(display, pipe); u32 enable_mask; - drm_WARN_ONCE(&dev_priv->drm, status_mask & ~PIPESTAT_INT_STATUS_MASK, + drm_WARN_ONCE(display->drm, status_mask & ~PIPESTAT_INT_STATUS_MASK, "pipe %c: status_mask=0x%x\n", pipe_name(pipe), status_mask); - lockdep_assert_held(&dev_priv->irq_lock); - drm_WARN_ON(&dev_priv->drm, !intel_irqs_enabled(dev_priv)); + lockdep_assert_held(&display->irq.lock); + drm_WARN_ON(display->drm, !intel_irqs_enabled(dev_priv)); - if ((dev_priv->display.irq.pipestat_irq_mask[pipe] & status_mask) == 0) + if ((display->irq.pipestat_irq_mask[pipe] & status_mask) == 0) return; - dev_priv->display.irq.pipestat_irq_mask[pipe] &= ~status_mask; + display->irq.pipestat_irq_mask[pipe] &= ~status_mask; enable_mask = i915_pipestat_enable_mask(display, pipe); intel_de_write(display, reg, enable_mask | status_mask); @@ -368,49 +367,41 @@ void i915_disable_pipestat(struct drm_i915_private *dev_priv, static bool i915_has_legacy_blc_interrupt(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); - - if (IS_I85X(i915)) + if (display->platform.i85x) return true; - if (IS_PINEVIEW(i915)) + if (display->platform.pineview) return true; - return IS_DISPLAY_VER(display, 3, 4) && IS_MOBILE(i915); + return IS_DISPLAY_VER(display, 3, 4) && display->platform.mobile; } -/** - * i915_enable_asle_pipestat - enable ASLE pipestat for OpRegion - * @dev_priv: i915 device private - */ -void i915_enable_asle_pipestat(struct drm_i915_private *dev_priv) +/* enable ASLE pipestat for OpRegion */ +static void i915_enable_asle_pipestat(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; - 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(dev_priv, PIPE_B, PIPE_LEGACY_BLC_EVENT_STATUS); - if (DISPLAY_VER(dev_priv) >= 4) - i915_enable_pipestat(dev_priv, PIPE_A, + 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) -static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, +static void display_pipe_crc_irq_handler(struct intel_display *display, enum pipe pipe, u32 crc0, u32 crc1, u32 crc2, u32 crc3, u32 crc4) { - struct intel_display *display = &dev_priv->display; struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc; u32 crcs[5] = { crc0, crc1, crc2, crc3, crc4 }; @@ -427,7 +418,7 @@ static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, * don't trust that one either. */ if (pipe_crc->skipped <= 0 || - (DISPLAY_VER(dev_priv) >= 8 && pipe_crc->skipped == 1)) { + (DISPLAY_VER(display) >= 8 && pipe_crc->skipped == 1)) { pipe_crc->skipped++; spin_unlock(&pipe_crc->lock); return; @@ -440,20 +431,19 @@ static void display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, } #else static inline void -display_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, +display_pipe_crc_irq_handler(struct intel_display *display, enum pipe pipe, u32 crc0, u32 crc1, u32 crc2, u32 crc3, u32 crc4) {} #endif -static void flip_done_handler(struct drm_i915_private *i915, +static void flip_done_handler(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &i915->display; struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); - spin_lock(&i915->drm.event_lock); + spin_lock(&display->drm->event_lock); if (crtc->flip_done_event) { trace_intel_crtc_flip_done(crtc); @@ -461,25 +451,21 @@ static void flip_done_handler(struct drm_i915_private *i915, crtc->flip_done_event = NULL; } - spin_unlock(&i915->drm.event_lock); + spin_unlock(&display->drm->event_lock); } -static void hsw_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, +static void hsw_pipe_crc_irq_handler(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; - - display_pipe_crc_irq_handler(dev_priv, pipe, + display_pipe_crc_irq_handler(display, pipe, intel_de_read(display, PIPE_CRC_RES_HSW(pipe)), 0, 0, 0, 0); } -static void ivb_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, +static void ivb_pipe_crc_irq_handler(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; - - display_pipe_crc_irq_handler(dev_priv, pipe, + display_pipe_crc_irq_handler(display, pipe, intel_de_read(display, PIPE_CRC_RES_1_IVB(pipe)), intel_de_read(display, PIPE_CRC_RES_2_IVB(pipe)), intel_de_read(display, PIPE_CRC_RES_3_IVB(pipe)), @@ -487,58 +473,55 @@ static void ivb_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, intel_de_read(display, PIPE_CRC_RES_5_IVB(pipe))); } -static void i9xx_pipe_crc_irq_handler(struct drm_i915_private *dev_priv, +static void i9xx_pipe_crc_irq_handler(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; u32 res1, res2; - if (DISPLAY_VER(dev_priv) >= 3) - res1 = intel_de_read(display, PIPE_CRC_RES_RES1_I915(dev_priv, pipe)); + if (DISPLAY_VER(display) >= 3) + res1 = intel_de_read(display, PIPE_CRC_RES_RES1_I915(display, pipe)); else res1 = 0; - if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) - res2 = intel_de_read(display, PIPE_CRC_RES_RES2_G4X(dev_priv, pipe)); + if (DISPLAY_VER(display) >= 5 || display->platform.g4x) + res2 = intel_de_read(display, PIPE_CRC_RES_RES2_G4X(display, pipe)); else res2 = 0; - display_pipe_crc_irq_handler(dev_priv, pipe, - intel_de_read(display, PIPE_CRC_RES_RED(dev_priv, pipe)), - intel_de_read(display, PIPE_CRC_RES_GREEN(dev_priv, pipe)), - intel_de_read(display, PIPE_CRC_RES_BLUE(dev_priv, pipe)), + display_pipe_crc_irq_handler(display, pipe, + intel_de_read(display, PIPE_CRC_RES_RED(display, pipe)), + intel_de_read(display, PIPE_CRC_RES_GREEN(display, pipe)), + intel_de_read(display, PIPE_CRC_RES_BLUE(display, pipe)), res1, res2); } -static void i9xx_pipestat_irq_reset(struct drm_i915_private *dev_priv) +static void i9xx_pipestat_irq_reset(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { intel_de_write(display, - PIPESTAT(dev_priv, pipe), + PIPESTAT(display, pipe), PIPESTAT_INT_STATUS_MASK | PIPE_FIFO_UNDERRUN_STATUS); - dev_priv->display.irq.pipestat_irq_mask[pipe] = 0; + display->irq.pipestat_irq_mask[pipe] = 0; } } -void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, +void i9xx_pipestat_irq_ack(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; - spin_lock(&dev_priv->irq_lock); + spin_lock(&display->irq.lock); - if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && - !dev_priv->display.irq.vlv_display_irqs_enabled) { - spin_unlock(&dev_priv->irq_lock); + if ((display->platform.valleyview || display->platform.cherryview) && + !display->irq.vlv_display_irqs_enabled) { + spin_unlock(&display->irq.lock); return; } - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { i915_reg_t reg; u32 status_mask, enable_mask, iir_bit = 0; @@ -566,12 +549,12 @@ void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, break; } if (iir & iir_bit) - status_mask |= dev_priv->display.irq.pipestat_irq_mask[pipe]; + status_mask |= display->irq.pipestat_irq_mask[pipe]; if (!status_mask) continue; - reg = PIPESTAT(dev_priv, pipe); + reg = PIPESTAT(display, pipe); pipe_stats[pipe] = intel_de_read(display, reg) & status_mask; enable_mask = i915_pipestat_enable_mask(display, pipe); @@ -589,25 +572,24 @@ void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv, intel_de_write(display, reg, enable_mask); } } - spin_unlock(&dev_priv->irq_lock); + spin_unlock(&display->irq.lock); } -void i915_pipestat_irq_handler(struct drm_i915_private *dev_priv, +void i915_pipestat_irq_handler(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]) { - struct intel_display *display = &dev_priv->display; bool blc_event = false; enum pipe pipe; - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS) - intel_handle_vblank(dev_priv, pipe); + intel_handle_vblank(display, pipe); if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) blc_event = true; if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) - i9xx_pipe_crc_irq_handler(dev_priv, pipe); + i9xx_pipe_crc_irq_handler(display, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) intel_cpu_fifo_underrun_irq_handler(display, pipe); @@ -617,22 +599,21 @@ void i915_pipestat_irq_handler(struct drm_i915_private *dev_priv, intel_opregion_asle_intr(display); } -void i965_pipestat_irq_handler(struct drm_i915_private *dev_priv, +void i965_pipestat_irq_handler(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]) { - struct intel_display *display = &dev_priv->display; bool blc_event = false; enum pipe pipe; - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS) - intel_handle_vblank(dev_priv, pipe); + intel_handle_vblank(display, pipe); if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS) blc_event = true; if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) - i9xx_pipe_crc_irq_handler(dev_priv, pipe); + i9xx_pipe_crc_irq_handler(display, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) intel_cpu_fifo_underrun_irq_handler(display, pipe); @@ -645,21 +626,20 @@ void i965_pipestat_irq_handler(struct drm_i915_private *dev_priv, intel_gmbus_irq_handler(display); } -void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv, +void valleyview_pipestat_irq_handler(struct intel_display *display, u32 pipe_stats[I915_MAX_PIPES]) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS) - intel_handle_vblank(dev_priv, pipe); + intel_handle_vblank(display, pipe); if (pipe_stats[pipe] & PLANE_FLIP_DONE_INT_STATUS_VLV) - flip_done_handler(dev_priv, pipe); + flip_done_handler(display, pipe); if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS) - i9xx_pipe_crc_irq_handler(dev_priv, pipe); + i9xx_pipe_crc_irq_handler(display, pipe); if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS) intel_cpu_fifo_underrun_irq_handler(display, pipe); @@ -669,18 +649,17 @@ void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv, intel_gmbus_irq_handler(display); } -static void ibx_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) +static void ibx_irq_handler(struct intel_display *display, u32 pch_iir) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK; - ibx_hpd_irq_handler(dev_priv, hotplug_trigger); + ibx_hpd_irq_handler(display, hotplug_trigger); if (pch_iir & SDE_AUDIO_POWER_MASK) { int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK) >> SDE_AUDIO_POWER_SHIFT); - drm_dbg(&dev_priv->drm, "PCH audio power change on port %d\n", + drm_dbg(display->drm, "PCH audio power change on port %d\n", port_name(port)); } @@ -691,26 +670,26 @@ static void ibx_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) intel_gmbus_irq_handler(display); if (pch_iir & SDE_AUDIO_HDCP_MASK) - drm_dbg(&dev_priv->drm, "PCH HDCP audio interrupt\n"); + drm_dbg(display->drm, "PCH HDCP audio interrupt\n"); if (pch_iir & SDE_AUDIO_TRANS_MASK) - drm_dbg(&dev_priv->drm, "PCH transcoder audio interrupt\n"); + drm_dbg(display->drm, "PCH transcoder audio interrupt\n"); if (pch_iir & SDE_POISON) - drm_err(&dev_priv->drm, "PCH poison interrupt\n"); + drm_err(display->drm, "PCH poison interrupt\n"); if (pch_iir & SDE_FDI_MASK) { - for_each_pipe(dev_priv, pipe) - drm_dbg(&dev_priv->drm, " pipe %c FDI IIR: 0x%08x\n", + for_each_pipe(display, pipe) + drm_dbg(display->drm, " pipe %c FDI IIR: 0x%08x\n", pipe_name(pipe), intel_de_read(display, FDI_RX_IIR(pipe))); } if (pch_iir & (SDE_TRANSB_CRC_DONE | SDE_TRANSA_CRC_DONE)) - drm_dbg(&dev_priv->drm, "PCH transcoder CRC done interrupt\n"); + drm_dbg(display->drm, "PCH transcoder CRC done interrupt\n"); if (pch_iir & (SDE_TRANSB_CRC_ERR | SDE_TRANSA_CRC_ERR)) - drm_dbg(&dev_priv->drm, + drm_dbg(display->drm, "PCH transcoder CRC error interrupt\n"); if (pch_iir & SDE_TRANSA_FIFO_UNDER) @@ -753,14 +732,13 @@ static const struct pipe_fault_handler ivb_pipe_fault_handlers[] = { {} }; -static void ivb_err_int_handler(struct drm_i915_private *dev_priv) +static void ivb_err_int_handler(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; u32 err_int = intel_de_read(display, GEN7_ERR_INT); enum pipe pipe; if (err_int & ERR_INT_POISON) - drm_err(&dev_priv->drm, "Poison interrupt\n"); + drm_err(display->drm, "Poison interrupt\n"); if (err_int & ERR_INT_INVALID_GTT_PTE) drm_err_ratelimited(display->drm, "Invalid GTT PTE\n"); @@ -768,17 +746,17 @@ static void ivb_err_int_handler(struct drm_i915_private *dev_priv) if (err_int & ERR_INT_INVALID_PTE_DATA) drm_err_ratelimited(display->drm, "Invalid PTE data\n"); - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { u32 fault_errors; if (err_int & ERR_INT_FIFO_UNDERRUN(pipe)) intel_cpu_fifo_underrun_irq_handler(display, pipe); if (err_int & ERR_INT_PIPE_CRC_DONE(pipe)) { - if (IS_IVYBRIDGE(dev_priv)) - ivb_pipe_crc_irq_handler(dev_priv, pipe); + if (display->platform.ivybridge) + ivb_pipe_crc_irq_handler(display, pipe); else - hsw_pipe_crc_irq_handler(dev_priv, pipe); + hsw_pipe_crc_irq_handler(display, pipe); } fault_errors = err_int & ivb_err_int_pipe_fault_mask(pipe); @@ -790,34 +768,32 @@ static void ivb_err_int_handler(struct drm_i915_private *dev_priv) intel_de_write(display, GEN7_ERR_INT, err_int); } -static void cpt_serr_int_handler(struct drm_i915_private *dev_priv) +static void cpt_serr_int_handler(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; u32 serr_int = intel_de_read(display, SERR_INT); enum pipe pipe; if (serr_int & SERR_INT_POISON) - drm_err(&dev_priv->drm, "PCH poison interrupt\n"); + drm_err(display->drm, "PCH poison interrupt\n"); - for_each_pipe(dev_priv, pipe) + for_each_pipe(display, pipe) if (serr_int & SERR_INT_TRANS_FIFO_UNDERRUN(pipe)) intel_pch_fifo_underrun_irq_handler(display, pipe); intel_de_write(display, SERR_INT, serr_int); } -static void cpt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) +static void cpt_irq_handler(struct intel_display *display, u32 pch_iir) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_CPT; - ibx_hpd_irq_handler(dev_priv, hotplug_trigger); + ibx_hpd_irq_handler(display, hotplug_trigger); if (pch_iir & SDE_AUDIO_POWER_MASK_CPT) { int port = ffs((pch_iir & SDE_AUDIO_POWER_MASK_CPT) >> SDE_AUDIO_POWER_SHIFT_CPT); - drm_dbg(&dev_priv->drm, "PCH audio power change on port %c\n", + drm_dbg(display->drm, "PCH audio power change on port %c\n", port_name(port)); } @@ -828,20 +804,20 @@ static void cpt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) intel_gmbus_irq_handler(display); if (pch_iir & SDE_AUDIO_CP_REQ_CPT) - drm_dbg(&dev_priv->drm, "Audio CP request interrupt\n"); + drm_dbg(display->drm, "Audio CP request interrupt\n"); if (pch_iir & SDE_AUDIO_CP_CHG_CPT) - drm_dbg(&dev_priv->drm, "Audio CP change interrupt\n"); + drm_dbg(display->drm, "Audio CP change interrupt\n"); if (pch_iir & SDE_FDI_MASK_CPT) { - for_each_pipe(dev_priv, pipe) - drm_dbg(&dev_priv->drm, " pipe %c FDI IIR: 0x%08x\n", + for_each_pipe(display, pipe) + drm_dbg(display->drm, " pipe %c FDI IIR: 0x%08x\n", pipe_name(pipe), intel_de_read(display, FDI_RX_IIR(pipe))); } if (pch_iir & SDE_ERROR_CPT) - cpt_serr_int_handler(dev_priv); + cpt_serr_int_handler(display); } static u32 ilk_gtt_fault_pipe_fault_mask(enum pipe pipe) @@ -894,14 +870,13 @@ static void ilk_gtt_fault_irq_handler(struct intel_display *display) } } -void ilk_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) +void ilk_display_irq_handler(struct intel_display *display, u32 de_iir) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; u32 hotplug_trigger = de_iir & DE_DP_A_HOTPLUG; if (hotplug_trigger) - ilk_hpd_irq_handler(dev_priv, hotplug_trigger); + ilk_hpd_irq_handler(display, hotplug_trigger); if (de_iir & DE_AUX_CHANNEL_A) intel_dp_aux_irq_handler(display); @@ -910,58 +885,57 @@ void ilk_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) intel_opregion_asle_intr(display); if (de_iir & DE_POISON) - drm_err(&dev_priv->drm, "Poison interrupt\n"); + drm_err(display->drm, "Poison interrupt\n"); if (de_iir & DE_GTT_FAULT) ilk_gtt_fault_irq_handler(display); - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { if (de_iir & DE_PIPE_VBLANK(pipe)) - intel_handle_vblank(dev_priv, pipe); + intel_handle_vblank(display, pipe); if (de_iir & DE_PLANE_FLIP_DONE(pipe)) - flip_done_handler(dev_priv, pipe); + flip_done_handler(display, pipe); if (de_iir & DE_PIPE_FIFO_UNDERRUN(pipe)) intel_cpu_fifo_underrun_irq_handler(display, pipe); if (de_iir & DE_PIPE_CRC_DONE(pipe)) - i9xx_pipe_crc_irq_handler(dev_priv, pipe); + i9xx_pipe_crc_irq_handler(display, pipe); } /* check event from PCH */ if (de_iir & DE_PCH_EVENT) { u32 pch_iir = intel_de_read(display, SDEIIR); - if (HAS_PCH_CPT(dev_priv)) - cpt_irq_handler(dev_priv, pch_iir); + if (HAS_PCH_CPT(display)) + cpt_irq_handler(display, pch_iir); else - ibx_irq_handler(dev_priv, pch_iir); + ibx_irq_handler(display, pch_iir); /* should clear PCH hotplug event before clear CPU irq */ intel_de_write(display, SDEIIR, pch_iir); } - if (DISPLAY_VER(dev_priv) == 5 && de_iir & DE_PCU_EVENT) - gen5_rps_irq_handler(&to_gt(dev_priv)->rps); + if (DISPLAY_VER(display) == 5 && de_iir & DE_PCU_EVENT) + ilk_display_rps_irq_handler(display); } -void ivb_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) +void ivb_display_irq_handler(struct intel_display *display, u32 de_iir) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; u32 hotplug_trigger = de_iir & DE_DP_A_HOTPLUG_IVB; if (hotplug_trigger) - ilk_hpd_irq_handler(dev_priv, hotplug_trigger); + ilk_hpd_irq_handler(display, hotplug_trigger); if (de_iir & DE_ERR_INT_IVB) - ivb_err_int_handler(dev_priv); + ivb_err_int_handler(display); if (de_iir & DE_EDP_PSR_INT_HSW) { struct intel_encoder *encoder; - for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) { + for_each_intel_encoder_with_psr(display->drm, encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); u32 psr_iir; @@ -977,35 +951,35 @@ void ivb_display_irq_handler(struct drm_i915_private *dev_priv, u32 de_iir) if (de_iir & DE_GSE_IVB) intel_opregion_asle_intr(display); - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { if (de_iir & DE_PIPE_VBLANK_IVB(pipe)) - intel_handle_vblank(dev_priv, pipe); + intel_handle_vblank(display, pipe); if (de_iir & DE_PLANE_FLIP_DONE_IVB(pipe)) - flip_done_handler(dev_priv, pipe); + flip_done_handler(display, pipe); } /* 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(dev_priv, pch_iir); + cpt_irq_handler(display, pch_iir); /* clear PCH hotplug event before clear CPU irq */ intel_de_write(display, SDEIIR, pch_iir); } } -static u32 gen8_de_port_aux_mask(struct drm_i915_private *dev_priv) +static u32 gen8_de_port_aux_mask(struct intel_display *display) { u32 mask; - if (DISPLAY_VER(dev_priv) >= 20) + if (DISPLAY_VER(display) >= 20) return 0; - else if (DISPLAY_VER(dev_priv) >= 14) + else if (DISPLAY_VER(display) >= 14) return TGL_DE_PORT_AUX_DDIA | TGL_DE_PORT_AUX_DDIB; - else if (DISPLAY_VER(dev_priv) >= 13) + else if (DISPLAY_VER(display) >= 13) return TGL_DE_PORT_AUX_DDIA | TGL_DE_PORT_AUX_DDIB | TGL_DE_PORT_AUX_DDIC | @@ -1015,7 +989,7 @@ static u32 gen8_de_port_aux_mask(struct drm_i915_private *dev_priv) TGL_DE_PORT_AUX_USBC2 | TGL_DE_PORT_AUX_USBC3 | TGL_DE_PORT_AUX_USBC4; - else if (DISPLAY_VER(dev_priv) >= 12) + else if (DISPLAY_VER(display) >= 12) return TGL_DE_PORT_AUX_DDIA | TGL_DE_PORT_AUX_DDIB | TGL_DE_PORT_AUX_DDIC | @@ -1027,12 +1001,12 @@ static u32 gen8_de_port_aux_mask(struct drm_i915_private *dev_priv) TGL_DE_PORT_AUX_USBC6; mask = GEN8_AUX_CHANNEL_A; - if (DISPLAY_VER(dev_priv) >= 9) + if (DISPLAY_VER(display) >= 9) mask |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | GEN9_AUX_CHANNEL_D; - if (DISPLAY_VER(dev_priv) == 11) { + if (DISPLAY_VER(display) == 11) { mask |= ICL_AUX_CHANNEL_F; mask |= ICL_AUX_CHANNEL_E; } @@ -1040,10 +1014,8 @@ static u32 gen8_de_port_aux_mask(struct drm_i915_private *dev_priv) return mask; } -static u32 gen8_de_pipe_fault_mask(struct drm_i915_private *dev_priv) +static u32 gen8_de_pipe_fault_mask(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; - if (DISPLAY_VER(display) >= 14) return MTL_PIPEDMC_ATS_FAULT | MTL_PLANE_ATS_FAULT | @@ -1195,15 +1167,14 @@ gen8_pipe_fault_handlers(struct intel_display *display) return bdw_pipe_fault_handlers; } -static void intel_pmdemand_irq_handler(struct drm_i915_private *dev_priv) +static void intel_pmdemand_irq_handler(struct intel_display *display) { - wake_up_all(&dev_priv->display.pmdemand.waitqueue); + wake_up_all(&display->pmdemand.waitqueue); } static void -gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir) +gen8_de_misc_irq_handler(struct intel_display *display, u32 iir) { - struct intel_display *display = &dev_priv->display; bool found = false; if (HAS_DBUF_OVERLAP_DETECTION(display)) { @@ -1213,20 +1184,20 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir) } } - if (DISPLAY_VER(dev_priv) >= 14) { + if (DISPLAY_VER(display) >= 14) { if (iir & (XELPDP_PMDEMAND_RSP | XELPDP_PMDEMAND_RSPTOUT_ERR)) { if (iir & XELPDP_PMDEMAND_RSPTOUT_ERR) - drm_dbg(&dev_priv->drm, + drm_dbg(display->drm, "Error waiting for Punit PM Demand Response\n"); - intel_pmdemand_irq_handler(dev_priv); + intel_pmdemand_irq_handler(display); found = true; } if (iir & XELPDP_RM_TIMEOUT) { u32 val = intel_de_read(display, RM_TIMEOUT_REG_CAPTURE); - drm_warn(&dev_priv->drm, "Register Access Timeout = 0x%x\n", val); + drm_warn(display->drm, "Register Access Timeout = 0x%x\n", val); found = true; } } else if (iir & GEN8_DE_MISC_GSE) { @@ -1239,12 +1210,12 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir) u32 psr_iir; i915_reg_t iir_reg; - for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) { + for_each_intel_encoder_with_psr(display->drm, encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - if (DISPLAY_VER(dev_priv) >= 12) - iir_reg = TRANS_PSR_IIR(dev_priv, - intel_dp->psr.transcoder); + if (DISPLAY_VER(display) >= 12) + iir_reg = TRANS_PSR_IIR(display, + intel_dp->psr.transcoder); else iir_reg = EDP_PSR_IIR; @@ -1256,19 +1227,18 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir) intel_psr_irq_handler(intel_dp, psr_iir); /* prior GEN12 only have one EDP PSR */ - if (DISPLAY_VER(dev_priv) < 12) + if (DISPLAY_VER(display) < 12) break; } } if (!found) - drm_err(&dev_priv->drm, "Unexpected DE Misc interrupt: 0x%08x\n", iir); + drm_err(display->drm, "Unexpected DE Misc interrupt: 0x%08x\n", iir); } -static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, +static void gen11_dsi_te_interrupt_handler(struct intel_display *display, u32 te_trigger) { - struct intel_display *display = &dev_priv->display; enum pipe pipe = INVALID_PIPE; enum transcoder dsi_trans; enum port port; @@ -1278,7 +1248,7 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, * Incase of dual link, TE comes from DSI_1 * this is to check if dual link is enabled */ - val = intel_de_read(display, TRANS_DDI_FUNC_CTL2(dev_priv, TRANSCODER_DSI_0)); + val = intel_de_read(display, TRANS_DDI_FUNC_CTL2(display, TRANSCODER_DSI_0)); val &= PORT_SYNC_MODE_ENABLE; /* @@ -1294,12 +1264,12 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, val = val & OP_MODE_MASK; if (val != CMD_MODE_NO_GATE && val != CMD_MODE_TE_GATE) { - drm_err(&dev_priv->drm, "DSI trancoder not configured in command mode\n"); + drm_err(display->drm, "DSI trancoder not configured in command mode\n"); return; } /* Get PIPE for handling VBLANK event */ - val = intel_de_read(display, TRANS_DDI_FUNC_CTL(dev_priv, dsi_trans)); + val = intel_de_read(display, TRANS_DDI_FUNC_CTL(display, dsi_trans)); switch (val & TRANS_DDI_EDP_INPUT_MASK) { case TRANS_DDI_EDP_INPUT_A_ON: pipe = PIPE_A; @@ -1311,28 +1281,27 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv, pipe = PIPE_C; break; default: - drm_err(&dev_priv->drm, "Invalid PIPE\n"); + drm_err(display->drm, "Invalid PIPE\n"); return; } - intel_handle_vblank(dev_priv, pipe); + intel_handle_vblank(display, pipe); /* clear TE in dsi IIR */ port = (te_trigger & DSI1_TE) ? PORT_B : PORT_A; intel_de_rmw(display, DSI_INTR_IDENT_REG(port), 0, 0); } -static u32 gen8_de_pipe_flip_done_mask(struct drm_i915_private *i915) +static u32 gen8_de_pipe_flip_done_mask(struct intel_display *display) { - if (DISPLAY_VER(i915) >= 9) + if (DISPLAY_VER(display) >= 9) return GEN9_PIPE_PLANE1_FLIP_DONE; else return GEN8_PIPE_PRIMARY_FLIP_DONE; } -static void gen8_read_and_ack_pch_irqs(struct drm_i915_private *i915, u32 *pch_iir, u32 *pica_iir) +static void gen8_read_and_ack_pch_irqs(struct intel_display *display, u32 *pch_iir, u32 *pica_iir) { - struct intel_display *display = &i915->display; u32 pica_ier = 0; *pica_iir = 0; @@ -1346,7 +1315,7 @@ static void gen8_read_and_ack_pch_irqs(struct drm_i915_private *i915, u32 *pch_i * their flags both in the PICA and SDE IIR. */ if (*pch_iir & SDE_PICAINTERRUPT) { - drm_WARN_ON(&i915->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); @@ -1359,32 +1328,31 @@ static void gen8_read_and_ack_pch_irqs(struct drm_i915_private *i915, u32 *pch_i intel_de_write(display, PICAINTERRUPT_IER, pica_ier); } -void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) +void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl) { - struct intel_display *display = &dev_priv->display; u32 iir; enum pipe pipe; - drm_WARN_ON_ONCE(&dev_priv->drm, !HAS_DISPLAY(dev_priv)); + drm_WARN_ON_ONCE(display->drm, !HAS_DISPLAY(display)); if (master_ctl & GEN8_DE_MISC_IRQ) { iir = intel_de_read(display, GEN8_DE_MISC_IIR); if (iir) { intel_de_write(display, GEN8_DE_MISC_IIR, iir); - gen8_de_misc_irq_handler(dev_priv, iir); + gen8_de_misc_irq_handler(display, iir); } else { - drm_err_ratelimited(&dev_priv->drm, + drm_err_ratelimited(display->drm, "The master control interrupt lied (DE MISC)!\n"); } } - if (DISPLAY_VER(dev_priv) >= 11 && (master_ctl & GEN11_DE_HPD_IRQ)) { + if (DISPLAY_VER(display) >= 11 && (master_ctl & GEN11_DE_HPD_IRQ)) { iir = intel_de_read(display, GEN11_DE_HPD_IIR); if (iir) { intel_de_write(display, GEN11_DE_HPD_IIR, iir); - gen11_hpd_irq_handler(dev_priv, iir); + gen11_hpd_irq_handler(display, iir); } else { - drm_err_ratelimited(&dev_priv->drm, + drm_err_ratelimited(display->drm, "The master control interrupt lied, (DE HPD)!\n"); } } @@ -1396,52 +1364,52 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) intel_de_write(display, GEN8_DE_PORT_IIR, iir); - if (iir & gen8_de_port_aux_mask(dev_priv)) { + if (iir & gen8_de_port_aux_mask(display)) { intel_dp_aux_irq_handler(display); found = true; } - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { u32 hotplug_trigger = iir & BXT_DE_PORT_HOTPLUG_MASK; if (hotplug_trigger) { - bxt_hpd_irq_handler(dev_priv, hotplug_trigger); + bxt_hpd_irq_handler(display, hotplug_trigger); found = true; } - } else if (IS_BROADWELL(dev_priv)) { + } else if (display->platform.broadwell) { u32 hotplug_trigger = iir & BDW_DE_PORT_HOTPLUG_MASK; if (hotplug_trigger) { - ilk_hpd_irq_handler(dev_priv, hotplug_trigger); + ilk_hpd_irq_handler(display, hotplug_trigger); found = true; } } - if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) && + if ((display->platform.geminilake || display->platform.broxton) && (iir & BXT_DE_PORT_GMBUS)) { intel_gmbus_irq_handler(display); found = true; } - if (DISPLAY_VER(dev_priv) >= 11) { + if (DISPLAY_VER(display) >= 11) { u32 te_trigger = iir & (DSI0_TE | DSI1_TE); if (te_trigger) { - gen11_dsi_te_interrupt_handler(dev_priv, te_trigger); + gen11_dsi_te_interrupt_handler(display, te_trigger); found = true; } } if (!found) - drm_err_ratelimited(&dev_priv->drm, + drm_err_ratelimited(display->drm, "Unexpected DE Port interrupt\n"); } else { - drm_err_ratelimited(&dev_priv->drm, + drm_err_ratelimited(display->drm, "The master control interrupt lied (DE PORT)!\n"); } } - for_each_pipe(dev_priv, pipe) { + for_each_pipe(display, pipe) { u32 fault_errors; if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe))) @@ -1449,7 +1417,7 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) iir = intel_de_read(display, GEN8_DE_PIPE_IIR(pipe)); if (!iir) { - drm_err_ratelimited(&dev_priv->drm, + drm_err_ratelimited(display->drm, "The master control interrupt lied (DE PIPE)!\n"); continue; } @@ -1457,36 +1425,36 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) intel_de_write(display, GEN8_DE_PIPE_IIR(pipe), iir); if (iir & GEN8_PIPE_VBLANK) - intel_handle_vblank(dev_priv, pipe); + intel_handle_vblank(display, pipe); - if (iir & gen8_de_pipe_flip_done_mask(dev_priv)) - flip_done_handler(dev_priv, pipe); + if (iir & gen8_de_pipe_flip_done_mask(display)) + flip_done_handler(display, pipe); - if (HAS_DSB(dev_priv)) { + if (HAS_DSB(display)) { if (iir & GEN12_DSB_INT(INTEL_DSB_0)) - intel_dsb_irq_handler(&dev_priv->display, pipe, INTEL_DSB_0); + intel_dsb_irq_handler(display, pipe, INTEL_DSB_0); if (iir & GEN12_DSB_INT(INTEL_DSB_1)) - intel_dsb_irq_handler(&dev_priv->display, pipe, INTEL_DSB_1); + intel_dsb_irq_handler(display, pipe, INTEL_DSB_1); if (iir & GEN12_DSB_INT(INTEL_DSB_2)) - intel_dsb_irq_handler(&dev_priv->display, pipe, INTEL_DSB_2); + intel_dsb_irq_handler(display, pipe, INTEL_DSB_2); } if (iir & GEN8_PIPE_CDCLK_CRC_DONE) - hsw_pipe_crc_irq_handler(dev_priv, pipe); + hsw_pipe_crc_irq_handler(display, pipe); if (iir & GEN8_PIPE_FIFO_UNDERRUN) intel_cpu_fifo_underrun_irq_handler(display, pipe); - fault_errors = iir & gen8_de_pipe_fault_mask(dev_priv); + fault_errors = iir & gen8_de_pipe_fault_mask(display); if (fault_errors) intel_pipe_fault_irq_handler(display, gen8_pipe_fault_handlers(display), 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; @@ -1495,31 +1463,30 @@ void gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) * scheme also closed the SDE interrupt handling race we've seen * on older pch-split platforms. But this needs testing. */ - gen8_read_and_ack_pch_irqs(dev_priv, &iir, &pica_iir); + gen8_read_and_ack_pch_irqs(display, &iir, &pica_iir); if (iir) { if (pica_iir) - xelpdp_pica_irq_handler(dev_priv, pica_iir); + xelpdp_pica_irq_handler(display, pica_iir); - if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) - icp_irq_handler(dev_priv, iir); - else if (INTEL_PCH_TYPE(dev_priv) >= PCH_SPT) - spt_irq_handler(dev_priv, iir); + if (INTEL_PCH_TYPE(display) >= PCH_ICP) + icp_irq_handler(display, iir); + else if (INTEL_PCH_TYPE(display) >= PCH_SPT) + spt_irq_handler(display, iir); else - cpt_irq_handler(dev_priv, iir); + cpt_irq_handler(display, iir); } else { /* * Like on previous PCH there seems to be something * fishy going on with forwarding PCH interrupts. */ - drm_dbg(&dev_priv->drm, + drm_dbg(display->drm, "The master control interrupt lied (SDE)!\n"); } } } -u32 gen11_gu_misc_irq_ack(struct drm_i915_private *i915, const u32 master_ctl) +u32 gen11_gu_misc_irq_ack(struct intel_display *display, const u32 master_ctl) { - struct intel_display *display = &i915->display; u32 iir; if (!(master_ctl & GEN11_GU_MISC_IRQ)) @@ -1532,20 +1499,17 @@ u32 gen11_gu_misc_irq_ack(struct drm_i915_private *i915, const u32 master_ctl) return iir; } -void gen11_gu_misc_irq_handler(struct drm_i915_private *i915, const u32 iir) +void gen11_gu_misc_irq_handler(struct intel_display *display, const u32 iir) { - struct intel_display *display = &i915->display; - if (iir & GEN11_GU_MISC_GSE) intel_opregion_asle_intr(display); } -void gen11_display_irq_handler(struct drm_i915_private *i915) +void gen11_display_irq_handler(struct intel_display *display) { - struct intel_display *display = &i915->display; u32 disp_ctl; - disable_rpm_wakeref_asserts(&i915->runtime_pm); + intel_display_rpm_assert_block(display); /* * GEN11_DISPLAY_INT_CTL has same format as GEN8_MASTER_IRQ * for the display related bits. @@ -1553,16 +1517,15 @@ void gen11_display_irq_handler(struct drm_i915_private *i915) disp_ctl = intel_de_read(display, GEN11_DISPLAY_INT_CTL); intel_de_write(display, GEN11_DISPLAY_INT_CTL, 0); - gen8_de_irq_handler(i915, disp_ctl); + gen8_de_irq_handler(display, disp_ctl); intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); - enable_rpm_wakeref_asserts(&i915->runtime_pm); + intel_display_rpm_assert_unblock(display); } -static void i915gm_irq_cstate_wa_enable(struct drm_i915_private *i915) +static void i915gm_irq_cstate_wa_enable(struct intel_display *display) { - struct intel_display *display = &i915->display; - lockdep_assert_held(&i915->drm.vblank_time_lock); + lockdep_assert_held(&display->drm->vblank_time_lock); /* * Vblank/CRC interrupts fail to wake the device up from C2+. @@ -1570,117 +1533,116 @@ static void i915gm_irq_cstate_wa_enable(struct drm_i915_private *i915) * the problem. There is a small power cost so we do this * only when vblank/CRC interrupts are actually enabled. */ - if (i915->display.irq.vblank_enabled++ == 0) + if (display->irq.vblank_enabled++ == 0) intel_de_write(display, SCPD0, _MASKED_BIT_ENABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); } -static void i915gm_irq_cstate_wa_disable(struct drm_i915_private *i915) +static void i915gm_irq_cstate_wa_disable(struct intel_display *display) { - struct intel_display *display = &i915->display; - lockdep_assert_held(&i915->drm.vblank_time_lock); + lockdep_assert_held(&display->drm->vblank_time_lock); - if (--i915->display.irq.vblank_enabled == 0) + if (--display->irq.vblank_enabled == 0) intel_de_write(display, SCPD0, _MASKED_BIT_DISABLE(CSTATE_RENDER_CLOCK_GATE_DISABLE)); } -void i915gm_irq_cstate_wa(struct drm_i915_private *i915, bool enable) +void i915gm_irq_cstate_wa(struct intel_display *display, bool enable) { - spin_lock_irq(&i915->drm.vblank_time_lock); + spin_lock_irq(&display->drm->vblank_time_lock); if (enable) - i915gm_irq_cstate_wa_enable(i915); + i915gm_irq_cstate_wa_enable(display); else - i915gm_irq_cstate_wa_disable(i915); + i915gm_irq_cstate_wa_disable(display); - spin_unlock_irq(&i915->drm.vblank_time_lock); + spin_unlock_irq(&display->drm->vblank_time_lock); } int i8xx_enable_vblank(struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->dev); + struct intel_display *display = to_intel_display(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - i915_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_STATUS); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_lock_irqsave(&display->irq.lock, irqflags); + i915_enable_pipestat(display, pipe, PIPE_VBLANK_INTERRUPT_STATUS); + spin_unlock_irqrestore(&display->irq.lock, irqflags); return 0; } void i8xx_disable_vblank(struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->dev); + struct intel_display *display = to_intel_display(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - i915_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_STATUS); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_lock_irqsave(&display->irq.lock, irqflags); + i915_disable_pipestat(display, pipe, PIPE_VBLANK_INTERRUPT_STATUS); + spin_unlock_irqrestore(&display->irq.lock, irqflags); } int i915gm_enable_vblank(struct drm_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(crtc->dev); + struct intel_display *display = to_intel_display(crtc->dev); - i915gm_irq_cstate_wa_enable(i915); + i915gm_irq_cstate_wa_enable(display); return i8xx_enable_vblank(crtc); } void i915gm_disable_vblank(struct drm_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(crtc->dev); + struct intel_display *display = to_intel_display(crtc->dev); i8xx_disable_vblank(crtc); - i915gm_irq_cstate_wa_disable(i915); + i915gm_irq_cstate_wa_disable(display); } int i965_enable_vblank(struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->dev); + struct intel_display *display = to_intel_display(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - i915_enable_pipestat(dev_priv, pipe, + 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; } void i965_disable_vblank(struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->dev); + struct intel_display *display = to_intel_display(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - i915_disable_pipestat(dev_priv, pipe, + 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 drm_i915_private *dev_priv = to_i915(crtc->dev); + struct intel_display *display = to_intel_display(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; - u32 bit = DISPLAY_VER(dev_priv) >= 7 ? + u32 bit = DISPLAY_VER(display) >= 7 ? DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe); - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - ilk_enable_display_irq(dev_priv, bit); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_lock_irqsave(&display->irq.lock, irqflags); + ilk_enable_display_irq(display, bit); + 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. */ - if (HAS_PSR(dev_priv)) + if (HAS_PSR(display)) drm_crtc_vblank_restore(crtc); return 0; @@ -1688,15 +1650,15 @@ int ilk_enable_vblank(struct drm_crtc *crtc) void ilk_disable_vblank(struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->dev); + struct intel_display *display = to_intel_display(crtc->dev); enum pipe pipe = to_intel_crtc(crtc)->pipe; unsigned long irqflags; - u32 bit = DISPLAY_VER(dev_priv) >= 7 ? + u32 bit = DISPLAY_VER(display) >= 7 ? DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe); - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - ilk_disable_display_irq(dev_priv, bit); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_lock_irqsave(&display->irq.lock, irqflags); + ilk_disable_display_irq(display, bit); + spin_unlock_irqrestore(&display->irq.lock, irqflags); } static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc, @@ -1722,44 +1684,36 @@ 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); - bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_lock_irqsave(&display->irq.lock, irqflags); + bdw_enable_pipe_irq(display, pipe, GEN8_PIPE_VBLANK); + 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. */ - if (HAS_PSR(dev_priv)) + if (HAS_PSR(display)) drm_crtc_vblank_restore(&crtc->base); return 0; @@ -1769,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); - bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + spin_lock_irqsave(&display->irq.lock, irqflags); + bdw_disable_pipe_irq(display, pipe, GEN8_PIPE_VBLANK); + 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) @@ -1892,11 +1845,11 @@ void vlv_display_error_irq_handler(struct intel_display *display, vlv_page_table_error_irq_handler(display, dpinvgtt); } -static void _vlv_display_irq_reset(struct drm_i915_private *dev_priv) +static void _vlv_display_irq_reset(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); - if (IS_CHERRYVIEW(dev_priv)) + if (display->platform.cherryview) intel_de_write(display, DPINVGTT, DPINVGTT_STATUS_MASK_CHV); else intel_de_write(display, DPINVGTT, DPINVGTT_STATUS_MASK_VLV); @@ -1904,31 +1857,60 @@ static void _vlv_display_irq_reset(struct drm_i915_private *dev_priv) gen2_error_reset(to_intel_uncore(display->drm), VLV_ERROR_REGS); - i915_hotplug_interrupt_update_locked(dev_priv, 0xffffffff, 0); - intel_de_rmw(display, PORT_HOTPLUG_STAT(dev_priv), 0, 0); + i915_hotplug_interrupt_update_locked(display, 0xffffffff, 0); + intel_de_rmw(display, PORT_HOTPLUG_STAT(display), 0, 0); - i9xx_pipestat_irq_reset(dev_priv); + i9xx_pipestat_irq_reset(display); intel_display_irq_regs_reset(display, VLV_IRQ_REGS); dev_priv->irq_mask = ~0u; } -void vlv_display_irq_reset(struct drm_i915_private *dev_priv) +void vlv_display_irq_reset(struct intel_display *display) { - if (dev_priv->display.irq.vlv_display_irqs_enabled) - _vlv_display_irq_reset(dev_priv); + 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 drm_i915_private *i915) +void i9xx_display_irq_reset(struct intel_display *display) { - struct intel_display *display = &i915->display; - - if (I915_HAS_HOTPLUG(i915)) { - i915_hotplug_interrupt_update(i915, 0xffffffff, 0); - intel_de_rmw(display, PORT_HOTPLUG_STAT(i915), 0, 0); + if (HAS_HOTPLUG(display)) { + i915_hotplug_interrupt_update(display, 0xffffffff, 0); + intel_de_rmw(display, PORT_HOTPLUG_STAT(display), 0, 0); } - i9xx_pipestat_irq_reset(i915); + 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) @@ -1937,17 +1919,14 @@ static u32 vlv_error_mask(void) return VLV_ERROR_PAGE_TABLE; } -void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) +static void _vlv_display_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 pipestat_mask; u32 enable_mask; enum pipe pipe; - if (!dev_priv->display.irq.vlv_display_irqs_enabled) - return; - - if (IS_CHERRYVIEW(dev_priv)) + if (display->platform.cherryview) intel_de_write(display, DPINVGTT, DPINVGTT_STATUS_MASK_CHV | DPINVGTT_EN_MASK_CHV); @@ -1961,9 +1940,9 @@ void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) pipestat_mask = PIPE_CRC_DONE_INTERRUPT_STATUS; - i915_enable_pipestat(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); - for_each_pipe(dev_priv, pipe) - i915_enable_pipestat(dev_priv, pipe, pipestat_mask); + i915_enable_pipestat(display, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); + for_each_pipe(display, pipe) + i915_enable_pipestat(display, pipe, pipestat_mask); enable_mask = I915_DISPLAY_PORT_INTERRUPT | I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | @@ -1972,53 +1951,76 @@ void vlv_display_irq_postinstall(struct drm_i915_private *dev_priv) I915_LPE_PIPE_B_INTERRUPT | I915_MASTER_ERROR_INTERRUPT; - if (IS_CHERRYVIEW(dev_priv)) + if (display->platform.cherryview) enable_mask |= I915_DISPLAY_PIPE_C_EVENT_INTERRUPT | I915_LPE_PIPE_C_INTERRUPT; - drm_WARN_ON(&dev_priv->drm, dev_priv->irq_mask != ~0u); + drm_WARN_ON(display->drm, dev_priv->irq_mask != ~0u); dev_priv->irq_mask = ~enable_mask; intel_display_irq_regs_init(display, VLV_IRQ_REGS, dev_priv->irq_mask, enable_mask); } -void gen8_display_irq_reset(struct drm_i915_private *dev_priv) +void vlv_display_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &dev_priv->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(dev_priv)) + if (!HAS_DISPLAY(display)) return; intel_de_write(display, EDP_PSR_IMR, 0xffffffff); intel_de_write(display, EDP_PSR_IIR, 0xffffffff); - for_each_pipe(dev_priv, pipe) + for_each_pipe(display, pipe) if (intel_display_power_is_enabled(display, POWER_DOMAIN_PIPE(pipe))) intel_display_irq_regs_reset(display, GEN8_DE_PIPE_IRQ_REGS(pipe)); 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 drm_i915_private *dev_priv) +void gen11_display_irq_reset(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; enum pipe pipe; u32 trans_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C) | BIT(TRANSCODER_D); - if (!HAS_DISPLAY(dev_priv)) + if (!HAS_DISPLAY(display)) return; intel_de_write(display, GEN11_DISPLAY_INT_CTL, 0); - if (DISPLAY_VER(dev_priv) >= 12) { + if (DISPLAY_VER(display) >= 12) { enum transcoder trans; - for_each_cpu_transcoder_masked(dev_priv, trans, trans_mask) { + for_each_cpu_transcoder_masked(display, trans, trans_mask) { enum intel_display_power_domain domain; domain = POWER_DOMAIN_TRANSCODER(trans); @@ -2026,10 +2028,10 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv) continue; intel_de_write(display, - TRANS_PSR_IMR(dev_priv, trans), + TRANS_PSR_IMR(display, trans), 0xffffffff); intel_de_write(display, - TRANS_PSR_IIR(dev_priv, trans), + TRANS_PSR_IIR(display, trans), 0xffffffff); } } else { @@ -2037,7 +2039,7 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv) intel_de_write(display, EDP_PSR_IIR, 0xffffffff); } - for_each_pipe(dev_priv, pipe) + for_each_pipe(display, pipe) if (intel_display_power_is_enabled(display, POWER_DOMAIN_PIPE(pipe))) intel_display_irq_regs_reset(display, GEN8_DE_PIPE_IRQ_REGS(pipe)); @@ -2045,55 +2047,55 @@ void gen11_display_irq_reset(struct drm_i915_private *dev_priv) intel_display_irq_regs_reset(display, GEN8_DE_PORT_IRQ_REGS); intel_display_irq_regs_reset(display, GEN8_DE_MISC_IRQ_REGS); - if (DISPLAY_VER(dev_priv) >= 14) + if (DISPLAY_VER(display) >= 14) intel_display_irq_regs_reset(display, PICAINTERRUPT_IRQ_REGS); 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); } -void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, +void gen8_irq_power_well_post_enable(struct intel_display *display, u8 pipe_mask) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN | - gen8_de_pipe_flip_done_mask(dev_priv); + 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; } - for_each_pipe_masked(dev_priv, pipe, pipe_mask) + for_each_pipe_masked(display, pipe, pipe_mask) intel_display_irq_regs_init(display, GEN8_DE_PIPE_IRQ_REGS(pipe), - dev_priv->display.irq.de_irq_mask[pipe], - ~dev_priv->display.irq.de_irq_mask[pipe] | extra_ier); + 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 drm_i915_private *dev_priv, +void gen8_irq_power_well_pre_disable(struct intel_display *display, u8 pipe_mask) { - struct intel_display *display = &dev_priv->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(dev_priv, pipe, pipe_mask) + 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); @@ -2110,17 +2112,16 @@ void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, * to avoid races with the irq handler, assuming we have MSI. Shared legacy * interrupts could still race. */ -static void ibx_irq_postinstall(struct drm_i915_private *dev_priv) +static void ibx_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; 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; @@ -2128,40 +2129,50 @@ static void ibx_irq_postinstall(struct drm_i915_private *dev_priv) intel_display_irq_regs_init(display, SDE_IRQ_REGS, ~mask, 0xffffffff); } -void valleyview_enable_display_irqs(struct drm_i915_private *dev_priv) +void valleyview_enable_display_irqs(struct intel_display *display) { - lockdep_assert_held(&dev_priv->irq_lock); + struct drm_i915_private *dev_priv = to_i915(display->drm); - if (dev_priv->display.irq.vlv_display_irqs_enabled) - return; + spin_lock_irq(&display->irq.lock); + + if (display->irq.vlv_display_irqs_enabled) + goto out; - dev_priv->display.irq.vlv_display_irqs_enabled = true; + display->irq.vlv_display_irqs_enabled = true; if (intel_irqs_enabled(dev_priv)) { - _vlv_display_irq_reset(dev_priv); - vlv_display_irq_postinstall(dev_priv); + _vlv_display_irq_reset(display); + _vlv_display_irq_postinstall(display); } + +out: + spin_unlock_irq(&display->irq.lock); } -void valleyview_disable_display_irqs(struct drm_i915_private *dev_priv) +void valleyview_disable_display_irqs(struct intel_display *display) { - lockdep_assert_held(&dev_priv->irq_lock); + struct drm_i915_private *dev_priv = to_i915(display->drm); - if (!dev_priv->display.irq.vlv_display_irqs_enabled) - return; + spin_lock_irq(&display->irq.lock); + + if (!display->irq.vlv_display_irqs_enabled) + goto out; - dev_priv->display.irq.vlv_display_irqs_enabled = false; + display->irq.vlv_display_irqs_enabled = false; if (intel_irqs_enabled(dev_priv)) - _vlv_display_irq_reset(dev_priv); + _vlv_display_irq_reset(display); +out: + spin_unlock_irq(&display->irq.lock); } -void ilk_de_irq_postinstall(struct drm_i915_private *i915) +void ilk_de_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &i915->display; + struct drm_i915_private *i915 = to_i915(display->drm); + u32 display_mask, extra_mask; - if (DISPLAY_VER(i915) >= 7) { + if (DISPLAY_VER(display) >= 7) { display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | DE_PCH_EVENT_IVB | DE_AUX_CHANNEL_A_IVB); extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB | @@ -2182,59 +2193,57 @@ void ilk_de_irq_postinstall(struct drm_i915_private *i915) DE_DP_A_HOTPLUG); } - if (IS_HASWELL(i915)) { + if (display->platform.haswell) { intel_display_irq_regs_assert_irr_is_zero(display, EDP_PSR_IIR); display_mask |= DE_EDP_PSR_INT_HSW; } - if (IS_IRONLAKE_M(i915)) + if (display->platform.ironlake && display->platform.mobile) extra_mask |= DE_PCU_EVENT; i915->irq_mask = ~display_mask; - ibx_irq_postinstall(i915); + ibx_irq_postinstall(display); intel_display_irq_regs_init(display, DE_IRQ_REGS, i915->irq_mask, display_mask | extra_mask); } -static void mtp_irq_postinstall(struct drm_i915_private *i915); -static void icp_irq_postinstall(struct drm_i915_private *i915); +static void mtp_irq_postinstall(struct intel_display *display); +static void icp_irq_postinstall(struct intel_display *display); -void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) +void gen8_de_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; - - u32 de_pipe_masked = gen8_de_pipe_fault_mask(dev_priv) | + u32 de_pipe_masked = gen8_de_pipe_fault_mask(display) | GEN8_PIPE_CDCLK_CRC_DONE; u32 de_pipe_enables; - u32 de_port_masked = gen8_de_port_aux_mask(dev_priv); + u32 de_port_masked = gen8_de_port_aux_mask(display); u32 de_port_enables; u32 de_misc_masked = GEN8_DE_EDP_PSR; u32 trans_mask = BIT(TRANSCODER_A) | BIT(TRANSCODER_B) | BIT(TRANSCODER_C) | BIT(TRANSCODER_D); enum pipe pipe; - if (!HAS_DISPLAY(dev_priv)) + if (!HAS_DISPLAY(display)) return; - if (DISPLAY_VER(dev_priv) >= 14) - mtp_irq_postinstall(dev_priv); - else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) - icp_irq_postinstall(dev_priv); - else if (HAS_PCH_SPLIT(dev_priv)) - ibx_irq_postinstall(dev_priv); + if (DISPLAY_VER(display) >= 14) + mtp_irq_postinstall(display); + else if (INTEL_PCH_TYPE(display) >= PCH_ICP) + icp_irq_postinstall(display); + else if (HAS_PCH_SPLIT(display)) + ibx_irq_postinstall(display); - if (DISPLAY_VER(dev_priv) < 11) + if (DISPLAY_VER(display) < 11) de_misc_masked |= GEN8_DE_MISC_GSE; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) de_port_masked |= BXT_DE_PORT_GMBUS; - if (DISPLAY_VER(dev_priv) >= 14) { + if (DISPLAY_VER(display) >= 14) { de_misc_masked |= XELPDP_PMDEMAND_RSPTOUT_ERR | XELPDP_PMDEMAND_RSP | XELPDP_RM_TIMEOUT; - } else if (DISPLAY_VER(dev_priv) >= 11) { + } else if (DISPLAY_VER(display) >= 11) { enum port port; if (intel_bios_is_dsi_present(display, &port)) @@ -2244,25 +2253,25 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) if (HAS_DBUF_OVERLAP_DETECTION(display)) de_misc_masked |= XE2LPD_DBUF_OVERLAP_DETECTED; - if (HAS_DSB(dev_priv)) + if (HAS_DSB(display)) de_pipe_masked |= GEN12_DSB_INT(INTEL_DSB_0) | GEN12_DSB_INT(INTEL_DSB_1) | GEN12_DSB_INT(INTEL_DSB_2); de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN | - gen8_de_pipe_flip_done_mask(dev_priv); + gen8_de_pipe_flip_done_mask(display); de_port_enables = de_port_masked; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) de_port_enables |= BXT_DE_PORT_HOTPLUG_MASK; - else if (IS_BROADWELL(dev_priv)) + else if (display->platform.broadwell) de_port_enables |= BDW_DE_PORT_HOTPLUG_MASK; - if (DISPLAY_VER(dev_priv) >= 12) { + if (DISPLAY_VER(display) >= 12) { enum transcoder trans; - for_each_cpu_transcoder_masked(dev_priv, trans, trans_mask) { + for_each_cpu_transcoder_masked(display, trans, trans_mask) { enum intel_display_power_domain domain; domain = POWER_DOMAIN_TRANSCODER(trans); @@ -2270,19 +2279,19 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) continue; intel_display_irq_regs_assert_irr_is_zero(display, - TRANS_PSR_IIR(dev_priv, trans)); + TRANS_PSR_IIR(display, trans)); } } else { intel_display_irq_regs_assert_irr_is_zero(display, EDP_PSR_IIR); } - for_each_pipe(dev_priv, pipe) { - dev_priv->display.irq.de_irq_mask[pipe] = ~de_pipe_masked; + for_each_pipe(display, pipe) { + display->irq.de_irq_mask[pipe] = ~de_pipe_masked; if (intel_display_power_is_enabled(display, POWER_DOMAIN_PIPE(pipe))) intel_display_irq_regs_init(display, GEN8_DE_PIPE_IRQ_REGS(pipe), - dev_priv->display.irq.de_irq_mask[pipe], + display->irq.de_irq_mask[pipe], de_pipe_enables); } @@ -2291,7 +2300,7 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) intel_display_irq_regs_init(display, GEN8_DE_MISC_IRQ_REGS, ~de_misc_masked, de_misc_masked); - if (IS_DISPLAY_VER(dev_priv, 11, 13)) { + if (IS_DISPLAY_VER(display, 11, 13)) { u32 de_hpd_masked = 0; u32 de_hpd_enables = GEN11_DE_TC_HOTPLUG_MASK | GEN11_DE_TBT_HOTPLUG_MASK; @@ -2301,9 +2310,8 @@ void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) } } -static void mtp_irq_postinstall(struct drm_i915_private *i915) +static void mtp_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &i915->display; u32 sde_mask = SDE_GMBUS_ICP | SDE_PICAINTERRUPT; u32 de_hpd_mask = XELPDP_AUX_TC_MASK; u32 de_hpd_enables = de_hpd_mask | XELPDP_DP_ALT_HOTPLUG_MASK | @@ -2315,43 +2323,68 @@ static void mtp_irq_postinstall(struct drm_i915_private *i915) intel_display_irq_regs_init(display, SDE_IRQ_REGS, ~sde_mask, 0xffffffff); } -static void icp_irq_postinstall(struct drm_i915_private *dev_priv) +static void icp_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; u32 mask = SDE_GMBUS_ICP; intel_display_irq_regs_init(display, SDE_IRQ_REGS, ~mask, 0xffffffff); } -void gen11_de_irq_postinstall(struct drm_i915_private *dev_priv) +void gen11_de_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; - - if (!HAS_DISPLAY(dev_priv)) + if (!HAS_DISPLAY(display)) return; - gen8_de_irq_postinstall(dev_priv); + gen8_de_irq_postinstall(display); intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); } -void dg1_de_irq_postinstall(struct drm_i915_private *i915) +void dg1_de_irq_postinstall(struct intel_display *display) { - struct intel_display *display = &i915->display; - - if (!HAS_DISPLAY(i915)) + if (!HAS_DISPLAY(display)) return; - gen8_de_irq_postinstall(i915); + gen8_de_irq_postinstall(display); intel_de_write(display, GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); } -void intel_display_irq_init(struct drm_i915_private *i915) +void intel_display_irq_init(struct intel_display *display) { - i915->drm.vblank_disable_immediate = true; + spin_lock_init(&display->irq.lock); - intel_hotplug_irq_init(i915); + display->drm->vblank_disable_immediate = true; + + intel_hotplug_irq_init(display); + + 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; - INIT_WORK(&i915->display.irq.vblank_dc_work, - intel_display_vblank_dc_work); + 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 d9867cd0a220..c66db3851da4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.h +++ b/drivers/gpu/drm/i915/display/intel_display_irq.h @@ -12,28 +12,29 @@ enum pipe; struct drm_crtc; -struct drm_i915_private; +struct drm_printer; struct intel_display; +struct intel_display_irq_snapshot; -void valleyview_enable_display_irqs(struct drm_i915_private *i915); -void valleyview_disable_display_irqs(struct drm_i915_private *i915); +void valleyview_enable_display_irqs(struct intel_display *display); +void valleyview_disable_display_irqs(struct intel_display *display); -void ilk_update_display_irq(struct drm_i915_private *i915, +void ilk_update_display_irq(struct intel_display *display, u32 interrupt_mask, u32 enabled_irq_mask); -void ilk_enable_display_irq(struct drm_i915_private *i915, u32 bits); -void ilk_disable_display_irq(struct drm_i915_private *i915, u32 bits); +void ilk_enable_display_irq(struct intel_display *display, u32 bits); +void ilk_disable_display_irq(struct intel_display *display, u32 bits); -void bdw_update_port_irq(struct drm_i915_private *i915, u32 interrupt_mask, u32 enabled_irq_mask); -void bdw_enable_pipe_irq(struct drm_i915_private *i915, enum pipe pipe, u32 bits); -void bdw_disable_pipe_irq(struct drm_i915_private *i915, enum pipe pipe, u32 bits); +void bdw_update_port_irq(struct intel_display *display, u32 interrupt_mask, u32 enabled_irq_mask); +void bdw_enable_pipe_irq(struct intel_display *display, enum pipe pipe, u32 bits); +void bdw_disable_pipe_irq(struct intel_display *display, enum pipe pipe, u32 bits); -void ibx_display_interrupt_update(struct drm_i915_private *i915, +void ibx_display_interrupt_update(struct intel_display *display, u32 interrupt_mask, u32 enabled_irq_mask); -void ibx_enable_display_interrupt(struct drm_i915_private *i915, u32 bits); -void ibx_disable_display_interrupt(struct drm_i915_private *i915, u32 bits); +void ibx_enable_display_interrupt(struct intel_display *display, u32 bits); +void ibx_disable_display_interrupt(struct intel_display *display, u32 bits); -void gen8_irq_power_well_post_enable(struct drm_i915_private *i915, u8 pipe_mask); -void gen8_irq_power_well_pre_disable(struct drm_i915_private *i915, u8 pipe_mask); +void gen8_irq_power_well_post_enable(struct intel_display *display, u8 pipe_mask); +void gen8_irq_power_well_pre_disable(struct intel_display *display, u8 pipe_mask); int i8xx_enable_vblank(struct drm_crtc *crtc); int i915gm_enable_vblank(struct drm_crtc *crtc); @@ -46,41 +47,46 @@ void i965_disable_vblank(struct drm_crtc *crtc); void ilk_disable_vblank(struct drm_crtc *crtc); void bdw_disable_vblank(struct drm_crtc *crtc); -void ivb_display_irq_handler(struct drm_i915_private *i915, u32 de_iir); -void ilk_display_irq_handler(struct drm_i915_private *i915, u32 de_iir); -void gen8_de_irq_handler(struct drm_i915_private *i915, u32 master_ctl); -void gen11_display_irq_handler(struct drm_i915_private *i915); +void ivb_display_irq_handler(struct intel_display *display, u32 de_iir); +void ilk_display_irq_handler(struct intel_display *display, u32 de_iir); +void gen8_de_irq_handler(struct intel_display *display, u32 master_ctl); +void gen11_display_irq_handler(struct intel_display *display); -u32 gen11_gu_misc_irq_ack(struct drm_i915_private *i915, const u32 master_ctl); -void gen11_gu_misc_irq_handler(struct drm_i915_private *i915, const u32 iir); +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 drm_i915_private *i915); -void vlv_display_irq_reset(struct drm_i915_private *i915); -void gen8_display_irq_reset(struct drm_i915_private *i915); -void gen11_display_irq_reset(struct drm_i915_private *i915); +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 vlv_display_irq_postinstall(struct drm_i915_private *i915); -void ilk_de_irq_postinstall(struct drm_i915_private *i915); -void gen8_de_irq_postinstall(struct drm_i915_private *i915); -void gen11_de_irq_postinstall(struct drm_i915_private *i915); -void dg1_de_irq_postinstall(struct drm_i915_private *i915); +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); +void gen11_de_irq_postinstall(struct intel_display *display); +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 drm_i915_private *i915, enum pipe pipe, u32 status_mask); -void i915_disable_pipestat(struct drm_i915_private *i915, enum pipe pipe, u32 status_mask); -void i915_enable_asle_pipestat(struct drm_i915_private *i915); +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 i9xx_pipestat_irq_ack(struct drm_i915_private *i915, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); +void i9xx_pipestat_irq_ack(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); -void i915_pipestat_irq_handler(struct drm_i915_private *i915, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); -void i965_pipestat_irq_handler(struct drm_i915_private *i915, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); -void valleyview_pipestat_irq_handler(struct drm_i915_private *i915, u32 pipe_stats[I915_MAX_PIPES]); +void i915_pipestat_irq_handler(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); +void i965_pipestat_irq_handler(struct intel_display *display, u32 iir, u32 pipe_stats[I915_MAX_PIPES]); +void valleyview_pipestat_irq_handler(struct intel_display *display, u32 pipe_stats[I915_MAX_PIPES]); void vlv_display_error_irq_ack(struct intel_display *display, u32 *eir, u32 *dpinvgtt); void vlv_display_error_irq_handler(struct intel_display *display, u32 eir, u32 dpinvgtt); -void intel_display_irq_init(struct drm_i915_private *i915); +void intel_display_irq_init(struct intel_display *display); -void i915gm_irq_cstate_wa(struct drm_i915_private *i915, bool enable); +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 f7171e6932dc..16356523816f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -16,6 +16,7 @@ #include "intel_display_power.h" #include "intel_display_power_map.h" #include "intel_display_power_well.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dmc.h" #include "intel_mchbar_regs.h" @@ -204,7 +205,7 @@ static bool __intel_display_power_is_enabled(struct intel_display *display, struct i915_power_well *power_well; bool is_enabled; - if (pm_runtime_suspended(display->drm->dev)) + if (intel_display_rpm_suspended(display)) return false; is_enabled = true; @@ -322,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) { @@ -455,7 +485,6 @@ static bool intel_display_power_grab_async_put_ref(struct intel_display *display, enum intel_display_power_domain domain) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; struct intel_power_domain_mask async_put_mask; bool ret = false; @@ -473,8 +502,8 @@ intel_display_power_grab_async_put_ref(struct intel_display *display, goto out_verify; cancel_async_put_work(power_domains, false); - intel_runtime_pm_put_raw(&dev_priv->runtime_pm, - fetch_and_zero(&power_domains->async_put_wakeref)); + intel_display_rpm_put_raw(display, + fetch_and_zero(&power_domains->async_put_wakeref)); out_verify: verify_async_put_domains_state(power_domains); @@ -512,9 +541,10 @@ __intel_display_power_get_domain(struct intel_display *display, intel_wakeref_t intel_display_power_get(struct intel_display *display, enum intel_display_power_domain domain) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; - intel_wakeref_t wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + struct ref_tracker *wakeref; + + wakeref = intel_display_rpm_get(display); mutex_lock(&power_domains->lock); __intel_display_power_get_domain(display, domain); @@ -539,12 +569,11 @@ intel_wakeref_t intel_display_power_get_if_enabled(struct intel_display *display, enum intel_display_power_domain domain) { - struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; bool is_enabled; - wakeref = intel_runtime_pm_get_if_in_use(&dev_priv->runtime_pm); + wakeref = intel_display_rpm_get_if_in_use(display); if (!wakeref) return NULL; @@ -560,7 +589,7 @@ intel_display_power_get_if_enabled(struct intel_display *display, mutex_unlock(&power_domains->lock); if (!is_enabled) { - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); wakeref = NULL; } @@ -623,12 +652,10 @@ release_async_put_domains(struct i915_power_domains *power_domains, struct intel_display *display = container_of(power_domains, struct intel_display, power.domains); - struct drm_i915_private *dev_priv = to_i915(display->drm); - struct intel_runtime_pm *rpm = &dev_priv->runtime_pm; enum intel_display_power_domain domain; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; - wakeref = intel_runtime_pm_get_noresume(rpm); + wakeref = intel_display_rpm_get_noresume(display); for_each_power_domain(domain, mask) { /* Clear before put, so put's sanity check is happy. */ @@ -636,7 +663,7 @@ release_async_put_domains(struct i915_power_domains *power_domains, __intel_display_power_put_domain(display, domain); } - intel_runtime_pm_put(rpm, wakeref); + intel_display_rpm_put(display, wakeref); } static void @@ -644,11 +671,10 @@ intel_display_power_put_async_work(struct work_struct *work) { struct intel_display *display = container_of(work, struct intel_display, power.domains.async_put_work.work); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; - struct intel_runtime_pm *rpm = &dev_priv->runtime_pm; - intel_wakeref_t new_work_wakeref = intel_runtime_pm_get_raw(rpm); - intel_wakeref_t old_work_wakeref = NULL; + struct ref_tracker *new_work_wakeref, *old_work_wakeref = NULL; + + new_work_wakeref = intel_display_rpm_get_raw(display); mutex_lock(&power_domains->lock); @@ -688,9 +714,9 @@ out_verify: mutex_unlock(&power_domains->lock); if (old_work_wakeref) - intel_runtime_pm_put_raw(rpm, old_work_wakeref); + intel_display_rpm_put_raw(display, old_work_wakeref); if (new_work_wakeref) - intel_runtime_pm_put_raw(rpm, new_work_wakeref); + intel_display_rpm_put_raw(display, new_work_wakeref); } /** @@ -711,10 +737,10 @@ void __intel_display_power_put_async(struct intel_display *display, intel_wakeref_t wakeref, int delay_ms) { - struct drm_i915_private *i915 = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; - struct intel_runtime_pm *rpm = &i915->runtime_pm; - intel_wakeref_t work_wakeref = intel_runtime_pm_get_raw(rpm); + struct ref_tracker *work_wakeref; + + work_wakeref = intel_display_rpm_get_raw(display); delay_ms = delay_ms >= 0 ? delay_ms : 100; @@ -746,9 +772,9 @@ out_verify: mutex_unlock(&power_domains->lock); if (work_wakeref) - intel_runtime_pm_put_raw(rpm, work_wakeref); + intel_display_rpm_put_raw(display, work_wakeref); - intel_runtime_pm_put(rpm, wakeref); + intel_display_rpm_put(display, wakeref); } /** @@ -765,7 +791,6 @@ out_verify: */ void intel_display_power_flush_work(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); struct i915_power_domains *power_domains = &display->power.domains; struct intel_power_domain_mask async_put_mask; intel_wakeref_t work_wakeref; @@ -786,7 +811,7 @@ out_verify: mutex_unlock(&power_domains->lock); if (work_wakeref) - intel_runtime_pm_put_raw(&i915->runtime_pm, work_wakeref); + intel_display_rpm_put_raw(display, work_wakeref); } /** @@ -824,10 +849,8 @@ void intel_display_power_put(struct intel_display *display, enum intel_display_power_domain domain, intel_wakeref_t wakeref) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - __intel_display_power_put(display, domain); - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); } #else /** @@ -846,10 +869,8 @@ void intel_display_power_put(struct intel_display *display, void intel_display_power_put_unchecked(struct intel_display *display, enum intel_display_power_domain domain) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - __intel_display_power_put(display, domain); - intel_runtime_pm_put_unchecked(&dev_priv->runtime_pm); + intel_display_rpm_put_unchecked(display); } #endif @@ -1373,26 +1394,24 @@ 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); - lpt_disable_clkout_dp(dev_priv); + lpt_disable_clkout_dp(display); hsw_disable_lcpll(display, true, true); } static void hsw_disable_pc8(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); + struct drm_i915_private __maybe_unused *dev_priv = to_i915(display->drm); drm_dbg_kms(display->drm, "Disabling package C8+\n"); hsw_restore_lcpll(display); - intel_init_pch_refclk(dev_priv); + intel_init_pch_refclk(display); /* Many display registers don't survive PC8+ */ #ifdef I915 /* FIXME */ @@ -1423,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; @@ -1632,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; @@ -1916,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; @@ -1940,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)); } /* @@ -1979,7 +1995,6 @@ void intel_power_domains_init_hw(struct intel_display *display, bool resume) */ void intel_power_domains_driver_remove(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); intel_wakeref_t wakeref __maybe_unused = fetch_and_zero(&display->power.domains.init_wakeref); @@ -1993,7 +2008,7 @@ void intel_power_domains_driver_remove(struct intel_display *display) intel_power_domains_verify_state(display); /* Keep the power well enabled, but cancel its rpm wakeref. */ - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); } /** @@ -2238,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 || @@ -2250,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); @@ -2267,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_map.c b/drivers/gpu/drm/i915/display/intel_display_power_map.c index e80e1fd611ca..ab1163744bc5 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_map.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_map.c @@ -1696,6 +1696,7 @@ I915_DECL_PW_DOMAINS(xe3lpd_pwdoms_dc_off, XE3LPD_PW_C_POWER_DOMAINS, XE3LPD_PW_D_POWER_DOMAINS, POWER_DOMAIN_AUDIO_MMIO, + POWER_DOMAIN_AUDIO_PLAYBACK, POWER_DOMAIN_INIT); static const struct i915_power_well_desc xe3lpd_power_wells_dcoff[] = { 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 8ec87ffd87d2..b104bce0e14d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -13,6 +13,7 @@ #include "intel_de.h" #include "intel_display_irq.h" #include "intel_display_power_well.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dkl_phy.h" #include "intel_dkl_phy_regs.h" @@ -24,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" @@ -186,22 +188,18 @@ int intel_power_well_refcount(struct i915_power_well *power_well) static void hsw_power_well_post_enable(struct intel_display *display, u8 irq_pipe_mask, bool has_vga) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (has_vga) intel_vga_reset_io_mem(display); if (irq_pipe_mask) - gen8_irq_power_well_post_enable(dev_priv, irq_pipe_mask); + gen8_irq_power_well_post_enable(display, irq_pipe_mask); } static void hsw_power_well_pre_disable(struct intel_display *display, u8 irq_pipe_mask) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (irq_pipe_mask) - gen8_irq_power_well_pre_disable(dev_priv, irq_pipe_mask); + gen8_irq_power_well_pre_disable(display, irq_pipe_mask); } #define ICL_AUX_PW_TO_PHY(pw_idx) \ @@ -752,8 +750,9 @@ void gen9_sanitize_dc_state(struct intel_display *display) void gen9_set_dc_state(struct intel_display *display, u32 state) { struct i915_power_domains *power_domains = &display->power.domains; - u32 val; + bool dc6_was_enabled, enable_dc6; u32 mask; + u32 val; if (!HAS_DISPLAY(display)) return; @@ -762,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", @@ -772,11 +774,19 @@ void gen9_set_dc_state(struct intel_display *display, u32 state) drm_err(display->drm, "DC state mismatch (0x%x -> 0x%x)\n", power_domains->dc_state, val & mask); + enable_dc6 = state & DC_STATE_EN_UPTO_DC6; + dc6_was_enabled = val & DC_STATE_EN_UPTO_DC6; + if (!dc6_was_enabled && enable_dc6) + intel_dmc_update_dc6_allowed_count(display, true); + val &= ~mask; val |= state; gen9_write_dc_state(display, val); + if (!enable_dc6 && dc6_was_enabled) + intel_dmc_update_dc6_allowed_count(display, false); + power_domains->dc_state = val & mask; } @@ -816,7 +826,8 @@ static void assert_can_enable_dc5(struct intel_display *display) (intel_de_read(display, DC_STATE_EN) & DC_STATE_EN_UPTO_DC5), "DC5 already programmed to be enabled.\n"); - assert_rpm_wakelock_held(&dev_priv->runtime_pm); + + assert_display_rpm_held(display); assert_dmc_loaded(display); } @@ -1201,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; @@ -1225,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(dev_priv); - spin_unlock_irq(&dev_priv->irq_lock); + valleyview_enable_display_irqs(display); /* * During driver initialization/resume we can avoid restoring the @@ -1236,8 +1244,8 @@ static void vlv_display_power_well_init(struct intel_display *display) if (display->power.domains.initializing) return; - intel_hpd_init(dev_priv); - intel_hpd_poll_disable(dev_priv); + intel_hpd_init(display); + intel_hpd_poll_disable(display); /* Re-enable the ADPA, if we have one */ for_each_intel_encoder(display->drm, encoder) { @@ -1245,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); } @@ -1254,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(dev_priv); - spin_unlock_irq(&dev_priv->irq_lock); + valleyview_disable_display_irqs(display); /* make sure we're done processing display irqs */ intel_synchronize_irq(dev_priv); @@ -1265,7 +1271,7 @@ static void vlv_display_power_well_deinit(struct intel_display *display) /* Prevent us from re-enabling polling on accident in late suspend */ if (!display->drm->dev->power.is_suspended) - intel_hpd_poll_enable(dev_priv); + intel_hpd_poll_enable(display); } static void vlv_display_power_well_enable(struct intel_display *display, diff --git a/drivers/gpu/drm/i915/display/intel_display_reset.c b/drivers/gpu/drm/i915/display/intel_display_reset.c index 1f2798404f2c..1dbd3e841df3 100644 --- a/drivers/gpu/drm/i915/display/intel_display_reset.c +++ b/drivers/gpu/drm/i915/display/intel_display_reset.c @@ -107,14 +107,14 @@ void intel_display_reset_finish(struct intel_display *display, bool test_only) intel_display_driver_init_hw(display); intel_clock_gating_init(i915); intel_cx0_pll_power_save_wa(display); - intel_hpd_init(i915); + intel_hpd_init(display); ret = __intel_display_driver_resume(display, state, ctx); if (ret) drm_err(display->drm, "Restoring old state failed with %i\n", ret); - intel_hpd_poll_disable(i915); + intel_hpd_poll_disable(display); } drm_atomic_state_put(state); diff --git a/drivers/gpu/drm/i915/display/intel_display_rpm.c b/drivers/gpu/drm/i915/display/intel_display_rpm.c new file mode 100644 index 000000000000..48da67dd0136 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_display_rpm.c @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: MIT +/* Copyright © 2025 Intel Corporation */ + +#include "i915_drv.h" +#include "intel_display_rpm.h" +#include "intel_runtime_pm.h" + +static struct intel_runtime_pm *display_to_rpm(struct intel_display *display) +{ + struct drm_i915_private *i915 = to_i915(display->drm); + + return &i915->runtime_pm; +} + +struct ref_tracker *intel_display_rpm_get_raw(struct intel_display *display) +{ + return intel_runtime_pm_get_raw(display_to_rpm(display)); +} + +void intel_display_rpm_put_raw(struct intel_display *display, struct ref_tracker *wakeref) +{ + intel_runtime_pm_put_raw(display_to_rpm(display), wakeref); +} + +struct ref_tracker *intel_display_rpm_get(struct intel_display *display) +{ + return intel_runtime_pm_get(display_to_rpm(display)); +} + +struct ref_tracker *intel_display_rpm_get_if_in_use(struct intel_display *display) +{ + return intel_runtime_pm_get_if_in_use(display_to_rpm(display)); +} + +struct ref_tracker *intel_display_rpm_get_noresume(struct intel_display *display) +{ + return intel_runtime_pm_get_noresume(display_to_rpm(display)); +} + +void intel_display_rpm_put(struct intel_display *display, struct ref_tracker *wakeref) +{ + intel_runtime_pm_put(display_to_rpm(display), wakeref); +} + +void intel_display_rpm_put_unchecked(struct intel_display *display) +{ + intel_runtime_pm_put_unchecked(display_to_rpm(display)); +} + +bool intel_display_rpm_suspended(struct intel_display *display) +{ + return intel_runtime_pm_suspended(display_to_rpm(display)); +} + +void assert_display_rpm_held(struct intel_display *display) +{ + assert_rpm_wakelock_held(display_to_rpm(display)); +} + +void intel_display_rpm_assert_block(struct intel_display *display) +{ + disable_rpm_wakeref_asserts(display_to_rpm(display)); +} + +void intel_display_rpm_assert_unblock(struct intel_display *display) +{ + enable_rpm_wakeref_asserts(display_to_rpm(display)); +} diff --git a/drivers/gpu/drm/i915/display/intel_display_rpm.h b/drivers/gpu/drm/i915/display/intel_display_rpm.h new file mode 100644 index 000000000000..6ef48515f84b --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_display_rpm.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright © 2025 Intel Corporation */ + +#ifndef __INTEL_DISPLAY_RPM__ +#define __INTEL_DISPLAY_RPM__ + +#include <linux/types.h> + +struct intel_display; +struct ref_tracker; + +struct ref_tracker *intel_display_rpm_get(struct intel_display *display); +void intel_display_rpm_put(struct intel_display *display, struct ref_tracker *wakeref); + +#define __with_intel_display_rpm(__display, __wakeref) \ + for (struct ref_tracker *(__wakeref) = intel_display_rpm_get(__display); (__wakeref); \ + intel_display_rpm_put((__display), (__wakeref)), (__wakeref) = NULL) + +#define with_intel_display_rpm(__display) \ + __with_intel_display_rpm((__display), __UNIQUE_ID(wakeref)) + +/* Only for special cases. */ +bool intel_display_rpm_suspended(struct intel_display *display); + +void assert_display_rpm_held(struct intel_display *display); +void intel_display_rpm_assert_block(struct intel_display *display); +void intel_display_rpm_assert_unblock(struct intel_display *display); + +/* Only for display power implementation. */ +struct ref_tracker *intel_display_rpm_get_raw(struct intel_display *display); +void intel_display_rpm_put_raw(struct intel_display *display, struct ref_tracker *wakeref); + +struct ref_tracker *intel_display_rpm_get_if_in_use(struct intel_display *display); +struct ref_tracker *intel_display_rpm_get_noresume(struct intel_display *display); +void intel_display_rpm_put_unchecked(struct intel_display *display); + +#endif /* __INTEL_DISPLAY_RPM__ */ 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 99a6fd2900b9..d6d0440dcee9 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -581,7 +581,7 @@ struct dpll { struct intel_atomic_state { struct drm_atomic_state base; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; struct __intel_global_objs_state *global_objs; int num_global_objs; @@ -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 { @@ -1620,7 +1621,7 @@ struct intel_psr { bool sink_support; bool source_support; bool enabled; - bool paused; + int pause_counter; enum pipe pipe; enum transcoder transcoder; bool active; @@ -1650,6 +1651,8 @@ struct intel_psr { u8 entry_setup_frames; bool link_ok; + + u8 active_non_psr_pipes; }; struct intel_dp { @@ -1658,7 +1661,6 @@ struct intel_dp { int link_rate; u8 lane_count; u8 sink_count; - bool link_trained; bool needs_modeset_retry; bool use_max_params; u8 dpcd[DP_RECEIVER_CAP_SIZE]; @@ -1683,6 +1685,7 @@ struct intel_dp { int common_rates[DP_MAX_SUPPORTED_RATES]; struct { /* TODO: move the rest of link specific fields to here */ + bool active; /* common rate,lane_count configs in bw order */ int num_configs; #define INTEL_DP_MAX_LANE_COUNT 4 @@ -1739,7 +1742,7 @@ struct intel_dp { struct { struct intel_dp_mst_encoder *stream_encoders[I915_MAX_PIPES]; struct drm_dp_mst_topology_mgr mgr; - int active_links; + int active_streams; } mst; u32 (*get_aux_clock_divider)(struct intel_dp *dp, int index); @@ -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_display_wa.c b/drivers/gpu/drm/i915/display/intel_display_wa.c index e5a8022db664..da429c332914 100644 --- a/drivers/gpu/drm/i915/display/intel_display_wa.c +++ b/drivers/gpu/drm/i915/display/intel_display_wa.c @@ -3,38 +3,38 @@ * Copyright © 2023 Intel Corporation */ -#include "i915_drv.h" #include "i915_reg.h" #include "intel_de.h" +#include "intel_display_core.h" #include "intel_display_wa.h" -static void gen11_display_wa_apply(struct drm_i915_private *i915) +static void gen11_display_wa_apply(struct intel_display *display) { /* Wa_14010594013 */ - intel_de_rmw(i915, GEN8_CHICKEN_DCPR_1, 0, ICL_DELAY_PMRSP); + intel_de_rmw(display, GEN8_CHICKEN_DCPR_1, 0, ICL_DELAY_PMRSP); } -static void xe_d_display_wa_apply(struct drm_i915_private *i915) +static void xe_d_display_wa_apply(struct intel_display *display) { /* Wa_14013723622 */ - intel_de_rmw(i915, CLKREQ_POLICY, CLKREQ_POLICY_MEM_UP_OVRD, 0); + intel_de_rmw(display, CLKREQ_POLICY, CLKREQ_POLICY_MEM_UP_OVRD, 0); } -static void adlp_display_wa_apply(struct drm_i915_private *i915) +static void adlp_display_wa_apply(struct intel_display *display) { /* Wa_22011091694:adlp */ - intel_de_rmw(i915, GEN9_CLKGATE_DIS_5, 0, DPCE_GATING_DIS); + intel_de_rmw(display, GEN9_CLKGATE_DIS_5, 0, DPCE_GATING_DIS); /* Bspec/49189 Initialize Sequence */ - intel_de_rmw(i915, GEN8_CHICKEN_DCPR_1, DDI_CLOCK_REG_ACCESS, 0); + intel_de_rmw(display, GEN8_CHICKEN_DCPR_1, DDI_CLOCK_REG_ACCESS, 0); } -void intel_display_wa_apply(struct drm_i915_private *i915) +void intel_display_wa_apply(struct intel_display *display) { - if (IS_ALDERLAKE_P(i915)) - adlp_display_wa_apply(i915); - else if (DISPLAY_VER(i915) == 12) - xe_d_display_wa_apply(i915); - else if (DISPLAY_VER(i915) == 11) - gen11_display_wa_apply(i915); + if (display->platform.alderlake_p) + adlp_display_wa_apply(display); + else if (DISPLAY_VER(display) == 12) + xe_d_display_wa_apply(display); + else if (DISPLAY_VER(display) == 11) + gen11_display_wa_apply(display); } diff --git a/drivers/gpu/drm/i915/display/intel_display_wa.h b/drivers/gpu/drm/i915/display/intel_display_wa.h index be644ab6ae00..babd9d16603d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_wa.h +++ b/drivers/gpu/drm/i915/display/intel_display_wa.h @@ -8,14 +8,17 @@ #include <linux/types.h> -struct drm_i915_private; +struct intel_display; -void intel_display_wa_apply(struct drm_i915_private *i915); +void intel_display_wa_apply(struct intel_display *display); #ifdef I915 -static inline bool intel_display_needs_wa_16023588340(struct drm_i915_private *i915) { return false; } +static inline bool intel_display_needs_wa_16023588340(struct intel_display *display) +{ + return false; +} #else -bool intel_display_needs_wa_16023588340(struct drm_i915_private *i915); +bool intel_display_needs_wa_16023588340(struct intel_display *display); #endif #endif diff --git a/drivers/gpu/drm/i915/display/intel_dkl_phy.c b/drivers/gpu/drm/i915/display/intel_dkl_phy.c index 0813fb9b5823..dad7192132ad 100644 --- a/drivers/gpu/drm/i915/display/intel_dkl_phy.c +++ b/drivers/gpu/drm/i915/display/intel_dkl_phy.c @@ -4,6 +4,7 @@ */ #include <drm/drm_device.h> +#include <drm/drm_print.h> #include "intel_de.h" #include "intel_display.h" diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index fa6944e55d95..b58189d24e7e 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -28,6 +28,8 @@ #include "i915_drv.h" #include "i915_reg.h" #include "intel_de.h" +#include "intel_display_rpm.h" +#include "intel_display_power_well.h" #include "intel_dmc.h" #include "intel_dmc_regs.h" #include "intel_step.h" @@ -57,6 +59,10 @@ struct intel_dmc { const char *fw_path; u32 max_fw_size; /* bytes */ u32 version; + struct { + u32 dc5_start; + u32 count; + } dc6_allowed; struct dmc_fw_info { u32 mmio_count; i915_reg_t mmioaddr[20]; @@ -167,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; @@ -183,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; } @@ -511,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) { @@ -535,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; @@ -545,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; @@ -582,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; @@ -595,7 +645,7 @@ void intel_dmc_load_program(struct intel_display *display) disable_all_event_handlers(display); - assert_rpm_wakelock_held(&i915->runtime_pm); + assert_display_rpm_held(display); preempt_disable(); @@ -1006,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; @@ -1232,18 +1280,56 @@ void intel_dmc_snapshot_print(const struct intel_dmc_snapshot *snapshot, struct DMC_VERSION_MINOR(snapshot->version)); } +void intel_dmc_update_dc6_allowed_count(struct intel_display *display, + bool start_tracking) +{ + struct intel_dmc *dmc = display_to_dmc(display); + u32 dc5_cur_count; + + if (DISPLAY_VER(dmc->display) < 14) + return; + + dc5_cur_count = intel_de_read(dmc->display, DG1_DMC_DEBUG_DC5_COUNT); + + if (!start_tracking) + dmc->dc6_allowed.count += dc5_cur_count - dmc->dc6_allowed.dc5_start; + + dmc->dc6_allowed.dc5_start = dc5_cur_count; +} + +static bool intel_dmc_get_dc6_allowed_count(struct intel_display *display, u32 *count) +{ + struct i915_power_domains *power_domains = &display->power.domains; + struct intel_dmc *dmc = display_to_dmc(display); + bool dc6_enabled; + + if (DISPLAY_VER(display) < 14) + return false; + + mutex_lock(&power_domains->lock); + dc6_enabled = intel_de_read(display, DC_STATE_EN) & + DC_STATE_EN_UPTO_DC6; + if (dc6_enabled) + intel_dmc_update_dc6_allowed_count(display, false); + + *count = dmc->dc6_allowed.count; + mutex_unlock(&power_domains->lock); + + return true; +} + 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); - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; i915_reg_t dc5_reg, dc6_reg = INVALID_MMIO_REG; + u32 dc6_allowed_count; if (!HAS_DMC(display)) return -ENODEV; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); + wakeref = intel_display_rpm_get(display); seq_printf(m, "DMC initialized: %s\n", str_yes_no(dmc)); seq_printf(m, "fw loaded: %s\n", @@ -1254,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))); @@ -1268,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 { @@ -1280,14 +1366,18 @@ 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; } seq_printf(m, "DC3 -> DC5 count: %d\n", intel_de_read(display, dc5_reg)); - if (i915_mmio_reg_valid(dc6_reg)) + + if (intel_dmc_get_dc6_allowed_count(display, &dc6_allowed_count)) + seq_printf(m, "DC5 -> DC6 allowed count: %d\n", + dc6_allowed_count); + else if (i915_mmio_reg_valid(dc6_reg)) seq_printf(m, "DC5 -> DC6 count: %d\n", intel_de_read(display, dc6_reg)); @@ -1299,7 +1389,7 @@ out: intel_de_read(display, DMC_SSP_BASE)); seq_printf(m, "htp: 0x%08x\n", intel_de_read(display, DMC_HTP_SKL)); - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h index 44cecef98e73..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); @@ -26,6 +30,7 @@ void intel_dmc_debugfs_register(struct intel_display *display); struct intel_dmc_snapshot *intel_dmc_snapshot_capture(struct intel_display *display); void intel_dmc_snapshot_print(const struct intel_dmc_snapshot *snapshot, struct drm_printer *p); +void intel_dmc_update_dc6_allowed_count(struct intel_display *display, bool start_tracking); void assert_dmc_loaded(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 392c3653d0d7..640c43bf62d4 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,10 +59,12 @@ #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" #include "intel_display_driver.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dp.h" #include "intel_dp_aux.h" @@ -87,12 +90,10 @@ #include "intel_pfit.h" #include "intel_pps.h" #include "intel_psr.h" -#include "intel_runtime_pm.h" #include "intel_quirks.h" #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 @@ -2523,6 +2524,7 @@ intel_dp_dsc_compute_pipe_bpp_limits(struct intel_dp *intel_dp, bool intel_dp_compute_config_limits(struct intel_dp *intel_dp, + struct intel_connector *connector, struct intel_crtc_state *crtc_state, bool respect_downstream_limits, bool dsc, @@ -2576,7 +2578,7 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp, intel_dp_test_compute_config(intel_dp, crtc_state, limits); return intel_dp_compute_config_link_bpp_limits(intel_dp, - intel_dp->attached_connector, + connector, crtc_state, dsc, limits); @@ -2637,7 +2639,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, joiner_needs_dsc = intel_dp_joiner_needs_dsc(display, num_joined_pipes); dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en || - !intel_dp_compute_config_limits(intel_dp, pipe_config, + !intel_dp_compute_config_limits(intel_dp, connector, pipe_config, respect_downstream_limits, false, &limits); @@ -2671,7 +2673,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, str_yes_no(ret), str_yes_no(joiner_needs_dsc), str_yes_no(intel_dp->force_dsc_en)); - if (!intel_dp_compute_config_limits(intel_dp, pipe_config, + if (!intel_dp_compute_config_limits(intel_dp, connector, pipe_config, respect_downstream_limits, true, &limits)) @@ -3104,6 +3106,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 +3275,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; @@ -3223,7 +3299,7 @@ void intel_dp_set_link_params(struct intel_dp *intel_dp, int link_rate, int lane_count) { memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set)); - intel_dp->link_trained = false; + intel_dp->link.active = false; intel_dp->needs_modeset_retry = false; intel_dp->link_rate = link_rate; intel_dp->lane_count = lane_count; @@ -3587,7 +3663,7 @@ void intel_dp_sync_state(struct intel_encoder *encoder, if (crtc_state) { intel_dp_reset_link_params(intel_dp); intel_dp_set_link_params(intel_dp, crtc_state->port_clock, crtc_state->lane_count); - intel_dp->link_trained = true; + intel_dp->link.active = true; } } @@ -4456,6 +4532,23 @@ intel_dp_mst_disconnect(struct intel_dp *intel_dp) static bool intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *esi) { + struct intel_display *display = to_intel_display(intel_dp); + + /* + * Display WA for HSD #13013007775: mtl/arl/lnl + * Read the sink count and link service IRQ registers in separate + * transactions to prevent disconnecting the sink on a TBT link + * inadvertently. + */ + if (IS_DISPLAY_VER(display, 14, 20) && !display->platform.battlemage) { + if (drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 3) != 3) + return false; + + /* DP_SINK_COUNT_ESI + 3 == DP_LINK_SERVICE_IRQ_VECTOR_ESI0 */ + return drm_dp_dpcd_readb(&intel_dp->aux, DP_LINK_SERVICE_IRQ_VECTOR_ESI0, + &esi[3]) == 1; + } + return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 4) == 4; } @@ -5005,8 +5098,6 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) bool link_ok = true; bool reprobe_needed = false; - drm_WARN_ON_ONCE(display->drm, intel_dp->mst.active_links < 0); - for (;;) { u8 esi[4] = {}; u8 ack[4] = {}; @@ -5021,7 +5112,7 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) drm_dbg_kms(display->drm, "DPRX ESI: %4ph\n", esi); - if (intel_dp->mst.active_links > 0 && link_ok && + if (intel_dp_mst_active_streams(intel_dp) > 0 && link_ok && esi[3] & LINK_STATUS_CHANGED) { if (!intel_dp_mst_link_status(intel_dp)) link_ok = false; @@ -5082,7 +5173,7 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp) { u8 link_status[DP_LINK_STATUS_SIZE]; - if (!intel_dp->link_trained) + if (!intel_dp->link.active) return false; /* @@ -5394,6 +5485,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; @@ -5829,20 +5925,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); @@ -5881,24 +5978,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; @@ -5909,20 +6007,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, @@ -5983,21 +6082,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; @@ -6061,10 +6160,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; @@ -6086,17 +6186,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; @@ -6106,12 +6207,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; @@ -6122,26 +6223,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); @@ -6150,10 +6251,10 @@ 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(i915); + intel_hpd_schedule_detection(display); } static const struct drm_connector_funcs intel_dp_connector_funcs = { @@ -6180,13 +6281,12 @@ enum irqreturn intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd) { struct intel_display *display = to_intel_display(dig_port); - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct intel_dp *intel_dp = &dig_port->dp; u8 dpcd[DP_RECEIVER_CAP_SIZE]; if (dig_port->base.type == INTEL_OUTPUT_EDP && (long_hpd || - intel_runtime_pm_suspended(&i915->runtime_pm) || + intel_display_rpm_suspended(display) || !intel_pps_have_panel_power_or_vdd(intel_dp))) { /* * vdd off can generate a long/short pulse on eDP which @@ -6283,36 +6383,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 @@ -6347,7 +6448,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; @@ -6362,9 +6462,9 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, * eDP and LVDS bail out early in this case to prevent interfering * with an already powered-on LVDS power sequencer. */ - if (intel_get_lvds_encoder(dev_priv)) { + 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"); @@ -6395,7 +6495,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..742ae26ac4a9 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -194,6 +194,7 @@ void intel_dp_wait_source_oui(struct intel_dp *intel_dp); int intel_dp_output_bpp(enum intel_output_format output_format, int bpp); bool intel_dp_compute_config_limits(struct intel_dp *intel_dp, + struct intel_connector *connector, struct intel_crtc_state *crtc_state, bool respect_downstream_limits, bool dsc, @@ -208,5 +209,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 ec27bbd70bcf..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; @@ -247,7 +247,7 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp, u32 aux_clock_divider; enum intel_display_power_domain aux_domain; intel_wakeref_t aux_wakeref; - intel_wakeref_t pps_wakeref; + intel_wakeref_t pps_wakeref = NULL; int i, ret, recv_bytes; int try, clock = 0; u32 status; @@ -272,7 +272,20 @@ intel_dp_aux_xfer(struct intel_dp *intel_dp, aux_domain = intel_aux_power_domain(dig_port); aux_wakeref = intel_display_power_get(display, aux_domain); - pps_wakeref = intel_pps_lock(intel_dp); + + /* + * The PPS state needs to be locked for: + * - eDP on all platforms, since AUX transfers on eDP need VDD power + * (either forced or via panel power) which depends on the PPS + * state. + * - non-eDP on platforms where the PPS is a pipe instance (VLV/CHV), + * since changing the PPS state (via a parallel modeset for + * instance) may interfere with the AUX transfers on a non-eDP + * output as well. + */ + if (intel_dp_is_edp(intel_dp) || + display->platform.valleyview || display->platform.cherryview) + pps_wakeref = intel_pps_lock(intel_dp); /* * We will be called with VDD already enabled for dpcd/edid/oui reads. @@ -430,7 +443,9 @@ out: if (vdd) intel_pps_vdd_off_unlocked(intel_dp, false); - intel_pps_unlock(intel_dp, pps_wakeref); + if (pps_wakeref) + intel_pps_unlock(intel_dp, pps_wakeref); + intel_display_power_put_async(display, aux_domain, aux_wakeref); out_unlock: intel_digital_port_unlock(encoder); @@ -771,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; @@ -786,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 { @@ -799,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 8173de8aec63..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; @@ -663,7 +662,8 @@ intel_dp_aux_supports_vesa_backlight(struct intel_connector *connector) struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_panel *panel = &connector->panel; - if ((intel_dp->edp_dpcd[3] & DP_EDP_PANEL_LUMINANCE_CONTROL_CAPABLE)) { + if ((intel_dp->edp_dpcd[3] & DP_EDP_PANEL_LUMINANCE_CONTROL_CAPABLE) && + (intel_dp->edp_dpcd[3] & DP_EDP_SMOOTH_BRIGHTNESS_CAPABLE)) { drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] AUX Luminance Based Backlight Control Supported!\n", connector->base.base.id, connector->base.name); diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 2966f5b39392..a479b63112ea 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -56,6 +56,8 @@ lt_dbg(_intel_dp, _dp_phy, "Sink disconnected: " _format, ## __VA_ARGS__); \ } while (0) +#define MAX_SEQ_TRAIN_FAILURES 2 + static void intel_dp_reset_lttpr_common_caps(struct intel_dp *intel_dp) { memset(intel_dp->lttpr_common_caps, 0, sizeof(intel_dp->lttpr_common_caps)); @@ -164,7 +166,7 @@ static int intel_dp_init_lttpr_phys(struct intel_dp *intel_dp, const u8 dpcd[DP_ * resetting its internal state when the mode is changed from * non-transparent to transparent. */ - if (intel_dp->link_trained) { + if (intel_dp->link.active) { if (lttpr_count < 0 || intel_dp_lttpr_transparent_mode_enabled(intel_dp)) goto out_reset_lttpr_count; @@ -711,8 +713,21 @@ void intel_dp_link_training_set_mode(struct intel_dp *intel_dp, int link_rate, b static void intel_dp_update_downspread_ctrl(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { + /* + * Currently, we set the MSA ignore bit based on vrr.in_range. + * We can't really read that out during driver load since we don't have + * the connector information read in yet. So if we do end up doing a + * modeset during initial_commit() we'll clear the MSA ignore bit. + * GOP likely wouldn't have set this bit so after the initial commit, + * if there are no modesets and we enable VRR mode seamlessly + * (without a full modeset), the MSA ignore bit might never get set. + * + * #TODO: Implement readout of vrr.in_range. + * We need fastset support for setting the MSA ignore bit in DPCD, + * especially on the first real commit when clearing the inherited flag. + */ intel_dp_link_training_set_mode(intel_dp, - crtc_state->port_clock, crtc_state->vrr.flipline); + crtc_state->port_clock, crtc_state->vrr.in_range); } void intel_dp_link_training_set_bw(struct intel_dp *intel_dp, @@ -1110,7 +1125,10 @@ intel_dp_128b132b_intra_hop(struct intel_dp *intel_dp, void intel_dp_stop_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { - intel_dp->link_trained = true; + struct intel_display *display = to_intel_display(intel_dp); + struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; + + intel_dp->link.active = true; intel_dp_disable_dpcd_training_pattern(intel_dp, DP_PHY_DPRX); intel_dp_program_link_training_pattern(intel_dp, crtc_state, DP_PHY_DPRX, @@ -1120,6 +1138,15 @@ void intel_dp_stop_link_train(struct intel_dp *intel_dp, wait_for(intel_dp_128b132b_intra_hop(intel_dp, crtc_state) == 0, 500)) { lt_dbg(intel_dp, DP_PHY_DPRX, "128b/132b intra-hop not clearing\n"); } + + intel_hpd_unblock(encoder); + + if (!display->hotplug.ignore_long_hpd && + intel_dp->link.seq_train_failures < MAX_SEQ_TRAIN_FAILURES) { + int delay_ms = intel_dp->link.seq_train_failures ? 0 : 2000; + + intel_encoder_link_check_queue_work(encoder, delay_ms); + } } static bool @@ -1602,7 +1629,11 @@ void intel_dp_start_link_train(struct intel_atomic_state *state, * non-transparent mode. During an earlier LTTPR detection this * could've been prevented by an active link. */ - int lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp); + int lttpr_count; + + intel_hpd_block(encoder); + + lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp); if (lttpr_count < 0) /* Still continue with enabling the port and link training. */ @@ -1620,7 +1651,6 @@ void intel_dp_start_link_train(struct intel_atomic_state *state, lt_dbg(intel_dp, DP_PHY_DPRX, "Forcing link training failure\n"); } else if (passed) { intel_dp->link.seq_train_failures = 0; - intel_encoder_link_check_queue_work(encoder, 2000); return; } @@ -1643,10 +1673,8 @@ void intel_dp_start_link_train(struct intel_atomic_state *state, return; } - if (intel_dp->link.seq_train_failures < 2) { - intel_encoder_link_check_queue_work(encoder, 0); + if (intel_dp->link.seq_train_failures < MAX_SEQ_TRAIN_FAILURES) return; - } if (intel_dp_schedule_fallback_link_training(state, intel_dp, crtc_state)) return; @@ -1693,7 +1721,7 @@ static int i915_dp_force_link_rate_show(struct seq_file *m, void *data) if (err) return err; - if (intel_dp->link_trained) + if (intel_dp->link.active) current_rate = intel_dp->link_rate; force_rate = intel_dp->link.force_rate; @@ -1791,7 +1819,7 @@ static int i915_dp_force_lane_count_show(struct seq_file *m, void *data) if (err) return err; - if (intel_dp->link_trained) + if (intel_dp->link.active) current_lane_count = intel_dp->lane_count; force_lane_count = intel_dp->link.force_lane_count; diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 6dc2d31ccb5a..06f4ad8de591 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,7 +52,9 @@ #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" /* @@ -104,6 +107,34 @@ static struct intel_dp *to_primary_dp(struct intel_encoder *encoder) return &dig_port->dp; } +int intel_dp_mst_active_streams(struct intel_dp *intel_dp) +{ + return intel_dp->mst.active_streams; +} + +static bool intel_dp_mst_dec_active_streams(struct intel_dp *intel_dp) +{ + struct intel_display *display = to_intel_display(intel_dp); + + drm_dbg_kms(display->drm, "active MST streams %d -> %d\n", + intel_dp->mst.active_streams, intel_dp->mst.active_streams - 1); + + if (drm_WARN_ON(display->drm, intel_dp->mst.active_streams == 0)) + return true; + + return --intel_dp->mst.active_streams == 0; +} + +static bool intel_dp_mst_inc_active_streams(struct intel_dp *intel_dp) +{ + struct intel_display *display = to_intel_display(intel_dp); + + drm_dbg_kms(display->drm, "active MST streams %d -> %d\n", + intel_dp->mst.active_streams, intel_dp->mst.active_streams + 1); + + return intel_dp->mst.active_streams++ == 0; +} + static int intel_dp_mst_max_dpt_bpp(const struct intel_crtc_state *crtc_state, bool dsc) { @@ -210,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, @@ -300,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, @@ -590,12 +599,13 @@ adjust_limits_for_dsc_hblank_expansion_quirk(struct intel_dp *intel_dp, static bool mst_stream_compute_config_limits(struct intel_dp *intel_dp, - const struct intel_connector *connector, + struct intel_connector *connector, struct intel_crtc_state *crtc_state, bool dsc, struct link_config_limits *limits) { - if (!intel_dp_compute_config_limits(intel_dp, crtc_state, false, dsc, + if (!intel_dp_compute_config_limits(intel_dp, connector, + crtc_state, false, dsc, limits)) return false; @@ -710,6 +720,12 @@ 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); intel_ddi_compute_min_voltage_level(pipe_config); @@ -990,25 +1006,17 @@ 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; - drm_dbg_kms(display->drm, "active links %d\n", - intel_dp->mst.active_links); - - if (intel_dp->mst.active_links == 1) - intel_dp->link_trained = false; + if (intel_dp_mst_active_streams(intel_dp) == 1) + intel_dp->link.active = false; 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, @@ -1034,8 +1042,8 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, bool last_mst_stream; int i; - intel_dp->mst.active_links--; - last_mst_stream = intel_dp->mst.active_links == 0; + last_mst_stream = intel_dp_mst_dec_active_streams(intel_dp); + drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 12 && last_mst_stream && !intel_dp_mst_is_master_trans(old_crtc_state)); @@ -1062,6 +1070,8 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, drm_dp_remove_payload_part2(&intel_dp->mst.mgr, new_mst_state, old_payload, new_payload); + intel_vrr_transcoder_disable(old_crtc_state); + intel_ddi_disable_transcoder_func(old_crtc_state); for_each_pipe_crtc_modeset_disable(display, pipe_crtc, old_crtc_state, i) { @@ -1104,8 +1114,6 @@ static void mst_stream_post_disable(struct intel_atomic_state *state, primary_encoder->post_disable(state, primary_encoder, old_crtc_state, NULL); - drm_dbg_kms(display->drm, "active links %d\n", - intel_dp->mst.active_links); } static void mst_stream_post_pll_disable(struct intel_atomic_state *state, @@ -1116,7 +1124,7 @@ static void mst_stream_post_pll_disable(struct intel_atomic_state *state, struct intel_encoder *primary_encoder = to_primary_encoder(encoder); struct intel_dp *intel_dp = to_primary_dp(encoder); - if (intel_dp->mst.active_links == 0 && + if (intel_dp_mst_active_streams(intel_dp) == 0 && primary_encoder->post_pll_disable) primary_encoder->post_pll_disable(state, primary_encoder, old_crtc_state, old_conn_state); } @@ -1129,7 +1137,7 @@ static void mst_stream_pre_pll_enable(struct intel_atomic_state *state, struct intel_encoder *primary_encoder = to_primary_encoder(encoder); struct intel_dp *intel_dp = to_primary_dp(encoder); - if (intel_dp->mst.active_links == 0) + if (intel_dp_mst_active_streams(intel_dp) == 0) primary_encoder->pre_pll_enable(state, primary_encoder, pipe_config, NULL); else @@ -1189,13 +1197,11 @@ static void mst_stream_pre_enable(struct intel_atomic_state *state, */ connector->encoder = encoder; intel_mst->connector = connector; - first_mst_stream = intel_dp->mst.active_links == 0; + + first_mst_stream = intel_dp_mst_inc_active_streams(intel_dp); drm_WARN_ON(display->drm, DISPLAY_VER(display) >= 12 && first_mst_stream && !intel_dp_mst_is_master_trans(pipe_config)); - drm_dbg_kms(display->drm, "active links %d\n", - intel_dp->mst.active_links); - if (first_mst_stream) intel_dp_set_power(intel_dp, DP_SET_POWER_D0); @@ -1210,8 +1216,6 @@ static void mst_stream_pre_enable(struct intel_atomic_state *state, intel_mst_reprobe_topology(intel_dp, pipe_config); } - intel_dp->mst.active_links++; - ret = drm_dp_add_payload_part1(&intel_dp->mst.mgr, mst_state, drm_atomic_get_mst_payload_state(mst_state, connector->mst.port)); if (ret < 0) @@ -1279,9 +1283,9 @@ static void mst_stream_enable(struct intel_atomic_state *state, struct drm_dp_mst_topology_state *mst_state = drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst.mgr); enum transcoder trans = pipe_config->cpu_transcoder; - bool first_mst_stream = intel_dp->mst.active_links == 1; + 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); @@ -1296,41 +1300,17 @@ 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); + intel_vrr_transcoder_enable(pipe_config); + intel_ddi_clear_act_sent(encoder, pipe_config); intel_de_rmw(display, TRANS_DDI_FUNC_CTL(display, trans), 0, TRANS_DDI_DP_VC_PAYLOAD_ALLOC); - drm_dbg_kms(display->drm, "active links %d\n", - intel_dp->mst.active_links); - intel_ddi_wait_for_act_sent(encoder, pipe_config); drm_dp_check_act_status(&intel_dp->mst.mgr); @@ -1870,12 +1850,6 @@ mst_stream_encoders_create(struct intel_digital_port *dig_port) } int -intel_dp_mst_encoder_active_links(struct intel_digital_port *dig_port) -{ - return dig_port->dp.mst.active_links; -} - -int intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id) { struct intel_display *display = to_intel_display(dig_port); @@ -2101,7 +2075,7 @@ void intel_dp_mst_prepare_probe(struct intel_dp *intel_dp) u8 rate_select; u8 link_bw; - if (intel_dp->link_trained) + if (intel_dp->link.active) return; if (intel_mst_probed_link_params_valid(intel_dp, link_rate, lane_count)) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h b/drivers/gpu/drm/i915/display/intel_dp_mst.h index c1bbfeb02ca9..ab09b487c6bb 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h @@ -18,7 +18,7 @@ struct intel_link_bw_limits; int intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_id); void intel_dp_mst_encoder_cleanup(struct intel_digital_port *dig_port); -int intel_dp_mst_encoder_active_links(struct intel_digital_port *dig_port); +int intel_dp_mst_active_streams(struct intel_dp *intel_dp); bool intel_dp_mst_is_master_trans(const struct intel_crtc_state *crtc_state); bool intel_dp_mst_is_slave_trans(const struct intel_crtc_state *crtc_state); bool intel_dp_mst_source_support(struct intel_dp *intel_dp); 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 08a30e5aafce..a9e9b98d0bf9 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -373,14 +373,14 @@ int chv_calc_dpll_params(int refclk, struct dpll *clock) static int i9xx_pll_refclk(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); 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 i915->display.vbt.lvds_ssc_freq; - else if (HAS_PCH_SPLIT(i915)) + return display->vbt.lvds_ssc_freq; + else if (HAS_PCH_SPLIT(display)) return 120000; - else if (DISPLAY_VER(i915) != 2) + else if (DISPLAY_VER(display) != 2) return 96000; else return 48000; @@ -389,27 +389,27 @@ static int i9xx_pll_refclk(const struct intel_crtc_state *crtc_state) void i9xx_dpll_get_hw_state(struct intel_crtc *crtc, struct intel_dpll_hw_state *dpll_hw_state) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct i9xx_dpll_hw_state *hw_state = &dpll_hw_state->i9xx; - if (DISPLAY_VER(dev_priv) >= 4) { + if (DISPLAY_VER(display) >= 4) { u32 tmp; /* No way to read it out on pipes B and C */ - if (IS_CHERRYVIEW(dev_priv) && crtc->pipe != PIPE_A) - tmp = dev_priv->display.state.chv_dpll_md[crtc->pipe]; + if (display->platform.cherryview && crtc->pipe != PIPE_A) + tmp = display->state.chv_dpll_md[crtc->pipe]; else - tmp = intel_de_read(dev_priv, - DPLL_MD(dev_priv, crtc->pipe)); + tmp = intel_de_read(display, + DPLL_MD(display, crtc->pipe)); hw_state->dpll_md = tmp; } - hw_state->dpll = intel_de_read(dev_priv, DPLL(dev_priv, crtc->pipe)); + hw_state->dpll = intel_de_read(display, DPLL(display, crtc->pipe)); - if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) { - hw_state->fp0 = intel_de_read(dev_priv, FP0(crtc->pipe)); - hw_state->fp1 = intel_de_read(dev_priv, FP1(crtc->pipe)); + if (!display->platform.valleyview && !display->platform.cherryview) { + hw_state->fp0 = intel_de_read(display, FP0(crtc->pipe)); + hw_state->fp1 = intel_de_read(display, FP1(crtc->pipe)); } else { /* Mask out read-only status bits. */ hw_state->dpll &= ~(DPLL_LOCK_VLV | @@ -421,8 +421,8 @@ void i9xx_dpll_get_hw_state(struct intel_crtc *crtc, /* Returns the clock of the currently programmed mode of the given pipe. */ void i9xx_crtc_clock_get(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); const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; u32 dpll = hw_state->dpll; u32 fp; @@ -436,7 +436,7 @@ void i9xx_crtc_clock_get(struct intel_crtc_state *crtc_state) fp = hw_state->fp1; clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; - if (IS_PINEVIEW(dev_priv)) { + if (display->platform.pineview) { clock.n = ffs((fp & FP_N_PINEVIEW_DIV_MASK) >> FP_N_DIV_SHIFT) - 1; clock.m2 = (fp & FP_M2_PINEVIEW_DIV_MASK) >> FP_M2_DIV_SHIFT; } else { @@ -444,8 +444,8 @@ void i9xx_crtc_clock_get(struct intel_crtc_state *crtc_state) clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT; } - if (DISPLAY_VER(dev_priv) != 2) { - if (IS_PINEVIEW(dev_priv)) + if (DISPLAY_VER(display) != 2) { + if (display->platform.pineview) clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW) >> DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW); else @@ -462,23 +462,23 @@ void i9xx_crtc_clock_get(struct intel_crtc_state *crtc_state) 7 : 14; break; default: - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Unknown DPLL mode %08x in programmed " "mode\n", (int)(dpll & DPLL_MODE_MASK)); return; } - if (IS_PINEVIEW(dev_priv)) + if (display->platform.pineview) port_clock = pnv_calc_dpll_params(refclk, &clock); else port_clock = i9xx_calc_dpll_params(refclk, &clock); } else { enum pipe lvds_pipe; - if (IS_I85X(dev_priv) && - intel_lvds_port_enabled(dev_priv, LVDS, &lvds_pipe) && + if (display->platform.i85x && + intel_lvds_port_enabled(display, LVDS, &lvds_pipe) && lvds_pipe == crtc->pipe) { - u32 lvds = intel_de_read(dev_priv, LVDS); + u32 lvds = intel_de_read(display, LVDS); clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> DPLL_FPA01_P1_POST_DIV_SHIFT); @@ -577,7 +577,7 @@ void chv_crtc_clock_get(struct intel_crtc_state *crtc_state) * Returns whether the given set of divisors are valid for a given refclk with * the given connectors. */ -static bool intel_pll_is_valid(struct drm_i915_private *dev_priv, +static bool intel_pll_is_valid(struct intel_display *display, const struct intel_limit *limit, const struct dpll *clock) { @@ -590,14 +590,14 @@ static bool intel_pll_is_valid(struct drm_i915_private *dev_priv, if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1) return false; - if (!IS_PINEVIEW(dev_priv) && - !IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) && - !IS_BROXTON(dev_priv) && !IS_GEMINILAKE(dev_priv)) + if (!display->platform.pineview && + !display->platform.valleyview && !display->platform.cherryview && + !display->platform.broxton && !display->platform.geminilake) if (clock->m1 <= clock->m2) return false; - if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv) && - !IS_BROXTON(dev_priv) && !IS_GEMINILAKE(dev_priv)) { + if (!display->platform.valleyview && !display->platform.cherryview && + !display->platform.broxton && !display->platform.geminilake) { if (clock->p < limit->p.min || limit->p.max < clock->p) return false; if (clock->m < limit->m.min || limit->m.max < clock->m) @@ -620,7 +620,7 @@ i9xx_select_p2_div(const struct intel_limit *limit, const struct intel_crtc_state *crtc_state, int target) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { /* @@ -628,7 +628,7 @@ i9xx_select_p2_div(const struct intel_limit *limit, * We haven't figured out how to reliably set up different * single/dual channel state, if we even can. */ - if (intel_is_dual_link_lvds(dev_priv)) + if (intel_is_dual_link_lvds(display)) return limit->p2.p2_fast; else return limit->p2.p2_slow; @@ -656,7 +656,7 @@ i9xx_find_best_dpll(const struct intel_limit *limit, const struct dpll *match_clock, struct dpll *best_clock) { - struct drm_device *dev = crtc_state->uapi.crtc->dev; + struct intel_display *display = to_intel_display(crtc_state); struct dpll clock; int err = target; @@ -677,7 +677,7 @@ i9xx_find_best_dpll(const struct intel_limit *limit, int this_err; i9xx_calc_dpll_params(refclk, &clock); - if (!intel_pll_is_valid(to_i915(dev), + if (!intel_pll_is_valid(display, limit, &clock)) continue; @@ -714,7 +714,7 @@ pnv_find_best_dpll(const struct intel_limit *limit, const struct dpll *match_clock, struct dpll *best_clock) { - struct drm_device *dev = crtc_state->uapi.crtc->dev; + struct intel_display *display = to_intel_display(crtc_state); struct dpll clock; int err = target; @@ -733,7 +733,7 @@ pnv_find_best_dpll(const struct intel_limit *limit, int this_err; pnv_calc_dpll_params(refclk, &clock); - if (!intel_pll_is_valid(to_i915(dev), + if (!intel_pll_is_valid(display, limit, &clock)) continue; @@ -770,7 +770,7 @@ g4x_find_best_dpll(const struct intel_limit *limit, const struct dpll *match_clock, struct dpll *best_clock) { - struct drm_device *dev = crtc_state->uapi.crtc->dev; + struct intel_display *display = to_intel_display(crtc_state); struct dpll clock; int max_n; bool found = false; @@ -794,7 +794,7 @@ g4x_find_best_dpll(const struct intel_limit *limit, int this_err; i9xx_calc_dpll_params(refclk, &clock); - if (!intel_pll_is_valid(to_i915(dev), + if (!intel_pll_is_valid(display, limit, &clock)) continue; @@ -817,7 +817,7 @@ g4x_find_best_dpll(const struct intel_limit *limit, * Check if the calculated PLL configuration is more optimal compared to the * best configuration and error found so far. Return the calculated error. */ -static bool vlv_PLL_is_optimal(struct drm_device *dev, int target_freq, +static bool vlv_PLL_is_optimal(struct intel_display *display, int target_freq, const struct dpll *calculated_clock, const struct dpll *best_clock, unsigned int best_error_ppm, @@ -827,13 +827,13 @@ static bool vlv_PLL_is_optimal(struct drm_device *dev, int target_freq, * For CHV ignore the error and consider only the P value. * Prefer a bigger P value based on HW requirements. */ - if (IS_CHERRYVIEW(to_i915(dev))) { + if (display->platform.cherryview) { *error_ppm = 0; return calculated_clock->p > best_clock->p; } - if (drm_WARN_ON_ONCE(dev, !target_freq)) + if (drm_WARN_ON_ONCE(display->drm, !target_freq)) return false; *error_ppm = div_u64(1000000ULL * @@ -864,8 +864,7 @@ vlv_find_best_dpll(const struct intel_limit *limit, const struct dpll *match_clock, struct dpll *best_clock) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_device *dev = crtc->base.dev; + struct intel_display *display = to_intel_display(crtc_state); struct dpll clock; unsigned int bestppm = 1000000; /* min update 19.2 MHz */ @@ -889,12 +888,12 @@ vlv_find_best_dpll(const struct intel_limit *limit, vlv_calc_dpll_params(refclk, &clock); - if (!intel_pll_is_valid(to_i915(dev), + if (!intel_pll_is_valid(display, limit, &clock)) continue; - if (!vlv_PLL_is_optimal(dev, target, + if (!vlv_PLL_is_optimal(display, target, &clock, best_clock, bestppm, &ppm)) @@ -922,8 +921,7 @@ chv_find_best_dpll(const struct intel_limit *limit, const struct dpll *match_clock, struct dpll *best_clock) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_device *dev = crtc->base.dev; + struct intel_display *display = to_intel_display(crtc_state); unsigned int best_error_ppm; struct dpll clock; u64 m2; @@ -958,10 +956,10 @@ chv_find_best_dpll(const struct intel_limit *limit, chv_calc_dpll_params(refclk, &clock); - if (!intel_pll_is_valid(to_i915(dev), limit, &clock)) + if (!intel_pll_is_valid(display, limit, &clock)) continue; - if (!vlv_PLL_is_optimal(dev, target, &clock, best_clock, + if (!vlv_PLL_is_optimal(display, target, &clock, best_clock, best_error_ppm, &error_ppm)) continue; @@ -1005,8 +1003,6 @@ static u32 i9xx_dpll(const struct intel_crtc_state *crtc_state, const struct dpll *reduced_clock) { 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); u32 dpll; dpll = DPLL_VCO_ENABLE | DPLL_VGA_MODE_DIS; @@ -1016,8 +1012,8 @@ static u32 i9xx_dpll(const struct intel_crtc_state *crtc_state, else dpll |= DPLLB_MODE_DAC_SERIAL; - if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) || - IS_G33(dev_priv) || IS_PINEVIEW(dev_priv)) { + if (display->platform.i945g || display->platform.i945gm || + display->platform.g33 || display->platform.pineview) { dpll |= (crtc_state->pixel_multiplier - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; } @@ -1030,10 +1026,10 @@ static u32 i9xx_dpll(const struct intel_crtc_state *crtc_state, dpll |= DPLL_SDVO_HIGH_SPEED; /* compute bitmask from p1 value */ - if (IS_G4X(dev_priv)) { + if (display->platform.g4x) { dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; dpll |= (1 << (reduced_clock->p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT; - } else if (IS_PINEVIEW(dev_priv)) { + } else if (display->platform.pineview) { dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW; WARN_ON(reduced_clock->p1 != clock->p1); } else { @@ -1057,7 +1053,7 @@ static u32 i9xx_dpll(const struct intel_crtc_state *crtc_state, } WARN_ON(reduced_clock->p2 != clock->p2); - if (DISPLAY_VER(dev_priv) >= 4) + if (DISPLAY_VER(display) >= 4) dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); if (crtc_state->sdvo_tv_clock) @@ -1075,11 +1071,10 @@ static void i9xx_compute_dpll(struct intel_crtc_state *crtc_state, const struct dpll *clock, const struct dpll *reduced_clock) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; - if (IS_PINEVIEW(dev_priv)) { + if (display->platform.pineview) { hw_state->fp0 = pnv_dpll_compute_fp(clock); hw_state->fp1 = pnv_dpll_compute_fp(reduced_clock); } else { @@ -1089,7 +1084,7 @@ static void i9xx_compute_dpll(struct intel_crtc_state *crtc_state, hw_state->dpll = i9xx_dpll(crtc_state, clock, reduced_clock); - if (DISPLAY_VER(dev_priv) >= 4) + if (DISPLAY_VER(display) >= 4) hw_state->dpll_md = i965_dpll_md(crtc_state); } @@ -1098,8 +1093,6 @@ static u32 i8xx_dpll(const struct intel_crtc_state *crtc_state, const struct dpll *reduced_clock) { 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); u32 dpll; dpll = DPLL_VCO_ENABLE | DPLL_VGA_MODE_DIS; @@ -1129,7 +1122,7 @@ static u32 i8xx_dpll(const struct intel_crtc_state *crtc_state, * both DPLLS. The spec says we should disable the DVO 2X clock * when not needed, but this seems to work fine in practice. */ - if (IS_I830(dev_priv) || + if (display->platform.i830 || intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DVO)) dpll |= DPLL_DVO_2X_MODE; @@ -1157,14 +1150,14 @@ static void i8xx_compute_dpll(struct intel_crtc_state *crtc_state, static int hsw_crtc_compute_clock(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_encoder *encoder = intel_get_crtc_new_encoder(state, crtc_state); int ret; - if (DISPLAY_VER(dev_priv) < 11 && + if (DISPLAY_VER(display) < 11 && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI)) return 0; @@ -1186,13 +1179,13 @@ static int hsw_crtc_compute_clock(struct intel_atomic_state *state, static int hsw_crtc_get_shared_dpll(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_encoder *encoder = intel_get_crtc_new_encoder(state, crtc_state); - if (DISPLAY_VER(dev_priv) < 11 && + if (DISPLAY_VER(display) < 11 && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI)) return 0; @@ -1241,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) && i915->display.vbt.lvds_ssc_freq == 100000) || - (HAS_PCH_IBX(i915) && intel_is_dual_link_lvds(i915)))) + ((intel_panel_use_ssc(display) && display->vbt.lvds_ssc_freq == 100000) || + (HAS_PCH_IBX(display) && intel_is_dual_link_lvds(display)))) return 25; if (crtc_state->sdvo_tv_clock) @@ -1276,8 +1267,6 @@ static u32 ilk_dpll(const struct intel_crtc_state *crtc_state, const struct dpll *reduced_clock) { 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); u32 dpll; dpll = DPLL_VCO_ENABLE; @@ -1311,7 +1300,7 @@ static u32 ilk_dpll(const struct intel_crtc_state *crtc_state, * clear if it''s a win or loss power wise. No point in doing * this on ILK at all since it has a fixed DPLL<->pipe mapping. */ - if (INTEL_NUM_PIPES(dev_priv) == 3 && + if (INTEL_NUM_PIPES(display) == 3 && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG)) dpll |= DPLL_SDVO_HIGH_SPEED; @@ -1362,7 +1351,6 @@ static int ilk_crtc_compute_clock(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); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit; @@ -1375,13 +1363,13 @@ static int ilk_crtc_compute_clock(struct intel_atomic_state *state, if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(display)) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "using SSC reference clock of %d kHz\n", - dev_priv->display.vbt.lvds_ssc_freq); - refclk = dev_priv->display.vbt.lvds_ssc_freq; + display->vbt.lvds_ssc_freq); + refclk = display->vbt.lvds_ssc_freq; } - if (intel_is_dual_link_lvds(dev_priv)) { + if (intel_is_dual_link_lvds(display)) { if (refclk == 100000) limit = &ilk_limits_dual_lvds_100m; else @@ -1539,7 +1527,6 @@ static int g4x_crtc_compute_clock(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); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit; @@ -1547,13 +1534,13 @@ static int g4x_crtc_compute_clock(struct intel_atomic_state *state, if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(display)) { - refclk = dev_priv->display.vbt.lvds_ssc_freq; - drm_dbg_kms(&dev_priv->drm, + refclk = display->vbt.lvds_ssc_freq; + drm_dbg_kms(display->drm, "using SSC reference clock of %d kHz\n", refclk); } - if (intel_is_dual_link_lvds(dev_priv)) + if (intel_is_dual_link_lvds(display)) limit = &intel_limits_g4x_dual_channel_lvds; else limit = &intel_limits_g4x_single_channel_lvds; @@ -1589,7 +1576,6 @@ static int pnv_crtc_compute_clock(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); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit; @@ -1597,8 +1583,8 @@ static int pnv_crtc_compute_clock(struct intel_atomic_state *state, if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(display)) { - refclk = dev_priv->display.vbt.lvds_ssc_freq; - drm_dbg_kms(&dev_priv->drm, + refclk = display->vbt.lvds_ssc_freq; + drm_dbg_kms(display->drm, "using SSC reference clock of %d kHz\n", refclk); } @@ -1628,7 +1614,6 @@ static int i9xx_crtc_compute_clock(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); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit; @@ -1636,8 +1621,8 @@ static int i9xx_crtc_compute_clock(struct intel_atomic_state *state, if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(display)) { - refclk = dev_priv->display.vbt.lvds_ssc_freq; - drm_dbg_kms(&dev_priv->drm, + refclk = display->vbt.lvds_ssc_freq; + drm_dbg_kms(display->drm, "using SSC reference clock of %d kHz\n", refclk); } @@ -1669,7 +1654,6 @@ static int i8xx_crtc_compute_clock(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); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit; @@ -1677,8 +1661,8 @@ static int i8xx_crtc_compute_clock(struct intel_atomic_state *state, if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(display)) { - refclk = dev_priv->display.vbt.lvds_ssc_freq; - drm_dbg_kms(&dev_priv->drm, + refclk = display->vbt.lvds_ssc_freq; + drm_dbg_kms(display->drm, "using SSC reference clock of %d kHz\n", refclk); } @@ -1751,12 +1735,12 @@ static const struct intel_dpll_funcs i8xx_dpll_funcs = { int intel_dpll_crtc_compute_clock(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); int ret; - drm_WARN_ON(&i915->drm, !intel_crtc_needs_modeset(crtc_state)); + drm_WARN_ON(display->drm, !intel_crtc_needs_modeset(crtc_state)); memset(&crtc_state->dpll_hw_state, 0, sizeof(crtc_state->dpll_hw_state)); @@ -1764,9 +1748,9 @@ int intel_dpll_crtc_compute_clock(struct intel_atomic_state *state, if (!crtc_state->hw.enable) return 0; - ret = i915->display.funcs.dpll->crtc_compute_clock(state, crtc); + ret = display->funcs.dpll->crtc_compute_clock(state, crtc); if (ret) { - drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] Couldn't calculate DPLL settings\n", + drm_dbg_kms(display->drm, "[CRTC:%d:%s] Couldn't calculate DPLL settings\n", crtc->base.base.id, crtc->base.name); return ret; } @@ -1777,23 +1761,23 @@ int intel_dpll_crtc_compute_clock(struct intel_atomic_state *state, int intel_dpll_crtc_get_shared_dpll(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); int ret; - drm_WARN_ON(&i915->drm, !intel_crtc_needs_modeset(crtc_state)); - drm_WARN_ON(&i915->drm, !crtc_state->hw.enable && crtc_state->shared_dpll); + drm_WARN_ON(display->drm, !intel_crtc_needs_modeset(crtc_state)); + drm_WARN_ON(display->drm, !crtc_state->hw.enable && crtc_state->shared_dpll); if (!crtc_state->hw.enable || crtc_state->shared_dpll) return 0; - if (!i915->display.funcs.dpll->crtc_get_shared_dpll) + if (!display->funcs.dpll->crtc_get_shared_dpll) return 0; - ret = i915->display.funcs.dpll->crtc_get_shared_dpll(state, crtc); + ret = display->funcs.dpll->crtc_get_shared_dpll(state, crtc); if (ret) { - drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] Couldn't get a shared DPLL\n", + drm_dbg_kms(display->drm, "[CRTC:%d:%s] Couldn't get a shared DPLL\n", crtc->base.base.id, crtc->base.name); return ret; } @@ -1802,43 +1786,42 @@ int intel_dpll_crtc_get_shared_dpll(struct intel_atomic_state *state, } void -intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv) -{ - if (DISPLAY_VER(dev_priv) >= 14) - dev_priv->display.funcs.dpll = &mtl_dpll_funcs; - else if (IS_DG2(dev_priv)) - dev_priv->display.funcs.dpll = &dg2_dpll_funcs; - else if (DISPLAY_VER(dev_priv) >= 9 || HAS_DDI(dev_priv)) - dev_priv->display.funcs.dpll = &hsw_dpll_funcs; - else if (HAS_PCH_SPLIT(dev_priv)) - dev_priv->display.funcs.dpll = &ilk_dpll_funcs; - else if (IS_CHERRYVIEW(dev_priv)) - dev_priv->display.funcs.dpll = &chv_dpll_funcs; - else if (IS_VALLEYVIEW(dev_priv)) - dev_priv->display.funcs.dpll = &vlv_dpll_funcs; - else if (IS_G4X(dev_priv)) - dev_priv->display.funcs.dpll = &g4x_dpll_funcs; - else if (IS_PINEVIEW(dev_priv)) - dev_priv->display.funcs.dpll = &pnv_dpll_funcs; - else if (DISPLAY_VER(dev_priv) != 2) - dev_priv->display.funcs.dpll = &i9xx_dpll_funcs; +intel_dpll_init_clock_hook(struct intel_display *display) +{ + 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(display)) + display->funcs.dpll = &ilk_dpll_funcs; + else if (display->platform.cherryview) + display->funcs.dpll = &chv_dpll_funcs; + else if (display->platform.valleyview) + display->funcs.dpll = &vlv_dpll_funcs; + else if (display->platform.g4x) + display->funcs.dpll = &g4x_dpll_funcs; + else if (display->platform.pineview) + display->funcs.dpll = &pnv_dpll_funcs; + else if (DISPLAY_VER(display) != 2) + display->funcs.dpll = &i9xx_dpll_funcs; else - dev_priv->display.funcs.dpll = &i8xx_dpll_funcs; + display->funcs.dpll = &i8xx_dpll_funcs; } -static bool i9xx_has_pps(struct drm_i915_private *dev_priv) +static bool i9xx_has_pps(struct intel_display *display) { - if (IS_I830(dev_priv)) + if (display->platform.i830) return false; - return IS_PINEVIEW(dev_priv) || IS_MOBILE(dev_priv); + return display->platform.pineview || display->platform.mobile; } void i9xx_enable_pll(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); const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; enum pipe pipe = crtc->pipe; int i; @@ -1846,27 +1829,27 @@ void i9xx_enable_pll(const struct intel_crtc_state *crtc_state) assert_transcoder_disabled(display, crtc_state->cpu_transcoder); /* PLL is protected by panel, make sure we can write it */ - if (i9xx_has_pps(dev_priv)) + if (i9xx_has_pps(display)) assert_pps_unlocked(display, pipe); - intel_de_write(dev_priv, FP0(pipe), hw_state->fp0); - intel_de_write(dev_priv, FP1(pipe), hw_state->fp1); + intel_de_write(display, FP0(pipe), hw_state->fp0); + intel_de_write(display, FP1(pipe), hw_state->fp1); /* * Apparently we need to have VGA mode enabled prior to changing * the P1/P2 dividers. Otherwise the DPLL will keep using the old * dividers, even though the register value does change. */ - intel_de_write(dev_priv, DPLL(dev_priv, pipe), + intel_de_write(display, DPLL(display, pipe), hw_state->dpll & ~DPLL_VGA_MODE_DIS); - intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll); + intel_de_write(display, DPLL(display, pipe), hw_state->dpll); /* Wait for the clocks to stabilize. */ - intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe)); + intel_de_posting_read(display, DPLL(display, pipe)); udelay(150); - if (DISPLAY_VER(dev_priv) >= 4) { - intel_de_write(dev_priv, DPLL_MD(dev_priv, pipe), + if (DISPLAY_VER(display) >= 4) { + intel_de_write(display, DPLL_MD(display, pipe), hw_state->dpll_md); } else { /* The pixel multiplier can only be updated once the @@ -1874,20 +1857,21 @@ void i9xx_enable_pll(const struct intel_crtc_state *crtc_state) * * So write it again. */ - intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll); + intel_de_write(display, DPLL(display, pipe), hw_state->dpll); } /* We do this three times for luck */ for (i = 0; i < 3; i++) { - intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll); - intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe)); + intel_de_write(display, DPLL(display, pipe), hw_state->dpll); + intel_de_posting_read(display, DPLL(display, pipe)); udelay(150); /* wait for warmup */ } } -static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, +static void vlv_pllb_recal_opamp(struct intel_display *display, enum dpio_phy phy, enum dpio_channel ch) { + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 tmp; /* @@ -1916,6 +1900,7 @@ static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, static void vlv_prepare_pll(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); const struct dpll *clock = &crtc_state->dpll; @@ -1930,7 +1915,7 @@ static void vlv_prepare_pll(const struct intel_crtc_state *crtc_state) /* PLL B needs special handling */ if (pipe == PIPE_B) - vlv_pllb_recal_opamp(dev_priv, phy, ch); + vlv_pllb_recal_opamp(display, phy, ch); /* Set up Tx target for periodic Rcomp update */ vlv_dpio_write(dev_priv, phy, VLV_PCS_DW17_BCAST, 0x0100000f); @@ -2003,24 +1988,23 @@ static void vlv_prepare_pll(const struct intel_crtc_state *crtc_state) static void _vlv_enable_pll(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); const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; enum pipe pipe = crtc->pipe; - intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll); - intel_de_posting_read(dev_priv, DPLL(dev_priv, pipe)); + intel_de_write(display, DPLL(display, pipe), hw_state->dpll); + intel_de_posting_read(display, DPLL(display, pipe)); udelay(150); - if (intel_de_wait_for_set(dev_priv, DPLL(dev_priv, pipe), DPLL_LOCK_VLV, 1)) - drm_err(&dev_priv->drm, "DPLL %d failed to lock\n", pipe); + if (intel_de_wait_for_set(display, DPLL(display, pipe), DPLL_LOCK_VLV, 1)) + drm_err(display->drm, "DPLL %d failed to lock\n", pipe); } void vlv_enable_pll(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); const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; enum pipe pipe = crtc->pipe; @@ -2030,7 +2014,7 @@ void vlv_enable_pll(const struct intel_crtc_state *crtc_state) assert_pps_unlocked(display, pipe); /* Enable Refclk */ - intel_de_write(dev_priv, DPLL(dev_priv, pipe), + intel_de_write(display, DPLL(display, pipe), hw_state->dpll & ~(DPLL_VCO_ENABLE | DPLL_EXT_BUFFER_ENABLE_VLV)); if (hw_state->dpll & DPLL_VCO_ENABLE) { @@ -2038,8 +2022,8 @@ void vlv_enable_pll(const struct intel_crtc_state *crtc_state) _vlv_enable_pll(crtc_state); } - intel_de_write(dev_priv, DPLL_MD(dev_priv, pipe), hw_state->dpll_md); - intel_de_posting_read(dev_priv, DPLL_MD(dev_priv, pipe)); + intel_de_write(display, DPLL_MD(display, pipe), hw_state->dpll_md); + intel_de_posting_read(display, DPLL_MD(display, pipe)); } static void chv_prepare_pll(const struct intel_crtc_state *crtc_state) @@ -2133,6 +2117,7 @@ static void chv_prepare_pll(const struct intel_crtc_state *crtc_state) static void _chv_enable_pll(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); const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; @@ -2156,18 +2141,17 @@ static void _chv_enable_pll(const struct intel_crtc_state *crtc_state) udelay(1); /* Enable PLL */ - intel_de_write(dev_priv, DPLL(dev_priv, pipe), hw_state->dpll); + intel_de_write(display, DPLL(display, pipe), hw_state->dpll); /* Check PLL is locked */ - if (intel_de_wait_for_set(dev_priv, DPLL(dev_priv, pipe), DPLL_LOCK_VLV, 1)) - drm_err(&dev_priv->drm, "PLL %d failed to lock\n", pipe); + if (intel_de_wait_for_set(display, DPLL(display, pipe), DPLL_LOCK_VLV, 1)) + drm_err(display->drm, "PLL %d failed to lock\n", pipe); } void chv_enable_pll(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); const struct i9xx_dpll_hw_state *hw_state = &crtc_state->dpll_hw_state.i9xx; enum pipe pipe = crtc->pipe; @@ -2177,7 +2161,7 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state) assert_pps_unlocked(display, pipe); /* Enable Refclk and SSC */ - intel_de_write(dev_priv, DPLL(dev_priv, pipe), + intel_de_write(display, DPLL(display, pipe), hw_state->dpll & ~DPLL_VCO_ENABLE); if (hw_state->dpll & DPLL_VCO_ENABLE) { @@ -2192,29 +2176,29 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state) * DPLLCMD is AWOL. Use chicken bits to propagate * the value from DPLLBMD to either pipe B or C. */ - intel_de_write(dev_priv, CBR4_VLV, CBR_DPLLBMD_PIPE(pipe)); - intel_de_write(dev_priv, DPLL_MD(dev_priv, PIPE_B), + intel_de_write(display, CBR4_VLV, CBR_DPLLBMD_PIPE(pipe)); + intel_de_write(display, DPLL_MD(display, PIPE_B), hw_state->dpll_md); - intel_de_write(dev_priv, CBR4_VLV, 0); - dev_priv->display.state.chv_dpll_md[pipe] = hw_state->dpll_md; + intel_de_write(display, CBR4_VLV, 0); + display->state.chv_dpll_md[pipe] = hw_state->dpll_md; /* * DPLLB VGA mode also seems to cause problems. * We should always have it disabled. */ - drm_WARN_ON(&dev_priv->drm, - (intel_de_read(dev_priv, DPLL(dev_priv, PIPE_B)) & + drm_WARN_ON(display->drm, + (intel_de_read(display, DPLL(display, PIPE_B)) & DPLL_VGA_MODE_DIS) == 0); } else { - intel_de_write(dev_priv, DPLL_MD(dev_priv, pipe), + intel_de_write(display, DPLL_MD(display, pipe), hw_state->dpll_md); - intel_de_posting_read(dev_priv, DPLL_MD(dev_priv, pipe)); + intel_de_posting_read(display, DPLL_MD(display, pipe)); } } /** * vlv_force_pll_on - forcibly enable just the PLL - * @dev_priv: i915 private structure + * @display: display device * @pipe: pipe PLL to enable * @dpll: PLL configuration * @@ -2222,10 +2206,9 @@ void chv_enable_pll(const struct intel_crtc_state *crtc_state) * in cases where we need the PLL enabled even when @pipe is not going to * be enabled. */ -int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, +int vlv_force_pll_on(struct intel_display *display, enum pipe pipe, const struct dpll *dpll) { - struct intel_display *display = &dev_priv->display; struct intel_crtc *crtc = intel_crtc_for_pipe(display, pipe); struct intel_crtc_state *crtc_state; @@ -2238,7 +2221,7 @@ int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, crtc_state->dpll = *dpll; crtc_state->output_types = BIT(INTEL_OUTPUT_EDP); - if (IS_CHERRYVIEW(dev_priv)) { + if (display->platform.cherryview) { chv_compute_dpll(crtc_state); chv_enable_pll(crtc_state); } else { @@ -2251,9 +2234,8 @@ int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, return 0; } -void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) +void vlv_disable_pll(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; u32 val; /* Make sure the pipe isn't still relying on us */ @@ -2268,9 +2250,9 @@ void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) intel_de_posting_read(display, DPLL(display, pipe)); } -void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) +void chv_disable_pll(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; + struct drm_i915_private *dev_priv = to_i915(display->drm); enum dpio_channel ch = vlv_pipe_to_channel(pipe); enum dpio_phy phy = vlv_pipe_to_phy(pipe); u32 val; @@ -2316,18 +2298,18 @@ void i9xx_disable_pll(const struct intel_crtc_state *crtc_state) /** * vlv_force_pll_off - forcibly disable just the PLL - * @dev_priv: i915 private structure + * @display: display device * @pipe: pipe PLL to disable * * Disable the PLL for @pipe. To be used in cases where we need * the PLL enabled even when @pipe is not going to be enabled. */ -void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe) +void vlv_force_pll_off(struct intel_display *display, enum pipe pipe) { - if (IS_CHERRYVIEW(dev_priv)) - chv_disable_pll(dev_priv, pipe); + if (display->platform.cherryview) + chv_disable_pll(display, pipe); else - vlv_disable_pll(dev_priv, pipe); + vlv_disable_pll(display, pipe); } /* Only for pre-ILK configs */ diff --git a/drivers/gpu/drm/i915/display/intel_dpll.h b/drivers/gpu/drm/i915/display/intel_dpll.h index 21d06cbd2ce7..280e90a57c87 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.h +++ b/drivers/gpu/drm/i915/display/intel_dpll.h @@ -8,16 +8,15 @@ #include <linux/types.h> +enum pipe; struct dpll; -struct drm_i915_private; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; struct intel_display; struct intel_dpll_hw_state; -enum pipe; -void intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv); +void intel_dpll_init_clock_hook(struct intel_display *display); int intel_dpll_crtc_compute_clock(struct intel_atomic_state *state, struct intel_crtc *crtc); int intel_dpll_crtc_get_shared_dpll(struct intel_atomic_state *state, @@ -29,14 +28,14 @@ void i9xx_dpll_get_hw_state(struct intel_crtc *crtc, void vlv_compute_dpll(struct intel_crtc_state *crtc_state); void chv_compute_dpll(struct intel_crtc_state *crtc_state); -int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe, +int vlv_force_pll_on(struct intel_display *display, enum pipe pipe, const struct dpll *dpll); -void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe); +void vlv_force_pll_off(struct intel_display *display, enum pipe pipe); void chv_enable_pll(const struct intel_crtc_state *crtc_state); -void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe); +void chv_disable_pll(struct intel_display *display, enum pipe pipe); void vlv_enable_pll(const struct intel_crtc_state *crtc_state); -void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe); +void vlv_disable_pll(struct intel_display *display, enum pipe pipe); void i9xx_enable_pll(const struct intel_crtc_state *crtc_state); void i9xx_disable_pll(const struct intel_crtc_state *crtc_state); bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index c825a507b905..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" /** @@ -257,7 +260,7 @@ void intel_enable_shared_dpll(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 intel_shared_dpll *pll = crtc_state->shared_dpll; - unsigned int pipe_mask = BIT(crtc->pipe); + unsigned int pipe_mask = intel_crtc_joined_pipe_mask(crtc_state); unsigned int old_mask; if (drm_WARN_ON(display->drm, !pll)) @@ -303,7 +306,7 @@ void intel_disable_shared_dpll(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 intel_shared_dpll *pll = crtc_state->shared_dpll; - unsigned int pipe_mask = BIT(crtc->pipe); + unsigned int pipe_mask = intel_crtc_joined_pipe_mask(crtc_state); /* PCH only available on ILK+ */ if (DISPLAY_VER(display) < 5) @@ -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); @@ -715,7 +717,6 @@ static void hsw_ddi_spll_enable(struct intel_display *display, static void hsw_ddi_wrpll_disable(struct intel_display *display, struct intel_shared_dpll *pll) { - struct drm_i915_private *i915 = to_i915(display->drm); const enum intel_dpll_id id = pll->info->id; intel_de_rmw(display, WRPLL_CTL(id), WRPLL_PLL_ENABLE, 0); @@ -726,13 +727,12 @@ static void hsw_ddi_wrpll_disable(struct intel_display *display, * that depend on it have been shut down. */ if (display->dpll.pch_ssc_use & BIT(id)) - intel_init_pch_refclk(i915); + intel_init_pch_refclk(display); } static void hsw_ddi_spll_disable(struct intel_display *display, struct intel_shared_dpll *pll) { - struct drm_i915_private *i915 = to_i915(display->drm); enum intel_dpll_id id = pll->info->id; intel_de_rmw(display, SPLL_CTL, SPLL_PLL_ENABLE, 0); @@ -743,7 +743,7 @@ static void hsw_ddi_spll_disable(struct intel_display *display, * that depend on it have been shut down. */ if (display->dpll.pch_ssc_use & BIT(id)) - intel_init_pch_refclk(i915); + intel_init_pch_refclk(display); } static bool hsw_ddi_wrpll_get_hw_state(struct intel_display *display, @@ -2606,10 +2606,8 @@ ehl_combo_pll_div_frac_wa_needed(struct intel_display *display) { return ((display->platform.elkhartlake && IS_DISPLAY_STEP(display, STEP_B0, STEP_FOREVER)) || - display->platform.tigerlake || - display->platform.alderlake_s || - display->platform.alderlake_p) && - display->dpll.ref_clks.nssc == 38400; + DISPLAY_VER(display) >= 12) && + display->dpll.ref_clks.nssc == 38400; } struct icl_combo_pll_params { @@ -4309,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; @@ -4339,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.c b/drivers/gpu/drm/i915/display/intel_dpt.c index 0d8ebe38226e..43bd97e4f589 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.c +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -9,6 +9,7 @@ #include "gt/gen8_ppgtt.h" #include "i915_drv.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dpt.h" #include "intel_fb.h" @@ -127,7 +128,7 @@ struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm, struct drm_i915_private *i915 = vm->i915; struct intel_display *display = &i915->display; struct i915_dpt *dpt = i915_vm_to_dpt(vm); - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; struct i915_vma *vma; void __iomem *iomem; struct i915_gem_ww_ctx ww; @@ -137,7 +138,7 @@ struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm, if (i915_gem_object_is_stolen(dpt->obj)) pin_flags |= PIN_MAPPABLE; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); + wakeref = intel_display_rpm_get(display); atomic_inc(&display->restore.pending_fb_pin); for_i915_gem_ww(&ww, err, true) { @@ -169,7 +170,7 @@ struct i915_vma *intel_dpt_pin_to_ggtt(struct i915_address_space *vm, dpt->obj->mm.dirty = true; atomic_dec(&display->restore.pending_fb_pin); - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); return err ? ERR_PTR(err) : vma; } 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 9fc4003d1579..481488d1fe67 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -4,13 +4,15 @@ * */ +#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" #include "intel_display_types.h" #include "intel_dsb.h" #include "intel_dsb_buffer.h" @@ -142,10 +144,10 @@ static int dsb_vtotal(struct intel_atomic_state *state, static int dsb_dewake_scanline_start(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_pre_commit_crtc_state(state, crtc); - struct drm_i915_private *i915 = to_i915(state->base.dev); - unsigned int latency = skl_watermark_max_latency(i915, 0); + unsigned int latency = skl_watermark_max_latency(display, 0); return intel_mode_vdisplay(&crtc_state->hw.adjusted_mode) - intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, latency); @@ -795,22 +797,22 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state, enum intel_dsb_id dsb_id, unsigned int max_cmds) { - struct drm_i915_private *i915 = to_i915(state->base.dev); - intel_wakeref_t wakeref; + struct intel_display *display = to_intel_display(state); + struct ref_tracker *wakeref; struct intel_dsb *dsb; unsigned int size; - if (!HAS_DSB(i915)) + if (!HAS_DSB(display)) return NULL; - if (!i915->display.params.enable_dsb) + if (!display->params.enable_dsb) return NULL; dsb = kzalloc(sizeof(*dsb), GFP_KERNEL); if (!dsb) goto out; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); + wakeref = intel_display_rpm_get(display); /* ~1 qword per instruction, full cachelines */ size = ALIGN(max_cmds * 8, CACHELINE_BYTES); @@ -818,7 +820,7 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state, if (!intel_dsb_buffer_create(crtc, &dsb->dsb_buf, size)) goto out_put_rpm; - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); dsb->id = dsb_id; dsb->crtc = crtc; @@ -831,10 +833,10 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state, return dsb; out_put_rpm: - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); kfree(dsb); out: - drm_info_once(&i915->drm, + drm_info_once(display->drm, "[CRTC:%d:%s] DSB %d queue setup failed, will fallback to MMIO for display HW programming\n", crtc->base.base.id, crtc->base.name, dsb_id); 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_dcs_backlight.c b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c index 049443245310..b3c453bf7d5c 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c +++ b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c @@ -24,9 +24,10 @@ */ #include <drm/drm_mipi_dsi.h> +#include <drm/drm_print.h> #include <video/mipi_display.h> -#include "i915_drv.h" +#include "intel_display_core.h" #include "intel_display_types.h" #include "intel_dsi.h" #include "intel_dsi_dcs_backlight.h" @@ -162,7 +163,7 @@ static void dcs_enable_backlight(const struct intel_crtc_state *crtc_state, static int dcs_setup_backlight(struct intel_connector *connector, enum pipe unused) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_panel *panel = &connector->panel; if (panel->vbt.backlight.brightness_precision_bits > 8) @@ -172,7 +173,7 @@ static int dcs_setup_backlight(struct intel_connector *connector, panel->backlight.level = panel->backlight.max; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CONNECTOR:%d:%s] Using DCS for backlight control\n", connector->base.base.id, connector->base.name); diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c index 7b2ffd14ae6e..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" @@ -102,13 +102,13 @@ static enum port intel_dsi_seq_port_to_port(struct intel_dsi *intel_dsi, static const u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi, const u8 *data) { - struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); + struct intel_display *display = to_intel_display(&intel_dsi->base); struct mipi_dsi_device *dsi_device; u8 type, flags, seq_port; u16 len; enum port port; - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); flags = *data++; type = *data++; @@ -120,12 +120,12 @@ static const u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi, port = intel_dsi_seq_port_to_port(intel_dsi, seq_port); - if (drm_WARN_ON(&dev_priv->drm, !intel_dsi->dsi_hosts[port])) + if (drm_WARN_ON(display->drm, !intel_dsi->dsi_hosts[port])) goto out; dsi_device = intel_dsi->dsi_hosts[port]->device; if (!dsi_device) { - drm_dbg_kms(&dev_priv->drm, "no dsi device for port %c\n", + drm_dbg_kms(display->drm, "no dsi device for port %c\n", port_name(port)); goto out; } @@ -150,8 +150,7 @@ static const u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi, case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM: case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM: case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM: - drm_dbg(&dev_priv->drm, - "Generic Read not yet implemented or used\n"); + drm_dbg_kms(display->drm, "Generic Read not yet implemented or used\n"); break; case MIPI_DSI_GENERIC_LONG_WRITE: mipi_dsi_generic_write(dsi_device, data, len); @@ -163,15 +162,14 @@ static const u8 *mipi_exec_send_packet(struct intel_dsi *intel_dsi, mipi_dsi_dcs_write_buffer(dsi_device, data, 2); break; case MIPI_DSI_DCS_READ: - drm_dbg(&dev_priv->drm, - "DCS Read not yet implemented or used\n"); + drm_dbg_kms(display->drm, "DCS Read not yet implemented or used\n"); break; case MIPI_DSI_DCS_LONG_WRITE: mipi_dsi_dcs_write_buffer(dsi_device, data, len); break; } - if (DISPLAY_VER(dev_priv) < 11) + if (DISPLAY_VER(display) < 11) vlv_dsi_wait_for_fifo_empty(intel_dsi, port); out: @@ -182,10 +180,10 @@ out: static const u8 *mipi_exec_delay(struct intel_dsi *intel_dsi, const u8 *data) { - struct drm_i915_private *i915 = to_i915(intel_dsi->base.base.dev); + struct intel_display *display = to_intel_display(&intel_dsi->base); u32 delay = *((const u32 *) data); - drm_dbg_kms(&i915->drm, "%d usecs\n", delay); + drm_dbg_kms(display->drm, "%d usecs\n", delay); usleep_range(delay, delay + 10); data += 4; @@ -196,7 +194,7 @@ static const u8 *mipi_exec_delay(struct intel_dsi *intel_dsi, const u8 *data) static void soc_gpio_set_value(struct intel_connector *connector, u8 gpio_index, const char *con_id, u8 idx, bool value) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); /* XXX: this table is a quick ugly hack. */ static struct gpio_desc *soc_gpio_table[U8_MAX + 1]; struct gpio_desc *gpio_desc = soc_gpio_table[gpio_index]; @@ -204,10 +202,10 @@ static void soc_gpio_set_value(struct intel_connector *connector, u8 gpio_index, if (gpio_desc) { gpiod_set_value(gpio_desc, value); } else { - gpio_desc = devm_gpiod_get_index(dev_priv->drm.dev, con_id, idx, + gpio_desc = devm_gpiod_get_index(display->drm->dev, con_id, idx, value ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW); if (IS_ERR(gpio_desc)) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "GPIO index %u request failed (%pe)\n", gpio_index, gpio_desc); return; @@ -242,16 +240,16 @@ static void soc_opaque_gpio_set_value(struct intel_connector *connector, static void vlv_gpio_set_value(struct intel_connector *connector, u8 gpio_source, u8 gpio_index, bool value) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); /* XXX: this assumes vlv_gpio_table only has NC GPIOs. */ if (connector->panel.vbt.dsi.seq_version < 3) { if (gpio_source == 1) { - drm_dbg_kms(&dev_priv->drm, "SC gpio not supported\n"); + drm_dbg_kms(display->drm, "SC gpio not supported\n"); return; } if (gpio_source > 1) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "unknown gpio source %u\n", gpio_source); return; } @@ -264,7 +262,7 @@ static void vlv_gpio_set_value(struct intel_connector *connector, static void chv_gpio_set_value(struct intel_connector *connector, u8 gpio_source, u8 gpio_index, bool value) { - struct drm_i915_private *dev_priv = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); if (connector->panel.vbt.dsi.seq_version >= 3) { if (gpio_index >= CHV_GPIO_IDX_START_SE) { @@ -284,13 +282,13 @@ static void chv_gpio_set_value(struct intel_connector *connector, } else { /* XXX: The spec is unclear about CHV GPIO on seq v2 */ if (gpio_source != 0) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "unknown gpio source %u\n", gpio_source); return; } if (gpio_index >= CHV_GPIO_IDX_START_E) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "invalid gpio index %u for GPIO N\n", gpio_index); return; @@ -320,13 +318,12 @@ enum { MIPI_VIO_EN_2, }; -static void icl_native_gpio_set_value(struct drm_i915_private *dev_priv, +static void icl_native_gpio_set_value(struct intel_display *display, int gpio, bool value) { - struct intel_display *display = &dev_priv->display; int index; - if (drm_WARN_ON(&dev_priv->drm, DISPLAY_VER(dev_priv) == 11 && gpio >= MIPI_RESET_2)) + if (drm_WARN_ON(display->drm, DISPLAY_VER(display) == 11 && gpio >= MIPI_RESET_2)) return; switch (gpio) { @@ -343,25 +340,25 @@ static void icl_native_gpio_set_value(struct drm_i915_private *dev_priv, * The locking protects against concurrent SHOTPLUG_CTL_DDI * modifications in irq setup and handling. */ - spin_lock_irq(&dev_priv->irq_lock); - intel_de_rmw(dev_priv, SHOTPLUG_CTL_DDI, + 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: index = gpio == MIPI_AVDD_EN_1 ? 0 : 1; - intel_de_rmw(dev_priv, PP_CONTROL(dev_priv, index), PANEL_POWER_ON, + intel_de_rmw(display, PP_CONTROL(display, index), PANEL_POWER_ON, value ? PANEL_POWER_ON : 0); break; case MIPI_BKLT_EN_1: case MIPI_BKLT_EN_2: index = gpio == MIPI_BKLT_EN_1 ? 0 : 1; - intel_de_rmw(dev_priv, PP_CONTROL(dev_priv, index), EDP_BLC_ENABLE, + intel_de_rmw(display, PP_CONTROL(display, index), EDP_BLC_ENABLE, value ? EDP_BLC_ENABLE : 0); break; case MIPI_AVEE_EN_1: @@ -389,13 +386,12 @@ static void icl_native_gpio_set_value(struct drm_i915_private *dev_priv, static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) { - struct drm_device *dev = intel_dsi->base.base.dev; - struct drm_i915_private *i915 = to_i915(dev); + struct intel_display *display = to_intel_display(&intel_dsi->base); struct intel_connector *connector = intel_dsi->attached_connector; u8 gpio_source = 0, gpio_index = 0, gpio_number; bool value; int size; - bool native = DISPLAY_VER(i915) >= 11; + bool native = DISPLAY_VER(display) >= 11; if (connector->panel.vbt.dsi.seq_version >= 3) { size = 3; @@ -416,16 +412,16 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data) gpio_source = (data[1] >> 1) & 3; } - drm_dbg_kms(&i915->drm, "GPIO index %u, number %u, source %u, native %s, set to %s\n", + drm_dbg_kms(display->drm, "GPIO index %u, number %u, source %u, native %s, set to %s\n", gpio_index, gpio_number, gpio_source, str_yes_no(native), str_on_off(value)); if (native) - icl_native_gpio_set_value(i915, gpio_number, value); - else if (DISPLAY_VER(i915) >= 9) + icl_native_gpio_set_value(display, gpio_number, value); + else if (DISPLAY_VER(display) >= 9) bxt_gpio_set_value(connector, gpio_index, value); - else if (IS_VALLEYVIEW(i915)) + else if (display->platform.valleyview) vlv_gpio_set_value(connector, gpio_source, gpio_number, value); - else if (IS_CHERRYVIEW(i915)) + else if (display->platform.cherryview) chv_gpio_set_value(connector, gpio_source, gpio_number, value); return data + size; @@ -463,8 +459,8 @@ static int i2c_adapter_lookup(struct acpi_resource *ares, void *data) static void i2c_acpi_find_adapter(struct intel_dsi *intel_dsi, const u16 target_addr) { - struct drm_device *drm_dev = intel_dsi->base.base.dev; - struct acpi_device *adev = ACPI_COMPANION(drm_dev->dev); + struct intel_display *display = to_intel_display(&intel_dsi->base); + struct acpi_device *adev = ACPI_COMPANION(display->drm->dev); struct i2c_adapter_lookup lookup = { .target_addr = target_addr, .intel_dsi = intel_dsi, @@ -484,7 +480,7 @@ static inline void i2c_acpi_find_adapter(struct intel_dsi *intel_dsi, static const u8 *mipi_exec_i2c(struct intel_dsi *intel_dsi, const u8 *data) { - struct drm_i915_private *i915 = to_i915(intel_dsi->base.base.dev); + struct intel_display *display = to_intel_display(&intel_dsi->base); struct i2c_adapter *adapter; struct i2c_msg msg; int ret; @@ -494,7 +490,7 @@ static const u8 *mipi_exec_i2c(struct intel_dsi *intel_dsi, const u8 *data) u8 payload_size = *(data + 6); u8 *payload_data; - drm_dbg_kms(&i915->drm, "bus %d target-addr 0x%02x reg 0x%02x data %*ph\n", + drm_dbg_kms(display->drm, "bus %d target-addr 0x%02x reg 0x%02x data %*ph\n", vbt_i2c_bus_num, target_addr, reg_offset, payload_size, data + 7); if (intel_dsi->i2c_bus_num < 0) { @@ -504,7 +500,7 @@ static const u8 *mipi_exec_i2c(struct intel_dsi *intel_dsi, const u8 *data) adapter = i2c_get_adapter(intel_dsi->i2c_bus_num); if (!adapter) { - drm_err(&i915->drm, "Cannot find a valid i2c bus for xfer\n"); + drm_err(display->drm, "Cannot find a valid i2c bus for xfer\n"); goto err_bus; } @@ -522,7 +518,7 @@ static const u8 *mipi_exec_i2c(struct intel_dsi *intel_dsi, const u8 *data) ret = i2c_transfer(adapter, &msg, 1); if (ret < 0) - drm_err(&i915->drm, + drm_err(display->drm, "Failed to xfer payload of size (%u) to reg (%u)\n", payload_size, reg_offset); @@ -535,16 +531,16 @@ err_bus: static const u8 *mipi_exec_spi(struct intel_dsi *intel_dsi, const u8 *data) { - struct drm_i915_private *i915 = to_i915(intel_dsi->base.base.dev); + struct intel_display *display = to_intel_display(&intel_dsi->base); - drm_dbg_kms(&i915->drm, "Skipping SPI element execution\n"); + drm_dbg_kms(display->drm, "Skipping SPI element execution\n"); return data + *(data + 5) + 6; } static const u8 *mipi_exec_pmic(struct intel_dsi *intel_dsi, const u8 *data) { - struct drm_i915_private *i915 = to_i915(intel_dsi->base.base.dev); + struct intel_display *display = to_intel_display(&intel_dsi->base); #ifdef CONFIG_PMIC_OPREGION u32 value, mask, reg_address; u16 i2c_address; @@ -560,9 +556,9 @@ static const u8 *mipi_exec_pmic(struct intel_dsi *intel_dsi, const u8 *data) reg_address, value, mask); if (ret) - drm_err(&i915->drm, "%s failed, error: %d\n", __func__, ret); + drm_err(display->drm, "%s failed, error: %d\n", __func__, ret); #else - drm_err(&i915->drm, + drm_err(display->drm, "Your hardware requires CONFIG_PMIC_OPREGION and it is not set\n"); #endif @@ -612,12 +608,12 @@ static const char *sequence_name(enum mipi_seq seq_id) static void intel_dsi_vbt_exec(struct intel_dsi *intel_dsi, enum mipi_seq seq_id) { - struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); + struct intel_display *display = to_intel_display(&intel_dsi->base); struct intel_connector *connector = intel_dsi->attached_connector; const u8 *data; fn_mipi_elem_exec mipi_elem_exec; - if (drm_WARN_ON(&dev_priv->drm, + if (drm_WARN_ON(display->drm, seq_id >= ARRAY_SIZE(connector->panel.vbt.dsi.sequence))) return; @@ -625,9 +621,9 @@ static void intel_dsi_vbt_exec(struct intel_dsi *intel_dsi, if (!data) return; - drm_WARN_ON(&dev_priv->drm, *data != seq_id); + drm_WARN_ON(display->drm, *data != seq_id); - drm_dbg_kms(&dev_priv->drm, "Starting MIPI sequence %d - %s\n", + drm_dbg_kms(display->drm, "Starting MIPI sequence %d - %s\n", seq_id, sequence_name(seq_id)); /* Skip Sequence Byte. */ @@ -657,19 +653,19 @@ static void intel_dsi_vbt_exec(struct intel_dsi *intel_dsi, /* Consistency check if we have size. */ if (operation_size && data != next) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "Inconsistent operation size\n"); return; } } else if (operation_size) { /* We have size, skip. */ - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Unsupported MIPI operation byte %u\n", operation_byte); data += operation_size; } else { /* No size, can't skip without parsing. */ - drm_err(&dev_priv->drm, + drm_err(display->drm, "Unsupported MIPI operation byte %u\n", operation_byte); return; @@ -695,54 +691,44 @@ void intel_dsi_vbt_exec_sequence(struct intel_dsi *intel_dsi, void intel_dsi_log_params(struct intel_dsi *intel_dsi) { - struct drm_i915_private *i915 = to_i915(intel_dsi->base.base.dev); - - drm_dbg_kms(&i915->drm, "Pclk %d\n", intel_dsi->pclk); - drm_dbg_kms(&i915->drm, "Pixel overlap %d\n", - intel_dsi->pixel_overlap); - drm_dbg_kms(&i915->drm, "Lane count %d\n", intel_dsi->lane_count); - drm_dbg_kms(&i915->drm, "DPHY param reg 0x%x\n", intel_dsi->dphy_reg); - drm_dbg_kms(&i915->drm, "Video mode format %s\n", - intel_dsi->video_mode == NON_BURST_SYNC_PULSE ? - "non-burst with sync pulse" : - intel_dsi->video_mode == NON_BURST_SYNC_EVENTS ? - "non-burst with sync events" : - intel_dsi->video_mode == BURST_MODE ? - "burst" : "<unknown>"); - drm_dbg_kms(&i915->drm, "Burst mode ratio %d\n", - intel_dsi->burst_mode_ratio); - drm_dbg_kms(&i915->drm, "Reset timer %d\n", intel_dsi->rst_timer_val); - drm_dbg_kms(&i915->drm, "Eot %s\n", - str_enabled_disabled(intel_dsi->eotp_pkt)); - drm_dbg_kms(&i915->drm, "Clockstop %s\n", - str_enabled_disabled(!intel_dsi->clock_stop)); - drm_dbg_kms(&i915->drm, "Mode %s\n", - intel_dsi->operation_mode ? "command" : "video"); + struct intel_display *display = to_intel_display(&intel_dsi->base); + struct drm_printer p = drm_dbg_printer(display->drm, DRM_UT_KMS, + "DSI parameters:"); + + drm_printf(&p, "Pclk %d\n", intel_dsi->pclk); + drm_printf(&p, "Pixel overlap %d\n", intel_dsi->pixel_overlap); + drm_printf(&p, "Lane count %d\n", intel_dsi->lane_count); + drm_printf(&p, "DPHY param reg 0x%x\n", intel_dsi->dphy_reg); + drm_printf(&p, "Video mode format %s\n", + intel_dsi->video_mode == NON_BURST_SYNC_PULSE ? + "non-burst with sync pulse" : + intel_dsi->video_mode == NON_BURST_SYNC_EVENTS ? + "non-burst with sync events" : + intel_dsi->video_mode == BURST_MODE ? + "burst" : "<unknown>"); + drm_printf(&p, "Burst mode ratio %d\n", intel_dsi->burst_mode_ratio); + drm_printf(&p, "Reset timer %d\n", intel_dsi->rst_timer_val); + drm_printf(&p, "Eot %s\n", str_enabled_disabled(intel_dsi->eotp_pkt)); + drm_printf(&p, "Clockstop %s\n", str_enabled_disabled(!intel_dsi->clock_stop)); + drm_printf(&p, "Mode %s\n", intel_dsi->operation_mode ? "command" : "video"); if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) - drm_dbg_kms(&i915->drm, - "Dual link: DSI_DUAL_LINK_FRONT_BACK\n"); + drm_printf(&p, "Dual link: DSI_DUAL_LINK_FRONT_BACK\n"); else if (intel_dsi->dual_link == DSI_DUAL_LINK_PIXEL_ALT) - drm_dbg_kms(&i915->drm, - "Dual link: DSI_DUAL_LINK_PIXEL_ALT\n"); + drm_printf(&p, "Dual link: DSI_DUAL_LINK_PIXEL_ALT\n"); else - drm_dbg_kms(&i915->drm, "Dual link: NONE\n"); - drm_dbg_kms(&i915->drm, "Pixel Format %d\n", intel_dsi->pixel_format); - drm_dbg_kms(&i915->drm, "TLPX %d\n", intel_dsi->escape_clk_div); - drm_dbg_kms(&i915->drm, "LP RX Timeout 0x%x\n", - intel_dsi->lp_rx_timeout); - drm_dbg_kms(&i915->drm, "Turnaround Timeout 0x%x\n", - intel_dsi->turn_arnd_val); - drm_dbg_kms(&i915->drm, "Init Count 0x%x\n", intel_dsi->init_count); - drm_dbg_kms(&i915->drm, "HS to LP Count 0x%x\n", - intel_dsi->hs_to_lp_count); - drm_dbg_kms(&i915->drm, "LP Byte Clock %d\n", intel_dsi->lp_byte_clk); - drm_dbg_kms(&i915->drm, "DBI BW Timer 0x%x\n", intel_dsi->bw_timer); - drm_dbg_kms(&i915->drm, "LP to HS Clock Count 0x%x\n", - intel_dsi->clk_lp_to_hs_count); - drm_dbg_kms(&i915->drm, "HS to LP Clock Count 0x%x\n", - intel_dsi->clk_hs_to_lp_count); - drm_dbg_kms(&i915->drm, "BTA %s\n", - str_enabled_disabled(!(intel_dsi->video_frmt_cfg_bits & DISABLE_VIDEO_BTA))); + drm_printf(&p, "Dual link: NONE\n"); + drm_printf(&p, "Pixel Format %d\n", intel_dsi->pixel_format); + drm_printf(&p, "TLPX %d\n", intel_dsi->escape_clk_div); + drm_printf(&p, "LP RX Timeout 0x%x\n", intel_dsi->lp_rx_timeout); + drm_printf(&p, "Turnaround Timeout 0x%x\n", intel_dsi->turn_arnd_val); + drm_printf(&p, "Init Count 0x%x\n", intel_dsi->init_count); + drm_printf(&p, "HS to LP Count 0x%x\n", intel_dsi->hs_to_lp_count); + drm_printf(&p, "LP Byte Clock %d\n", intel_dsi->lp_byte_clk); + drm_printf(&p, "DBI BW Timer 0x%x\n", intel_dsi->bw_timer); + drm_printf(&p, "LP to HS Clock Count 0x%x\n", intel_dsi->clk_lp_to_hs_count); + drm_printf(&p, "HS to LP Clock Count 0x%x\n", intel_dsi->clk_hs_to_lp_count); + drm_printf(&p, "BTA %s\n", + str_enabled_disabled(!(intel_dsi->video_frmt_cfg_bits & DISABLE_VIDEO_BTA))); } static enum mipi_dsi_pixel_format vbt_to_dsi_pixel_format(unsigned int format) @@ -764,8 +750,7 @@ static enum mipi_dsi_pixel_format vbt_to_dsi_pixel_format(unsigned int format) bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) { - struct drm_device *dev = intel_dsi->base.base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(&intel_dsi->base); struct intel_connector *connector = intel_dsi->attached_connector; struct mipi_config *mipi_config = connector->panel.vbt.dsi.config; struct mipi_pps_data *pps = connector->panel.vbt.dsi.pps; @@ -773,7 +758,7 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) u16 burst_mode_ratio; enum port port; - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); intel_dsi->eotp_pkt = mipi_config->eot_pkt_disabled ? 0 : 1; intel_dsi->clock_stop = mipi_config->enable_clk_stop ? 1 : 0; @@ -819,7 +804,7 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) u32 bitrate; if (mipi_config->target_burst_mode_freq == 0) { - drm_err(&dev_priv->drm, "Burst mode target is not set\n"); + drm_err(display->drm, "Burst mode target is not set\n"); return false; } @@ -836,7 +821,7 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id) mipi_config->target_burst_mode_freq = bitrate; if (mipi_config->target_burst_mode_freq < bitrate) { - drm_err(&dev_priv->drm, "Burst mode freq is less than computed\n"); + drm_err(display->drm, "Burst mode freq is less than computed\n"); return false; } @@ -900,8 +885,7 @@ static const struct pinctrl_map soc_pwm_pinctrl_map[] = { void intel_dsi_vbt_gpio_init(struct intel_dsi *intel_dsi, bool panel_is_on) { - struct drm_device *dev = intel_dsi->base.base.dev; - struct drm_i915_private *dev_priv = to_i915(dev); + struct intel_display *display = to_intel_display(&intel_dsi->base); struct intel_connector *connector = intel_dsi->attached_connector; struct mipi_config *mipi_config = connector->panel.vbt.dsi.config; enum gpiod_flags flags = panel_is_on ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; @@ -911,13 +895,13 @@ void intel_dsi_vbt_gpio_init(struct intel_dsi *intel_dsi, bool panel_is_on) struct pinctrl *pinctrl; int ret; - if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && + if ((display->platform.valleyview || display->platform.cherryview) && mipi_config->pwm_blc == PPS_BLC_PMIC) { gpiod_lookup_table = &pmic_panel_gpio_table; want_panel_gpio = true; } - if (IS_VALLEYVIEW(dev_priv) && mipi_config->pwm_blc == PPS_BLC_SOC) { + if (display->platform.valleyview && mipi_config->pwm_blc == PPS_BLC_SOC) { gpiod_lookup_table = &soc_panel_gpio_table; want_panel_gpio = true; want_backlight_gpio = true; @@ -926,12 +910,12 @@ void intel_dsi_vbt_gpio_init(struct intel_dsi *intel_dsi, bool panel_is_on) ret = pinctrl_register_mappings(soc_pwm_pinctrl_map, ARRAY_SIZE(soc_pwm_pinctrl_map)); if (ret) - drm_err(&dev_priv->drm, + drm_err(display->drm, "Failed to register pwm0 pinmux mapping\n"); - pinctrl = devm_pinctrl_get_select(dev->dev, "soc_pwm0"); + pinctrl = devm_pinctrl_get_select(display->drm->dev, "soc_pwm0"); if (IS_ERR(pinctrl)) - drm_err(&dev_priv->drm, + drm_err(display->drm, "Failed to set pinmux to PWM\n"); } @@ -939,9 +923,9 @@ void intel_dsi_vbt_gpio_init(struct intel_dsi *intel_dsi, bool panel_is_on) gpiod_add_lookup_table(gpiod_lookup_table); if (want_panel_gpio) { - intel_dsi->gpio_panel = devm_gpiod_get(dev->dev, "panel", flags); + intel_dsi->gpio_panel = devm_gpiod_get(display->drm->dev, "panel", flags); if (IS_ERR(intel_dsi->gpio_panel)) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "Failed to own gpio for panel control\n"); intel_dsi->gpio_panel = NULL; } @@ -949,9 +933,9 @@ void intel_dsi_vbt_gpio_init(struct intel_dsi *intel_dsi, bool panel_is_on) if (want_backlight_gpio) { intel_dsi->gpio_backlight = - devm_gpiod_get(dev->dev, "backlight", flags); + devm_gpiod_get(display->drm->dev, "backlight", flags); if (IS_ERR(intel_dsi->gpio_backlight)) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "Failed to own gpio for backlight control\n"); intel_dsi->gpio_backlight = NULL; } diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c index c16fb34b737d..b61520353c92 100644 --- a/drivers/gpu/drm/i915/display/intel_dvo.c +++ b/drivers/gpu/drm/i915/display/intel_dvo.c @@ -31,10 +31,11 @@ #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 "i915_utils.h" #include "intel_connector.h" #include "intel_de.h" #include "intel_display_driver.h" @@ -129,13 +130,13 @@ static struct intel_dvo *intel_attached_dvo(struct intel_connector *connector) static bool intel_dvo_connector_get_hw_state(struct intel_connector *connector) { - struct drm_i915_private *i915 = to_i915(connector->base.dev); + struct intel_display *display = to_intel_display(connector); struct intel_encoder *encoder = intel_attached_encoder(connector); struct intel_dvo *intel_dvo = enc_to_dvo(encoder); enum port port = encoder->port; u32 tmp; - tmp = intel_de_read(i915, DVO(port)); + tmp = intel_de_read(display, DVO(port)); if (!(tmp & DVO_ENABLE)) return false; @@ -146,11 +147,11 @@ static bool intel_dvo_connector_get_hw_state(struct intel_connector *connector) static bool intel_dvo_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; u32 tmp; - tmp = intel_de_read(i915, DVO(port)); + tmp = intel_de_read(display, DVO(port)); *pipe = REG_FIELD_GET(DVO_PIPE_SEL_MASK, tmp); @@ -160,13 +161,13 @@ static bool intel_dvo_get_hw_state(struct intel_encoder *encoder, static void intel_dvo_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); enum port port = encoder->port; u32 tmp, flags = 0; pipe_config->output_types |= BIT(INTEL_OUTPUT_DVO); - tmp = intel_de_read(i915, DVO(port)); + tmp = intel_de_read(display, DVO(port)); if (tmp & DVO_HSYNC_ACTIVE_HIGH) flags |= DRM_MODE_FLAG_PHSYNC; else @@ -186,14 +187,14 @@ static void intel_disable_dvo(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 *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dvo *intel_dvo = enc_to_dvo(encoder); enum port port = encoder->port; intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false); - intel_de_rmw(i915, DVO(port), DVO_ENABLE, 0); - intel_de_posting_read(i915, DVO(port)); + intel_de_rmw(display, DVO(port), DVO_ENABLE, 0); + intel_de_posting_read(display, DVO(port)); } static void intel_enable_dvo(struct intel_atomic_state *state, @@ -201,7 +202,7 @@ static void intel_enable_dvo(struct intel_atomic_state *state, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dvo *intel_dvo = enc_to_dvo(encoder); enum port port = encoder->port; @@ -209,8 +210,8 @@ static void intel_enable_dvo(struct intel_atomic_state *state, &pipe_config->hw.mode, &pipe_config->hw.adjusted_mode); - intel_de_rmw(i915, DVO(port), 0, DVO_ENABLE); - intel_de_posting_read(i915, DVO(port)); + intel_de_rmw(display, DVO(port), 0, DVO_ENABLE); + intel_de_posting_read(display, DVO(port)); intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true); } @@ -288,7 +289,7 @@ static void intel_dvo_pre_enable(struct intel_atomic_state *state, const struct intel_crtc_state *pipe_config, const struct drm_connector_state *conn_state) { - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; enum port port = encoder->port; @@ -296,7 +297,7 @@ static void intel_dvo_pre_enable(struct intel_atomic_state *state, u32 dvo_val; /* Save the active data order, since I don't know what it should be set to. */ - dvo_val = intel_de_read(i915, DVO(port)) & + dvo_val = intel_de_read(display, DVO(port)) & (DVO_DEDICATED_INT_ENABLE | DVO_PRESERVE_MASK | DVO_ACT_DATA_ORDER_MASK); dvo_val |= DVO_DATA_ORDER_FP | DVO_BORDER_ENABLE | @@ -309,10 +310,10 @@ static void intel_dvo_pre_enable(struct intel_atomic_state *state, if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) dvo_val |= DVO_VSYNC_ACTIVE_HIGH; - intel_de_write(i915, DVO_SRCDIM(port), + intel_de_write(display, DVO_SRCDIM(port), DVO_SRCDIM_HORIZONTAL(adjusted_mode->crtc_hdisplay) | DVO_SRCDIM_VERTICAL(adjusted_mode->crtc_vdisplay)); - intel_de_write(i915, DVO(port), dvo_val); + intel_de_write(display, DVO(port), dvo_val); } static enum drm_connector_status @@ -320,10 +321,9 @@ intel_dvo_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 drm_i915_private *i915 = to_i915(connector->base.dev); struct intel_dvo *intel_dvo = intel_attached_dvo(connector); - 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 (!intel_display_device_enabled(display)) @@ -414,11 +414,10 @@ static int intel_dvo_connector_type(const struct intel_dvo_device *dvo) } } -static bool intel_dvo_init_dev(struct drm_i915_private *dev_priv, +static bool intel_dvo_init_dev(struct intel_display *display, struct intel_dvo *intel_dvo, const struct intel_dvo_device *dvo) { - struct intel_display *display = &dev_priv->display; struct i2c_adapter *i2c; u32 dpll[I915_MAX_PIPES]; enum pipe pipe; @@ -458,15 +457,15 @@ static bool intel_dvo_init_dev(struct drm_i915_private *dev_priv, * the clock enabled before we attempt to initialize * the device. */ - for_each_pipe(dev_priv, pipe) - dpll[pipe] = intel_de_rmw(dev_priv, DPLL(dev_priv, pipe), 0, + for_each_pipe(display, pipe) + dpll[pipe] = intel_de_rmw(display, DPLL(display, pipe), 0, DPLL_DVO_2X_MODE); ret = dvo->dev_ops->init(&intel_dvo->dev, i2c); /* restore the DVO 2x clock state to original */ - for_each_pipe(dev_priv, pipe) { - intel_de_write(dev_priv, DPLL(dev_priv, pipe), dpll[pipe]); + for_each_pipe(display, pipe) { + intel_de_write(display, DPLL(display, pipe), dpll[pipe]); } intel_gmbus_force_bit(i2c, false); @@ -474,14 +473,14 @@ static bool intel_dvo_init_dev(struct drm_i915_private *dev_priv, return ret; } -static bool intel_dvo_probe(struct drm_i915_private *i915, +static bool intel_dvo_probe(struct intel_display *display, struct intel_dvo *intel_dvo) { int i; /* Now, try to find a controller */ for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { - if (intel_dvo_init_dev(i915, intel_dvo, + if (intel_dvo_init_dev(display, intel_dvo, &intel_dvo_devices[i])) return true; } @@ -489,9 +488,8 @@ static bool intel_dvo_probe(struct drm_i915_private *i915, return false; } -void intel_dvo_init(struct drm_i915_private *i915) +void intel_dvo_init(struct intel_display *display) { - struct intel_display *display = &i915->display; struct intel_connector *connector; struct intel_encoder *encoder; struct intel_dvo *intel_dvo; @@ -518,7 +516,7 @@ void intel_dvo_init(struct drm_i915_private *i915) encoder->pre_enable = intel_dvo_pre_enable; connector->get_hw_state = intel_dvo_connector_get_hw_state; - if (!intel_dvo_probe(i915, intel_dvo)) { + if (!intel_dvo_probe(display, intel_dvo)) { kfree(intel_dvo); intel_connector_free(connector); return; @@ -535,12 +533,12 @@ void intel_dvo_init(struct drm_i915_private *i915) encoder->cloneable = BIT(INTEL_OUTPUT_ANALOG) | BIT(INTEL_OUTPUT_DVO); - drm_encoder_init(&i915->drm, &encoder->base, + drm_encoder_init(display->drm, &encoder->base, &intel_dvo_enc_funcs, intel_dvo_encoder_type(&intel_dvo->dev), "DVO %c", port_name(encoder->port)); - drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] detected %s\n", + drm_dbg_kms(display->drm, "[ENCODER:%d:%s] detected %s\n", encoder->base.base.id, encoder->base.name, intel_dvo->dev.name); @@ -549,7 +547,7 @@ void intel_dvo_init(struct drm_i915_private *i915) DRM_CONNECTOR_POLL_DISCONNECT; connector->base.polled = connector->polled; - drm_connector_init_with_ddc(&i915->drm, &connector->base, + drm_connector_init_with_ddc(display->drm, &connector->base, &intel_dvo_connector_funcs, intel_dvo_connector_type(&intel_dvo->dev), intel_gmbus_get_adapter(display, GMBUS_PIN_DPC)); diff --git a/drivers/gpu/drm/i915/display/intel_dvo.h b/drivers/gpu/drm/i915/display/intel_dvo.h index bf7a356422ab..83776552fc87 100644 --- a/drivers/gpu/drm/i915/display/intel_dvo.h +++ b/drivers/gpu/drm/i915/display/intel_dvo.h @@ -6,12 +6,12 @@ #ifndef __INTEL_DVO_H__ #define __INTEL_DVO_H__ -struct drm_i915_private; +struct intel_display; #ifdef I915 -void intel_dvo_init(struct drm_i915_private *dev_priv); +void intel_dvo_init(struct intel_display *display); #else -static inline void intel_dvo_init(struct drm_i915_private *dev_priv) +static inline void intel_dvo_init(struct intel_display *display) { } #endif 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_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c index 30ac9b089ad6..c648ab8a93d7 100644 --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c @@ -12,6 +12,7 @@ #include "i915_drv.h" #include "intel_atomic_plane.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_dpt.h" #include "intel_fb.h" @@ -117,7 +118,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, struct drm_i915_private *dev_priv = to_i915(dev); struct drm_gem_object *_obj = intel_fb_bo(fb); struct drm_i915_gem_object *obj = to_intel_bo(_obj); - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; struct i915_gem_ww_ctx ww; struct i915_vma *vma; unsigned int pinctl; @@ -136,7 +137,7 @@ intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, * intel_runtime_pm_put(), so it is correct to wrap only the * pin/unpin/fence and not more. */ - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + wakeref = intel_display_rpm_get(display); atomic_inc(&display->restore.pending_fb_pin); @@ -215,7 +216,7 @@ err: vma = ERR_PTR(ret); atomic_dec(&display->restore.pending_fb_pin); - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); return vma; } diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index b6978135e8ad..bed2bba20b55 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -55,6 +55,7 @@ #include "intel_cdclk.h" #include "intel_de.h" #include "intel_display_device.h" +#include "intel_display_rpm.h" #include "intel_display_trace.h" #include "intel_display_types.h" #include "intel_display_wa.h" @@ -251,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; @@ -519,6 +523,20 @@ static void ilk_fbc_activate(struct intel_fbc *fbc) DPFC_CTL_EN | g4x_dpfc_ctl(fbc)); } +static void fbc_compressor_clkgate_disable_wa(struct intel_fbc *fbc, + bool disable) +{ + struct intel_display *display = fbc->display; + + if (display->platform.dg2) + intel_de_rmw(display, GEN9_CLKGATE_DIS_4, DG2_DPFC_GATING_DIS, + disable ? DG2_DPFC_GATING_DIS : 0); + else if (DISPLAY_VER(display) >= 14) + intel_de_rmw(display, MTL_PIPE_CLKGATE_DIS2(fbc->id), + MTL_DPFC_GATING_DIS, + disable ? MTL_DPFC_GATING_DIS : 0); +} + static void ilk_fbc_deactivate(struct intel_fbc *fbc) { struct intel_display *display = fbc->display; @@ -532,6 +550,10 @@ static void ilk_fbc_deactivate(struct intel_fbc *fbc) if (dpfc_ctl & DPFC_CTL_EN) { dpfc_ctl &= ~DPFC_CTL_EN; intel_de_write(display, ILK_DPFC_CONTROL(fbc->id), dpfc_ctl); + + /* wa_18038517565 Enable DPFC clock gating after FBC disable */ + if (display->platform.dg2 || DISPLAY_VER(display) >= 14) + fbc_compressor_clkgate_disable_wa(fbc, false); } } @@ -921,6 +943,10 @@ static void intel_fbc_program_workarounds(struct intel_fbc *fbc) if (DISPLAY_VER(display) >= 11 && !display->platform.dg2) intel_de_rmw(display, ILK_DPFC_CHICKEN(fbc->id), 0, DPFC_CHICKEN_FORCE_SLB_INVALIDATION); + + /* wa_18038517565 Disable DPFC clock gating before FBC enable */ + if (display->platform.dg2 || DISPLAY_VER(display) >= 14) + fbc_compressor_clkgate_disable_wa(fbc, true); } static void __intel_fbc_cleanup_cfb(struct intel_fbc *fbc) @@ -1436,7 +1462,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, return 0; } - if (intel_display_needs_wa_16023588340(i915)) { + if (intel_display_needs_wa_16023588340(display)) { plane_state->no_fbc_reason = "Wa_16023588340"; return 0; } @@ -1464,14 +1490,15 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, * Recommendation is to keep this combination disabled * Bspec: 50422 HSD: 14010260002 * - * In Xe3, PSR2 selective fetch and FBC dirty rect feature cannot - * coexist. So if PSR2 selective fetch is supported then mark that - * FBC is not supported. - * TODO: Need a logic to decide between PSR2 and FBC Dirty rect + * TODO: Implement a logic to select between PSR2 selective fetch and + * FBC based on Bspec: 68881 in xe2lpd onwards. + * + * As we still see some strange underruns in those platforms while + * disabling PSR2, keep FBC disabled in case of selective update is on + * until the selection logic is implemented. */ - if ((IS_DISPLAY_VER(display, 12, 14) || HAS_FBC_DIRTY_RECT(display)) && - crtc_state->has_sel_update && !crtc_state->has_panel_replay) { - plane_state->no_fbc_reason = "PSR2 enabled"; + if (DISPLAY_VER(display) >= 12 && crtc_state->has_sel_update) { + plane_state->no_fbc_reason = "Selective update enabled"; return 0; } @@ -2120,13 +2147,12 @@ static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused) { struct intel_fbc *fbc = m->private; struct intel_display *display = fbc->display; - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_plane *plane; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; drm_modeset_lock_all(display->drm); - wakeref = intel_runtime_pm_get(&i915->runtime_pm); + wakeref = intel_display_rpm_get(display); mutex_lock(&fbc->lock); if (fbc->active) { @@ -2151,7 +2177,7 @@ static int intel_fbc_debugfs_status_show(struct seq_file *m, void *unused) } mutex_unlock(&fbc->lock); - intel_runtime_pm_put(&i915->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); drm_modeset_unlock_all(display->drm); diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index adc19d5607de..2dc4029d71ed 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c @@ -47,9 +47,10 @@ #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" #include "intel_fb_pin.h" @@ -65,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) @@ -209,11 +210,10 @@ 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); - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; struct fb_info *info; struct i915_vma *vma; unsigned long flags = 0; @@ -226,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, @@ -234,20 +234,20 @@ 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; } - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + wakeref = intel_display_rpm_get(display); /* Pin the GGTT vma for our access via info->screen_base. * This also validates that any existing fb inherited from the @@ -265,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; } @@ -277,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 @@ -292,21 +292,22 @@ 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; ifbdev->vma = vma; ifbdev->vma_flags = flags; - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); return 0; out_unpin: intel_fb_unpin_vma(vma, flags); out_unlock: - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); + return ret; } @@ -319,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 = @@ -338,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); @@ -361,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 = @@ -375,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); /* @@ -392,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]); @@ -403,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, @@ -412,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); @@ -420,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; } @@ -437,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 = @@ -448,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: @@ -479,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 7a8fbff39be0..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); @@ -136,24 +133,22 @@ static void i9xx_set_fifo_underrun_reporting(struct intel_display *display, static void ilk_set_fifo_underrun_reporting(struct intel_display *display, enum pipe pipe, bool enable) { - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 bit = (pipe == PIPE_A) ? DE_PIPEA_FIFO_UNDERRUN : DE_PIPEB_FIFO_UNDERRUN; if (enable) - ilk_enable_display_irq(dev_priv, bit); + ilk_enable_display_irq(display, bit); else - ilk_disable_display_irq(dev_priv, bit); + ilk_disable_display_irq(display, bit); } 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; @@ -169,7 +164,6 @@ static void ivb_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); if (enable) { intel_de_write(display, GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe)); @@ -177,9 +171,9 @@ static void ivb_set_fifo_underrun_reporting(struct intel_display *display, if (!ivb_can_enable_err_int(display)) return; - ilk_enable_display_irq(dev_priv, DE_ERR_INT_IVB); + ilk_enable_display_irq(display, DE_ERR_INT_IVB); } else { - ilk_disable_display_irq(dev_priv, DE_ERR_INT_IVB); + ilk_disable_display_irq(display, DE_ERR_INT_IVB); if (old && intel_de_read(display, GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe)) { @@ -193,36 +187,32 @@ static void ivb_set_fifo_underrun_reporting(struct intel_display *display, static void bdw_set_fifo_underrun_reporting(struct intel_display *display, enum pipe pipe, bool enable) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (enable) - bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_FIFO_UNDERRUN); + bdw_enable_pipe_irq(display, pipe, GEN8_PIPE_FIFO_UNDERRUN); else - bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_FIFO_UNDERRUN); + bdw_disable_pipe_irq(display, pipe, GEN8_PIPE_FIFO_UNDERRUN); } static void ibx_set_fifo_underrun_reporting(struct intel_display *display, enum pipe pch_transcoder, bool enable) { - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 bit = (pch_transcoder == PIPE_A) ? SDE_TRANSA_FIFO_UNDER : SDE_TRANSB_FIFO_UNDER; if (enable) - ibx_enable_display_interrupt(dev_priv, bit); + ibx_enable_display_interrupt(display, bit); else - ibx_disable_display_interrupt(dev_priv, bit); + ibx_disable_display_interrupt(display, bit); } 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; @@ -240,8 +230,6 @@ static void cpt_set_fifo_underrun_reporting(struct intel_display *display, enum pipe pch_transcoder, bool enable, bool old) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - if (enable) { intel_de_write(display, SERR_INT, SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)); @@ -249,9 +237,9 @@ static void cpt_set_fifo_underrun_reporting(struct intel_display *display, if (!cpt_can_enable_serr_int(display)) return; - ibx_enable_display_interrupt(dev_priv, SDE_ERROR_CPT); + ibx_enable_display_interrupt(display, SDE_ERROR_CPT); } else { - ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT); + ibx_disable_display_interrupt(display, SDE_ERROR_CPT); if (old && intel_de_read(display, SERR_INT) & SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) { @@ -265,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; @@ -305,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; } @@ -334,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; @@ -348,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); @@ -362,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; } @@ -429,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) @@ -444,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); } /** @@ -457,28 +441,25 @@ 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, struct intel_crtc *crtc, bool enable) { - struct drm_i915_private *i915 = to_i915(display->drm); - crtc->cpu_fifo_underrun_disabled = !enable; /* @@ -490,6 +471,6 @@ void intel_init_fifo_underrun_reporting(struct intel_display *display, * PCH transcoders B and C would prevent enabling the south * error interrupt (see cpt_can_enable_serr_int()). */ - if (intel_has_pch_trancoder(i915, crtc->pipe)) + if (intel_has_pch_trancoder(display, crtc->pipe)) crtc->pch_fifo_underrun_disabled = !enable; } 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 1bf424a822f3..3e3038f4ee1f 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -22,13 +22,18 @@ #include "intel_de.h" #include "intel_display_power.h" #include "intel_display_power_well.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" +#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 @@ -136,7 +141,7 @@ intel_hdcp_required_content_stream(struct intel_atomic_state *state, data->k++; /* if there is only one active stream */ - if (dig_port->dp.mst.active_links <= 1) + if (intel_dp_mst_active_streams(&dig_port->dp) <= 1) break; } drm_connector_list_iter_end(&conn_iter); @@ -248,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; } @@ -334,9 +339,7 @@ static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port *dig_port, static bool hdcp_key_loadable(struct intel_display *display) { - struct drm_i915_private *i915 = to_i915(display->drm); enum i915_power_well_id id; - intel_wakeref_t wakeref; bool enabled = false; /* @@ -349,7 +352,7 @@ static bool hdcp_key_loadable(struct intel_display *display) id = SKL_DISP_PW_1; /* PG1 (power well #1) needs to be enabled */ - with_intel_runtime_pm(&i915->runtime_pm, wakeref) + with_intel_display_rpm(display) enabled = intel_display_power_well_is_enabled(display, id); /* @@ -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 33b8d5229db0..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" @@ -64,6 +65,7 @@ #include "intel_panel.h" #include "intel_pfit.h" #include "intel_snps_phy.h" +#include "intel_vrr.h" static void assert_hdmi_port_disabled(struct intel_hdmi *intel_hdmi) @@ -714,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) @@ -723,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; @@ -742,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 : @@ -768,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; @@ -778,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"); @@ -978,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; @@ -988,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; @@ -1004,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; @@ -1014,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; @@ -1028,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 |= @@ -1538,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) @@ -1557,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); @@ -1569,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; @@ -1582,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; @@ -1813,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; @@ -1879,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) @@ -1889,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 */ @@ -1942,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) { @@ -1975,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; @@ -1995,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); @@ -2010,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; @@ -2047,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; } @@ -2073,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; } @@ -2210,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); @@ -2218,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; } @@ -2322,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; @@ -2384,6 +2385,8 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder, } } + intel_vrr_compute_config(pipe_config, conn_state); + intel_hdmi_compute_gcp_infoframe(encoder, pipe_config, conn_state); @@ -2422,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); @@ -2455,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"); @@ -2478,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"); @@ -2487,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; } @@ -2522,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); @@ -2551,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: @@ -2566,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 = { @@ -2624,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 = { @@ -2642,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); } /* @@ -2679,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) @@ -2808,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); @@ -2819,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; @@ -2828,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); @@ -2839,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; @@ -2892,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); @@ -2986,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; @@ -3011,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 00d7b1ccf190..fc5d8928c37e 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -30,6 +30,7 @@ #include "i915_irq.h" #include "intel_connector.h" #include "intel_display_power.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_hdcp.h" #include "intel_hotplug.h" @@ -118,7 +119,7 @@ intel_connector_hpd_pin(struct intel_connector *connector) /** * intel_hpd_irq_storm_detect - gather stats and detect HPD IRQ storm on a pin - * @dev_priv: private driver data pointer + * @display: display device * @pin: the pin to gather stats on * @long_hpd: whether the HPD IRQ was long or short * @@ -127,13 +128,13 @@ intel_connector_hpd_pin(struct intel_connector *connector) * responsible for further action. * * The number of IRQs that are allowed within @HPD_STORM_DETECT_PERIOD is - * stored in @dev_priv->display.hotplug.hpd_storm_threshold which defaults to + * stored in @display->hotplug.hpd_storm_threshold which defaults to * @HPD_STORM_DEFAULT_THRESHOLD. Long IRQs count as +10 to this threshold, and * short IRQs count as +1. If this threshold is exceeded, it's considered an * IRQ storm and the IRQ state is set to @HPD_MARK_DISABLED. * * By default, most systems will only count long IRQs towards - * &dev_priv->display.hotplug.hpd_storm_threshold. However, some older systems also + * &display->hotplug.hpd_storm_threshold. However, some older systems also * suffer from short IRQ storms and must also track these. Because short IRQ * storms are naturally caused by sideband interactions with DP MST devices, * short IRQ detection is only enabled for systems without DP MST support. @@ -145,10 +146,10 @@ intel_connector_hpd_pin(struct intel_connector *connector) * * Return true if an IRQ storm was detected on @pin. */ -static bool intel_hpd_irq_storm_detect(struct drm_i915_private *dev_priv, +static bool intel_hpd_irq_storm_detect(struct intel_display *display, enum hpd_pin pin, bool long_hpd) { - struct intel_hotplug *hpd = &dev_priv->display.hotplug; + struct intel_hotplug *hpd = &display->hotplug; unsigned long start = hpd->stats[pin].last_jiffies; unsigned long end = start + msecs_to_jiffies(HPD_STORM_DETECT_PERIOD); const int increment = long_hpd ? 10 : 1; @@ -156,7 +157,7 @@ static bool intel_hpd_irq_storm_detect(struct drm_i915_private *dev_priv, bool storm = false; if (!threshold || - (!long_hpd && !dev_priv->display.hotplug.hpd_short_storm_enabled)) + (!long_hpd && !display->hotplug.hpd_short_storm_enabled)) return false; if (!time_in_range(jiffies, start, end)) { @@ -167,11 +168,11 @@ static bool intel_hpd_irq_storm_detect(struct drm_i915_private *dev_priv, hpd->stats[pin].count += increment; if (hpd->stats[pin].count > threshold) { hpd->stats[pin].state = HPD_MARK_DISABLED; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "HPD interrupt storm detected on PIN %d\n", pin); storm = true; } else { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Received HPD interrupt on PIN %d - cnt: %d\n", pin, hpd->stats[pin].count); @@ -180,56 +181,62 @@ static bool intel_hpd_irq_storm_detect(struct drm_i915_private *dev_priv, return storm; } -static bool detection_work_enabled(struct drm_i915_private *i915) +static bool detection_work_enabled(struct intel_display *display) { - lockdep_assert_held(&i915->irq_lock); + lockdep_assert_held(&display->irq.lock); - return i915->display.hotplug.detection_work_enabled; + return display->hotplug.detection_work_enabled; } static bool -mod_delayed_detection_work(struct drm_i915_private *i915, struct delayed_work *work, int delay) +mod_delayed_detection_work(struct intel_display *display, struct delayed_work *work, int delay) { - lockdep_assert_held(&i915->irq_lock); + struct drm_i915_private *i915 = to_i915(display->drm); - if (!detection_work_enabled(i915)) + lockdep_assert_held(&display->irq.lock); + + if (!detection_work_enabled(display)) return false; return mod_delayed_work(i915->unordered_wq, work, delay); } static bool -queue_delayed_detection_work(struct drm_i915_private *i915, struct delayed_work *work, int delay) +queue_delayed_detection_work(struct intel_display *display, struct delayed_work *work, int delay) { - lockdep_assert_held(&i915->irq_lock); + struct drm_i915_private *i915 = to_i915(display->drm); + + lockdep_assert_held(&display->irq.lock); - if (!detection_work_enabled(i915)) + if (!detection_work_enabled(display)) return false; return queue_delayed_work(i915->unordered_wq, work, delay); } static bool -queue_detection_work(struct drm_i915_private *i915, struct work_struct *work) +queue_detection_work(struct intel_display *display, struct work_struct *work) { - lockdep_assert_held(&i915->irq_lock); + struct drm_i915_private *i915 = to_i915(display->drm); - if (!detection_work_enabled(i915)) + lockdep_assert_held(&display->irq.lock); + + if (!detection_work_enabled(display)) return false; return queue_work(i915->unordered_wq, work); } static void -intel_hpd_irq_storm_switch_to_polling(struct drm_i915_private *dev_priv) +intel_hpd_irq_storm_switch_to_polling(struct intel_display *display) { 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(&dev_priv->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { enum hpd_pin pin; @@ -238,15 +245,15 @@ intel_hpd_irq_storm_switch_to_polling(struct drm_i915_private *dev_priv) pin = intel_connector_hpd_pin(connector); if (pin == HPD_NONE || - dev_priv->display.hotplug.stats[pin].state != HPD_MARK_DISABLED) + display->hotplug.stats[pin].state != HPD_MARK_DISABLED) continue; - drm_info(&dev_priv->drm, + drm_info(display->drm, "HPD interrupt storm detected on connector %s: " "switching from hotplug detection to polling\n", connector->base.name); - dev_priv->display.hotplug.stats[pin].state = HPD_DISABLED; + display->hotplug.stats[pin].state = HPD_DISABLED; connector->base.polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; hpd_disabled = true; @@ -255,36 +262,35 @@ intel_hpd_irq_storm_switch_to_polling(struct drm_i915_private *dev_priv) /* Enable polling and queue hotplug re-enabling. */ if (hpd_disabled) { - drm_kms_helper_poll_reschedule(&dev_priv->drm); - mod_delayed_detection_work(dev_priv, - &dev_priv->display.hotplug.reenable_work, + drm_kms_helper_poll_reschedule(display->drm); + mod_delayed_detection_work(display, + &display->hotplug.reenable_work, msecs_to_jiffies(HPD_STORM_REENABLE_DELAY)); } } static void intel_hpd_irq_storm_reenable_work(struct work_struct *work) { - struct drm_i915_private *dev_priv = - container_of(work, typeof(*dev_priv), - display.hotplug.reenable_work.work); + struct intel_display *display = + container_of(work, typeof(*display), hotplug.reenable_work.work); struct drm_connector_list_iter conn_iter; struct intel_connector *connector; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; enum hpd_pin pin; - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + wakeref = intel_display_rpm_get(display); - spin_lock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); - drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { pin = intel_connector_hpd_pin(connector); if (pin == HPD_NONE || - dev_priv->display.hotplug.stats[pin].state != HPD_DISABLED) + display->hotplug.stats[pin].state != HPD_DISABLED) continue; if (connector->base.polled != connector->polled) - drm_dbg(&dev_priv->drm, + drm_dbg(display->drm, "Reenabling HPD on connector %s\n", connector->base.name); connector->base.polled = connector->polled; @@ -292,15 +298,15 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work) drm_connector_list_iter_end(&conn_iter); for_each_hpd_pin(pin) { - if (dev_priv->display.hotplug.stats[pin].state == HPD_DISABLED) - dev_priv->display.hotplug.stats[pin].state = HPD_ENABLED; + if (display->hotplug.stats[pin].state == HPD_DISABLED) + display->hotplug.stats[pin].state = HPD_ENABLED; } - intel_hpd_irq_setup(dev_priv); + intel_hpd_irq_setup(display); - spin_unlock_irq(&dev_priv->irq_lock); + spin_unlock_irq(&display->irq.lock); - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); } static enum intel_hotplug_state @@ -349,32 +355,72 @@ static bool intel_encoder_has_hpd_pulse(struct intel_encoder *encoder) enc_to_dig_port(encoder)->hpd_pulse != NULL; } +static bool hpd_pin_has_pulse(struct intel_display *display, enum hpd_pin pin) +{ + struct intel_encoder *encoder; + + for_each_intel_encoder(display->drm, encoder) { + if (encoder->hpd_pin != pin) + continue; + + if (intel_encoder_has_hpd_pulse(encoder)) + return true; + } + + return false; +} + +static bool hpd_pin_is_blocked(struct intel_display *display, enum hpd_pin pin) +{ + lockdep_assert_held(&display->irq.lock); + + return display->hotplug.stats[pin].blocked_count; +} + +static u32 get_blocked_hpd_pin_mask(struct intel_display *display) +{ + enum hpd_pin pin; + u32 hpd_pin_mask = 0; + + for_each_hpd_pin(pin) { + if (hpd_pin_is_blocked(display, pin)) + hpd_pin_mask |= BIT(pin); + } + + return hpd_pin_mask; +} + static void i915_digport_work_func(struct work_struct *work) { - struct drm_i915_private *dev_priv = - container_of(work, struct drm_i915_private, display.hotplug.dig_port_work); - u32 long_port_mask, short_port_mask; + struct intel_display *display = + container_of(work, struct intel_display, hotplug.dig_port_work); + 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); - long_port_mask = dev_priv->display.hotplug.long_port_mask; - dev_priv->display.hotplug.long_port_mask = 0; - short_port_mask = dev_priv->display.hotplug.short_port_mask; - dev_priv->display.hotplug.short_port_mask = 0; - spin_unlock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); - for_each_intel_encoder(&dev_priv->drm, encoder) { + blocked_hpd_pin_mask = get_blocked_hpd_pin_mask(display); + long_hpd_pin_mask = hotplug->long_hpd_pin_mask & ~blocked_hpd_pin_mask; + hotplug->long_hpd_pin_mask &= ~long_hpd_pin_mask; + 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(&display->irq.lock); + + for_each_intel_encoder(display->drm, encoder) { struct intel_digital_port *dig_port; - enum port port = encoder->port; + enum hpd_pin pin = encoder->hpd_pin; bool long_hpd, short_hpd; enum irqreturn ret; if (!intel_encoder_has_hpd_pulse(encoder)) continue; - long_hpd = long_port_mask & BIT(port); - short_hpd = short_port_mask & BIT(port); + long_hpd = long_hpd_pin_mask & BIT(pin); + short_hpd = short_hpd_pin_mask & BIT(pin); if (!long_hpd && !short_hpd) continue; @@ -384,16 +430,16 @@ static void i915_digport_work_func(struct work_struct *work) ret = dig_port->hpd_pulse(dig_port, long_hpd); if (ret == IRQ_NONE) { /* fall back to old school hpd */ - old_bits |= BIT(encoder->hpd_pin); + old_bits |= BIT(pin); } } if (old_bits) { - spin_lock_irq(&dev_priv->irq_lock); - dev_priv->display.hotplug.event_bits |= old_bits; - queue_delayed_detection_work(dev_priv, - &dev_priv->display.hotplug.hotplug_work, 0); - spin_unlock_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(&display->irq.lock); } } @@ -406,13 +452,17 @@ static void i915_digport_work_func(struct work_struct *work) */ void intel_hpd_trigger_irq(struct intel_digital_port *dig_port) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); + struct intel_hotplug *hotplug = &display->hotplug; + struct intel_encoder *encoder = &dig_port->base; + + spin_lock_irq(&display->irq.lock); - spin_lock_irq(&i915->irq_lock); - i915->display.hotplug.short_port_mask |= BIT(dig_port->base.port); - spin_unlock_irq(&i915->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); - queue_work(i915->display.hotplug.dp_wq, &i915->display.hotplug.dig_port_work); + spin_unlock_irq(&display->irq.lock); } /* @@ -420,9 +470,9 @@ void intel_hpd_trigger_irq(struct intel_digital_port *dig_port) */ static void i915_hotplug_work_func(struct work_struct *work) { - struct drm_i915_private *dev_priv = - container_of(work, struct drm_i915_private, - display.hotplug.hotplug_work.work); + struct intel_display *display = + container_of(work, struct intel_display, hotplug.hotplug_work.work); + struct intel_hotplug *hotplug = &display->hotplug; struct drm_connector_list_iter conn_iter; struct intel_connector *connector; u32 changed = 0, retry = 0; @@ -430,30 +480,32 @@ static void i915_hotplug_work_func(struct work_struct *work) u32 hpd_retry_bits; struct drm_connector *first_changed_connector = NULL; int changed_connectors = 0; + u32 blocked_hpd_pin_mask; - mutex_lock(&dev_priv->drm.mode_config.mutex); - drm_dbg_kms(&dev_priv->drm, "running encoder hotplug functions\n"); + 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); - hpd_event_bits = dev_priv->display.hotplug.event_bits; - dev_priv->display.hotplug.event_bits = 0; - hpd_retry_bits = dev_priv->display.hotplug.retry_bits; - dev_priv->display.hotplug.retry_bits = 0; + blocked_hpd_pin_mask = get_blocked_hpd_pin_mask(display); + hpd_event_bits = hotplug->event_bits & ~blocked_hpd_pin_mask; + hotplug->event_bits &= ~hpd_event_bits; + hpd_retry_bits = hotplug->retry_bits & ~blocked_hpd_pin_mask; + hotplug->retry_bits &= ~hpd_retry_bits; /* Enable polling for connectors which had HPD IRQ storms */ - intel_hpd_irq_storm_switch_to_polling(dev_priv); + 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 (dev_priv->display.hotplug.ignore_long_hpd) { - drm_dbg_kms(&dev_priv->drm, "Ignore HPD flag on - skip encoder hotplug handlers\n"); - mutex_unlock(&dev_priv->drm.mode_config.mutex); + if (display->hotplug.ignore_long_hpd) { + drm_dbg_kms(display->drm, "Ignore HPD flag on - skip encoder hotplug handlers\n"); + mutex_unlock(&display->drm->mode_config.mutex); return; } - drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { enum hpd_pin pin; u32 hpd_bit; @@ -472,7 +524,7 @@ static void i915_hotplug_work_func(struct work_struct *work) else connector->hotplug_retries++; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Connector %s (pin %i) received hotplug event. (retry %d)\n", connector->base.name, pin, connector->hotplug_retries); @@ -495,12 +547,12 @@ static void i915_hotplug_work_func(struct work_struct *work) } } drm_connector_list_iter_end(&conn_iter); - mutex_unlock(&dev_priv->drm.mode_config.mutex); + mutex_unlock(&display->drm->mode_config.mutex); if (changed_connectors == 1) drm_kms_helper_connector_hotplug_event(first_changed_connector); else if (changed_connectors > 0) - drm_kms_helper_hotplug_event(&dev_priv->drm); + drm_kms_helper_hotplug_event(display->drm); if (first_changed_connector) drm_connector_put(first_changed_connector); @@ -508,20 +560,20 @@ 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); - dev_priv->display.hotplug.retry_bits |= retry; + spin_lock_irq(&display->irq.lock); + display->hotplug.retry_bits |= retry; - mod_delayed_detection_work(dev_priv, - &dev_priv->display.hotplug.hotplug_work, + 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); } } /** * intel_hpd_irq_handler - main hotplug irq handler - * @dev_priv: drm_i915_private + * @display: display device * @pin_mask: a mask of hpd pins that have triggered the irq * @long_mask: a mask of hpd pins that may be long hpd pulses * @@ -535,7 +587,7 @@ static void i915_hotplug_work_func(struct work_struct *work) * Here, we do hotplug irq storm detection and mitigation, and pass further * processing to appropriate bottom halves. */ -void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, +void intel_hpd_irq_handler(struct intel_display *display, u32 pin_mask, u32 long_mask) { struct intel_encoder *encoder; @@ -548,7 +600,7 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, if (!pin_mask) return; - spin_lock(&dev_priv->irq_lock); + spin_lock(&display->irq.lock); /* * Determine whether ->hpd_pulse() exists for each pin, and @@ -556,8 +608,7 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, * as each pin may have up to two encoders (HDMI and DP) and * only the one of them (DP) will have ->hpd_pulse(). */ - for_each_intel_encoder(&dev_priv->drm, encoder) { - enum port port = encoder->port; + for_each_intel_encoder(display->drm, encoder) { bool long_hpd; pin = encoder->hpd_pin; @@ -569,18 +620,20 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, long_hpd = long_mask & BIT(pin); - drm_dbg(&dev_priv->drm, + drm_dbg(display->drm, "digital hpd on [ENCODER:%d:%s] - %s\n", encoder->base.base.id, encoder->base.name, long_hpd ? "long" : "short"); - queue_dig = true; + + if (!hpd_pin_is_blocked(display, pin)) + queue_dig = true; if (long_hpd) { long_hpd_pulse_mask |= BIT(pin); - dev_priv->display.hotplug.long_port_mask |= BIT(port); + display->hotplug.long_hpd_pin_mask |= BIT(pin); } else { short_hpd_pulse_mask |= BIT(pin); - dev_priv->display.hotplug.short_port_mask |= BIT(port); + display->hotplug.short_hpd_pin_mask |= BIT(pin); } } @@ -591,20 +644,20 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, if (!(BIT(pin) & pin_mask)) continue; - if (dev_priv->display.hotplug.stats[pin].state == HPD_DISABLED) { + if (display->hotplug.stats[pin].state == HPD_DISABLED) { /* * On GMCH platforms the interrupt mask bits only * prevent irq generation, not the setting of the * hotplug bits itself. So only WARN about unexpected * interrupts on saner platforms. */ - drm_WARN_ONCE(&dev_priv->drm, !HAS_GMCH(dev_priv), + drm_WARN_ONCE(display->drm, !HAS_GMCH(display), "Received HPD interrupt on pin %d although disabled\n", pin); continue; } - if (dev_priv->display.hotplug.stats[pin].state != HPD_ENABLED) + if (display->hotplug.stats[pin].state != HPD_ENABLED) continue; /* @@ -615,13 +668,15 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, if (((short_hpd_pulse_mask | long_hpd_pulse_mask) & BIT(pin))) { long_hpd = long_hpd_pulse_mask & BIT(pin); } else { - dev_priv->display.hotplug.event_bits |= BIT(pin); + display->hotplug.event_bits |= BIT(pin); long_hpd = true; - queue_hp = true; + + if (!hpd_pin_is_blocked(display, pin)) + queue_hp = true; } - if (intel_hpd_irq_storm_detect(dev_priv, pin, long_hpd)) { - dev_priv->display.hotplug.event_bits &= ~BIT(pin); + if (intel_hpd_irq_storm_detect(display, pin, long_hpd)) { + display->hotplug.event_bits &= ~BIT(pin); storm_detected = true; queue_hp = true; } @@ -632,7 +687,7 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, * happens later in our hotplug work. */ if (storm_detected) - intel_hpd_irq_setup(dev_priv); + intel_hpd_irq_setup(display); /* * Our hotplug handler can grab modeset locks (by calling down into the @@ -641,17 +696,17 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, * deadlock. */ if (queue_dig) - queue_work(dev_priv->display.hotplug.dp_wq, &dev_priv->display.hotplug.dig_port_work); + queue_work(display->hotplug.dp_wq, &display->hotplug.dig_port_work); if (queue_hp) - queue_delayed_detection_work(dev_priv, - &dev_priv->display.hotplug.hotplug_work, 0); + queue_delayed_detection_work(display, + &display->hotplug.hotplug_work, 0); - spin_unlock(&dev_priv->irq_lock); + spin_unlock(&display->irq.lock); } /** * intel_hpd_init - initializes and enables hpd support - * @dev_priv: i915 device instance + * @display: display device instance * * This function enables the hotplug support. It requires that interrupts have * already been enabled with intel_irq_init_hw(). From this point on hotplug and @@ -663,40 +718,40 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, * * Also see: intel_hpd_poll_enable() and intel_hpd_poll_disable(). */ -void intel_hpd_init(struct drm_i915_private *dev_priv) +void intel_hpd_init(struct intel_display *display) { int i; - if (!HAS_DISPLAY(dev_priv)) + if (!HAS_DISPLAY(display)) return; for_each_hpd_pin(i) { - dev_priv->display.hotplug.stats[i].count = 0; - dev_priv->display.hotplug.stats[i].state = HPD_ENABLED; + display->hotplug.stats[i].count = 0; + display->hotplug.stats[i].state = HPD_ENABLED; } /* * 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); - intel_hpd_irq_setup(dev_priv); - spin_unlock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); + intel_hpd_irq_setup(display); + spin_unlock_irq(&display->irq.lock); } -static void i915_hpd_poll_detect_connectors(struct drm_i915_private *i915) +static void i915_hpd_poll_detect_connectors(struct intel_display *display) { struct drm_connector_list_iter conn_iter; struct intel_connector *connector; struct intel_connector *first_changed_connector = NULL; int changed = 0; - mutex_lock(&i915->drm.mode_config.mutex); + mutex_lock(&display->drm->mode_config.mutex); - if (!i915->drm.mode_config.poll_enabled) + if (!display->drm->mode_config.poll_enabled) goto out; - 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.polled & DRM_CONNECTOR_POLL_HPD)) continue; @@ -714,7 +769,7 @@ static void i915_hpd_poll_detect_connectors(struct drm_i915_private *i915) drm_connector_list_iter_end(&conn_iter); out: - mutex_unlock(&i915->drm.mode_config.mutex); + mutex_unlock(&display->drm->mode_config.mutex); if (!changed) return; @@ -722,25 +777,23 @@ out: if (changed == 1) drm_kms_helper_connector_hotplug_event(&first_changed_connector->base); else - drm_kms_helper_hotplug_event(&i915->drm); + drm_kms_helper_hotplug_event(display->drm); drm_connector_put(&first_changed_connector->base); } static void i915_hpd_poll_init_work(struct work_struct *work) { - struct drm_i915_private *dev_priv = - container_of(work, struct drm_i915_private, - display.hotplug.poll_init_work); - struct intel_display *display = &dev_priv->display; + struct intel_display *display = + container_of(work, typeof(*display), hotplug.poll_init_work); struct drm_connector_list_iter conn_iter; struct intel_connector *connector; intel_wakeref_t wakeref; bool enabled; - mutex_lock(&dev_priv->drm.mode_config.mutex); + mutex_lock(&display->drm->mode_config.mutex); - enabled = READ_ONCE(dev_priv->display.hotplug.poll_enabled); + enabled = READ_ONCE(display->hotplug.poll_enabled); /* * Prevent taking a power reference from this sequence of * i915_hpd_poll_init_work() -> drm_helper_hpd_irq_event() -> @@ -750,14 +803,14 @@ static void i915_hpd_poll_init_work(struct work_struct *work) if (!enabled) { wakeref = intel_display_power_get(display, POWER_DOMAIN_DISPLAY_CORE); - drm_WARN_ON(&dev_priv->drm, - READ_ONCE(dev_priv->display.hotplug.poll_enabled)); - cancel_work(&dev_priv->display.hotplug.poll_init_work); + drm_WARN_ON(display->drm, + READ_ONCE(display->hotplug.poll_enabled)); + 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(&dev_priv->drm, &conn_iter); + drm_connector_list_iter_begin(display->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { enum hpd_pin pin; @@ -765,7 +818,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work) if (pin == HPD_NONE) continue; - if (dev_priv->display.hotplug.stats[pin].state == HPD_DISABLED) + if (display->hotplug.stats[pin].state == HPD_DISABLED) continue; connector->base.polled = connector->polled; @@ -776,19 +829,19 @@ 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(&dev_priv->drm); + drm_kms_helper_poll_reschedule(display->drm); - mutex_unlock(&dev_priv->drm.mode_config.mutex); + mutex_unlock(&display->drm->mode_config.mutex); /* * We might have missed any hotplugs that happened while we were * in the middle of disabling polling */ if (!enabled) { - i915_hpd_poll_detect_connectors(dev_priv); + i915_hpd_poll_detect_connectors(display); intel_display_power_put(display, POWER_DOMAIN_DISPLAY_CORE, @@ -798,7 +851,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work) /** * intel_hpd_poll_enable - enable polling for connectors with hpd - * @dev_priv: i915 device instance + * @display: display device instance * * This function enables polling for all connectors which support HPD. * Under certain conditions HPD may not be functional. On most Intel GPUs, @@ -812,15 +865,12 @@ static void i915_hpd_poll_init_work(struct work_struct *work) * * Also see: intel_hpd_init() and intel_hpd_poll_disable(). */ -void intel_hpd_poll_enable(struct drm_i915_private *dev_priv) +void intel_hpd_poll_enable(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; - - if (!HAS_DISPLAY(dev_priv) || - !intel_display_device_enabled(display)) + if (!HAS_DISPLAY(display) || !intel_display_device_enabled(display)) return; - WRITE_ONCE(dev_priv->display.hotplug.poll_enabled, true); + WRITE_ONCE(display->hotplug.poll_enabled, true); /* * We might already be holding dev->mode_config.mutex, so do this in a @@ -828,15 +878,15 @@ void intel_hpd_poll_enable(struct drm_i915_private *dev_priv) * As well, there's no issue if we race here since we always reschedule * this worker anyway */ - spin_lock_irq(&dev_priv->irq_lock); - queue_detection_work(dev_priv, - &dev_priv->display.hotplug.poll_init_work); - spin_unlock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); + queue_detection_work(display, + &display->hotplug.poll_init_work); + spin_unlock_irq(&display->irq.lock); } /** * intel_hpd_poll_disable - disable polling for connectors with hpd - * @dev_priv: i915 device instance + * @display: display device instance * * This function disables polling for all connectors which support HPD. * Under certain conditions HPD may not be functional. On most Intel GPUs, @@ -853,26 +903,26 @@ void intel_hpd_poll_enable(struct drm_i915_private *dev_priv) * * Also see: intel_hpd_init() and intel_hpd_poll_enable(). */ -void intel_hpd_poll_disable(struct drm_i915_private *dev_priv) +void intel_hpd_poll_disable(struct intel_display *display) { - if (!HAS_DISPLAY(dev_priv)) + if (!HAS_DISPLAY(display)) return; - WRITE_ONCE(dev_priv->display.hotplug.poll_enabled, false); + WRITE_ONCE(display->hotplug.poll_enabled, false); - spin_lock_irq(&dev_priv->irq_lock); - queue_detection_work(dev_priv, - &dev_priv->display.hotplug.poll_init_work); - spin_unlock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); + queue_detection_work(display, + &display->hotplug.poll_init_work); + spin_unlock_irq(&display->irq.lock); } -void intel_hpd_poll_fini(struct drm_i915_private *i915) +void intel_hpd_poll_fini(struct intel_display *display) { struct intel_connector *connector; struct drm_connector_list_iter conn_iter; /* Kill all the work that may have been queued by hpd. */ - 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) { intel_connector_cancel_modeset_retry_work(connector); intel_hdcp_cancel_works(connector); @@ -880,157 +930,261 @@ void intel_hpd_poll_fini(struct drm_i915_private *i915) drm_connector_list_iter_end(&conn_iter); } -void intel_hpd_init_early(struct drm_i915_private *i915) +void intel_hpd_init_early(struct intel_display *display) { - INIT_DELAYED_WORK(&i915->display.hotplug.hotplug_work, + INIT_DELAYED_WORK(&display->hotplug.hotplug_work, i915_hotplug_work_func); - INIT_WORK(&i915->display.hotplug.dig_port_work, i915_digport_work_func); - INIT_WORK(&i915->display.hotplug.poll_init_work, i915_hpd_poll_init_work); - INIT_DELAYED_WORK(&i915->display.hotplug.reenable_work, + INIT_WORK(&display->hotplug.dig_port_work, i915_digport_work_func); + INIT_WORK(&display->hotplug.poll_init_work, i915_hpd_poll_init_work); + INIT_DELAYED_WORK(&display->hotplug.reenable_work, intel_hpd_irq_storm_reenable_work); - i915->display.hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD; + display->hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD; /* If we have MST support, we want to avoid doing short HPD IRQ storm * detection, as short HPD storms will occur as a natural part of * sideband messaging with MST. * On older platforms however, IRQ storms can occur with both long and * short pulses, as seen on some G4x systems. */ - i915->display.hotplug.hpd_short_storm_enabled = !HAS_DP_MST(i915); + display->hotplug.hpd_short_storm_enabled = !HAS_DP_MST(display); } -static bool cancel_all_detection_work(struct drm_i915_private *i915) +static bool cancel_all_detection_work(struct intel_display *display) { bool was_pending = false; - if (cancel_delayed_work_sync(&i915->display.hotplug.hotplug_work)) + if (cancel_delayed_work_sync(&display->hotplug.hotplug_work)) was_pending = true; - if (cancel_work_sync(&i915->display.hotplug.poll_init_work)) + if (cancel_work_sync(&display->hotplug.poll_init_work)) was_pending = true; - if (cancel_delayed_work_sync(&i915->display.hotplug.reenable_work)) + if (cancel_delayed_work_sync(&display->hotplug.reenable_work)) was_pending = true; return was_pending; } -void intel_hpd_cancel_work(struct drm_i915_private *dev_priv) +void intel_hpd_cancel_work(struct intel_display *display) { - if (!HAS_DISPLAY(dev_priv)) + 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)); - dev_priv->display.hotplug.long_port_mask = 0; - dev_priv->display.hotplug.short_port_mask = 0; - dev_priv->display.hotplug.event_bits = 0; - dev_priv->display.hotplug.retry_bits = 0; + display->hotplug.long_hpd_pin_mask = 0; + display->hotplug.short_hpd_pin_mask = 0; + 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(&dev_priv->display.hotplug.dig_port_work); + cancel_work_sync(&display->hotplug.dig_port_work); /* * All other work triggered by hotplug events should be canceled by * now. */ - if (cancel_all_detection_work(dev_priv)) - drm_dbg_kms(&dev_priv->drm, "Hotplug detection work still active\n"); + if (cancel_all_detection_work(display)) + drm_dbg_kms(display->drm, "Hotplug detection work still active\n"); } -bool intel_hpd_disable(struct drm_i915_private *dev_priv, enum hpd_pin pin) +static void queue_work_for_missed_irqs(struct intel_display *display) { - bool ret = false; + struct intel_hotplug *hotplug = &display->hotplug; + bool queue_hp_work = false; + u32 blocked_hpd_pin_mask; + enum hpd_pin pin; - if (pin == HPD_NONE) - return false; + lockdep_assert_held(&display->irq.lock); - spin_lock_irq(&dev_priv->irq_lock); - if (dev_priv->display.hotplug.stats[pin].state == HPD_ENABLED) { - dev_priv->display.hotplug.stats[pin].state = HPD_DISABLED; - ret = true; + blocked_hpd_pin_mask = get_blocked_hpd_pin_mask(display); + if ((hotplug->event_bits | hotplug->retry_bits) & ~blocked_hpd_pin_mask) + queue_hp_work = true; + + for_each_hpd_pin(pin) { + switch (display->hotplug.stats[pin].state) { + case HPD_MARK_DISABLED: + queue_hp_work = true; + break; + case HPD_DISABLED: + case HPD_ENABLED: + break; + default: + MISSING_CASE(display->hotplug.stats[pin].state); + } } - spin_unlock_irq(&dev_priv->irq_lock); - return ret; + if ((hotplug->long_hpd_pin_mask | hotplug->short_hpd_pin_mask) & ~blocked_hpd_pin_mask) + queue_work(hotplug->dp_wq, &hotplug->dig_port_work); + + if (queue_hp_work) + queue_delayed_detection_work(display, &display->hotplug.hotplug_work, 0); } -void intel_hpd_enable(struct drm_i915_private *dev_priv, enum hpd_pin pin) +static bool block_hpd_pin(struct intel_display *display, enum hpd_pin pin) { - if (pin == HPD_NONE) + struct intel_hotplug *hotplug = &display->hotplug; + + lockdep_assert_held(&display->irq.lock); + + hotplug->stats[pin].blocked_count++; + + return hotplug->stats[pin].blocked_count == 1; +} + +static bool unblock_hpd_pin(struct intel_display *display, enum hpd_pin pin) +{ + struct intel_hotplug *hotplug = &display->hotplug; + + lockdep_assert_held(&display->irq.lock); + + if (drm_WARN_ON(display->drm, hotplug->stats[pin].blocked_count == 0)) + return true; + + hotplug->stats[pin].blocked_count--; + + return hotplug->stats[pin].blocked_count == 0; +} + +/** + * intel_hpd_block - Block handling of HPD IRQs on an HPD pin + * @encoder: Encoder to block the HPD handling for + * + * Blocks the handling of HPD IRQs on the HPD pin of @encoder. + * + * On return: + * + * - It's guaranteed that the blocked encoders' HPD pulse handler + * (via intel_digital_port::hpd_pulse()) is not running. + * - The hotplug event handling (via intel_encoder::hotplug()) of an + * HPD IRQ pending at the time this function is called may be still + * running. + * - Detection on the encoder's connector (via + * drm_connector_helper_funcs::detect_ctx(), + * drm_connector_funcs::detect()) remains allowed, for instance as part of + * userspace connector probing, or DRM core's connector polling. + * + * The call must be followed by calling intel_hpd_unblock(), or + * intel_hpd_clear_and_unblock(). + * + * Note that the handling of HPD IRQs for another encoder using the same HPD + * pin as that of @encoder will be also blocked. + */ +void intel_hpd_block(struct intel_encoder *encoder) +{ + struct intel_display *display = to_intel_display(encoder); + struct intel_hotplug *hotplug = &display->hotplug; + bool do_flush = false; + + if (encoder->hpd_pin == HPD_NONE) + return; + + spin_lock_irq(&display->irq.lock); + + if (block_hpd_pin(display, encoder->hpd_pin)) + do_flush = true; + + spin_unlock_irq(&display->irq.lock); + + if (do_flush && hpd_pin_has_pulse(display, encoder->hpd_pin)) + flush_work(&hotplug->dig_port_work); +} + +/** + * intel_hpd_unblock - Unblock handling of HPD IRQs on an HPD pin + * @encoder: Encoder to unblock the HPD handling for + * + * Unblock the handling of HPD IRQs on the HPD pin of @encoder, which was + * previously blocked by intel_hpd_block(). Any HPD IRQ raised on the + * HPD pin while it was blocked will be handled for @encoder and for any + * other encoder sharing the same HPD pin. + */ +void intel_hpd_unblock(struct intel_encoder *encoder) +{ + struct intel_display *display = to_intel_display(encoder); + + if (encoder->hpd_pin == HPD_NONE) return; - spin_lock_irq(&dev_priv->irq_lock); - dev_priv->display.hotplug.stats[pin].state = HPD_ENABLED; - spin_unlock_irq(&dev_priv->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(&display->irq.lock); } -static void queue_work_for_missed_irqs(struct drm_i915_private *i915) +/** + * intel_hpd_clear_and_unblock - Unblock handling of new HPD IRQs on an HPD pin + * @encoder: Encoder to unblock the HPD handling for + * + * Unblock the handling of HPD IRQs on the HPD pin of @encoder, which was + * previously blocked by intel_hpd_block(). Any HPD IRQ raised on the + * HPD pin while it was blocked will be cleared, handling only new IRQs. + */ +void intel_hpd_clear_and_unblock(struct intel_encoder *encoder) { - bool queue_work = false; - enum hpd_pin pin; + struct intel_display *display = to_intel_display(encoder); + struct intel_hotplug *hotplug = &display->hotplug; + enum hpd_pin pin = encoder->hpd_pin; - lockdep_assert_held(&i915->irq_lock); + if (pin == HPD_NONE) + return; - if (i915->display.hotplug.event_bits || - i915->display.hotplug.retry_bits) - queue_work = true; + spin_lock_irq(&display->irq.lock); - for_each_hpd_pin(pin) { - switch (i915->display.hotplug.stats[pin].state) { - case HPD_MARK_DISABLED: - queue_work = true; - break; - case HPD_ENABLED: - break; - default: - MISSING_CASE(i915->display.hotplug.stats[pin].state); - } + if (unblock_hpd_pin(display, pin)) { + hotplug->event_bits &= ~BIT(pin); + hotplug->retry_bits &= ~BIT(pin); + hotplug->short_hpd_pin_mask &= ~BIT(pin); + hotplug->long_hpd_pin_mask &= ~BIT(pin); } - if (queue_work) - queue_delayed_detection_work(i915, &i915->display.hotplug.hotplug_work, 0); + spin_unlock_irq(&display->irq.lock); } -void intel_hpd_enable_detection_work(struct drm_i915_private *i915) +void intel_hpd_enable_detection_work(struct intel_display *display) { - spin_lock_irq(&i915->irq_lock); - i915->display.hotplug.detection_work_enabled = true; - queue_work_for_missed_irqs(i915); - spin_unlock_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(&display->irq.lock); } -void intel_hpd_disable_detection_work(struct drm_i915_private *i915) +void intel_hpd_disable_detection_work(struct intel_display *display) { - spin_lock_irq(&i915->irq_lock); - i915->display.hotplug.detection_work_enabled = false; - spin_unlock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); + display->hotplug.detection_work_enabled = false; + spin_unlock_irq(&display->irq.lock); - cancel_all_detection_work(i915); + cancel_all_detection_work(display); } -bool intel_hpd_schedule_detection(struct drm_i915_private *i915) +bool intel_hpd_schedule_detection(struct intel_display *display) { unsigned long flags; bool ret; - spin_lock_irqsave(&i915->irq_lock, flags); - ret = queue_delayed_detection_work(i915, &i915->display.hotplug.hotplug_work, 0); - spin_unlock_irqrestore(&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(&display->irq.lock, flags); return ret; } static int i915_hpd_storm_ctl_show(struct seq_file *m, void *data) { - struct drm_i915_private *dev_priv = m->private; - struct intel_hotplug *hotplug = &dev_priv->display.hotplug; + struct intel_display *display = m->private; + struct drm_i915_private *dev_priv = to_i915(display->drm); + struct intel_hotplug *hotplug = &display->hotplug; /* Synchronize with everything first in case there's been an HPD * storm, but we haven't finished handling it in the kernel yet */ intel_synchronize_irq(dev_priv); - flush_work(&dev_priv->display.hotplug.dig_port_work); - flush_delayed_work(&dev_priv->display.hotplug.hotplug_work); + flush_work(&display->hotplug.dig_port_work); + flush_delayed_work(&display->hotplug.hotplug_work); seq_printf(m, "Threshold: %d\n", hotplug->hpd_storm_threshold); seq_printf(m, "Detected: %s\n", @@ -1044,8 +1198,8 @@ static ssize_t i915_hpd_storm_ctl_write(struct file *file, loff_t *offp) { struct seq_file *m = file->private_data; - struct drm_i915_private *dev_priv = m->private; - struct intel_hotplug *hotplug = &dev_priv->display.hotplug; + struct intel_display *display = m->private; + struct intel_hotplug *hotplug = &display->hotplug; unsigned int new_threshold; int i; char *newline; @@ -1070,21 +1224,21 @@ static ssize_t i915_hpd_storm_ctl_write(struct file *file, return -EINVAL; if (new_threshold > 0) - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Setting HPD storm detection threshold to %d\n", new_threshold); else - drm_dbg_kms(&dev_priv->drm, "Disabling HPD storm detection\n"); + 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(&dev_priv->display.hotplug.reenable_work); + flush_delayed_work(&display->hotplug.reenable_work); return len; } @@ -1105,10 +1259,10 @@ static const struct file_operations i915_hpd_storm_ctl_fops = { static int i915_hpd_short_storm_ctl_show(struct seq_file *m, void *data) { - struct drm_i915_private *dev_priv = m->private; + struct intel_display *display = m->private; seq_printf(m, "Enabled: %s\n", - str_yes_no(dev_priv->display.hotplug.hpd_short_storm_enabled)); + str_yes_no(display->hotplug.hpd_short_storm_enabled)); return 0; } @@ -1125,8 +1279,8 @@ static ssize_t i915_hpd_short_storm_ctl_write(struct file *file, size_t len, loff_t *offp) { struct seq_file *m = file->private_data; - struct drm_i915_private *dev_priv = m->private; - struct intel_hotplug *hotplug = &dev_priv->display.hotplug; + struct intel_display *display = m->private; + struct intel_hotplug *hotplug = &display->hotplug; char *newline; char tmp[16]; int i; @@ -1147,22 +1301,22 @@ static ssize_t i915_hpd_short_storm_ctl_write(struct file *file, /* Reset to the "default" state for this system */ if (strcmp(tmp, "reset") == 0) - new_state = !HAS_DP_MST(dev_priv); + new_state = !HAS_DP_MST(display); else if (kstrtobool(tmp, &new_state) != 0) return -EINVAL; - drm_dbg_kms(&dev_priv->drm, "%sabling HPD short storm detection\n", + 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(&dev_priv->display.hotplug.reenable_work); + flush_delayed_work(&display->hotplug.reenable_work); return len; } @@ -1176,14 +1330,14 @@ static const struct file_operations i915_hpd_short_storm_ctl_fops = { .write = i915_hpd_short_storm_ctl_write, }; -void intel_hpd_debugfs_register(struct drm_i915_private *i915) +void intel_hpd_debugfs_register(struct intel_display *display) { - struct drm_minor *minor = i915->drm.primary; + struct drm_minor *minor = display->drm->primary; debugfs_create_file("i915_hpd_storm_ctl", 0644, minor->debugfs_root, - i915, &i915_hpd_storm_ctl_fops); + display, &i915_hpd_storm_ctl_fops); debugfs_create_file("i915_hpd_short_storm_ctl", 0644, minor->debugfs_root, - i915, &i915_hpd_short_storm_ctl_fops); + display, &i915_hpd_short_storm_ctl_fops); debugfs_create_bool("i915_ignore_long_hpd", 0644, minor->debugfs_root, - &i915->display.hotplug.ignore_long_hpd); + &display->hotplug.ignore_long_hpd); } diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.h b/drivers/gpu/drm/i915/display/intel_hotplug.h index d6986902b054..edc41c9d3d65 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.h +++ b/drivers/gpu/drm/i915/display/intel_hotplug.h @@ -8,30 +8,31 @@ #include <linux/types.h> -struct drm_i915_private; +enum port; struct intel_connector; struct intel_digital_port; +struct intel_display; struct intel_encoder; -enum port; -void intel_hpd_poll_enable(struct drm_i915_private *dev_priv); -void intel_hpd_poll_disable(struct drm_i915_private *dev_priv); -void intel_hpd_poll_fini(struct drm_i915_private *i915); +void intel_hpd_poll_enable(struct intel_display *display); +void intel_hpd_poll_disable(struct intel_display *display); +void intel_hpd_poll_fini(struct intel_display *display); enum intel_hotplug_state intel_encoder_hotplug(struct intel_encoder *encoder, struct intel_connector *connector); -void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, +void intel_hpd_irq_handler(struct intel_display *display, u32 pin_mask, u32 long_mask); void intel_hpd_trigger_irq(struct intel_digital_port *dig_port); -void intel_hpd_init(struct drm_i915_private *dev_priv); -void intel_hpd_init_early(struct drm_i915_private *i915); -void intel_hpd_cancel_work(struct drm_i915_private *dev_priv); +void intel_hpd_init(struct intel_display *display); +void intel_hpd_init_early(struct intel_display *display); +void intel_hpd_cancel_work(struct intel_display *display); enum hpd_pin intel_hpd_pin_default(enum port port); -bool intel_hpd_disable(struct drm_i915_private *dev_priv, enum hpd_pin pin); -void intel_hpd_enable(struct drm_i915_private *dev_priv, enum hpd_pin pin); -void intel_hpd_debugfs_register(struct drm_i915_private *i915); +void intel_hpd_block(struct intel_encoder *encoder); +void intel_hpd_unblock(struct intel_encoder *encoder); +void intel_hpd_clear_and_unblock(struct intel_encoder *encoder); +void intel_hpd_debugfs_register(struct intel_display *display); -void intel_hpd_enable_detection_work(struct drm_i915_private *i915); -void intel_hpd_disable_detection_work(struct drm_i915_private *i915); -bool intel_hpd_schedule_detection(struct drm_i915_private *i915); +void intel_hpd_enable_detection_work(struct intel_display *display); +void intel_hpd_disable_detection_work(struct intel_display *display); +bool intel_hpd_schedule_detection(struct intel_display *display); #endif /* __INTEL_HOTPLUG_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_hotplug_irq.c b/drivers/gpu/drm/i915/display/intel_hotplug_irq.c index 2137ac7b882a..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" @@ -131,68 +133,67 @@ static const u32 hpd_mtp[HPD_NUM_PINS] = { [HPD_PORT_TC4] = SDE_TC_HOTPLUG_ICP(HPD_PORT_TC4), }; -static void intel_hpd_init_pins(struct drm_i915_private *dev_priv) +static void intel_hpd_init_pins(struct intel_display *display) { - struct intel_hotplug *hpd = &dev_priv->display.hotplug; + struct intel_hotplug *hpd = &display->hotplug; - if (HAS_GMCH(dev_priv)) { - if (IS_G4X(dev_priv) || IS_VALLEYVIEW(dev_priv) || - IS_CHERRYVIEW(dev_priv)) + if (HAS_GMCH(display)) { + if (display->platform.g4x || display->platform.valleyview || + display->platform.cherryview) hpd->hpd = hpd_status_g4x; else hpd->hpd = hpd_status_i915; return; } - if (DISPLAY_VER(dev_priv) >= 14) + if (DISPLAY_VER(display) >= 14) hpd->hpd = hpd_xelpdp; - else if (DISPLAY_VER(dev_priv) >= 11) + else if (DISPLAY_VER(display) >= 11) hpd->hpd = hpd_gen11; - else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + else if (display->platform.geminilake || display->platform.broxton) hpd->hpd = hpd_bxt; - else if (DISPLAY_VER(dev_priv) == 9) + else if (DISPLAY_VER(display) == 9) hpd->hpd = NULL; /* no north HPD on SKL */ - else if (DISPLAY_VER(dev_priv) >= 8) + else if (DISPLAY_VER(display) >= 8) hpd->hpd = hpd_bdw; - else if (DISPLAY_VER(dev_priv) >= 7) + else if (DISPLAY_VER(display) >= 7) hpd->hpd = hpd_ivb; 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 drm_i915_private *dev_priv, +void i915_hotplug_interrupt_update_locked(struct intel_display *display, u32 mask, u32 bits) { - lockdep_assert_held(&dev_priv->irq_lock); - drm_WARN_ON(&dev_priv->drm, bits & ~mask); + lockdep_assert_held(&display->irq.lock); + drm_WARN_ON(display->drm, bits & ~mask); - intel_uncore_rmw(&dev_priv->uncore, PORT_HOTPLUG_EN(dev_priv), mask, - bits); + intel_de_rmw(display, PORT_HOTPLUG_EN(display), mask, bits); } /** * i915_hotplug_interrupt_update - update hotplug interrupt enable - * @dev_priv: driver private + * @display: display device * @mask: bits to update * @bits: bits to enable * NOTE: the HPD enable bits are modified both inside and outside @@ -202,13 +203,13 @@ void i915_hotplug_interrupt_update_locked(struct drm_i915_private *dev_priv, * held already, this function acquires the lock itself. A non-locking * version is also available. */ -void i915_hotplug_interrupt_update(struct drm_i915_private *dev_priv, +void i915_hotplug_interrupt_update(struct intel_display *display, u32 mask, u32 bits) { - spin_lock_irq(&dev_priv->irq_lock); - i915_hotplug_interrupt_update_locked(dev_priv, mask, bits); - spin_unlock_irq(&dev_priv->irq_lock); + spin_lock_irq(&display->irq.lock); + i915_hotplug_interrupt_update_locked(display, mask, bits); + spin_unlock_irq(&display->irq.lock); } static bool gen11_port_hotplug_long_detect(enum hpd_pin pin, u32 val) @@ -339,7 +340,7 @@ static bool i9xx_port_hotplug_long_detect(enum hpd_pin pin, u32 val) * * Note that the caller is expected to zero out the masks initially. */ -static void intel_get_hpd_pins(struct drm_i915_private *dev_priv, +static void intel_get_hpd_pins(struct intel_display *display, u32 *pin_mask, u32 *long_mask, u32 hotplug_trigger, u32 dig_hotplug_reg, const u32 hpd[HPD_NUM_PINS], @@ -359,37 +360,37 @@ static void intel_get_hpd_pins(struct drm_i915_private *dev_priv, *long_mask |= BIT(pin); } - drm_dbg(&dev_priv->drm, - "hotplug event received, stat 0x%08x, dig 0x%08x, pins 0x%08x, long 0x%08x\n", - hotplug_trigger, dig_hotplug_reg, *pin_mask, *long_mask); + drm_dbg_kms(display->drm, + "hotplug event received, stat 0x%08x, dig 0x%08x, pins 0x%08x, long 0x%08x\n", + hotplug_trigger, dig_hotplug_reg, *pin_mask, *long_mask); } -static u32 intel_hpd_enabled_irqs(struct drm_i915_private *dev_priv, +static u32 intel_hpd_enabled_irqs(struct intel_display *display, const u32 hpd[HPD_NUM_PINS]) { struct intel_encoder *encoder; u32 enabled_irqs = 0; - for_each_intel_encoder(&dev_priv->drm, encoder) - if (dev_priv->display.hotplug.stats[encoder->hpd_pin].state == HPD_ENABLED) + for_each_intel_encoder(display->drm, encoder) + if (display->hotplug.stats[encoder->hpd_pin].state == HPD_ENABLED) enabled_irqs |= hpd[encoder->hpd_pin]; return enabled_irqs; } -static u32 intel_hpd_hotplug_irqs(struct drm_i915_private *dev_priv, +static u32 intel_hpd_hotplug_irqs(struct intel_display *display, const u32 hpd[HPD_NUM_PINS]) { struct intel_encoder *encoder; u32 hotplug_irqs = 0; - for_each_intel_encoder(&dev_priv->drm, encoder) + for_each_intel_encoder(display->drm, encoder) hotplug_irqs |= hpd[encoder->hpd_pin]; return hotplug_irqs; } -static u32 intel_hpd_hotplug_mask(struct drm_i915_private *i915, +static u32 intel_hpd_hotplug_mask(struct intel_display *display, hotplug_mask_func hotplug_mask) { enum hpd_pin pin; @@ -401,25 +402,25 @@ static u32 intel_hpd_hotplug_mask(struct drm_i915_private *i915, return hotplug; } -static u32 intel_hpd_hotplug_enables(struct drm_i915_private *i915, +static u32 intel_hpd_hotplug_enables(struct intel_display *display, hotplug_enables_func hotplug_enables) { struct intel_encoder *encoder; u32 hotplug = 0; - for_each_intel_encoder(&i915->drm, encoder) + for_each_intel_encoder(display->drm, encoder) hotplug |= hotplug_enables(encoder); return hotplug; } -u32 i9xx_hpd_irq_ack(struct drm_i915_private *dev_priv) +u32 i9xx_hpd_irq_ack(struct intel_display *display) { u32 hotplug_status = 0, hotplug_status_mask; int i; - if (IS_G4X(dev_priv) || - IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + if (display->platform.g4x || + display->platform.valleyview || display->platform.cherryview) hotplug_status_mask = HOTPLUG_INT_STATUS_G4X | DP_AUX_CHANNEL_MASK_INT_STATUS_G4X; else @@ -435,53 +436,51 @@ u32 i9xx_hpd_irq_ack(struct drm_i915_private *dev_priv) * bits can itself generate a new hotplug interrupt :( */ for (i = 0; i < 10; i++) { - u32 tmp = intel_uncore_read(&dev_priv->uncore, - PORT_HOTPLUG_STAT(dev_priv)) & hotplug_status_mask; + u32 tmp = intel_de_read(display, + PORT_HOTPLUG_STAT(display)) & hotplug_status_mask; if (tmp == 0) return hotplug_status; hotplug_status |= tmp; - intel_uncore_write(&dev_priv->uncore, - PORT_HOTPLUG_STAT(dev_priv), - hotplug_status); + intel_de_write(display, PORT_HOTPLUG_STAT(display), + hotplug_status); } - drm_WARN_ONCE(&dev_priv->drm, 1, + drm_WARN_ONCE(display->drm, 1, "PORT_HOTPLUG_STAT did not clear (0x%08x)\n", - intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT(dev_priv))); + intel_de_read(display, PORT_HOTPLUG_STAT(display))); return hotplug_status; } -void i9xx_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 hotplug_status) +void i9xx_hpd_irq_handler(struct intel_display *display, u32 hotplug_status) { - struct intel_display *display = &dev_priv->display; u32 pin_mask = 0, long_mask = 0; u32 hotplug_trigger; - if (IS_G4X(dev_priv) || - IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) + if (display->platform.g4x || + display->platform.valleyview || display->platform.cherryview) hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_G4X; else hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_I915; if (hotplug_trigger) { - intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, + intel_get_hpd_pins(display, &pin_mask, &long_mask, hotplug_trigger, hotplug_trigger, - dev_priv->display.hotplug.hpd, + display->hotplug.hpd, i9xx_port_hotplug_long_detect); - intel_hpd_irq_handler(dev_priv, pin_mask, long_mask); + intel_hpd_irq_handler(display, pin_mask, long_mask); } - if ((IS_G4X(dev_priv) || - IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && + if ((display->platform.g4x || + display->platform.valleyview || display->platform.cherryview) && hotplug_status & DP_AUX_CHANNEL_MASK_INT_STATUS_G4X) intel_dp_aux_irq_handler(display); } -void ibx_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 hotplug_trigger) +void ibx_hpd_irq_handler(struct intel_display *display, u32 hotplug_trigger) { u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0; @@ -491,7 +490,7 @@ void ibx_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 hotplug_trigger) * zero. Not acking leads to "The master control interrupt lied (SDE)!" * errors. */ - dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG); + dig_hotplug_reg = intel_de_read(display, PCH_PORT_HOTPLUG); if (!hotplug_trigger) { u32 mask = PORTA_HOTPLUG_STATUS_MASK | PORTD_HOTPLUG_STATUS_MASK | @@ -500,63 +499,61 @@ void ibx_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 hotplug_trigger) dig_hotplug_reg &= ~mask; } - intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, dig_hotplug_reg); + intel_de_write(display, PCH_PORT_HOTPLUG, dig_hotplug_reg); if (!hotplug_trigger) return; - intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, + intel_get_hpd_pins(display, &pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, - dev_priv->display.hotplug.pch_hpd, + display->hotplug.pch_hpd, pch_port_hotplug_long_detect); - intel_hpd_irq_handler(dev_priv, pin_mask, long_mask); + intel_hpd_irq_handler(display, pin_mask, long_mask); } -void xelpdp_pica_irq_handler(struct drm_i915_private *i915, u32 iir) +void xelpdp_pica_irq_handler(struct intel_display *display, u32 iir) { - struct intel_display *display = &i915->display; enum hpd_pin pin; u32 hotplug_trigger = iir & (XELPDP_DP_ALT_HOTPLUG_MASK | XELPDP_TBT_HOTPLUG_MASK); u32 trigger_aux = iir & XELPDP_AUX_TC_MASK; u32 pin_mask = 0, long_mask = 0; - if (DISPLAY_VER(i915) >= 20) + if (DISPLAY_VER(display) >= 20) trigger_aux |= iir & XE2LPD_AUX_DDI_MASK; for (pin = HPD_PORT_TC1; pin <= HPD_PORT_TC4; pin++) { u32 val; - if (!(i915->display.hotplug.hpd[pin] & hotplug_trigger)) + if (!(display->hotplug.hpd[pin] & hotplug_trigger)) continue; pin_mask |= BIT(pin); - val = intel_de_read(i915, XELPDP_PORT_HOTPLUG_CTL(pin)); - intel_de_write(i915, XELPDP_PORT_HOTPLUG_CTL(pin), val); + val = intel_de_read(display, XELPDP_PORT_HOTPLUG_CTL(pin)); + intel_de_write(display, XELPDP_PORT_HOTPLUG_CTL(pin), val); if (val & (XELPDP_DP_ALT_HPD_LONG_DETECT | XELPDP_TBT_HPD_LONG_DETECT)) long_mask |= BIT(pin); } if (pin_mask) { - drm_dbg(&i915->drm, - "pica hotplug event received, stat 0x%08x, pins 0x%08x, long 0x%08x\n", - hotplug_trigger, pin_mask, long_mask); + drm_dbg_kms(display->drm, + "pica hotplug event received, stat 0x%08x, pins 0x%08x, long 0x%08x\n", + hotplug_trigger, pin_mask, long_mask); - intel_hpd_irq_handler(i915, pin_mask, long_mask); + intel_hpd_irq_handler(display, pin_mask, long_mask); } if (trigger_aux) intel_dp_aux_irq_handler(display); if (!pin_mask && !trigger_aux) - drm_err(&i915->drm, + drm_err(display->drm, "Unexpected DE HPD/AUX interrupt 0x%08x\n", iir); } -void icp_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) +void icp_irq_handler(struct intel_display *display, u32 pch_iir) { - struct intel_display *display = &dev_priv->display; 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; @@ -565,37 +562,36 @@ void icp_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) u32 dig_hotplug_reg; /* Locking due to DSI native GPIO sequences */ - spin_lock(&dev_priv->irq_lock); - dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_DDI, 0, 0); - spin_unlock(&dev_priv->irq_lock); + spin_lock(&display->irq.lock); + dig_hotplug_reg = intel_de_rmw(display, SHOTPLUG_CTL_DDI, 0, 0); + spin_unlock(&display->irq.lock); - intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, + intel_get_hpd_pins(display, &pin_mask, &long_mask, ddi_hotplug_trigger, dig_hotplug_reg, - dev_priv->display.hotplug.pch_hpd, + display->hotplug.pch_hpd, icp_ddi_port_hotplug_long_detect); } if (tc_hotplug_trigger) { u32 dig_hotplug_reg; - dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_TC, 0, 0); + dig_hotplug_reg = intel_de_rmw(display, SHOTPLUG_CTL_TC, 0, 0); - intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, + intel_get_hpd_pins(display, &pin_mask, &long_mask, tc_hotplug_trigger, dig_hotplug_reg, - dev_priv->display.hotplug.pch_hpd, + display->hotplug.pch_hpd, icp_tc_port_hotplug_long_detect); } if (pin_mask) - intel_hpd_irq_handler(dev_priv, pin_mask, long_mask); + intel_hpd_irq_handler(display, pin_mask, long_mask); if (pch_iir & SDE_GMBUS_ICP) intel_gmbus_irq_handler(display); } -void spt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) +void spt_irq_handler(struct intel_display *display, u32 pch_iir) { - struct intel_display *display = &dev_priv->display; u32 hotplug_trigger = pch_iir & SDE_HOTPLUG_MASK_SPT & ~SDE_PORTE_HOTPLUG_SPT; u32 hotplug2_trigger = pch_iir & SDE_PORTE_HOTPLUG_SPT; @@ -604,61 +600,61 @@ void spt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir) if (hotplug_trigger) { u32 dig_hotplug_reg; - dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG, 0, 0); + dig_hotplug_reg = intel_de_rmw(display, PCH_PORT_HOTPLUG, 0, 0); - intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, + intel_get_hpd_pins(display, &pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, - dev_priv->display.hotplug.pch_hpd, + display->hotplug.pch_hpd, spt_port_hotplug_long_detect); } if (hotplug2_trigger) { u32 dig_hotplug_reg; - dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG2, 0, 0); + dig_hotplug_reg = intel_de_rmw(display, PCH_PORT_HOTPLUG2, 0, 0); - intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, + intel_get_hpd_pins(display, &pin_mask, &long_mask, hotplug2_trigger, dig_hotplug_reg, - dev_priv->display.hotplug.pch_hpd, + display->hotplug.pch_hpd, spt_port_hotplug2_long_detect); } if (pin_mask) - intel_hpd_irq_handler(dev_priv, pin_mask, long_mask); + intel_hpd_irq_handler(display, pin_mask, long_mask); if (pch_iir & SDE_GMBUS_CPT) intel_gmbus_irq_handler(display); } -void ilk_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 hotplug_trigger) +void ilk_hpd_irq_handler(struct intel_display *display, u32 hotplug_trigger) { u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0; - dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL, 0, 0); + dig_hotplug_reg = intel_de_rmw(display, DIGITAL_PORT_HOTPLUG_CNTRL, 0, 0); - intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, + intel_get_hpd_pins(display, &pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, - dev_priv->display.hotplug.hpd, + display->hotplug.hpd, ilk_port_hotplug_long_detect); - intel_hpd_irq_handler(dev_priv, pin_mask, long_mask); + intel_hpd_irq_handler(display, pin_mask, long_mask); } -void bxt_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 hotplug_trigger) +void bxt_hpd_irq_handler(struct intel_display *display, u32 hotplug_trigger) { u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0; - dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG, 0, 0); + dig_hotplug_reg = intel_de_rmw(display, PCH_PORT_HOTPLUG, 0, 0); - intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, + intel_get_hpd_pins(display, &pin_mask, &long_mask, hotplug_trigger, dig_hotplug_reg, - dev_priv->display.hotplug.hpd, + display->hotplug.hpd, bxt_port_hotplug_long_detect); - intel_hpd_irq_handler(dev_priv, pin_mask, long_mask); + intel_hpd_irq_handler(display, pin_mask, long_mask); } -void gen11_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 iir) +void gen11_hpd_irq_handler(struct intel_display *display, u32 iir) { u32 pin_mask = 0, long_mask = 0; u32 trigger_tc = iir & GEN11_DE_TC_HOTPLUG_MASK; @@ -667,29 +663,29 @@ void gen11_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 iir) if (trigger_tc) { u32 dig_hotplug_reg; - dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL, 0, 0); + dig_hotplug_reg = intel_de_rmw(display, GEN11_TC_HOTPLUG_CTL, 0, 0); - intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, + intel_get_hpd_pins(display, &pin_mask, &long_mask, trigger_tc, dig_hotplug_reg, - dev_priv->display.hotplug.hpd, + display->hotplug.hpd, gen11_port_hotplug_long_detect); } if (trigger_tbt) { u32 dig_hotplug_reg; - dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL, 0, 0); + dig_hotplug_reg = intel_de_rmw(display, GEN11_TBT_HOTPLUG_CTL, 0, 0); - intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask, + intel_get_hpd_pins(display, &pin_mask, &long_mask, trigger_tbt, dig_hotplug_reg, - dev_priv->display.hotplug.hpd, + display->hotplug.hpd, gen11_port_hotplug_long_detect); } if (pin_mask) - intel_hpd_irq_handler(dev_priv, pin_mask, long_mask); + intel_hpd_irq_handler(display, pin_mask, long_mask); else - drm_err(&dev_priv->drm, + drm_err(display->drm, "Unexpected DE HPD interrupt 0x%08x\n", iir); } @@ -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 | @@ -735,37 +731,37 @@ static u32 ibx_hotplug_enables(struct intel_encoder *encoder) } } -static void ibx_hpd_detection_setup(struct drm_i915_private *dev_priv) +static void ibx_hpd_detection_setup(struct intel_display *display) { /* * Enable digital hotplug on the PCH, and configure the DP short pulse * duration to 2ms (which is the minimum in the Display Port spec). * The pulse duration bits are reserved on LPT+. */ - intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG, - intel_hpd_hotplug_mask(dev_priv, ibx_hotplug_mask), - intel_hpd_hotplug_enables(dev_priv, ibx_hotplug_enables)); + intel_de_rmw(display, PCH_PORT_HOTPLUG, + intel_hpd_hotplug_mask(display, ibx_hotplug_mask), + intel_hpd_hotplug_enables(display, ibx_hotplug_enables)); } static void ibx_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); - intel_uncore_rmw(&i915->uncore, PCH_PORT_HOTPLUG, - ibx_hotplug_mask(encoder->hpd_pin), - ibx_hotplug_enables(encoder)); + intel_de_rmw(display, PCH_PORT_HOTPLUG, + ibx_hotplug_mask(encoder->hpd_pin), + ibx_hotplug_enables(encoder)); } -static void ibx_hpd_irq_setup(struct drm_i915_private *dev_priv) +static void ibx_hpd_irq_setup(struct intel_display *display) { u32 hotplug_irqs, enabled_irqs; - enabled_irqs = intel_hpd_enabled_irqs(dev_priv, dev_priv->display.hotplug.pch_hpd); - hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->display.hotplug.pch_hpd); + enabled_irqs = intel_hpd_enabled_irqs(display, display->hotplug.pch_hpd); + hotplug_irqs = intel_hpd_hotplug_irqs(display, display->hotplug.pch_hpd); - ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs); + ibx_display_interrupt_update(display, hotplug_irqs, enabled_irqs); - ibx_hpd_detection_setup(dev_priv); + ibx_hpd_detection_setup(display); } static u32 icp_ddi_hotplug_mask(enum hpd_pin hpd_pin) @@ -806,36 +802,36 @@ static u32 icp_tc_hotplug_enables(struct intel_encoder *encoder) return icp_tc_hotplug_mask(encoder->hpd_pin); } -static void icp_ddi_hpd_detection_setup(struct drm_i915_private *dev_priv) +static void icp_ddi_hpd_detection_setup(struct intel_display *display) { - intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_DDI, - intel_hpd_hotplug_mask(dev_priv, icp_ddi_hotplug_mask), - intel_hpd_hotplug_enables(dev_priv, icp_ddi_hotplug_enables)); + intel_de_rmw(display, SHOTPLUG_CTL_DDI, + intel_hpd_hotplug_mask(display, icp_ddi_hotplug_mask), + intel_hpd_hotplug_enables(display, icp_ddi_hotplug_enables)); } static void icp_ddi_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); - intel_uncore_rmw(&i915->uncore, SHOTPLUG_CTL_DDI, - icp_ddi_hotplug_mask(encoder->hpd_pin), - icp_ddi_hotplug_enables(encoder)); + intel_de_rmw(display, SHOTPLUG_CTL_DDI, + icp_ddi_hotplug_mask(encoder->hpd_pin), + icp_ddi_hotplug_enables(encoder)); } -static void icp_tc_hpd_detection_setup(struct drm_i915_private *dev_priv) +static void icp_tc_hpd_detection_setup(struct intel_display *display) { - intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_TC, - intel_hpd_hotplug_mask(dev_priv, icp_tc_hotplug_mask), - intel_hpd_hotplug_enables(dev_priv, icp_tc_hotplug_enables)); + intel_de_rmw(display, SHOTPLUG_CTL_TC, + intel_hpd_hotplug_mask(display, icp_tc_hotplug_mask), + intel_hpd_hotplug_enables(display, icp_tc_hotplug_enables)); } static void icp_tc_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); - intel_uncore_rmw(&i915->uncore, SHOTPLUG_CTL_TC, - icp_tc_hotplug_mask(encoder->hpd_pin), - icp_tc_hotplug_enables(encoder)); + intel_de_rmw(display, SHOTPLUG_CTL_TC, + icp_tc_hotplug_mask(encoder->hpd_pin), + icp_tc_hotplug_enables(encoder)); } static void icp_hpd_enable_detection(struct intel_encoder *encoder) @@ -844,23 +840,23 @@ static void icp_hpd_enable_detection(struct intel_encoder *encoder) icp_tc_hpd_enable_detection(encoder); } -static void icp_hpd_irq_setup(struct drm_i915_private *dev_priv) +static void icp_hpd_irq_setup(struct intel_display *display) { u32 hotplug_irqs, enabled_irqs; - enabled_irqs = intel_hpd_enabled_irqs(dev_priv, dev_priv->display.hotplug.pch_hpd); - hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->display.hotplug.pch_hpd); + enabled_irqs = intel_hpd_enabled_irqs(display, display->hotplug.pch_hpd); + hotplug_irqs = intel_hpd_hotplug_irqs(display, display->hotplug.pch_hpd); /* * We reduce the value to 250us to be able to detect SHPD when an external display * is connected. This is also expected of us as stated in DP1.4a Table 3-4. */ - intel_uncore_write(&dev_priv->uncore, SHPD_FILTER_CNT, SHPD_FILTER_CNT_250); + intel_de_write(display, SHPD_FILTER_CNT, SHPD_FILTER_CNT_250); - ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs); + ibx_display_interrupt_update(display, hotplug_irqs, enabled_irqs); - icp_ddi_hpd_detection_setup(dev_priv); - icp_tc_hpd_detection_setup(dev_priv); + icp_ddi_hpd_detection_setup(display); + icp_tc_hpd_detection_setup(display); } static u32 gen11_hotplug_mask(enum hpd_pin hpd_pin) @@ -883,88 +879,88 @@ static u32 gen11_hotplug_enables(struct intel_encoder *encoder) return gen11_hotplug_mask(encoder->hpd_pin); } -static void dg1_hpd_invert(struct drm_i915_private *i915) +static void dg1_hpd_invert(struct intel_display *display) { u32 val = (INVERT_DDIA_HPD | INVERT_DDIB_HPD | INVERT_DDIC_HPD | INVERT_DDID_HPD); - intel_uncore_rmw(&i915->uncore, SOUTH_CHICKEN1, 0, val); + intel_de_rmw(display, SOUTH_CHICKEN1, 0, val); } static void dg1_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); - dg1_hpd_invert(i915); + dg1_hpd_invert(display); icp_hpd_enable_detection(encoder); } -static void dg1_hpd_irq_setup(struct drm_i915_private *dev_priv) +static void dg1_hpd_irq_setup(struct intel_display *display) { - dg1_hpd_invert(dev_priv); - icp_hpd_irq_setup(dev_priv); + dg1_hpd_invert(display); + icp_hpd_irq_setup(display); } -static void gen11_tc_hpd_detection_setup(struct drm_i915_private *dev_priv) +static void gen11_tc_hpd_detection_setup(struct intel_display *display) { - intel_uncore_rmw(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL, - intel_hpd_hotplug_mask(dev_priv, gen11_hotplug_mask), - intel_hpd_hotplug_enables(dev_priv, gen11_hotplug_enables)); + intel_de_rmw(display, GEN11_TC_HOTPLUG_CTL, + intel_hpd_hotplug_mask(display, gen11_hotplug_mask), + intel_hpd_hotplug_enables(display, gen11_hotplug_enables)); } static void gen11_tc_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); - intel_uncore_rmw(&i915->uncore, GEN11_TC_HOTPLUG_CTL, - gen11_hotplug_mask(encoder->hpd_pin), - gen11_hotplug_enables(encoder)); + intel_de_rmw(display, GEN11_TC_HOTPLUG_CTL, + gen11_hotplug_mask(encoder->hpd_pin), + gen11_hotplug_enables(encoder)); } -static void gen11_tbt_hpd_detection_setup(struct drm_i915_private *dev_priv) +static void gen11_tbt_hpd_detection_setup(struct intel_display *display) { - intel_uncore_rmw(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL, - intel_hpd_hotplug_mask(dev_priv, gen11_hotplug_mask), - intel_hpd_hotplug_enables(dev_priv, gen11_hotplug_enables)); + intel_de_rmw(display, GEN11_TBT_HOTPLUG_CTL, + intel_hpd_hotplug_mask(display, gen11_hotplug_mask), + intel_hpd_hotplug_enables(display, gen11_hotplug_enables)); } static void gen11_tbt_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); - intel_uncore_rmw(&i915->uncore, GEN11_TBT_HOTPLUG_CTL, - gen11_hotplug_mask(encoder->hpd_pin), - gen11_hotplug_enables(encoder)); + intel_de_rmw(display, GEN11_TBT_HOTPLUG_CTL, + gen11_hotplug_mask(encoder->hpd_pin), + gen11_hotplug_enables(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 drm_i915_private *dev_priv) +static void gen11_hpd_irq_setup(struct intel_display *display) { u32 hotplug_irqs, enabled_irqs; - enabled_irqs = intel_hpd_enabled_irqs(dev_priv, dev_priv->display.hotplug.hpd); - hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->display.hotplug.hpd); + enabled_irqs = intel_hpd_enabled_irqs(display, display->hotplug.hpd); + hotplug_irqs = intel_hpd_hotplug_irqs(display, display->hotplug.hpd); - intel_uncore_rmw(&dev_priv->uncore, GEN11_DE_HPD_IMR, hotplug_irqs, - ~enabled_irqs & hotplug_irqs); - intel_uncore_posting_read(&dev_priv->uncore, GEN11_DE_HPD_IMR); + intel_de_rmw(display, GEN11_DE_HPD_IMR, hotplug_irqs, + ~enabled_irqs & hotplug_irqs); + intel_de_posting_read(display, GEN11_DE_HPD_IMR); - gen11_tc_hpd_detection_setup(dev_priv); - gen11_tbt_hpd_detection_setup(dev_priv); + gen11_tc_hpd_detection_setup(display); + gen11_tbt_hpd_detection_setup(display); - if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP) - icp_hpd_irq_setup(dev_priv); + if (INTEL_PCH_TYPE(display) >= PCH_ICP) + icp_hpd_irq_setup(display); } static u32 mtp_ddi_hotplug_mask(enum hpd_pin hpd_pin) @@ -1001,39 +997,39 @@ static u32 mtp_tc_hotplug_enables(struct intel_encoder *encoder) return mtp_tc_hotplug_mask(encoder->hpd_pin); } -static void mtp_ddi_hpd_detection_setup(struct drm_i915_private *i915) +static void mtp_ddi_hpd_detection_setup(struct intel_display *display) { - intel_de_rmw(i915, SHOTPLUG_CTL_DDI, - intel_hpd_hotplug_mask(i915, mtp_ddi_hotplug_mask), - intel_hpd_hotplug_enables(i915, mtp_ddi_hotplug_enables)); + intel_de_rmw(display, SHOTPLUG_CTL_DDI, + intel_hpd_hotplug_mask(display, mtp_ddi_hotplug_mask), + intel_hpd_hotplug_enables(display, mtp_ddi_hotplug_enables)); } static void mtp_ddi_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); - intel_de_rmw(i915, SHOTPLUG_CTL_DDI, + intel_de_rmw(display, SHOTPLUG_CTL_DDI, mtp_ddi_hotplug_mask(encoder->hpd_pin), mtp_ddi_hotplug_enables(encoder)); } -static void mtp_tc_hpd_detection_setup(struct drm_i915_private *i915) +static void mtp_tc_hpd_detection_setup(struct intel_display *display) { - intel_de_rmw(i915, SHOTPLUG_CTL_TC, - intel_hpd_hotplug_mask(i915, mtp_tc_hotplug_mask), - intel_hpd_hotplug_enables(i915, mtp_tc_hotplug_enables)); + intel_de_rmw(display, SHOTPLUG_CTL_TC, + intel_hpd_hotplug_mask(display, mtp_tc_hotplug_mask), + intel_hpd_hotplug_enables(display, mtp_tc_hotplug_enables)); } static void mtp_tc_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); - intel_de_rmw(i915, SHOTPLUG_CTL_DDI, + intel_de_rmw(display, SHOTPLUG_CTL_DDI, mtp_tc_hotplug_mask(encoder->hpd_pin), mtp_tc_hotplug_enables(encoder)); } -static void mtp_hpd_invert(struct drm_i915_private *i915) +static void mtp_hpd_invert(struct intel_display *display) { u32 val = (INVERT_DDIA_HPD | INVERT_DDIB_HPD | @@ -1044,49 +1040,49 @@ static void mtp_hpd_invert(struct drm_i915_private *i915) INVERT_TC4_HPD | INVERT_DDID_HPD_MTP | INVERT_DDIE_HPD); - intel_de_rmw(i915, SOUTH_CHICKEN1, 0, val); + intel_de_rmw(display, SOUTH_CHICKEN1, 0, val); } static void mtp_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); - mtp_hpd_invert(i915); + mtp_hpd_invert(display); mtp_ddi_hpd_enable_detection(encoder); mtp_tc_hpd_enable_detection(encoder); } -static void mtp_hpd_irq_setup(struct drm_i915_private *i915) +static void mtp_hpd_irq_setup(struct intel_display *display) { u32 hotplug_irqs, enabled_irqs; - enabled_irqs = intel_hpd_enabled_irqs(i915, i915->display.hotplug.pch_hpd); - hotplug_irqs = intel_hpd_hotplug_irqs(i915, i915->display.hotplug.pch_hpd); + enabled_irqs = intel_hpd_enabled_irqs(display, display->hotplug.pch_hpd); + hotplug_irqs = intel_hpd_hotplug_irqs(display, display->hotplug.pch_hpd); /* * Use 250us here to align with the DP1.4a(Table 3-4) spec as to what the * SHPD_FILTER_CNT value should be. */ - intel_de_write(i915, SHPD_FILTER_CNT, SHPD_FILTER_CNT_250); + intel_de_write(display, SHPD_FILTER_CNT, SHPD_FILTER_CNT_250); - mtp_hpd_invert(i915); - ibx_display_interrupt_update(i915, hotplug_irqs, enabled_irqs); + mtp_hpd_invert(display); + ibx_display_interrupt_update(display, hotplug_irqs, enabled_irqs); - mtp_ddi_hpd_detection_setup(i915); - mtp_tc_hpd_detection_setup(i915); + mtp_ddi_hpd_detection_setup(display); + mtp_tc_hpd_detection_setup(display); } -static void xe2lpd_sde_hpd_irq_setup(struct drm_i915_private *i915) +static void xe2lpd_sde_hpd_irq_setup(struct intel_display *display) { u32 hotplug_irqs, enabled_irqs; - enabled_irqs = intel_hpd_enabled_irqs(i915, i915->display.hotplug.pch_hpd); - hotplug_irqs = intel_hpd_hotplug_irqs(i915, i915->display.hotplug.pch_hpd); + enabled_irqs = intel_hpd_enabled_irqs(display, display->hotplug.pch_hpd); + hotplug_irqs = intel_hpd_hotplug_irqs(display, display->hotplug.pch_hpd); - ibx_display_interrupt_update(i915, hotplug_irqs, enabled_irqs); + ibx_display_interrupt_update(display, hotplug_irqs, enabled_irqs); - mtp_ddi_hpd_detection_setup(i915); - mtp_tc_hpd_detection_setup(i915); + mtp_ddi_hpd_detection_setup(display); + mtp_tc_hpd_detection_setup(display); } static bool is_xelpdp_pica_hpd_pin(enum hpd_pin hpd_pin) @@ -1094,7 +1090,7 @@ static bool is_xelpdp_pica_hpd_pin(enum hpd_pin hpd_pin) return hpd_pin >= HPD_PORT_TC1 && hpd_pin <= HPD_PORT_TC4; } -static void _xelpdp_pica_hpd_detection_setup(struct drm_i915_private *i915, +static void _xelpdp_pica_hpd_detection_setup(struct intel_display *display, enum hpd_pin hpd_pin, bool enable) { u32 mask = XELPDP_TBT_HOTPLUG_ENABLE | @@ -1103,18 +1099,18 @@ static void _xelpdp_pica_hpd_detection_setup(struct drm_i915_private *i915, if (!is_xelpdp_pica_hpd_pin(hpd_pin)) return; - intel_de_rmw(i915, XELPDP_PORT_HOTPLUG_CTL(hpd_pin), + intel_de_rmw(display, XELPDP_PORT_HOTPLUG_CTL(hpd_pin), mask, enable ? mask : 0); } static void xelpdp_pica_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); - _xelpdp_pica_hpd_detection_setup(i915, encoder->hpd_pin, true); + _xelpdp_pica_hpd_detection_setup(display, encoder->hpd_pin, true); } -static void xelpdp_pica_hpd_detection_setup(struct drm_i915_private *i915) +static void xelpdp_pica_hpd_detection_setup(struct intel_display *display) { struct intel_encoder *encoder; u32 available_pins = 0; @@ -1122,11 +1118,11 @@ static void xelpdp_pica_hpd_detection_setup(struct drm_i915_private *i915) BUILD_BUG_ON(BITS_PER_TYPE(available_pins) < HPD_NUM_PINS); - for_each_intel_encoder(&i915->drm, encoder) + for_each_intel_encoder(display->drm, encoder) available_pins |= BIT(encoder->hpd_pin); for_each_hpd_pin(pin) - _xelpdp_pica_hpd_detection_setup(i915, pin, available_pins & BIT(pin)); + _xelpdp_pica_hpd_detection_setup(display, pin, available_pins & BIT(pin)); } static void xelpdp_hpd_enable_detection(struct intel_encoder *encoder) @@ -1135,23 +1131,23 @@ static void xelpdp_hpd_enable_detection(struct intel_encoder *encoder) mtp_hpd_enable_detection(encoder); } -static void xelpdp_hpd_irq_setup(struct drm_i915_private *i915) +static void xelpdp_hpd_irq_setup(struct intel_display *display) { u32 hotplug_irqs, enabled_irqs; - enabled_irqs = intel_hpd_enabled_irqs(i915, i915->display.hotplug.hpd); - hotplug_irqs = intel_hpd_hotplug_irqs(i915, i915->display.hotplug.hpd); + enabled_irqs = intel_hpd_enabled_irqs(display, display->hotplug.hpd); + hotplug_irqs = intel_hpd_hotplug_irqs(display, display->hotplug.hpd); - intel_de_rmw(i915, PICAINTERRUPT_IMR, hotplug_irqs, + intel_de_rmw(display, PICAINTERRUPT_IMR, hotplug_irqs, ~enabled_irqs & hotplug_irqs); - intel_uncore_posting_read(&i915->uncore, PICAINTERRUPT_IMR); + intel_de_posting_read(display, PICAINTERRUPT_IMR); - xelpdp_pica_hpd_detection_setup(i915); + xelpdp_pica_hpd_detection_setup(display); - if (INTEL_PCH_TYPE(i915) >= PCH_LNL) - xe2lpd_sde_hpd_irq_setup(i915); - else if (INTEL_PCH_TYPE(i915) >= PCH_MTL) - mtp_hpd_irq_setup(i915); + if (INTEL_PCH_TYPE(display) >= PCH_LNL) + xe2lpd_sde_hpd_irq_setup(display); + else if (INTEL_PCH_TYPE(display) >= PCH_MTL) + mtp_hpd_irq_setup(display); } static u32 spt_hotplug_mask(enum hpd_pin hpd_pin) @@ -1190,57 +1186,57 @@ static u32 spt_hotplug2_enables(struct intel_encoder *encoder) return spt_hotplug2_mask(encoder->hpd_pin); } -static void spt_hpd_detection_setup(struct drm_i915_private *dev_priv) +static void spt_hpd_detection_setup(struct intel_display *display) { /* Display WA #1179 WaHardHangonHotPlug: cnp */ - if (HAS_PCH_CNP(dev_priv)) { - intel_uncore_rmw(&dev_priv->uncore, SOUTH_CHICKEN1, CHASSIS_CLK_REQ_DURATION_MASK, - CHASSIS_CLK_REQ_DURATION(0xf)); + if (HAS_PCH_CNP(display)) { + intel_de_rmw(display, SOUTH_CHICKEN1, CHASSIS_CLK_REQ_DURATION_MASK, + CHASSIS_CLK_REQ_DURATION(0xf)); } /* Enable digital hotplug on the PCH */ - intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG, - intel_hpd_hotplug_mask(dev_priv, spt_hotplug_mask), - intel_hpd_hotplug_enables(dev_priv, spt_hotplug_enables)); + intel_de_rmw(display, PCH_PORT_HOTPLUG, + intel_hpd_hotplug_mask(display, spt_hotplug_mask), + intel_hpd_hotplug_enables(display, spt_hotplug_enables)); - intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG2, - intel_hpd_hotplug_mask(dev_priv, spt_hotplug2_mask), - intel_hpd_hotplug_enables(dev_priv, spt_hotplug2_enables)); + intel_de_rmw(display, PCH_PORT_HOTPLUG2, + intel_hpd_hotplug_mask(display, spt_hotplug2_mask), + intel_hpd_hotplug_enables(display, spt_hotplug2_enables)); } static void spt_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); /* Display WA #1179 WaHardHangonHotPlug: cnp */ - if (HAS_PCH_CNP(i915)) { - intel_uncore_rmw(&i915->uncore, SOUTH_CHICKEN1, - CHASSIS_CLK_REQ_DURATION_MASK, - CHASSIS_CLK_REQ_DURATION(0xf)); + if (HAS_PCH_CNP(display)) { + intel_de_rmw(display, SOUTH_CHICKEN1, + CHASSIS_CLK_REQ_DURATION_MASK, + CHASSIS_CLK_REQ_DURATION(0xf)); } - intel_uncore_rmw(&i915->uncore, PCH_PORT_HOTPLUG, - spt_hotplug_mask(encoder->hpd_pin), - spt_hotplug_enables(encoder)); + intel_de_rmw(display, PCH_PORT_HOTPLUG, + spt_hotplug_mask(encoder->hpd_pin), + spt_hotplug_enables(encoder)); - intel_uncore_rmw(&i915->uncore, PCH_PORT_HOTPLUG2, - spt_hotplug2_mask(encoder->hpd_pin), - spt_hotplug2_enables(encoder)); + intel_de_rmw(display, PCH_PORT_HOTPLUG2, + spt_hotplug2_mask(encoder->hpd_pin), + spt_hotplug2_enables(encoder)); } -static void spt_hpd_irq_setup(struct drm_i915_private *dev_priv) +static void spt_hpd_irq_setup(struct intel_display *display) { u32 hotplug_irqs, enabled_irqs; - if (INTEL_PCH_TYPE(dev_priv) >= PCH_CNP) - intel_uncore_write(&dev_priv->uncore, SHPD_FILTER_CNT, SHPD_FILTER_CNT_500_ADJ); + 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(dev_priv, dev_priv->display.hotplug.pch_hpd); - hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->display.hotplug.pch_hpd); + enabled_irqs = intel_hpd_enabled_irqs(display, display->hotplug.pch_hpd); + hotplug_irqs = intel_hpd_hotplug_irqs(display, display->hotplug.pch_hpd); - ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs); + ibx_display_interrupt_update(display, hotplug_irqs, enabled_irqs); - spt_hpd_detection_setup(dev_priv); + spt_hpd_detection_setup(display); } static u32 ilk_hotplug_mask(enum hpd_pin hpd_pin) @@ -1265,44 +1261,44 @@ static u32 ilk_hotplug_enables(struct intel_encoder *encoder) } } -static void ilk_hpd_detection_setup(struct drm_i915_private *dev_priv) +static void ilk_hpd_detection_setup(struct intel_display *display) { /* * Enable digital hotplug on the CPU, and configure the DP short pulse * duration to 2ms (which is the minimum in the Display Port spec) * The pulse duration bits are reserved on HSW+. */ - intel_uncore_rmw(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL, - intel_hpd_hotplug_mask(dev_priv, ilk_hotplug_mask), - intel_hpd_hotplug_enables(dev_priv, ilk_hotplug_enables)); + intel_de_rmw(display, DIGITAL_PORT_HOTPLUG_CNTRL, + intel_hpd_hotplug_mask(display, ilk_hotplug_mask), + intel_hpd_hotplug_enables(display, ilk_hotplug_enables)); } static void ilk_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); - intel_uncore_rmw(&i915->uncore, DIGITAL_PORT_HOTPLUG_CNTRL, - ilk_hotplug_mask(encoder->hpd_pin), - ilk_hotplug_enables(encoder)); + intel_de_rmw(display, DIGITAL_PORT_HOTPLUG_CNTRL, + ilk_hotplug_mask(encoder->hpd_pin), + ilk_hotplug_enables(encoder)); ibx_hpd_enable_detection(encoder); } -static void ilk_hpd_irq_setup(struct drm_i915_private *dev_priv) +static void ilk_hpd_irq_setup(struct intel_display *display) { u32 hotplug_irqs, enabled_irqs; - enabled_irqs = intel_hpd_enabled_irqs(dev_priv, dev_priv->display.hotplug.hpd); - hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->display.hotplug.hpd); + enabled_irqs = intel_hpd_enabled_irqs(display, display->hotplug.hpd); + hotplug_irqs = intel_hpd_hotplug_irqs(display, display->hotplug.hpd); - if (DISPLAY_VER(dev_priv) >= 8) - bdw_update_port_irq(dev_priv, hotplug_irqs, enabled_irqs); + if (DISPLAY_VER(display) >= 8) + bdw_update_port_irq(display, hotplug_irqs, enabled_irqs); else - ilk_update_display_irq(dev_priv, hotplug_irqs, enabled_irqs); + ilk_update_display_irq(display, hotplug_irqs, enabled_irqs); - ilk_hpd_detection_setup(dev_priv); + ilk_hpd_detection_setup(display); - ibx_hpd_irq_setup(dev_priv); + ibx_hpd_irq_setup(display); } static u32 bxt_hotplug_mask(enum hpd_pin hpd_pin) @@ -1344,80 +1340,80 @@ static u32 bxt_hotplug_enables(struct intel_encoder *encoder) } } -static void bxt_hpd_detection_setup(struct drm_i915_private *dev_priv) +static void bxt_hpd_detection_setup(struct intel_display *display) { - intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG, - intel_hpd_hotplug_mask(dev_priv, bxt_hotplug_mask), - intel_hpd_hotplug_enables(dev_priv, bxt_hotplug_enables)); + intel_de_rmw(display, PCH_PORT_HOTPLUG, + intel_hpd_hotplug_mask(display, bxt_hotplug_mask), + intel_hpd_hotplug_enables(display, bxt_hotplug_enables)); } static void bxt_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); - intel_uncore_rmw(&i915->uncore, PCH_PORT_HOTPLUG, - bxt_hotplug_mask(encoder->hpd_pin), - bxt_hotplug_enables(encoder)); + intel_de_rmw(display, PCH_PORT_HOTPLUG, + bxt_hotplug_mask(encoder->hpd_pin), + bxt_hotplug_enables(encoder)); } -static void bxt_hpd_irq_setup(struct drm_i915_private *dev_priv) +static void bxt_hpd_irq_setup(struct intel_display *display) { u32 hotplug_irqs, enabled_irqs; - enabled_irqs = intel_hpd_enabled_irqs(dev_priv, dev_priv->display.hotplug.hpd); - hotplug_irqs = intel_hpd_hotplug_irqs(dev_priv, dev_priv->display.hotplug.hpd); + enabled_irqs = intel_hpd_enabled_irqs(display, display->hotplug.hpd); + hotplug_irqs = intel_hpd_hotplug_irqs(display, display->hotplug.hpd); - bdw_update_port_irq(dev_priv, hotplug_irqs, enabled_irqs); + bdw_update_port_irq(display, hotplug_irqs, enabled_irqs); - bxt_hpd_detection_setup(dev_priv); + bxt_hpd_detection_setup(display); } -static void g45_hpd_peg_band_gap_wa(struct drm_i915_private *i915) +static void g45_hpd_peg_band_gap_wa(struct intel_display *display) { /* * For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written * 0xd. Failure to do so will result in spurious interrupts being * generated on the port when a cable is not attached. */ - intel_de_rmw(i915, PEG_BAND_GAP_DATA, 0xf, 0xd); + intel_de_rmw(display, PEG_BAND_GAP_DATA, 0xf, 0xd); } static void i915_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); u32 hotplug_en = hpd_mask_i915[encoder->hpd_pin]; - if (IS_G45(i915)) - g45_hpd_peg_band_gap_wa(i915); + if (display->platform.g45) + g45_hpd_peg_band_gap_wa(display); /* HPD sense and interrupt enable are one and the same */ - i915_hotplug_interrupt_update(i915, hotplug_en, hotplug_en); + i915_hotplug_interrupt_update(display, hotplug_en, hotplug_en); } -static void i915_hpd_irq_setup(struct drm_i915_private *dev_priv) +static void i915_hpd_irq_setup(struct intel_display *display) { 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 * generations. */ - hotplug_en = intel_hpd_enabled_irqs(dev_priv, hpd_mask_i915); + hotplug_en = intel_hpd_enabled_irqs(display, hpd_mask_i915); /* * Programming the CRT detection parameters tends to generate a spurious * hotplug event about three seconds later. So just do it once. */ - if (IS_G4X(dev_priv)) + if (display->platform.g4x) hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; - if (IS_G45(dev_priv)) - g45_hpd_peg_band_gap_wa(dev_priv); + if (display->platform.g45) + g45_hpd_peg_band_gap_wa(display); /* Ignore TV since it's buggy */ - i915_hotplug_interrupt_update_locked(dev_priv, + i915_hotplug_interrupt_update_locked(display, HOTPLUG_INT_EN_MASK | CRT_HOTPLUG_VOLTAGE_COMPARE_MASK | CRT_HOTPLUG_ACTIVATION_PERIOD_64, @@ -1426,7 +1422,7 @@ static void i915_hpd_irq_setup(struct drm_i915_private *dev_priv) struct intel_hotplug_funcs { /* Enable HPD sense and interrupts for all present encoders */ - void (*hpd_irq_setup)(struct drm_i915_private *i915); + void (*hpd_irq_setup)(struct intel_display *display); /* Enable HPD sense for a single encoder */ void (*hpd_enable_detection)(struct intel_encoder *encoder); }; @@ -1449,47 +1445,47 @@ HPD_FUNCS(ilk); void intel_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); - if (i915->display.funcs.hotplug) - i915->display.funcs.hotplug->hpd_enable_detection(encoder); + if (display->funcs.hotplug) + display->funcs.hotplug->hpd_enable_detection(encoder); } -void intel_hpd_irq_setup(struct drm_i915_private *i915) +void intel_hpd_irq_setup(struct intel_display *display) { - if ((IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) && - !i915->display.irq.vlv_display_irqs_enabled) + if ((display->platform.valleyview || display->platform.cherryview) && + !display->irq.vlv_display_irqs_enabled) return; - if (i915->display.funcs.hotplug) - i915->display.funcs.hotplug->hpd_irq_setup(i915); + if (display->funcs.hotplug) + display->funcs.hotplug->hpd_irq_setup(display); } -void intel_hotplug_irq_init(struct drm_i915_private *i915) +void intel_hotplug_irq_init(struct intel_display *display) { - intel_hpd_init_pins(i915); + intel_hpd_init_pins(display); - intel_hpd_init_early(i915); + intel_hpd_init_early(display); - if (HAS_GMCH(i915)) { - if (I915_HAS_HOTPLUG(i915)) - i915->display.funcs.hotplug = &i915_hpd_funcs; + if (HAS_GMCH(display)) { + if (HAS_HOTPLUG(display)) + display->funcs.hotplug = &i915_hpd_funcs; } else { - if (HAS_PCH_DG2(i915)) - i915->display.funcs.hotplug = &icp_hpd_funcs; - else if (HAS_PCH_DG1(i915)) - i915->display.funcs.hotplug = &dg1_hpd_funcs; - else if (DISPLAY_VER(i915) >= 14) - i915->display.funcs.hotplug = &xelpdp_hpd_funcs; - else if (DISPLAY_VER(i915) >= 11) - i915->display.funcs.hotplug = &gen11_hpd_funcs; - else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) - i915->display.funcs.hotplug = &bxt_hpd_funcs; - else if (INTEL_PCH_TYPE(i915) >= PCH_ICP) - i915->display.funcs.hotplug = &icp_hpd_funcs; - else if (INTEL_PCH_TYPE(i915) >= PCH_SPT) - i915->display.funcs.hotplug = &spt_hpd_funcs; + if (HAS_PCH_DG2(display)) + display->funcs.hotplug = &icp_hpd_funcs; + else if (HAS_PCH_DG1(display)) + display->funcs.hotplug = &dg1_hpd_funcs; + else if (DISPLAY_VER(display) >= 14) + display->funcs.hotplug = &xelpdp_hpd_funcs; + else if (DISPLAY_VER(display) >= 11) + 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(display) >= PCH_ICP) + display->funcs.hotplug = &icp_hpd_funcs; + else if (INTEL_PCH_TYPE(display) >= PCH_SPT) + display->funcs.hotplug = &spt_hpd_funcs; else - i915->display.funcs.hotplug = &ilk_hpd_funcs; + display->funcs.hotplug = &ilk_hpd_funcs; } } diff --git a/drivers/gpu/drm/i915/display/intel_hotplug_irq.h b/drivers/gpu/drm/i915/display/intel_hotplug_irq.h index e4db752df096..9063bb02a2e9 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug_irq.h +++ b/drivers/gpu/drm/i915/display/intel_hotplug_irq.h @@ -8,28 +8,28 @@ #include <linux/types.h> -struct drm_i915_private; +struct intel_display; struct intel_encoder; -u32 i9xx_hpd_irq_ack(struct drm_i915_private *i915); +u32 i9xx_hpd_irq_ack(struct intel_display *display); -void i9xx_hpd_irq_handler(struct drm_i915_private *i915, u32 hotplug_status); -void ibx_hpd_irq_handler(struct drm_i915_private *i915, u32 hotplug_trigger); -void ilk_hpd_irq_handler(struct drm_i915_private *i915, u32 hotplug_trigger); -void gen11_hpd_irq_handler(struct drm_i915_private *i915, u32 iir); -void bxt_hpd_irq_handler(struct drm_i915_private *i915, u32 hotplug_trigger); -void xelpdp_pica_irq_handler(struct drm_i915_private *i915, u32 iir); -void icp_irq_handler(struct drm_i915_private *i915, u32 pch_iir); -void spt_irq_handler(struct drm_i915_private *i915, u32 pch_iir); +void i9xx_hpd_irq_handler(struct intel_display *display, u32 hotplug_status); +void ibx_hpd_irq_handler(struct intel_display *display, u32 hotplug_trigger); +void ilk_hpd_irq_handler(struct intel_display *display, u32 hotplug_trigger); +void gen11_hpd_irq_handler(struct intel_display *display, u32 iir); +void bxt_hpd_irq_handler(struct intel_display *display, u32 hotplug_trigger); +void xelpdp_pica_irq_handler(struct intel_display *display, u32 iir); +void icp_irq_handler(struct intel_display *display, u32 pch_iir); +void spt_irq_handler(struct intel_display *display, u32 pch_iir); -void i915_hotplug_interrupt_update_locked(struct drm_i915_private *i915, +void i915_hotplug_interrupt_update_locked(struct intel_display *display, u32 mask, u32 bits); -void i915_hotplug_interrupt_update(struct drm_i915_private *i915, +void i915_hotplug_interrupt_update(struct intel_display *display, u32 mask, u32 bits); void intel_hpd_enable_detection(struct intel_encoder *encoder); -void intel_hpd_irq_setup(struct drm_i915_private *i915); +void intel_hpd_irq_setup(struct intel_display *display); -void intel_hotplug_irq_init(struct drm_i915_private *i915); +void intel_hotplug_irq_init(struct intel_display *display); #endif /* __INTEL_HOTPLUG_IRQ_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_hti.c b/drivers/gpu/drm/i915/display/intel_hti.c index fb6b84f6a81d..dc454420c134 100644 --- a/drivers/gpu/drm/i915/display/intel_hti.c +++ b/drivers/gpu/drm/i915/display/intel_hti.c @@ -4,6 +4,7 @@ */ #include <drm/drm_device.h> +#include <drm/drm_print.h> #include "intel_de.h" #include "intel_display.h" diff --git a/drivers/gpu/drm/i915/display/intel_load_detect.c b/drivers/gpu/drm/i915/display/intel_load_detect.c index 86cc03a4413c..aad52d0d83e1 100644 --- a/drivers/gpu/drm/i915/display/intel_load_detect.c +++ b/drivers/gpu/drm/i915/display/intel_load_detect.c @@ -6,6 +6,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_uapi.h> +#include <drm/drm_print.h> #include "intel_atomic.h" #include "intel_crtc.h" 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_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c index 63c1afa30b05..f94b7eeae20f 100644 --- a/drivers/gpu/drm/i915/display/intel_lspcon.c +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c @@ -27,6 +27,7 @@ #include <drm/display/drm_hdmi_helper.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_edid.h> +#include <drm/drm_print.h> #include "i915_reg.h" #include "i915_utils.h" diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index 19f52d1659fa..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" @@ -84,15 +84,15 @@ static struct intel_lvds_encoder *to_lvds_encoder(struct intel_encoder *encoder) return container_of(encoder, struct intel_lvds_encoder, base); } -bool intel_lvds_port_enabled(struct drm_i915_private *i915, +bool intel_lvds_port_enabled(struct intel_display *display, i915_reg_t lvds_reg, enum pipe *pipe) { u32 val; - val = intel_de_read(i915, lvds_reg); + 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); @@ -104,7 +104,6 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { 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); intel_wakeref_t wakeref; bool ret; @@ -113,7 +112,7 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder, if (!wakeref) return false; - ret = intel_lvds_port_enabled(i915, lvds_encoder->reg, pipe); + ret = intel_lvds_port_enabled(display, lvds_encoder->reg, pipe); intel_display_power_put(display, encoder->power_domain, wakeref); @@ -123,13 +122,13 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder, static void intel_lvds_get_config(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder); u32 tmp, flags = 0; crtc_state->output_types |= BIT(INTEL_OUTPUT_LVDS); - tmp = intel_de_read(dev_priv, lvds_encoder->reg); + tmp = intel_de_read(display, lvds_encoder->reg); if (tmp & LVDS_HSYNC_POLARITY) flags |= DRM_MODE_FLAG_NHSYNC; else @@ -141,13 +140,13 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, crtc_state->hw.adjusted_mode.flags |= flags; - if (DISPLAY_VER(dev_priv) < 5) + if (DISPLAY_VER(display) < 5) crtc_state->gmch_pfit.lvds_border_bits = tmp & LVDS_BORDER_ENABLE; /* gen2/3 store dither state in pfit control, needs to match */ - if (DISPLAY_VER(dev_priv) < 4) { - tmp = intel_de_read(dev_priv, PFIT_CONTROL(dev_priv)); + if (DISPLAY_VER(display) < 4) { + tmp = intel_de_read(display, PFIT_CONTROL(display)); crtc_state->gmch_pfit.control |= tmp & PFIT_PANEL_8TO6_DITHER_ENABLE; } @@ -155,24 +154,24 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, crtc_state->hw.adjusted_mode.crtc_clock = crtc_state->port_clock; } -static void intel_lvds_pps_get_hw_state(struct drm_i915_private *dev_priv, +static void intel_lvds_pps_get_hw_state(struct intel_display *display, struct intel_lvds_pps *pps) { u32 val; - pps->powerdown_on_reset = intel_de_read(dev_priv, - PP_CONTROL(dev_priv, 0)) & PANEL_POWER_RESET; + pps->powerdown_on_reset = intel_de_read(display, + PP_CONTROL(display, 0)) & PANEL_POWER_RESET; - val = intel_de_read(dev_priv, PP_ON_DELAYS(dev_priv, 0)); + val = intel_de_read(display, PP_ON_DELAYS(display, 0)); pps->port = REG_FIELD_GET(PANEL_PORT_SELECT_MASK, val); pps->delays.power_up = REG_FIELD_GET(PANEL_POWER_UP_DELAY_MASK, val); pps->delays.backlight_on = REG_FIELD_GET(PANEL_LIGHT_ON_DELAY_MASK, val); - val = intel_de_read(dev_priv, PP_OFF_DELAYS(dev_priv, 0)); + val = intel_de_read(display, PP_OFF_DELAYS(display, 0)); pps->delays.power_down = REG_FIELD_GET(PANEL_POWER_DOWN_DELAY_MASK, val); pps->delays.backlight_off = REG_FIELD_GET(PANEL_LIGHT_OFF_DELAY_MASK, val); - val = intel_de_read(dev_priv, PP_DIVISOR(dev_priv, 0)); + val = intel_de_read(display, PP_DIVISOR(display, 0)); pps->divider = REG_FIELD_GET(PP_REFERENCE_DIVIDER_MASK, val); val = REG_FIELD_GET(PANEL_POWER_CYCLE_DELAY_MASK, val); /* @@ -185,12 +184,12 @@ static void intel_lvds_pps_get_hw_state(struct drm_i915_private *dev_priv, /* Convert from 100ms to 100us units */ pps->delays.power_cycle = val * 1000; - if (DISPLAY_VER(dev_priv) < 5 && + if (DISPLAY_VER(display) < 5 && pps->delays.power_up == 0 && pps->delays.backlight_on == 0 && pps->delays.power_down == 0 && pps->delays.backlight_off == 0) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Panel power timings uninitialized, " "setting defaults\n"); /* Set T2 to 40ms and T5 to 200ms in 100 usec units */ @@ -201,7 +200,7 @@ static void intel_lvds_pps_get_hw_state(struct drm_i915_private *dev_priv, pps->delays.backlight_off = 200 * 10; } - drm_dbg(&dev_priv->drm, "LVDS PPS:power_up %d power_down %d power_cycle %d backlight_on %d backlight_off %d " + drm_dbg(display->drm, "LVDS PPS:power_up %d power_down %d power_cycle %d backlight_on %d backlight_off %d " "divider %d port %d powerdown_on_reset %d\n", pps->delays.power_up, pps->delays.power_down, pps->delays.power_cycle, pps->delays.backlight_on, @@ -209,28 +208,28 @@ static void intel_lvds_pps_get_hw_state(struct drm_i915_private *dev_priv, pps->port, pps->powerdown_on_reset); } -static void intel_lvds_pps_init_hw(struct drm_i915_private *dev_priv, +static void intel_lvds_pps_init_hw(struct intel_display *display, struct intel_lvds_pps *pps) { u32 val; - val = intel_de_read(dev_priv, PP_CONTROL(dev_priv, 0)); - drm_WARN_ON(&dev_priv->drm, + val = intel_de_read(display, PP_CONTROL(display, 0)); + drm_WARN_ON(display->drm, (val & PANEL_UNLOCK_MASK) != PANEL_UNLOCK_REGS); if (pps->powerdown_on_reset) val |= PANEL_POWER_RESET; - intel_de_write(dev_priv, PP_CONTROL(dev_priv, 0), val); + intel_de_write(display, PP_CONTROL(display, 0), val); - intel_de_write(dev_priv, PP_ON_DELAYS(dev_priv, 0), + intel_de_write(display, PP_ON_DELAYS(display, 0), REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, pps->port) | REG_FIELD_PREP(PANEL_POWER_UP_DELAY_MASK, pps->delays.power_up) | REG_FIELD_PREP(PANEL_LIGHT_ON_DELAY_MASK, pps->delays.backlight_on)); - intel_de_write(dev_priv, PP_OFF_DELAYS(dev_priv, 0), + intel_de_write(display, PP_OFF_DELAYS(display, 0), REG_FIELD_PREP(PANEL_POWER_DOWN_DELAY_MASK, pps->delays.power_down) | REG_FIELD_PREP(PANEL_LIGHT_OFF_DELAY_MASK, pps->delays.backlight_off)); - intel_de_write(dev_priv, PP_DIVISOR(dev_priv, 0), + intel_de_write(display, PP_DIVISOR(display, 0), REG_FIELD_PREP(PP_REFERENCE_DIVIDER_MASK, pps->divider) | REG_FIELD_PREP(PANEL_POWER_CYCLE_DELAY_MASK, DIV_ROUND_UP(pps->delays.power_cycle, 1000) + 1)); @@ -243,25 +242,24 @@ 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 { assert_pll_disabled(display, pipe); } - intel_lvds_pps_init_hw(i915, &lvds_encoder->init_pps); + intel_lvds_pps_init_hw(display, &lvds_encoder->init_pps); 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 { @@ -296,7 +294,7 @@ static void intel_pre_enable_lvds(struct intel_atomic_state *state, * special lvds dither control bit on pch-split platforms, dithering is * only controlled through the TRANSCONF reg. */ - if (DISPLAY_VER(i915) == 4) { + if (DISPLAY_VER(display) == 4) { /* * Bspec wording suggests that LVDS port dithering only exists * for 18bpp panels. @@ -312,7 +310,7 @@ static void intel_pre_enable_lvds(struct intel_atomic_state *state, if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) temp |= LVDS_VSYNC_POLARITY; - intel_de_write(i915, lvds_encoder->reg, temp); + intel_de_write(display, lvds_encoder->reg, temp); } /* @@ -323,16 +321,16 @@ static void intel_enable_lvds(struct intel_atomic_state *state, const struct intel_crtc_state *crtc_state, const struct drm_connector_state *conn_state) { + struct intel_display *display = to_intel_display(encoder); struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - intel_de_rmw(dev_priv, lvds_encoder->reg, 0, LVDS_PORT_EN); + intel_de_rmw(display, lvds_encoder->reg, 0, LVDS_PORT_EN); - intel_de_rmw(dev_priv, PP_CONTROL(dev_priv, 0), 0, PANEL_POWER_ON); - intel_de_posting_read(dev_priv, lvds_encoder->reg); + intel_de_rmw(display, PP_CONTROL(display, 0), 0, PANEL_POWER_ON); + intel_de_posting_read(display, lvds_encoder->reg); - if (intel_de_wait_for_set(dev_priv, PP_STATUS(dev_priv, 0), PP_ON, 5000)) - drm_err(&dev_priv->drm, + if (intel_de_wait_for_set(display, PP_STATUS(display, 0), PP_ON, 5000)) + drm_err(display->drm, "timed out waiting for panel to power on\n"); intel_backlight_enable(crtc_state, conn_state); @@ -343,16 +341,16 @@ static void intel_disable_lvds(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 intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - intel_de_rmw(dev_priv, PP_CONTROL(dev_priv, 0), PANEL_POWER_ON, 0); - if (intel_de_wait_for_clear(dev_priv, PP_STATUS(dev_priv, 0), PP_ON, 1000)) - drm_err(&dev_priv->drm, + intel_de_rmw(display, PP_CONTROL(display, 0), PANEL_POWER_ON, 0); + if (intel_de_wait_for_clear(display, PP_STATUS(display, 0), PP_ON, 1000)) + drm_err(display->drm, "timed out waiting for panel to power off\n"); - intel_de_rmw(dev_priv, lvds_encoder->reg, LVDS_PORT_EN, 0); - intel_de_posting_read(dev_priv, lvds_encoder->reg); + intel_de_rmw(display, lvds_encoder->reg, LVDS_PORT_EN, 0); + intel_de_posting_read(display, lvds_encoder->reg); } static void gmch_disable_lvds(struct intel_atomic_state *state, @@ -384,10 +382,10 @@ static void pch_post_disable_lvds(struct intel_atomic_state *state, static void intel_lvds_shutdown(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - if (intel_de_wait_for_clear(dev_priv, PP_STATUS(dev_priv, 0), PP_CYCLE_DELAY_ACTIVE, 5000)) - drm_err(&dev_priv->drm, + if (intel_de_wait_for_clear(display, PP_STATUS(display, 0), PP_CYCLE_DELAY_ACTIVE, 5000)) + drm_err(display->drm, "timed out waiting for panel power cycle delay\n"); } @@ -420,7 +418,7 @@ static int intel_lvds_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); 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; @@ -429,12 +427,12 @@ static int intel_lvds_compute_config(struct intel_encoder *encoder, int ret; /* Should never happen!! */ - if (DISPLAY_VER(i915) < 4 && crtc->pipe == 0) { - drm_err(&i915->drm, "Can't support LVDS on pipe A\n"); + if (DISPLAY_VER(display) < 4 && crtc->pipe == 0) { + drm_err(display->drm, "Can't support LVDS on pipe A\n"); 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; @@ -447,7 +445,7 @@ static int intel_lvds_compute_config(struct intel_encoder *encoder, /* TODO: Check crtc_state->max_link_bpp_x16 instead of bw_constrained */ if (lvds_bpp != crtc_state->pipe_bpp && !crtc_state->bw_constrained) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "forcing display bpp (was %d) to LVDS (%d)\n", crtc_state->pipe_bpp, lvds_bpp); crtc_state->pipe_bpp = lvds_bpp; @@ -775,11 +773,11 @@ static const struct dmi_system_id intel_dual_link_lvds[] = { { } /* terminating entry */ }; -struct intel_encoder *intel_get_lvds_encoder(struct drm_i915_private *i915) +struct intel_encoder *intel_get_lvds_encoder(struct intel_display *display) { struct intel_encoder *encoder; - for_each_intel_encoder(&i915->drm, encoder) { + for_each_intel_encoder(display->drm, encoder) { if (encoder->type == INTEL_OUTPUT_LVDS) return encoder; } @@ -787,24 +785,24 @@ struct intel_encoder *intel_get_lvds_encoder(struct drm_i915_private *i915) return NULL; } -bool intel_is_dual_link_lvds(struct drm_i915_private *i915) +bool intel_is_dual_link_lvds(struct intel_display *display) { - struct intel_encoder *encoder = intel_get_lvds_encoder(i915); + struct intel_encoder *encoder = intel_get_lvds_encoder(display); return encoder && to_lvds_encoder(encoder)->is_dual_link; } static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder) { - struct drm_i915_private *i915 = to_i915(lvds_encoder->base.base.dev); + struct intel_display *display = to_intel_display(&lvds_encoder->base); struct intel_connector *connector = lvds_encoder->attached_connector; const struct drm_display_mode *fixed_mode = intel_panel_preferred_fixed_mode(connector); unsigned int val; /* use the module option value if specified */ - if (i915->display.params.lvds_channel_mode > 0) - return i915->display.params.lvds_channel_mode == 2; + if (display->params.lvds_channel_mode > 0) + return display->params.lvds_channel_mode == 2; /* single channel LVDS is limited to 112 MHz */ if (fixed_mode->clock > 112999) @@ -819,8 +817,8 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder) * we need to check "the value to be set" in VBT when LVDS * register is uninitialized. */ - val = intel_de_read(i915, lvds_encoder->reg); - if (HAS_PCH_CPT(i915)) + val = intel_de_read(display, lvds_encoder->reg); + if (HAS_PCH_CPT(display)) val &= ~(LVDS_DETECTED | LVDS_PIPE_SEL_MASK_CPT); else val &= ~(LVDS_DETECTED | LVDS_PIPE_SEL_MASK); @@ -837,14 +835,13 @@ static void intel_lvds_add_properties(struct drm_connector *connector) /** * intel_lvds_init - setup LVDS connectors on this device - * @i915: i915 device + * @display: display device * * Create the connector, register the LVDS DDC bus, and try to figure out what * modes we can display on the LVDS panel (if present). */ -void intel_lvds_init(struct drm_i915_private *i915) +void intel_lvds_init(struct intel_display *display) { - struct intel_display *display = &i915->display; struct intel_lvds_encoder *lvds_encoder; struct intel_connector *connector; const struct drm_edid *drm_edid; @@ -855,25 +852,25 @@ void intel_lvds_init(struct drm_i915_private *i915) /* Skip init on machines we know falsely report LVDS */ if (dmi_check_system(intel_no_lvds)) { - drm_WARN(&i915->drm, !i915->display.vbt.int_lvds_support, + drm_WARN(display->drm, !display->vbt.int_lvds_support, "Useless DMI match. Internal LVDS support disabled by VBT\n"); return; } - if (!i915->display.vbt.int_lvds_support) { - drm_dbg_kms(&i915->drm, + if (!display->vbt.int_lvds_support) { + drm_dbg_kms(display->drm, "Internal LVDS support disabled by VBT\n"); return; } - if (HAS_PCH_SPLIT(i915)) + if (HAS_PCH_SPLIT(display)) lvds_reg = PCH_LVDS; else lvds_reg = LVDS; - lvds = intel_de_read(i915, lvds_reg); + lvds = intel_de_read(display, lvds_reg); - if (HAS_PCH_SPLIT(i915)) { + if (HAS_PCH_SPLIT(display)) { if ((lvds & LVDS_DETECTED) == 0) return; } @@ -881,11 +878,11 @@ void intel_lvds_init(struct drm_i915_private *i915) ddc_pin = GMBUS_PIN_PANEL; if (!intel_bios_is_lvds_present(display, &ddc_pin)) { if ((lvds & LVDS_PORT_EN) == 0) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "LVDS is not present in VBT\n"); return; } - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "LVDS is not present in VBT, but enabled anyway\n"); } @@ -902,18 +899,18 @@ void intel_lvds_init(struct drm_i915_private *i915) lvds_encoder->attached_connector = connector; encoder = &lvds_encoder->base; - drm_connector_init_with_ddc(&i915->drm, &connector->base, + drm_connector_init_with_ddc(display->drm, &connector->base, &intel_lvds_connector_funcs, DRM_MODE_CONNECTOR_LVDS, intel_gmbus_get_adapter(display, ddc_pin)); - drm_encoder_init(&i915->drm, &encoder->base, &intel_lvds_enc_funcs, + drm_encoder_init(display->drm, &encoder->base, &intel_lvds_enc_funcs, DRM_MODE_ENCODER_LVDS, "LVDS"); 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 { @@ -931,7 +928,7 @@ void intel_lvds_init(struct drm_i915_private *i915) encoder->power_domain = POWER_DOMAIN_PORT_OTHER; encoder->port = PORT_NONE; encoder->cloneable = 0; - if (DISPLAY_VER(i915) < 4) + if (DISPLAY_VER(display) < 4) encoder->pipe_mask = BIT(PIPE_B); else encoder->pipe_mask = ~0; @@ -943,7 +940,7 @@ void intel_lvds_init(struct drm_i915_private *i915) intel_lvds_add_properties(&connector->base); - intel_lvds_pps_get_hw_state(i915, &lvds_encoder->init_pps); + intel_lvds_pps_get_hw_state(display, &lvds_encoder->init_pps); lvds_encoder->init_lvds_val = lvds; /* @@ -958,7 +955,7 @@ void intel_lvds_init(struct drm_i915_private *i915) * Attempt to get the fixed panel mode from DDC. Assume that the * preferred mode is the right one. */ - mutex_lock(&i915->drm.mode_config.mutex); + mutex_lock(&display->drm->mode_config.mutex); if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC) drm_edid = drm_edid_read_switcheroo(&connector->base, connector->base.ddc); else @@ -991,7 +988,7 @@ void intel_lvds_init(struct drm_i915_private *i915) if (!intel_panel_preferred_fixed_mode(connector)) intel_panel_add_encoder_fixed_mode(connector, encoder); - mutex_unlock(&i915->drm.mode_config.mutex); + mutex_unlock(&display->drm->mode_config.mutex); /* If we still don't have a mode after all that, give up. */ if (!intel_panel_preferred_fixed_mode(connector)) @@ -1002,7 +999,7 @@ void intel_lvds_init(struct drm_i915_private *i915) intel_backlight_setup(connector, INVALID_PIPE); lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder); - drm_dbg_kms(&i915->drm, "detected %s-link lvds configuration\n", + drm_dbg_kms(display->drm, "detected %s-link lvds configuration\n", lvds_encoder->is_dual_link ? "dual" : "single"); lvds_encoder->a3_power = lvds & LVDS_A3_POWER_MASK; @@ -1010,7 +1007,7 @@ void intel_lvds_init(struct drm_i915_private *i915) return; failed: - drm_dbg_kms(&i915->drm, "No LVDS modes found, disabling.\n"); + drm_dbg_kms(display->drm, "No LVDS modes found, disabling.\n"); drm_connector_cleanup(&connector->base); drm_encoder_cleanup(&encoder->base); kfree(lvds_encoder); diff --git a/drivers/gpu/drm/i915/display/intel_lvds.h b/drivers/gpu/drm/i915/display/intel_lvds.h index 7ad5fa9c0434..a6db1706a97c 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.h +++ b/drivers/gpu/drm/i915/display/intel_lvds.h @@ -11,28 +11,28 @@ #include "i915_reg_defs.h" enum pipe; -struct drm_i915_private; +struct intel_display; #ifdef I915 -bool intel_lvds_port_enabled(struct drm_i915_private *dev_priv, +bool intel_lvds_port_enabled(struct intel_display *display, i915_reg_t lvds_reg, enum pipe *pipe); -void intel_lvds_init(struct drm_i915_private *dev_priv); -struct intel_encoder *intel_get_lvds_encoder(struct drm_i915_private *dev_priv); -bool intel_is_dual_link_lvds(struct drm_i915_private *dev_priv); +void intel_lvds_init(struct intel_display *display); +struct intel_encoder *intel_get_lvds_encoder(struct intel_display *display); +bool intel_is_dual_link_lvds(struct intel_display *display); #else -static inline bool intel_lvds_port_enabled(struct drm_i915_private *dev_priv, +static inline bool intel_lvds_port_enabled(struct intel_display *display, i915_reg_t lvds_reg, enum pipe *pipe) { return false; } -static inline void intel_lvds_init(struct drm_i915_private *dev_priv) +static inline void intel_lvds_init(struct intel_display *display) { } -static inline struct intel_encoder *intel_get_lvds_encoder(struct drm_i915_private *dev_priv) +static inline struct intel_encoder *intel_get_lvds_encoder(struct intel_display *display) { return NULL; } -static inline bool intel_is_dual_link_lvds(struct drm_i915_private *dev_priv) +static inline bool intel_is_dual_link_lvds(struct intel_display *display) { return false; } diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 312b21b1ab59..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; } @@ -155,9 +155,8 @@ static void reset_crtc_encoder_state(struct intel_crtc *crtc) static void intel_crtc_disable_noatomic_complete(struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *i915 = to_i915(crtc->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_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); enum pipe pipe = crtc->pipe; @@ -169,7 +168,7 @@ static void intel_crtc_disable_noatomic_complete(struct intel_crtc *crtc) reset_crtc_encoder_state(crtc); intel_fbc_disable(crtc); - intel_update_watermarks(i915); + intel_update_watermarks(display); intel_display_power_put_all_in_set(display, &crtc->enabled_power_domains); @@ -184,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); @@ -215,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; @@ -234,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); @@ -260,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 = @@ -320,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; @@ -333,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); @@ -348,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, @@ -367,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; @@ -387,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); @@ -424,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; @@ -467,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; @@ -475,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); @@ -516,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; @@ -531,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) @@ -544,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); @@ -554,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 @@ -566,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; @@ -575,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 @@ -592,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; @@ -600,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); @@ -617,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); @@ -651,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; @@ -676,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); @@ -690,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); @@ -716,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; @@ -743,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; @@ -766,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), @@ -775,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; @@ -809,37 +803,37 @@ 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; - if (crtc_state->hw.active) { - /* - * The initial mode needs to be set in order to keep - * the atomic core happy. It wants a valid mode if the - * crtc's enabled, so we do the above call. - * - * But we don't set all the derived state fully, hence - * set a flag to indicate that a full recalculation is - * needed on the next commit. - */ - crtc_state->inherited = true; + /* + * The initial mode needs to be set in order to keep + * the atomic core happy. It wants a valid mode if the + * crtc's enabled, so we do the above call. + * + * But we don't set all the derived state fully, hence + * set a flag to indicate that a full recalculation is + * needed on the next commit. + */ + crtc_state->inherited = true; + if (crtc_state->hw.active) { intel_crtc_update_active_timings(crtc_state, crtc_state->vrr.enable); 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); @@ -855,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]); @@ -874,7 +868,7 @@ static void intel_modeset_readout_hw_state(struct drm_i915_private *i915) /* TODO move here (or even earlier?) on all platforms */ if (DISPLAY_VER(display) >= 9) - intel_wm_get_hw_state(i915); + intel_wm_get_hw_state(display); intel_bw_update_hw_state(display); intel_cdclk_update_hw_state(display); @@ -883,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) @@ -905,49 +899,51 @@ 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(i915); + intel_pch_sanitize(display); intel_cmtg_sanitize(display); @@ -955,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); @@ -969,35 +965,35 @@ 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); /* TODO move earlier on all platforms */ if (DISPLAY_VER(display) < 9) - intel_wm_get_hw_state(i915); - intel_wm_sanitize(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 99f6d6f53fa7..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" @@ -20,28 +21,27 @@ #include "intel_pps.h" #include "intel_sdvo.h" -bool intel_has_pch_trancoder(struct drm_i915_private *i915, +bool intel_has_pch_trancoder(struct intel_display *display, enum pipe pch_transcoder) { - 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; } -static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, +static void assert_pch_dp_disabled(struct intel_display *display, enum pipe pipe, enum port port, i915_reg_t dp_reg) { - struct intel_display *display = &dev_priv->display; enum pipe port_pipe; bool state; @@ -52,16 +52,15 @@ static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, 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)); } -static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, +static void assert_pch_hdmi_disabled(struct intel_display *display, enum pipe pipe, enum port port, i915_reg_t hdmi_reg) { - struct intel_display *display = &dev_priv->display; enum pipe port_pipe; bool state; @@ -72,20 +71,19 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, 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)); } -static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, +static void assert_pch_ports_disabled(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; enum pipe port_pipe; - assert_pch_dp_disabled(dev_priv, pipe, PORT_B, PCH_DP_B); - assert_pch_dp_disabled(dev_priv, pipe, PORT_C, PCH_DP_C); - assert_pch_dp_disabled(dev_priv, pipe, PORT_D, PCH_DP_D); + assert_pch_dp_disabled(display, pipe, PORT_B, PCH_DP_B); + assert_pch_dp_disabled(display, pipe, PORT_C, PCH_DP_C); + assert_pch_dp_disabled(display, pipe, PORT_D, PCH_DP_D); INTEL_DISPLAY_STATE_WARN(display, intel_crt_port_enabled(display, PCH_ADPA, &port_pipe) && port_pipe == pipe, @@ -93,20 +91,19 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, pipe_name(pipe)); INTEL_DISPLAY_STATE_WARN(display, - intel_lvds_port_enabled(dev_priv, PCH_LVDS, &port_pipe) && port_pipe == pipe, + intel_lvds_port_enabled(display, PCH_LVDS, &port_pipe) && port_pipe == pipe, "PCH LVDS enabled on transcoder %c, should be disabled\n", pipe_name(pipe)); /* PCH SDVOB multiplex with HDMIB */ - assert_pch_hdmi_disabled(dev_priv, pipe, PORT_B, PCH_HDMIB); - assert_pch_hdmi_disabled(dev_priv, pipe, PORT_C, PCH_HDMIC); - assert_pch_hdmi_disabled(dev_priv, pipe, PORT_D, PCH_HDMID); + assert_pch_hdmi_disabled(display, pipe, PORT_B, PCH_HDMIB); + assert_pch_hdmi_disabled(display, pipe, PORT_C, PCH_HDMIC); + assert_pch_hdmi_disabled(display, pipe, PORT_D, PCH_HDMID); } -static void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv, +static void assert_pch_transcoder_disabled(struct intel_display *display, enum pipe pipe) { - struct intel_display *display = &dev_priv->display; u32 val; bool enabled; @@ -117,45 +114,45 @@ static void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv, pipe_name(pipe)); } -static void ibx_sanitize_pch_hdmi_port(struct drm_i915_private *dev_priv, +static void ibx_sanitize_pch_hdmi_port(struct intel_display *display, enum port port, i915_reg_t hdmi_reg) { - u32 val = intel_de_read(dev_priv, hdmi_reg); + u32 val = intel_de_read(display, hdmi_reg); if (val & SDVO_ENABLE || (val & SDVO_PIPE_SEL_MASK) == SDVO_PIPE_SEL(PIPE_A)) return; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Sanitizing transcoder select for HDMI %c\n", port_name(port)); val &= ~SDVO_PIPE_SEL_MASK; val |= SDVO_PIPE_SEL(PIPE_A); - intel_de_write(dev_priv, hdmi_reg, val); + intel_de_write(display, hdmi_reg, val); } -static void ibx_sanitize_pch_dp_port(struct drm_i915_private *dev_priv, +static void ibx_sanitize_pch_dp_port(struct intel_display *display, enum port port, i915_reg_t dp_reg) { - u32 val = intel_de_read(dev_priv, dp_reg); + u32 val = intel_de_read(display, dp_reg); if (val & DP_PORT_EN || (val & DP_PIPE_SEL_MASK) == DP_PIPE_SEL(PIPE_A)) return; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Sanitizing transcoder select for DP %c\n", port_name(port)); val &= ~DP_PIPE_SEL_MASK; val |= DP_PIPE_SEL(PIPE_A); - intel_de_write(dev_priv, dp_reg, val); + intel_de_write(display, dp_reg, val); } -static void ibx_sanitize_pch_ports(struct drm_i915_private *dev_priv) +static void ibx_sanitize_pch_ports(struct intel_display *display) { /* * The BIOS may select transcoder B on some of the PCH @@ -168,14 +165,14 @@ static void ibx_sanitize_pch_ports(struct drm_i915_private *dev_priv) * (see. intel_dp_link_down(), intel_disable_hdmi(), * intel_disable_sdvo()). */ - ibx_sanitize_pch_dp_port(dev_priv, PORT_B, PCH_DP_B); - ibx_sanitize_pch_dp_port(dev_priv, PORT_C, PCH_DP_C); - ibx_sanitize_pch_dp_port(dev_priv, PORT_D, PCH_DP_D); + ibx_sanitize_pch_dp_port(display, PORT_B, PCH_DP_B); + ibx_sanitize_pch_dp_port(display, PORT_C, PCH_DP_C); + ibx_sanitize_pch_dp_port(display, PORT_D, PCH_DP_D); /* PCH SDVOB multiplex with HDMIB */ - ibx_sanitize_pch_hdmi_port(dev_priv, PORT_B, PCH_HDMIB); - ibx_sanitize_pch_hdmi_port(dev_priv, PORT_C, PCH_HDMIC); - ibx_sanitize_pch_hdmi_port(dev_priv, PORT_D, PCH_HDMID); + ibx_sanitize_pch_hdmi_port(display, PORT_B, PCH_HDMIB); + ibx_sanitize_pch_hdmi_port(display, PORT_C, PCH_HDMIC); + ibx_sanitize_pch_hdmi_port(display, PORT_D, PCH_HDMID); } static void intel_pch_transcoder_set_m1_n1(struct intel_crtc *crtc, @@ -225,32 +222,30 @@ void intel_pch_transcoder_get_m2_n2(struct intel_crtc *crtc, static void ilk_pch_transcoder_set_timings(const struct intel_crtc_state *crtc_state, enum pipe pch_transcoder) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; - intel_de_write(dev_priv, PCH_TRANS_HTOTAL(pch_transcoder), - intel_de_read(dev_priv, TRANS_HTOTAL(dev_priv, cpu_transcoder))); - intel_de_write(dev_priv, PCH_TRANS_HBLANK(pch_transcoder), - intel_de_read(dev_priv, TRANS_HBLANK(dev_priv, cpu_transcoder))); - intel_de_write(dev_priv, PCH_TRANS_HSYNC(pch_transcoder), - intel_de_read(dev_priv, TRANS_HSYNC(dev_priv, cpu_transcoder))); - - intel_de_write(dev_priv, PCH_TRANS_VTOTAL(pch_transcoder), - intel_de_read(dev_priv, TRANS_VTOTAL(dev_priv, cpu_transcoder))); - intel_de_write(dev_priv, PCH_TRANS_VBLANK(pch_transcoder), - intel_de_read(dev_priv, TRANS_VBLANK(dev_priv, cpu_transcoder))); - intel_de_write(dev_priv, PCH_TRANS_VSYNC(pch_transcoder), - intel_de_read(dev_priv, TRANS_VSYNC(dev_priv, cpu_transcoder))); - intel_de_write(dev_priv, PCH_TRANS_VSYNCSHIFT(pch_transcoder), - intel_de_read(dev_priv, TRANS_VSYNCSHIFT(dev_priv, cpu_transcoder))); + intel_de_write(display, PCH_TRANS_HTOTAL(pch_transcoder), + intel_de_read(display, TRANS_HTOTAL(display, cpu_transcoder))); + intel_de_write(display, PCH_TRANS_HBLANK(pch_transcoder), + intel_de_read(display, TRANS_HBLANK(display, cpu_transcoder))); + intel_de_write(display, PCH_TRANS_HSYNC(pch_transcoder), + intel_de_read(display, TRANS_HSYNC(display, cpu_transcoder))); + + intel_de_write(display, PCH_TRANS_VTOTAL(pch_transcoder), + intel_de_read(display, TRANS_VTOTAL(display, cpu_transcoder))); + intel_de_write(display, PCH_TRANS_VBLANK(pch_transcoder), + intel_de_read(display, TRANS_VBLANK(display, cpu_transcoder))); + intel_de_write(display, PCH_TRANS_VSYNC(pch_transcoder), + intel_de_read(display, TRANS_VSYNC(display, cpu_transcoder))); + intel_de_write(display, PCH_TRANS_VSYNCSHIFT(pch_transcoder), + intel_de_read(display, TRANS_VSYNCSHIFT(display, cpu_transcoder))); } 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 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 val, pipeconf_val; @@ -262,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); /* @@ -280,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); @@ -299,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 @@ -317,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; @@ -326,18 +320,18 @@ static void ilk_disable_pch_transcoder(struct intel_crtc *crtc) assert_fdi_rx_disabled(display, pipe); /* Ports must be off as well */ - assert_pch_ports_disabled(dev_priv, pipe); + assert_pch_ports_disabled(display, pipe); reg = PCH_TRANSCONF(pipe); - intel_de_rmw(dev_priv, reg, TRANS_ENABLE, 0); + intel_de_rmw(display, reg, TRANS_ENABLE, 0); /* wait for PCH transcoder off, transcoder state */ - if (intel_de_wait_for_clear(dev_priv, reg, TRANS_STATE_ENABLE, 50)) - drm_err(&dev_priv->drm, "failed to disable transcoder %c\n", + if (intel_de_wait_for_clear(display, reg, TRANS_STATE_ENABLE, 50)) + 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(dev_priv, TRANS_CHICKEN2(pipe), + intel_de_rmw(display, TRANS_CHICKEN2(pipe), TRANS_CHICKEN2_TIMING_OVERRIDE, 0); } @@ -366,14 +360,13 @@ void ilk_pch_pre_enable(struct intel_atomic_state *state, void ilk_pch_enable(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(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); enum pipe pipe = crtc->pipe; u32 temp; - assert_pch_transcoder_disabled(dev_priv, pipe); + assert_pch_transcoder_disabled(display, pipe); /* For PCH output, training FDI link */ intel_fdi_link_train(crtc, crtc_state); @@ -382,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); @@ -418,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,23 +452,27 @@ void ilk_pch_disable(struct intel_atomic_state *state, void ilk_pch_post_disable(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(crtc); + 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(dev_priv, TRANS_DP_CTL(pipe), + intel_de_rmw(display, TRANS_DP_CTL(pipe), TRANS_DP_OUTPUT_ENABLE | TRANS_DP_PORT_SEL_MASK, TRANS_DP_PORT_SEL_NONE); /* disable DPLL_SEL */ - intel_de_rmw(dev_priv, PCH_DPLL_SEL, + intel_de_rmw(display, PCH_DPLL_SEL, TRANS_DPLL_ENABLE(pipe) | TRANS_DPLLB_SEL(pipe), 0); } ilk_fdi_pll_disable(crtc); + + intel_disable_shared_dpll(old_crtc_state); } static void ilk_pch_clock_get(struct intel_crtc_state *crtc_state) @@ -497,9 +494,8 @@ static void ilk_pch_clock_get(struct intel_crtc_state *crtc_state) 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 intel_display *display = to_intel_display(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; @@ -518,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. @@ -550,8 +546,6 @@ void ilk_pch_get_config(struct intel_crtc_state *crtc_state) static void lpt_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 transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 val, pipeconf_val; @@ -559,49 +553,49 @@ static void lpt_enable_pch_transcoder(const struct intel_crtc_state *crtc_state) assert_fdi_tx_enabled(display, (enum pipe)cpu_transcoder); assert_fdi_rx_enabled(display, PIPE_A); - val = intel_de_read(dev_priv, TRANS_CHICKEN2(PIPE_A)); + val = intel_de_read(display, TRANS_CHICKEN2(PIPE_A)); /* Workaround: set timing override bit. */ val |= TRANS_CHICKEN2_TIMING_OVERRIDE; /* Configure frame start delay to match the CPU */ val &= ~TRANS_CHICKEN2_FRAME_START_DELAY_MASK; val |= TRANS_CHICKEN2_FRAME_START_DELAY(crtc_state->framestart_delay - 1); - intel_de_write(dev_priv, TRANS_CHICKEN2(PIPE_A), val); + intel_de_write(display, TRANS_CHICKEN2(PIPE_A), val); val = TRANS_ENABLE; - pipeconf_val = intel_de_read(dev_priv, - TRANSCONF(dev_priv, cpu_transcoder)); + pipeconf_val = intel_de_read(display, + TRANSCONF(display, cpu_transcoder)); if ((pipeconf_val & TRANSCONF_INTERLACE_MASK_HSW) == TRANSCONF_INTERLACE_IF_ID_ILK) val |= TRANS_INTERLACE_INTERLACED; else val |= TRANS_INTERLACE_PROGRESSIVE; - intel_de_write(dev_priv, LPT_TRANSCONF, val); - if (intel_de_wait_for_set(dev_priv, LPT_TRANSCONF, + intel_de_write(display, LPT_TRANSCONF, val); + if (intel_de_wait_for_set(display, LPT_TRANSCONF, TRANS_STATE_ENABLE, 100)) - drm_err(&dev_priv->drm, "Failed to enable PCH transcoder\n"); + drm_err(display->drm, "Failed to enable PCH transcoder\n"); } -static void lpt_disable_pch_transcoder(struct drm_i915_private *dev_priv) +static void lpt_disable_pch_transcoder(struct intel_display *display) { - intel_de_rmw(dev_priv, LPT_TRANSCONF, TRANS_ENABLE, 0); + intel_de_rmw(display, LPT_TRANSCONF, TRANS_ENABLE, 0); /* wait for PCH transcoder off, transcoder state */ - if (intel_de_wait_for_clear(dev_priv, LPT_TRANSCONF, + if (intel_de_wait_for_clear(display, LPT_TRANSCONF, TRANS_STATE_ENABLE, 50)) - drm_err(&dev_priv->drm, "Failed to disable PCH transcoder\n"); + drm_err(display->drm, "Failed to disable PCH transcoder\n"); /* Workaround: clear timing override bit. */ - intel_de_rmw(dev_priv, TRANS_CHICKEN2(PIPE_A), TRANS_CHICKEN2_TIMING_OVERRIDE, 0); + intel_de_rmw(display, TRANS_CHICKEN2(PIPE_A), TRANS_CHICKEN2_TIMING_OVERRIDE, 0); } void lpt_pch_enable(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(crtc); const struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); - assert_pch_transcoder_disabled(dev_priv, PIPE_A); + assert_pch_transcoder_disabled(display, PIPE_A); lpt_program_iclkip(crtc_state); @@ -614,36 +608,36 @@ void lpt_pch_enable(struct intel_atomic_state *state, void lpt_pch_disable(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(crtc); - lpt_disable_pch_transcoder(dev_priv); + lpt_disable_pch_transcoder(display); - lpt_disable_iclkip(dev_priv); + lpt_disable_iclkip(display); } void lpt_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); u32 tmp; - if ((intel_de_read(dev_priv, LPT_TRANSCONF) & TRANS_ENABLE) == 0) + if ((intel_de_read(display, LPT_TRANSCONF) & TRANS_ENABLE) == 0) return; crtc_state->has_pch_encoder = true; - tmp = intel_de_read(dev_priv, FDI_RX_CTL(PIPE_A)); + tmp = intel_de_read(display, FDI_RX_CTL(PIPE_A)); crtc_state->fdi_lanes = ((FDI_DP_PORT_WIDTH_MASK & tmp) >> FDI_DP_PORT_WIDTH_SHIFT) + 1; intel_cpu_transcoder_get_m1_n1(crtc, crtc_state->cpu_transcoder, &crtc_state->fdi_m_n); - crtc_state->hw.adjusted_mode.crtc_clock = lpt_get_iclkip(dev_priv); + crtc_state->hw.adjusted_mode.crtc_clock = lpt_get_iclkip(display); } -void intel_pch_sanitize(struct drm_i915_private *i915) +void intel_pch_sanitize(struct intel_display *display) { - if (HAS_PCH_IBX(i915)) - ibx_sanitize_pch_ports(i915); + if (HAS_PCH_IBX(display)) + ibx_sanitize_pch_ports(display); } diff --git a/drivers/gpu/drm/i915/display/intel_pch_display.h b/drivers/gpu/drm/i915/display/intel_pch_display.h index 35f8288af3d1..cd6b3ed05887 100644 --- a/drivers/gpu/drm/i915/display/intel_pch_display.h +++ b/drivers/gpu/drm/i915/display/intel_pch_display.h @@ -9,14 +9,14 @@ #include <linux/types.h> enum pipe; -struct drm_i915_private; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; +struct intel_display; struct intel_link_m_n; #ifdef I915 -bool intel_has_pch_trancoder(struct drm_i915_private *i915, +bool intel_has_pch_trancoder(struct intel_display *display, enum pipe pch_transcoder); enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc); @@ -41,9 +41,9 @@ void intel_pch_transcoder_get_m1_n1(struct intel_crtc *crtc, void intel_pch_transcoder_get_m2_n2(struct intel_crtc *crtc, struct intel_link_m_n *m_n); -void intel_pch_sanitize(struct drm_i915_private *i915); +void intel_pch_sanitize(struct intel_display *display); #else -static inline bool intel_has_pch_trancoder(struct drm_i915_private *i915, +static inline bool intel_has_pch_trancoder(struct intel_display *display, enum pipe pch_transcoder) { return false; @@ -90,7 +90,7 @@ static inline void intel_pch_transcoder_get_m2_n2(struct intel_crtc *crtc, struct intel_link_m_n *m_n) { } -static inline void intel_pch_sanitize(struct drm_i915_private *i915) +static inline void intel_pch_sanitize(struct intel_display *display) { } #endif diff --git a/drivers/gpu/drm/i915/display/intel_pch_refclk.c b/drivers/gpu/drm/i915/display/intel_pch_refclk.c index 33467de3d115..693b90e3dfc3 100644 --- a/drivers/gpu/drm/i915/display/intel_pch_refclk.c +++ b/drivers/gpu/drm/i915/display/intel_pch_refclk.c @@ -11,27 +11,28 @@ #include "intel_pch_refclk.h" #include "intel_sbi.h" -static void lpt_fdi_reset_mphy(struct drm_i915_private *dev_priv) +static void lpt_fdi_reset_mphy(struct intel_display *display) { - intel_de_rmw(dev_priv, SOUTH_CHICKEN2, 0, FDI_MPHY_IOSFSB_RESET_CTL); + intel_de_rmw(display, SOUTH_CHICKEN2, 0, FDI_MPHY_IOSFSB_RESET_CTL); - if (wait_for_us(intel_de_read(dev_priv, SOUTH_CHICKEN2) & + if (wait_for_us(intel_de_read(display, SOUTH_CHICKEN2) & FDI_MPHY_IOSFSB_RESET_STATUS, 100)) - drm_err(&dev_priv->drm, "FDI mPHY reset assert timeout\n"); + drm_err(display->drm, "FDI mPHY reset assert timeout\n"); - intel_de_rmw(dev_priv, SOUTH_CHICKEN2, FDI_MPHY_IOSFSB_RESET_CTL, 0); + intel_de_rmw(display, SOUTH_CHICKEN2, FDI_MPHY_IOSFSB_RESET_CTL, 0); - if (wait_for_us((intel_de_read(dev_priv, SOUTH_CHICKEN2) & + if (wait_for_us((intel_de_read(display, SOUTH_CHICKEN2) & FDI_MPHY_IOSFSB_RESET_STATUS) == 0, 100)) - drm_err(&dev_priv->drm, "FDI mPHY reset de-assert timeout\n"); + drm_err(display->drm, "FDI mPHY reset de-assert timeout\n"); } /* WaMPhyProgramming:hsw */ -static void lpt_fdi_program_mphy(struct drm_i915_private *dev_priv) +static void lpt_fdi_program_mphy(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 tmp; - lpt_fdi_reset_mphy(dev_priv); + lpt_fdi_reset_mphy(display); tmp = intel_sbi_read(dev_priv, 0x8008, SBI_MPHY); tmp &= ~(0xFF << 24); @@ -103,11 +104,12 @@ static void lpt_fdi_program_mphy(struct drm_i915_private *dev_priv) intel_sbi_write(dev_priv, 0x21EC, tmp, SBI_MPHY); } -void lpt_disable_iclkip(struct drm_i915_private *dev_priv) +void lpt_disable_iclkip(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 temp; - intel_de_write(dev_priv, PIXCLK_GATE, PIXCLK_GATE_GATE); + intel_de_write(display, PIXCLK_GATE, PIXCLK_GATE_GATE); intel_sbi_lock(dev_priv); @@ -175,24 +177,25 @@ int lpt_iclkip(const struct intel_crtc_state *crtc_state) /* Program iCLKIP clock to the desired frequency */ void lpt_program_iclkip(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); int clock = crtc_state->hw.adjusted_mode.crtc_clock; struct iclkip_params p; u32 temp; - lpt_disable_iclkip(dev_priv); + lpt_disable_iclkip(display); lpt_compute_iclkip(&p, clock); - drm_WARN_ON(&dev_priv->drm, lpt_iclkip_freq(&p) != clock); + drm_WARN_ON(display->drm, lpt_iclkip_freq(&p) != clock); /* This should not happen with any sane values */ - drm_WARN_ON(&dev_priv->drm, SBI_SSCDIVINTPHASE_DIVSEL(p.divsel) & + drm_WARN_ON(display->drm, SBI_SSCDIVINTPHASE_DIVSEL(p.divsel) & ~SBI_SSCDIVINTPHASE_DIVSEL_MASK); - drm_WARN_ON(&dev_priv->drm, SBI_SSCDIVINTPHASE_DIR(p.phasedir) & + drm_WARN_ON(display->drm, SBI_SSCDIVINTPHASE_DIR(p.phasedir) & ~SBI_SSCDIVINTPHASE_INCVAL_MASK); - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "iCLKIP clock: found settings for %dKHz refresh rate: auxdiv=%x, divsel=%x, phasedir=%x, phaseinc=%x\n", clock, p.auxdiv, p.divsel, p.phasedir, p.phaseinc); @@ -224,15 +227,16 @@ void lpt_program_iclkip(const struct intel_crtc_state *crtc_state) /* Wait for initialization time */ udelay(24); - intel_de_write(dev_priv, PIXCLK_GATE, PIXCLK_GATE_UNGATE); + intel_de_write(display, PIXCLK_GATE, PIXCLK_GATE_UNGATE); } -int lpt_get_iclkip(struct drm_i915_private *dev_priv) +int lpt_get_iclkip(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); struct iclkip_params p; u32 temp; - if ((intel_de_read(dev_priv, PIXCLK_GATE) & PIXCLK_GATE_UNGATE) == 0) + if ((intel_de_read(display, PIXCLK_GATE) & PIXCLK_GATE_UNGATE) == 0) return 0; iclkip_params_init(&p); @@ -268,15 +272,16 @@ int lpt_get_iclkip(struct drm_i915_private *dev_priv) * - Sequence to enable CLKOUT_DP without spread * - Sequence to enable CLKOUT_DP for FDI usage and configure PCH FDI I/O */ -static void lpt_enable_clkout_dp(struct drm_i915_private *dev_priv, +static void lpt_enable_clkout_dp(struct intel_display *display, bool with_spread, bool with_fdi) { + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 reg, tmp; - if (drm_WARN(&dev_priv->drm, with_fdi && !with_spread, + if (drm_WARN(display->drm, with_fdi && !with_spread, "FDI requires downspread\n")) with_spread = true; - if (drm_WARN(&dev_priv->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; @@ -295,10 +300,10 @@ static void lpt_enable_clkout_dp(struct drm_i915_private *dev_priv, intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK); if (with_fdi) - lpt_fdi_program_mphy(dev_priv); + 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); @@ -307,13 +312,14 @@ static void lpt_enable_clkout_dp(struct drm_i915_private *dev_priv, } /* Sequence to disable CLKOUT_DP */ -void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv) +void lpt_disable_clkout_dp(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 reg, tmp; 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); @@ -364,15 +370,16 @@ static const u16 sscdivintphase[] = { * < 0 slow down the clock, > 0 speed up the clock, 0 == no bend (135MHz) * change in clock period = -(steps / 10) * 5.787 ps */ -static void lpt_bend_clkout_dp(struct drm_i915_private *dev_priv, int steps) +static void lpt_bend_clkout_dp(struct intel_display *display, int steps) { + struct drm_i915_private *dev_priv = to_i915(display->drm); u32 tmp; int idx = BEND_IDX(steps); - if (drm_WARN_ON(&dev_priv->drm, steps % 5 != 0)) + if (drm_WARN_ON(display->drm, steps % 5 != 0)) return; - if (drm_WARN_ON(&dev_priv->drm, idx >= ARRAY_SIZE(sscdivintphase))) + if (drm_WARN_ON(display->drm, idx >= ARRAY_SIZE(sscdivintphase))) return; intel_sbi_lock(dev_priv); @@ -393,10 +400,10 @@ static void lpt_bend_clkout_dp(struct drm_i915_private *dev_priv, int steps) #undef BEND_IDX -static bool spll_uses_pch_ssc(struct drm_i915_private *dev_priv) +static bool spll_uses_pch_ssc(struct intel_display *display) { - u32 fuse_strap = intel_de_read(dev_priv, FUSE_STRAP); - u32 ctl = intel_de_read(dev_priv, SPLL_CTL); + u32 fuse_strap = intel_de_read(display, FUSE_STRAP); + u32 ctl = intel_de_read(display, SPLL_CTL); if ((ctl & SPLL_PLL_ENABLE) == 0) return false; @@ -405,18 +412,17 @@ static bool spll_uses_pch_ssc(struct drm_i915_private *dev_priv) (fuse_strap & HSW_CPU_SSC_ENABLE) == 0) return true; - if (IS_BROADWELL(dev_priv) && + if (display->platform.broadwell && (ctl & SPLL_REF_MASK) == SPLL_REF_PCH_SSC_BDW) return true; return false; } -static bool wrpll_uses_pch_ssc(struct drm_i915_private *dev_priv, - enum intel_dpll_id id) +static bool wrpll_uses_pch_ssc(struct intel_display *display, enum intel_dpll_id id) { - u32 fuse_strap = intel_de_read(dev_priv, FUSE_STRAP); - u32 ctl = intel_de_read(dev_priv, WRPLL_CTL(id)); + u32 fuse_strap = intel_de_read(display, FUSE_STRAP); + u32 ctl = intel_de_read(display, WRPLL_CTL(id)); if ((ctl & WRPLL_PLL_ENABLE) == 0) return false; @@ -424,7 +430,7 @@ static bool wrpll_uses_pch_ssc(struct drm_i915_private *dev_priv, if ((ctl & WRPLL_REF_MASK) == WRPLL_REF_PCH_SSC) return true; - if ((IS_BROADWELL(dev_priv) || IS_HASWELL_ULT(dev_priv)) && + if ((display->platform.broadwell || display->platform.haswell_ult) && (ctl & WRPLL_REF_MASK) == WRPLL_REF_MUXED_SSC_BDW && (fuse_strap & HSW_CPU_SSC_ENABLE) == 0) return true; @@ -432,12 +438,12 @@ static bool wrpll_uses_pch_ssc(struct drm_i915_private *dev_priv, return false; } -static void lpt_init_pch_refclk(struct drm_i915_private *dev_priv) +static void lpt_init_pch_refclk(struct intel_display *display) { struct intel_encoder *encoder; bool has_fdi = false; - for_each_intel_encoder(&dev_priv->drm, encoder) { + for_each_intel_encoder(display->drm, encoder) { switch (encoder->type) { case INTEL_OUTPUT_ANALOG: has_fdi = true; @@ -462,37 +468,36 @@ static void lpt_init_pch_refclk(struct drm_i915_private *dev_priv) * clock hierarchy. That would also allow us to do * clock bending finally. */ - dev_priv->display.dpll.pch_ssc_use = 0; + display->dpll.pch_ssc_use = 0; - if (spll_uses_pch_ssc(dev_priv)) { - drm_dbg_kms(&dev_priv->drm, "SPLL using PCH SSC\n"); - dev_priv->display.dpll.pch_ssc_use |= BIT(DPLL_ID_SPLL); + if (spll_uses_pch_ssc(display)) { + drm_dbg_kms(display->drm, "SPLL using PCH SSC\n"); + display->dpll.pch_ssc_use |= BIT(DPLL_ID_SPLL); } - if (wrpll_uses_pch_ssc(dev_priv, DPLL_ID_WRPLL1)) { - drm_dbg_kms(&dev_priv->drm, "WRPLL1 using PCH SSC\n"); - dev_priv->display.dpll.pch_ssc_use |= BIT(DPLL_ID_WRPLL1); + if (wrpll_uses_pch_ssc(display, DPLL_ID_WRPLL1)) { + drm_dbg_kms(display->drm, "WRPLL1 using PCH SSC\n"); + display->dpll.pch_ssc_use |= BIT(DPLL_ID_WRPLL1); } - if (wrpll_uses_pch_ssc(dev_priv, DPLL_ID_WRPLL2)) { - drm_dbg_kms(&dev_priv->drm, "WRPLL2 using PCH SSC\n"); - dev_priv->display.dpll.pch_ssc_use |= BIT(DPLL_ID_WRPLL2); + if (wrpll_uses_pch_ssc(display, DPLL_ID_WRPLL2)) { + drm_dbg_kms(display->drm, "WRPLL2 using PCH SSC\n"); + display->dpll.pch_ssc_use |= BIT(DPLL_ID_WRPLL2); } - if (dev_priv->display.dpll.pch_ssc_use) + if (display->dpll.pch_ssc_use) return; if (has_fdi) { - lpt_bend_clkout_dp(dev_priv, 0); - lpt_enable_clkout_dp(dev_priv, true, true); + lpt_bend_clkout_dp(display, 0); + lpt_enable_clkout_dp(display, true, true); } else { - lpt_disable_clkout_dp(dev_priv); + lpt_disable_clkout_dp(display); } } -static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) +static void ilk_init_pch_refclk(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; struct intel_encoder *encoder; struct intel_shared_dpll *pll; int i; @@ -521,7 +526,7 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) } } - if (HAS_PCH_IBX(dev_priv)) { + if (HAS_PCH_IBX(display)) { has_ck505 = display->vbt.display_clock_mode; can_ssc = has_ck505; } else { @@ -607,7 +612,7 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) /* SSC must be turned on before enabling the CPU output */ if (intel_panel_use_ssc(display) && can_ssc) { - drm_dbg_kms(&dev_priv->drm, "Using SSC on panel\n"); + drm_dbg_kms(display->drm, "Using SSC on panel\n"); val |= DREF_SSC1_ENABLE; } else { val &= ~DREF_SSC1_ENABLE; @@ -623,7 +628,7 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) /* Enable CPU source on CPU attached eDP */ if (has_cpu_edp) { if (intel_panel_use_ssc(display) && can_ssc) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Using SSC on eDP\n"); val |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; } else { @@ -670,10 +675,10 @@ static void ilk_init_pch_refclk(struct drm_i915_private *dev_priv) /* * Initialize reference clocks when the driver loads */ -void intel_init_pch_refclk(struct drm_i915_private *dev_priv) +void intel_init_pch_refclk(struct intel_display *display) { - if (HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)) - ilk_init_pch_refclk(dev_priv); - else if (HAS_PCH_LPT(dev_priv)) - lpt_init_pch_refclk(dev_priv); + if (HAS_PCH_IBX(display) || HAS_PCH_CPT(display)) + ilk_init_pch_refclk(display); + else if (HAS_PCH_LPT(display)) + lpt_init_pch_refclk(display); } diff --git a/drivers/gpu/drm/i915/display/intel_pch_refclk.h b/drivers/gpu/drm/i915/display/intel_pch_refclk.h index ae3403c0ced8..25cc53c568bc 100644 --- a/drivers/gpu/drm/i915/display/intel_pch_refclk.h +++ b/drivers/gpu/drm/i915/display/intel_pch_refclk.h @@ -8,25 +8,25 @@ #include <linux/types.h> -struct drm_i915_private; struct intel_crtc_state; +struct intel_display; #ifdef I915 void lpt_program_iclkip(const struct intel_crtc_state *crtc_state); -void lpt_disable_iclkip(struct drm_i915_private *dev_priv); -int lpt_get_iclkip(struct drm_i915_private *dev_priv); +void lpt_disable_iclkip(struct intel_display *display); +int lpt_get_iclkip(struct intel_display *display); int lpt_iclkip(const struct intel_crtc_state *crtc_state); -void intel_init_pch_refclk(struct drm_i915_private *dev_priv); -void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv); +void intel_init_pch_refclk(struct intel_display *display); +void lpt_disable_clkout_dp(struct intel_display *display); #else static inline void lpt_program_iclkip(const struct intel_crtc_state *crtc_state) { } -static inline void lpt_disable_iclkip(struct drm_i915_private *dev_priv) +static inline void lpt_disable_iclkip(struct intel_display *display) { } -static inline int lpt_get_iclkip(struct drm_i915_private *dev_priv) +static inline int lpt_get_iclkip(struct intel_display *display) { return 0; } @@ -34,10 +34,10 @@ static inline int lpt_iclkip(const struct intel_crtc_state *crtc_state) { return 0; } -static inline void intel_init_pch_refclk(struct drm_i915_private *dev_priv) +static inline void intel_init_pch_refclk(struct intel_display *display) { } -static inline void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv) +static inline void lpt_disable_clkout_dp(struct intel_display *display) { } #endif diff --git a/drivers/gpu/drm/i915/display/intel_pipe_crc.c b/drivers/gpu/drm/i915/display/intel_pipe_crc.c index 10e26c3db946..6182f484b5bd 100644 --- a/drivers/gpu/drm/i915/display/intel_pipe_crc.c +++ b/drivers/gpu/drm/i915/display/intel_pipe_crc.c @@ -75,7 +75,7 @@ static int i8xx_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source, return 0; } -static void i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv, +static void i9xx_pipe_crc_auto_source(struct intel_display *display, enum pipe pipe, enum intel_pipe_crc_source *source) { @@ -85,8 +85,8 @@ static void i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv, *source = INTEL_PIPE_CRC_SOURCE_PIPE; - drm_modeset_lock_all(&dev_priv->drm); - for_each_intel_encoder(&dev_priv->drm, encoder) { + drm_modeset_lock_all(display->drm); + for_each_intel_encoder(display->drm, encoder) { if (!encoder->base.crtc) continue; @@ -113,7 +113,7 @@ static void i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv, *source = INTEL_PIPE_CRC_SOURCE_DP_D; break; default: - drm_WARN(&dev_priv->drm, 1, "nonexisting DP port %c\n", + drm_WARN(display->drm, 1, "nonexisting DP port %c\n", port_name(dig_port->base.port)); break; } @@ -122,10 +122,10 @@ static void i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv, break; } } - drm_modeset_unlock_all(&dev_priv->drm); + drm_modeset_unlock_all(display->drm); } -static int vlv_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, +static int vlv_pipe_crc_ctl_reg(struct intel_display *display, enum pipe pipe, enum intel_pipe_crc_source *source, u32 *val) @@ -133,7 +133,7 @@ static int vlv_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, bool need_stable_symbols = false; if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) - i9xx_pipe_crc_auto_source(dev_priv, pipe, source); + i9xx_pipe_crc_auto_source(display, pipe, source); switch (*source) { case INTEL_PIPE_CRC_SOURCE_PIPE: @@ -148,7 +148,7 @@ static int vlv_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, need_stable_symbols = true; break; case INTEL_PIPE_CRC_SOURCE_DP_D: - if (!IS_CHERRYVIEW(dev_priv)) + if (!display->platform.cherryview) return -EINVAL; *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_DP_D_VLV; need_stable_symbols = true; @@ -170,7 +170,7 @@ static int vlv_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, * - DisplayPort scrambling: used for EMI reduction */ if (need_stable_symbols) { - u32 tmp = intel_de_read(dev_priv, PORT_DFT2_G4X(dev_priv)); + u32 tmp = intel_de_read(display, PORT_DFT2_G4X(display)); tmp |= DC_BALANCE_RESET_VLV; switch (pipe) { @@ -186,26 +186,26 @@ static int vlv_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, default: return -EINVAL; } - intel_de_write(dev_priv, PORT_DFT2_G4X(dev_priv), tmp); + intel_de_write(display, PORT_DFT2_G4X(display), tmp); } return 0; } -static int i9xx_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, +static int i9xx_pipe_crc_ctl_reg(struct intel_display *display, enum pipe pipe, enum intel_pipe_crc_source *source, u32 *val) { if (*source == INTEL_PIPE_CRC_SOURCE_AUTO) - i9xx_pipe_crc_auto_source(dev_priv, pipe, source); + i9xx_pipe_crc_auto_source(display, pipe, source); switch (*source) { case INTEL_PIPE_CRC_SOURCE_PIPE: *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_PIPE_I9XX; break; case INTEL_PIPE_CRC_SOURCE_TV: - if (!SUPPORTS_TV(dev_priv)) + if (!SUPPORTS_TV(display)) return -EINVAL; *val = PIPE_CRC_ENABLE | PIPE_CRC_SOURCE_TV_PRE; break; @@ -229,10 +229,10 @@ static int i9xx_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, return 0; } -static void vlv_undo_pipe_scramble_reset(struct drm_i915_private *dev_priv, +static void vlv_undo_pipe_scramble_reset(struct intel_display *display, enum pipe pipe) { - u32 tmp = intel_de_read(dev_priv, PORT_DFT2_G4X(dev_priv)); + u32 tmp = intel_de_read(display, PORT_DFT2_G4X(display)); switch (pipe) { case PIPE_A: @@ -249,7 +249,7 @@ static void vlv_undo_pipe_scramble_reset(struct drm_i915_private *dev_priv, } if (!(tmp & PIPE_SCRAMBLE_RESET_MASK)) tmp &= ~DC_BALANCE_RESET_VLV; - intel_de_write(dev_priv, PORT_DFT2_G4X(dev_priv), tmp); + intel_de_write(display, PORT_DFT2_G4X(display), tmp); } static int ilk_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source, @@ -281,18 +281,18 @@ static int ilk_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source, static void intel_crtc_crc_setup_workarounds(struct intel_crtc *crtc, bool enable) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_crtc_state *pipe_config; struct drm_atomic_state *state; struct drm_modeset_acquire_ctx ctx; int ret; - if (IS_I945GM(dev_priv) || IS_I915GM(dev_priv)) - i915gm_irq_cstate_wa(dev_priv, enable); + if (display->platform.i945gm || display->platform.i915gm) + i915gm_irq_cstate_wa(display, enable); drm_modeset_acquire_init(&ctx, 0); - state = drm_atomic_state_alloc(&dev_priv->drm); + state = drm_atomic_state_alloc(display->drm); if (!state) { ret = -ENOMEM; goto unlock; @@ -311,7 +311,7 @@ retry: pipe_config->uapi.mode_changed = pipe_config->has_psr; pipe_config->crc_enabled = enable; - if (IS_HASWELL(dev_priv) && + if (display->platform.haswell && pipe_config->hw.active && crtc->pipe == PIPE_A && pipe_config->cpu_transcoder == TRANSCODER_EDP) pipe_config->uapi.mode_changed = true; @@ -327,13 +327,13 @@ put_state: drm_atomic_state_put(state); unlock: - drm_WARN(&dev_priv->drm, ret, + drm_WARN(display->drm, ret, "Toggling workaround to %i returns %i\n", enable, ret); drm_modeset_drop_locks(&ctx); drm_modeset_acquire_fini(&ctx); } -static int ivb_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, +static int ivb_pipe_crc_ctl_reg(struct intel_display *display, enum pipe pipe, enum intel_pipe_crc_source *source, u32 *val) @@ -361,7 +361,7 @@ static int ivb_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, return 0; } -static int skl_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, +static int skl_pipe_crc_ctl_reg(struct intel_display *display, enum pipe pipe, enum intel_pipe_crc_source *source, u32 *val) @@ -404,22 +404,22 @@ static int skl_pipe_crc_ctl_reg(struct drm_i915_private *dev_priv, return 0; } -static int get_new_crc_ctl_reg(struct drm_i915_private *dev_priv, +static int get_new_crc_ctl_reg(struct intel_display *display, enum pipe pipe, enum intel_pipe_crc_source *source, u32 *val) { - if (DISPLAY_VER(dev_priv) == 2) + if (DISPLAY_VER(display) == 2) return i8xx_pipe_crc_ctl_reg(source, val); - else if (DISPLAY_VER(dev_priv) < 5) - return i9xx_pipe_crc_ctl_reg(dev_priv, pipe, source, val); - else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - return vlv_pipe_crc_ctl_reg(dev_priv, pipe, source, val); - else if (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv)) + else if (DISPLAY_VER(display) < 5) + return i9xx_pipe_crc_ctl_reg(display, pipe, source, val); + else if (display->platform.valleyview || display->platform.cherryview) + return vlv_pipe_crc_ctl_reg(display, pipe, source, val); + else if (display->platform.ironlake || display->platform.sandybridge) return ilk_pipe_crc_ctl_reg(source, val); - else if (DISPLAY_VER(dev_priv) < 9) - return ivb_pipe_crc_ctl_reg(dev_priv, pipe, source, val); + else if (DISPLAY_VER(display) < 9) + return ivb_pipe_crc_ctl_reg(display, pipe, source, val); else - return skl_pipe_crc_ctl_reg(dev_priv, pipe, source, val); + return skl_pipe_crc_ctl_reg(display, pipe, source, val); } static int @@ -447,7 +447,7 @@ void intel_crtc_crc_init(struct intel_crtc *crtc) spin_lock_init(&pipe_crc->lock); } -static int i8xx_crc_source_valid(struct drm_i915_private *dev_priv, +static int i8xx_crc_source_valid(struct intel_display *display, const enum intel_pipe_crc_source source) { switch (source) { @@ -459,7 +459,7 @@ static int i8xx_crc_source_valid(struct drm_i915_private *dev_priv, } } -static int i9xx_crc_source_valid(struct drm_i915_private *dev_priv, +static int i9xx_crc_source_valid(struct intel_display *display, const enum intel_pipe_crc_source source) { switch (source) { @@ -472,7 +472,7 @@ static int i9xx_crc_source_valid(struct drm_i915_private *dev_priv, } } -static int vlv_crc_source_valid(struct drm_i915_private *dev_priv, +static int vlv_crc_source_valid(struct intel_display *display, const enum intel_pipe_crc_source source) { switch (source) { @@ -487,7 +487,7 @@ static int vlv_crc_source_valid(struct drm_i915_private *dev_priv, } } -static int ilk_crc_source_valid(struct drm_i915_private *dev_priv, +static int ilk_crc_source_valid(struct intel_display *display, const enum intel_pipe_crc_source source) { switch (source) { @@ -501,7 +501,7 @@ static int ilk_crc_source_valid(struct drm_i915_private *dev_priv, } } -static int ivb_crc_source_valid(struct drm_i915_private *dev_priv, +static int ivb_crc_source_valid(struct intel_display *display, const enum intel_pipe_crc_source source) { switch (source) { @@ -515,7 +515,7 @@ static int ivb_crc_source_valid(struct drm_i915_private *dev_priv, } } -static int skl_crc_source_valid(struct drm_i915_private *dev_priv, +static int skl_crc_source_valid(struct intel_display *display, const enum intel_pipe_crc_source source) { switch (source) { @@ -535,21 +535,21 @@ static int skl_crc_source_valid(struct drm_i915_private *dev_priv, } static int -intel_is_valid_crc_source(struct drm_i915_private *dev_priv, +intel_is_valid_crc_source(struct intel_display *display, const enum intel_pipe_crc_source source) { - if (DISPLAY_VER(dev_priv) == 2) - return i8xx_crc_source_valid(dev_priv, source); - else if (DISPLAY_VER(dev_priv) < 5) - return i9xx_crc_source_valid(dev_priv, source); - else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - return vlv_crc_source_valid(dev_priv, source); - else if (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv)) - return ilk_crc_source_valid(dev_priv, source); - else if (DISPLAY_VER(dev_priv) < 9) - return ivb_crc_source_valid(dev_priv, source); + if (DISPLAY_VER(display) == 2) + return i8xx_crc_source_valid(display, source); + else if (DISPLAY_VER(display) < 5) + return i9xx_crc_source_valid(display, source); + else if (display->platform.valleyview || display->platform.cherryview) + return vlv_crc_source_valid(display, source); + else if (display->platform.ironlake || display->platform.sandybridge) + return ilk_crc_source_valid(display, source); + else if (DISPLAY_VER(display) < 9) + return ivb_crc_source_valid(display, source); else - return skl_crc_source_valid(dev_priv, source); + return skl_crc_source_valid(display, source); } const char *const *intel_crtc_get_crc_sources(struct drm_crtc *crtc, @@ -562,16 +562,16 @@ const char *const *intel_crtc_get_crc_sources(struct drm_crtc *crtc, int intel_crtc_verify_crc_source(struct drm_crtc *crtc, const char *source_name, size_t *values_cnt) { - struct drm_i915_private *dev_priv = to_i915(crtc->dev); + struct intel_display *display = to_intel_display(crtc->dev); enum intel_pipe_crc_source source; if (display_crc_ctl_parse_source(source_name, &source) < 0) { - drm_dbg(&dev_priv->drm, "unknown source %s\n", source_name); + drm_dbg_kms(display->drm, "unknown source %s\n", source_name); return -EINVAL; } if (source == INTEL_PIPE_CRC_SOURCE_AUTO || - intel_is_valid_crc_source(dev_priv, source) == 0) { + intel_is_valid_crc_source(display, source) == 0) { *values_cnt = 5; return 0; } @@ -583,7 +583,6 @@ int intel_crtc_set_crc_source(struct drm_crtc *_crtc, const char *source_name) { 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); struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc; enum intel_display_power_domain power_domain; enum intel_pipe_crc_source source; @@ -594,14 +593,14 @@ int intel_crtc_set_crc_source(struct drm_crtc *_crtc, const char *source_name) bool enable; if (display_crc_ctl_parse_source(source_name, &source) < 0) { - drm_dbg(&dev_priv->drm, "unknown source %s\n", source_name); + drm_dbg_kms(display->drm, "unknown source %s\n", source_name); return -EINVAL; } power_domain = POWER_DOMAIN_PIPE(pipe); wakeref = intel_display_power_get_if_enabled(display, power_domain); if (!wakeref) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "Trying to capture CRC while pipe is off\n"); return -EIO; } @@ -610,17 +609,17 @@ int intel_crtc_set_crc_source(struct drm_crtc *_crtc, const char *source_name) if (enable) intel_crtc_crc_setup_workarounds(crtc, true); - ret = get_new_crc_ctl_reg(dev_priv, pipe, &source, &val); + ret = get_new_crc_ctl_reg(display, pipe, &source, &val); if (ret != 0) goto out; pipe_crc->source = source; - intel_de_write(dev_priv, PIPE_CRC_CTL(dev_priv, pipe), val); - intel_de_posting_read(dev_priv, PIPE_CRC_CTL(dev_priv, pipe)); + intel_de_write(display, PIPE_CRC_CTL(display, pipe), val); + intel_de_posting_read(display, PIPE_CRC_CTL(display, pipe)); if (!source) { - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) - vlv_undo_pipe_scramble_reset(dev_priv, pipe); + if (display->platform.valleyview || display->platform.cherryview) + vlv_undo_pipe_scramble_reset(display, pipe); } pipe_crc->skipped = 0; @@ -636,7 +635,7 @@ out: void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc; enum pipe pipe = crtc->pipe; u32 val = 0; @@ -644,19 +643,20 @@ void intel_crtc_enable_pipe_crc(struct intel_crtc *crtc) if (!crtc->base.crc.opened) return; - if (get_new_crc_ctl_reg(dev_priv, pipe, &pipe_crc->source, &val) < 0) + if (get_new_crc_ctl_reg(display, pipe, &pipe_crc->source, &val) < 0) return; /* Don't need pipe_crc->lock here, IRQs are not generated. */ pipe_crc->skipped = 0; - intel_de_write(dev_priv, PIPE_CRC_CTL(dev_priv, pipe), val); - intel_de_posting_read(dev_priv, PIPE_CRC_CTL(dev_priv, pipe)); + intel_de_write(display, PIPE_CRC_CTL(display, pipe), val); + intel_de_posting_read(display, PIPE_CRC_CTL(display, pipe)); } void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc) { - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); + struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_pipe_crc *pipe_crc = &crtc->pipe_crc; enum pipe pipe = crtc->pipe; @@ -665,7 +665,7 @@ void intel_crtc_disable_pipe_crc(struct intel_crtc *crtc) pipe_crc->skipped = INT_MIN; spin_unlock_irq(&pipe_crc->lock); - intel_de_write(dev_priv, PIPE_CRC_CTL(dev_priv, pipe), 0); - intel_de_posting_read(dev_priv, PIPE_CRC_CTL(dev_priv, pipe)); + intel_de_write(display, PIPE_CRC_CTL(display, pipe), 0); + intel_de_posting_read(display, PIPE_CRC_CTL(display, pipe)); intel_synchronize_irq(dev_priv); } diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c b/drivers/gpu/drm/i915/display/intel_plane_initial.c index b1675b46e06c..c00d9184c586 100644 --- a/drivers/gpu/drm/i915/display/intel_plane_initial.c +++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c @@ -52,44 +52,57 @@ intel_reuse_initial_plane_obj(struct intel_crtc *this, return false; } +static enum intel_memory_type +initial_plane_memory_type(struct intel_display *display) +{ + 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; + else + return INTEL_MEMORY_STOLEN_SYSTEM; +} + static bool -initial_plane_phys_lmem(struct intel_display *display, - struct intel_initial_plane_config *plane_config) +initial_plane_phys(struct intel_display *display, + struct intel_initial_plane_config *plane_config) { struct drm_i915_private *i915 = to_i915(display->drm); - gen8_pte_t __iomem *gte = to_gt(i915)->ggtt->gsm; + struct i915_ggtt *ggtt = to_gt(i915)->ggtt; struct intel_memory_region *mem; + enum intel_memory_type mem_type; + bool is_present, is_local; dma_addr_t dma_addr; - gen8_pte_t pte; u32 base; + mem_type = initial_plane_memory_type(display); + mem = intel_memory_region_by_type(i915, mem_type); + if (!mem) { + drm_dbg_kms(display->drm, + "Initial plane memory region (type %s) not initialized\n", + intel_memory_type_str(mem_type)); + return false; + } + base = round_down(plane_config->base, I915_GTT_MIN_ALIGNMENT); - gte += base / I915_GTT_PAGE_SIZE; + dma_addr = intel_ggtt_read_entry(&ggtt->vm, base, &is_present, &is_local); - pte = ioread64(gte); - if (!(pte & GEN12_GGTT_PTE_LM)) { + if (!is_present) { drm_err(display->drm, - "Initial plane programming missing PTE_LM bit\n"); + "Initial plane FB PTE not present\n"); return false; } - dma_addr = pte & GEN12_GGTT_PTE_ADDR_MASK; - - if (IS_DGFX(i915)) - mem = i915->mm.regions[INTEL_REGION_LMEM_0]; - else - mem = i915->mm.stolen_region; - if (!mem) { - drm_dbg_kms(display->drm, - "Initial plane memory region not initialized\n"); + if (intel_memory_type_is_local(mem->type) != is_local) { + drm_err(display->drm, + "Initial plane FB PTE unsuitable for %s\n", + mem->region.name); return false; } - /* - * On lmem we don't currently expect this to - * ever be placed in the stolen portion. - */ if (dma_addr < mem->region.start || dma_addr > mem->region.end) { drm_err(display->drm, "Initial plane programming using invalid range, dma_addr=%pa (%s [%pa-%pa])\n", @@ -107,42 +120,6 @@ initial_plane_phys_lmem(struct intel_display *display, return true; } -static bool -initial_plane_phys_smem(struct intel_display *display, - struct intel_initial_plane_config *plane_config) -{ - struct drm_i915_private *i915 = to_i915(display->drm); - struct intel_memory_region *mem; - u32 base; - - base = round_down(plane_config->base, I915_GTT_MIN_ALIGNMENT); - - mem = i915->mm.stolen_region; - if (!mem) { - drm_dbg_kms(display->drm, - "Initial plane memory region not initialized\n"); - return false; - } - - /* FIXME get and validate the dma_addr from the PTE */ - plane_config->phys_base = base; - plane_config->mem = mem; - - return true; -} - -static bool -initial_plane_phys(struct intel_display *display, - struct intel_initial_plane_config *plane_config) -{ - struct drm_i915_private *i915 = to_i915(display->drm); - - if (IS_DGFX(i915) || HAS_LMEMBAR_SMEM_STOLEN(i915)) - return initial_plane_phys_lmem(display, plane_config); - else - return initial_plane_phys_smem(display, plane_config); -} - static struct i915_vma * initial_plane_vma(struct intel_display *display, struct intel_initial_plane_config *plane_config) diff --git a/drivers/gpu/drm/i915/display/intel_pmdemand.c b/drivers/gpu/drm/i915/display/intel_pmdemand.c index 63301a01906c..1253376c7654 100644 --- a/drivers/gpu/drm/i915/display/intel_pmdemand.c +++ b/drivers/gpu/drm/i915/display/intel_pmdemand.c @@ -5,6 +5,8 @@ #include <linux/bitops.h> +#include <drm/drm_print.h> + #include "i915_reg.h" #include "i915_utils.h" #include "intel_atomic.h" @@ -476,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 617ce4993172..05e1e5c7e8b7 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -91,7 +91,6 @@ static void vlv_power_sequencer_kick(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); enum pipe pipe = intel_dp->pps.vlv_pps_pipe; bool pll_enabled, release_cl_override = false; @@ -134,7 +133,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp) release_cl_override = display->platform.cherryview && !chv_phy_powergate_ch(display, phy, ch, true); - if (vlv_force_pll_on(dev_priv, pipe, vlv_get_dpll(display))) { + if (vlv_force_pll_on(display, pipe, vlv_get_dpll(display))) { drm_err(display->drm, "Failed to force on PLL for pipe %c!\n", pipe_name(pipe)); @@ -158,7 +157,7 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp) intel_de_posting_read(display, intel_dp->output_reg); if (!pll_enabled) { - vlv_force_pll_off(dev_priv, pipe); + vlv_force_pll_off(display, pipe); if (release_cl_override) chv_phy_powergate_ch(display, phy, ch, false); @@ -351,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; @@ -374,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; @@ -500,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)); @@ -519,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); @@ -744,11 +739,11 @@ bool intel_pps_vdd_on_unlocked(struct intel_dp *intel_dp) i915_reg_t pp_stat_reg, pp_ctrl_reg; bool need_to_disable = !intel_dp->pps.want_panel_vdd; - lockdep_assert_held(&display->pps.mutex); - if (!intel_dp_is_edp(intel_dp)) return false; + lockdep_assert_held(&display->pps.mutex); + cancel_delayed_work(&intel_dp->pps.panel_vdd_work); intel_dp->pps.want_panel_vdd = true; @@ -925,11 +920,11 @@ void intel_pps_vdd_off_unlocked(struct intel_dp *intel_dp, bool sync) { struct intel_display *display = to_intel_display(intel_dp); - lockdep_assert_held(&display->pps.mutex); - if (!intel_dp_is_edp(intel_dp)) return; + lockdep_assert_held(&display->pps.mutex); + INTEL_DISPLAY_STATE_WARN(display, !intel_dp->pps.want_panel_vdd, "[ENCODER:%d:%s] %s VDD not forced on", dp_to_dig_port(intel_dp)->base.base.base.id, @@ -1592,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; @@ -1639,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; @@ -1792,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; @@ -1837,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; @@ -1846,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); @@ -1855,7 +1846,7 @@ void assert_pps_unlocked(struct intel_display *display, enum pipe pipe) switch (port_sel) { case PANEL_PORT_SELECT_LVDS: - intel_lvds_port_enabled(dev_priv, PCH_LVDS, &panel_pipe); + intel_lvds_port_enabled(display, PCH_LVDS, &panel_pipe); break; case PANEL_PORT_SELECT_DPA: g4x_dp_port_enabled(display, DP_A, PORT_A, &panel_pipe); @@ -1883,7 +1874,7 @@ void assert_pps_unlocked(struct intel_display *display, enum pipe pipe) drm_WARN_ON(display->drm, port_sel != PANEL_PORT_SELECT_LVDS); - intel_lvds_port_enabled(dev_priv, LVDS, &panel_pipe); + intel_lvds_port_enabled(display, LVDS, &panel_pipe); } val = intel_de_read(display, pp_reg); diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 4e938bad808c..430ad4ef7146 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" @@ -36,7 +37,9 @@ #include "intel_ddi.h" #include "intel_de.h" #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" @@ -45,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" /** @@ -463,8 +467,8 @@ void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir) if (DISPLAY_VER(display) >= 9) { u32 val; - val = intel_de_rmw(dev_priv, - PSR_EVENT(dev_priv, cpu_transcoder), + val = intel_de_rmw(display, + PSR_EVENT(display, cpu_transcoder), 0, 0); psr_event_print(display, val, intel_dp->psr.sel_update_enabled); @@ -689,7 +693,6 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp) static void hsw_psr_setup_aux(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); enum transcoder cpu_transcoder = intel_dp->psr.transcoder; u32 aux_clock_divider, aux_ctl; /* write DP_SET_POWER=D0 */ @@ -704,7 +707,7 @@ static void hsw_psr_setup_aux(struct intel_dp *intel_dp) BUILD_BUG_ON(sizeof(aux_msg) > 20); for (i = 0; i < sizeof(aux_msg); i += 4) - intel_de_write(dev_priv, + intel_de_write(display, psr_aux_data_reg(display, cpu_transcoder, i >> 2), intel_dp_aux_pack(&aux_msg[i], sizeof(aux_msg) - i)); @@ -794,31 +797,10 @@ 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); + intel_alpm_enable_sink(intel_dp, crtc_state); crtc_state->has_panel_replay ? _panel_replay_enable_sink(intel_dp, crtc_state) : @@ -839,7 +821,6 @@ static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); struct intel_connector *connector = intel_dp->attached_connector; - struct drm_i915_private *dev_priv = to_i915(display->drm); u32 val = 0; if (DISPLAY_VER(display) >= 11) @@ -873,7 +854,7 @@ static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp) * WA 0479: hsw,bdw * "Do not skip both TP1 and TP2/TP3" */ - if (DISPLAY_VER(dev_priv) < 9 && + if (DISPLAY_VER(display) < 9 && connector->panel.vbt.psr.tp1_wakeup_time_us == 0 && connector->panel.vbt.psr.tp2_tp3_wakeup_time_us == 0) val |= EDP_PSR_TP2_TP3_TIME_100us; @@ -906,10 +887,21 @@ 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); - struct drm_i915_private *dev_priv = to_i915(display->drm); enum transcoder cpu_transcoder = intel_dp->psr.transcoder; u32 max_sleep_time = 0x1f; u32 val = EDP_PSR_ENABLE; @@ -919,7 +911,7 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp) if (DISPLAY_VER(display) < 20) val |= EDP_PSR_MAX_SLEEP_TIME(max_sleep_time); - if (IS_HASWELL(dev_priv)) + if (display->platform.haswell) val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES; if (intel_dp->psr.link_standby) @@ -935,6 +927,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) @@ -1013,14 +1013,21 @@ static void dg2_activate_panel_replay(struct intel_dp *intel_dp) static void hsw_activate_psr2(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); 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 && !IS_ALDERLAKE_P(dev_priv)) + if (DISPLAY_VER(display) < 14 && !display->platform.alderlake_p) val |= EDP_SU_TRACK_ENABLE; if (DISPLAY_VER(display) >= 10 && DISPLAY_VER(display) < 13) @@ -1038,7 +1045,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) } /* Wa_22012278275:adl-p */ - if (IS_ALDERLAKE_P(dev_priv) && IS_DISPLAY_STEP(display, STEP_A0, STEP_E0)) { + if (display->platform.alderlake_p && IS_DISPLAY_STEP(display, STEP_A0, STEP_E0)) { static const u8 map[] = { 2, /* 5 lines */ 1, /* 6 lines */ @@ -1103,9 +1110,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) static bool transcoder_has_psr2(struct intel_display *display, enum transcoder cpu_transcoder) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - - if (IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(display) >= 14) + if (display->platform.alderlake_p || DISPLAY_VER(display) >= 14) return cpu_transcoder == TRANSCODER_A || cpu_transcoder == TRANSCODER_B; else if (DISPLAY_VER(display) >= 12) return cpu_transcoder == TRANSCODER_A; @@ -1183,10 +1188,9 @@ dc3co_is_pipe_port_compatible(struct intel_dp *intel_dp, struct intel_display *display = to_intel_display(intel_dp); struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe; - struct drm_i915_private *dev_priv = to_i915(display->drm); enum port port = dig_port->base.port; - if (IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(display) >= 14) + if (display->platform.alderlake_p || DISPLAY_VER(display) >= 14) return pipe <= PIPE_B && port <= PORT_B; else return pipe == PIPE_A && port == PORT_A; @@ -1197,7 +1201,6 @@ tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); const u32 crtc_vdisplay = crtc_state->uapi.adjusted_mode.crtc_vdisplay; struct i915_power_domains *power_domains = &display->power.domains; u32 exit_scanlines; @@ -1223,7 +1226,7 @@ tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp, return; /* Wa_16011303918:adl-p */ - if (IS_ALDERLAKE_P(dev_priv) && IS_DISPLAY_STEP(display, STEP_A0, STEP_B0)) + if (display->platform.alderlake_p && IS_DISPLAY_STEP(display, STEP_A0, STEP_B0)) return; /* @@ -1264,7 +1267,6 @@ static bool psr2_granularity_check(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config; const int crtc_hdisplay = crtc_state->hw.adjusted_mode.crtc_hdisplay; const int crtc_vdisplay = crtc_state->hw.adjusted_mode.crtc_vdisplay; @@ -1286,7 +1288,7 @@ static bool psr2_granularity_check(struct intel_dp *intel_dp, * For other platforms with SW tracking we can adjust the y coordinates * to match sink requirement if multiple of 4. */ - if (IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(display) >= 14) + if (display->platform.alderlake_p || DISPLAY_VER(display) >= 14) y_granularity = intel_dp->psr.su_y_granularity; else if (intel_dp->psr.su_y_granularity <= 2) y_granularity = 4; @@ -1412,7 +1414,6 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); int crtc_hdisplay = crtc_state->hw.adjusted_mode.crtc_hdisplay; int crtc_vdisplay = crtc_state->hw.adjusted_mode.crtc_vdisplay; int psr_max_h = 0, psr_max_v = 0, max_bpp = 0; @@ -1421,20 +1422,20 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, return false; /* JSL and EHL only supports eDP 1.3 */ - if (IS_JASPERLAKE(dev_priv) || IS_ELKHARTLAKE(dev_priv)) { + if (display->platform.jasperlake || display->platform.elkhartlake) { drm_dbg_kms(display->drm, "PSR2 not supported by phy\n"); return false; } /* Wa_16011181250 */ - if (IS_ROCKETLAKE(dev_priv) || IS_ALDERLAKE_S(dev_priv) || - IS_DG2(dev_priv)) { + if (display->platform.rocketlake || display->platform.alderlake_s || + display->platform.dg2) { drm_dbg_kms(display->drm, "PSR2 is defeatured for this platform\n"); return false; } - if (IS_ALDERLAKE_P(dev_priv) && IS_DISPLAY_STEP(display, STEP_A0, STEP_B0)) { + if (display->platform.alderlake_p && IS_DISPLAY_STEP(display, STEP_A0, STEP_B0)) { drm_dbg_kms(display->drm, "PSR2 not completely functional in this stepping\n"); return false; @@ -1453,7 +1454,7 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, * over PSR2. */ if (crtc_state->dsc.compression_enable && - (DISPLAY_VER(display) < 14 && !IS_ALDERLAKE_P(dev_priv))) { + (DISPLAY_VER(display) < 14 && !display->platform.alderlake_p)) { drm_dbg_kms(display->drm, "PSR2 cannot be enabled since DSC is enabled\n"); return false; @@ -1486,7 +1487,7 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, /* Wa_16011303918:adl-p */ if (crtc_state->vrr.enable && - IS_ALDERLAKE_P(dev_priv) && IS_DISPLAY_STEP(display, STEP_A0, STEP_B0)) { + display->platform.alderlake_p && IS_DISPLAY_STEP(display, STEP_A0, STEP_B0)) { drm_dbg_kms(display->drm, "PSR2 not enabled, not compatible with HW stepping + VRR\n"); return false; @@ -1604,6 +1605,12 @@ _panel_replay_compute_config(struct intel_dp *intel_dp, return false; } + if (crtc_state->crc_enabled) { + drm_dbg_kms(display->drm, + "Panel Replay not enabled because it would inhibit pipe CRC calculation\n"); + return false; + } + if (!intel_dp_is_edp(intel_dp)) return true; @@ -1634,12 +1641,6 @@ _panel_replay_compute_config(struct intel_dp *intel_dp, if (!alpm_config_valid(intel_dp, crtc_state, true)) return false; - if (crtc_state->crc_enabled) { - drm_dbg_kms(display->drm, - "Panel Replay not enabled because it would inhibit pipe CRC calculation\n"); - return false; - } - return true; } @@ -1658,6 +1659,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"); @@ -1711,6 +1715,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, @@ -1827,7 +1849,6 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); enum transcoder cpu_transcoder = intel_dp->psr.transcoder; u32 mask = 0; @@ -1866,7 +1887,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, * As a workaround leave LPSP unmasked to prevent PSR entry * when external displays are active. */ - if (DISPLAY_VER(display) >= 8 || IS_HASWELL_ULT(dev_priv)) + if (DISPLAY_VER(display) >= 8 || display->platform.haswell_ult) mask |= EDP_PSR_DEBUG_MASK_LPSP; if (DISPLAY_VER(display) < 20) @@ -1880,7 +1901,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, mask |= EDP_PSR_DEBUG_MASK_DISP_REG_WRITE; /* allow PSR with sprite enabled */ - if (IS_HASWELL(dev_priv)) + if (display->platform.haswell) mask |= EDP_PSR_DEBUG_MASK_SPRITE_ENABLE; } @@ -1903,9 +1924,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 @@ -1925,7 +1943,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, */ if (!intel_dp->psr.panel_replay_enabled && (IS_DISPLAY_VERx100_STEP(display, 1400, STEP_A0, STEP_B0) || - IS_ALDERLAKE_P(dev_priv))) + display->platform.alderlake_p)) intel_de_rmw(display, CHICKEN_TRANS(display, cpu_transcoder), 0, ADLP_1_BASED_X_GRANULARITY); @@ -1936,10 +1954,18 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, MTL_CLKGATE_DIS_TRANS(display, cpu_transcoder), 0, MTL_CLKGATE_DIS_TRANS_DMASC_GATING_DIS); - else if (IS_ALDERLAKE_P(dev_priv)) + else if (display->platform.alderlake_p) 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); + + intel_alpm_configure(intel_dp, crtc_state); } static bool psr_interrupt_error_check(struct intel_dp *intel_dp) @@ -1995,6 +2021,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; @@ -2006,8 +2033,9 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp, intel_dp->psr.sel_update_enabled ? "2" : "1"); /* - * Enabling here only for PSR. Panel Replay enable bit is already - * written at this point. See + * Enabling sink PSR/Panel Replay here only for PSR. Panel Replay enable + * bit is already written at this point. Sink ALPM is enabled here for + * PSR and Panel Replay. See * intel_psr_panel_replay_enable_sink. Modifiers/options: * - Selective Update * - Region Early Transport @@ -2024,7 +2052,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp, intel_psr_enable_source(intel_dp, crtc_state); intel_dp->psr.enabled = true; - intel_dp->psr.paused = false; + intel_dp->psr.pause_counter = 0; /* * Link_ok is sticky and set here on PSR enable. We can assume link @@ -2070,6 +2098,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); @@ -2104,7 +2138,6 @@ static void intel_psr_wait_exit_locked(struct intel_dp *intel_dp) static void intel_psr_disable_locked(struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); enum transcoder cpu_transcoder = intel_dp->psr.transcoder; lockdep_assert_held(&intel_dp->psr.lock); @@ -2136,7 +2169,7 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) intel_de_rmw(display, MTL_CLKGATE_DIS_TRANS(display, cpu_transcoder), MTL_CLKGATE_DIS_TRANS_DMASC_GATING_DIS, 0); - else if (IS_ALDERLAKE_P(dev_priv)) + else if (display->platform.alderlake_p) intel_de_rmw(display, CLKGATE_DIS_MISC, CLKGATE_DIS_MISC_DMASC_GATING_DIS, 0); } @@ -2144,16 +2177,8 @@ 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); - } + if (intel_dp->psr.panel_replay_enabled && intel_dp_is_edp(intel_dp)) + intel_alpm_disable(intel_dp); /* Disable PSR on Sink */ if (!intel_dp->psr.panel_replay_enabled) { @@ -2164,12 +2189,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; } /** @@ -2210,7 +2242,6 @@ void intel_psr_disable(struct intel_dp *intel_dp, */ void intel_psr_pause(struct intel_dp *intel_dp) { - struct intel_display *display = to_intel_display(intel_dp); struct intel_psr *psr = &intel_dp->psr; if (!CAN_PSR(intel_dp) && !CAN_PANEL_REPLAY(intel_dp)) @@ -2223,12 +2254,10 @@ void intel_psr_pause(struct intel_dp *intel_dp) return; } - /* If we ever hit this, we will need to add refcount to pause/resume */ - drm_WARN_ON(display->drm, psr->paused); - - intel_psr_exit(intel_dp); - intel_psr_wait_exit_locked(intel_dp); - psr->paused = true; + if (intel_dp->psr.pause_counter++ == 0) { + intel_psr_exit(intel_dp); + intel_psr_wait_exit_locked(intel_dp); + } mutex_unlock(&psr->lock); @@ -2244,6 +2273,7 @@ void intel_psr_pause(struct intel_dp *intel_dp) */ void intel_psr_resume(struct intel_dp *intel_dp) { + struct intel_display *display = to_intel_display(intel_dp); struct intel_psr *psr = &intel_dp->psr; if (!CAN_PSR(intel_dp) && !CAN_PANEL_REPLAY(intel_dp)) @@ -2251,28 +2281,36 @@ void intel_psr_resume(struct intel_dp *intel_dp) mutex_lock(&psr->lock); - if (!psr->paused) - goto unlock; + if (!psr->enabled) + goto out; - psr->paused = false; - intel_psr_activate(intel_dp); + if (!psr->pause_counter) { + drm_warn(display->drm, "Unbalanced PSR pause/resume!\n"); + goto out; + } -unlock: + if (--intel_dp->psr.pause_counter == 0) + intel_psr_activate(intel_dp); + +out: mutex_unlock(&psr->lock); } /** - * 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) { @@ -2283,8 +2321,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; } @@ -2312,37 +2357,76 @@ void intel_psr_trigger_frame_change_event(struct intel_dsb *dsb, CURSURFLIVE(display, crtc->pipe), 0); } -static u32 man_trk_ctl_enable_bit_get(struct intel_display *display) +/** + * 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 drm_i915_private *dev_priv = to_i915(display->drm); + 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. + */ - return IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(display) >= 14 ? 0 : + 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 : PSR2_MAN_TRK_CTL_ENABLE; } static u32 man_trk_ctl_single_full_frame_bit_get(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - - return IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(display) >= 14 ? + return display->platform.alderlake_p || DISPLAY_VER(display) >= 14 ? ADLP_PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME : PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME; } static u32 man_trk_ctl_partial_frame_bit_get(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - - return IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(display) >= 14 ? + return display->platform.alderlake_p || DISPLAY_VER(display) >= 14 ? ADLP_PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE : PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE; } static u32 man_trk_ctl_continuos_full_frame(struct intel_display *display) { - struct drm_i915_private *dev_priv = to_i915(display->drm); - - return IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(display) >= 14 ? + return display->platform.alderlake_p || DISPLAY_VER(display) >= 14 ? ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME : PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME; } @@ -2405,8 +2489,6 @@ static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state, bool full_update) { 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); u32 val = man_trk_ctl_enable_bit_get(display); /* SF partial frame enable has to be set even on full update */ @@ -2420,7 +2502,7 @@ static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state, if (crtc_state->psr2_su_area.y1 == -1) goto exit; - if (IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(display) >= 14) { + if (display->platform.alderlake_p || DISPLAY_VER(display) >= 14) { val |= ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(crtc_state->psr2_su_area.y1); val |= ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(crtc_state->psr2_su_area.y2 - 1); } else { @@ -2474,13 +2556,12 @@ static void clip_area_update(struct drm_rect *overlap_damage_area, static void intel_psr2_sel_fetch_pipe_alignment(struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config; u16 y_alignment; /* ADLP aligns the SU region to vdsc slice height in case dsc is enabled */ if (crtc_state->dsc.compression_enable && - (IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(display) >= 14)) + (display->platform.alderlake_p || DISPLAY_VER(display) >= 14)) y_alignment = vdsc_cfg->slice_height; else y_alignment = crtc_state->su_y_granularity; @@ -2601,12 +2682,11 @@ static void intel_psr_apply_su_area_workarounds(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); /* Wa_14014971492 */ if (!crtc_state->has_panel_replay && ((IS_DISPLAY_VERx100_STEP(display, 1400, STEP_A0, STEP_B0) || - IS_ALDERLAKE_P(i915) || IS_TIGERLAKE(i915))) && + display->platform.alderlake_p || display->platform.tigerlake)) && crtc_state->splitter.enable) crtc_state->psr2_su_area.y1 = 0; @@ -2807,7 +2887,6 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = 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 = @@ -2839,7 +2918,7 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state, new_crtc_state->has_sel_update != psr->sel_update_enabled || new_crtc_state->enable_psr2_su_region_et != psr->su_region_et_enabled || new_crtc_state->has_panel_replay != psr->panel_replay_enabled || - (DISPLAY_VER(i915) < 11 && new_crtc_state->wm_level_disabled)) + (DISPLAY_VER(display) < 11 && new_crtc_state->wm_level_disabled)) intel_psr_disable_locked(intel_dp); else if (new_crtc_state->wm_level_disabled) /* Wa_14015648006 */ @@ -3322,7 +3401,7 @@ void intel_psr_flush(struct intel_display *display, * we have to ensure that the PSR is not activated until * intel_psr_resume() is called. */ - if (intel_dp->psr.paused) + if (intel_dp->psr.pause_counter) goto unlock; if (origin == ORIGIN_FLIP || @@ -3419,29 +3498,14 @@ 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); } } @@ -3626,6 +3690,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) { @@ -3634,8 +3860,8 @@ psr_source_status(struct intel_dp *intel_dp, struct seq_file *m) const char *status = "unknown"; u32 val, status_val; - if (intel_dp_is_edp(intel_dp) && (intel_dp->psr.sel_update_enabled || - intel_dp->psr.panel_replay_enabled)) { + if ((intel_dp_is_edp(intel_dp) || DISPLAY_VER(display) >= 30) && + (intel_dp->psr.sel_update_enabled || intel_dp->psr.panel_replay_enabled)) { static const char * const live_status[] = { "IDLE", "CAPTURE", @@ -3728,10 +3954,9 @@ static void intel_psr_print_mode(struct intel_dp *intel_dp, static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp) { struct intel_display *display = to_intel_display(intel_dp); - struct drm_i915_private *dev_priv = to_i915(display->drm); enum transcoder cpu_transcoder = intel_dp->psr.transcoder; struct intel_psr *psr = &intel_dp->psr; - intel_wakeref_t wakeref; + struct ref_tracker *wakeref; bool enabled; u32 val, psr2_ctl; @@ -3740,7 +3965,7 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp) if (!(psr->sink_support || psr->sink_panel_replay_support)) return 0; - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); + wakeref = intel_display_rpm_get(display); mutex_lock(&psr->lock); intel_psr_print_mode(intel_dp, m); @@ -3822,7 +4047,7 @@ static int intel_psr_status(struct seq_file *m, struct intel_dp *intel_dp) unlock: mutex_unlock(&psr->lock); - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + intel_display_rpm_put(display, wakeref); return 0; } @@ -3853,9 +4078,7 @@ static int i915_edp_psr_debug_set(void *data, u64 val) { struct intel_display *display = data; - struct drm_i915_private *dev_priv = to_i915(display->drm); struct intel_encoder *encoder; - intel_wakeref_t wakeref; int ret = -ENODEV; if (!HAS_PSR(display)) @@ -3866,12 +4089,9 @@ i915_edp_psr_debug_set(void *data, u64 val) drm_dbg_kms(display->drm, "Setting PSR debug to %llx\n", val); - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); - // TODO: split to each transcoder's PSR debug state - ret = intel_psr_debug_set(intel_dp, val); - - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); + with_intel_display_rpm(display) + ret = intel_psr_debug_set(intel_dp, val); } return ret; @@ -4004,3 +4224,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 6e2d9929b4d7..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. @@ -2036,7 +2031,7 @@ static u16 intel_sdvo_get_hotplug_support(struct intel_sdvo *intel_sdvo) struct intel_display *display = to_intel_display(&intel_sdvo->base); u16 hotplug; - if (!I915_HAS_HOTPLUG(display)) + if (!HAS_HOTPLUG(display)) return 0; /* @@ -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_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c index b9acd9fe160c..2b53ac9f4935 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_phy.c +++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c @@ -5,6 +5,8 @@ #include <linux/math.h> +#include <drm/drm_print.h> + #include "i915_reg.h" #include "i915_utils.h" #include "intel_ddi.h" 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_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index b8d14ed8a56e..c1014e74791f 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -3,8 +3,10 @@ * Copyright © 2019 Intel Corporation */ -#include "i915_drv.h" +#include <drm/drm_print.h> + #include "i915_reg.h" +#include "i915_utils.h" #include "intel_atomic.h" #include "intel_cx0_phy_regs.h" #include "intel_ddi.h" @@ -92,11 +94,6 @@ static struct intel_tc_port *to_tc_port(struct intel_digital_port *dig_port) return dig_port->tc; } -static struct drm_i915_private *tc_to_i915(struct intel_tc_port *tc) -{ - return to_i915(tc->dig_port->base.base.dev); -} - static bool intel_tc_port_in_mode(struct intel_digital_port *dig_port, enum tc_port_mode mode) { @@ -219,10 +216,11 @@ __tc_cold_unblock(struct intel_tc_port *tc, enum intel_display_power_domain doma static void tc_cold_unblock(struct intel_tc_port *tc, intel_wakeref_t wakeref) { + struct intel_display __maybe_unused *display = to_intel_display(tc->dig_port); enum intel_display_power_domain domain = tc_phy_cold_off_domain(tc); #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) - drm_WARN_ON(&tc_to_i915(tc)->drm, tc->lock_power_domain != domain); + drm_WARN_ON(display->drm, tc->lock_power_domain != domain); #endif __tc_cold_unblock(tc, domain, wakeref); } @@ -266,13 +264,13 @@ assert_tc_port_power_enabled(struct intel_tc_port *tc) static u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); struct intel_tc_port *tc = to_tc_port(dig_port); u32 lane_mask; - lane_mask = intel_de_read(i915, PORT_TX_DFLEXDPSP(tc->phy_fia)); + lane_mask = intel_de_read(display, PORT_TX_DFLEXDPSP(tc->phy_fia)); - drm_WARN_ON(&i915->drm, lane_mask == 0xffffffff); + drm_WARN_ON(display->drm, lane_mask == 0xffffffff); assert_tc_cold_blocked(tc); lane_mask &= DP_LANE_ASSIGNMENT_MASK(tc->phy_fia_idx); @@ -281,13 +279,13 @@ static u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port) u32 intel_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_port) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); struct intel_tc_port *tc = to_tc_port(dig_port); u32 pin_mask; - pin_mask = intel_de_read(i915, PORT_TX_DFLEXPA1(tc->phy_fia)); + pin_mask = intel_de_read(display, PORT_TX_DFLEXPA1(tc->phy_fia)); - drm_WARN_ON(&i915->drm, pin_mask == 0xffffffff); + drm_WARN_ON(display->drm, pin_mask == 0xffffffff); assert_tc_cold_blocked(tc); return (pin_mask & DP_PIN_ASSIGNMENT_MASK(tc->phy_fia_idx)) >> @@ -297,13 +295,12 @@ u32 intel_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_port) static int lnl_tc_port_get_max_lane_count(struct intel_digital_port *dig_port) { struct intel_display *display = to_intel_display(dig_port); - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); enum tc_port tc_port = intel_encoder_to_tc(&dig_port->base); intel_wakeref_t wakeref; u32 val, pin_assignment; with_intel_display_power(display, POWER_DOMAIN_DISPLAY_CORE, wakeref) - val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port)); + val = intel_de_read(display, TCSS_DDI_STATUS(tc_port)); pin_assignment = REG_FIELD_GET(TCSS_DDI_STATUS_PIN_ASSIGNMENT_MASK, val); @@ -369,7 +366,7 @@ static int intel_tc_port_get_max_lane_count(struct intel_digital_port *dig_port) int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); struct intel_tc_port *tc = to_tc_port(dig_port); if (!intel_encoder_is_tc(&dig_port->base) || tc->mode != TC_PORT_DP_ALT) @@ -377,10 +374,10 @@ int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port) assert_tc_cold_blocked(tc); - if (DISPLAY_VER(i915) >= 20) + if (DISPLAY_VER(display) >= 20) return lnl_tc_port_get_max_lane_count(dig_port); - if (DISPLAY_VER(i915) >= 14) + if (DISPLAY_VER(display) >= 14) return mtl_tc_port_get_max_lane_count(dig_port); return intel_tc_port_get_max_lane_count(dig_port); @@ -389,20 +386,20 @@ int intel_tc_port_max_lane_count(struct intel_digital_port *dig_port) void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port, int required_lanes) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); struct intel_tc_port *tc = to_tc_port(dig_port); bool lane_reversal = dig_port->lane_reversal; u32 val; - if (DISPLAY_VER(i915) >= 14) + if (DISPLAY_VER(display) >= 14) return; - drm_WARN_ON(&i915->drm, + drm_WARN_ON(display->drm, lane_reversal && tc->mode != TC_PORT_LEGACY); assert_tc_cold_blocked(tc); - val = intel_de_read(i915, PORT_TX_DFLEXDPMLE1(tc->phy_fia)); + val = intel_de_read(display, PORT_TX_DFLEXDPMLE1(tc->phy_fia)); val &= ~DFLEXDPMLE1_DPMLETC_MASK(tc->phy_fia_idx); switch (required_lanes) { @@ -423,16 +420,16 @@ void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port, MISSING_CASE(required_lanes); } - intel_de_write(i915, PORT_TX_DFLEXDPMLE1(tc->phy_fia), val); + intel_de_write(display, PORT_TX_DFLEXDPMLE1(tc->phy_fia), val); } static void tc_port_fixup_legacy_flag(struct intel_tc_port *tc, u32 live_status_mask) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); u32 valid_hpd_mask; - drm_WARN_ON(&i915->drm, tc->mode != TC_PORT_DISCONNECTED); + drm_WARN_ON(display->drm, tc->mode != TC_PORT_DISCONNECTED); if (hweight32(live_status_mask) != 1) return; @@ -447,7 +444,7 @@ static void tc_port_fixup_legacy_flag(struct intel_tc_port *tc, return; /* If live status mismatches the VBT flag, trust the live status. */ - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Port %s: live status %08x mismatches the legacy port flag %08x, fixing flag\n", tc->port_name, live_status_mask, valid_hpd_mask); @@ -490,21 +487,20 @@ icl_tc_phy_cold_off_domain(struct intel_tc_port *tc) static u32 icl_tc_phy_hpd_live_status(struct intel_tc_port *tc) { struct intel_display *display = to_intel_display(tc->dig_port); - struct drm_i915_private *i915 = tc_to_i915(tc); struct intel_digital_port *dig_port = tc->dig_port; - u32 isr_bit = i915->display.hotplug.pch_hpd[dig_port->base.hpd_pin]; + u32 isr_bit = display->hotplug.pch_hpd[dig_port->base.hpd_pin]; intel_wakeref_t wakeref; u32 fia_isr; u32 pch_isr; u32 mask = 0; with_intel_display_power(display, tc_phy_cold_off_domain(tc), wakeref) { - fia_isr = intel_de_read(i915, PORT_TX_DFLEXDPSP(tc->phy_fia)); - pch_isr = intel_de_read(i915, SDEISR); + fia_isr = intel_de_read(display, PORT_TX_DFLEXDPSP(tc->phy_fia)); + pch_isr = intel_de_read(display, SDEISR); } if (fia_isr == 0xffffffff) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Port %s: PHY in TCCOLD, nothing connected\n", tc->port_name); return mask; @@ -531,14 +527,14 @@ static u32 icl_tc_phy_hpd_live_status(struct intel_tc_port *tc) */ static bool icl_tc_phy_is_ready(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); u32 val; assert_tc_cold_blocked(tc); - val = intel_de_read(i915, PORT_TX_DFLEXDPPMS(tc->phy_fia)); + val = intel_de_read(display, PORT_TX_DFLEXDPPMS(tc->phy_fia)); if (val == 0xffffffff) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Port %s: PHY in TCCOLD, assuming not ready\n", tc->port_name); return false; @@ -550,14 +546,14 @@ static bool icl_tc_phy_is_ready(struct intel_tc_port *tc) static bool icl_tc_phy_take_ownership(struct intel_tc_port *tc, bool take) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); u32 val; assert_tc_cold_blocked(tc); - val = intel_de_read(i915, PORT_TX_DFLEXDPCSSS(tc->phy_fia)); + val = intel_de_read(display, PORT_TX_DFLEXDPCSSS(tc->phy_fia)); if (val == 0xffffffff) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Port %s: PHY in TCCOLD, can't %s ownership\n", tc->port_name, take ? "take" : "release"); @@ -568,21 +564,21 @@ static bool icl_tc_phy_take_ownership(struct intel_tc_port *tc, if (take) val |= DP_PHY_MODE_STATUS_NOT_SAFE(tc->phy_fia_idx); - intel_de_write(i915, PORT_TX_DFLEXDPCSSS(tc->phy_fia), val); + intel_de_write(display, PORT_TX_DFLEXDPCSSS(tc->phy_fia), val); return true; } static bool icl_tc_phy_is_owned(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); u32 val; assert_tc_cold_blocked(tc); - val = intel_de_read(i915, PORT_TX_DFLEXDPCSSS(tc->phy_fia)); + val = intel_de_read(display, PORT_TX_DFLEXDPCSSS(tc->phy_fia)); if (val == 0xffffffff) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Port %s: PHY in TCCOLD, assume not owned\n", tc->port_name); return false; @@ -619,30 +615,30 @@ static void icl_tc_phy_get_hw_state(struct intel_tc_port *tc) static bool tc_phy_verify_legacy_or_dp_alt_mode(struct intel_tc_port *tc, int required_lanes) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); struct intel_digital_port *dig_port = tc->dig_port; int max_lanes; max_lanes = intel_tc_port_max_lane_count(dig_port); if (tc->mode == TC_PORT_LEGACY) { - drm_WARN_ON(&i915->drm, max_lanes != 4); + drm_WARN_ON(display->drm, max_lanes != 4); return true; } - drm_WARN_ON(&i915->drm, tc->mode != TC_PORT_DP_ALT); + drm_WARN_ON(display->drm, tc->mode != TC_PORT_DP_ALT); /* * Now we have to re-check the live state, in case the port recently * became disconnected. Not necessary for legacy mode. */ if (!(tc_phy_hpd_live_status(tc) & BIT(TC_PORT_DP_ALT))) { - drm_dbg_kms(&i915->drm, "Port %s: PHY sudden disconnect\n", + drm_dbg_kms(display->drm, "Port %s: PHY sudden disconnect\n", tc->port_name); return false; } if (max_lanes < required_lanes) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Port %s: PHY max lanes %d < required lanes %d\n", tc->port_name, max_lanes, required_lanes); @@ -655,7 +651,7 @@ static bool tc_phy_verify_legacy_or_dp_alt_mode(struct intel_tc_port *tc, static bool icl_tc_phy_connect(struct intel_tc_port *tc, int required_lanes) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); tc->lock_wakeref = tc_cold_block(tc); @@ -664,8 +660,8 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc, if ((!tc_phy_is_ready(tc) || !icl_tc_phy_take_ownership(tc, true)) && - !drm_WARN_ON(&i915->drm, tc->mode == TC_PORT_LEGACY)) { - drm_dbg_kms(&i915->drm, "Port %s: can't take PHY ownership (ready %s)\n", + !drm_WARN_ON(display->drm, tc->mode == TC_PORT_LEGACY)) { + drm_dbg_kms(display->drm, "Port %s: can't take PHY ownership (ready %s)\n", tc->port_name, str_yes_no(tc_phy_is_ready(tc))); goto out_unblock_tc_cold; @@ -733,14 +729,13 @@ tgl_tc_phy_cold_off_domain(struct intel_tc_port *tc) static void tgl_tc_phy_init(struct intel_tc_port *tc) { struct intel_display *display = to_intel_display(tc->dig_port); - struct drm_i915_private *i915 = tc_to_i915(tc); intel_wakeref_t wakeref; u32 val; with_intel_display_power(display, tc_phy_cold_off_domain(tc), wakeref) - val = intel_de_read(i915, PORT_TX_DFLEXDPSP(FIA1)); + val = intel_de_read(display, PORT_TX_DFLEXDPSP(FIA1)); - drm_WARN_ON(&i915->drm, val == 0xffffffff); + drm_WARN_ON(display->drm, val == 0xffffffff); tc_phy_load_fia_params(tc, val & MODULAR_FIA_MASK); } @@ -775,19 +770,18 @@ adlp_tc_phy_cold_off_domain(struct intel_tc_port *tc) static u32 adlp_tc_phy_hpd_live_status(struct intel_tc_port *tc) { struct intel_display *display = to_intel_display(tc->dig_port); - struct drm_i915_private *i915 = tc_to_i915(tc); struct intel_digital_port *dig_port = tc->dig_port; enum hpd_pin hpd_pin = dig_port->base.hpd_pin; - u32 cpu_isr_bits = i915->display.hotplug.hpd[hpd_pin]; - u32 pch_isr_bit = i915->display.hotplug.pch_hpd[hpd_pin]; + u32 cpu_isr_bits = display->hotplug.hpd[hpd_pin]; + u32 pch_isr_bit = display->hotplug.pch_hpd[hpd_pin]; intel_wakeref_t wakeref; u32 cpu_isr; u32 pch_isr; u32 mask = 0; with_intel_display_power(display, POWER_DOMAIN_DISPLAY_CORE, wakeref) { - cpu_isr = intel_de_read(i915, GEN11_DE_HPD_ISR); - pch_isr = intel_de_read(i915, SDEISR); + cpu_isr = intel_de_read(display, GEN11_DE_HPD_ISR); + pch_isr = intel_de_read(display, SDEISR); } if (cpu_isr & (cpu_isr_bits & GEN11_DE_TC_HOTPLUG_MASK)) @@ -810,15 +804,15 @@ static u32 adlp_tc_phy_hpd_live_status(struct intel_tc_port *tc) */ static bool adlp_tc_phy_is_ready(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); enum tc_port tc_port = intel_encoder_to_tc(&tc->dig_port->base); u32 val; assert_display_core_power_enabled(tc); - val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port)); + val = intel_de_read(display, TCSS_DDI_STATUS(tc_port)); if (val == 0xffffffff) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Port %s: PHY in TCCOLD, assuming not ready\n", tc->port_name); return false; @@ -830,12 +824,12 @@ static bool adlp_tc_phy_is_ready(struct intel_tc_port *tc) static bool adlp_tc_phy_take_ownership(struct intel_tc_port *tc, bool take) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); enum port port = tc->dig_port->base.port; assert_tc_port_power_enabled(tc); - intel_de_rmw(i915, DDI_BUF_CTL(port), DDI_BUF_CTL_TC_PHY_OWNERSHIP, + intel_de_rmw(display, DDI_BUF_CTL(port), DDI_BUF_CTL_TC_PHY_OWNERSHIP, take ? DDI_BUF_CTL_TC_PHY_OWNERSHIP : 0); return true; @@ -843,13 +837,13 @@ static bool adlp_tc_phy_take_ownership(struct intel_tc_port *tc, static bool adlp_tc_phy_is_owned(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); enum port port = tc->dig_port->base.port; u32 val; assert_tc_port_power_enabled(tc); - val = intel_de_read(i915, DDI_BUF_CTL(port)); + val = intel_de_read(display, DDI_BUF_CTL(port)); return val & DDI_BUF_CTL_TC_PHY_OWNERSHIP; } @@ -872,7 +866,6 @@ static void adlp_tc_phy_get_hw_state(struct intel_tc_port *tc) static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes) { struct intel_display *display = to_intel_display(tc->dig_port); - struct drm_i915_private *i915 = tc_to_i915(tc); enum intel_display_power_domain port_power_domain = tc_port_power_domain(tc); intel_wakeref_t port_wakeref; @@ -885,15 +878,15 @@ static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes) port_wakeref = intel_display_power_get(display, port_power_domain); if (!adlp_tc_phy_take_ownership(tc, true) && - !drm_WARN_ON(&i915->drm, tc->mode == TC_PORT_LEGACY)) { - drm_dbg_kms(&i915->drm, "Port %s: can't take PHY ownership\n", + !drm_WARN_ON(display->drm, tc->mode == TC_PORT_LEGACY)) { + drm_dbg_kms(display->drm, "Port %s: can't take PHY ownership\n", tc->port_name); goto out_put_port_power; } if (!tc_phy_is_ready(tc) && - !drm_WARN_ON(&i915->drm, tc->mode == TC_PORT_LEGACY)) { - drm_dbg_kms(&i915->drm, "Port %s: PHY not ready\n", + !drm_WARN_ON(display->drm, tc->mode == TC_PORT_LEGACY)) { + drm_dbg_kms(display->drm, "Port %s: PHY not ready\n", tc->port_name); goto out_release_phy; } @@ -965,19 +958,18 @@ static const struct intel_tc_phy_ops adlp_tc_phy_ops = { static u32 xelpdp_tc_phy_hpd_live_status(struct intel_tc_port *tc) { struct intel_display *display = to_intel_display(tc->dig_port); - struct drm_i915_private *i915 = tc_to_i915(tc); struct intel_digital_port *dig_port = tc->dig_port; enum hpd_pin hpd_pin = dig_port->base.hpd_pin; - u32 pica_isr_bits = i915->display.hotplug.hpd[hpd_pin]; - u32 pch_isr_bit = i915->display.hotplug.pch_hpd[hpd_pin]; + u32 pica_isr_bits = display->hotplug.hpd[hpd_pin]; + u32 pch_isr_bit = display->hotplug.pch_hpd[hpd_pin]; intel_wakeref_t wakeref; u32 pica_isr; u32 pch_isr; u32 mask = 0; with_intel_display_power(display, POWER_DOMAIN_DISPLAY_CORE, wakeref) { - pica_isr = intel_de_read(i915, PICAINTERRUPT_ISR); - pch_isr = intel_de_read(i915, SDEISR); + pica_isr = intel_de_read(display, PICAINTERRUPT_ISR); + pch_isr = intel_de_read(display, SDEISR); } if (pica_isr & (pica_isr_bits & XELPDP_DP_ALT_HOTPLUG_MASK)) @@ -994,22 +986,22 @@ static u32 xelpdp_tc_phy_hpd_live_status(struct intel_tc_port *tc) static bool xelpdp_tc_phy_tcss_power_is_enabled(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); enum port port = tc->dig_port->base.port; - i915_reg_t reg = XELPDP_PORT_BUF_CTL1(i915, port); + i915_reg_t reg = XELPDP_PORT_BUF_CTL1(display, port); assert_tc_cold_blocked(tc); - return intel_de_read(i915, reg) & XELPDP_TCSS_POWER_STATE; + return intel_de_read(display, reg) & XELPDP_TCSS_POWER_STATE; } static bool xelpdp_tc_phy_wait_for_tcss_power(struct intel_tc_port *tc, bool enabled) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); if (wait_for(xelpdp_tc_phy_tcss_power_is_enabled(tc) == enabled, 5)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Port %s: timeout waiting for TCSS power to get %s\n", str_enabled_disabled(enabled), tc->port_name); @@ -1069,7 +1061,7 @@ static void __xelpdp_tc_phy_enable_tcss_power(struct intel_tc_port *tc, bool ena static bool xelpdp_tc_phy_enable_tcss_power(struct intel_tc_port *tc, bool enable) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); __xelpdp_tc_phy_enable_tcss_power(tc, enable); @@ -1082,7 +1074,7 @@ static bool xelpdp_tc_phy_enable_tcss_power(struct intel_tc_port *tc, bool enabl return true; out_disable: - if (drm_WARN_ON(&i915->drm, tc->mode == TC_PORT_LEGACY)) + if (drm_WARN_ON(display->drm, tc->mode == TC_PORT_LEGACY)) return false; if (!enable) @@ -1096,35 +1088,35 @@ out_disable: static void xelpdp_tc_phy_take_ownership(struct intel_tc_port *tc, bool take) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); enum port port = tc->dig_port->base.port; - i915_reg_t reg = XELPDP_PORT_BUF_CTL1(i915, port); + i915_reg_t reg = XELPDP_PORT_BUF_CTL1(display, port); u32 val; assert_tc_cold_blocked(tc); - val = intel_de_read(i915, reg); + val = intel_de_read(display, reg); if (take) val |= XELPDP_TC_PHY_OWNERSHIP; else val &= ~XELPDP_TC_PHY_OWNERSHIP; - intel_de_write(i915, reg, val); + intel_de_write(display, reg, val); } static bool xelpdp_tc_phy_is_owned(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); enum port port = tc->dig_port->base.port; - i915_reg_t reg = XELPDP_PORT_BUF_CTL1(i915, port); + i915_reg_t reg = XELPDP_PORT_BUF_CTL1(display, port); assert_tc_cold_blocked(tc); - return intel_de_read(i915, reg) & XELPDP_TC_PHY_OWNERSHIP; + return intel_de_read(display, reg) & XELPDP_TC_PHY_OWNERSHIP; } static void xelpdp_tc_phy_get_hw_state(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); intel_wakeref_t tc_cold_wref; enum intel_display_power_domain domain; @@ -1134,7 +1126,7 @@ static void xelpdp_tc_phy_get_hw_state(struct intel_tc_port *tc) if (tc->mode != TC_PORT_DISCONNECTED) tc->lock_wakeref = tc_cold_block(tc); - drm_WARN_ON(&i915->drm, + drm_WARN_ON(display->drm, (tc->mode == TC_PORT_DP_ALT || tc->mode == TC_PORT_LEGACY) && !xelpdp_tc_phy_tcss_power_is_enabled(tc)); @@ -1207,13 +1199,13 @@ tc_phy_cold_off_domain(struct intel_tc_port *tc) static u32 tc_phy_hpd_live_status(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); u32 mask; mask = tc->phy_ops->hpd_live_status(tc); /* The sink can be connected only in a single mode. */ - drm_WARN_ON_ONCE(&i915->drm, hweight32(mask) > 1); + drm_WARN_ON_ONCE(display->drm, hweight32(mask) > 1); return mask; } @@ -1236,9 +1228,9 @@ static void tc_phy_get_hw_state(struct intel_tc_port *tc) static bool tc_phy_is_ready_and_owned(struct intel_tc_port *tc, bool phy_is_ready, bool phy_is_owned) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); - drm_WARN_ON(&i915->drm, phy_is_owned && !phy_is_ready); + drm_WARN_ON(display->drm, phy_is_owned && !phy_is_ready); return phy_is_ready && phy_is_owned; } @@ -1246,8 +1238,7 @@ static bool tc_phy_is_ready_and_owned(struct intel_tc_port *tc, static bool tc_phy_is_connected(struct intel_tc_port *tc, enum icl_port_dpll_id port_pll_type) { - struct intel_encoder *encoder = &tc->dig_port->base; - struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(tc->dig_port); bool phy_is_ready = tc_phy_is_ready(tc); bool phy_is_owned = tc_phy_is_owned(tc); bool is_connected; @@ -1257,7 +1248,7 @@ static bool tc_phy_is_connected(struct intel_tc_port *tc, else is_connected = port_pll_type == ICL_PORT_DPLL_DEFAULT; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Port %s: PHY connected: %s (ready: %s, owned: %s, pll_type: %s)\n", tc->port_name, str_yes_no(is_connected), @@ -1270,10 +1261,10 @@ static bool tc_phy_is_connected(struct intel_tc_port *tc, static bool tc_phy_wait_for_ready(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); if (wait_for(tc_phy_is_ready(tc), 500)) { - drm_err(&i915->drm, "Port %s: timeout waiting for PHY ready\n", + drm_err(display->drm, "Port %s: timeout waiting for PHY ready\n", tc->port_name); return false; @@ -1343,7 +1334,7 @@ get_tc_mode_in_phy_not_owned_state(struct intel_tc_port *tc, static enum tc_port_mode tc_phy_get_current_mode(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); enum tc_port_mode live_mode = tc_phy_hpd_live_mode(tc); bool phy_is_ready; bool phy_is_owned; @@ -1363,11 +1354,11 @@ tc_phy_get_current_mode(struct intel_tc_port *tc) if (!tc_phy_is_ready_and_owned(tc, phy_is_ready, phy_is_owned)) { mode = get_tc_mode_in_phy_not_owned_state(tc, live_mode); } else { - drm_WARN_ON(&i915->drm, live_mode == TC_PORT_TBT_ALT); + drm_WARN_ON(display->drm, live_mode == TC_PORT_TBT_ALT); mode = get_tc_mode_in_phy_owned_state(tc, live_mode); } - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Port %s: PHY mode: %s (ready: %s, owned: %s, HPD: %s)\n", tc->port_name, tc_port_mode_name(mode), @@ -1407,7 +1398,7 @@ tc_phy_get_target_mode(struct intel_tc_port *tc) static void tc_phy_connect(struct intel_tc_port *tc, int required_lanes) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); u32 live_status_mask = tc_phy_hpd_live_status(tc); bool connected; @@ -1421,7 +1412,7 @@ static void tc_phy_connect(struct intel_tc_port *tc, int required_lanes) connected = tc->phy_ops->connect(tc, required_lanes); } - drm_WARN_ON(&i915->drm, !connected); + drm_WARN_ON(display->drm, !connected); } static void tc_phy_disconnect(struct intel_tc_port *tc) @@ -1491,12 +1482,12 @@ static void __intel_tc_port_put_link(struct intel_tc_port *tc) static bool tc_port_is_enabled(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); struct intel_digital_port *dig_port = tc->dig_port; assert_tc_port_power_enabled(tc); - return intel_de_read(i915, DDI_BUF_CTL(dig_port->base.port)) & + return intel_de_read(display, DDI_BUF_CTL(dig_port->base.port)) & DDI_BUF_CTL_ENABLE; } @@ -1509,15 +1500,15 @@ static bool tc_port_is_enabled(struct intel_tc_port *tc) */ void intel_tc_port_init_mode(struct intel_digital_port *dig_port) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); struct intel_tc_port *tc = to_tc_port(dig_port); bool update_mode = false; mutex_lock(&tc->lock); - drm_WARN_ON(&i915->drm, tc->mode != TC_PORT_DISCONNECTED); - drm_WARN_ON(&i915->drm, tc->lock_wakeref); - drm_WARN_ON(&i915->drm, tc->link_refcount); + drm_WARN_ON(display->drm, tc->mode != TC_PORT_DISCONNECTED); + drm_WARN_ON(display->drm, tc->lock_wakeref); + drm_WARN_ON(display->drm, tc->link_refcount); tc_phy_get_hw_state(tc); /* @@ -1540,8 +1531,8 @@ void intel_tc_port_init_mode(struct intel_digital_port *dig_port) if (!tc_port_is_enabled(tc)) { update_mode = true; } else if (tc->mode == TC_PORT_DISCONNECTED) { - drm_WARN_ON(&i915->drm, !tc->legacy_port); - drm_err(&i915->drm, + drm_WARN_ON(display->drm, !tc->legacy_port); + drm_err(display->drm, "Port %s: PHY disconnected on enabled port, connecting it\n", tc->port_name); update_mode = true; @@ -1556,28 +1547,28 @@ void intel_tc_port_init_mode(struct intel_digital_port *dig_port) mutex_unlock(&tc->lock); } -static bool tc_port_has_active_links(struct intel_tc_port *tc, - const struct intel_crtc_state *crtc_state) +static bool tc_port_has_active_streams(struct intel_tc_port *tc, + const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); struct intel_digital_port *dig_port = tc->dig_port; enum icl_port_dpll_id pll_type = ICL_PORT_DPLL_DEFAULT; - int active_links = 0; + int active_streams = 0; if (dig_port->dp.is_mst) { /* TODO: get the PLL type for MST, once HW readout is done for it. */ - active_links = intel_dp_mst_encoder_active_links(dig_port); + active_streams = intel_dp_mst_active_streams(&dig_port->dp); } else if (crtc_state && crtc_state->hw.active) { pll_type = intel_ddi_port_pll_type(&dig_port->base, crtc_state); - active_links = 1; + active_streams = 1; } - if (active_links && !tc_phy_is_connected(tc, pll_type)) - drm_err(&i915->drm, - "Port %s: PHY disconnected with %d active link(s)\n", - tc->port_name, active_links); + if (active_streams && !tc_phy_is_connected(tc, pll_type)) + drm_err(display->drm, + "Port %s: PHY disconnected with %d active stream(s)\n", + tc->port_name, active_streams); - return active_links; + return active_streams; } /** @@ -1595,13 +1586,13 @@ static bool tc_port_has_active_links(struct intel_tc_port *tc, void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); struct intel_tc_port *tc = to_tc_port(dig_port); mutex_lock(&tc->lock); - drm_WARN_ON(&i915->drm, tc->link_refcount != 1); - if (!tc_port_has_active_links(tc, crtc_state)) { + drm_WARN_ON(display->drm, tc->link_refcount != 1); + if (!tc_port_has_active_streams(tc, crtc_state)) { /* * TBT-alt is the default mode in any case the PHY ownership is not * held (regardless of the sink's connected live state), so @@ -1610,7 +1601,7 @@ void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port, */ if (tc->init_mode != TC_PORT_TBT_ALT && tc->init_mode != TC_PORT_DISCONNECTED) - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Port %s: PHY left in %s mode on disabled port, disconnecting it\n", tc->port_name, tc_port_mode_name(tc->init_mode)); @@ -1618,7 +1609,7 @@ void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port, __intel_tc_port_put_link(tc); } - drm_dbg_kms(&i915->drm, "Port %s: sanitize mode (%s)\n", + drm_dbg_kms(display->drm, "Port %s: sanitize mode (%s)\n", tc->port_name, tc_port_mode_name(tc->mode)); @@ -1637,12 +1628,12 @@ void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port, */ bool intel_tc_port_connected(struct intel_encoder *encoder) { + struct intel_display *display = to_intel_display(encoder); struct intel_digital_port *dig_port = enc_to_dig_port(encoder); - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct intel_tc_port *tc = to_tc_port(dig_port); u32 mask = ~0; - drm_WARN_ON(&i915->drm, !intel_tc_port_ref_held(dig_port)); + drm_WARN_ON(display->drm, !intel_tc_port_ref_held(dig_port)); if (tc->mode != TC_PORT_DISCONNECTED) mask = BIT(tc->mode); @@ -1677,14 +1668,14 @@ static int reset_link_commit(struct intel_tc_port *tc, struct intel_atomic_state *state, struct drm_modeset_acquire_ctx *ctx) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); struct intel_digital_port *dig_port = tc->dig_port; struct intel_dp *intel_dp = enc_to_intel_dp(&dig_port->base); struct intel_crtc *crtc; u8 pipe_mask; int ret; - ret = drm_modeset_lock(&i915->drm.mode_config.connection_mutex, ctx); + ret = drm_modeset_lock(&display->drm->mode_config.connection_mutex, ctx); if (ret) return ret; @@ -1695,7 +1686,7 @@ static int reset_link_commit(struct intel_tc_port *tc, if (!pipe_mask) return 0; - for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, pipe_mask) { + for_each_intel_crtc_in_pipe_mask(display->drm, crtc, pipe_mask) { struct intel_crtc_state *crtc_state; crtc_state = intel_atomic_get_crtc_state(&state->base, crtc); @@ -1713,13 +1704,13 @@ static int reset_link_commit(struct intel_tc_port *tc, static int reset_link(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); struct drm_modeset_acquire_ctx ctx; struct drm_atomic_state *_state; struct intel_atomic_state *state; int ret; - _state = drm_atomic_state_alloc(&i915->drm); + _state = drm_atomic_state_alloc(display->drm); if (!_state) return -ENOMEM; @@ -1738,21 +1729,21 @@ static void intel_tc_port_link_reset_work(struct work_struct *work) { struct intel_tc_port *tc = container_of(work, struct intel_tc_port, link_reset_work.work); - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); int ret; if (!__intel_tc_port_link_needs_reset(tc)) return; - mutex_lock(&i915->drm.mode_config.mutex); + mutex_lock(&display->drm->mode_config.mutex); - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Port %s: TypeC DP-alt sink disconnected, resetting link\n", tc->port_name); ret = reset_link(tc); - drm_WARN_ON(&i915->drm, ret); + drm_WARN_ON(display->drm, ret); - mutex_unlock(&i915->drm.mode_config.mutex); + mutex_unlock(&display->drm->mode_config.mutex); } bool intel_tc_port_link_reset(struct intel_digital_port *dig_port) @@ -1780,7 +1771,7 @@ void intel_tc_port_link_cancel_reset_work(struct intel_digital_port *dig_port) static void __intel_tc_port_lock(struct intel_tc_port *tc, int required_lanes) { - struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_display *display = to_intel_display(tc->dig_port); mutex_lock(&tc->lock); @@ -1790,9 +1781,8 @@ static void __intel_tc_port_lock(struct intel_tc_port *tc, intel_tc_port_update_mode(tc, required_lanes, false); - drm_WARN_ON(&i915->drm, tc->mode == TC_PORT_DISCONNECTED); - drm_WARN_ON(&i915->drm, tc->mode != TC_PORT_TBT_ALT && - !tc_phy_is_owned(tc)); + drm_WARN_ON(display->drm, tc->mode == TC_PORT_DISCONNECTED); + drm_WARN_ON(display->drm, tc->mode != TC_PORT_TBT_ALT && !tc_phy_is_owned(tc)); } void intel_tc_port_lock(struct intel_digital_port *dig_port) @@ -1885,12 +1875,12 @@ void intel_tc_port_put_link(struct intel_digital_port *dig_port) int intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); struct intel_tc_port *tc; enum port port = dig_port->base.port; enum tc_port tc_port = intel_encoder_to_tc(&dig_port->base); - if (drm_WARN_ON(&i915->drm, tc_port == TC_PORT_NONE)) + if (drm_WARN_ON(display->drm, tc_port == TC_PORT_NONE)) return -EINVAL; tc = kzalloc(sizeof(*tc), GFP_KERNEL); @@ -1900,11 +1890,11 @@ int intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) dig_port->tc = tc; tc->dig_port = dig_port; - if (DISPLAY_VER(i915) >= 14) + if (DISPLAY_VER(display) >= 14) tc->phy_ops = &xelpdp_tc_phy_ops; - else if (DISPLAY_VER(i915) >= 13) + else if (DISPLAY_VER(display) >= 13) tc->phy_ops = &adlp_tc_phy_ops; - else if (DISPLAY_VER(i915) >= 12) + else if (DISPLAY_VER(display) >= 12) tc->phy_ops = &tgl_tc_phy_ops; else tc->phy_ops = &icl_tc_phy_ops; diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c index 5dbe857ea85b..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); - i915_disable_pipestat(dev_priv, 0, + 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); - i915_enable_pipestat(dev_priv, 0, + 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_vblank.c b/drivers/gpu/drm/i915/display/intel_vblank.c index 7b240ce681a0..139fa5deba80 100644 --- a/drivers/gpu/drm/i915/display/intel_vblank.c +++ b/drivers/gpu/drm/i915/display/intel_vblank.c @@ -224,12 +224,13 @@ int intel_crtc_scanline_offset(const struct intel_crtc_state *crtc_state) */ if (DISPLAY_VER(display) >= 20 || display->platform.battlemage) return 1; - else if (DISPLAY_VER(display) == 2) - return -1; - else if (HAS_DDI(display) && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) - return 2; - else + else if (DISPLAY_VER(display) >= 9 || + display->platform.broadwell || display->platform.haswell) + return intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) ? 2 : 1; + else if (DISPLAY_VER(display) >= 3) return 1; + else + return -1; } /* diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index 3ed64c17bdff..8e799e225af1 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -9,6 +9,7 @@ #include <drm/display/drm_dsc_helper.h> #include <drm/drm_fixed.h> +#include <drm/drm_print.h> #include "i915_utils.h" #include "intel_crtc.h" @@ -259,6 +260,15 @@ static int intel_dsc_slice_dimensions_valid(struct intel_crtc_state *pipe_config return 0; } +static bool is_dsi_dsc_1_1(struct intel_crtc_state *crtc_state) +{ + struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config; + + return vdsc_cfg->dsc_version_major == 1 && + vdsc_cfg->dsc_version_minor == 1 && + intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI); +} + int intel_dsc_compute_params(struct intel_crtc_state *pipe_config) { struct intel_display *display = to_intel_display(pipe_config); @@ -317,8 +327,19 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config) * From XE_LPD onwards we supports compression bpps in steps of 1 * upto uncompressed bpp-1, hence add calculations for all the rc * parameters + * + * We don't want to calculate all rc parameters when the panel + * is MIPI DSI and it's using DSC 1.1. The reason being that some + * DSI panels vendors have hardcoded PPS params in the VBT causing + * the parameters sent from the source which are derived through + * interpolation to differ from the params the panel expects. + * This causes a noise in the display. + * Furthermore for DSI panels we are currently using bits_per_pixel + * (compressed bpp) hardcoded from VBT, (unlike other encoders where we + * find the optimum compressed bpp) so dont need to rely on interpolation, + * as we can get the required rc parameters from the tables. */ - if (DISPLAY_VER(display) >= 13) { + if (DISPLAY_VER(display) >= 13 && !is_dsi_dsc_1_1(pipe_config)) { calculate_rc_params(vdsc_cfg); } else { if ((compressed_bpp == 8 || 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 cac49319026d..c6565baf815a 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -4,6 +4,8 @@ * */ +#include <drm/drm_print.h> + #include "i915_reg.h" #include "intel_de.h" #include "intel_display_types.h" @@ -32,6 +34,8 @@ bool intel_vrr_is_capable(struct intel_connector *connector) return false; fallthrough; case DRM_MODE_CONNECTOR_DisplayPort: + if (connector->mst.dp) + return false; intel_dp = intel_attached_dp(connector); if (!drm_dp_sink_can_do_video_without_timing_msa(intel_dp->dpcd)) @@ -182,7 +186,8 @@ is_cmrr_frac_required(struct intel_crtc_state *crtc_state) int calculated_refresh_k, actual_refresh_k, pixel_clock_per_line; struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - if (!HAS_CMRR(display)) + /* Avoid CMRR for now till we have VRR with fixed timings working */ + if (!HAS_CMRR(display) || true) return false; actual_refresh_k = @@ -222,6 +227,121 @@ cmrr_get_vtotal(struct intel_crtc_state *crtc_state, bool video_mode_required) return vtotal; } +static +void intel_vrr_compute_cmrr_timings(struct intel_crtc_state *crtc_state) +{ + crtc_state->cmrr.enable = true; + /* + * TODO: Compute precise target refresh rate to determine + * if video_mode_required should be true. Currently set to + * false due to uncertainty about the precise target + * refresh Rate. + */ + crtc_state->vrr.vmax = cmrr_get_vtotal(crtc_state, false); + crtc_state->vrr.vmin = crtc_state->vrr.vmax; + crtc_state->vrr.flipline = crtc_state->vrr.vmin; + crtc_state->mode_flags |= I915_MODE_FLAG_VRR; +} + +static +void intel_vrr_compute_vrr_timings(struct intel_crtc_state *crtc_state) +{ + crtc_state->vrr.enable = true; + crtc_state->mode_flags |= I915_MODE_FLAG_VRR; +} + +/* + * For fixed refresh rate mode Vmin, Vmax and Flipline all are set to + * Vtotal value. + */ +static +int intel_vrr_fixed_rr_vtotal(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + int crtc_vtotal = crtc_state->hw.adjusted_mode.crtc_vtotal; + + if (DISPLAY_VER(display) >= 13) + return crtc_vtotal; + else + return crtc_vtotal - + intel_vrr_real_vblank_delay(crtc_state); +} + +static +int intel_vrr_fixed_rr_vmax(const struct intel_crtc_state *crtc_state) +{ + return intel_vrr_fixed_rr_vtotal(crtc_state); +} + +static +int intel_vrr_fixed_rr_vmin(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + + return intel_vrr_fixed_rr_vtotal(crtc_state) - + intel_vrr_flipline_offset(display); +} + +static +int intel_vrr_fixed_rr_flipline(const struct intel_crtc_state *crtc_state) +{ + return intel_vrr_fixed_rr_vtotal(crtc_state); +} + +void intel_vrr_set_fixed_rr_timings(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + + if (!intel_vrr_possible(crtc_state)) + return; + + intel_de_write(display, TRANS_VRR_VMIN(display, cpu_transcoder), + intel_vrr_fixed_rr_vmin(crtc_state) - 1); + intel_de_write(display, TRANS_VRR_VMAX(display, cpu_transcoder), + intel_vrr_fixed_rr_vmax(crtc_state) - 1); + intel_de_write(display, TRANS_VRR_FLIPLINE(display, cpu_transcoder), + intel_vrr_fixed_rr_flipline(crtc_state) - 1); +} + +static +void intel_vrr_compute_fixed_rr_timings(struct intel_crtc_state *crtc_state) +{ + /* + * For fixed rr, vmin = vmax = flipline. + * vmin is already set to crtc_vtotal set vmax and flipline the same. + */ + crtc_state->vrr.vmax = crtc_state->hw.adjusted_mode.crtc_vtotal; + crtc_state->vrr.flipline = crtc_state->hw.adjusted_mode.crtc_vtotal; +} + +static +int intel_vrr_compute_vmin(struct intel_crtc_state *crtc_state) +{ + /* + * To make fixed rr and vrr work seamless the guardband/pipeline full + * should be set such that it satisfies both the fixed and variable + * timings. + * For this set the vmin as crtc_vtotal. With this we never need to + * change anything to do with the guardband. + */ + return crtc_state->hw.adjusted_mode.crtc_vtotal; +} + +static +int intel_vrr_compute_vmax(struct intel_connector *connector, + const struct drm_display_mode *adjusted_mode) +{ + const struct drm_display_info *info = &connector->base.display_info; + int vmax; + + vmax = adjusted_mode->crtc_clock * 1000 / + (adjusted_mode->crtc_htotal * info->monitor_range.min_vfreq); + vmax = max_t(int, vmax, adjusted_mode->crtc_vtotal); + + return vmax; +} + void intel_vrr_compute_config(struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) @@ -232,14 +352,9 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, struct intel_dp *intel_dp = intel_attached_dp(connector); bool is_edp = intel_dp_is_edp(intel_dp); struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; - const struct drm_display_info *info = &connector->base.display_info; int vmin, vmax; - /* - * FIXME all joined pipes share the same transcoder. - * Need to account for that during VRR toggle/push/etc. - */ - if (crtc_state->joiner_pipes) + if (!HAS_VRR(display)) return; if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) @@ -247,28 +362,40 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, crtc_state->vrr.in_range = intel_vrr_is_in_range(connector, drm_mode_vrefresh(adjusted_mode)); - if (!crtc_state->vrr.in_range) - return; - - if (HAS_LRR(display)) - crtc_state->update_lrr = true; - vmin = DIV_ROUND_UP(adjusted_mode->crtc_clock * 1000, - adjusted_mode->crtc_htotal * info->monitor_range.max_vfreq); - vmax = adjusted_mode->crtc_clock * 1000 / - (adjusted_mode->crtc_htotal * info->monitor_range.min_vfreq); + /* + * Allow fixed refresh rate with VRR Timing Generator. + * For now set the vrr.in_range to 0, to allow fixed_rr but skip actual + * VRR and LRR. + * #TODO For actual VRR with joiner, we need to figure out how to + * correctly sequence transcoder level stuff vs. pipe level stuff + * in the commit. + */ + if (crtc_state->joiner_pipes) + crtc_state->vrr.in_range = false; - vmin = max_t(int, vmin, adjusted_mode->crtc_vtotal); - vmax = max_t(int, vmax, adjusted_mode->crtc_vtotal); + vmin = intel_vrr_compute_vmin(crtc_state); - if (vmin >= vmax) - return; + if (crtc_state->vrr.in_range) { + if (HAS_LRR(display)) + crtc_state->update_lrr = true; + vmax = intel_vrr_compute_vmax(connector, adjusted_mode); + } else { + vmax = vmin; + } crtc_state->vrr.vmin = vmin; crtc_state->vrr.vmax = vmax; crtc_state->vrr.flipline = crtc_state->vrr.vmin; + if (crtc_state->uapi.vrr_enabled && vmin < vmax) + intel_vrr_compute_vrr_timings(crtc_state); + else if (is_cmrr_frac_required(crtc_state) && is_edp) + intel_vrr_compute_cmrr_timings(crtc_state); + else + intel_vrr_compute_fixed_rr_timings(crtc_state); + /* * flipline determines the min vblank length the hardware will * generate, and on ICL/TGL flipline>=vmin+1, hence we reduce @@ -276,29 +403,6 @@ intel_vrr_compute_config(struct intel_crtc_state *crtc_state, */ crtc_state->vrr.vmin -= intel_vrr_flipline_offset(display); - /* - * When panel is VRR capable and userspace has - * not enabled adaptive sync mode then Fixed Average - * Vtotal mode should be enabled. - */ - if (crtc_state->uapi.vrr_enabled) { - crtc_state->vrr.enable = true; - crtc_state->mode_flags |= I915_MODE_FLAG_VRR; - } else if (is_cmrr_frac_required(crtc_state) && is_edp) { - crtc_state->vrr.enable = true; - crtc_state->cmrr.enable = true; - /* - * TODO: Compute precise target refresh rate to determine - * if video_mode_required should be true. Currently set to - * false due to uncertainty about the precise target - * refresh Rate. - */ - crtc_state->vrr.vmax = cmrr_get_vtotal(crtc_state, false); - crtc_state->vrr.vmin = crtc_state->vrr.vmax; - crtc_state->vrr.flipline = crtc_state->vrr.vmin; - crtc_state->mode_flags |= I915_MODE_FLAG_VRR; - } - if (HAS_AS_SDP(display)) { crtc_state->vrr.vsync_start = (crtc_state->hw.adjusted_mode.crtc_vtotal - @@ -340,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 @@ -380,14 +487,11 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state) lower_32_bits(crtc_state->cmrr.cmrr_n)); } - intel_de_write(display, TRANS_VRR_VMIN(display, cpu_transcoder), - crtc_state->vrr.vmin - 1); - intel_de_write(display, TRANS_VRR_VMAX(display, cpu_transcoder), - crtc_state->vrr.vmax - 1); - intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), - trans_vrr_ctl(crtc_state)); - intel_de_write(display, TRANS_VRR_FLIPLINE(display, cpu_transcoder), - crtc_state->vrr.flipline - 1); + intel_vrr_set_fixed_rr_timings(crtc_state); + + if (!intel_vrr_always_use_vrr_tg(display) && !crtc_state->vrr.enable) + intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), + trans_vrr_ctl(crtc_state)); if (HAS_AS_SDP(display)) intel_de_write(display, @@ -461,6 +565,17 @@ bool intel_vrr_is_push_sent(const struct intel_crtc_state *crtc_state) return intel_de_read(display, TRANS_PUSH(display, cpu_transcoder)) & TRANS_PUSH_SEND; } +bool intel_vrr_always_use_vrr_tg(struct intel_display *display) +{ + if (!HAS_VRR(display)) + return false; + + if (DISPLAY_VER(display) >= 30) + return true; + + return false; +} + void intel_vrr_enable(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); @@ -469,16 +584,25 @@ void intel_vrr_enable(const struct intel_crtc_state *crtc_state) if (!crtc_state->vrr.enable) return; + intel_de_write(display, TRANS_VRR_VMIN(display, cpu_transcoder), + crtc_state->vrr.vmin - 1); + intel_de_write(display, TRANS_VRR_VMAX(display, cpu_transcoder), + crtc_state->vrr.vmax - 1); + intel_de_write(display, TRANS_VRR_FLIPLINE(display, cpu_transcoder), + crtc_state->vrr.flipline - 1); + intel_de_write(display, TRANS_PUSH(display, cpu_transcoder), TRANS_PUSH_EN); - if (crtc_state->cmrr.enable) { - intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), - VRR_CTL_VRR_ENABLE | VRR_CTL_CMRR_ENABLE | - trans_vrr_ctl(crtc_state)); - } else { - intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), - VRR_CTL_VRR_ENABLE | trans_vrr_ctl(crtc_state)); + if (!intel_vrr_always_use_vrr_tg(display)) { + if (crtc_state->cmrr.enable) { + intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), + VRR_CTL_VRR_ENABLE | VRR_CTL_CMRR_ENABLE | + trans_vrr_ctl(crtc_state)); + } else { + intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), + VRR_CTL_VRR_ENABLE | trans_vrr_ctl(crtc_state)); + } } } @@ -490,24 +614,77 @@ void intel_vrr_disable(const struct intel_crtc_state *old_crtc_state) if (!old_crtc_state->vrr.enable) return; + if (!intel_vrr_always_use_vrr_tg(display)) { + intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), + trans_vrr_ctl(old_crtc_state)); + intel_de_wait_for_clear(display, + TRANS_VRR_STATUS(display, cpu_transcoder), + VRR_STATUS_VRR_EN_LIVE, 1000); + intel_de_write(display, TRANS_PUSH(display, cpu_transcoder), 0); + } + + intel_vrr_set_fixed_rr_timings(old_crtc_state); +} + +void intel_vrr_transcoder_enable(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + + if (!HAS_VRR(display)) + return; + + if (!intel_vrr_possible(crtc_state)) + return; + + if (!intel_vrr_always_use_vrr_tg(display)) { + intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), + trans_vrr_ctl(crtc_state)); + return; + } + + intel_de_write(display, TRANS_PUSH(display, cpu_transcoder), + TRANS_PUSH_EN); + intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), - trans_vrr_ctl(old_crtc_state)); - intel_de_wait_for_clear(display, - TRANS_VRR_STATUS(display, cpu_transcoder), + VRR_CTL_VRR_ENABLE | trans_vrr_ctl(crtc_state)); +} + +void intel_vrr_transcoder_disable(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + + if (!HAS_VRR(display)) + return; + + if (!intel_vrr_possible(crtc_state)) + return; + + intel_de_write(display, TRANS_VRR_CTL(display, cpu_transcoder), 0); + + intel_de_wait_for_clear(display, TRANS_VRR_STATUS(display, cpu_transcoder), VRR_STATUS_VRR_EN_LIVE, 1000); intel_de_write(display, TRANS_PUSH(display, cpu_transcoder), 0); } +bool intel_vrr_is_fixed_rr(const struct intel_crtc_state *crtc_state) +{ + return crtc_state->vrr.flipline && + crtc_state->vrr.flipline == crtc_state->vrr.vmax && + crtc_state->vrr.flipline == intel_vrr_vmin_flipline(crtc_state); +} + void intel_vrr_get_config(struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; u32 trans_vrr_ctl, trans_vrr_vsync; + bool vrr_enable; trans_vrr_ctl = intel_de_read(display, TRANS_VRR_CTL(display, cpu_transcoder)); - crtc_state->vrr.enable = trans_vrr_ctl & VRR_CTL_VRR_ENABLE; if (HAS_CMRR(display)) crtc_state->cmrr.enable = (trans_vrr_ctl & VRR_CTL_CMRR_ENABLE); @@ -536,6 +713,16 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) crtc_state->vrr.vmin = intel_de_read(display, TRANS_VRR_VMIN(display, cpu_transcoder)) + 1; + /* + * For platforms that always use VRR Timing Generator, the VTOTAL.Vtotal + * bits are not filled. Since for these platforms TRAN_VMIN is always + * filled with crtc_vtotal, use TRAN_VRR_VMIN to get the vtotal for + * adjusted_mode. + */ + if (intel_vrr_always_use_vrr_tg(display)) + crtc_state->hw.adjusted_mode.crtc_vtotal = + intel_vrr_vmin_vtotal(crtc_state); + if (HAS_AS_SDP(display)) { trans_vrr_vsync = intel_de_read(display, @@ -547,6 +734,18 @@ void intel_vrr_get_config(struct intel_crtc_state *crtc_state) } } + vrr_enable = trans_vrr_ctl & VRR_CTL_VRR_ENABLE; + + if (intel_vrr_always_use_vrr_tg(display)) + crtc_state->vrr.enable = vrr_enable && !intel_vrr_is_fixed_rr(crtc_state); + else + crtc_state->vrr.enable = vrr_enable; + + /* + * #TODO: For Both VRR and CMRR the flag I915_MODE_FLAG_VRR is set for mode_flags. + * Since CMRR is currently disabled, set this flag for VRR for now. + * Need to keep this in mind while re-enabling CMRR. + */ if (crtc_state->vrr.enable) crtc_state->mode_flags |= I915_MODE_FLAG_VRR; } diff --git a/drivers/gpu/drm/i915/display/intel_vrr.h b/drivers/gpu/drm/i915/display/intel_vrr.h index 514822577e8a..38bf9996b883 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.h +++ b/drivers/gpu/drm/i915/display/intel_vrr.h @@ -13,6 +13,7 @@ struct intel_atomic_state; struct intel_connector; struct intel_crtc_state; struct intel_dsb; +struct intel_display; bool intel_vrr_is_capable(struct intel_connector *connector); bool intel_vrr_is_in_range(struct intel_connector *connector, int vrefresh); @@ -35,5 +36,10 @@ int intel_vrr_vmin_vtotal(const struct intel_crtc_state *crtc_state); int intel_vrr_vmax_vblank_start(const struct intel_crtc_state *crtc_state); int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state); int intel_vrr_vblank_delay(const struct intel_crtc_state *crtc_state); +bool intel_vrr_is_fixed_rr(const struct intel_crtc_state *crtc_state); +void intel_vrr_transcoder_enable(const struct intel_crtc_state *crtc_state); +void intel_vrr_transcoder_disable(const struct intel_crtc_state *crtc_state); +void intel_vrr_set_fixed_rr_timings(const struct intel_crtc_state *crtc_state); +bool intel_vrr_always_use_vrr_tg(struct intel_display *display); #endif /* __INTEL_VRR_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_wm.c b/drivers/gpu/drm/i915/display/intel_wm.c index f00f4cfc58e5..bba82e888db2 100644 --- a/drivers/gpu/drm/i915/display/intel_wm.c +++ b/drivers/gpu/drm/i915/display/intel_wm.c @@ -5,15 +5,18 @@ #include <linux/debugfs.h> -#include "i915_drv.h" +#include <drm/drm_file.h> +#include <drm/drm_print.h> + #include "i9xx_wm.h" +#include "intel_display_core.h" #include "intel_display_types.h" #include "intel_wm.h" #include "skl_watermark.h" /** * intel_update_watermarks - update FIFO watermark values based on current modes - * @i915: i915 device + * @display: display device * * Calculate watermark values for the various WM regs based on current mode * and plane configuration. @@ -44,10 +47,10 @@ * We don't use the sprite, so we can ignore that. And on Crestline we have * to set the non-SR watermarks to 8. */ -void intel_update_watermarks(struct drm_i915_private *i915) +void intel_update_watermarks(struct intel_display *display) { - if (i915->display.funcs.wm->update_wm) - i915->display.funcs.wm->update_wm(i915); + if (display->funcs.wm->update_wm) + display->funcs.wm->update_wm(display); } int intel_wm_compute(struct intel_atomic_state *state, @@ -64,10 +67,10 @@ int intel_wm_compute(struct intel_atomic_state *state, bool intel_initial_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); - if (i915->display.funcs.wm->initial_watermarks) { - i915->display.funcs.wm->initial_watermarks(state, crtc); + if (display->funcs.wm->initial_watermarks) { + display->funcs.wm->initial_watermarks(state, crtc); return true; } @@ -77,41 +80,41 @@ bool intel_initial_watermarks(struct intel_atomic_state *state, void intel_atomic_update_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); - if (i915->display.funcs.wm->atomic_update_watermarks) - i915->display.funcs.wm->atomic_update_watermarks(state, crtc); + if (display->funcs.wm->atomic_update_watermarks) + display->funcs.wm->atomic_update_watermarks(state, crtc); } void intel_optimize_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); - if (i915->display.funcs.wm->optimize_watermarks) - i915->display.funcs.wm->optimize_watermarks(state, crtc); + if (display->funcs.wm->optimize_watermarks) + display->funcs.wm->optimize_watermarks(state, crtc); } int intel_compute_global_watermarks(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); - if (i915->display.funcs.wm->compute_global_watermarks) - return i915->display.funcs.wm->compute_global_watermarks(state); + if (display->funcs.wm->compute_global_watermarks) + return display->funcs.wm->compute_global_watermarks(state); return 0; } -void intel_wm_get_hw_state(struct drm_i915_private *i915) +void intel_wm_get_hw_state(struct intel_display *display) { - if (i915->display.funcs.wm->get_hw_state) - return i915->display.funcs.wm->get_hw_state(i915); + if (display->funcs.wm->get_hw_state) + return display->funcs.wm->get_hw_state(display); } -void intel_wm_sanitize(struct drm_i915_private *i915) +void intel_wm_sanitize(struct intel_display *display) { - if (i915->display.funcs.wm->sanitize) - return i915->display.funcs.wm->sanitize(i915); + if (display->funcs.wm->sanitize) + return display->funcs.wm->sanitize(display); } bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state, @@ -137,16 +140,16 @@ bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state, return plane_state->uapi.visible; } -void intel_print_wm_latency(struct drm_i915_private *dev_priv, +void intel_print_wm_latency(struct intel_display *display, const char *name, const u16 wm[]) { int level; - for (level = 0; level < dev_priv->display.wm.num_levels; level++) { + for (level = 0; level < display->wm.num_levels; level++) { unsigned int latency = wm[level]; if (latency == 0) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "%s WM%d latency not provided\n", name, level); continue; @@ -156,43 +159,43 @@ void intel_print_wm_latency(struct drm_i915_private *dev_priv, * - latencies are in us on gen9. * - before then, WM1+ latency values are in 0.5us units */ - if (DISPLAY_VER(dev_priv) >= 9) + if (DISPLAY_VER(display) >= 9) latency *= 10; else if (level > 0) latency *= 5; - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(display->drm, "%s WM%d latency %u (%u.%u usec)\n", name, level, wm[level], latency / 10, latency % 10); } } -void intel_wm_init(struct drm_i915_private *i915) +void intel_wm_init(struct intel_display *display) { - if (DISPLAY_VER(i915) >= 9) - skl_wm_init(i915); + if (DISPLAY_VER(display) >= 9) + skl_wm_init(display); else - i9xx_wm_init(i915); + i9xx_wm_init(display); } static void wm_latency_show(struct seq_file *m, const u16 wm[8]) { - struct drm_i915_private *dev_priv = m->private; + struct intel_display *display = m->private; int level; - drm_modeset_lock_all(&dev_priv->drm); + drm_modeset_lock_all(display->drm); - for (level = 0; level < dev_priv->display.wm.num_levels; level++) { + for (level = 0; level < display->wm.num_levels; level++) { unsigned int latency = wm[level]; /* * - WM1+ latency values in 0.5us units * - latencies are in us on gen9/vlv/chv */ - if (DISPLAY_VER(dev_priv) >= 9 || - IS_VALLEYVIEW(dev_priv) || - IS_CHERRYVIEW(dev_priv) || - IS_G4X(dev_priv)) + if (DISPLAY_VER(display) >= 9 || + display->platform.valleyview || + display->platform.cherryview || + display->platform.g4x) latency *= 10; else if (level > 0) latency *= 5; @@ -201,18 +204,18 @@ static void wm_latency_show(struct seq_file *m, const u16 wm[8]) level, wm[level], latency / 10, latency % 10); } - drm_modeset_unlock_all(&dev_priv->drm); + drm_modeset_unlock_all(display->drm); } static int pri_wm_latency_show(struct seq_file *m, void *data) { - struct drm_i915_private *dev_priv = m->private; + struct intel_display *display = m->private; const u16 *latencies; - if (DISPLAY_VER(dev_priv) >= 9) - latencies = dev_priv->display.wm.skl_latency; + if (DISPLAY_VER(display) >= 9) + latencies = display->wm.skl_latency; else - latencies = dev_priv->display.wm.pri_latency; + latencies = display->wm.pri_latency; wm_latency_show(m, latencies); @@ -221,13 +224,13 @@ static int pri_wm_latency_show(struct seq_file *m, void *data) static int spr_wm_latency_show(struct seq_file *m, void *data) { - struct drm_i915_private *dev_priv = m->private; + struct intel_display *display = m->private; const u16 *latencies; - if (DISPLAY_VER(dev_priv) >= 9) - latencies = dev_priv->display.wm.skl_latency; + if (DISPLAY_VER(display) >= 9) + latencies = display->wm.skl_latency; else - latencies = dev_priv->display.wm.spr_latency; + latencies = display->wm.spr_latency; wm_latency_show(m, latencies); @@ -236,13 +239,13 @@ static int spr_wm_latency_show(struct seq_file *m, void *data) static int cur_wm_latency_show(struct seq_file *m, void *data) { - struct drm_i915_private *dev_priv = m->private; + struct intel_display *display = m->private; const u16 *latencies; - if (DISPLAY_VER(dev_priv) >= 9) - latencies = dev_priv->display.wm.skl_latency; + if (DISPLAY_VER(display) >= 9) + latencies = display->wm.skl_latency; else - latencies = dev_priv->display.wm.cur_latency; + latencies = display->wm.cur_latency; wm_latency_show(m, latencies); @@ -251,39 +254,39 @@ static int cur_wm_latency_show(struct seq_file *m, void *data) static int pri_wm_latency_open(struct inode *inode, struct file *file) { - struct drm_i915_private *dev_priv = inode->i_private; + struct intel_display *display = inode->i_private; - if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) + if (DISPLAY_VER(display) < 5 && !display->platform.g4x) return -ENODEV; - return single_open(file, pri_wm_latency_show, dev_priv); + return single_open(file, pri_wm_latency_show, display); } static int spr_wm_latency_open(struct inode *inode, struct file *file) { - struct drm_i915_private *dev_priv = inode->i_private; + struct intel_display *display = inode->i_private; - if (HAS_GMCH(dev_priv)) + if (HAS_GMCH(display)) return -ENODEV; - return single_open(file, spr_wm_latency_show, dev_priv); + return single_open(file, spr_wm_latency_show, display); } static int cur_wm_latency_open(struct inode *inode, struct file *file) { - struct drm_i915_private *dev_priv = inode->i_private; + struct intel_display *display = inode->i_private; - if (HAS_GMCH(dev_priv)) + if (HAS_GMCH(display)) return -ENODEV; - return single_open(file, cur_wm_latency_show, dev_priv); + return single_open(file, cur_wm_latency_show, display); } static ssize_t wm_latency_write(struct file *file, const char __user *ubuf, size_t len, loff_t *offp, u16 wm[8]) { struct seq_file *m = file->private_data; - struct drm_i915_private *dev_priv = m->private; + struct intel_display *display = m->private; u16 new[8] = {}; int level; int ret; @@ -300,15 +303,15 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf, ret = sscanf(tmp, "%hu %hu %hu %hu %hu %hu %hu %hu", &new[0], &new[1], &new[2], &new[3], &new[4], &new[5], &new[6], &new[7]); - if (ret != dev_priv->display.wm.num_levels) + if (ret != display->wm.num_levels) return -EINVAL; - drm_modeset_lock_all(&dev_priv->drm); + drm_modeset_lock_all(display->drm); - for (level = 0; level < dev_priv->display.wm.num_levels; level++) + for (level = 0; level < display->wm.num_levels; level++) wm[level] = new[level]; - drm_modeset_unlock_all(&dev_priv->drm); + drm_modeset_unlock_all(display->drm); return len; } @@ -317,13 +320,13 @@ static ssize_t pri_wm_latency_write(struct file *file, const char __user *ubuf, size_t len, loff_t *offp) { struct seq_file *m = file->private_data; - struct drm_i915_private *dev_priv = m->private; + struct intel_display *display = m->private; u16 *latencies; - if (DISPLAY_VER(dev_priv) >= 9) - latencies = dev_priv->display.wm.skl_latency; + if (DISPLAY_VER(display) >= 9) + latencies = display->wm.skl_latency; else - latencies = dev_priv->display.wm.pri_latency; + latencies = display->wm.pri_latency; return wm_latency_write(file, ubuf, len, offp, latencies); } @@ -332,13 +335,13 @@ static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf, size_t len, loff_t *offp) { struct seq_file *m = file->private_data; - struct drm_i915_private *dev_priv = m->private; + struct intel_display *display = m->private; u16 *latencies; - if (DISPLAY_VER(dev_priv) >= 9) - latencies = dev_priv->display.wm.skl_latency; + if (DISPLAY_VER(display) >= 9) + latencies = display->wm.skl_latency; else - latencies = dev_priv->display.wm.spr_latency; + latencies = display->wm.spr_latency; return wm_latency_write(file, ubuf, len, offp, latencies); } @@ -347,13 +350,13 @@ static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf, size_t len, loff_t *offp) { struct seq_file *m = file->private_data; - struct drm_i915_private *dev_priv = m->private; + struct intel_display *display = m->private; u16 *latencies; - if (DISPLAY_VER(dev_priv) >= 9) - latencies = dev_priv->display.wm.skl_latency; + if (DISPLAY_VER(display) >= 9) + latencies = display->wm.skl_latency; else - latencies = dev_priv->display.wm.cur_latency; + latencies = display->wm.cur_latency; return wm_latency_write(file, ubuf, len, offp, latencies); } @@ -385,18 +388,18 @@ static const struct file_operations i915_cur_wm_latency_fops = { .write = cur_wm_latency_write }; -void intel_wm_debugfs_register(struct drm_i915_private *i915) +void intel_wm_debugfs_register(struct intel_display *display) { - struct drm_minor *minor = i915->drm.primary; + struct drm_minor *minor = display->drm->primary; debugfs_create_file("i915_pri_wm_latency", 0644, minor->debugfs_root, - i915, &i915_pri_wm_latency_fops); + display, &i915_pri_wm_latency_fops); debugfs_create_file("i915_spr_wm_latency", 0644, minor->debugfs_root, - i915, &i915_spr_wm_latency_fops); + display, &i915_spr_wm_latency_fops); debugfs_create_file("i915_cur_wm_latency", 0644, minor->debugfs_root, - i915, &i915_cur_wm_latency_fops); + display, &i915_cur_wm_latency_fops); - skl_watermark_debugfs_register(i915); + skl_watermark_debugfs_register(display); } diff --git a/drivers/gpu/drm/i915/display/intel_wm.h b/drivers/gpu/drm/i915/display/intel_wm.h index 7d3a447054b3..9ad4e9eae5ca 100644 --- a/drivers/gpu/drm/i915/display/intel_wm.h +++ b/drivers/gpu/drm/i915/display/intel_wm.h @@ -8,13 +8,13 @@ #include <linux/types.h> -struct drm_i915_private; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; +struct intel_display; struct intel_plane_state; -void intel_update_watermarks(struct drm_i915_private *i915); +void intel_update_watermarks(struct intel_display *display); int intel_wm_compute(struct intel_atomic_state *state, struct intel_crtc *crtc); bool intel_initial_watermarks(struct intel_atomic_state *state, @@ -24,13 +24,13 @@ void intel_atomic_update_watermarks(struct intel_atomic_state *state, void intel_optimize_watermarks(struct intel_atomic_state *state, struct intel_crtc *crtc); int intel_compute_global_watermarks(struct intel_atomic_state *state); -void intel_wm_get_hw_state(struct drm_i915_private *i915); -void intel_wm_sanitize(struct drm_i915_private *i915); +void intel_wm_get_hw_state(struct intel_display *display); +void intel_wm_sanitize(struct intel_display *display); bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state); -void intel_print_wm_latency(struct drm_i915_private *i915, +void intel_print_wm_latency(struct intel_display *display, const char *name, const u16 wm[]); -void intel_wm_init(struct drm_i915_private *i915); -void intel_wm_debugfs_register(struct drm_i915_private *i915); +void intel_wm_init(struct intel_display *display); +void intel_wm_debugfs_register(struct intel_display *display); #endif /* __INTEL_WM_H__ */ 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 70e550539bb2..c7b336359a5e 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -601,7 +601,7 @@ static u32 tgl_plane_min_alignment(struct intel_plane *plane, * Figure out what's going on here... */ if (display->platform.alderlake_p && - intel_plane_can_async_flip(plane, fb->modifier)) + intel_plane_can_async_flip(plane, fb->format->format, fb->modifier)) return mult * 16 * 1024; switch (fb->modifier) { @@ -2666,6 +2666,7 @@ static const struct drm_plane_funcs skl_plane_funcs = { .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = skl_plane_format_mod_supported, + .format_mod_supported_async = intel_plane_format_mod_supported_async, }; static const struct drm_plane_funcs icl_plane_funcs = { @@ -2675,6 +2676,7 @@ static const struct drm_plane_funcs icl_plane_funcs = { .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = icl_plane_format_mod_supported, + .format_mod_supported_async = intel_plane_format_mod_supported_async, }; static const struct drm_plane_funcs tgl_plane_funcs = { @@ -2684,28 +2686,29 @@ static const struct drm_plane_funcs tgl_plane_funcs = { .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = tgl_plane_format_mod_supported, + .format_mod_supported_async = intel_plane_format_mod_supported_async, }; static void skl_plane_enable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; - spin_lock_irq(&i915->irq_lock); - bdw_enable_pipe_irq(i915, pipe, GEN9_PIPE_PLANE_FLIP_DONE(plane->id)); - spin_unlock_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(&display->irq.lock); } static void skl_plane_disable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; - spin_lock_irq(&i915->irq_lock); - bdw_disable_pipe_irq(i915, pipe, GEN9_PIPE_PLANE_FLIP_DONE(plane->id)); - spin_unlock_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(&display->irq.lock); } static bool skl_plane_has_rc_ccs(struct intel_display *display, diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 621e97943542..8080f777910a 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -19,6 +19,7 @@ #include "intel_de.h" #include "intel_display.h" #include "intel_display_power.h" +#include "intel_display_rpm.h" #include "intel_display_types.h" #include "intel_fb.h" #include "intel_fixed.h" @@ -34,7 +35,7 @@ */ #define DSB_EXE_TIME 100 -static void skl_sagv_disable(struct drm_i915_private *i915); +static void skl_sagv_disable(struct intel_display *display); /* Stores plane specific WM parameters */ struct skl_wm_params { @@ -69,23 +70,21 @@ u8 intel_enabled_dbuf_slices_mask(struct intel_display *display) * FIXME: We still don't have the proper code detect if we need to apply the WA, * so assume we'll always need it in order to avoid underruns. */ -static bool skl_needs_memory_bw_wa(struct drm_i915_private *i915) +static bool skl_needs_memory_bw_wa(struct intel_display *display) { - return DISPLAY_VER(i915) == 9; + return DISPLAY_VER(display) == 9; } bool -intel_has_sagv(struct drm_i915_private *i915) +intel_has_sagv(struct intel_display *display) { - struct intel_display *display = &i915->display; - return HAS_SAGV(display) && display->sagv.status != I915_SAGV_NOT_CONTROLLED; } static u32 -intel_sagv_block_time(struct drm_i915_private *i915) +intel_sagv_block_time(struct intel_display *display) { - struct intel_display *display = &i915->display; + struct drm_i915_private *i915 = to_i915(display->drm); if (DISPLAY_VER(display) >= 14) { u32 val; @@ -115,10 +114,8 @@ intel_sagv_block_time(struct drm_i915_private *i915) } } -static void intel_sagv_init(struct drm_i915_private *i915) +static void intel_sagv_init(struct intel_display *display) { - struct intel_display *display = &i915->display; - if (!HAS_SAGV(display)) display->sagv.status = I915_SAGV_NOT_CONTROLLED; @@ -127,14 +124,14 @@ static void intel_sagv_init(struct drm_i915_private *i915) * For icl+ this was already determined by intel_bw_init_hw(). */ if (DISPLAY_VER(display) < 11) - skl_sagv_disable(i915); + skl_sagv_disable(display); drm_WARN_ON(display->drm, display->sagv.status == I915_SAGV_UNKNOWN); - display->sagv.block_time_us = intel_sagv_block_time(i915); + display->sagv.block_time_us = intel_sagv_block_time(display); drm_dbg_kms(display->drm, "SAGV supported: %s, original SAGV block time: %u us\n", - str_yes_no(intel_has_sagv(i915)), display->sagv.block_time_us); + str_yes_no(intel_has_sagv(display)), display->sagv.block_time_us); /* avoid overflow when adding with wm0 latency/etc. */ if (drm_WARN(display->drm, display->sagv.block_time_us > U16_MAX, @@ -142,7 +139,7 @@ static void intel_sagv_init(struct drm_i915_private *i915) display->sagv.block_time_us)) display->sagv.block_time_us = 0; - if (!intel_has_sagv(i915)) + if (!intel_has_sagv(display)) display->sagv.block_time_us = 0; } @@ -157,17 +154,18 @@ static void intel_sagv_init(struct drm_i915_private *i915) * - All planes can enable watermarks for latencies >= SAGV engine block time * - We're not using an interlaced display configuration */ -static void skl_sagv_enable(struct drm_i915_private *i915) +static void skl_sagv_enable(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); int ret; - if (!intel_has_sagv(i915)) + if (!intel_has_sagv(display)) return; - if (i915->display.sagv.status == I915_SAGV_ENABLED) + if (display->sagv.status == I915_SAGV_ENABLED) return; - drm_dbg_kms(&i915->drm, "Enabling SAGV\n"); + drm_dbg_kms(display->drm, "Enabling SAGV\n"); ret = snb_pcode_write(&i915->uncore, GEN9_PCODE_SAGV_CONTROL, GEN9_SAGV_ENABLE); @@ -177,29 +175,30 @@ static void skl_sagv_enable(struct drm_i915_private *i915) * Some skl systems, pre-release machines in particular, * don't actually have SAGV. */ - if (IS_SKYLAKE(i915) && ret == -ENXIO) { - drm_dbg(&i915->drm, "No SAGV found on system, ignoring\n"); - i915->display.sagv.status = I915_SAGV_NOT_CONTROLLED; + if (display->platform.skylake && ret == -ENXIO) { + drm_dbg(display->drm, "No SAGV found on system, ignoring\n"); + display->sagv.status = I915_SAGV_NOT_CONTROLLED; return; } else if (ret < 0) { - drm_err(&i915->drm, "Failed to enable SAGV\n"); + drm_err(display->drm, "Failed to enable SAGV\n"); return; } - i915->display.sagv.status = I915_SAGV_ENABLED; + display->sagv.status = I915_SAGV_ENABLED; } -static void skl_sagv_disable(struct drm_i915_private *i915) +static void skl_sagv_disable(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); int ret; - if (!intel_has_sagv(i915)) + if (!intel_has_sagv(display)) return; - if (i915->display.sagv.status == I915_SAGV_DISABLED) + if (display->sagv.status == I915_SAGV_DISABLED) return; - drm_dbg_kms(&i915->drm, "Disabling SAGV\n"); + drm_dbg_kms(display->drm, "Disabling SAGV\n"); /* bspec says to keep retrying for at least 1 ms */ ret = skl_pcode_request(&i915->uncore, GEN9_PCODE_SAGV_CONTROL, GEN9_SAGV_DISABLE, @@ -209,47 +208,47 @@ static void skl_sagv_disable(struct drm_i915_private *i915) * Some skl systems, pre-release machines in particular, * don't actually have SAGV. */ - if (IS_SKYLAKE(i915) && ret == -ENXIO) { - drm_dbg(&i915->drm, "No SAGV found on system, ignoring\n"); - i915->display.sagv.status = I915_SAGV_NOT_CONTROLLED; + if (display->platform.skylake && ret == -ENXIO) { + drm_dbg(display->drm, "No SAGV found on system, ignoring\n"); + display->sagv.status = I915_SAGV_NOT_CONTROLLED; return; } else if (ret < 0) { - drm_err(&i915->drm, "Failed to disable SAGV (%d)\n", ret); + drm_err(display->drm, "Failed to disable SAGV (%d)\n", ret); return; } - i915->display.sagv.status = I915_SAGV_DISABLED; + display->sagv.status = I915_SAGV_DISABLED; } static void skl_sagv_pre_plane_update(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_bw_state *new_bw_state = intel_atomic_get_new_bw_state(state); if (!new_bw_state) return; - if (!intel_can_enable_sagv(i915, new_bw_state)) - skl_sagv_disable(i915); + if (!intel_can_enable_sagv(display, new_bw_state)) + skl_sagv_disable(display); } static void skl_sagv_post_plane_update(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_bw_state *new_bw_state = intel_atomic_get_new_bw_state(state); if (!new_bw_state) return; - if (intel_can_enable_sagv(i915, new_bw_state)) - skl_sagv_enable(i915); + if (intel_can_enable_sagv(display, new_bw_state)) + skl_sagv_enable(display); } static void icl_sagv_pre_plane_update(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_bw_state *old_bw_state = intel_atomic_get_old_bw_state(state); const struct intel_bw_state *new_bw_state = @@ -267,7 +266,7 @@ static void icl_sagv_pre_plane_update(struct intel_atomic_state *state) WARN_ON(!new_bw_state->base.changed); - drm_dbg_kms(&i915->drm, "Restricting QGV points: 0x%x -> 0x%x\n", + drm_dbg_kms(display->drm, "Restricting QGV points: 0x%x -> 0x%x\n", old_mask, new_mask); /* @@ -276,12 +275,12 @@ static void icl_sagv_pre_plane_update(struct intel_atomic_state *state) * time. Also masking should be done before updating the configuration * and unmasking afterwards. */ - icl_pcode_restrict_qgv_points(i915, new_mask); + icl_pcode_restrict_qgv_points(display, new_mask); } static void icl_sagv_post_plane_update(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_bw_state *old_bw_state = intel_atomic_get_old_bw_state(state); const struct intel_bw_state *new_bw_state = @@ -299,7 +298,7 @@ static void icl_sagv_post_plane_update(struct intel_atomic_state *state) WARN_ON(!new_bw_state->base.changed); - drm_dbg_kms(&i915->drm, "Relaxing QGV points: 0x%x -> 0x%x\n", + drm_dbg_kms(display->drm, "Relaxing QGV points: 0x%x -> 0x%x\n", old_mask, new_mask); /* @@ -308,12 +307,12 @@ static void icl_sagv_post_plane_update(struct intel_atomic_state *state) * time. Also masking should be done before updating the configuration * and unmasking afterwards. */ - icl_pcode_restrict_qgv_points(i915, new_mask); + icl_pcode_restrict_qgv_points(display, new_mask); } void intel_sagv_pre_plane_update(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); /* * Just return if we can't control SAGV or don't have it. @@ -322,10 +321,10 @@ void intel_sagv_pre_plane_update(struct intel_atomic_state *state) * disabled in a BIOS, we are not even allowed to send a PCode request, * as it will throw an error. So have to check it here. */ - if (!intel_has_sagv(i915)) + if (!intel_has_sagv(display)) return; - if (DISPLAY_VER(i915) >= 11) + if (DISPLAY_VER(display) >= 11) icl_sagv_pre_plane_update(state); else skl_sagv_pre_plane_update(state); @@ -333,7 +332,7 @@ void intel_sagv_pre_plane_update(struct intel_atomic_state *state) void intel_sagv_post_plane_update(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); /* * Just return if we can't control SAGV or don't have it. @@ -342,10 +341,10 @@ void intel_sagv_post_plane_update(struct intel_atomic_state *state) * disabled in a BIOS, we are not even allowed to send a PCode request, * as it will throw an error. So have to check it here. */ - if (!intel_has_sagv(i915)) + if (!intel_has_sagv(display)) return; - if (DISPLAY_VER(i915) >= 11) + if (DISPLAY_VER(display) >= 11) icl_sagv_post_plane_update(state); else skl_sagv_post_plane_update(state); @@ -353,12 +352,12 @@ void intel_sagv_post_plane_update(struct intel_atomic_state *state) static bool skl_crtc_can_enable_sagv(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); enum plane_id plane_id; int max_level = INT_MAX; - if (!intel_has_sagv(i915)) + if (!intel_has_sagv(display)) return false; if (!crtc_state->hw.active) @@ -377,7 +376,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state) continue; /* Find the highest enabled wm level for this plane */ - for (level = i915->display.wm.num_levels - 1; + for (level = display->wm.num_levels - 1; !wm->wm[level].enable; --level) { } @@ -423,104 +422,37 @@ static bool tgl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state) return true; } -static bool intel_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state) +bool intel_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); - if (!i915->display.params.enable_sagv) + if (!display->params.enable_sagv) return false; - if (DISPLAY_VER(i915) >= 12) + /* + * SAGV is initially forced off because its current + * state can't be queried from pcode. Allow SAGV to + * be enabled upon the first real commit. + */ + if (crtc_state->inherited) + return false; + + if (DISPLAY_VER(display) >= 12) return tgl_crtc_can_enable_sagv(crtc_state); else return skl_crtc_can_enable_sagv(crtc_state); } -bool intel_can_enable_sagv(struct drm_i915_private *i915, +bool intel_can_enable_sagv(struct intel_display *display, const struct intel_bw_state *bw_state) { - if (DISPLAY_VER(i915) < 11 && + if (DISPLAY_VER(display) < 11 && bw_state->active_pipes && !is_power_of_2(bw_state->active_pipes)) return false; return bw_state->pipe_sagv_reject == 0; } -static int intel_compute_sagv_mask(struct intel_atomic_state *state) -{ - struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(state->base.dev); - int ret; - struct intel_crtc *crtc; - struct intel_crtc_state *new_crtc_state; - struct intel_bw_state *new_bw_state = NULL; - const struct intel_bw_state *old_bw_state = NULL; - int i; - - for_each_new_intel_crtc_in_state(state, crtc, - new_crtc_state, i) { - struct skl_pipe_wm *pipe_wm = &new_crtc_state->wm.skl.optimal; - - new_bw_state = intel_atomic_get_bw_state(state); - if (IS_ERR(new_bw_state)) - return PTR_ERR(new_bw_state); - - old_bw_state = intel_atomic_get_old_bw_state(state); - - /* - * We store use_sagv_wm in the crtc state rather than relying on - * that bw state since we have no convenient way to get at the - * latter from the plane commit hooks (especially in the legacy - * cursor case). - * - * drm_atomic_check_only() gets upset if we pull more crtcs - * into the state, so we have to calculate this based on the - * individual intel_crtc_can_enable_sagv() rather than - * the overall intel_can_enable_sagv(). Otherwise the - * crtcs not included in the commit would not switch to the - * SAGV watermarks when we are about to enable SAGV, and that - * would lead to underruns. This does mean extra power draw - * when only a subset of the crtcs are blocking SAGV as the - * other crtcs can't be allowed to use the more optimal - * normal (ie. non-SAGV) watermarks. - */ - pipe_wm->use_sagv_wm = !HAS_HW_SAGV_WM(display) && - DISPLAY_VER(i915) >= 12 && - intel_crtc_can_enable_sagv(new_crtc_state); - - if (intel_crtc_can_enable_sagv(new_crtc_state)) - new_bw_state->pipe_sagv_reject &= ~BIT(crtc->pipe); - else - new_bw_state->pipe_sagv_reject |= BIT(crtc->pipe); - } - - if (!new_bw_state) - return 0; - - new_bw_state->active_pipes = - intel_calc_active_pipes(state, old_bw_state->active_pipes); - - if (new_bw_state->active_pipes != old_bw_state->active_pipes) { - ret = intel_atomic_lock_global_state(&new_bw_state->base); - if (ret) - return ret; - } - - if (intel_can_enable_sagv(i915, new_bw_state) != - intel_can_enable_sagv(i915, old_bw_state)) { - ret = intel_atomic_serialize_global_state(&new_bw_state->base); - if (ret) - return ret; - } else if (new_bw_state->pipe_sagv_reject != old_bw_state->pipe_sagv_reject) { - ret = intel_atomic_lock_global_state(&new_bw_state->base); - if (ret) - return ret; - } - - return 0; -} - static u16 skl_ddb_entry_init(struct skl_ddb_entry *entry, u16 start, u16 end) { @@ -530,17 +462,17 @@ static u16 skl_ddb_entry_init(struct skl_ddb_entry *entry, return end; } -static int intel_dbuf_slice_size(struct drm_i915_private *i915) +static int intel_dbuf_slice_size(struct intel_display *display) { - return DISPLAY_INFO(i915)->dbuf.size / - hweight8(DISPLAY_INFO(i915)->dbuf.slice_mask); + return DISPLAY_INFO(display)->dbuf.size / + hweight8(DISPLAY_INFO(display)->dbuf.slice_mask); } static void -skl_ddb_entry_for_slices(struct drm_i915_private *i915, u8 slice_mask, +skl_ddb_entry_for_slices(struct intel_display *display, u8 slice_mask, struct skl_ddb_entry *ddb) { - int slice_size = intel_dbuf_slice_size(i915); + int slice_size = intel_dbuf_slice_size(display); if (!slice_mask) { ddb->start = 0; @@ -552,10 +484,10 @@ skl_ddb_entry_for_slices(struct drm_i915_private *i915, u8 slice_mask, ddb->end = fls(slice_mask) * slice_size; WARN_ON(ddb->start >= ddb->end); - WARN_ON(ddb->end > DISPLAY_INFO(i915)->dbuf.size); + WARN_ON(ddb->end > DISPLAY_INFO(display)->dbuf.size); } -static unsigned int mbus_ddb_offset(struct drm_i915_private *i915, u8 slice_mask) +static unsigned int mbus_ddb_offset(struct intel_display *display, u8 slice_mask) { struct skl_ddb_entry ddb; @@ -564,15 +496,15 @@ static unsigned int mbus_ddb_offset(struct drm_i915_private *i915, u8 slice_mask else if (slice_mask & (BIT(DBUF_S3) | BIT(DBUF_S4))) slice_mask = BIT(DBUF_S3); - skl_ddb_entry_for_slices(i915, slice_mask, &ddb); + skl_ddb_entry_for_slices(display, slice_mask, &ddb); return ddb.start; } -u32 skl_ddb_dbuf_slice_mask(struct drm_i915_private *i915, +u32 skl_ddb_dbuf_slice_mask(struct intel_display *display, const struct skl_ddb_entry *entry) { - int slice_size = intel_dbuf_slice_size(i915); + int slice_size = intel_dbuf_slice_size(display); enum dbuf_slice start_slice, end_slice; u8 slice_mask = 0; @@ -618,15 +550,14 @@ static void intel_crtc_dbuf_weights(const struct intel_dbuf_state *dbuf_state, unsigned int *weight_end, unsigned int *weight_total) { - struct drm_i915_private *i915 = - to_i915(dbuf_state->base.state->base.dev); + struct intel_display *display = to_intel_display(dbuf_state->base.state->base.dev); enum pipe pipe; *weight_start = 0; *weight_end = 0; *weight_total = 0; - for_each_pipe(i915, pipe) { + for_each_pipe(display, pipe) { int weight = dbuf_state->weight[pipe]; /* @@ -652,7 +583,7 @@ static void intel_crtc_dbuf_weights(const struct intel_dbuf_state *dbuf_state, static int skl_crtc_allocate_ddb(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); unsigned int weight_total, weight_start, weight_end; const struct intel_dbuf_state *old_dbuf_state = intel_atomic_get_old_dbuf_state(state); @@ -674,8 +605,8 @@ skl_crtc_allocate_ddb(struct intel_atomic_state *state, struct intel_crtc *crtc) dbuf_slice_mask = new_dbuf_state->slices[pipe]; - skl_ddb_entry_for_slices(i915, dbuf_slice_mask, &ddb_slices); - mbus_offset = mbus_ddb_offset(i915, dbuf_slice_mask); + skl_ddb_entry_for_slices(display, dbuf_slice_mask, &ddb_slices); + mbus_offset = mbus_ddb_offset(display, dbuf_slice_mask); ddb_range_size = skl_ddb_entry_size(&ddb_slices); intel_crtc_dbuf_weights(new_dbuf_state, pipe, @@ -709,7 +640,7 @@ out: crtc_state->wm.skl.ddb.start = mbus_offset + new_dbuf_state->ddb[pipe].start; crtc_state->wm.skl.ddb.end = mbus_offset + new_dbuf_state->ddb[pipe].end; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[CRTC:%d:%s] dbuf slices 0x%x -> 0x%x, ddb (%d - %d) -> (%d - %d), active pipes 0x%x -> 0x%x\n", crtc->base.base.id, crtc->base.name, old_dbuf_state->slices[pipe], new_dbuf_state->slices[pipe], @@ -734,10 +665,10 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, const struct skl_wm_level *result_prev, struct skl_wm_level *result /* out */); -static unsigned int skl_wm_latency(struct drm_i915_private *i915, int level, +static unsigned int skl_wm_latency(struct intel_display *display, int level, const struct skl_wm_params *wp) { - unsigned int latency = i915->display.wm.skl_latency[level]; + unsigned int latency = display->wm.skl_latency[level]; if (latency == 0) return 0; @@ -746,11 +677,11 @@ static unsigned int skl_wm_latency(struct drm_i915_private *i915, int level, * WaIncreaseLatencyIPCEnabled: kbl,cfl * Display WA #1141: kbl,cfl */ - if ((IS_KABYLAKE(i915) || IS_COFFEELAKE(i915) || IS_COMETLAKE(i915)) && - skl_watermark_ipc_enabled(i915)) + if ((display->platform.kabylake || display->platform.coffeelake || + display->platform.cometlake) && skl_watermark_ipc_enabled(display)) latency += 4; - if (skl_needs_memory_bw_wa(i915) && wp && wp->x_tiled) + if (skl_needs_memory_bw_wa(display) && wp && wp->x_tiled) latency += 15; return latency; @@ -760,8 +691,8 @@ static unsigned int skl_cursor_allocation(const struct intel_crtc_state *crtc_state, int num_active) { + struct intel_display *display = to_intel_display(crtc_state); struct intel_plane *plane = to_intel_plane(crtc_state->uapi.crtc->cursor); - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); struct skl_wm_level wm = {}; int ret, min_ddb_alloc = 0; struct skl_wm_params wp; @@ -772,10 +703,10 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state, DRM_FORMAT_MOD_LINEAR, DRM_MODE_ROTATE_0, crtc_state->pixel_rate, &wp, 0, 0); - drm_WARN_ON(&i915->drm, ret); + drm_WARN_ON(display->drm, ret); - for (level = 0; level < i915->display.wm.num_levels; level++) { - unsigned int latency = skl_wm_latency(i915, level, &wp); + for (level = 0; level < display->wm.num_levels; level++) { + unsigned int latency = skl_wm_latency(display, level, &wp); skl_compute_plane_wm(crtc_state, plane, level, latency, &wp, &wm, &wm); if (wm.min_ddb_alloc == U16_MAX) @@ -797,14 +728,13 @@ static void skl_ddb_entry_init_from_hw(struct skl_ddb_entry *entry, u32 reg) } static void -skl_ddb_get_hw_plane_state(struct drm_i915_private *i915, +skl_ddb_get_hw_plane_state(struct intel_display *display, const enum pipe pipe, const enum plane_id plane_id, struct skl_ddb_entry *ddb, struct skl_ddb_entry *ddb_y, u16 *min_ddb, u16 *interim_ddb) { - struct intel_display *display = &i915->display; u32 val; /* Cursor doesn't support NV12/planar, so no extra calculation needed */ @@ -837,7 +767,6 @@ static void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc, u16 *min_ddb, u16 *interim_ddb) { struct intel_display *display = to_intel_display(crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); enum intel_display_power_domain power_domain; enum pipe pipe = crtc->pipe; intel_wakeref_t wakeref; @@ -849,7 +778,7 @@ static void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc, return; for_each_plane_id_on_crtc(crtc, plane_id) - skl_ddb_get_hw_plane_state(i915, pipe, + skl_ddb_get_hw_plane_state(display, pipe, plane_id, &ddb[plane_id], &ddb_y[plane_id], @@ -1367,16 +1296,16 @@ static u8 dg2_compute_dbuf_slices(enum pipe pipe, u8 active_pipes, bool join_mbu static u8 skl_compute_dbuf_slices(struct intel_crtc *crtc, u8 active_pipes, bool join_mbus) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); enum pipe pipe = crtc->pipe; - if (IS_DG2(i915)) + if (display->platform.dg2) return dg2_compute_dbuf_slices(pipe, active_pipes, join_mbus); - else if (DISPLAY_VER(i915) >= 13) + else if (DISPLAY_VER(display) >= 13) return adlp_compute_dbuf_slices(pipe, active_pipes, join_mbus); - else if (DISPLAY_VER(i915) == 12) + else if (DISPLAY_VER(display) == 12) return tgl_compute_dbuf_slices(pipe, active_pipes, join_mbus); - else if (DISPLAY_VER(i915) == 11) + else if (DISPLAY_VER(display) == 11) return icl_compute_dbuf_slices(pipe, active_pipes, join_mbus); /* * For anything else just return one slice yet. @@ -1416,8 +1345,8 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state, static u64 skl_total_relative_data_rate(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); enum plane_id plane_id; u64 data_rate = 0; @@ -1427,7 +1356,7 @@ skl_total_relative_data_rate(const struct intel_crtc_state *crtc_state) data_rate += crtc_state->rel_data_rate[plane_id]; - if (DISPLAY_VER(i915) < 11) + if (DISPLAY_VER(display) < 11) data_rate += crtc_state->rel_data_rate_y[plane_id]; } @@ -1489,7 +1418,7 @@ skl_check_nv12_wm_level(struct skl_wm_level *wm, struct skl_wm_level *uv_wm, } } -static bool skl_need_wm_copy_wa(struct drm_i915_private *i915, int level, +static bool skl_need_wm_copy_wa(struct intel_display *display, int level, const struct skl_plane_wm *wm) { /* @@ -1543,7 +1472,6 @@ static int skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_dbuf_state *dbuf_state = @@ -1585,7 +1513,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, * Find the highest watermark level for which we can satisfy the block * requirement of active planes. */ - for (level = i915->display.wm.num_levels - 1; level >= 0; level--) { + for (level = display->wm.num_levels - 1; level >= 0; level--) { blocks = 0; for_each_plane_id_on_crtc(crtc, plane_id) { const struct skl_plane_wm *wm = @@ -1596,7 +1524,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, &crtc_state->wm.skl.plane_ddb[plane_id]; if (wm->wm[level].min_ddb_alloc > skl_ddb_entry_size(ddb)) { - drm_WARN_ON(&i915->drm, + drm_WARN_ON(display->drm, wm->wm[level].min_ddb_alloc != U16_MAX); blocks = U32_MAX; break; @@ -1615,9 +1543,9 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, } if (level < 0) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Requested display configuration exceeds system DDB limitations"); - drm_dbg_kms(&i915->drm, "minimum required %d/%d\n", + drm_dbg_kms(display->drm, "minimum required %d/%d\n", blocks, iter.size); return -EINVAL; } @@ -1645,7 +1573,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, if (plane_id == PLANE_CURSOR) continue; - if (DISPLAY_VER(i915) < 11 && + if (DISPLAY_VER(display) < 11 && crtc_state->nv12_planes & BIT(plane_id)) { skl_allocate_plane_ddb(&iter, ddb_y, &wm->wm[level], crtc_state->rel_data_rate_y[plane_id]); @@ -1661,7 +1589,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, *interim_ddb = wm->sagv.wm0.min_ddb_alloc; } } - drm_WARN_ON(&i915->drm, iter.size != 0 || iter.data_rate != 0); + drm_WARN_ON(display->drm, iter.size != 0 || iter.data_rate != 0); /* * When we calculated watermark values we didn't know how high @@ -1669,7 +1597,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, * all levels as "enabled." Go back now and disable the ones * that aren't actually possible. */ - for (level++; level < i915->display.wm.num_levels; level++) { + for (level++; level < display->wm.num_levels; level++) { for_each_plane_id_on_crtc(crtc, plane_id) { const struct skl_ddb_entry *ddb = &crtc_state->wm.skl.plane_ddb[plane_id]; @@ -1678,7 +1606,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id]; - if (DISPLAY_VER(i915) < 11 && + if (DISPLAY_VER(display) < 11 && crtc_state->nv12_planes & BIT(plane_id)) skl_check_nv12_wm_level(&wm->wm[level], &wm->uv_wm[level], @@ -1686,7 +1614,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, else skl_check_wm_level(&wm->wm[level], ddb); - if (skl_need_wm_copy_wa(i915, level, wm)) { + if (skl_need_wm_copy_wa(display, level, wm)) { wm->wm[level].blocks = wm->wm[level - 1].blocks; wm->wm[level].lines = wm->wm[level - 1].lines; wm->wm[level].ignore_lines = wm->wm[level - 1].ignore_lines; @@ -1708,7 +1636,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, struct skl_plane_wm *wm = &crtc_state->wm.skl.optimal.planes[plane_id]; - if (DISPLAY_VER(i915) < 11 && + if (DISPLAY_VER(display) < 11 && crtc_state->nv12_planes & BIT(plane_id)) { skl_check_wm_level(&wm->trans_wm, ddb_y); } else { @@ -1734,7 +1662,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, * 2xcdclk is 1350 MHz and the pixel rate should never exceed that. */ static uint_fixed_16_16_t -skl_wm_method1(const struct drm_i915_private *i915, u32 pixel_rate, +skl_wm_method1(struct intel_display *display, u32 pixel_rate, u8 cpp, u32 latency, u32 dbuf_block_size) { u32 wm_intermediate_val; @@ -1746,7 +1674,7 @@ skl_wm_method1(const struct drm_i915_private *i915, u32 pixel_rate, wm_intermediate_val = latency * pixel_rate * cpp; ret = div_fixed16(wm_intermediate_val, 1000 * dbuf_block_size); - if (DISPLAY_VER(i915) >= 10) + if (DISPLAY_VER(display) >= 10) ret = add_fixed16_u32(ret, 1); return ret; @@ -1772,7 +1700,7 @@ skl_wm_method2(u32 pixel_rate, u32 pipe_htotal, u32 latency, static uint_fixed_16_16_t intel_get_linetime_us(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); u32 pixel_rate; u32 crtc_htotal; uint_fixed_16_16_t linetime_us; @@ -1782,7 +1710,7 @@ intel_get_linetime_us(const struct intel_crtc_state *crtc_state) pixel_rate = crtc_state->pixel_rate; - if (drm_WARN_ON(&i915->drm, pixel_rate == 0)) + if (drm_WARN_ON(display->drm, pixel_rate == 0)) return u32_to_fixed16(0); crtc_htotal = crtc_state->hw.pipe_mode.crtc_htotal; @@ -1798,15 +1726,13 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state, u32 plane_pixel_rate, struct skl_wm_params *wp, int color_plane, unsigned int pan_x) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct intel_display *display = to_intel_display(crtc_state); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); u32 interm_pbpl; /* only planar format has two planes */ if (color_plane == 1 && !intel_format_info_is_yuv_semiplanar(format, modifier)) { - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Non planar format have single plane\n"); return -EINVAL; } @@ -1824,7 +1750,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state, wp->cpp = format->cpp[color_plane]; wp->plane_pixel_rate = plane_pixel_rate; - if (DISPLAY_VER(i915) >= 11 && + if (DISPLAY_VER(display) >= 11 && modifier == I915_FORMAT_MOD_Yf_TILED && wp->cpp == 1) wp->dbuf_block_size = 256; else @@ -1849,7 +1775,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state, wp->y_min_scanlines = 4; } - if (skl_needs_memory_bw_wa(i915)) + if (skl_needs_memory_bw_wa(display)) wp->y_min_scanlines *= 2; wp->plane_bytes_per_line = wp->width * wp->cpp; @@ -1860,7 +1786,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state, if (DISPLAY_VER(display) >= 30) interm_pbpl += (pan_x != 0); - else if (DISPLAY_VER(i915) >= 10) + else if (DISPLAY_VER(display) >= 10) interm_pbpl++; wp->plane_blocks_per_line = div_fixed16(interm_pbpl, @@ -1869,7 +1795,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state, interm_pbpl = DIV_ROUND_UP(wp->plane_bytes_per_line, wp->dbuf_block_size); - if (!wp->x_tiled || DISPLAY_VER(i915) >= 10) + if (!wp->x_tiled || DISPLAY_VER(display) >= 10) interm_pbpl++; wp->plane_blocks_per_line = u32_to_fixed16(interm_pbpl); @@ -1906,18 +1832,18 @@ skl_compute_plane_wm_params(const struct intel_crtc_state *crtc_state, plane_state->uapi.src.x1); } -static bool skl_wm_has_lines(struct drm_i915_private *i915, int level) +static bool skl_wm_has_lines(struct intel_display *display, int level) { - if (DISPLAY_VER(i915) >= 10) + if (DISPLAY_VER(display) >= 10) return true; /* The number of lines are ignored for the level 0 watermark. */ return level > 0; } -static int skl_wm_max_lines(struct drm_i915_private *i915) +static int skl_wm_max_lines(struct intel_display *display) { - if (DISPLAY_VER(i915) >= 13) + if (DISPLAY_VER(display) >= 13) return 255; else return 31; @@ -1938,7 +1864,7 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, const struct skl_wm_level *result_prev, struct skl_wm_level *result /* out */) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); uint_fixed_16_16_t method1, method2; uint_fixed_16_16_t selected_result; u32 blocks, lines, min_ddb_alloc = 0; @@ -1950,7 +1876,7 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, return; } - method1 = skl_wm_method1(i915, wp->plane_pixel_rate, + method1 = skl_wm_method1(display, wp->plane_pixel_rate, wp->cpp, latency, wp->dbuf_block_size); method2 = skl_wm_method2(wp->plane_pixel_rate, crtc_state->hw.pipe_mode.crtc_htotal, @@ -1965,7 +1891,7 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, (wp->plane_bytes_per_line / wp->dbuf_block_size < 1)) { selected_result = method2; } else if (latency >= wp->linetime_us) { - if (DISPLAY_VER(i915) == 9) + if (DISPLAY_VER(display) == 9) selected_result = min_fixed16(method1, method2); else selected_result = method2; @@ -1975,7 +1901,7 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, } blocks = fixed16_to_u32_round_up(selected_result); - if (DISPLAY_VER(i915) < 30) + if (DISPLAY_VER(display) < 30) blocks++; /* @@ -1994,13 +1920,13 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, * channels' impact on the level 0 memory latency and the relevant * wm calculations. */ - if (skl_wm_has_lines(i915, level)) + if (skl_wm_has_lines(display, level)) blocks = max(blocks, fixed16_to_u32_round_up(wp->plane_blocks_per_line)); lines = div_round_up_fixed16(selected_result, wp->plane_blocks_per_line); - if (DISPLAY_VER(i915) == 9) { + if (DISPLAY_VER(display) == 9) { /* Display WA #1125: skl,bxt,kbl */ if (level == 0 && wp->rc_surface) blocks += fixed16_to_u32_round_up(wp->y_tile_minimum); @@ -2025,7 +1951,7 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, } } - if (DISPLAY_VER(i915) >= 11) { + if (DISPLAY_VER(display) >= 11) { if (wp->y_tiled) { int extra_lines; @@ -2042,10 +1968,10 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, } } - if (!skl_wm_has_lines(i915, level)) + if (!skl_wm_has_lines(display, level)) lines = 0; - if (lines > skl_wm_max_lines(i915)) { + if (lines > skl_wm_max_lines(display)) { /* reject it */ result->min_ddb_alloc = U16_MAX; return; @@ -2064,8 +1990,8 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state, result->enable = true; result->auto_min_alloc_wm_enable = xe3_auto_min_alloc_capable(plane, level); - if (DISPLAY_VER(i915) < 12 && i915->display.sagv.block_time_us) - result->can_sagv = latency >= i915->display.sagv.block_time_us; + if (DISPLAY_VER(display) < 12 && display->sagv.block_time_us) + result->can_sagv = latency >= display->sagv.block_time_us; } static void @@ -2074,13 +2000,13 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state, const struct skl_wm_params *wm_params, struct skl_wm_level *levels) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); struct skl_wm_level *result_prev = &levels[0]; int level; - for (level = 0; level < i915->display.wm.num_levels; level++) { + for (level = 0; level < display->wm.num_levels; level++) { struct skl_wm_level *result = &levels[level]; - unsigned int latency = skl_wm_latency(i915, level, wm_params); + unsigned int latency = skl_wm_latency(display, level, wm_params); skl_compute_plane_wm(crtc_state, plane, level, latency, wm_params, result_prev, result); @@ -2094,21 +2020,21 @@ static void tgl_compute_sagv_wm(const struct intel_crtc_state *crtc_state, const struct skl_wm_params *wm_params, struct skl_plane_wm *plane_wm) { - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); struct skl_wm_level *sagv_wm = &plane_wm->sagv.wm0; struct skl_wm_level *levels = plane_wm->wm; unsigned int latency = 0; - if (i915->display.sagv.block_time_us) - latency = i915->display.sagv.block_time_us + - skl_wm_latency(i915, 0, wm_params); + if (display->sagv.block_time_us) + latency = display->sagv.block_time_us + + skl_wm_latency(display, 0, wm_params); skl_compute_plane_wm(crtc_state, plane, 0, latency, wm_params, &levels[0], sagv_wm); } -static void skl_compute_transition_wm(struct drm_i915_private *i915, +static void skl_compute_transition_wm(struct intel_display *display, struct skl_wm_level *trans_wm, const struct skl_wm_level *wm0, const struct skl_wm_params *wp) @@ -2117,23 +2043,23 @@ static void skl_compute_transition_wm(struct drm_i915_private *i915, u16 wm0_blocks, trans_offset, blocks; /* Transition WM don't make any sense if ipc is disabled */ - if (!skl_watermark_ipc_enabled(i915)) + if (!skl_watermark_ipc_enabled(display)) return; /* * WaDisableTWM:skl,kbl,cfl,bxt * Transition WM are not recommended by HW team for GEN9 */ - if (DISPLAY_VER(i915) == 9) + if (DISPLAY_VER(display) == 9) return; - if (DISPLAY_VER(i915) >= 11) + if (DISPLAY_VER(display) >= 11) trans_min = 4; else trans_min = 14; /* Display WA #1140: glk,cnl */ - if (DISPLAY_VER(i915) == 10) + if (DISPLAY_VER(display) == 10) trans_amount = 0; else trans_amount = 10; /* This is configurable amount */ @@ -2175,8 +2101,7 @@ static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state, struct intel_plane *plane, int color_plane) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); struct skl_plane_wm *wm = &crtc_state->wm.skl.raw.planes[plane->id]; struct skl_wm_params wm_params; int ret; @@ -2188,13 +2113,13 @@ static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state, skl_compute_wm_levels(crtc_state, plane, &wm_params, wm->wm); - skl_compute_transition_wm(i915, &wm->trans_wm, + skl_compute_transition_wm(display, &wm->trans_wm, &wm->wm[0], &wm_params); - if (DISPLAY_VER(i915) >= 12) { + if (DISPLAY_VER(display) >= 12) { tgl_compute_sagv_wm(crtc_state, plane, &wm_params, wm); - skl_compute_transition_wm(i915, &wm->sagv.trans_wm, + skl_compute_transition_wm(display, &wm->sagv.trans_wm, &wm->sagv.wm0, &wm_params); } @@ -2254,8 +2179,8 @@ static int skl_build_plane_wm(struct intel_crtc_state *crtc_state, static int icl_build_plane_wm(struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state) { + struct intel_display *display = to_intel_display(plane_state); struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane); - struct drm_i915_private *i915 = to_i915(plane->base.dev); enum plane_id plane_id = plane->id; struct skl_plane_wm *wm = &crtc_state->wm.skl.raw.planes[plane_id]; int ret; @@ -2269,9 +2194,9 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state, if (plane_state->planar_linked_plane) { const struct drm_framebuffer *fb = plane_state->hw.fb; - drm_WARN_ON(&i915->drm, + drm_WARN_ON(display->drm, !intel_wm_plane_visible(crtc_state, plane_state)); - drm_WARN_ON(&i915->drm, !fb->format->is_yuv || + drm_WARN_ON(display->drm, !fb->format->is_yuv || fb->format->num_planes == 1); ret = skl_build_plane_wm_single(crtc_state, plane_state, @@ -2411,15 +2336,14 @@ static int skl_max_wm0_lines(const struct intel_crtc_state *crtc_state) static int skl_max_wm_level_for_vblank(struct intel_crtc_state *crtc_state, int wm0_lines) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc_state); int level; - for (level = i915->display.wm.num_levels - 1; level >= 0; level--) { + for (level = display->wm.num_levels - 1; level >= 0; level--) { int latency; /* FIXME should we care about the latency w/a's? */ - latency = skl_wm_latency(i915, level, NULL); + latency = skl_wm_latency(display, level, NULL); if (latency == 0) continue; @@ -2436,8 +2360,8 @@ static int skl_max_wm_level_for_vblank(struct intel_crtc_state *crtc_state, static int skl_wm_check_vblank(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); int wm0_lines, level; if (!crtc_state->hw.active) @@ -2453,9 +2377,9 @@ static int skl_wm_check_vblank(struct intel_crtc_state *crtc_state) * PSR needs to toggle LATENCY_REPORTING_REMOVED_PIPE_* * based on whether we're limited by the vblank duration. */ - crtc_state->wm_level_disabled = level < i915->display.wm.num_levels - 1; + crtc_state->wm_level_disabled = level < display->wm.num_levels - 1; - for (level++; level < i915->display.wm.num_levels; level++) { + for (level++; level < display->wm.num_levels; level++) { enum plane_id plane_id; for_each_plane_id_on_crtc(crtc, plane_id) { @@ -2471,10 +2395,10 @@ static int skl_wm_check_vblank(struct intel_crtc_state *crtc_state) } } - if (DISPLAY_VER(i915) >= 12 && - i915->display.sagv.block_time_us && + if (DISPLAY_VER(display) >= 12 && + display->sagv.block_time_us && skl_is_vblank_too_short(crtc_state, wm0_lines, - i915->display.sagv.block_time_us)) { + display->sagv.block_time_us)) { enum plane_id plane_id; for_each_plane_id_on_crtc(crtc, plane_id) { @@ -2492,7 +2416,7 @@ static int skl_wm_check_vblank(struct intel_crtc_state *crtc_state) static int skl_build_pipe_wm(struct intel_atomic_state *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_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); const struct intel_plane_state *plane_state; @@ -2508,7 +2432,7 @@ static int skl_build_pipe_wm(struct intel_atomic_state *state, if (plane->pipe != crtc->pipe) continue; - if (DISPLAY_VER(i915) >= 11) + if (DISPLAY_VER(display) >= 11) ret = icl_build_plane_wm(crtc_state, plane_state); else ret = skl_build_plane_wm(crtc_state, plane_state); @@ -2531,11 +2455,10 @@ static bool skl_wm_level_equals(const struct skl_wm_level *l1, l1->auto_min_alloc_wm_enable == l2->auto_min_alloc_wm_enable; } -static bool skl_plane_wm_equals(struct drm_i915_private *i915, +static bool skl_plane_wm_equals(struct intel_display *display, const struct skl_plane_wm *wm1, const struct skl_plane_wm *wm2) { - struct intel_display *display = &i915->display; int level; for (level = 0; level < display->wm.num_levels; level++) { @@ -2590,14 +2513,14 @@ static int skl_ddb_add_affected_planes(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_plane *plane; - for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) { + for_each_intel_plane_on_crtc(display->drm, crtc, plane) { struct intel_plane_state *plane_state; enum plane_id plane_id = plane->id; @@ -2608,7 +2531,7 @@ skl_ddb_add_affected_planes(struct intel_atomic_state *state, continue; if (new_crtc_state->do_async_flip) { - drm_dbg_kms(&i915->drm, "[PLANE:%d:%s] Can't change DDB during async flip\n", + drm_dbg_kms(display->drm, "[PLANE:%d:%s] Can't change DDB during async flip\n", plane->base.base.id, plane->base.name); return -EINVAL; } @@ -2627,7 +2550,7 @@ skl_ddb_add_affected_planes(struct intel_atomic_state *state, static u8 intel_dbuf_enabled_slices(const struct intel_dbuf_state *dbuf_state) { - struct drm_i915_private *i915 = to_i915(dbuf_state->base.state->base.dev); + struct intel_display *display = to_intel_display(dbuf_state->base.state->base.dev); u8 enabled_slices; enum pipe pipe; @@ -2637,7 +2560,7 @@ static u8 intel_dbuf_enabled_slices(const struct intel_dbuf_state *dbuf_state) */ enabled_slices = BIT(DBUF_S1); - for_each_pipe(i915, pipe) + for_each_pipe(display, pipe) enabled_slices |= dbuf_state->slices[pipe]; return enabled_slices; @@ -2647,7 +2570,6 @@ static int skl_compute_ddb(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(state->base.dev); const struct intel_dbuf_state *old_dbuf_state; struct intel_dbuf_state *new_dbuf_state = NULL; struct intel_crtc_state *new_crtc_state; @@ -2686,7 +2608,7 @@ skl_compute_ddb(struct intel_atomic_state *state) } } - for_each_intel_crtc(&i915->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { enum pipe pipe = crtc->pipe; new_dbuf_state->slices[pipe] = @@ -2709,11 +2631,11 @@ skl_compute_ddb(struct intel_atomic_state *state) if (ret) return ret; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "Enabled dbuf slices 0x%x -> 0x%x (total dbuf slices 0x%x), mbus joined? %s->%s\n", old_dbuf_state->enabled_slices, new_dbuf_state->enabled_slices, - DISPLAY_INFO(i915)->dbuf.slice_mask, + DISPLAY_INFO(display)->dbuf.slice_mask, str_yes_no(old_dbuf_state->joined_mbus), str_yes_no(new_dbuf_state->joined_mbus)); } @@ -2731,7 +2653,7 @@ skl_compute_ddb(struct intel_atomic_state *state) return ret; } - for_each_intel_crtc(&i915->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { ret = skl_crtc_allocate_ddb(state, crtc); if (ret) return ret; @@ -2758,7 +2680,7 @@ static char enast(bool enable) static void skl_print_wm_changes(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *old_crtc_state; const struct intel_crtc_state *new_crtc_state; struct intel_plane *plane; @@ -2775,7 +2697,7 @@ skl_print_wm_changes(struct intel_atomic_state *state) old_pipe_wm = &old_crtc_state->wm.skl.optimal; new_pipe_wm = &new_crtc_state->wm.skl.optimal; - for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) { + for_each_intel_plane_on_crtc(display->drm, crtc, plane) { enum plane_id plane_id = plane->id; const struct skl_ddb_entry *old, *new; @@ -2785,24 +2707,24 @@ skl_print_wm_changes(struct intel_atomic_state *state) if (skl_ddb_entry_equal(old, new)) continue; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] ddb (%4d - %4d) -> (%4d - %4d), size %4d -> %4d\n", plane->base.base.id, plane->base.name, old->start, old->end, new->start, new->end, skl_ddb_entry_size(old), skl_ddb_entry_size(new)); } - for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) { + for_each_intel_plane_on_crtc(display->drm, crtc, plane) { enum plane_id plane_id = plane->id; const struct skl_plane_wm *old_wm, *new_wm; old_wm = &old_pipe_wm->planes[plane_id]; new_wm = &new_pipe_wm->planes[plane_id]; - if (skl_plane_wm_equals(i915, old_wm, new_wm)) + if (skl_plane_wm_equals(display, old_wm, new_wm)) continue; - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] level %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm,%cstwm" " -> %cwm0,%cwm1,%cwm2,%cwm3,%cwm4,%cwm5,%cwm6,%cwm7,%ctwm,%cswm,%cstwm\n", plane->base.base.id, plane->base.name, @@ -2821,7 +2743,7 @@ skl_print_wm_changes(struct intel_atomic_state *state) enast(new_wm->sagv.wm0.enable), enast(new_wm->sagv.trans_wm.enable)); - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] lines %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%4d" " -> %c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%3d,%c%4d\n", plane->base.base.id, plane->base.name, @@ -2848,7 +2770,7 @@ skl_print_wm_changes(struct intel_atomic_state *state) enast(new_wm->sagv.wm0.ignore_lines), new_wm->sagv.wm0.lines, enast(new_wm->sagv.trans_wm.ignore_lines), new_wm->sagv.trans_wm.lines); - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] blocks %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d" " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d\n", plane->base.base.id, plane->base.name, @@ -2867,7 +2789,7 @@ skl_print_wm_changes(struct intel_atomic_state *state) new_wm->sagv.wm0.blocks, new_wm->sagv.trans_wm.blocks); - drm_dbg_kms(&i915->drm, + drm_dbg_kms(display->drm, "[PLANE:%d:%s] min_ddb %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d" " -> %4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%4d,%5d\n", plane->base.base.id, plane->base.name, @@ -2945,14 +2867,14 @@ static bool skl_plane_selected_wm_equals(struct intel_plane *plane, static int skl_wm_add_affected_planes(struct intel_atomic_state *state, struct intel_crtc *crtc) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_crtc_state *old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc); struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_plane *plane; - for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) { + for_each_intel_plane_on_crtc(display->drm, crtc, plane) { struct intel_plane_state *plane_state; enum plane_id plane_id = plane->id; @@ -2971,7 +2893,7 @@ static int skl_wm_add_affected_planes(struct intel_atomic_state *state, continue; if (new_crtc_state->do_async_flip) { - drm_dbg_kms(&i915->drm, "[PLANE:%d:%s] Can't change watermarks during async flip\n", + drm_dbg_kms(display->drm, "[PLANE:%d:%s] Can't change watermarks during async flip\n", plane->base.base.id, plane->base.name); return -EINVAL; } @@ -3002,7 +2924,6 @@ void intel_program_dpkgc_latency(struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(display->drm); struct intel_crtc *crtc; struct intel_crtc_state *new_crtc_state; u32 latency = LNL_PKG_C_LATENCY_MASK; @@ -3028,7 +2949,7 @@ intel_program_dpkgc_latency(struct intel_atomic_state *state) added_wake_time = DSB_EXE_TIME + display->sagv.block_time_us; - latency = skl_watermark_max_latency(i915, 1); + latency = skl_watermark_max_latency(display, 1); /* Wa_22020432604 */ if ((DISPLAY_VER(display) == 20 || DISPLAY_VER(display) == 30) && !latency) { @@ -3055,6 +2976,7 @@ intel_program_dpkgc_latency(struct intel_atomic_state *state) static int skl_compute_wm(struct intel_atomic_state *state) { + struct intel_display *display = to_intel_display(state); struct intel_crtc *crtc; struct intel_crtc_state __maybe_unused *new_crtc_state; int ret, i; @@ -3069,16 +2991,35 @@ skl_compute_wm(struct intel_atomic_state *state) if (ret) return ret; - ret = intel_compute_sagv_mask(state); - if (ret) - return ret; - /* * skl_compute_ddb() will have adjusted the final watermarks * based on how much ddb is available. Now we can actually * check if the final watermarks changed. */ for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) { + struct skl_pipe_wm *pipe_wm = &new_crtc_state->wm.skl.optimal; + + /* + * We store use_sagv_wm in the crtc state rather than relying on + * that bw state since we have no convenient way to get at the + * latter from the plane commit hooks (especially in the legacy + * cursor case). + * + * drm_atomic_check_only() gets upset if we pull more crtcs + * into the state, so we have to calculate this based on the + * individual intel_crtc_can_enable_sagv() rather than + * the overall intel_can_enable_sagv(). Otherwise the + * crtcs not included in the commit would not switch to the + * SAGV watermarks when we are about to enable SAGV, and that + * would lead to underruns. This does mean extra power draw + * when only a subset of the crtcs are blocking SAGV as the + * other crtcs can't be allowed to use the more optimal + * normal (ie. non-SAGV) watermarks. + */ + pipe_wm->use_sagv_wm = !HAS_HW_SAGV_WM(display) && + DISPLAY_VER(display) >= 12 && + intel_crtc_can_enable_sagv(new_crtc_state); + ret = skl_wm_add_affected_planes(state, crtc); if (ret) return ret; @@ -3149,11 +3090,10 @@ static void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc, } } -static void skl_wm_get_hw_state(struct drm_i915_private *i915) +static void skl_wm_get_hw_state(struct intel_display *display) { - struct intel_display *display = &i915->display; struct intel_dbuf_state *dbuf_state = - to_intel_dbuf_state(i915->display.dbuf.obj.state); + to_intel_dbuf_state(display->dbuf.obj.state); struct intel_crtc *crtc; if (HAS_MBUS_JOINING(display)) @@ -3193,7 +3133,7 @@ static void skl_wm_get_hw_state(struct drm_i915_private *i915) if (!crtc_state->hw.active) continue; - skl_ddb_get_hw_plane_state(i915, crtc->pipe, + skl_ddb_get_hw_plane_state(display, crtc->pipe, plane_id, ddb, ddb_y, min_ddb, interim_ddb); @@ -3209,13 +3149,13 @@ static void skl_wm_get_hw_state(struct drm_i915_private *i915) */ slices = skl_compute_dbuf_slices(crtc, dbuf_state->active_pipes, dbuf_state->joined_mbus); - mbus_offset = mbus_ddb_offset(i915, slices); + mbus_offset = mbus_ddb_offset(display, slices); crtc_state->wm.skl.ddb.start = mbus_offset + dbuf_state->ddb[pipe].start; crtc_state->wm.skl.ddb.end = mbus_offset + dbuf_state->ddb[pipe].end; /* The slices actually used by the planes on the pipe */ dbuf_state->slices[pipe] = - skl_ddb_dbuf_slice_mask(i915, &crtc_state->wm.skl.ddb); + skl_ddb_dbuf_slice_mask(display, &crtc_state->wm.skl.ddb); drm_dbg_kms(display->drm, "[CRTC:%d:%s] dbuf slices 0x%x, ddb (%d - %d), active pipes 0x%x, mbus joined: %s\n", @@ -3228,49 +3168,52 @@ static void skl_wm_get_hw_state(struct drm_i915_private *i915) dbuf_state->enabled_slices = display->dbuf.enabled_slices; } -bool skl_watermark_ipc_enabled(struct drm_i915_private *i915) +bool skl_watermark_ipc_enabled(struct intel_display *display) { - return i915->display.wm.ipc_enabled; + return display->wm.ipc_enabled; } -void skl_watermark_ipc_update(struct drm_i915_private *i915) +void skl_watermark_ipc_update(struct intel_display *display) { - if (!HAS_IPC(i915)) + if (!HAS_IPC(display)) return; - intel_de_rmw(i915, DISP_ARB_CTL2, DISP_IPC_ENABLE, - skl_watermark_ipc_enabled(i915) ? DISP_IPC_ENABLE : 0); + intel_de_rmw(display, DISP_ARB_CTL2, DISP_IPC_ENABLE, + skl_watermark_ipc_enabled(display) ? DISP_IPC_ENABLE : 0); } -static bool skl_watermark_ipc_can_enable(struct drm_i915_private *i915) +static bool skl_watermark_ipc_can_enable(struct intel_display *display) { + struct drm_i915_private *i915 = to_i915(display->drm); + /* Display WA #0477 WaDisableIPC: skl */ - if (IS_SKYLAKE(i915)) + if (display->platform.skylake) return false; /* Display WA #1141: SKL:all KBL:all CFL */ - if (IS_KABYLAKE(i915) || - IS_COFFEELAKE(i915) || - IS_COMETLAKE(i915)) + if (display->platform.kabylake || + display->platform.coffeelake || + display->platform.cometlake) return i915->dram_info.symmetric_memory; return true; } -void skl_watermark_ipc_init(struct drm_i915_private *i915) +void skl_watermark_ipc_init(struct intel_display *display) { - if (!HAS_IPC(i915)) + if (!HAS_IPC(display)) return; - i915->display.wm.ipc_enabled = skl_watermark_ipc_can_enable(i915); + display->wm.ipc_enabled = skl_watermark_ipc_can_enable(display); - skl_watermark_ipc_update(i915); + skl_watermark_ipc_update(display); } static void -adjust_wm_latency(struct drm_i915_private *i915, +adjust_wm_latency(struct intel_display *display, u16 wm[], int num_levels, int read_latency) { + struct drm_i915_private *i915 = to_i915(display->drm); bool wm_lv_0_adjust_needed = i915->dram_info.wm_lv_0_adjust_needed; int i, level; @@ -3311,31 +3254,32 @@ adjust_wm_latency(struct drm_i915_private *i915, wm[0] += 1; } -static void mtl_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) +static void mtl_read_wm_latency(struct intel_display *display, u16 wm[]) { - int num_levels = i915->display.wm.num_levels; + int num_levels = display->wm.num_levels; u32 val; - val = intel_de_read(i915, MTL_LATENCY_LP0_LP1); + val = intel_de_read(display, MTL_LATENCY_LP0_LP1); wm[0] = REG_FIELD_GET(MTL_LATENCY_LEVEL_EVEN_MASK, val); wm[1] = REG_FIELD_GET(MTL_LATENCY_LEVEL_ODD_MASK, val); - val = intel_de_read(i915, MTL_LATENCY_LP2_LP3); + val = intel_de_read(display, MTL_LATENCY_LP2_LP3); wm[2] = REG_FIELD_GET(MTL_LATENCY_LEVEL_EVEN_MASK, val); wm[3] = REG_FIELD_GET(MTL_LATENCY_LEVEL_ODD_MASK, val); - val = intel_de_read(i915, MTL_LATENCY_LP4_LP5); + val = intel_de_read(display, MTL_LATENCY_LP4_LP5); wm[4] = REG_FIELD_GET(MTL_LATENCY_LEVEL_EVEN_MASK, val); wm[5] = REG_FIELD_GET(MTL_LATENCY_LEVEL_ODD_MASK, val); - adjust_wm_latency(i915, wm, num_levels, 6); + adjust_wm_latency(display, wm, num_levels, 6); } -static void skl_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) +static void skl_read_wm_latency(struct intel_display *display, u16 wm[]) { - int num_levels = i915->display.wm.num_levels; - int read_latency = DISPLAY_VER(i915) >= 12 ? 3 : 2; - int mult = IS_DG2(i915) ? 2 : 1; + struct drm_i915_private *i915 = to_i915(display->drm); + int num_levels = display->wm.num_levels; + int read_latency = DISPLAY_VER(display) >= 12 ? 3 : 2; + int mult = display->platform.dg2 ? 2 : 1; u32 val; int ret; @@ -3343,7 +3287,7 @@ static void skl_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) val = 0; /* data0 to be programmed to 0 for first set */ ret = snb_pcode_read(&i915->uncore, GEN9_PCODE_READ_MEM_LATENCY, &val, NULL); if (ret) { - drm_err(&i915->drm, "SKL Mailbox read error = %d\n", ret); + drm_err(display->drm, "SKL Mailbox read error = %d\n", ret); return; } @@ -3356,7 +3300,7 @@ static void skl_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) val = 1; /* data0 to be programmed to 1 for second set */ ret = snb_pcode_read(&i915->uncore, GEN9_PCODE_READ_MEM_LATENCY, &val, NULL); if (ret) { - drm_err(&i915->drm, "SKL Mailbox read error = %d\n", ret); + drm_err(display->drm, "SKL Mailbox read error = %d\n", ret); return; } @@ -3365,24 +3309,22 @@ static void skl_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) wm[6] = REG_FIELD_GET(GEN9_MEM_LATENCY_LEVEL_2_6_MASK, val) * mult; wm[7] = REG_FIELD_GET(GEN9_MEM_LATENCY_LEVEL_3_7_MASK, val) * mult; - adjust_wm_latency(i915, wm, num_levels, read_latency); + adjust_wm_latency(display, wm, num_levels, read_latency); } -static void skl_setup_wm_latency(struct drm_i915_private *i915) +static void skl_setup_wm_latency(struct intel_display *display) { - struct intel_display *display = &i915->display; - if (HAS_HW_SAGV_WM(display)) display->wm.num_levels = 6; else display->wm.num_levels = 8; if (DISPLAY_VER(display) >= 14) - mtl_read_wm_latency(i915, display->wm.skl_latency); + mtl_read_wm_latency(display, display->wm.skl_latency); else - skl_read_wm_latency(i915, display->wm.skl_latency); + skl_read_wm_latency(display, display->wm.skl_latency); - intel_print_wm_latency(i915, "Gen9 Plane", display->wm.skl_latency); + intel_print_wm_latency(display, "Gen9 Plane", display->wm.skl_latency); } static struct intel_global_state *intel_dbuf_duplicate_state(struct intel_global_obj *obj) @@ -3410,19 +3352,18 @@ static const struct intel_global_state_funcs intel_dbuf_funcs = { struct intel_dbuf_state * intel_atomic_get_dbuf_state(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); struct intel_global_state *dbuf_state; - dbuf_state = intel_atomic_get_global_obj_state(state, &i915->display.dbuf.obj); + dbuf_state = intel_atomic_get_global_obj_state(state, &display->dbuf.obj); if (IS_ERR(dbuf_state)) return ERR_CAST(dbuf_state); return to_intel_dbuf_state(dbuf_state); } -int intel_dbuf_init(struct drm_i915_private *i915) +int intel_dbuf_init(struct intel_display *display) { - struct intel_display *display = &i915->display; struct intel_dbuf_state *dbuf_state; dbuf_state = kzalloc(sizeof(*dbuf_state), GFP_KERNEL); @@ -3457,34 +3398,34 @@ static bool xelpdp_is_only_pipe_per_dbuf_bank(enum pipe pipe, u8 active_pipes) static u32 pipe_mbus_dbox_ctl(const struct intel_crtc *crtc, const struct intel_dbuf_state *dbuf_state) { - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); u32 val = 0; - if (DISPLAY_VER(i915) >= 14) + if (DISPLAY_VER(display) >= 14) val |= MBUS_DBOX_I_CREDIT(2); - if (DISPLAY_VER(i915) >= 12) { + if (DISPLAY_VER(display) >= 12) { val |= MBUS_DBOX_B2B_TRANSACTIONS_MAX(16); val |= MBUS_DBOX_B2B_TRANSACTIONS_DELAY(1); val |= MBUS_DBOX_REGULATE_B2B_TRANSACTIONS_EN; } - if (DISPLAY_VER(i915) >= 14) + if (DISPLAY_VER(display) >= 14) val |= dbuf_state->joined_mbus ? MBUS_DBOX_A_CREDIT(12) : MBUS_DBOX_A_CREDIT(8); - else if (IS_ALDERLAKE_P(i915)) + else if (display->platform.alderlake_p) /* Wa_22010947358:adl-p */ val |= dbuf_state->joined_mbus ? MBUS_DBOX_A_CREDIT(6) : MBUS_DBOX_A_CREDIT(4); else val |= MBUS_DBOX_A_CREDIT(2); - if (DISPLAY_VER(i915) >= 14) { + if (DISPLAY_VER(display) >= 14) { val |= MBUS_DBOX_B_CREDIT(0xA); - } else if (IS_ALDERLAKE_P(i915)) { + } else if (display->platform.alderlake_p) { val |= MBUS_DBOX_BW_CREDIT(2); val |= MBUS_DBOX_B_CREDIT(8); - } else if (DISPLAY_VER(i915) >= 12) { + } else if (DISPLAY_VER(display) >= 12) { val |= MBUS_DBOX_BW_CREDIT(2); val |= MBUS_DBOX_B_CREDIT(12); } else { @@ -3492,7 +3433,7 @@ static u32 pipe_mbus_dbox_ctl(const struct intel_crtc *crtc, val |= MBUS_DBOX_B_CREDIT(8); } - if (DISPLAY_VERx100(i915) == 1400) { + if (DISPLAY_VERx100(display) == 1400) { if (xelpdp_is_only_pipe_per_dbuf_bank(crtc->pipe, dbuf_state->active_pipes)) val |= MBUS_DBOX_BW_8CREDITS_MTL; else @@ -3502,22 +3443,22 @@ static u32 pipe_mbus_dbox_ctl(const struct intel_crtc *crtc, return val; } -static void pipe_mbus_dbox_ctl_update(struct drm_i915_private *i915, +static void pipe_mbus_dbox_ctl_update(struct intel_display *display, const struct intel_dbuf_state *dbuf_state) { struct intel_crtc *crtc; - for_each_intel_crtc_in_pipe_mask(&i915->drm, crtc, dbuf_state->active_pipes) - intel_de_write(i915, PIPE_MBUS_DBOX_CTL(crtc->pipe), + for_each_intel_crtc_in_pipe_mask(display->drm, crtc, dbuf_state->active_pipes) + intel_de_write(display, PIPE_MBUS_DBOX_CTL(crtc->pipe), pipe_mbus_dbox_ctl(crtc, dbuf_state)); } static void intel_mbus_dbox_update(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_dbuf_state *new_dbuf_state, *old_dbuf_state; - if (DISPLAY_VER(i915) < 11) + if (DISPLAY_VER(display) < 11) return; new_dbuf_state = intel_atomic_get_new_dbuf_state(state); @@ -3527,7 +3468,7 @@ static void intel_mbus_dbox_update(struct intel_atomic_state *state) new_dbuf_state->active_pipes == old_dbuf_state->active_pipes)) return; - pipe_mbus_dbox_ctl_update(i915, new_dbuf_state); + pipe_mbus_dbox_ctl_update(display, new_dbuf_state); } int intel_dbuf_state_set_mdclk_cdclk_ratio(struct intel_atomic_state *state, @@ -3544,10 +3485,9 @@ int intel_dbuf_state_set_mdclk_cdclk_ratio(struct intel_atomic_state *state, return intel_atomic_lock_global_state(&dbuf_state->base); } -void intel_dbuf_mdclk_cdclk_ratio_update(struct drm_i915_private *i915, +void intel_dbuf_mdclk_cdclk_ratio_update(struct intel_display *display, int ratio, bool joined_mbus) { - struct intel_display *display = &i915->display; enum dbuf_slice slice; if (!HAS_MBUS_JOINING(display)) @@ -3571,7 +3511,7 @@ void intel_dbuf_mdclk_cdclk_ratio_update(struct drm_i915_private *i915, static void intel_dbuf_mdclk_min_tracker_update(struct intel_atomic_state *state) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_dbuf_state *old_dbuf_state = intel_atomic_get_old_dbuf_state(state); const struct intel_dbuf_state *new_dbuf_state = @@ -3586,7 +3526,7 @@ static void intel_dbuf_mdclk_min_tracker_update(struct intel_atomic_state *state mdclk_cdclk_ratio = new_dbuf_state->mdclk_cdclk_ratio; } - intel_dbuf_mdclk_cdclk_ratio_update(i915, mdclk_cdclk_ratio, + intel_dbuf_mdclk_cdclk_ratio_update(display, mdclk_cdclk_ratio, new_dbuf_state->joined_mbus); } @@ -3594,13 +3534,12 @@ static enum pipe intel_mbus_joined_pipe(struct intel_atomic_state *state, const struct intel_dbuf_state *dbuf_state) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(state->base.dev); enum pipe pipe = ffs(dbuf_state->active_pipes) - 1; const struct intel_crtc_state *new_crtc_state; struct intel_crtc *crtc; - drm_WARN_ON(&i915->drm, !dbuf_state->joined_mbus); - drm_WARN_ON(&i915->drm, !is_power_of_2(dbuf_state->active_pipes)); + drm_WARN_ON(display->drm, !dbuf_state->joined_mbus); + drm_WARN_ON(display->drm, !is_power_of_2(dbuf_state->active_pipes)); crtc = intel_crtc_for_pipe(display, pipe); new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); @@ -3611,7 +3550,7 @@ static enum pipe intel_mbus_joined_pipe(struct intel_atomic_state *state, return INVALID_PIPE; } -static void mbus_ctl_join_update(struct drm_i915_private *i915, +static void mbus_ctl_join_update(struct intel_display *display, const struct intel_dbuf_state *dbuf_state, enum pipe pipe) { @@ -3627,7 +3566,7 @@ static void mbus_ctl_join_update(struct drm_i915_private *i915, else mbus_ctl |= MBUS_JOIN_PIPE_SELECT_NONE; - intel_de_rmw(i915, MBUS_CTL, + intel_de_rmw(display, MBUS_CTL, MBUS_HASHING_MODE_MASK | MBUS_JOIN | MBUS_JOIN_PIPE_SELECT_MASK, mbus_ctl); } @@ -3635,18 +3574,18 @@ static void mbus_ctl_join_update(struct drm_i915_private *i915, static void intel_dbuf_mbus_join_update(struct intel_atomic_state *state, enum pipe pipe) { - struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_display *display = to_intel_display(state); const struct intel_dbuf_state *old_dbuf_state = intel_atomic_get_old_dbuf_state(state); const struct intel_dbuf_state *new_dbuf_state = intel_atomic_get_new_dbuf_state(state); - drm_dbg_kms(&i915->drm, "Changing mbus joined: %s -> %s (pipe: %c)\n", + drm_dbg_kms(display->drm, "Changing mbus joined: %s -> %s (pipe: %c)\n", str_yes_no(old_dbuf_state->joined_mbus), str_yes_no(new_dbuf_state->joined_mbus), pipe != INVALID_PIPE ? pipe_name(pipe) : '*'); - mbus_ctl_join_update(i915, new_dbuf_state, pipe); + mbus_ctl_join_update(display, new_dbuf_state, pipe); } void intel_dbuf_mbus_pre_ddb_update(struct intel_atomic_state *state) @@ -3751,9 +3690,8 @@ void intel_dbuf_post_plane_update(struct intel_atomic_state *state) gen9_dbuf_slices_update(display, new_slices); } -static void skl_mbus_sanitize(struct drm_i915_private *i915) +static void skl_mbus_sanitize(struct intel_display *display) { - struct intel_display *display = &i915->display; struct intel_dbuf_state *dbuf_state = to_intel_dbuf_state(display->dbuf.obj.state); @@ -3768,28 +3706,28 @@ static void skl_mbus_sanitize(struct drm_i915_private *i915) dbuf_state->active_pipes); dbuf_state->joined_mbus = false; - intel_dbuf_mdclk_cdclk_ratio_update(i915, + intel_dbuf_mdclk_cdclk_ratio_update(display, dbuf_state->mdclk_cdclk_ratio, dbuf_state->joined_mbus); - pipe_mbus_dbox_ctl_update(i915, dbuf_state); - mbus_ctl_join_update(i915, dbuf_state, INVALID_PIPE); + pipe_mbus_dbox_ctl_update(display, dbuf_state); + mbus_ctl_join_update(display, dbuf_state, INVALID_PIPE); } -static bool skl_dbuf_is_misconfigured(struct drm_i915_private *i915) +static bool skl_dbuf_is_misconfigured(struct intel_display *display) { const struct intel_dbuf_state *dbuf_state = - to_intel_dbuf_state(i915->display.dbuf.obj.state); + to_intel_dbuf_state(display->dbuf.obj.state); struct skl_ddb_entry entries[I915_MAX_PIPES] = {}; struct intel_crtc *crtc; - for_each_intel_crtc(&i915->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); entries[crtc->pipe] = crtc_state->wm.skl.ddb; } - for_each_intel_crtc(&i915->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); u8 slices; @@ -3807,7 +3745,7 @@ static bool skl_dbuf_is_misconfigured(struct drm_i915_private *i915) return false; } -static void skl_dbuf_sanitize(struct drm_i915_private *i915) +static void skl_dbuf_sanitize(struct intel_display *display) { struct intel_crtc *crtc; @@ -3822,12 +3760,12 @@ static void skl_dbuf_sanitize(struct drm_i915_private *i915) * all the planes so that skl_commit_modeset_enables() can * simply ignore them. */ - if (!skl_dbuf_is_misconfigured(i915)) + if (!skl_dbuf_is_misconfigured(display)) return; - drm_dbg_kms(&i915->drm, "BIOS has misprogrammed the DBUF, disabling all planes\n"); + drm_dbg_kms(display->drm, "BIOS has misprogrammed the DBUF, disabling all planes\n"); - for_each_intel_crtc(&i915->drm, crtc) { + for_each_intel_crtc(display->drm, crtc) { struct intel_plane *plane = to_intel_plane(crtc->base.primary); const struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); @@ -3837,16 +3775,16 @@ static void skl_dbuf_sanitize(struct drm_i915_private *i915) if (plane_state->uapi.visible) intel_plane_disable_noatomic(crtc, plane); - drm_WARN_ON(&i915->drm, crtc_state->active_planes != 0); + drm_WARN_ON(display->drm, crtc_state->active_planes != 0); memset(&crtc_state->wm.skl.ddb, 0, sizeof(crtc_state->wm.skl.ddb)); } } -static void skl_wm_sanitize(struct drm_i915_private *i915) +static void skl_wm_sanitize(struct intel_display *display) { - skl_mbus_sanitize(i915); - skl_dbuf_sanitize(i915); + skl_mbus_sanitize(display); + skl_dbuf_sanitize(display); } void skl_wm_crtc_disable_noatomic(struct intel_crtc *crtc) @@ -3897,7 +3835,6 @@ void intel_wm_state_verify(struct intel_atomic_state *state, struct intel_crtc *crtc) { struct intel_display *display = to_intel_display(state); - struct drm_i915_private *i915 = to_i915(state->base.dev); const struct intel_crtc_state *new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct skl_hw_state { @@ -3912,7 +3849,7 @@ void intel_wm_state_verify(struct intel_atomic_state *state, u8 hw_enabled_slices; int level; - if (DISPLAY_VER(i915) < 9 || !new_crtc_state->hw.active) + if (DISPLAY_VER(display) < 9 || !new_crtc_state->hw.active) return; hw = kzalloc(sizeof(*hw), GFP_KERNEL); @@ -3925,26 +3862,26 @@ void intel_wm_state_verify(struct intel_atomic_state *state, hw_enabled_slices = intel_enabled_dbuf_slices_mask(display); - if (DISPLAY_VER(i915) >= 11 && - hw_enabled_slices != i915->display.dbuf.enabled_slices) - drm_err(&i915->drm, + if (DISPLAY_VER(display) >= 11 && + hw_enabled_slices != display->dbuf.enabled_slices) + drm_err(display->drm, "mismatch in DBUF Slices (expected 0x%x, got 0x%x)\n", - i915->display.dbuf.enabled_slices, + display->dbuf.enabled_slices, hw_enabled_slices); - for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) { + for_each_intel_plane_on_crtc(display->drm, crtc, plane) { const struct skl_ddb_entry *hw_ddb_entry, *sw_ddb_entry; const struct skl_wm_level *hw_wm_level, *sw_wm_level; /* Watermarks */ - for (level = 0; level < i915->display.wm.num_levels; level++) { + for (level = 0; level < display->wm.num_levels; level++) { hw_wm_level = &hw->wm.planes[plane->id].wm[level]; sw_wm_level = skl_plane_wm_level(sw_wm, plane->id, level); if (skl_wm_level_equals(hw_wm_level, sw_wm_level)) continue; - drm_err(&i915->drm, + drm_err(display->drm, "[PLANE:%d:%s] mismatch in WM%d (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n", plane->base.base.id, plane->base.name, level, sw_wm_level->enable, @@ -3959,7 +3896,7 @@ void intel_wm_state_verify(struct intel_atomic_state *state, sw_wm_level = skl_plane_trans_wm(sw_wm, plane->id); if (!skl_wm_level_equals(hw_wm_level, sw_wm_level)) { - drm_err(&i915->drm, + drm_err(display->drm, "[PLANE:%d:%s] mismatch in trans WM (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n", plane->base.base.id, plane->base.name, sw_wm_level->enable, @@ -3975,7 +3912,7 @@ void intel_wm_state_verify(struct intel_atomic_state *state, if (HAS_HW_SAGV_WM(display) && !skl_wm_level_equals(hw_wm_level, sw_wm_level)) { - drm_err(&i915->drm, + drm_err(display->drm, "[PLANE:%d:%s] mismatch in SAGV WM (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n", plane->base.base.id, plane->base.name, sw_wm_level->enable, @@ -3991,7 +3928,7 @@ void intel_wm_state_verify(struct intel_atomic_state *state, if (HAS_HW_SAGV_WM(display) && !skl_wm_level_equals(hw_wm_level, sw_wm_level)) { - drm_err(&i915->drm, + drm_err(display->drm, "[PLANE:%d:%s] mismatch in SAGV trans WM (expected e=%d b=%u l=%u, got e=%d b=%u l=%u)\n", plane->base.base.id, plane->base.name, sw_wm_level->enable, @@ -4007,7 +3944,7 @@ void intel_wm_state_verify(struct intel_atomic_state *state, sw_ddb_entry = &new_crtc_state->wm.skl.plane_ddb[PLANE_CURSOR]; if (!skl_ddb_entry_equal(hw_ddb_entry, sw_ddb_entry)) { - drm_err(&i915->drm, + drm_err(display->drm, "[PLANE:%d:%s] mismatch in DDB (expected (%u,%u), found (%u,%u))\n", plane->base.base.id, plane->base.name, sw_ddb_entry->start, sw_ddb_entry->end, @@ -4024,29 +3961,29 @@ static const struct intel_wm_funcs skl_wm_funcs = { .sanitize = skl_wm_sanitize, }; -void skl_wm_init(struct drm_i915_private *i915) +void skl_wm_init(struct intel_display *display) { - intel_sagv_init(i915); + intel_sagv_init(display); - skl_setup_wm_latency(i915); + skl_setup_wm_latency(display); - i915->display.funcs.wm = &skl_wm_funcs; + display->funcs.wm = &skl_wm_funcs; } static int skl_watermark_ipc_status_show(struct seq_file *m, void *data) { - struct drm_i915_private *i915 = m->private; + struct intel_display *display = m->private; seq_printf(m, "Isochronous Priority Control: %s\n", - str_yes_no(skl_watermark_ipc_enabled(i915))); + str_yes_no(skl_watermark_ipc_enabled(display))); return 0; } static int skl_watermark_ipc_status_open(struct inode *inode, struct file *file) { - struct drm_i915_private *i915 = inode->i_private; + struct intel_display *display = inode->i_private; - return single_open(file, skl_watermark_ipc_status_show, i915); + return single_open(file, skl_watermark_ipc_status_show, display); } static ssize_t skl_watermark_ipc_status_write(struct file *file, @@ -4054,8 +3991,7 @@ static ssize_t skl_watermark_ipc_status_write(struct file *file, size_t len, loff_t *offp) { struct seq_file *m = file->private_data; - struct drm_i915_private *i915 = m->private; - intel_wakeref_t wakeref; + struct intel_display *display = m->private; bool enable; int ret; @@ -4063,12 +3999,12 @@ static ssize_t skl_watermark_ipc_status_write(struct file *file, if (ret < 0) return ret; - with_intel_runtime_pm(&i915->runtime_pm, wakeref) { - if (!skl_watermark_ipc_enabled(i915) && enable) - drm_info(&i915->drm, + with_intel_display_rpm(display) { + if (!skl_watermark_ipc_enabled(display) && enable) + drm_info(display->drm, "Enabling IPC: WM will be proper only after next commit\n"); - i915->display.wm.ipc_enabled = enable; - skl_watermark_ipc_update(i915); + display->wm.ipc_enabled = enable; + skl_watermark_ipc_update(display); } return len; @@ -4085,7 +4021,7 @@ static const struct file_operations skl_watermark_ipc_status_fops = { static int intel_sagv_status_show(struct seq_file *m, void *unused) { - struct drm_i915_private *i915 = m->private; + struct intel_display *display = m->private; static const char * const sagv_status[] = { [I915_SAGV_UNKNOWN] = "unknown", [I915_SAGV_DISABLED] = "disabled", @@ -4093,37 +4029,36 @@ static int intel_sagv_status_show(struct seq_file *m, void *unused) [I915_SAGV_NOT_CONTROLLED] = "not controlled", }; - seq_printf(m, "SAGV available: %s\n", str_yes_no(intel_has_sagv(i915))); + seq_printf(m, "SAGV available: %s\n", str_yes_no(intel_has_sagv(display))); seq_printf(m, "SAGV modparam: %s\n", - str_enabled_disabled(i915->display.params.enable_sagv)); - seq_printf(m, "SAGV status: %s\n", sagv_status[i915->display.sagv.status]); - seq_printf(m, "SAGV block time: %d usec\n", i915->display.sagv.block_time_us); + str_enabled_disabled(display->params.enable_sagv)); + seq_printf(m, "SAGV status: %s\n", sagv_status[display->sagv.status]); + seq_printf(m, "SAGV block time: %d usec\n", display->sagv.block_time_us); return 0; } DEFINE_SHOW_ATTRIBUTE(intel_sagv_status); -void skl_watermark_debugfs_register(struct drm_i915_private *i915) +void skl_watermark_debugfs_register(struct intel_display *display) { - struct intel_display *display = &i915->display; struct drm_minor *minor = display->drm->primary; if (HAS_IPC(display)) - debugfs_create_file("i915_ipc_status", 0644, minor->debugfs_root, i915, - &skl_watermark_ipc_status_fops); + debugfs_create_file("i915_ipc_status", 0644, minor->debugfs_root, + display, &skl_watermark_ipc_status_fops); if (HAS_SAGV(display)) - debugfs_create_file("i915_sagv_status", 0444, minor->debugfs_root, i915, - &intel_sagv_status_fops); + debugfs_create_file("i915_sagv_status", 0444, minor->debugfs_root, + display, &intel_sagv_status_fops); } -unsigned int skl_watermark_max_latency(struct drm_i915_private *i915, int initial_wm_level) +unsigned int skl_watermark_max_latency(struct intel_display *display, int initial_wm_level) { int level; - for (level = i915->display.wm.num_levels - 1; level >= initial_wm_level; level--) { - unsigned int latency = skl_wm_latency(i915, level, NULL); + for (level = display->wm.num_levels - 1; level >= initial_wm_level; level--) { + unsigned int latency = skl_wm_latency(display, level, NULL); if (latency) return latency; diff --git a/drivers/gpu/drm/i915/display/skl_watermark.h b/drivers/gpu/drm/i915/display/skl_watermark.h index d9cff6c54310..95b0b599d5c3 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.h +++ b/drivers/gpu/drm/i915/display/skl_watermark.h @@ -12,7 +12,6 @@ #include "intel_global_state.h" #include "intel_wm_types.h" -struct drm_i915_private; struct intel_atomic_state; struct intel_bw_state; struct intel_crtc; @@ -27,11 +26,12 @@ u8 intel_enabled_dbuf_slices_mask(struct intel_display *display); void intel_sagv_pre_plane_update(struct intel_atomic_state *state); void intel_sagv_post_plane_update(struct intel_atomic_state *state); -bool intel_can_enable_sagv(struct drm_i915_private *i915, +bool intel_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state); +bool intel_can_enable_sagv(struct intel_display *display, const struct intel_bw_state *bw_state); -bool intel_has_sagv(struct drm_i915_private *i915); +bool intel_has_sagv(struct intel_display *display); -u32 skl_ddb_dbuf_slice_mask(struct drm_i915_private *i915, +u32 skl_ddb_dbuf_slice_mask(struct intel_display *display, const struct skl_ddb_entry *entry); bool skl_ddb_allocation_overlaps(const struct skl_ddb_entry *ddb, @@ -45,14 +45,14 @@ void skl_wm_crtc_disable_noatomic(struct intel_crtc *crtc); void skl_wm_plane_disable_noatomic(struct intel_crtc *crtc, struct intel_plane *plane); -void skl_watermark_ipc_init(struct drm_i915_private *i915); -void skl_watermark_ipc_update(struct drm_i915_private *i915); -bool skl_watermark_ipc_enabled(struct drm_i915_private *i915); -void skl_watermark_debugfs_register(struct drm_i915_private *i915); +void skl_watermark_ipc_init(struct intel_display *display); +void skl_watermark_ipc_update(struct intel_display *display); +bool skl_watermark_ipc_enabled(struct intel_display *display); +void skl_watermark_debugfs_register(struct intel_display *display); -unsigned int skl_watermark_max_latency(struct drm_i915_private *i915, +unsigned int skl_watermark_max_latency(struct intel_display *display, int initial_wm_level); -void skl_wm_init(struct drm_i915_private *i915); +void skl_wm_init(struct intel_display *display); const struct skl_wm_level *skl_plane_wm_level(const struct skl_pipe_wm *pipe_wm, enum plane_id plane_id, @@ -86,13 +86,13 @@ intel_atomic_get_dbuf_state(struct intel_atomic_state *state); #define intel_atomic_get_new_dbuf_state(state) \ to_intel_dbuf_state(intel_atomic_get_new_global_obj_state(state, &to_intel_display(state)->dbuf.obj)) -int intel_dbuf_init(struct drm_i915_private *i915); +int intel_dbuf_init(struct intel_display *display); int intel_dbuf_state_set_mdclk_cdclk_ratio(struct intel_atomic_state *state, int ratio); void intel_dbuf_pre_plane_update(struct intel_atomic_state *state); void intel_dbuf_post_plane_update(struct intel_atomic_state *state); -void intel_dbuf_mdclk_cdclk_ratio_update(struct drm_i915_private *i915, +void intel_dbuf_mdclk_cdclk_ratio_update(struct intel_display *display, int ratio, bool joined_mbus); void intel_dbuf_mbus_pre_ddb_update(struct intel_atomic_state *state); void intel_dbuf_mbus_post_ddb_update(struct intel_atomic_state *state); diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index af717df83197..346737f15fa9 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -251,8 +251,10 @@ static int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs, return 0; } -static void band_gap_reset(struct drm_i915_private *dev_priv) +static void band_gap_reset(struct intel_display *display) { + struct drm_i915_private *dev_priv = to_i915(display->drm); + vlv_flisdsi_get(dev_priv); vlv_flisdsi_write(dev_priv, 0x08, 0x0001); @@ -269,13 +271,13 @@ static int intel_dsi_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, 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); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); struct intel_connector *intel_connector = intel_dsi->attached_connector; struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; int ret; - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB; pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; @@ -298,7 +300,7 @@ static int intel_dsi_compute_config(struct intel_encoder *encoder, else pipe_config->pipe_bpp = 18; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { /* Enable Frame time stamp based scanline reporting */ pipe_config->mode_flags |= I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP; @@ -468,7 +470,7 @@ static void vlv_dsi_device_ready(struct intel_encoder *encoder) vlv_flisdsi_put(dev_priv); /* bandgap reset is needed after everytime we do power gate */ - band_gap_reset(dev_priv); + band_gap_reset(display); for_each_dsi_port(port, intel_dsi->ports) { @@ -495,11 +497,11 @@ static void vlv_dsi_device_ready(struct intel_encoder *encoder) static void intel_dsi_device_ready(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - if (IS_GEMINILAKE(dev_priv)) + if (display->platform.geminilake) glk_dsi_device_ready(encoder); - else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + else if (display->platform.geminilake || display->platform.broxton) bxt_dsi_device_ready(encoder); else vlv_dsi_device_ready(encoder); @@ -559,23 +561,22 @@ static void glk_dsi_clear_device_ready(struct intel_encoder *encoder) glk_dsi_disable_mipi_io(encoder); } -static i915_reg_t port_ctrl_reg(struct drm_i915_private *i915, enum port port) +static i915_reg_t port_ctrl_reg(struct intel_display *display, enum port port) { - return IS_GEMINILAKE(i915) || IS_BROXTON(i915) ? + return display->platform.geminilake || display->platform.broxton ? BXT_MIPI_PORT_CTRL(port) : VLV_MIPI_PORT_CTRL(port); } static void vlv_dsi_clear_device_ready(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; drm_dbg_kms(display->drm, "\n"); for_each_dsi_port(port, intel_dsi->ports) { /* Common bit for both MIPI Port A & MIPI Port C on VLV/CHV */ - i915_reg_t port_ctrl = IS_BROXTON(dev_priv) ? + i915_reg_t port_ctrl = display->platform.broxton ? BXT_MIPI_PORT_CTRL(port) : VLV_MIPI_PORT_CTRL(PORT_A); intel_de_write(display, MIPI_DEVICE_READY(display, port), @@ -594,7 +595,7 @@ static void vlv_dsi_clear_device_ready(struct intel_encoder *encoder) * On VLV/CHV, wait till Clock lanes are in LP-00 state for MIPI * Port A only. MIPI Port C has no similar bit for checking. */ - if ((IS_BROXTON(dev_priv) || port == PORT_A) && + if ((display->platform.broxton || port == PORT_A) && intel_de_wait_for_clear(display, port_ctrl, AFE_LATCHOUT, 30)) drm_err(display->drm, "DSI LP not going Low\n"); @@ -612,7 +613,6 @@ static void intel_dsi_port_enable(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(encoder->base.dev); struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; @@ -620,7 +620,7 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder, if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) { u32 temp = intel_dsi->pixel_overlap; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { for_each_dsi_port(port, intel_dsi->ports) intel_de_rmw(display, MIPI_CTRL(display, port), BXT_PIXEL_OVERLAP_CNT_MASK, @@ -633,7 +633,7 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder, } for_each_dsi_port(port, intel_dsi->ports) { - i915_reg_t port_ctrl = port_ctrl_reg(dev_priv, port); + i915_reg_t port_ctrl = port_ctrl_reg(display, port); u32 temp; temp = intel_de_read(display, port_ctrl); @@ -644,7 +644,7 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder, if (intel_dsi->ports == (BIT(PORT_A) | BIT(PORT_C))) { temp |= (intel_dsi->dual_link - 1) << DUAL_LINK_MODE_SHIFT; - if (IS_BROXTON(dev_priv)) + if (display->platform.broxton) temp |= LANE_CONFIGURATION_DUAL_LINK_A; else temp |= crtc->pipe ? @@ -664,12 +664,11 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder, static void intel_dsi_port_disable(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; for_each_dsi_port(port, intel_dsi->ports) { - i915_reg_t port_ctrl = port_ctrl_reg(dev_priv, port); + i915_reg_t port_ctrl = port_ctrl_reg(display, port); /* de-assert ip_tg_enable signal */ intel_de_rmw(display, port_ctrl, DPI_ENABLE, 0); @@ -730,7 +729,6 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, struct intel_display *display = to_intel_display(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); enum pipe pipe = crtc->pipe; enum port port; bool glk_cold_boot = false; @@ -745,7 +743,7 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, * The BIOS may leave the PLL in a wonky state where it doesn't * lock. It needs to be fully powered down to fix it. */ - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { bxt_dsi_pll_disable(encoder); bxt_dsi_pll_enable(encoder, pipe_config); } else { @@ -753,7 +751,7 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, vlv_dsi_pll_enable(encoder, pipe_config); } - if (IS_BROXTON(dev_priv)) { + if (display->platform.broxton) { /* Add MIPI IO reset programming for modeset */ intel_de_rmw(display, BXT_P_CR_GT_DISP_PWRON, 0, MIPIO_RST_CTRL); @@ -762,13 +760,13 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, intel_de_write(display, BXT_P_DSI_REGULATOR_TX_CTRL, 0); } - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + if (display->platform.valleyview || display->platform.cherryview) { /* Disable DPOunit clock gating, can stall pipe */ - intel_de_rmw(display, DSPCLK_GATE_D(dev_priv), + intel_de_rmw(display, DSPCLK_GATE_D(display), 0, DPOUNIT_CLOCK_GATE_DISABLE); } - if (!IS_GEMINILAKE(dev_priv)) + if (!display->platform.geminilake) intel_dsi_prepare(encoder, pipe_config); /* Give the panel time to power-on and then deassert its reset */ @@ -776,7 +774,7 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, msleep(intel_dsi->panel_on_delay); intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DEASSERT_RESET); - if (IS_GEMINILAKE(dev_priv)) { + if (display->platform.geminilake) { glk_cold_boot = glk_dsi_enable_io(encoder); /* Prepare port in cold boot(s3/s4) scenario */ @@ -788,7 +786,7 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state, intel_dsi_device_ready(encoder); /* Prepare port in normal boot scenario */ - if (IS_GEMINILAKE(dev_priv) && !glk_cold_boot) + if (display->platform.geminilake && !glk_cold_boot) intel_dsi_prepare(encoder, pipe_config); /* Send initialization commands in LP mode */ @@ -836,11 +834,11 @@ static void intel_dsi_disable(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 *i915 = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; - drm_dbg_kms(&i915->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF); intel_backlight_disable(old_conn_state); @@ -860,9 +858,9 @@ static void intel_dsi_disable(struct intel_atomic_state *state, static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - if (IS_GEMINILAKE(dev_priv)) + if (display->platform.geminilake) glk_dsi_clear_device_ready(encoder); else vlv_dsi_clear_device_ready(encoder); @@ -874,13 +872,12 @@ static void intel_dsi_post_disable(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(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; drm_dbg_kms(display->drm, "\n"); - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { intel_crtc_vblank_off(old_crtc_state); skl_scaler_disable(old_crtc_state); @@ -907,7 +904,7 @@ static void intel_dsi_post_disable(struct intel_atomic_state *state, /* Transition to LP-00 */ intel_dsi_clear_device_ready(encoder); - if (IS_BROXTON(dev_priv)) { + if (display->platform.broxton) { /* Power down DSI regulator to save power */ intel_de_write(display, BXT_P_DSI_REGULATOR_CFG, STAP_SELECT); intel_de_write(display, BXT_P_DSI_REGULATOR_TX_CTRL, @@ -917,12 +914,12 @@ static void intel_dsi_post_disable(struct intel_atomic_state *state, intel_de_rmw(display, BXT_P_CR_GT_DISP_PWRON, MIPIO_RST_CTRL, 0); } - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { bxt_dsi_pll_disable(encoder); } else { vlv_dsi_pll_disable(encoder); - intel_de_rmw(display, DSPCLK_GATE_D(dev_priv), + intel_de_rmw(display, DSPCLK_GATE_D(display), DPOUNIT_CLOCK_GATE_DISABLE, 0); } @@ -939,7 +936,6 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); intel_wakeref_t wakeref; enum port port; @@ -957,13 +953,13 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, * configuration, otherwise accessing DSI registers will hang the * machine. See BSpec North Display Engine registers/MIPI[BXT]. */ - if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) && - !bxt_dsi_pll_is_enabled(dev_priv)) + if ((display->platform.geminilake || display->platform.broxton) && + !bxt_dsi_pll_is_enabled(display)) goto out_put_power; /* XXX: this only works for one DSI output */ for_each_dsi_port(port, intel_dsi->ports) { - i915_reg_t port_ctrl = port_ctrl_reg(dev_priv, port); + i915_reg_t port_ctrl = port_ctrl_reg(display, port); bool enabled = intel_de_read(display, port_ctrl) & DPI_ENABLE; /* @@ -971,10 +967,10 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, * bit in port C control register does not get set. As a * workaround, check pipe B conf instead. */ - if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) && + if ((display->platform.valleyview || display->platform.cherryview) && port == PORT_C) enabled = intel_de_read(display, - TRANSCONF(dev_priv, PIPE_B)) & TRANSCONF_ENABLE; + TRANSCONF(display, PIPE_B)) & TRANSCONF_ENABLE; /* Try command mode if video mode not enabled */ if (!enabled) { @@ -989,7 +985,7 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, if (!(intel_de_read(display, MIPI_DEVICE_READY(display, port)) & DEVICE_READY)) continue; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { u32 tmp = intel_de_read(display, MIPI_CTRL(display, port)); tmp &= BXT_PIPE_SELECT_MASK; tmp >>= BXT_PIPE_SELECT_SHIFT; @@ -1177,15 +1173,15 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder, static void intel_dsi_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); u32 pclk; - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI); - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { bxt_dsi_get_pipe_config(encoder, pipe_config); pclk = bxt_dsi_get_pclk(encoder, pipe_config); } else { @@ -1218,7 +1214,6 @@ static void set_dsi_timings(struct intel_encoder *encoder, const struct drm_display_mode *adjusted_mode) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; unsigned int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); @@ -1253,7 +1248,7 @@ static void set_dsi_timings(struct intel_encoder *encoder, hbp = txbyteclkhs(hbp, bpp, lane_count, intel_dsi->burst_mode_ratio); for_each_dsi_port(port, intel_dsi->ports) { - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { /* * Program hdisplay and vdisplay on MIPI transcoder. * This is different from calculated hactive and @@ -1307,7 +1302,6 @@ static void intel_dsi_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_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; @@ -1327,7 +1321,7 @@ static void intel_dsi_prepare(struct intel_encoder *encoder, } for_each_dsi_port(port, intel_dsi->ports) { - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { + if (display->platform.valleyview || display->platform.cherryview) { /* * escape clock divider, 20MHz, shared for A and C. * device ready must be off when doing this! txclkesc? @@ -1342,7 +1336,7 @@ static void intel_dsi_prepare(struct intel_encoder *encoder, tmp &= ~READ_REQUEST_PRIORITY_MASK; intel_de_write(display, MIPI_CTRL(display, port), tmp | READ_REQUEST_PRIORITY_HIGH); - } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + } else if (display->platform.geminilake || display->platform.broxton) { enum pipe pipe = crtc->pipe; intel_de_rmw(display, MIPI_CTRL(display, port), @@ -1377,7 +1371,7 @@ static void intel_dsi_prepare(struct intel_encoder *encoder, if (intel_dsi->clock_stop) tmp |= CLOCKSTOP; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) { + if (display->platform.geminilake || display->platform.broxton) { tmp |= BXT_DPHY_DEFEATURE_EN; if (!is_cmd_mode(intel_dsi)) tmp |= BXT_DEFEATURE_DPI_FIFO_CTR; @@ -1424,7 +1418,7 @@ static void intel_dsi_prepare(struct intel_encoder *encoder, intel_de_write(display, MIPI_INIT_COUNT(display, port), txclkesc(intel_dsi->escape_clk_div, 100)); - if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) && + if ((display->platform.geminilake || display->platform.broxton) && !intel_dsi->dual_link) { /* * BXT spec says write MIPI_INIT_COUNT for @@ -1461,7 +1455,7 @@ static void intel_dsi_prepare(struct intel_encoder *encoder, intel_de_write(display, MIPI_LP_BYTECLK(display, port), intel_dsi->lp_byte_clk); - if (IS_GEMINILAKE(dev_priv)) { + if (display->platform.geminilake) { intel_de_write(display, MIPI_TLPX_TIME_COUNT(display, port), intel_dsi->lp_byte_clk); /* Shadow of DPHY reg */ @@ -1513,18 +1507,17 @@ static void intel_dsi_prepare(struct intel_encoder *encoder, static void intel_dsi_unprepare(struct intel_encoder *encoder) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; - if (IS_GEMINILAKE(dev_priv)) + if (display->platform.geminilake) return; for_each_dsi_port(port, intel_dsi->ports) { /* Panel commands can be sent when clock is in LP11 */ intel_de_write(display, MIPI_DEVICE_READY(display, port), 0x0); - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) bxt_dsi_reset_clocks(encoder, port); else vlv_dsi_reset_clocks(encoder, port); @@ -1596,8 +1589,8 @@ static void vlv_dsi_add_properties(struct intel_connector *connector) static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) { - struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev); struct intel_connector *connector = intel_dsi->attached_connector; + struct intel_display *display = to_intel_display(connector); struct mipi_config *mipi_config = connector->panel.vbt.dsi.config; u32 tlpx_ns, extra_byte_count, tlpx_ui; u32 ui_num, ui_den; @@ -1645,7 +1638,7 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) * For GEMINILAKE dphy_param_reg will be programmed in terms of * HS byte clock count for other platform in HS ddr clock count */ - mul = IS_GEMINILAKE(dev_priv) ? 8 : 2; + mul = display->platform.geminilake ? 8 : 2; ths_prepare_ns = max(mipi_config->ths_prepare, mipi_config->tclk_prepare); @@ -1653,7 +1646,7 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) prepare_cnt = DIV_ROUND_UP(ths_prepare_ns * ui_den, ui_num * mul); if (prepare_cnt > PREPARE_CNT_MAX) { - drm_dbg_kms(&dev_priv->drm, "prepare count too high %u\n", + drm_dbg_kms(display->drm, "prepare count too high %u\n", prepare_cnt); prepare_cnt = PREPARE_CNT_MAX; } @@ -1674,7 +1667,7 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) exit_zero_cnt += 1; if (exit_zero_cnt > EXIT_ZERO_CNT_MAX) { - drm_dbg_kms(&dev_priv->drm, "exit zero count too high %u\n", + drm_dbg_kms(display->drm, "exit zero count too high %u\n", exit_zero_cnt); exit_zero_cnt = EXIT_ZERO_CNT_MAX; } @@ -1685,7 +1678,7 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) * ui_den, ui_num * mul); if (clk_zero_cnt > CLK_ZERO_CNT_MAX) { - drm_dbg_kms(&dev_priv->drm, "clock zero count too high %u\n", + drm_dbg_kms(display->drm, "clock zero count too high %u\n", clk_zero_cnt); clk_zero_cnt = CLK_ZERO_CNT_MAX; } @@ -1695,7 +1688,7 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) trail_cnt = DIV_ROUND_UP(tclk_trail_ns * ui_den, ui_num * mul); if (trail_cnt > TRAIL_CNT_MAX) { - drm_dbg_kms(&dev_priv->drm, "trail count too high %u\n", + drm_dbg_kms(display->drm, "trail count too high %u\n", trail_cnt); trail_cnt = TRAIL_CNT_MAX; } @@ -1761,7 +1754,7 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi) int vlv_dsi_min_cdclk(const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev); + struct intel_display *display = to_intel_display(crtc_state); if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI)) return 0; @@ -1770,7 +1763,7 @@ int vlv_dsi_min_cdclk(const struct intel_crtc_state *crtc_state) * On Valleyview some DSI panels lose (v|h)sync when the clock is lower * than 320000KHz. */ - if (IS_VALLEYVIEW(dev_priv)) + if (display->platform.valleyview) return 320000; /* @@ -1778,7 +1771,7 @@ int vlv_dsi_min_cdclk(const struct intel_crtc_state *crtc_state) * picture gets unstable, despite that values are * correct for DSI PLL and DE PLL. */ - if (IS_GEMINILAKE(dev_priv)) + if (display->platform.geminilake) return 158400; return 0; @@ -1903,9 +1896,8 @@ static const struct dmi_system_id vlv_dsi_dmi_quirk_table[] = { { } }; -void vlv_dsi_init(struct drm_i915_private *dev_priv) +void vlv_dsi_init(struct intel_display *display) { - struct intel_display *display = &dev_priv->display; struct intel_dsi *intel_dsi; struct intel_encoder *encoder; struct intel_connector *connector; @@ -1914,16 +1906,16 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) enum port port; enum pipe pipe; - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); /* There is no detection method for MIPI so rely on VBT */ if (!intel_bios_is_dsi_present(display, &port)) return; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) - dev_priv->display.dsi.mmio_base = BXT_MIPI_BASE; + if (display->platform.geminilake || display->platform.broxton) + display->dsi.mmio_base = BXT_MIPI_BASE; else - dev_priv->display.dsi.mmio_base = VLV_MIPI_BASE; + display->dsi.mmio_base = VLV_MIPI_BASE; intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL); if (!intel_dsi) @@ -1938,12 +1930,12 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) encoder = &intel_dsi->base; intel_dsi->attached_connector = connector; - drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_dsi_funcs, + drm_encoder_init(display->drm, &encoder->base, &intel_dsi_funcs, DRM_MODE_ENCODER_DSI, "DSI %c", port_name(port)); encoder->compute_config = intel_dsi_compute_config; encoder->pre_enable = intel_dsi_pre_enable; - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) encoder->enable = bxt_dsi_enable; encoder->disable = intel_dsi_disable; encoder->post_disable = intel_dsi_post_disable; @@ -1963,7 +1955,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) * On BYT/CHV, pipe A maps to MIPI DSI port A, pipe B maps to MIPI DSI * port C. BXT isn't limited like this. */ - if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) + if (display->platform.geminilake || display->platform.broxton) encoder->pipe_mask = ~0; else if (port == PORT_A) encoder->pipe_mask = BIT(PIPE_A); @@ -1979,10 +1971,10 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) else intel_dsi->ports = BIT(port); - if (drm_WARN_ON(&dev_priv->drm, connector->panel.vbt.dsi.bl_ports & ~intel_dsi->ports)) + if (drm_WARN_ON(display->drm, connector->panel.vbt.dsi.bl_ports & ~intel_dsi->ports)) connector->panel.vbt.dsi.bl_ports &= intel_dsi->ports; - if (drm_WARN_ON(&dev_priv->drm, connector->panel.vbt.dsi.cabc_ports & ~intel_dsi->ports)) + if (drm_WARN_ON(display->drm, connector->panel.vbt.dsi.cabc_ports & ~intel_dsi->ports)) connector->panel.vbt.dsi.cabc_ports &= intel_dsi->ports; /* Create a DSI host (and a device) for each port. */ @@ -1998,18 +1990,18 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) } if (!intel_dsi_vbt_init(intel_dsi, MIPI_DSI_GENERIC_PANEL_ID)) { - drm_dbg_kms(&dev_priv->drm, "no device found\n"); + drm_dbg_kms(display->drm, "no device found\n"); goto err; } /* Use clock read-back from current hw-state for fastboot */ current_mode = intel_encoder_current_mode(encoder); if (current_mode) { - drm_dbg_kms(&dev_priv->drm, "Calculated pclk %d GOP %d\n", + drm_dbg_kms(display->drm, "Calculated pclk %d GOP %d\n", intel_dsi->pclk, current_mode->clock); if (intel_fuzzy_clock_check(intel_dsi->pclk, current_mode->clock)) { - drm_dbg_kms(&dev_priv->drm, "Using GOP pclk\n"); + drm_dbg_kms(display->drm, "Using GOP pclk\n"); intel_dsi->pclk = current_mode->clock; } @@ -2021,7 +2013,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) intel_dsi_vbt_gpio_init(intel_dsi, intel_dsi_get_hw_state(encoder, &pipe)); - drm_connector_init(&dev_priv->drm, &connector->base, &intel_dsi_connector_funcs, + drm_connector_init(display->drm, &connector->base, &intel_dsi_connector_funcs, DRM_MODE_CONNECTOR_DSI); drm_connector_helper_add(&connector->base, &intel_dsi_connector_helper_funcs); @@ -2030,12 +2022,12 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv) intel_connector_attach_encoder(connector, encoder); - mutex_lock(&dev_priv->drm.mode_config.mutex); + mutex_lock(&display->drm->mode_config.mutex); intel_panel_add_vbt_lfp_fixed_mode(connector); - mutex_unlock(&dev_priv->drm.mode_config.mutex); + mutex_unlock(&display->drm->mode_config.mutex); if (!intel_panel_preferred_fixed_mode(connector)) { - drm_dbg_kms(&dev_priv->drm, "no fixed mode\n"); + drm_dbg_kms(display->drm, "no fixed mode\n"); goto err_cleanup_connector; } diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.h b/drivers/gpu/drm/i915/display/vlv_dsi.h index 277bacfbc551..ff349b5876c2 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.h +++ b/drivers/gpu/drm/i915/display/vlv_dsi.h @@ -7,14 +7,14 @@ #define __VLV_DSI_H__ enum port; -struct drm_i915_private; struct intel_crtc_state; +struct intel_display; struct intel_dsi; #ifdef I915 void vlv_dsi_wait_for_fifo_empty(struct intel_dsi *intel_dsi, enum port port); int vlv_dsi_min_cdclk(const struct intel_crtc_state *crtc_state); -void vlv_dsi_init(struct drm_i915_private *dev_priv); +void vlv_dsi_init(struct intel_display *display); #else static inline void vlv_dsi_wait_for_fifo_empty(struct intel_dsi *intel_dsi, enum port port) { @@ -23,7 +23,7 @@ static inline int vlv_dsi_min_cdclk(const struct intel_crtc_state *crtc_state) { return 0; } -static inline void vlv_dsi_init(struct drm_i915_private *dev_priv) +static inline void vlv_dsi_init(struct intel_display *display) { } #endif diff --git a/drivers/gpu/drm/i915/display/vlv_dsi_pll.c b/drivers/gpu/drm/i915/display/vlv_dsi_pll.c index 2ed47e7d1051..7ce924a5ef90 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi_pll.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi_pll.c @@ -57,7 +57,7 @@ static u32 dsi_clk_from_pclk(u32 pclk, enum mipi_dsi_pixel_format fmt, return dsi_clk_khz; } -static int dsi_calc_mnp(struct drm_i915_private *dev_priv, +static int dsi_calc_mnp(struct intel_display *display, struct intel_crtc_state *config, int target_dsi_clk) { @@ -68,11 +68,11 @@ static int dsi_calc_mnp(struct drm_i915_private *dev_priv, /* target_dsi_clk is expected in kHz */ if (target_dsi_clk < 300000 || target_dsi_clk > 1150000) { - drm_err(&dev_priv->drm, "DSI CLK Out of Range\n"); + drm_err(display->drm, "DSI CLK Out of Range\n"); return -ECHRNG; } - if (IS_CHERRYVIEW(dev_priv)) { + if (display->platform.cherryview) { ref_clk = 100000; n = 4; m_min = 70; @@ -116,13 +116,13 @@ static int dsi_calc_mnp(struct drm_i915_private *dev_priv, static int vlv_dsi_pclk(struct intel_encoder *encoder, struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); u32 dsi_clock; u32 pll_ctl, pll_div; u32 m = 0, p = 0, n; - int refclk = IS_CHERRYVIEW(dev_priv) ? 100000 : 25000; + int refclk = display->platform.cherryview ? 100000 : 25000; int i; pll_ctl = config->dsi_pll.ctrl; @@ -147,7 +147,7 @@ static int vlv_dsi_pclk(struct intel_encoder *encoder, p--; if (!p) { - drm_err(&dev_priv->drm, "wrong P1 divisor\n"); + drm_err(display->drm, "wrong P1 divisor\n"); return 0; } @@ -157,7 +157,7 @@ static int vlv_dsi_pclk(struct intel_encoder *encoder, } if (i == ARRAY_SIZE(lfsr_converts)) { - drm_err(&dev_priv->drm, "wrong m_seed programmed\n"); + drm_err(display->drm, "wrong m_seed programmed\n"); return 0; } @@ -175,16 +175,16 @@ static int vlv_dsi_pclk(struct intel_encoder *encoder, int vlv_dsi_pll_compute(struct intel_encoder *encoder, struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); int pclk, dsi_clk, ret; dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format, intel_dsi->lane_count); - ret = dsi_calc_mnp(dev_priv, config, dsi_clk); + ret = dsi_calc_mnp(display, config, dsi_clk); if (ret) { - drm_dbg_kms(&dev_priv->drm, "dsi_calc_mnp failed\n"); + drm_dbg_kms(display->drm, "dsi_calc_mnp failed\n"); return ret; } @@ -196,7 +196,7 @@ int vlv_dsi_pll_compute(struct intel_encoder *encoder, config->dsi_pll.ctrl |= DSI_PLL_VCO_EN; - drm_dbg_kms(&dev_priv->drm, "dsi pll div %08x, ctrl %08x\n", + drm_dbg_kms(display->drm, "dsi pll div %08x, ctrl %08x\n", config->dsi_pll.div, config->dsi_pll.ctrl); pclk = vlv_dsi_pclk(encoder, config); @@ -213,9 +213,10 @@ int vlv_dsi_pll_compute(struct intel_encoder *encoder, void vlv_dsi_pll_enable(struct intel_encoder *encoder, const struct intel_crtc_state *config) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); vlv_cck_get(dev_priv); @@ -235,20 +236,21 @@ void vlv_dsi_pll_enable(struct intel_encoder *encoder, DSI_PLL_LOCK, 20)) { vlv_cck_put(dev_priv); - drm_err(&dev_priv->drm, "DSI PLL lock failed\n"); + drm_err(display->drm, "DSI PLL lock failed\n"); return; } vlv_cck_put(dev_priv); - drm_dbg_kms(&dev_priv->drm, "DSI PLL locked\n"); + drm_dbg_kms(display->drm, "DSI PLL locked\n"); } void vlv_dsi_pll_disable(struct intel_encoder *encoder) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u32 tmp; - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); vlv_cck_get(dev_priv); @@ -260,14 +262,14 @@ void vlv_dsi_pll_disable(struct intel_encoder *encoder) vlv_cck_put(dev_priv); } -bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv) +bool bxt_dsi_pll_is_enabled(struct intel_display *display) { bool enabled; u32 val; u32 mask; mask = BXT_DSI_PLL_DO_ENABLE | BXT_DSI_PLL_LOCKED; - val = intel_de_read(dev_priv, BXT_DSI_PLL_ENABLE); + val = intel_de_read(display, BXT_DSI_PLL_ENABLE); enabled = (val & mask) == mask; if (!enabled) @@ -281,17 +283,17 @@ bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv) * times, and since accessing DSI registers with invalid dividers * causes a system hang. */ - val = intel_de_read(dev_priv, BXT_DSI_PLL_CTL); - if (IS_GEMINILAKE(dev_priv)) { + val = intel_de_read(display, BXT_DSI_PLL_CTL); + if (display->platform.geminilake) { if (!(val & BXT_DSIA_16X_MASK)) { - drm_dbg(&dev_priv->drm, - "Invalid PLL divider (%08x)\n", val); + drm_dbg_kms(display->drm, + "Invalid PLL divider (%08x)\n", val); enabled = false; } } else { if (!(val & BXT_DSIA_16X_MASK) || !(val & BXT_DSIC_16X_MASK)) { - drm_dbg(&dev_priv->drm, - "Invalid PLL divider (%08x)\n", val); + drm_dbg_kms(display->drm, + "Invalid PLL divider (%08x)\n", val); enabled = false; } } @@ -301,29 +303,30 @@ bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv) void bxt_dsi_pll_disable(struct intel_encoder *encoder) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); - intel_de_rmw(dev_priv, BXT_DSI_PLL_ENABLE, BXT_DSI_PLL_DO_ENABLE, 0); + intel_de_rmw(display, BXT_DSI_PLL_ENABLE, BXT_DSI_PLL_DO_ENABLE, 0); /* * PLL lock should deassert within 200us. * Wait up to 1ms before timing out. */ - if (intel_de_wait_for_clear(dev_priv, BXT_DSI_PLL_ENABLE, + if (intel_de_wait_for_clear(display, BXT_DSI_PLL_ENABLE, BXT_DSI_PLL_LOCKED, 1)) - drm_err(&dev_priv->drm, + drm_err(display->drm, "Timeout waiting for PLL lock deassertion\n"); } u32 vlv_dsi_get_pclk(struct intel_encoder *encoder, struct intel_crtc_state *config) { + struct intel_display *display = to_intel_display(encoder); struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u32 pll_ctl, pll_div; - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); vlv_cck_get(dev_priv); pll_ctl = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL); @@ -352,14 +355,14 @@ static int bxt_dsi_pclk(struct intel_encoder *encoder, u32 bxt_dsi_get_pclk(struct intel_encoder *encoder, struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); u32 pclk; - config->dsi_pll.ctrl = intel_de_read(dev_priv, BXT_DSI_PLL_CTL); + config->dsi_pll.ctrl = intel_de_read(display, BXT_DSI_PLL_CTL); pclk = bxt_dsi_pclk(encoder, config); - drm_dbg(&dev_priv->drm, "Calculated pclk=%u\n", pclk); + drm_dbg_kms(display->drm, "Calculated pclk=%u\n", pclk); return pclk; } @@ -375,10 +378,9 @@ void vlv_dsi_reset_clocks(struct intel_encoder *encoder, enum port port) temp | intel_dsi->escape_clk_div << ESCAPE_CLOCK_DIVIDER_SHIFT); } -static void glk_dsi_program_esc_clock(struct drm_device *dev, - const struct intel_crtc_state *config) +static void glk_dsi_program_esc_clock(struct intel_display *display, + const struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = to_i915(dev); u32 dsi_rate = 0; u32 pll_ratio = 0; u32 ddr_clk = 0; @@ -415,17 +417,16 @@ static void glk_dsi_program_esc_clock(struct drm_device *dev, txesc2_div = min_t(u32, div2_value, 10); - intel_de_write(dev_priv, MIPIO_TXESC_CLK_DIV1, + intel_de_write(display, MIPIO_TXESC_CLK_DIV1, (1 << (txesc1_div - 1)) & GLK_TX_ESC_CLK_DIV1_MASK); - intel_de_write(dev_priv, MIPIO_TXESC_CLK_DIV2, + intel_de_write(display, MIPIO_TXESC_CLK_DIV2, (1 << (txesc2_div - 1)) & GLK_TX_ESC_CLK_DIV2_MASK); } /* Program BXT Mipi clocks and dividers */ -static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port, +static void bxt_dsi_program_clocks(struct intel_display *display, enum port port, const struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = to_i915(dev); u32 tmp; u32 dsi_rate = 0; u32 pll_ratio = 0; @@ -436,7 +437,7 @@ static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port, u32 mipi_8by3_divider; /* Clear old configurations */ - tmp = intel_de_read(dev_priv, BXT_MIPI_CLOCK_CTL); + tmp = intel_de_read(display, BXT_MIPI_CLOCK_CTL); tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port)); tmp &= ~(BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port)); tmp &= ~(BXT_MIPI_8X_BY3_DIVIDER_MASK(port)); @@ -472,13 +473,13 @@ static void bxt_dsi_program_clocks(struct drm_device *dev, enum port port, tmp |= BXT_MIPI_RX_ESCLK_LOWER_DIVIDER(port, rx_div_lower); tmp |= BXT_MIPI_RX_ESCLK_UPPER_DIVIDER(port, rx_div_upper); - intel_de_write(dev_priv, BXT_MIPI_CLOCK_CTL, tmp); + intel_de_write(display, BXT_MIPI_CLOCK_CTL, tmp); } int bxt_dsi_pll_compute(struct intel_encoder *encoder, struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); u8 dsi_ratio, dsi_ratio_min, dsi_ratio_max; u32 dsi_clk; @@ -494,7 +495,7 @@ int bxt_dsi_pll_compute(struct intel_encoder *encoder, */ dsi_ratio = DIV_ROUND_UP(dsi_clk * 2, BXT_REF_CLOCK_KHZ); - if (IS_BROXTON(dev_priv)) { + if (display->platform.broxton) { dsi_ratio_min = BXT_DSI_PLL_RATIO_MIN; dsi_ratio_max = BXT_DSI_PLL_RATIO_MAX; } else { @@ -503,11 +504,11 @@ int bxt_dsi_pll_compute(struct intel_encoder *encoder, } if (dsi_ratio < dsi_ratio_min || dsi_ratio > dsi_ratio_max) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "Can't get a suitable ratio from DSI PLL ratios\n"); return -ECHRNG; } else - drm_dbg_kms(&dev_priv->drm, "DSI PLL calculation is Done!!\n"); + drm_dbg_kms(display->drm, "DSI PLL calculation is Done!!\n"); /* * Program DSI ratio and Select MIPIC and MIPIA PLL output as 8x @@ -519,7 +520,7 @@ int bxt_dsi_pll_compute(struct intel_encoder *encoder, /* As per recommendation from hardware team, * Prog PVD ratio =1 if dsi ratio <= 50 */ - if (IS_BROXTON(dev_priv) && dsi_ratio <= 50) + if (display->platform.broxton && dsi_ratio <= 50) config->dsi_pll.ctrl |= BXT_DSI_PLL_PVD_RATIO_1; pclk = bxt_dsi_pclk(encoder, config); @@ -536,46 +537,45 @@ int bxt_dsi_pll_compute(struct intel_encoder *encoder, void bxt_dsi_pll_enable(struct intel_encoder *encoder, const struct intel_crtc_state *config) { - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); enum port port; - drm_dbg_kms(&dev_priv->drm, "\n"); + drm_dbg_kms(display->drm, "\n"); /* Configure PLL vales */ - intel_de_write(dev_priv, BXT_DSI_PLL_CTL, config->dsi_pll.ctrl); - intel_de_posting_read(dev_priv, BXT_DSI_PLL_CTL); + intel_de_write(display, BXT_DSI_PLL_CTL, config->dsi_pll.ctrl); + intel_de_posting_read(display, BXT_DSI_PLL_CTL); /* Program TX, RX, Dphy clocks */ - if (IS_BROXTON(dev_priv)) { + if (display->platform.broxton) { for_each_dsi_port(port, intel_dsi->ports) - bxt_dsi_program_clocks(encoder->base.dev, port, config); + bxt_dsi_program_clocks(display, port, config); } else { - glk_dsi_program_esc_clock(encoder->base.dev, config); + glk_dsi_program_esc_clock(display, config); } /* Enable DSI PLL */ - intel_de_rmw(dev_priv, BXT_DSI_PLL_ENABLE, 0, BXT_DSI_PLL_DO_ENABLE); + intel_de_rmw(display, BXT_DSI_PLL_ENABLE, 0, BXT_DSI_PLL_DO_ENABLE); /* Timeout and fail if PLL not locked */ - if (intel_de_wait_for_set(dev_priv, BXT_DSI_PLL_ENABLE, + if (intel_de_wait_for_set(display, BXT_DSI_PLL_ENABLE, BXT_DSI_PLL_LOCKED, 1)) { - drm_err(&dev_priv->drm, + drm_err(display->drm, "Timed out waiting for DSI PLL to lock\n"); return; } - drm_dbg_kms(&dev_priv->drm, "DSI PLL locked\n"); + drm_dbg_kms(display->drm, "DSI PLL locked\n"); } void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port) { struct intel_display *display = to_intel_display(encoder); - struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); u32 tmp; /* Clear old configurations */ - if (IS_BROXTON(dev_priv)) { + if (display->platform.broxton) { tmp = intel_de_read(display, BXT_MIPI_CLOCK_CTL); tmp &= ~(BXT_MIPI_TX_ESCLK_FIXDIV_MASK(port)); tmp &= ~(BXT_MIPI_RX_ESCLK_UPPER_FIXDIV_MASK(port)); diff --git a/drivers/gpu/drm/i915/display/vlv_dsi_pll.h b/drivers/gpu/drm/i915/display/vlv_dsi_pll.h index f975660fa609..f26e31a7dd69 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi_pll.h +++ b/drivers/gpu/drm/i915/display/vlv_dsi_pll.h @@ -9,7 +9,6 @@ #include <linux/types.h> enum port; -struct drm_i915_private; struct intel_crtc_state; struct intel_display; struct intel_encoder; @@ -33,11 +32,11 @@ u32 bxt_dsi_get_pclk(struct intel_encoder *encoder, void bxt_dsi_reset_clocks(struct intel_encoder *encoder, enum port port); #ifdef I915 -bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv); +bool bxt_dsi_pll_is_enabled(struct intel_display *display); void assert_dsi_pll_enabled(struct intel_display *display); void assert_dsi_pll_disabled(struct intel_display *display); #else -static inline bool bxt_dsi_pll_is_enabled(struct drm_i915_private *dev_priv) +static inline bool bxt_dsi_pll_is_enabled(struct intel_display *display) { return false; } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_busy.c b/drivers/gpu/drm/i915/gem/i915_gem_busy.c index ddda468241ef..6e4d0ce3952f 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_busy.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_busy.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2014-2016 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_clflush.c b/drivers/gpu/drm/i915/gem/i915_gem_clflush.c index 7d97ea2a653e..c4854c5b4e0f 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_clflush.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_clflush.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2016 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_clflush.h b/drivers/gpu/drm/i915/gem/i915_gem_clflush.h index e6c382973129..9d7ee1579900 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_clflush.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_clflush.h @@ -1,6 +1,5 @@ +/* SPDX-License-Identifier: MIT */ /* - * SPDX-License-Identifier: MIT - * * Copyright © 2016 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index ab1af978911b..15835952352e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2011-2012 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.h b/drivers/gpu/drm/i915/gem/i915_gem_context.h index e5b0f66ea1fe..6e682a6a0574 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.h @@ -1,6 +1,5 @@ +/* SPDX-License-Identifier: MIT */ /* - * SPDX-License-Identifier: MIT - * * Copyright © 2016 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h index 67ac2586a0f3..0267c924634b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_context_types.h @@ -1,6 +1,5 @@ +/* SPDX-License-Identifier: MIT */ /* - * SPDX-License-Identifier: MIT - * * Copyright © 2019 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c index 9473050ac842..05e440643aa2 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright 2012 Red Hat Inc */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c b/drivers/gpu/drm/i915/gem/i915_gem_domain.c index 75a143d996e0..7a0cc51923b3 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2014-2016 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 7796c4119ef5..ca7e9216934a 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2008,2010 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c index ea7561ae6e13..232b984f60b6 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2014-2016 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h index 28d6526e32ab..8044d34707b6 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_ioctls.h @@ -1,6 +1,5 @@ +/* SPDX-License-Identifier: MIT */ /* - * SPDX-License-Identifier: MIT - * * Copyright © 2019 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c index 388f90784d8a..f566191d843b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c @@ -48,8 +48,7 @@ bool i915_gem_object_is_lmem(struct drm_i915_gem_object *obj) i915_gem_object_evictable(obj)) assert_object_held(obj); #endif - return mr && (mr->type == INTEL_MEMORY_LOCAL || - mr->type == INTEL_MEMORY_STOLEN_LOCAL); + return mr && intel_memory_type_is_local(mr->type); } /** diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c index c3dabb857960..f6d37dff320d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2014-2016 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.h b/drivers/gpu/drm/i915/gem/i915_gem_mman.h index 196417fd0f5c..946fb9825eb3 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.h @@ -1,6 +1,5 @@ +/* SPDX-License-Identifier: MIT */ /* - * SPDX-License-Identifier: MIT - * * Copyright © 2019 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c index 356530b599ce..1f38e367c60b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * Copyright © 2017 Intel Corporation * diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index a5f34542135c..c34f41605b46 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -1,6 +1,5 @@ +/* SPDX-License-Identifier: MIT */ /* - * SPDX-License-Identifier: MIT - * * Copyright © 2016 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h index 68413c05c812..64600aa8227f 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h @@ -1,6 +1,5 @@ +/* SPDX-License-Identifier: MIT */ /* - * SPDX-License-Identifier: MIT - * * Copyright © 2016 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index 8780aa243105..7f83f8bdc8fb 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2014-2016 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_phys.c b/drivers/gpu/drm/i915/gem/i915_gem_phys.c index ef85c6dc9fd5..f9e7cab140f8 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_phys.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_phys.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2014-2016 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pm.c b/drivers/gpu/drm/i915/gem/i915_gem_pm.c index 900c08337942..f0857c5c96df 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pm.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2019 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pm.h b/drivers/gpu/drm/i915/gem/i915_gem_pm.h index bedf1e95941a..bd5bd2c5e7f9 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pm.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_pm.h @@ -1,6 +1,5 @@ +/* SPDX-License-Identifier: MIT */ /* - * SPDX-License-Identifier: MIT - * * Copyright © 2019 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c index ae3343c81a64..19a3eb82dc6a 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2014-2016 Intel Corporation */ @@ -305,36 +304,20 @@ void __shmem_writeback(size_t size, struct address_space *mapping) .range_end = LLONG_MAX, .for_reclaim = 1, }; - unsigned long i; + struct folio *folio = NULL; + int error = 0; /* * Leave mmapings intact (GTT will have been revoked on unbinding, - * leaving only CPU mmapings around) and add those pages to the LRU + * leaving only CPU mmapings around) and add those folios to the LRU * instead of invoking writeback so they are aged and paged out * as normal. */ - - /* Begin writeback on each dirty page */ - for (i = 0; i < size >> PAGE_SHIFT; i++) { - struct page *page; - - page = find_lock_page(mapping, i); - if (!page) - continue; - - if (!page_mapped(page) && clear_page_dirty_for_io(page)) { - int ret; - - SetPageReclaim(page); - ret = mapping->a_ops->writepage(page, &wbc); - if (!PageWriteback(page)) - ClearPageReclaim(page); - if (!ret) - goto put; - } - unlock_page(page); -put: - put_page(page); + while ((folio = writeback_iter(mapping, &wbc, folio, &error))) { + if (folio_mapped(folio)) + folio_redirty_for_writepage(&wbc, folio); + else + error = shmem_writeout(folio, &wbc); } } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c index aec41f0f098f..b81e67504bbe 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shrinker.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2008-2015 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c index 9d958a6f377e..3380151edfc1 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2008-2012 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_throttle.c b/drivers/gpu/drm/i915/gem/i915_gem_throttle.c index af85d0c28168..8814cbcde5b5 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_throttle.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_throttle.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2014-2016 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_tiling.c b/drivers/gpu/drm/i915/gem/i915_gem_tiling.c index 5ac23ff3feff..5a296ba3758a 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_tiling.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2008 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c index 09b68713ab32..307a18eede72 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c @@ -1,9 +1,8 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2012-2014 Intel Corporation * - * Based on amdgpu_mn, which bears the following notice: + * Based on amdgpu_mn, which bears the following notice: * * Copyright 2014 Advanced Micro Devices, Inc. * All Rights Reserved. diff --git a/drivers/gpu/drm/i915/gem/i915_gem_wait.c b/drivers/gpu/drm/i915/gem/i915_gem_wait.c index 1f55e62044a4..7127e90c1a8f 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_wait.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_wait.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2016 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gemfs.c b/drivers/gpu/drm/i915/gem/i915_gemfs.c index 46b9a17d6abc..65d84a93c525 100644 --- a/drivers/gpu/drm/i915/gem/i915_gemfs.c +++ b/drivers/gpu/drm/i915/gem/i915_gemfs.c @@ -1,6 +1,5 @@ +// SPDX-License-Identifier: MIT /* - * SPDX-License-Identifier: MIT - * * Copyright © 2017 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/i915_gemfs.h b/drivers/gpu/drm/i915/gem/i915_gemfs.h index 5d835e44c4f6..16d4333c9a4e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gemfs.h +++ b/drivers/gpu/drm/i915/gem/i915_gemfs.h @@ -1,6 +1,5 @@ +/* SPDX-License-Identifier: MIT */ /* - * SPDX-License-Identifier: MIT - * * Copyright © 2017 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c index 804f74084bd4..9c3f17e51885 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c @@ -1837,6 +1837,8 @@ static int igt_mmap_revoke(void *arg) int i915_gem_mman_live_selftests(struct drm_i915_private *i915) { + int ret; + bool unuse_mm = false; static const struct i915_subtest tests[] = { SUBTEST(igt_partial_tiling), SUBTEST(igt_smoke_tiling), @@ -1848,5 +1850,15 @@ int i915_gem_mman_live_selftests(struct drm_i915_private *i915) SUBTEST(igt_mmap_gpu), }; - return i915_live_subtests(tests, i915); + if (!current->mm) { + kthread_use_mm(current->active_mm); + unuse_mm = true; + } + + ret = i915_live_subtests(tests, i915); + + if (unuse_mm) + kthread_unuse_mm(current->active_mm); + + return ret; } diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c index f6c59f20832f..46a5aa4ab9c8 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -289,6 +289,14 @@ u64 gen8_ggtt_pte_encode(dma_addr_t addr, return pte; } +static dma_addr_t gen8_ggtt_pte_decode(u64 pte, bool *is_present, bool *is_local) +{ + *is_present = pte & GEN8_PAGE_PRESENT; + *is_local = pte & GEN12_GGTT_PTE_LM; + + return pte & GEN12_GGTT_PTE_ADDR_MASK; +} + static bool should_update_ggtt_with_bind(struct i915_ggtt *ggtt) { struct intel_gt *gt = ggtt->vm.gt; @@ -435,6 +443,11 @@ static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte) writeq(pte, addr); } +static gen8_pte_t gen8_get_pte(void __iomem *addr) +{ + return readq(addr); +} + static void gen8_ggtt_insert_page(struct i915_address_space *vm, dma_addr_t addr, u64 offset, @@ -450,6 +463,16 @@ static void gen8_ggtt_insert_page(struct i915_address_space *vm, ggtt->invalidate(ggtt); } +static dma_addr_t gen8_ggtt_read_entry(struct i915_address_space *vm, + u64 offset, bool *is_present, bool *is_local) +{ + struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm); + gen8_pte_t __iomem *pte = + (gen8_pte_t __iomem *)ggtt->gsm + offset / I915_GTT_PAGE_SIZE; + + return ggtt->vm.pte_decode(gen8_get_pte(pte), is_present, is_local); +} + static void gen8_ggtt_insert_page_bind(struct i915_address_space *vm, dma_addr_t addr, u64 offset, unsigned int pat_index, u32 flags) @@ -605,6 +628,17 @@ static void gen6_ggtt_insert_page(struct i915_address_space *vm, ggtt->invalidate(ggtt); } +static dma_addr_t gen6_ggtt_read_entry(struct i915_address_space *vm, + u64 offset, + bool *is_present, bool *is_local) +{ + struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm); + gen6_pte_t __iomem *pte = + (gen6_pte_t __iomem *)ggtt->gsm + offset / I915_GTT_PAGE_SIZE; + + return vm->pte_decode(ioread32(pte), is_present, is_local); +} + /* * Binds an object into the global gtt with the specified cache level. * The object will be accessible to the GPU via commands whose operands @@ -769,6 +803,14 @@ void intel_ggtt_unbind_vma(struct i915_address_space *vm, vm->clear_range(vm, vma_res->start, vma_res->vma_size); } +dma_addr_t intel_ggtt_read_entry(struct i915_address_space *vm, + u64 offset, bool *is_present, bool *is_local) +{ + struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm); + + return ggtt->vm.read_entry(vm, offset, is_present, is_local); +} + /* * Reserve the top of the GuC address space for firmware images. Addresses * beyond GUC_GGTT_TOP in the GuC address space are inaccessible by GuC, @@ -1245,6 +1287,7 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt) ggtt->vm.scratch_range = gen8_ggtt_clear_range; ggtt->vm.insert_entries = gen8_ggtt_insert_entries; + ggtt->vm.read_entry = gen8_ggtt_read_entry; /* * Serialize GTT updates with aperture access on BXT if VT-d is on, @@ -1291,6 +1334,8 @@ static int gen8_gmch_probe(struct i915_ggtt *ggtt) else ggtt->vm.pte_encode = gen8_ggtt_pte_encode; + ggtt->vm.pte_decode = gen8_ggtt_pte_decode; + return ggtt_probe_common(ggtt, size); } @@ -1390,6 +1435,14 @@ static u64 iris_pte_encode(dma_addr_t addr, return pte; } +static dma_addr_t gen6_pte_decode(u64 pte, bool *is_present, bool *is_local) +{ + *is_present = pte & GEN6_PTE_VALID; + *is_local = false; + + return ((pte & 0xff0) << 28) | (pte & ~0xfff); +} + static int gen6_gmch_probe(struct i915_ggtt *ggtt) { struct drm_i915_private *i915 = ggtt->vm.i915; @@ -1428,6 +1481,7 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt) ggtt->vm.scratch_range = gen6_ggtt_clear_range; ggtt->vm.insert_page = gen6_ggtt_insert_page; ggtt->vm.insert_entries = gen6_ggtt_insert_entries; + ggtt->vm.read_entry = gen6_ggtt_read_entry; ggtt->vm.cleanup = gen6_gmch_remove; ggtt->invalidate = gen6_ggtt_invalidate; @@ -1443,6 +1497,8 @@ static int gen6_gmch_probe(struct i915_ggtt *ggtt) else ggtt->vm.pte_encode = snb_pte_encode; + ggtt->vm.pte_decode = gen6_pte_decode; + ggtt->vm.vma_ops.bind_vma = intel_ggtt_bind_vma; ggtt->vm.vma_ops.unbind_vma = intel_ggtt_unbind_vma; diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c b/drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c index 59eed0a0ce90..c5f5f0bdfb2c 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt_gmch.c @@ -27,6 +27,13 @@ static void gmch_ggtt_insert_page(struct i915_address_space *vm, intel_gmch_gtt_insert_page(addr, offset >> PAGE_SHIFT, flags); } +static dma_addr_t gmch_ggtt_read_entry(struct i915_address_space *vm, + u64 offset, bool *is_present, bool *is_local) +{ + return intel_gmch_gtt_read_entry(offset >> PAGE_SHIFT, + is_present, is_local); +} + static void gmch_ggtt_insert_entries(struct i915_address_space *vm, struct i915_vma_resource *vma_res, unsigned int pat_index, @@ -103,6 +110,7 @@ int intel_ggtt_gmch_probe(struct i915_ggtt *ggtt) ggtt->vm.insert_entries = gmch_ggtt_insert_entries; ggtt->vm.clear_range = gmch_ggtt_clear_range; ggtt->vm.scratch_range = gmch_ggtt_clear_range; + ggtt->vm.read_entry = gmch_ggtt_read_entry; ggtt->vm.cleanup = gmch_ggtt_remove; ggtt->invalidate = gmch_ggtt_invalidate; diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.c b/drivers/gpu/drm/i915/gt/intel_gtt.c index 30b128b1fde7..afbc5c769308 100644 --- a/drivers/gpu/drm/i915/gt/intel_gtt.c +++ b/drivers/gpu/drm/i915/gt/intel_gtt.c @@ -176,7 +176,6 @@ static void clear_vm_list(struct list_head *list) i915_vma_destroy_locked(vma); i915_gem_object_put(obj); } - } } diff --git a/drivers/gpu/drm/i915/gt/intel_gtt.h b/drivers/gpu/drm/i915/gt/intel_gtt.h index 0a36ea751b63..9d3a3ad567a0 100644 --- a/drivers/gpu/drm/i915/gt/intel_gtt.h +++ b/drivers/gpu/drm/i915/gt/intel_gtt.h @@ -312,6 +312,7 @@ struct i915_address_space { u64 (*pte_encode)(dma_addr_t addr, unsigned int pat_index, u32 flags); /* Create a valid PTE */ + dma_addr_t (*pte_decode)(u64 pte, bool *is_present, bool *is_local); #define PTE_READ_ONLY BIT(0) #define PTE_LM BIT(1) @@ -340,6 +341,8 @@ struct i915_address_space { struct i915_vma_resource *vma_res, unsigned int pat_index, u32 flags); + dma_addr_t (*read_entry)(struct i915_address_space *vm, + u64 offset, bool *is_present, bool *is_local); void (*cleanup)(struct i915_address_space *vm); void (*foreach)(struct i915_address_space *vm, @@ -590,6 +593,9 @@ void intel_ggtt_bind_vma(struct i915_address_space *vm, void intel_ggtt_unbind_vma(struct i915_address_space *vm, struct i915_vma_resource *vma_res); +dma_addr_t intel_ggtt_read_entry(struct i915_address_space *vm, + u64 offset, bool *is_present, bool *is_local); + int i915_ggtt_probe_hw(struct drm_i915_private *i915); int i915_ggtt_init_hw(struct drm_i915_private *i915); int i915_ggtt_enable_hw(struct drm_i915_private *i915); diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 51847a846002..c481b56fa67d 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -751,7 +751,6 @@ static int lrc_ring_indirect_offset(const struct intel_engine_cs *engine) static int lrc_ring_cmd_buf_cctl(const struct intel_engine_cs *engine) { - if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 55)) /* * Note that the CSFE context has a dummy slot for CMD_BUF_CCTL diff --git a/drivers/gpu/drm/i915/gt/intel_mocs.c b/drivers/gpu/drm/i915/gt/intel_mocs.c index cf41d325712e..5dd8121f4b15 100644 --- a/drivers/gpu/drm/i915/gt/intel_mocs.c +++ b/drivers/gpu/drm/i915/gt/intel_mocs.c @@ -314,7 +314,6 @@ static const struct drm_i915_mocs_entry icl_mocs_table[] = { }; static const struct drm_i915_mocs_entry dg1_mocs_table[] = { - /* UC */ MOCS_ENTRY(1, 0, L3_1_UC), /* WB - L3 */ diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c b/drivers/gpu/drm/i915/gt/intel_ring_submission.c index 6e9977b2d180..a876a34455f1 100644 --- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c @@ -365,7 +365,13 @@ static void reset_prepare(struct intel_engine_cs *engine) ENGINE_READ_FW(engine, RING_HEAD), ENGINE_READ_FW(engine, RING_TAIL), ENGINE_READ_FW(engine, RING_START)); - if (!stop_ring(engine)) { + /* + * Sometimes engine head failed to set to zero even after writing into it. + * Use wait_for_atomic() with 20ms delay to let engine resumes from + * correct RING_HEAD. Experimented different values and determined + * that 20ms works best based on testing. + */ + if (wait_for_atomic((!stop_ring(engine) == 0), 20)) { drm_err(&engine->i915->drm, "failed to set %s head to zero " "ctl %08x head %08x tail %08x start %08x\n", diff --git a/drivers/gpu/drm/i915/gt/intel_rps.c b/drivers/gpu/drm/i915/gt/intel_rps.c index 71ee01d9ef64..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" @@ -550,6 +550,7 @@ static unsigned int init_emon(struct intel_uncore *uncore) static bool gen5_rps_enable(struct intel_rps *rps) { struct drm_i915_private *i915 = rps_to_i915(rps); + struct intel_display *display = &i915->display; struct intel_uncore *uncore = rps_to_uncore(rps); u8 fstart, vstart; u32 rgvmodectl; @@ -607,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(i915, DE_PCU_EVENT); - spin_unlock(&i915->irq_lock); + ilk_display_rps_enable(display); spin_unlock_irq(&mchdev_lock); @@ -621,14 +620,13 @@ static bool gen5_rps_enable(struct intel_rps *rps) static void gen5_rps_disable(struct intel_rps *rps) { struct drm_i915_private *i915 = rps_to_i915(rps); + struct intel_display *display = &i915->display; struct intel_uncore *uncore = rps_to_uncore(rps); u16 rgvswctl; spin_lock_irq(&mchdev_lock); - spin_lock(&i915->irq_lock); - ilk_disable_display_irq(i915, 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/gt/intel_wopcm.h b/drivers/gpu/drm/i915/gt/intel_wopcm.h index 17d6aa86008a..d2038b6de5e7 100644 --- a/drivers/gpu/drm/i915/gt/intel_wopcm.h +++ b/drivers/gpu/drm/i915/gt/intel_wopcm.h @@ -1,6 +1,5 @@ +/* SPDX-License-Identifier: MIT */ /* - * SPDX-License-Identifier: MIT - * * Copyright © 2017-2018 Intel Corporation */ diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index 116683ebe074..b37e400f74e5 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -156,7 +156,7 @@ static void _wa_add(struct i915_wa_list *wal, const struct i915_wa *wa) if (IS_ALIGNED(wal->count, grow)) { /* Either uninitialized or full. */ struct i915_wa *list; - list = kmalloc_array(ALIGN(wal->count + 1, grow), sizeof(*wa), + list = kmalloc_array(ALIGN(wal->count + 1, grow), sizeof(*list), GFP_KERNEL); if (!list) { drm_err(&i915->drm, "No space for workaround init!\n"); diff --git a/drivers/gpu/drm/i915/gt/selftest_lrc.c b/drivers/gpu/drm/i915/gt/selftest_lrc.c index 22e750108c5f..23f04f6f8fba 100644 --- a/drivers/gpu/drm/i915/gt/selftest_lrc.c +++ b/drivers/gpu/drm/i915/gt/selftest_lrc.c @@ -7,6 +7,7 @@ #include "gem/i915_gem_internal.h" +#include "i915_drv.h" #include "i915_selftest.h" #include "intel_engine_heartbeat.h" #include "intel_engine_pm.h" @@ -859,6 +860,14 @@ static int live_lrc_timestamp(void *arg) }; /* + * This test was designed to isolate a hardware bug. + * The bug was found and fixed in future generations but + * now the test pollutes our CI on previous generation. + */ + if (GRAPHICS_VER(gt->i915) == 12) + return 0; + + /* * We want to verify that the timestamp is saved and restore across * context switches and is monotonic. * diff --git a/drivers/gpu/drm/i915/gt/selftest_migrate.c b/drivers/gpu/drm/i915/gt/selftest_migrate.c index 401bee030dbc..32c762eb79ed 100644 --- a/drivers/gpu/drm/i915/gt/selftest_migrate.c +++ b/drivers/gpu/drm/i915/gt/selftest_migrate.c @@ -661,7 +661,7 @@ static int live_emit_pte_full_ring(void *arg) out_rq: i915_request_add(rq); /* GEM_BUG_ON(rq->reserved_space > ring->space)? */ timer_delete_sync(&st.timer); - destroy_timer_on_stack(&st.timer); + timer_destroy_on_stack(&st.timer); out_unpin: intel_context_unpin(ce); out_put: diff --git a/drivers/gpu/drm/i915/gt/selftest_rc6.c b/drivers/gpu/drm/i915/gt/selftest_rc6.c index 908483ab0bc8..41716ed454b7 100644 --- a/drivers/gpu/drm/i915/gt/selftest_rc6.c +++ b/drivers/gpu/drm/i915/gt/selftest_rc6.c @@ -33,15 +33,22 @@ int live_rc6_manual(void *arg) { struct intel_gt *gt = arg; struct intel_rc6 *rc6 = >->rc6; - u64 rc0_power, rc6_power; + struct intel_rps *rps = >->rps; intel_wakeref_t wakeref; + u64 rc0_sample_energy[2]; + u64 rc6_sample_energy[2]; + u64 sleep_time = 1000; + u32 rc0_freq = 0; + u32 rc6_freq = 0; + u64 rc0_power; + u64 rc6_power; bool has_power; + u64 threshold; ktime_t dt; u64 res[2]; int err = 0; - u32 rc0_freq = 0; - u32 rc6_freq = 0; - struct intel_rps *rps = >->rps; + u64 diff; + /* * Our claim is that we can "encourage" the GPU to enter rc6 at will. @@ -60,14 +67,15 @@ int live_rc6_manual(void *arg) /* Force RC6 off for starters */ __intel_rc6_disable(rc6); - msleep(1); /* wakeup is not immediate, takes about 100us on icl */ + /* wakeup is not immediate, takes about 100us on icl */ + usleep_range(1000, 2000); res[0] = rc6_residency(rc6); dt = ktime_get(); - rc0_power = librapl_energy_uJ(); - msleep(1000); - rc0_power = librapl_energy_uJ() - rc0_power; + rc0_sample_energy[0] = librapl_energy_uJ(); + msleep(sleep_time); + rc0_sample_energy[1] = librapl_energy_uJ() - rc0_sample_energy[0]; dt = ktime_sub(ktime_get(), dt); res[1] = rc6_residency(rc6); rc0_freq = intel_rps_read_actual_frequency_fw(rps); @@ -79,11 +87,12 @@ int live_rc6_manual(void *arg) } if (has_power) { - rc0_power = div64_u64(NSEC_PER_SEC * rc0_power, + rc0_power = div64_u64(NSEC_PER_SEC * rc0_sample_energy[1], ktime_to_ns(dt)); + if (!rc0_power) { if (rc0_freq) - pr_debug("No power measured while in RC0! GPU Freq: %u in RC0\n", + pr_debug("No power measured while in RC0! GPU Freq: %uMHz in RC0\n", rc0_freq); else pr_err("No power and freq measured while in RC0\n"); @@ -98,10 +107,10 @@ int live_rc6_manual(void *arg) res[0] = rc6_residency(rc6); intel_uncore_forcewake_flush(rc6_to_uncore(rc6), FORCEWAKE_ALL); dt = ktime_get(); - rc6_power = librapl_energy_uJ(); - msleep(1000); + rc6_sample_energy[0] = librapl_energy_uJ(); + msleep(sleep_time); rc6_freq = intel_rps_read_actual_frequency_fw(rps); - rc6_power = librapl_energy_uJ() - rc6_power; + rc6_sample_energy[1] = librapl_energy_uJ() - rc6_sample_energy[0]; dt = ktime_sub(ktime_get(), dt); res[1] = rc6_residency(rc6); if (res[1] == res[0]) { @@ -113,13 +122,24 @@ int live_rc6_manual(void *arg) } if (has_power) { - rc6_power = div64_u64(NSEC_PER_SEC * rc6_power, + rc6_power = div64_u64(NSEC_PER_SEC * rc6_sample_energy[1], ktime_to_ns(dt)); - pr_info("GPU consumed %llduW in RC0 and %llduW in RC6\n", + pr_info("GPU consumed %lluuW in RC0 and %lluuW in RC6\n", rc0_power, rc6_power); + if (2 * rc6_power > rc0_power) { - pr_err("GPU leaked energy while in RC6! GPU Freq: %u in RC6 and %u in RC0\n", - rc6_freq, rc0_freq); + pr_err("GPU leaked energy while in RC6!\n" + "GPU Freq: %uMHz in RC6 and %uMHz in RC0\n" + "RC0 energy before & after sleep respectively: %lluuJ %lluuJ\n" + "RC6 energy before & after sleep respectively: %lluuJ %lluuJ\n", + rc6_freq, rc0_freq, rc0_sample_energy[0], rc0_sample_energy[1], + rc6_sample_energy[0], rc6_sample_energy[1]); + + diff = res[1] - res[0]; + threshold = (9 * NSEC_PER_MSEC * sleep_time) / 10; + if (diff < threshold) + pr_err("Did not enter RC6 properly, RC6 start residency=%lluns, RC6 end residency=%lluns\n", + res[0], res[1]); err = -EINVAL; goto out_unlock; } diff --git a/drivers/gpu/drm/i915/gt/selftest_tlb.c b/drivers/gpu/drm/i915/gt/selftest_tlb.c index 3941f2d6fa47..69ed946a39e5 100644 --- a/drivers/gpu/drm/i915/gt/selftest_tlb.c +++ b/drivers/gpu/drm/i915/gt/selftest_tlb.c @@ -143,7 +143,7 @@ pte_tlbinv(struct intel_context *ce, if (ce->engine->class == OTHER_CLASS) msleep(200); else - msleep(10); + usleep_range(10000, 20000); if (va == vb) { if (!i915_request_completed(rq)) { diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c index 5dc0ccd07636..d550eb6edfb8 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_fw.c @@ -230,7 +230,7 @@ int intel_gsc_fw_get_binary_info(struct intel_uc_fw *gsc_fw, const void *data, s gt_info(gt, "Invalid GSC firmware for MTL/ARL, got %d.%d.%d.%d but need 102.x.x.x", gsc->release.major, gsc->release.minor, gsc->release.patch, gsc->release.build); - return -EINVAL; + return -EINVAL; } if (min_ver.major) { diff --git a/drivers/gpu/drm/i915/gvt/aperture_gm.c b/drivers/gpu/drm/i915/gvt/aperture_gm.c index eedd1865bb98..62d14f82256f 100644 --- a/drivers/gpu/drm/i915/gvt/aperture_gm.c +++ b/drivers/gpu/drm/i915/gvt/aperture_gm.c @@ -46,6 +46,7 @@ static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm) unsigned int flags; u64 start, end, size; struct drm_mm_node *node; + intel_wakeref_t wakeref; int ret; if (high_gm) { @@ -63,12 +64,12 @@ static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm) } mutex_lock(>->ggtt->vm.mutex); - mmio_hw_access_pre(gt); + wakeref = mmio_hw_access_pre(gt); ret = i915_gem_gtt_insert(>->ggtt->vm, NULL, node, size, I915_GTT_PAGE_SIZE, I915_COLOR_UNEVICTABLE, start, end, flags); - mmio_hw_access_post(gt); + mmio_hw_access_post(gt, wakeref); mutex_unlock(>->ggtt->vm.mutex); if (ret) gvt_err("fail to alloc %s gm space from host\n", @@ -226,7 +227,7 @@ out_free_fence: vgpu->fence.regs[i] = NULL; } mutex_unlock(&gvt->gt->ggtt->vm.mutex); - intel_runtime_pm_put_unchecked(uncore->rpm); + intel_runtime_pm_put(uncore->rpm, wakeref); return -ENOSPC; } diff --git a/drivers/gpu/drm/i915/gvt/debugfs.c b/drivers/gpu/drm/i915/gvt/debugfs.c index baccbf1761b7..673534f061ef 100644 --- a/drivers/gpu/drm/i915/gvt/debugfs.c +++ b/drivers/gpu/drm/i915/gvt/debugfs.c @@ -91,16 +91,17 @@ static int vgpu_mmio_diff_show(struct seq_file *s, void *unused) .diff = 0, }; struct diff_mmio *node, *next; + intel_wakeref_t wakeref; INIT_LIST_HEAD(¶m.diff_mmio_list); mutex_lock(&gvt->lock); spin_lock_bh(&gvt->scheduler.mmio_context_lock); - mmio_hw_access_pre(gvt->gt); + wakeref = mmio_hw_access_pre(gvt->gt); /* Recognize all the diff mmios to list. */ intel_gvt_for_each_tracked_mmio(gvt, mmio_diff_handler, ¶m); - mmio_hw_access_post(gvt->gt); + mmio_hw_access_post(gvt->gt, wakeref); spin_unlock_bh(&gvt->scheduler.mmio_context_lock); mutex_unlock(&gvt->lock); diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 2fa7ca19ba5d..ae9b0ded3651 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -220,9 +220,11 @@ static u64 read_pte64(struct i915_ggtt *ggtt, unsigned long index) static void ggtt_invalidate(struct intel_gt *gt) { - mmio_hw_access_pre(gt); + intel_wakeref_t wakeref; + + wakeref = mmio_hw_access_pre(gt); intel_uncore_write(gt->uncore, GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); - mmio_hw_access_post(gt); + mmio_hw_access_post(gt, wakeref); } static void write_pte64(struct i915_ggtt *ggtt, unsigned long index, u64 pte) diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index 01d890999f25..1d10c16e6465 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -570,14 +570,15 @@ enum { GVT_FAILSAFE_GUEST_ERR, }; -static inline void mmio_hw_access_pre(struct intel_gt *gt) +static inline intel_wakeref_t mmio_hw_access_pre(struct intel_gt *gt) { - intel_runtime_pm_get(gt->uncore->rpm); + return intel_runtime_pm_get(gt->uncore->rpm); } -static inline void mmio_hw_access_post(struct intel_gt *gt) +static inline void mmio_hw_access_post(struct intel_gt *gt, + intel_wakeref_t wakeref) { - intel_runtime_pm_put_unchecked(gt->uncore->rpm); + intel_runtime_pm_put(gt->uncore->rpm, wakeref); } /** diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 4efee6797873..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" @@ -264,6 +265,7 @@ static int fence_mmio_write(struct intel_vgpu *vgpu, unsigned int off, { struct intel_gvt *gvt = vgpu->gvt; unsigned int fence_num = offset_to_fence_num(off); + intel_wakeref_t wakeref; int ret; ret = sanitize_fence_mmio_access(vgpu, fence_num, p_data, bytes); @@ -271,10 +273,10 @@ static int fence_mmio_write(struct intel_vgpu *vgpu, unsigned int off, return ret; write_vreg(vgpu, off, p_data, bytes); - mmio_hw_access_pre(gvt->gt); + wakeref = mmio_hw_access_pre(gvt->gt); intel_vgpu_write_fence(vgpu, fence_num, vgpu_vreg64(vgpu, fence_num_to_offset(fence_num))); - mmio_hw_access_post(gvt->gt); + mmio_hw_access_post(gvt->gt, wakeref); return 0; } @@ -513,7 +515,7 @@ static u32 bdw_vgpu_get_dp_bitrate(struct intel_vgpu *vgpu, enum port port) switch (wrpll_ctl & WRPLL_REF_MASK) { case WRPLL_REF_PCH_SSC: - refclk = vgpu->gvt->gt->i915->display.dpll.ref_clks.ssc; + refclk = 135000; break; case WRPLL_REF_LCPLL: refclk = 2700000; @@ -544,7 +546,7 @@ out: static u32 bxt_vgpu_get_dp_bitrate(struct intel_vgpu *vgpu, enum port port) { u32 dp_br = 0; - int refclk = vgpu->gvt->gt->i915->display.dpll.ref_clks.nssc; + int refclk = 100000; enum dpio_phy phy = DPIO_PHY0; enum dpio_channel ch = DPIO_CH0; struct dpll clock = {}; @@ -1975,10 +1977,12 @@ static int mmio_read_from_hw(struct intel_vgpu *vgpu, vgpu == gvt->scheduler.engine_owner[engine->id] || offset == i915_mmio_reg_offset(RING_TIMESTAMP(engine->mmio_base)) || offset == i915_mmio_reg_offset(RING_TIMESTAMP_UDW(engine->mmio_base))) { - mmio_hw_access_pre(gvt->gt); + intel_wakeref_t wakeref; + + wakeref = mmio_hw_access_pre(gvt->gt); vgpu_vreg(vgpu, offset) = intel_uncore_read(gvt->gt->uncore, _MMIO(offset)); - mmio_hw_access_post(gvt->gt); + mmio_hw_access_post(gvt->gt, wakeref); } return intel_vgpu_default_mmio_read(vgpu, offset, p_data, bytes); @@ -3209,10 +3213,12 @@ void intel_gvt_restore_fence(struct intel_gvt *gvt) int i, id; idr_for_each_entry(&(gvt)->vgpu_idr, vgpu, id) { - mmio_hw_access_pre(gvt->gt); + intel_wakeref_t wakeref; + + wakeref = mmio_hw_access_pre(gvt->gt); for (i = 0; i < vgpu_fence_sz(vgpu); i++) intel_vgpu_write_fence(vgpu, i, vgpu_vreg64(vgpu, fence_num_to_offset(i))); - mmio_hw_access_post(gvt->gt); + mmio_hw_access_post(gvt->gt, wakeref); } } @@ -3233,8 +3239,10 @@ void intel_gvt_restore_mmio(struct intel_gvt *gvt) int id; idr_for_each_entry(&(gvt)->vgpu_idr, vgpu, id) { - mmio_hw_access_pre(gvt->gt); + intel_wakeref_t wakeref; + + wakeref = mmio_hw_access_pre(gvt->gt); intel_gvt_for_each_tracked_mmio(gvt, mmio_pm_restore_handler, vgpu); - mmio_hw_access_post(gvt->gt); + mmio_hw_access_post(gvt->gt, wakeref); } } diff --git a/drivers/gpu/drm/i915/gvt/sched_policy.c b/drivers/gpu/drm/i915/gvt/sched_policy.c index 9f97f743aa71..6c2d68e88266 100644 --- a/drivers/gpu/drm/i915/gvt/sched_policy.c +++ b/drivers/gpu/drm/i915/gvt/sched_policy.c @@ -447,6 +447,7 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu) struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915; struct intel_engine_cs *engine; enum intel_engine_id id; + intel_wakeref_t wakeref; if (!vgpu_data->active) return; @@ -465,7 +466,7 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu) scheduler->current_vgpu = NULL; } - intel_runtime_pm_get(&dev_priv->runtime_pm); + wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm); spin_lock_bh(&scheduler->mmio_context_lock); for_each_engine(engine, vgpu->gvt->gt, id) { if (scheduler->engine_owner[engine->id] == vgpu) { @@ -474,6 +475,6 @@ void intel_vgpu_stop_schedule(struct intel_vgpu *vgpu) } } spin_unlock_bh(&scheduler->mmio_context_lock); - intel_runtime_pm_put_unchecked(&dev_priv->runtime_pm); + intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref); mutex_unlock(&vgpu->gvt->sched_lock); } diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 0d9e263913ff..967c0501e91e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -66,8 +66,6 @@ static int i915_capabilities(struct seq_file *m, void *data) struct drm_i915_private *i915 = node_to_i915(m->private); struct drm_printer p = drm_seq_file_printer(m); - seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(i915)); - intel_device_info_print(INTEL_INFO(i915), RUNTIME_INFO(i915), &p); i915_print_iommu_status(i915, &p); intel_gt_info_print(&to_gt(i915)->info, &p); diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index ce3cc93ea211..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); @@ -578,7 +573,7 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv) */ intel_dram_detect(dev_priv); - intel_bw_init_hw(dev_priv); + intel_bw_init_hw(display); return 0; @@ -622,11 +617,12 @@ static void i915_driver_hw_remove(struct drm_i915_private *dev_priv) * Perform any steps necessary to make the driver available via kernel * internal or userspace interfaces. */ -static void i915_driver_register(struct drm_i915_private *dev_priv) +static int i915_driver_register(struct drm_i915_private *dev_priv) { struct intel_display *display = &dev_priv->display; struct intel_gt *gt; unsigned int i; + int ret; i915_gem_driver_register(dev_priv); i915_pmu_register(dev_priv); @@ -634,10 +630,14 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) intel_vgpu_register(dev_priv); /* Reveal our presence to userspace */ - if (drm_dev_register(&dev_priv->drm, 0)) { - drm_err(&dev_priv->drm, - "Failed to register driver for userspace access!\n"); - return; + ret = drm_dev_register(&dev_priv->drm, 0); + if (ret) { + i915_probe_error(dev_priv, + "Failed to register driver for userspace access!\n"); + drm_dev_unregister(&dev_priv->drm); + i915_pmu_unregister(dev_priv); + i915_gem_driver_unregister(dev_priv); + return ret; } i915_debugfs_register(dev_priv); @@ -660,6 +660,8 @@ static void i915_driver_register(struct drm_i915_private *dev_priv) if (i915_switcheroo_register(dev_priv)) drm_err(&dev_priv->drm, "Failed to register vga switcheroo!\n"); + + return 0; } /** @@ -834,7 +836,9 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) goto out_cleanup_gem; - i915_driver_register(i915); + ret = i915_driver_register(i915); + if (ret) + goto out_cleanup_gem; enable_rpm_wakeref_asserts(&i915->runtime_pm); @@ -845,6 +849,7 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return 0; out_cleanup_gem: + intel_pxp_fini(i915); i915_gem_suspend(i915); i915_gem_driver_remove(i915); i915_gem_driver_release(i915); @@ -981,7 +986,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915) intel_dp_mst_suspend(display); intel_irq_suspend(i915); - intel_hpd_cancel_work(i915); + intel_hpd_cancel_work(display); if (HAS_DISPLAY(i915)) intel_display_driver_suspend_access(display); @@ -1064,7 +1069,7 @@ static int i915_drm_suspend(struct drm_device *dev) intel_display_driver_suspend(display); intel_irq_suspend(dev_priv); - intel_hpd_cancel_work(dev_priv); + intel_hpd_cancel_work(display); if (HAS_DISPLAY(dev_priv)) intel_display_driver_suspend_access(display); @@ -1195,13 +1200,11 @@ 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); - intel_init_pch_refclk(dev_priv); + intel_init_pch_refclk(display); /* * Interrupts have to be enabled before any batches are run. If not the @@ -1227,7 +1230,7 @@ static int i915_drm_resume(struct drm_device *dev) if (HAS_DISPLAY(dev_priv)) intel_display_driver_resume_access(display); - intel_hpd_init(dev_priv); + intel_hpd_init(display); intel_display_driver_resume(display); @@ -1235,7 +1238,7 @@ static int i915_drm_resume(struct drm_device *dev) intel_display_driver_enable_user_access(display); drm_kms_helper_poll_enable(dev); } - intel_hpd_poll_disable(dev_priv); + intel_hpd_poll_disable(display); intel_opregion_resume(display); @@ -1575,7 +1578,7 @@ static int intel_runtime_suspend(struct device *kdev) assert_forcewakes_inactive(&dev_priv->uncore); if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) - intel_hpd_poll_enable(dev_priv); + intel_hpd_poll_enable(display); drm_dbg(&dev_priv->drm, "Device suspended\n"); return 0; @@ -1633,11 +1636,11 @@ static int intel_runtime_resume(struct device *kdev) * everyone else do it here. */ if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) { - intel_hpd_init(dev_priv); - intel_hpd_poll_disable(dev_priv); + intel_hpd_init(display); + intel_hpd_poll_disable(display); } - skl_watermark_ipc_update(dev_priv); + skl_watermark_ipc_update(display); enable_rpm_wakeref_asserts(rpm); 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 54538b6f85df..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; @@ -306,6 +299,7 @@ struct drm_i915_private { INTEL_DRAM_LPDDR5, INTEL_DRAM_GDDR, INTEL_DRAM_GDDR_ECC, + __INTEL_DRAM_TYPE_MAX, } type; u8 num_qgv_points; u8 num_psf_gv_points; 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 37ca4a35daf2..95042879bec4 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -277,14 +277,14 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) intel_uncore_write(&dev_priv->uncore, GEN6_PMIIR, pm_iir); if (iir & I915_DISPLAY_PORT_INTERRUPT) - hotplug_status = i9xx_hpd_irq_ack(dev_priv); + hotplug_status = i9xx_hpd_irq_ack(display); if (iir & I915_MASTER_ERROR_INTERRUPT) vlv_display_error_irq_ack(display, &eir, &dpinvgtt); /* Call regardless, as some status bits might not be * signalled in IIR */ - i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); + i9xx_pipestat_irq_ack(display, iir, pipe_stats); if (iir & (I915_LPE_PIPE_A_INTERRUPT | I915_LPE_PIPE_B_INTERRUPT)) @@ -306,12 +306,12 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) gen6_rps_irq_handler(&to_gt(dev_priv)->rps, pm_iir); if (hotplug_status) - i9xx_hpd_irq_handler(dev_priv, hotplug_status); + i9xx_hpd_irq_handler(display, hotplug_status); if (iir & I915_MASTER_ERROR_INTERRUPT) vlv_display_error_irq_handler(display, eir, dpinvgtt); - valleyview_pipestat_irq_handler(dev_priv, pipe_stats); + valleyview_pipestat_irq_handler(display, pipe_stats); } while (0); pmu_irq_stats(dev_priv, ret); @@ -367,14 +367,14 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) gen8_gt_irq_handler(to_gt(dev_priv), master_ctl); if (iir & I915_DISPLAY_PORT_INTERRUPT) - hotplug_status = i9xx_hpd_irq_ack(dev_priv); + hotplug_status = i9xx_hpd_irq_ack(display); if (iir & I915_MASTER_ERROR_INTERRUPT) vlv_display_error_irq_ack(display, &eir, &dpinvgtt); /* Call regardless, as some status bits might not be * signalled in IIR */ - i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); + i9xx_pipestat_irq_ack(display, iir, pipe_stats); if (iir & (I915_LPE_PIPE_A_INTERRUPT | I915_LPE_PIPE_B_INTERRUPT | @@ -392,12 +392,12 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); if (hotplug_status) - i9xx_hpd_irq_handler(dev_priv, hotplug_status); + i9xx_hpd_irq_handler(display, hotplug_status); if (iir & I915_MASTER_ERROR_INTERRUPT) vlv_display_error_irq_handler(display, eir, dpinvgtt); - valleyview_pipestat_irq_handler(dev_priv, pipe_stats); + valleyview_pipestat_irq_handler(display, pipe_stats); } while (0); pmu_irq_stats(dev_priv, ret); @@ -418,6 +418,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) static irqreturn_t ilk_irq_handler(int irq, void *arg) { struct drm_i915_private *i915 = arg; + struct intel_display *display = &i915->display; void __iomem * const regs = intel_uncore_regs(&i915->uncore); u32 de_iir, gt_iir, de_ier, sde_ier = 0; irqreturn_t ret = IRQ_NONE; @@ -458,9 +459,9 @@ static irqreturn_t ilk_irq_handler(int irq, void *arg) if (de_iir) { raw_reg_write(regs, DEIIR, de_iir); if (DISPLAY_VER(i915) >= 7) - ivb_display_irq_handler(i915, de_iir); + ivb_display_irq_handler(display, de_iir); else - ilk_display_irq_handler(i915, de_iir); + ilk_display_irq_handler(display, de_iir); ret = IRQ_HANDLED; } @@ -506,6 +507,7 @@ static inline void gen8_master_intr_enable(void __iomem * const regs) static irqreturn_t gen8_irq_handler(int irq, void *arg) { struct drm_i915_private *dev_priv = arg; + struct intel_display *display = &dev_priv->display; void __iomem * const regs = intel_uncore_regs(&dev_priv->uncore); u32 master_ctl; @@ -524,7 +526,7 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg) /* IRQs are synced during runtime_suspend, we don't require a wakeref */ if (master_ctl & ~GEN8_GT_IRQS) { disable_rpm_wakeref_asserts(&dev_priv->runtime_pm); - gen8_de_irq_handler(dev_priv, master_ctl); + gen8_de_irq_handler(display, master_ctl); enable_rpm_wakeref_asserts(&dev_priv->runtime_pm); } @@ -556,6 +558,7 @@ static inline void gen11_master_intr_enable(void __iomem * const regs) static irqreturn_t gen11_irq_handler(int irq, void *arg) { struct drm_i915_private *i915 = arg; + struct intel_display *display = &i915->display; void __iomem * const regs = intel_uncore_regs(&i915->uncore); struct intel_gt *gt = to_gt(i915); u32 master_ctl; @@ -575,13 +578,13 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg) /* IRQs are synced during runtime_suspend, we don't require a wakeref */ if (master_ctl & GEN11_DISPLAY_IRQ) - gen11_display_irq_handler(i915); + gen11_display_irq_handler(display); - gu_misc_iir = gen11_gu_misc_irq_ack(i915, master_ctl); + gu_misc_iir = gen11_gu_misc_irq_ack(display, master_ctl); gen11_master_intr_enable(regs); - gen11_gu_misc_irq_handler(i915, gu_misc_iir); + gen11_gu_misc_irq_handler(display, gu_misc_iir); pmu_irq_stats(i915, IRQ_HANDLED); @@ -613,6 +616,7 @@ static inline void dg1_master_intr_enable(void __iomem * const regs) static irqreturn_t dg1_irq_handler(int irq, void *arg) { struct drm_i915_private * const i915 = arg; + struct intel_display *display = &i915->display; struct intel_gt *gt = to_gt(i915); void __iomem * const regs = intel_uncore_regs(gt->uncore); u32 master_tile_ctl, master_ctl; @@ -641,36 +645,22 @@ static irqreturn_t dg1_irq_handler(int irq, void *arg) gen11_gt_irq_handler(gt, master_ctl); if (master_ctl & GEN11_DISPLAY_IRQ) - gen11_display_irq_handler(i915); + gen11_display_irq_handler(display); - gu_misc_iir = gen11_gu_misc_irq_ack(i915, master_ctl); + gu_misc_iir = gen11_gu_misc_irq_ack(display, master_ctl); dg1_master_intr_enable(regs); - gen11_gu_misc_irq_handler(i915, gu_misc_iir); + gen11_gu_misc_irq_handler(display, gu_misc_iir); pmu_irq_stats(i915, IRQ_HANDLED); 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); @@ -686,45 +676,43 @@ 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) { + struct intel_display *display = &dev_priv->display; + intel_uncore_write(&dev_priv->uncore, VLV_MASTER_IER, 0); intel_uncore_posting_read(&dev_priv->uncore, VLV_MASTER_IER); gen5_gt_irq_reset(to_gt(dev_priv)); - spin_lock_irq(&dev_priv->irq_lock); - vlv_display_irq_reset(dev_priv); - spin_unlock_irq(&dev_priv->irq_lock); + vlv_display_irq_reset(display); } static void gen8_irq_reset(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct intel_uncore *uncore = &dev_priv->uncore; gen8_master_intr_disable(intel_uncore_regs(uncore)); gen8_gt_irq_reset(to_gt(dev_priv)); - gen8_display_irq_reset(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) { + struct intel_display *display = &dev_priv->display; struct intel_gt *gt = to_gt(dev_priv); struct intel_uncore *uncore = gt->uncore; gen11_master_intr_disable(intel_uncore_regs(&dev_priv->uncore)); gen11_gt_irq_reset(gt); - gen11_display_irq_reset(dev_priv); + gen11_display_irq_reset(display); gen2_irq_reset(uncore, GEN11_GU_MISC_IRQ_REGS); gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS); @@ -732,6 +720,7 @@ static void gen11_irq_reset(struct drm_i915_private *dev_priv) static void dg1_irq_reset(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct intel_uncore *uncore = &dev_priv->uncore; struct intel_gt *gt; unsigned int i; @@ -741,7 +730,7 @@ static void dg1_irq_reset(struct drm_i915_private *dev_priv) for_each_gt(gt, dev_priv, i) gen11_gt_irq_reset(gt); - gen11_display_irq_reset(dev_priv); + gen11_display_irq_reset(display); gen2_irq_reset(uncore, GEN11_GU_MISC_IRQ_REGS); gen2_irq_reset(uncore, GEN8_PCU_IRQ_REGS); @@ -751,6 +740,7 @@ static void dg1_irq_reset(struct drm_i915_private *dev_priv) static void cherryview_irq_reset(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct intel_uncore *uncore = &dev_priv->uncore; intel_uncore_write(uncore, GEN8_MASTER_IRQ, 0); @@ -760,25 +750,25 @@ 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(dev_priv); - spin_unlock_irq(&dev_priv->irq_lock); + vlv_display_irq_reset(display); } static void ilk_irq_postinstall(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; + gen5_gt_irq_postinstall(to_gt(dev_priv)); - ilk_de_irq_postinstall(dev_priv); + ilk_de_irq_postinstall(display); } static void valleyview_irq_postinstall(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; + gen5_gt_irq_postinstall(to_gt(dev_priv)); - spin_lock_irq(&dev_priv->irq_lock); - vlv_display_irq_postinstall(dev_priv); - spin_unlock_irq(&dev_priv->irq_lock); + vlv_display_irq_postinstall(display); intel_uncore_write(&dev_priv->uncore, VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE); intel_uncore_posting_read(&dev_priv->uncore, VLV_MASTER_IER); @@ -786,20 +776,23 @@ static void valleyview_irq_postinstall(struct drm_i915_private *dev_priv) static void gen8_irq_postinstall(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; + gen8_gt_irq_postinstall(to_gt(dev_priv)); - gen8_de_irq_postinstall(dev_priv); + gen8_de_irq_postinstall(display); gen8_master_intr_enable(intel_uncore_regs(&dev_priv->uncore)); } static void gen11_irq_postinstall(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct intel_gt *gt = to_gt(dev_priv); struct intel_uncore *uncore = gt->uncore; u32 gu_misc_masked = GEN11_GU_MISC_GSE; gen11_gt_irq_postinstall(gt); - gen11_de_irq_postinstall(dev_priv); + gen11_de_irq_postinstall(display); gen2_irq_init(uncore, GEN11_GU_MISC_IRQ_REGS, ~gu_misc_masked, gu_misc_masked); @@ -809,6 +802,7 @@ static void gen11_irq_postinstall(struct drm_i915_private *dev_priv) static void dg1_irq_postinstall(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct intel_uncore *uncore = &dev_priv->uncore; u32 gu_misc_masked = GEN11_GU_MISC_GSE; struct intel_gt *gt; @@ -819,7 +813,7 @@ static void dg1_irq_postinstall(struct drm_i915_private *dev_priv) gen2_irq_init(uncore, GEN11_GU_MISC_IRQ_REGS, ~gu_misc_masked, gu_misc_masked); - dg1_de_irq_postinstall(dev_priv); + dg1_de_irq_postinstall(display); dg1_master_intr_enable(intel_uncore_regs(uncore)); intel_uncore_posting_read(uncore, DG1_MSTR_TILE_INTR); @@ -827,11 +821,11 @@ static void dg1_irq_postinstall(struct drm_i915_private *dev_priv) static void cherryview_irq_postinstall(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; + gen8_gt_irq_postinstall(to_gt(dev_priv)); - spin_lock_irq(&dev_priv->irq_lock); - vlv_display_irq_postinstall(dev_priv); - spin_unlock_irq(&dev_priv->irq_lock); + vlv_display_irq_postinstall(display); intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); intel_uncore_posting_read(&dev_priv->uncore, GEN8_MASTER_IRQ); @@ -900,9 +894,10 @@ static void i9xx_error_irq_handler(struct drm_i915_private *dev_priv, static void i915_irq_reset(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct intel_uncore *uncore = &dev_priv->uncore; - i9xx_display_irq_reset(dev_priv); + i9xx_display_irq_reset(display); gen2_error_reset(uncore, GEN2_ERROR_REGS); gen2_irq_reset(uncore, GEN2_IRQ_REGS); @@ -911,6 +906,7 @@ static void i915_irq_reset(struct drm_i915_private *dev_priv) static void i915_irq_postinstall(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct intel_uncore *uncore = &dev_priv->uncore; u32 enable_mask; @@ -932,26 +928,20 @@ static void i915_irq_postinstall(struct drm_i915_private *dev_priv) enable_mask |= I915_ASLE_INTERRUPT; } - if (I915_HAS_HOTPLUG(dev_priv)) { + if (HAS_HOTPLUG(dev_priv)) { dev_priv->irq_mask &= ~I915_DISPLAY_PORT_INTERRUPT; enable_mask |= I915_DISPLAY_PORT_INTERRUPT; } 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(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); - i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); - spin_unlock_irq(&dev_priv->irq_lock); - - i915_enable_asle_pipestat(dev_priv); + i915_display_irq_postinstall(display); } static irqreturn_t i915_irq_handler(int irq, void *arg) { struct drm_i915_private *dev_priv = arg; + struct intel_display *display = &dev_priv->display; irqreturn_t ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) @@ -972,13 +962,13 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) ret = IRQ_HANDLED; - if (I915_HAS_HOTPLUG(dev_priv) && + if (HAS_HOTPLUG(dev_priv) && iir & I915_DISPLAY_PORT_INTERRUPT) - hotplug_status = i9xx_hpd_irq_ack(dev_priv); + hotplug_status = i9xx_hpd_irq_ack(display); /* Call regardless, as some status bits might not be * signalled in IIR */ - i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); + i9xx_pipestat_irq_ack(display, iir, pipe_stats); if (iir & I915_MASTER_ERROR_INTERRUPT) i9xx_error_irq_ack(dev_priv, &eir, &eir_stuck); @@ -992,9 +982,9 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) i9xx_error_irq_handler(dev_priv, eir, eir_stuck); if (hotplug_status) - i9xx_hpd_irq_handler(dev_priv, hotplug_status); + i9xx_hpd_irq_handler(display, hotplug_status); - i915_pipestat_irq_handler(dev_priv, iir, pipe_stats); + i915_pipestat_irq_handler(display, iir, pipe_stats); } while (0); pmu_irq_stats(dev_priv, ret); @@ -1006,9 +996,10 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) static void i965_irq_reset(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct intel_uncore *uncore = &dev_priv->uncore; - i9xx_display_irq_reset(dev_priv); + i9xx_display_irq_reset(display); gen2_error_reset(uncore, GEN2_ERROR_REGS); gen2_irq_reset(uncore, GEN2_IRQ_REGS); @@ -1036,6 +1027,7 @@ static u32 i965_error_mask(struct drm_i915_private *i915) static void i965_irq_postinstall(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; struct intel_uncore *uncore = &dev_priv->uncore; u32 enable_mask; @@ -1061,20 +1053,13 @@ 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(dev_priv, PIPE_A, PIPE_GMBUS_INTERRUPT_STATUS); - i915_enable_pipestat(dev_priv, PIPE_A, PIPE_CRC_DONE_INTERRUPT_STATUS); - i915_enable_pipestat(dev_priv, PIPE_B, PIPE_CRC_DONE_INTERRUPT_STATUS); - spin_unlock_irq(&dev_priv->irq_lock); - - i915_enable_asle_pipestat(dev_priv); + i965_display_irq_postinstall(display); } static irqreturn_t i965_irq_handler(int irq, void *arg) { struct drm_i915_private *dev_priv = arg; + struct intel_display *display = &dev_priv->display; irqreturn_t ret = IRQ_NONE; if (!intel_irqs_enabled(dev_priv)) @@ -1096,11 +1081,11 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) ret = IRQ_HANDLED; if (iir & I915_DISPLAY_PORT_INTERRUPT) - hotplug_status = i9xx_hpd_irq_ack(dev_priv); + hotplug_status = i9xx_hpd_irq_ack(display); /* Call regardless, as some status bits might not be * signalled in IIR */ - i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats); + i9xx_pipestat_irq_ack(display, iir, pipe_stats); if (iir & I915_MASTER_ERROR_INTERRUPT) i9xx_error_irq_ack(dev_priv, &eir, &eir_stuck); @@ -1119,9 +1104,9 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) i9xx_error_irq_handler(dev_priv, eir, eir_stuck); if (hotplug_status) - i9xx_hpd_irq_handler(dev_priv, hotplug_status); + i9xx_hpd_irq_handler(display, hotplug_status); - i965_pipestat_irq_handler(dev_priv, iir, pipe_stats); + i965_pipestat_irq_handler(display, iir, pipe_stats); } while (0); pmu_irq_stats(dev_priv, IRQ_HANDLED); @@ -1280,6 +1265,7 @@ int intel_irq_install(struct drm_i915_private *dev_priv) */ void intel_irq_uninstall(struct drm_i915_private *dev_priv) { + struct intel_display *display = &dev_priv->display; int irq = to_pci_dev(dev_priv->drm.dev)->irq; if (drm_WARN_ON(&dev_priv->drm, !dev_priv->irqs_enabled)) @@ -1289,7 +1275,7 @@ void intel_irq_uninstall(struct drm_i915_private *dev_priv) free_irq(irq, dev_priv); - intel_hpd_cancel_work(dev_priv); + intel_hpd_cancel_work(display); dev_priv->irqs_enabled = false; } diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index de0b413600a1..1658f1246c6f 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -1666,6 +1666,7 @@ static void i915_oa_stream_destroy(struct i915_perf_stream *stream) struct i915_perf *perf = stream->perf; struct intel_gt *gt = stream->engine->gt; struct i915_perf_group *g = stream->engine->oa_group; + int m; if (WARN_ON(stream != g->exclusive_stream)) return; @@ -1690,10 +1691,9 @@ static void i915_oa_stream_destroy(struct i915_perf_stream *stream) free_oa_configs(stream); free_noa_wait(stream); - if (perf->spurious_report_rs.missed) { - gt_notice(gt, "%d spurious OA report notices suppressed due to ratelimiting\n", - perf->spurious_report_rs.missed); - } + m = ratelimit_state_get_miss(&perf->spurious_report_rs); + if (m) + gt_notice(gt, "%d spurious OA report notices suppressed due to ratelimiting\n", m); } static void gen7_init_oa_buffer(struct i915_perf_stream *stream) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c5064eebe063..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) @@ -1077,6 +1079,7 @@ #define GEN9_CLKGATE_DIS_4 _MMIO(0x4653C) #define BXT_GMBUS_GATING_DIS (1 << 14) +#define DG2_DPFC_GATING_DIS REG_BIT(31) #define GEN9_CLKGATE_DIS_5 _MMIO(0x46540) #define DPCE_GATING_DIS REG_BIT(17) @@ -1105,7 +1108,6 @@ /* * Display engine regs */ - /* Pipe/transcoder A timing regs */ #define _TRANS_HTOTAL_A 0x60000 #define _TRANS_HTOTAL_B 0x61000 @@ -1396,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 @@ -1811,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 */ @@ -2783,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)) @@ -2863,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) @@ -3794,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) @@ -4242,6 +4191,11 @@ enum skl_power_gate { #define MTL_CLKGATE_DIS_TRANS(dev_priv, trans) _MMIO_TRANS2(dev_priv, trans, _MTL_CLKGATE_DIS_TRANS_A) #define MTL_CLKGATE_DIS_TRANS_DMASC_GATING_DIS REG_BIT(7) +#define _MTL_PIPE_CLKGATE_DIS2_A 0x60114 +#define _MTL_PIPE_CLKGATE_DIS2_B 0x61114 +#define MTL_PIPE_CLKGATE_DIS2(pipe) _MMIO_PIPE(pipe, _MTL_PIPE_CLKGATE_DIS2_A, _MTL_PIPE_CLKGATE_DIS2_B) +#define MTL_DPFC_GATING_DIS REG_BIT(6) + #define MTL_MEM_SS_INFO_GLOBAL _MMIO(0x45700) #define MTL_N_OF_ENABLED_QGV_POINTS_MASK REG_GENMASK(11, 8) #define MTL_N_OF_POPULATED_CH_MASK REG_GENMASK(7, 4) 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/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c index d40ee1b42110..59bd603e6deb 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.c +++ b/drivers/gpu/drm/i915/intel_memory_region.c @@ -171,6 +171,17 @@ intel_memory_region_by_type(struct drm_i915_private *i915, return NULL; } +bool intel_memory_type_is_local(enum intel_memory_type mem_type) +{ + switch (mem_type) { + case INTEL_MEMORY_LOCAL: + case INTEL_MEMORY_STOLEN_LOCAL: + return true; + default: + return false; + } +} + /** * intel_memory_region_reserve - Reserve a memory range * @mem: The region for which we want to reserve a range. @@ -216,7 +227,7 @@ static int intel_memory_region_memtest(struct intel_memory_region *mem, return err; } -static const char *region_type_str(u16 type) +const char *intel_memory_type_str(enum intel_memory_type type) { switch (type) { case INTEL_MEMORY_SYSTEM: @@ -260,7 +271,7 @@ intel_memory_region_create(struct drm_i915_private *i915, mem->instance = instance; snprintf(mem->uabi_name, sizeof(mem->uabi_name), "%s%u", - region_type_str(type), instance); + intel_memory_type_str(type), instance); mutex_init(&mem->objects.lock); INIT_LIST_HEAD(&mem->objects.list); diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h index 5973b6fe13cf..b3b75be9ced5 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.h +++ b/drivers/gpu/drm/i915/intel_memory_region.h @@ -85,6 +85,8 @@ struct intel_memory_region { void *region_private; }; +bool intel_memory_type_is_local(enum intel_memory_type mem_type); + struct intel_memory_region * intel_memory_region_lookup(struct drm_i915_private *i915, u16 class, u16 instance); @@ -107,6 +109,7 @@ void intel_memory_regions_driver_release(struct drm_i915_private *i915); struct intel_memory_region * intel_memory_region_by_type(struct drm_i915_private *i915, enum intel_memory_type mem_type); +const char *intel_memory_type_str(enum intel_memory_type type); __printf(2, 3) void intel_memory_region_set_name(struct intel_memory_region *mem, diff --git a/drivers/gpu/drm/i915/intel_wakeref.h b/drivers/gpu/drm/i915/intel_wakeref.h index 48836ef52d40..a2894a56e18f 100644 --- a/drivers/gpu/drm/i915/intel_wakeref.h +++ b/drivers/gpu/drm/i915/intel_wakeref.h @@ -7,8 +7,6 @@ #ifndef INTEL_WAKEREF_H #define INTEL_WAKEREF_H -#include <drm/drm_print.h> - #include <linux/atomic.h> #include <linux/bitfield.h> #include <linux/bits.h> @@ -16,11 +14,13 @@ #include <linux/mutex.h> #include <linux/refcount.h> #include <linux/ref_tracker.h> -#include <linux/slab.h> -#include <linux/stackdepot.h> #include <linux/timer.h> #include <linux/workqueue.h> +struct drm_printer; +struct intel_runtime_pm; +struct intel_wakeref; + typedef struct ref_tracker *intel_wakeref_t; #define INTEL_REFTRACK_DEAD_COUNT 16 @@ -32,9 +32,6 @@ typedef struct ref_tracker *intel_wakeref_t; #define INTEL_WAKEREF_BUG_ON(expr) BUILD_BUG_ON_INVALID(expr) #endif -struct intel_runtime_pm; -struct intel_wakeref; - struct intel_wakeref_ops { int (*get)(struct intel_wakeref *wf); int (*put)(struct intel_wakeref *wf); diff --git a/drivers/gpu/drm/i915/selftests/lib_sw_fence.c b/drivers/gpu/drm/i915/selftests/lib_sw_fence.c index d5ecc68155da..522ad49406ce 100644 --- a/drivers/gpu/drm/i915/selftests/lib_sw_fence.c +++ b/drivers/gpu/drm/i915/selftests/lib_sw_fence.c @@ -77,7 +77,7 @@ void timed_fence_fini(struct timed_fence *tf) if (timer_delete_sync(&tf->timer)) i915_sw_fence_commit(&tf->fence); - destroy_timer_on_stack(&tf->timer); + timer_destroy_on_stack(&tf->timer); i915_sw_fence_fini(&tf->fence); } diff --git a/drivers/gpu/drm/i915/selftests/librapl.c b/drivers/gpu/drm/i915/selftests/librapl.c index eb03b5b28bad..25b8726b9dff 100644 --- a/drivers/gpu/drm/i915/selftests/librapl.c +++ b/drivers/gpu/drm/i915/selftests/librapl.c @@ -22,12 +22,12 @@ u64 librapl_energy_uJ(void) unsigned long long power; u32 units; - if (rdmsrl_safe(MSR_RAPL_POWER_UNIT, &power)) + if (rdmsrq_safe(MSR_RAPL_POWER_UNIT, &power)) return 0; units = (power & 0x1f00) >> 8; - if (rdmsrl_safe(MSR_PP1_ENERGY_STATUS, &power)) + if (rdmsrq_safe(MSR_PP1_ENERGY_STATUS, &power)) return 0; return (1000000 * power) >> units; /* convert to uJ */ diff --git a/drivers/gpu/drm/i915/soc/intel_dram.c b/drivers/gpu/drm/i915/soc/intel_dram.c index f60eedb0e92c..eee5c4f45a43 100644 --- a/drivers/gpu/drm/i915/soc/intel_dram.c +++ b/drivers/gpu/drm/i915/soc/intel_dram.c @@ -33,8 +33,14 @@ static const char *intel_dram_type_str(enum intel_dram_type type) DRAM_TYPE_STR(DDR4), DRAM_TYPE_STR(LPDDR3), DRAM_TYPE_STR(LPDDR4), + DRAM_TYPE_STR(DDR5), + DRAM_TYPE_STR(LPDDR5), + DRAM_TYPE_STR(GDDR), + DRAM_TYPE_STR(GDDR_ECC), }; + BUILD_BUG_ON(ARRAY_SIZE(str) != __INTEL_DRAM_TYPE_MAX); + if (type >= ARRAY_SIZE(str)) type = INTEL_DRAM_UNKNOWN; @@ -444,8 +450,6 @@ skl_get_dram_info(struct drm_i915_private *i915) int ret; dram_info->type = skl_get_dram_type(i915); - drm_dbg_kms(&i915->drm, "DRAM type: %s\n", - intel_dram_type_str(dram_info->type)); ret = skl_dram_get_channels_info(i915); if (ret) @@ -560,10 +564,9 @@ static int bxt_get_dram_info(struct drm_i915_private *i915) dram_info->type != type); drm_dbg_kms(&i915->drm, - "CH%u DIMM size: %u Gb, width: X%u, ranks: %u, type: %s\n", + "CH%u DIMM size: %u Gb, width: X%u, ranks: %u\n", i - BXT_D_CR_DRP0_DUNIT_START, - dimm.size, dimm.width, dimm.ranks, - intel_dram_type_str(type)); + dimm.size, dimm.width, dimm.ranks); if (valid_ranks == 0) valid_ranks = dimm.ranks; @@ -730,6 +733,10 @@ void intel_dram_detect(struct drm_i915_private *i915) ret = bxt_get_dram_info(i915); else ret = skl_get_dram_info(i915); + + drm_dbg_kms(&i915->drm, "DRAM type: %s\n", + intel_dram_type_str(dram_info->type)); + if (ret) return; 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__ */ |