Merge tag 'drm-intel-next-2022-10-28' of git://anongit.freedesktop.org/drm/drm-intel...
authorDave Airlie <airlied@redhat.com>
Tue, 1 Nov 2022 07:48:12 +0000 (17:48 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 1 Nov 2022 07:48:17 +0000 (17:48 +1000)
- Hotplug code clean-up and organization (Jani, Gustavo)
- More VBT specific code clean-up, doc, organization,
  and improvements (Ville)
- More MTL enabling work (Matt, RK, Anusha, Jose)
- FBC related clean-ups and improvements (Ville)
- Removing unused sw_fence_await_reservation (Niranjana)
- Big chunch of display house clean-up (Ville)
- Many Watermark fixes and clean-ups (Ville)
- Fix device info for devices without display (Jani)
- Fix TC port PLLs after readout (Ville)
- DPLL ID clean-ups (Ville)
- Prep work for finishing (de)gamma readout (Ville)
- PSR fixes and improvements (Jouni, Jose)
- Reject excessive dotclocks early (Ville)
- DRRS related improvements (Ville)
- Simplify uncore register updates (Andrzej)
- Fix simulated GPU reset wrt. encoder HW readout (Imre)
- Add a ADL-P workaround (Jose)
- Fix clear mask in GEN7_MISCCPCTL update (Andrzej)
- Temporarily disable runtime_pm for discrete (Anshuman)
- Improve fbdev debugs (Nirmoy)
- Fix DP FRL link training status (Ankit)
- Other small display fixes (Ankit, Suraj)
- Allow panel fixed modes to have differing sync
  polarities (Ville)
- Clean up crtc state flag checks (Ville)
- Fix race conditions during DKL PHY accesses (Imre)
- Prep-work for cdclock squash and crawl modes (Anusha)
- ELD precompute and readout (Ville)

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Y1wd6ZJ8LdJpCfZL@intel.com
82 files changed:
drivers/gpu/drm/i915/Makefile
drivers/gpu/drm/i915/display/g4x_hdmi.c
drivers/gpu/drm/i915/display/hsw_ips.c
drivers/gpu/drm/i915/display/icl_dsi.c
drivers/gpu/drm/i915/display/intel_atomic.c
drivers/gpu/drm/i915/display/intel_atomic_plane.c
drivers/gpu/drm/i915/display/intel_audio.c
drivers/gpu/drm/i915/display/intel_audio_regs.h
drivers/gpu/drm/i915/display/intel_bios.c
drivers/gpu/drm/i915/display/intel_cdclk.c
drivers/gpu/drm/i915/display/intel_color.c
drivers/gpu/drm/i915/display/intel_color.h
drivers/gpu/drm/i915/display/intel_combo_phy.c
drivers/gpu/drm/i915/display/intel_connector.c
drivers/gpu/drm/i915/display/intel_connector.h
drivers/gpu/drm/i915/display/intel_crt.c
drivers/gpu/drm/i915/display/intel_crtc.c
drivers/gpu/drm/i915/display/intel_crtc_state_dump.c
drivers/gpu/drm/i915/display/intel_cursor.c
drivers/gpu/drm/i915/display/intel_ddi.c
drivers/gpu/drm/i915/display/intel_display.c
drivers/gpu/drm/i915/display/intel_display.h
drivers/gpu/drm/i915/display/intel_display_core.h
drivers/gpu/drm/i915/display/intel_display_debugfs.c
drivers/gpu/drm/i915/display/intel_display_power.c
drivers/gpu/drm/i915/display/intel_display_power_well.c
drivers/gpu/drm/i915/display/intel_display_types.h
drivers/gpu/drm/i915/display/intel_dkl_phy.c [new file with mode: 0644]
drivers/gpu/drm/i915/display/intel_dkl_phy.h [new file with mode: 0644]
drivers/gpu/drm/i915/display/intel_dkl_phy_regs.h [new file with mode: 0644]
drivers/gpu/drm/i915/display/intel_dmc.c
drivers/gpu/drm/i915/display/intel_dp.c
drivers/gpu/drm/i915/display/intel_dp_hdcp.c
drivers/gpu/drm/i915/display/intel_dp_mst.c
drivers/gpu/drm/i915/display/intel_dpll_mgr.c
drivers/gpu/drm/i915/display/intel_dpll_mgr.h
drivers/gpu/drm/i915/display/intel_drrs.c
drivers/gpu/drm/i915/display/intel_drrs.h
drivers/gpu/drm/i915/display/intel_dvo.c
drivers/gpu/drm/i915/display/intel_fb.c
drivers/gpu/drm/i915/display/intel_fb.h
drivers/gpu/drm/i915/display/intel_fbc.c
drivers/gpu/drm/i915/display/intel_fbdev.c
drivers/gpu/drm/i915/display/intel_hdmi.c
drivers/gpu/drm/i915/display/intel_hotplug.c
drivers/gpu/drm/i915/display/intel_hotplug.h
drivers/gpu/drm/i915/display/intel_lpe_audio.c
drivers/gpu/drm/i915/display/intel_lvds.c
drivers/gpu/drm/i915/display/intel_mg_phy_regs.h [moved from drivers/gpu/drm/i915/display/intel_tc_phy_regs.h with 99% similarity]
drivers/gpu/drm/i915/display/intel_modeset_setup.c
drivers/gpu/drm/i915/display/intel_modeset_verify.c
drivers/gpu/drm/i915/display/intel_opregion.c
drivers/gpu/drm/i915/display/intel_panel.c
drivers/gpu/drm/i915/display/intel_panel.h
drivers/gpu/drm/i915/display/intel_pipe_crc.c
drivers/gpu/drm/i915/display/intel_psr.c
drivers/gpu/drm/i915/display/intel_sdvo.c
drivers/gpu/drm/i915/display/intel_tc.c
drivers/gpu/drm/i915/display/intel_tc.h
drivers/gpu/drm/i915/display/intel_tv.c
drivers/gpu/drm/i915/display/skl_watermark.c
drivers/gpu/drm/i915/display/vlv_dsi.c
drivers/gpu/drm/i915/gem/i915_gem_clflush.c
drivers/gpu/drm/i915/gt/intel_gt_regs.h
drivers/gpu/drm/i915/gt/intel_workarounds.c
drivers/gpu/drm/i915/i915_driver.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_pci.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/i915_sw_fence.c
drivers/gpu/drm/i915/i915_sw_fence.h
drivers/gpu/drm/i915/intel_device_info.c
drivers/gpu/drm/i915/intel_device_info.h
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_runtime_pm.c
drivers/gpu/drm/i915/intel_step.c
drivers/gpu/drm/i915/intel_step.h
drivers/gpu/drm/i915/intel_uncore.h
drivers/gpu/drm/i915/pxp/intel_pxp_session.c
drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
drivers/gpu/drm/i915/vlv_suspend.c

index a26edcd..cea00aa 100644 (file)
@@ -282,6 +282,7 @@ i915-y += \
        display/intel_ddi.o \
        display/intel_ddi_buf_trans.o \
        display/intel_display_trace.o \
+       display/intel_dkl_phy.o \
        display/intel_dp.o \
        display/intel_dp_aux.o \
        display/intel_dp_aux_backlight.o \
index 2b73f5f..8aadf96 100644 (file)
@@ -585,7 +585,7 @@ void g4x_hdmi_init(struct drm_i915_private *dev_priv,
        } else {
                intel_encoder->pipe_mask = ~0;
        }
-       intel_encoder->cloneable = 1 << INTEL_OUTPUT_ANALOG;
+       intel_encoder->cloneable = BIT(INTEL_OUTPUT_ANALOG);
        intel_encoder->hpd_pin = intel_hpd_pin_default(dev_priv, port);
        /*
         * BSpec is unclear about HDMI+HDMI cloning on g4x, but it seems
@@ -593,7 +593,7 @@ void g4x_hdmi_init(struct drm_i915_private *dev_priv,
         * only one port anyway, nothing is lost by allowing it.
         */
        if (IS_G4X(dev_priv))
-               intel_encoder->cloneable |= 1 << INTEL_OUTPUT_HDMI;
+               intel_encoder->cloneable |= BIT(INTEL_OUTPUT_HDMI);
 
        dig_port->hdmi.hdmi_reg = hdmi_reg;
        dig_port->dp.output_reg = INVALID_MMIO_REG;
index a5be4af..83aa380 100644 (file)
@@ -104,8 +104,7 @@ static bool hsw_ips_need_disable(struct intel_atomic_state *state,
         * Disable IPS before we program the LUT.
         */
        if (IS_HASWELL(i915) &&
-           (new_crtc_state->uapi.color_mgmt_changed ||
-            new_crtc_state->update_pipe) &&
+           intel_crtc_needs_color_update(new_crtc_state) &&
            new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
                return true;
 
@@ -146,8 +145,7 @@ static bool hsw_ips_need_enable(struct intel_atomic_state *state,
         * Re-enable IPS after the LUT has been programmed.
         */
        if (IS_HASWELL(i915) &&
-           (new_crtc_state->uapi.color_mgmt_changed ||
-            new_crtc_state->update_pipe) &&
+           intel_crtc_needs_color_update(new_crtc_state) &&
            new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
                return true;
 
@@ -155,7 +153,7 @@ static bool hsw_ips_need_enable(struct intel_atomic_state *state,
         * We can't read out IPS on broadwell, assume the worst and
         * forcibly enable IPS on the first fastset.
         */
-       if (new_crtc_state->update_pipe && old_crtc_state->inherited)
+       if (intel_crtc_needs_fastset(new_crtc_state) && old_crtc_state->inherited)
                return true;
 
        return !old_crtc_state->ips_enabled;
index ed4d939..e05e7cd 100644 (file)
@@ -1974,16 +1974,8 @@ static void icl_dsi_add_properties(struct intel_connector *connector)
 {
        const struct drm_display_mode *fixed_mode =
                intel_panel_preferred_fixed_mode(connector);
-       u32 allowed_scalers;
 
-       allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT) |
-                          BIT(DRM_MODE_SCALE_FULLSCREEN) |
-                          BIT(DRM_MODE_SCALE_CENTER);
-
-       drm_connector_attach_scaling_mode_property(&connector->base,
-                                                  allowed_scalers);
-
-       connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT;
+       intel_attach_scaling_mode_property(&connector->base);
 
        drm_connector_set_panel_orientation_with_quirk(&connector->base,
                                                       intel_dsi_get_panel_orientation(connector),
@@ -1993,7 +1985,6 @@ static void icl_dsi_add_properties(struct intel_connector *connector)
 
 void icl_dsi_init(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = &dev_priv->drm;
        struct intel_dsi *intel_dsi;
        struct intel_encoder *encoder;
        struct intel_connector *intel_connector;
@@ -2018,7 +2009,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
        connector = &intel_connector->base;
 
        /* register DSI encoder with DRM subsystem */
-       drm_encoder_init(dev, &encoder->base, &gen11_dsi_encoder_funcs,
+       drm_encoder_init(&dev_priv->drm, &encoder->base, &gen11_dsi_encoder_funcs,
                         DRM_MODE_ENCODER_DSI, "DSI %c", port_name(port));
 
        encoder->pre_pll_enable = gen11_dsi_pre_pll_enable;
@@ -2042,12 +2033,10 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
        encoder->is_clock_enabled = gen11_dsi_is_clock_enabled;
 
        /* register DSI connector with DRM subsystem */
-       drm_connector_init(dev, connector, &gen11_dsi_connector_funcs,
+       drm_connector_init(&dev_priv->drm, connector, &gen11_dsi_connector_funcs,
                           DRM_MODE_CONNECTOR_DSI);
        drm_connector_helper_add(connector, &gen11_dsi_connector_helper_funcs);
        connector->display_info.subpixel_order = SubPixelHorizontalRGB;
-       connector->interlace_allowed = false;
-       connector->doublescan_allowed = false;
        intel_connector->get_hw_state = intel_connector_get_hw_state;
 
        /* attach connector to encoder */
@@ -2055,9 +2044,9 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
 
        intel_bios_init_panel(dev_priv, &intel_connector->panel, NULL, NULL);
 
-       mutex_lock(&dev->mode_config.mutex);
+       mutex_lock(&dev_priv->drm.mode_config.mutex);
        intel_panel_add_vbt_lfp_fixed_mode(intel_connector);
-       mutex_unlock(&dev->mode_config.mutex);
+       mutex_unlock(&dev_priv->drm.mode_config.mutex);
 
        if (!intel_panel_preferred_fixed_mode(intel_connector)) {
                drm_err(&dev_priv->drm, "DSI fixed mode info missing\n");
index 18f0a5a..6621aa2 100644 (file)
@@ -252,6 +252,11 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
        if (crtc_state->hw.gamma_lut)
                drm_property_blob_get(crtc_state->hw.gamma_lut);
 
+       if (crtc_state->pre_csc_lut)
+               drm_property_blob_get(crtc_state->pre_csc_lut);
+       if (crtc_state->post_csc_lut)
+               drm_property_blob_get(crtc_state->post_csc_lut);
+
        crtc_state->update_pipe = false;
        crtc_state->disable_lp_wm = false;
        crtc_state->disable_cxsr = false;
@@ -274,6 +279,9 @@ static void intel_crtc_put_color_blobs(struct intel_crtc_state *crtc_state)
        drm_property_blob_put(crtc_state->hw.degamma_lut);
        drm_property_blob_put(crtc_state->hw.gamma_lut);
        drm_property_blob_put(crtc_state->hw.ctm);
+
+       drm_property_blob_put(crtc_state->pre_csc_lut);
+       drm_property_blob_put(crtc_state->post_csc_lut);
 }
 
 void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
index aaa6708..bcf0239 100644 (file)
@@ -425,6 +425,47 @@ static bool intel_plane_do_async_flip(struct intel_plane *plane,
        return DISPLAY_VER(i915) < 13 || old_crtc_state->uapi.async_flip;
 }
 
+static bool i9xx_must_disable_cxsr(const struct intel_crtc_state *new_crtc_state,
+                                  const struct intel_plane_state *old_plane_state,
+                                  const struct intel_plane_state *new_plane_state)
+{
+       struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane);
+       bool old_visible = old_plane_state->uapi.visible;
+       bool new_visible = new_plane_state->uapi.visible;
+       u32 old_ctl = old_plane_state->ctl;
+       u32 new_ctl = new_plane_state->ctl;
+       bool modeset, turn_on, turn_off;
+
+       if (plane->id == PLANE_CURSOR)
+               return false;
+
+       modeset = intel_crtc_needs_modeset(new_crtc_state);
+       turn_off = old_visible && (!new_visible || modeset);
+       turn_on = new_visible && (!old_visible || modeset);
+
+       /* Must disable CxSR around plane enable/disable */
+       if (turn_on || turn_off)
+               return true;
+
+       if (!old_visible || !new_visible)
+               return false;
+
+       /*
+        * Most plane control register updates are blocked while in CxSR.
+        *
+        * Tiling mode is one exception where the primary plane can
+        * apparently handle it, whereas the sprites can not (the
+        * sprite issue being only relevant on VLV/CHV where CxSR
+        * is actually possible with a sprite enabled).
+        */
+       if (plane->id == PLANE_PRIMARY) {
+               old_ctl &= ~DISP_TILED;
+               new_ctl &= ~DISP_TILED;
+       }
+
+       return old_ctl != new_ctl;
+}
+
 static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_state,
                                           struct intel_crtc_state *new_crtc_state,
                                           const struct intel_plane_state *old_plane_state,
@@ -482,17 +523,9 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr
        if (turn_on) {
                if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
                        new_crtc_state->update_wm_pre = true;
-
-               /* must disable cxsr around plane enable/disable */
-               if (plane->id != PLANE_CURSOR)
-                       new_crtc_state->disable_cxsr = true;
        } else if (turn_off) {
                if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
                        new_crtc_state->update_wm_post = true;
-
-               /* must disable cxsr around plane enable/disable */
-               if (plane->id != PLANE_CURSOR)
-                       new_crtc_state->disable_cxsr = true;
        } else if (intel_wm_need_update(old_plane_state, new_plane_state)) {
                if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) {
                        /* FIXME bollocks */
@@ -504,6 +537,10 @@ static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_cr
        if (visible || was_visible)
                new_crtc_state->fb_bits |= plane->frontbuffer_bit;
 
+       if (HAS_GMCH(dev_priv) &&
+           i9xx_must_disable_cxsr(new_crtc_state, old_plane_state, new_plane_state))
+               new_crtc_state->disable_cxsr = true;
+
        /*
         * ILK/SNB DVSACNTR/Sprite Enable
         * IVB SPR_CTL/Sprite Enable
@@ -1005,7 +1042,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane,
                 */
                if (intel_crtc_needs_modeset(crtc_state)) {
                        ret = i915_sw_fence_await_reservation(&state->commit_ready,
-                                                             old_obj->base.resv, NULL,
+                                                             old_obj->base.resv,
                                                              false, 0,
                                                              GFP_KERNEL);
                        if (ret < 0)
@@ -1039,8 +1076,7 @@ intel_prepare_plane_fb(struct drm_plane *_plane,
                struct dma_fence *fence;
 
                ret = i915_sw_fence_await_reservation(&state->commit_ready,
-                                                     obj->base.resv, NULL,
-                                                     false,
+                                                     obj->base.resv, false,
                                                      i915_fence_timeout(dev_priv),
                                                      GFP_KERNEL);
                if (ret < 0)
index aacbc6d..c3176c9 100644 (file)
@@ -250,7 +250,7 @@ static const struct hdmi_aud_ncts hdmi_aud_ncts_36bpp[] = {
 /* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */
 static u32 audio_config_hdmi_pixel_clock(const struct intel_crtc_state *crtc_state)
 {
-       struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+       struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
        const struct drm_display_mode *adjusted_mode =
                &crtc_state->hw.adjusted_mode;
        int i;
@@ -260,17 +260,17 @@ static u32 audio_config_hdmi_pixel_clock(const struct intel_crtc_state *crtc_sta
                        break;
        }
 
-       if (DISPLAY_VER(dev_priv) < 12 && adjusted_mode->crtc_clock > 148500)
+       if (DISPLAY_VER(i915) < 12 && adjusted_mode->crtc_clock > 148500)
                i = ARRAY_SIZE(hdmi_audio_clock);
 
        if (i == ARRAY_SIZE(hdmi_audio_clock)) {
-               drm_dbg_kms(&dev_priv->drm,
+               drm_dbg_kms(&i915->drm,
                            "HDMI audio pixel clock setting for %d not found, falling back to defaults\n",
                            adjusted_mode->crtc_clock);
                i = 1;
        }
 
-       drm_dbg_kms(&dev_priv->drm,
+       drm_dbg_kms(&i915->drm,
                    "Configuring HDMI audio for pixel clock %d (0x%08x)\n",
                    hdmi_audio_clock[i].clock,
                    hdmi_audio_clock[i].config);
@@ -304,96 +304,67 @@ static int audio_config_hdmi_get_n(const struct intel_crtc_state *crtc_state,
        return 0;
 }
 
-static bool intel_eld_uptodate(struct drm_connector *connector,
-                              i915_reg_t reg_eldv, u32 bits_eldv,
-                              i915_reg_t reg_elda, u32 bits_elda,
-                              i915_reg_t reg_edid)
+/* ELD buffer size in dwords */
+static int g4x_eld_buffer_size(struct drm_i915_private *i915)
 {
-       struct drm_i915_private *dev_priv = to_i915(connector->dev);
-       const u8 *eld = connector->eld;
        u32 tmp;
-       int i;
-
-       tmp = intel_de_read(dev_priv, reg_eldv);
-       tmp &= bits_eldv;
-
-       if (!tmp)
-               return false;
 
-       tmp = intel_de_read(dev_priv, reg_elda);
-       tmp &= ~bits_elda;
-       intel_de_write(dev_priv, reg_elda, tmp);
+       tmp = intel_de_read(i915, G4X_AUD_CNTL_ST);
 
-       for (i = 0; i < drm_eld_size(eld) / 4; i++)
-               if (intel_de_read(dev_priv, reg_edid) != *((const u32 *)eld + i))
-                       return false;
-
-       return true;
+       return REG_FIELD_GET(G4X_ELD_BUFFER_SIZE_MASK, tmp);
 }
 
 static void g4x_audio_codec_disable(struct intel_encoder *encoder,
                                    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);
-       u32 eldv, tmp;
-
-       tmp = intel_de_read(dev_priv, G4X_AUD_VID_DID);
-       if (tmp == INTEL_AUDIO_DEVBLC || tmp == INTEL_AUDIO_DEVCL)
-               eldv = G4X_ELDV_DEVCL_DEVBLC;
-       else
-               eldv = G4X_ELDV_DEVCTG;
+       struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+       struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 
        /* Invalidate ELD */
-       tmp = intel_de_read(dev_priv, G4X_AUD_CNTL_ST);
-       tmp &= ~eldv;
-       intel_de_write(dev_priv, G4X_AUD_CNTL_ST, tmp);
+       intel_de_rmw(i915, G4X_AUD_CNTL_ST,
+                    G4X_ELD_VALID, 0);
+
+       intel_crtc_wait_for_next_vblank(crtc);
+       intel_crtc_wait_for_next_vblank(crtc);
 }
 
 static void g4x_audio_codec_enable(struct intel_encoder *encoder,
                                   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 drm_i915_private *i915 = to_i915(encoder->base.dev);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
        struct drm_connector *connector = conn_state->connector;
-       const u8 *eld = connector->eld;
-       u32 eldv;
-       u32 tmp;
-       int len, i;
+       const u32 *eld = (const u32 *)connector->eld;
+       int eld_buffer_size, len, i;
 
-       tmp = intel_de_read(dev_priv, G4X_AUD_VID_DID);
-       if (tmp == INTEL_AUDIO_DEVBLC || tmp == INTEL_AUDIO_DEVCL)
-               eldv = G4X_ELDV_DEVCL_DEVBLC;
-       else
-               eldv = G4X_ELDV_DEVCTG;
+       intel_crtc_wait_for_next_vblank(crtc);
 
-       if (intel_eld_uptodate(connector,
-                              G4X_AUD_CNTL_ST, eldv,
-                              G4X_AUD_CNTL_ST, G4X_ELD_ADDR_MASK,
-                              G4X_HDMIW_HDMIEDID))
-               return;
+       intel_de_rmw(i915, G4X_AUD_CNTL_ST,
+                    G4X_ELD_VALID | G4X_ELD_ADDRESS_MASK, 0);
 
-       tmp = intel_de_read(dev_priv, G4X_AUD_CNTL_ST);
-       tmp &= ~(eldv | G4X_ELD_ADDR_MASK);
-       len = (tmp >> 9) & 0x1f;                /* ELD buffer size */
-       intel_de_write(dev_priv, G4X_AUD_CNTL_ST, tmp);
+       eld_buffer_size = g4x_eld_buffer_size(i915);
+       len = min(drm_eld_size(connector->eld) / 4, eld_buffer_size);
 
-       len = min(drm_eld_size(eld) / 4, len);
        for (i = 0; i < len; i++)
-               intel_de_write(dev_priv, G4X_HDMIW_HDMIEDID,
-                              *((const u32 *)eld + i));
+               intel_de_write(i915, G4X_HDMIW_HDMIEDID, eld[i]);
+       for (; i < eld_buffer_size; i++)
+               intel_de_write(i915, G4X_HDMIW_HDMIEDID, 0);
 
-       tmp = intel_de_read(dev_priv, G4X_AUD_CNTL_ST);
-       tmp |= eldv;
-       intel_de_write(dev_priv, G4X_AUD_CNTL_ST, tmp);
+       drm_WARN_ON(&i915->drm,
+                   (intel_de_read(i915, G4X_AUD_CNTL_ST) & G4X_ELD_ADDRESS_MASK) != 0);
+
+       intel_de_rmw(i915, G4X_AUD_CNTL_ST,
+                    0, G4X_ELD_VALID);
 }
 
 static void
 hsw_dp_audio_config_update(struct intel_encoder *encoder,
                           const struct intel_crtc_state *crtc_state)
 {
-       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-       struct i915_audio_component *acomp = dev_priv->display.audio.component;
+       struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+       struct i915_audio_component *acomp = i915->display.audio.component;
        enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
        enum port port = encoder->port;
        const struct dp_aud_n_m *nm;
@@ -403,12 +374,12 @@ hsw_dp_audio_config_update(struct intel_encoder *encoder,
        rate = acomp ? acomp->aud_sample_rate[port] : 0;
        nm = audio_config_dp_get_n_m(crtc_state, rate);
        if (nm)
-               drm_dbg_kms(&dev_priv->drm, "using Maud %u, Naud %u\n", nm->m,
+               drm_dbg_kms(&i915->drm, "using Maud %u, Naud %u\n", nm->m,
                            nm->n);
        else
-               drm_dbg_kms(&dev_priv->drm, "using automatic Maud, Naud\n");
+               drm_dbg_kms(&i915->drm, "using automatic Maud, Naud\n");
 
-       tmp = intel_de_read(dev_priv, HSW_AUD_CFG(cpu_transcoder));
+       tmp = intel_de_read(i915, HSW_AUD_CFG(cpu_transcoder));
        tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
        tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK;
        tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
@@ -420,9 +391,9 @@ hsw_dp_audio_config_update(struct intel_encoder *encoder,
                tmp |= AUD_CONFIG_N_PROG_ENABLE;
        }
 
-       intel_de_write(dev_priv, HSW_AUD_CFG(cpu_transcoder), tmp);
+       intel_de_write(i915, HSW_AUD_CFG(cpu_transcoder), tmp);
 
-       tmp = intel_de_read(dev_priv, HSW_AUD_M_CTS_ENABLE(cpu_transcoder));
+       tmp = intel_de_read(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder));
        tmp &= ~AUD_CONFIG_M_MASK;
        tmp &= ~AUD_M_CTS_M_VALUE_INDEX;
        tmp &= ~AUD_M_CTS_M_PROG_ENABLE;
@@ -433,15 +404,15 @@ hsw_dp_audio_config_update(struct intel_encoder *encoder,
                tmp |= AUD_M_CTS_M_PROG_ENABLE;
        }
 
-       intel_de_write(dev_priv, HSW_AUD_M_CTS_ENABLE(cpu_transcoder), tmp);
+       intel_de_write(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder), tmp);
 }
 
 static void
 hsw_hdmi_audio_config_update(struct intel_encoder *encoder,
                             const struct intel_crtc_state *crtc_state)
 {
-       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-       struct i915_audio_component *acomp = dev_priv->display.audio.component;
+       struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+       struct i915_audio_component *acomp = i915->display.audio.component;
        enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
        enum port port = encoder->port;
        int n, rate;
@@ -449,7 +420,7 @@ hsw_hdmi_audio_config_update(struct intel_encoder *encoder,
 
        rate = acomp ? acomp->aud_sample_rate[port] : 0;
 
-       tmp = intel_de_read(dev_priv, HSW_AUD_CFG(cpu_transcoder));
+       tmp = intel_de_read(i915, HSW_AUD_CFG(cpu_transcoder));
        tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
        tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK;
        tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
@@ -457,25 +428,25 @@ hsw_hdmi_audio_config_update(struct intel_encoder *encoder,
 
        n = audio_config_hdmi_get_n(crtc_state, rate);
        if (n != 0) {
-               drm_dbg_kms(&dev_priv->drm, "using N %d\n", n);
+               drm_dbg_kms(&i915->drm, "using N %d\n", n);
 
                tmp &= ~AUD_CONFIG_N_MASK;
                tmp |= AUD_CONFIG_N(n);
                tmp |= AUD_CONFIG_N_PROG_ENABLE;
        } else {
-               drm_dbg_kms(&dev_priv->drm, "using automatic N\n");
+               drm_dbg_kms(&i915->drm, "using automatic N\n");
        }
 
-       intel_de_write(dev_priv, HSW_AUD_CFG(cpu_transcoder), tmp);
+       intel_de_write(i915, HSW_AUD_CFG(cpu_transcoder), tmp);
 
        /*
         * Let's disable "Enable CTS or M Prog bit"
         * and let HW calculate the value
         */
-       tmp = intel_de_read(dev_priv, HSW_AUD_M_CTS_ENABLE(cpu_transcoder));
+       tmp = intel_de_read(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder));
        tmp &= ~AUD_M_CTS_M_PROG_ENABLE;
        tmp &= ~AUD_M_CTS_M_VALUE_INDEX;
-       intel_de_write(dev_priv, HSW_AUD_M_CTS_ENABLE(cpu_transcoder), tmp);
+       intel_de_write(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder), tmp);
 }
 
 static void
@@ -488,33 +459,48 @@ hsw_audio_config_update(struct intel_encoder *encoder,
                hsw_hdmi_audio_config_update(encoder, crtc_state);
 }
 
+/* ELD buffer size in dwords */
+static int hsw_eld_buffer_size(struct drm_i915_private *i915,
+                              enum transcoder cpu_transcoder)
+{
+       u32 tmp;
+
+       tmp = intel_de_read(i915, HSW_AUD_DIP_ELD_CTRL(cpu_transcoder));
+
+       return REG_FIELD_GET(IBX_ELD_BUFFER_SIZE_MASK, tmp);
+}
+
 static void hsw_audio_codec_disable(struct intel_encoder *encoder,
                                    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);
+       struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+       struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
        enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
-       u32 tmp;
 
-       mutex_lock(&dev_priv->display.audio.mutex);
+       mutex_lock(&i915->display.audio.mutex);
 
        /* Disable timestamps */
-       tmp = intel_de_read(dev_priv, HSW_AUD_CFG(cpu_transcoder));
-       tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
-       tmp |= AUD_CONFIG_N_PROG_ENABLE;
-       tmp &= ~AUD_CONFIG_UPPER_N_MASK;
-       tmp &= ~AUD_CONFIG_LOWER_N_MASK;
-       if (intel_crtc_has_dp_encoder(old_crtc_state))
-               tmp |= AUD_CONFIG_N_VALUE_INDEX;
-       intel_de_write(dev_priv, HSW_AUD_CFG(cpu_transcoder), tmp);
+       intel_de_rmw(i915, HSW_AUD_CFG(cpu_transcoder),
+                    AUD_CONFIG_N_VALUE_INDEX |
+                    AUD_CONFIG_UPPER_N_MASK |
+                    AUD_CONFIG_LOWER_N_MASK,
+                    AUD_CONFIG_N_PROG_ENABLE |
+                    (intel_crtc_has_dp_encoder(old_crtc_state) ?
+                     AUD_CONFIG_N_VALUE_INDEX : 0));
 
        /* Invalidate ELD */
-       tmp = intel_de_read(dev_priv, HSW_AUD_PIN_ELD_CP_VLD);
-       tmp &= ~AUDIO_ELD_VALID(cpu_transcoder);
-       tmp &= ~AUDIO_OUTPUT_ENABLE(cpu_transcoder);
-       intel_de_write(dev_priv, HSW_AUD_PIN_ELD_CP_VLD, tmp);
+       intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD,
+                    AUDIO_ELD_VALID(cpu_transcoder), 0);
+
+       intel_crtc_wait_for_next_vblank(crtc);
+       intel_crtc_wait_for_next_vblank(crtc);
 
-       mutex_unlock(&dev_priv->display.audio.mutex);
+       /* Disable audio presence detect */
+       intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD,
+                    AUDIO_OUTPUT_ENABLE(cpu_transcoder), 0);
+
+       mutex_unlock(&i915->display.audio.mutex);
 }
 
 static unsigned int calc_hblank_early_prog(struct intel_encoder *encoder,
@@ -626,178 +612,190 @@ static void enable_audio_dsc_wa(struct intel_encoder *encoder,
        intel_de_write(i915, AUD_CONFIG_BE, val);
 }
 
-#undef ROUNDING_FACTOR
-
 static void hsw_audio_codec_enable(struct intel_encoder *encoder,
                                   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 drm_i915_private *i915 = to_i915(encoder->base.dev);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
        struct drm_connector *connector = conn_state->connector;
        enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
-       const u8 *eld = connector->eld;
-       u32 tmp;
-       int len, i;
+       const u32 *eld = (const u32 *)connector->eld;
+       int eld_buffer_size, len, i;
 
-       mutex_lock(&dev_priv->display.audio.mutex);
+       mutex_lock(&i915->display.audio.mutex);
 
        /* Enable Audio WA for 4k DSC usecases */
        if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP))
                enable_audio_dsc_wa(encoder, crtc_state);
 
-       /* Enable audio presence detect, invalidate ELD */
-       tmp = intel_de_read(dev_priv, HSW_AUD_PIN_ELD_CP_VLD);
-       tmp |= AUDIO_OUTPUT_ENABLE(cpu_transcoder);
-       tmp &= ~AUDIO_ELD_VALID(cpu_transcoder);
-       intel_de_write(dev_priv, HSW_AUD_PIN_ELD_CP_VLD, tmp);
+       /* Enable audio presence detect */
+       intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD,
+                    0, AUDIO_OUTPUT_ENABLE(cpu_transcoder));
 
-       /*
-        * FIXME: We're supposed to wait for vblank here, but we have vblanks
-        * disabled during the mode set. The proper fix would be to push the
-        * rest of the setup into a vblank work item, queued here, but the
-        * infrastructure is not there yet.
-        */
+       intel_crtc_wait_for_next_vblank(crtc);
+
+       /* Invalidate ELD */
+       intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD,
+                    AUDIO_ELD_VALID(cpu_transcoder), 0);
+
+       /* Reset ELD address */
+       intel_de_rmw(i915, HSW_AUD_DIP_ELD_CTRL(cpu_transcoder),
+                    IBX_ELD_ADDRESS_MASK, 0);
 
-       /* Reset ELD write address */
-       tmp = intel_de_read(dev_priv, HSW_AUD_DIP_ELD_CTRL(cpu_transcoder));
-       tmp &= ~IBX_ELD_ADDRESS_MASK;
-       intel_de_write(dev_priv, HSW_AUD_DIP_ELD_CTRL(cpu_transcoder), tmp);
+       eld_buffer_size = hsw_eld_buffer_size(i915, cpu_transcoder);
+       len = min(drm_eld_size(connector->eld) / 4, eld_buffer_size);
 
-       /* Up to 84 bytes of hw ELD buffer */
-       len = min(drm_eld_size(eld), 84);
-       for (i = 0; i < len / 4; i++)
-               intel_de_write(dev_priv, HSW_AUD_EDID_DATA(cpu_transcoder),
-                              *((const u32 *)eld + i));
+       for (i = 0; i < len; i++)
+               intel_de_write(i915, HSW_AUD_EDID_DATA(cpu_transcoder), eld[i]);
+       for (; i < eld_buffer_size; i++)
+               intel_de_write(i915, HSW_AUD_EDID_DATA(cpu_transcoder), 0);
+
+       drm_WARN_ON(&i915->drm,
+                   (intel_de_read(i915, HSW_AUD_DIP_ELD_CTRL(cpu_transcoder)) &
+                    IBX_ELD_ADDRESS_MASK) != 0);
 
        /* ELD valid */
-       tmp = intel_de_read(dev_priv, HSW_AUD_PIN_ELD_CP_VLD);
-       tmp |= AUDIO_ELD_VALID(cpu_transcoder);
-       intel_de_write(dev_priv, HSW_AUD_PIN_ELD_CP_VLD, tmp);
+       intel_de_rmw(i915, HSW_AUD_PIN_ELD_CP_VLD,
+                    0, AUDIO_ELD_VALID(cpu_transcoder));
 
        /* Enable timestamps */
        hsw_audio_config_update(encoder, crtc_state);
 
-       mutex_unlock(&dev_priv->display.audio.mutex);
+       mutex_unlock(&i915->display.audio.mutex);
+}
+
+struct ilk_audio_regs {
+       i915_reg_t hdmiw_hdmiedid, aud_config, aud_cntl_st, aud_cntrl_st2;
+};
+
+static void ilk_audio_regs_init(struct drm_i915_private *i915,
+                               enum pipe pipe,
+                               struct ilk_audio_regs *regs)
+{
+       if (HAS_PCH_IBX(i915)) {
+               regs->hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID(pipe);
+               regs->aud_config = IBX_AUD_CFG(pipe);
+               regs->aud_cntl_st = IBX_AUD_CNTL_ST(pipe);
+               regs->aud_cntrl_st2 = IBX_AUD_CNTL_ST2;
+       } else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
+               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 {
+               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;
+       }
+}
+
+/* ELD buffer size in dwords */
+static int ilk_eld_buffer_size(struct drm_i915_private *i915,
+                              enum pipe pipe)
+{
+       struct ilk_audio_regs regs;
+       u32 tmp;
+
+       ilk_audio_regs_init(i915, pipe, &regs);
+
+       tmp = intel_de_read(i915, regs.aud_cntl_st);
+
+       return REG_FIELD_GET(IBX_ELD_BUFFER_SIZE_MASK, tmp);
 }
 
 static void ilk_audio_codec_disable(struct intel_encoder *encoder,
                                    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);
+       struct drm_i915_private *i915 = to_i915(encoder->base.dev);
        struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
-       enum pipe pipe = crtc->pipe;
        enum port port = encoder->port;
-       u32 tmp, eldv;
-       i915_reg_t aud_config, aud_cntrl_st2;
+       enum pipe pipe = crtc->pipe;
+       struct ilk_audio_regs regs;
 
-       if (drm_WARN_ON(&dev_priv->drm, port == PORT_A))
+       if (drm_WARN_ON(&i915->drm, port == PORT_A))
                return;
 
-       if (HAS_PCH_IBX(dev_priv)) {
-               aud_config = IBX_AUD_CFG(pipe);
-               aud_cntrl_st2 = IBX_AUD_CNTL_ST2;
-       } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
-               aud_config = VLV_AUD_CFG(pipe);
-               aud_cntrl_st2 = VLV_AUD_CNTL_ST2;
-       } else {
-               aud_config = CPT_AUD_CFG(pipe);
-               aud_cntrl_st2 = CPT_AUD_CNTRL_ST2;
-       }
+       ilk_audio_regs_init(i915, pipe, &regs);
 
-       /* Disable timestamps */
-       tmp = intel_de_read(dev_priv, aud_config);
-       tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
-       tmp |= AUD_CONFIG_N_PROG_ENABLE;
-       tmp &= ~AUD_CONFIG_UPPER_N_MASK;
-       tmp &= ~AUD_CONFIG_LOWER_N_MASK;
-       if (intel_crtc_has_dp_encoder(old_crtc_state))
-               tmp |= AUD_CONFIG_N_VALUE_INDEX;
-       intel_de_write(dev_priv, aud_config, tmp);
+       mutex_lock(&i915->display.audio.mutex);
 
-       eldv = IBX_ELD_VALID(port);
+       /* Disable timestamps */
+       intel_de_rmw(i915, regs.aud_config,
+                    AUD_CONFIG_N_VALUE_INDEX |
+                    AUD_CONFIG_UPPER_N_MASK |
+                    AUD_CONFIG_LOWER_N_MASK,
+                    AUD_CONFIG_N_PROG_ENABLE |
+                    (intel_crtc_has_dp_encoder(old_crtc_state) ?
+                     AUD_CONFIG_N_VALUE_INDEX : 0));
 
        /* Invalidate ELD */
-       tmp = intel_de_read(dev_priv, aud_cntrl_st2);
-       tmp &= ~eldv;
-       intel_de_write(dev_priv, aud_cntrl_st2, tmp);
+       intel_de_rmw(i915, regs.aud_cntrl_st2,
+                    IBX_ELD_VALID(port), 0);
+
+       mutex_unlock(&i915->display.audio.mutex);
+
+       intel_crtc_wait_for_next_vblank(crtc);
+       intel_crtc_wait_for_next_vblank(crtc);
 }
 
 static void ilk_audio_codec_enable(struct intel_encoder *encoder,
                                   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 drm_i915_private *i915 = to_i915(encoder->base.dev);
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
        struct drm_connector *connector = conn_state->connector;
-       enum pipe pipe = crtc->pipe;
+       const u32 *eld = (const u32 *)connector->eld;
        enum port port = encoder->port;
-       const u8 *eld = connector->eld;
-       u32 tmp, eldv;
-       int len, i;
-       i915_reg_t hdmiw_hdmiedid, aud_config, aud_cntl_st, aud_cntrl_st2;
+       enum pipe pipe = crtc->pipe;
+       int eld_buffer_size, len, i;
+       struct ilk_audio_regs regs;
 
-       if (drm_WARN_ON(&dev_priv->drm, port == PORT_A))
+       if (drm_WARN_ON(&i915->drm, port == PORT_A))
                return;
 
-       /*
-        * FIXME: We're supposed to wait for vblank here, but we have vblanks
-        * disabled during the mode set. The proper fix would be to push the
-        * rest of the setup into a vblank work item, queued here, but the
-        * infrastructure is not there yet.
-        */
+       intel_crtc_wait_for_next_vblank(crtc);
 
-       if (HAS_PCH_IBX(dev_priv)) {
-               hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID(pipe);
-               aud_config = IBX_AUD_CFG(pipe);
-               aud_cntl_st = IBX_AUD_CNTL_ST(pipe);
-               aud_cntrl_st2 = IBX_AUD_CNTL_ST2;
-       } else if (IS_VALLEYVIEW(dev_priv) ||
-                  IS_CHERRYVIEW(dev_priv)) {
-               hdmiw_hdmiedid = VLV_HDMIW_HDMIEDID(pipe);
-               aud_config = VLV_AUD_CFG(pipe);
-               aud_cntl_st = VLV_AUD_CNTL_ST(pipe);
-               aud_cntrl_st2 = VLV_AUD_CNTL_ST2;
-       } else {
-               hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID(pipe);
-               aud_config = CPT_AUD_CFG(pipe);
-               aud_cntl_st = CPT_AUD_CNTL_ST(pipe);
-               aud_cntrl_st2 = CPT_AUD_CNTRL_ST2;
-       }
+       ilk_audio_regs_init(i915, pipe, &regs);
 
-       eldv = IBX_ELD_VALID(port);
+       mutex_lock(&i915->display.audio.mutex);
 
        /* Invalidate ELD */
-       tmp = intel_de_read(dev_priv, aud_cntrl_st2);
-       tmp &= ~eldv;
-       intel_de_write(dev_priv, aud_cntrl_st2, tmp);
+       intel_de_rmw(i915, regs.aud_cntrl_st2,
+                    IBX_ELD_VALID(port), 0);
 
-       /* Reset ELD write address */
-       tmp = intel_de_read(dev_priv, aud_cntl_st);
-       tmp &= ~IBX_ELD_ADDRESS_MASK;
-       intel_de_write(dev_priv, aud_cntl_st, tmp);
+       /* Reset ELD address */
+       intel_de_rmw(i915, regs.aud_cntl_st,
+                    IBX_ELD_ADDRESS_MASK, 0);
 
-       /* Up to 84 bytes of hw ELD buffer */
-       len = min(drm_eld_size(eld), 84);
-       for (i = 0; i < len / 4; i++)
-               intel_de_write(dev_priv, hdmiw_hdmiedid,
-                              *((const u32 *)eld + i));
+       eld_buffer_size = ilk_eld_buffer_size(i915, pipe);
+       len = min(drm_eld_size(connector->eld) / 4, eld_buffer_size);
+
+       for (i = 0; i < len; i++)
+               intel_de_write(i915, regs.hdmiw_hdmiedid, eld[i]);
+       for (; i < eld_buffer_size; i++)
+               intel_de_write(i915, regs.hdmiw_hdmiedid, 0);
+
+       drm_WARN_ON(&i915->drm,
+                   (intel_de_read(i915, regs.aud_cntl_st) & IBX_ELD_ADDRESS_MASK) != 0);
 
        /* ELD valid */
-       tmp = intel_de_read(dev_priv, aud_cntrl_st2);
-       tmp |= eldv;
-       intel_de_write(dev_priv, aud_cntrl_st2, tmp);
+       intel_de_rmw(i915, regs.aud_cntrl_st2,
+                    0, IBX_ELD_VALID(port));
 
        /* Enable timestamps */
-       tmp = intel_de_read(dev_priv, aud_config);
-       tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
-       tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
-       tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK;
-       if (intel_crtc_has_dp_encoder(crtc_state))
-               tmp |= AUD_CONFIG_N_VALUE_INDEX;
-       else
-               tmp |= audio_config_hdmi_pixel_clock(crtc_state);
-       intel_de_write(dev_priv, aud_config, tmp);
+       intel_de_rmw(i915, regs.aud_config,
+                    AUD_CONFIG_N_VALUE_INDEX |
+                    AUD_CONFIG_N_PROG_ENABLE |
+                    AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK,
+                    (intel_crtc_has_dp_encoder(crtc_state) ?
+                     AUD_CONFIG_N_VALUE_INDEX :
+                     audio_config_hdmi_pixel_clock(crtc_state)));
+
+       mutex_unlock(&i915->display.audio.mutex);
 }
 
 /**
@@ -813,8 +811,8 @@ void intel_audio_codec_enable(struct intel_encoder *encoder,
                              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 i915_audio_component *acomp = dev_priv->display.audio.component;
+       struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+       struct i915_audio_component *acomp = i915->display.audio.component;
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
        struct drm_connector *connector = conn_state->connector;
        const struct drm_display_mode *adjusted_mode =
@@ -825,30 +823,30 @@ void intel_audio_codec_enable(struct intel_encoder *encoder,
        if (!crtc_state->has_audio)
                return;
 
-       drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s][ENCODER:%d:%s] Enable audio codec on pipe %c, %u bytes ELD\n",
+       drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s][ENCODER:%d:%s] Enable audio codec on pipe %c, %u bytes ELD\n",
                    connector->base.id, connector->name,
                    encoder->base.base.id, encoder->base.name,
                    pipe_name(pipe), drm_eld_size(connector->eld));
 
        /* FIXME precompute the ELD in .compute_config() */
        if (!connector->eld[0])
-               drm_dbg_kms(&dev_priv->drm,
+               drm_dbg_kms(&i915->drm,
                            "Bogus ELD on [CONNECTOR:%d:%s]\n",
                            connector->base.id, connector->name);
 
        connector->eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2;
 
-       if (dev_priv->display.funcs.audio)
-               dev_priv->display.funcs.audio->audio_codec_enable(encoder,
+       if (i915->display.funcs.audio)
+               i915->display.funcs.audio->audio_codec_enable(encoder,
                                                                  crtc_state,
                                                                  conn_state);
 
-       mutex_lock(&dev_priv->display.audio.mutex);
+       mutex_lock(&i915->display.audio.mutex);
        encoder->audio_connector = connector;
 
        /* referred in audio callbacks */
-       dev_priv->display.audio.encoder_map[pipe] = encoder;
-       mutex_unlock(&dev_priv->display.audio.mutex);
+       i915->display.audio.encoder_map[pipe] = encoder;
+       mutex_unlock(&i915->display.audio.mutex);
 
        if (acomp && acomp->base.audio_ops &&
            acomp->base.audio_ops->pin_eld_notify) {
@@ -859,7 +857,7 @@ void intel_audio_codec_enable(struct intel_encoder *encoder,
                                                 (int) port, (int) pipe);
        }
 
-       intel_lpe_audio_notify(dev_priv, pipe, port, connector->eld,
+       intel_lpe_audio_notify(i915, pipe, port, connector->eld,
                               crtc_state->port_clock,
                               intel_crtc_has_dp_encoder(crtc_state));
 }
@@ -877,8 +875,8 @@ void intel_audio_codec_disable(struct intel_encoder *encoder,
                               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);
-       struct i915_audio_component *acomp = dev_priv->display.audio.component;
+       struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+       struct i915_audio_component *acomp = i915->display.audio.component;
        struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
        struct drm_connector *connector = old_conn_state->connector;
        enum port port = encoder->port;
@@ -887,19 +885,19 @@ void intel_audio_codec_disable(struct intel_encoder *encoder,
        if (!old_crtc_state->has_audio)
                return;
 
-       drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s][ENCODER:%d:%s] Disable audio codec on pipe %c\n",
+       drm_dbg_kms(&i915->drm, "[CONNECTOR:%d:%s][ENCODER:%d:%s] Disable audio codec on pipe %c\n",
                    connector->base.id, connector->name,
                    encoder->base.base.id, encoder->base.name, pipe_name(pipe));
 
-       if (dev_priv->display.funcs.audio)
-               dev_priv->display.funcs.audio->audio_codec_disable(encoder,
+       if (i915->display.funcs.audio)
+               i915->display.funcs.audio->audio_codec_disable(encoder,
                                                                   old_crtc_state,
                                                                   old_conn_state);
 
-       mutex_lock(&dev_priv->display.audio.mutex);
+       mutex_lock(&i915->display.audio.mutex);
        encoder->audio_connector = NULL;
-       dev_priv->display.audio.encoder_map[pipe] = NULL;
-       mutex_unlock(&dev_priv->display.audio.mutex);
+       i915->display.audio.encoder_map[pipe] = NULL;
+       mutex_unlock(&i915->display.audio.mutex);
 
        if (acomp && acomp->base.audio_ops &&
            acomp->base.audio_ops->pin_eld_notify) {
@@ -910,7 +908,7 @@ void intel_audio_codec_disable(struct intel_encoder *encoder,
                                                 (int) port, (int) pipe);
        }
 
-       intel_lpe_audio_notify(dev_priv, pipe, port, NULL, 0, false);
+       intel_lpe_audio_notify(i915, pipe, port, NULL, 0, false);
 }
 
 static const struct intel_audio_funcs g4x_audio_funcs = {
@@ -930,19 +928,18 @@ static const struct intel_audio_funcs hsw_audio_funcs = {
 
 /**
  * intel_audio_hooks_init - Set up chip specific audio hooks
- * @dev_priv: device private
+ * @i915: device private
  */
-void intel_audio_hooks_init(struct drm_i915_private *dev_priv)
+void intel_audio_hooks_init(struct drm_i915_private *i915)
 {
-       if (IS_G4X(dev_priv)) {
-               dev_priv->display.funcs.audio = &g4x_audio_funcs;
-       } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
-               dev_priv->display.funcs.audio = &ilk_audio_funcs;
-       } else if (IS_HASWELL(dev_priv) || DISPLAY_VER(dev_priv) >= 8) {
-               dev_priv->display.funcs.audio = &hsw_audio_funcs;
-       } else if (HAS_PCH_SPLIT(dev_priv)) {
-               dev_priv->display.funcs.audio = &ilk_audio_funcs;
-       }
+       if (IS_G4X(i915))
+               i915->display.funcs.audio = &g4x_audio_funcs;
+       else if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915))
+               i915->display.funcs.audio = &ilk_audio_funcs;
+       else if (IS_HASWELL(i915) || DISPLAY_VER(i915) >= 8)
+               i915->display.funcs.audio = &hsw_audio_funcs;
+       else if (HAS_PCH_SPLIT(i915))
+               i915->display.funcs.audio = &ilk_audio_funcs;
 }
 
 struct aud_ts_cdclk_m_n {
@@ -1000,7 +997,7 @@ static int glk_force_audio_cdclk_commit(struct intel_atomic_state *state,
        return drm_atomic_commit(&state->base);
 }
 
-static void glk_force_audio_cdclk(struct drm_i915_private *dev_priv,
+static void glk_force_audio_cdclk(struct drm_i915_private *i915,
                                  bool enable)
 {
        struct drm_modeset_acquire_ctx ctx;
@@ -1008,13 +1005,13 @@ static void glk_force_audio_cdclk(struct drm_i915_private *dev_priv,
        struct intel_crtc *crtc;
        int ret;
 
-       crtc = intel_first_crtc(dev_priv);
+       crtc = intel_first_crtc(i915);
        if (!crtc)
                return;
 
        drm_modeset_acquire_init(&ctx, 0);
-       state = drm_atomic_state_alloc(&dev_priv->drm);
-       if (drm_WARN_ON(&dev_priv->drm, !state))
+       state = drm_atomic_state_alloc(&i915->drm);
+       if (drm_WARN_ON(&i915->drm, !state))
                return;
 
        state->acquire_ctx = &ctx;
@@ -1028,7 +1025,7 @@ retry:
                goto retry;
        }
 
-       drm_WARN_ON(&dev_priv->drm, ret);
+       drm_WARN_ON(&i915->drm, ret);
 
        drm_atomic_state_put(state);
 
@@ -1038,30 +1035,30 @@ retry:
 
 static unsigned long i915_audio_component_get_power(struct device *kdev)
 {
-       struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
+       struct drm_i915_private *i915 = kdev_to_i915(kdev);
        intel_wakeref_t ret;
 
        /* Catch potential impedance mismatches before they occur! */
        BUILD_BUG_ON(sizeof(intel_wakeref_t) > sizeof(unsigned long));
 
-       ret = intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO_PLAYBACK);
+       ret = intel_display_power_get(i915, POWER_DOMAIN_AUDIO_PLAYBACK);
 
-       if (dev_priv->display.audio.power_refcount++ == 0) {
-               if (DISPLAY_VER(dev_priv) >= 9) {
-                       intel_de_write(dev_priv, AUD_FREQ_CNTRL,
-                                      dev_priv->display.audio.freq_cntrl);
-                       drm_dbg_kms(&dev_priv->drm,
+       if (i915->display.audio.power_refcount++ == 0) {
+               if (DISPLAY_VER(i915) >= 9) {
+                       intel_de_write(i915, AUD_FREQ_CNTRL,
+                                      i915->display.audio.freq_cntrl);
+                       drm_dbg_kms(&i915->drm,
                                    "restored AUD_FREQ_CNTRL to 0x%x\n",
-                                   dev_priv->display.audio.freq_cntrl);
+                                   i915->display.audio.freq_cntrl);
                }
 
                /* Force CDCLK to 2*BCLK as long as we need audio powered. */
-               if (IS_GEMINILAKE(dev_priv))
-                       glk_force_audio_cdclk(dev_priv, true);
+               if (IS_GEMINILAKE(i915))
+                       glk_force_audio_cdclk(i915, true);
 
-               if (DISPLAY_VER(dev_priv) >= 10)
-                       intel_de_write(dev_priv, AUD_PIN_BUF_CTL,
-                                      (intel_de_read(dev_priv, AUD_PIN_BUF_CTL) | AUD_PIN_BUF_ENABLE));
+               if (DISPLAY_VER(i915) >= 10)
+                       intel_de_rmw(i915, AUD_PIN_BUF_CTL,
+                                    0, AUD_PIN_BUF_ENABLE);
        }
 
        return ret;
@@ -1070,24 +1067,23 @@ static unsigned long i915_audio_component_get_power(struct device *kdev)
 static void i915_audio_component_put_power(struct device *kdev,
                                           unsigned long cookie)
 {
-       struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
+       struct drm_i915_private *i915 = kdev_to_i915(kdev);
 
        /* Stop forcing CDCLK to 2*BCLK if no need for audio to be powered. */
-       if (--dev_priv->display.audio.power_refcount == 0)
-               if (IS_GEMINILAKE(dev_priv))
-                       glk_force_audio_cdclk(dev_priv, false);
+       if (--i915->display.audio.power_refcount == 0)
+               if (IS_GEMINILAKE(i915))
+                       glk_force_audio_cdclk(i915, false);
 
-       intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO_PLAYBACK, cookie);
+       intel_display_power_put(i915, POWER_DOMAIN_AUDIO_PLAYBACK, cookie);
 }
 
 static void i915_audio_component_codec_wake_override(struct device *kdev,
                                                     bool enable)
 {
-       struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
+       struct drm_i915_private *i915 = kdev_to_i915(kdev);
        unsigned long cookie;
-       u32 tmp;
 
-       if (DISPLAY_VER(dev_priv) < 9)
+       if (DISPLAY_VER(i915) < 9)
                return;
 
        cookie = i915_audio_component_get_power(kdev);
@@ -1096,15 +1092,13 @@ static void i915_audio_component_codec_wake_override(struct device *kdev,
         * Enable/disable generating the codec wake signal, overriding the
         * internal logic to generate the codec wake to controller.
         */
-       tmp = intel_de_read(dev_priv, HSW_AUD_CHICKENBIT);
-       tmp &= ~SKL_AUD_CODEC_WAKE_SIGNAL;
-       intel_de_write(dev_priv, HSW_AUD_CHICKENBIT, tmp);
+       intel_de_rmw(i915, HSW_AUD_CHICKENBIT,
+                    SKL_AUD_CODEC_WAKE_SIGNAL, 0);
        usleep_range(1000, 1500);
 
        if (enable) {
-               tmp = intel_de_read(dev_priv, HSW_AUD_CHICKENBIT);
-               tmp |= SKL_AUD_CODEC_WAKE_SIGNAL;
-               intel_de_write(dev_priv, HSW_AUD_CHICKENBIT, tmp);
+               intel_de_rmw(i915, HSW_AUD_CHICKENBIT,
+                            0, SKL_AUD_CODEC_WAKE_SIGNAL);
                usleep_range(1000, 1500);
        }
 
@@ -1114,12 +1108,12 @@ static void i915_audio_component_codec_wake_override(struct device *kdev,
 /* Get CDCLK in kHz  */
 static int i915_audio_component_get_cdclk_freq(struct device *kdev)
 {
-       struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
+       struct drm_i915_private *i915 = kdev_to_i915(kdev);
 
-       if (drm_WARN_ON_ONCE(&dev_priv->drm, !HAS_DDI(dev_priv)))
+       if (drm_WARN_ON_ONCE(&i915->drm, !HAS_DDI(i915)))
                return -ENODEV;
 
-       return dev_priv->display.cdclk.hw.cdclk;
+       return i915->display.cdclk.hw.cdclk;
 }
 
 /*
@@ -1132,18 +1126,18 @@ static int i915_audio_component_get_cdclk_freq(struct device *kdev)
  *   will get the right intel_encoder with port matched
  * Non-MST & (pipe < 0): get the right intel_encoder with port matched
  */
-static struct intel_encoder *get_saved_enc(struct drm_i915_private *dev_priv,
-                                              int port, int pipe)
+static struct intel_encoder *get_saved_enc(struct drm_i915_private *i915,
+                                          int port, int pipe)
 {
        struct intel_encoder *encoder;
 
        /* MST */
        if (pipe >= 0) {
-               if (drm_WARN_ON(&dev_priv->drm,
-                               pipe >= ARRAY_SIZE(dev_priv->display.audio.encoder_map)))
+               if (drm_WARN_ON(&i915->drm,
+                               pipe >= ARRAY_SIZE(i915->display.audio.encoder_map)))
                        return NULL;
 
-               encoder = dev_priv->display.audio.encoder_map[pipe];
+               encoder = i915->display.audio.encoder_map[pipe];
                /*
                 * when bootup, audio driver may not know it is
                 * MST or not. So it will poll all the port & pipe
@@ -1158,8 +1152,8 @@ static struct intel_encoder *get_saved_enc(struct drm_i915_private *dev_priv,
        if (pipe > 0)
                return NULL;
 
-       for_each_pipe(dev_priv, pipe) {
-               encoder = dev_priv->display.audio.encoder_map[pipe];
+       for_each_pipe(i915, pipe) {
+               encoder = i915->display.audio.encoder_map[pipe];
                if (encoder == NULL)
                        continue;
 
@@ -1176,23 +1170,23 @@ static struct intel_encoder *get_saved_enc(struct drm_i915_private *dev_priv,
 static int i915_audio_component_sync_audio_rate(struct device *kdev, int port,
                                                int pipe, int rate)
 {
-       struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
-       struct i915_audio_component *acomp = dev_priv->display.audio.component;
+       struct drm_i915_private *i915 = kdev_to_i915(kdev);
+       struct i915_audio_component *acomp = i915->display.audio.component;
        struct intel_encoder *encoder;
        struct intel_crtc *crtc;
        unsigned long cookie;
        int err = 0;
 
-       if (!HAS_DDI(dev_priv))
+       if (!HAS_DDI(i915))
                return 0;
 
        cookie = i915_audio_component_get_power(kdev);
-       mutex_lock(&dev_priv->display.audio.mutex);
+       mutex_lock(&i915->display.audio.mutex);
 
        /* 1. get the pipe */
-       encoder = get_saved_enc(dev_priv, port, pipe);
+       encoder = get_saved_enc(i915, port, pipe);
        if (!encoder || !encoder->base.crtc) {
-               drm_dbg_kms(&dev_priv->drm, "Not valid for port %c\n",
+               drm_dbg_kms(&i915->drm, "Not valid for port %c\n",
                            port_name(port));
                err = -ENODEV;
                goto unlock;
@@ -1206,7 +1200,7 @@ static int i915_audio_component_sync_audio_rate(struct device *kdev, int port,
        hsw_audio_config_update(encoder, crtc->config);
 
  unlock:
-       mutex_unlock(&dev_priv->display.audio.mutex);
+       mutex_unlock(&i915->display.audio.mutex);
        i915_audio_component_put_power(kdev, cookie);
        return err;
 }
@@ -1215,18 +1209,18 @@ static int i915_audio_component_get_eld(struct device *kdev, int port,
                                        int pipe, bool *enabled,
                                        unsigned char *buf, int max_bytes)
 {
-       struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
+       struct drm_i915_private *i915 = kdev_to_i915(kdev);
        struct intel_encoder *intel_encoder;
        const u8 *eld;
        int ret = -EINVAL;
 
-       mutex_lock(&dev_priv->display.audio.mutex);
+       mutex_lock(&i915->display.audio.mutex);
 
-       intel_encoder = get_saved_enc(dev_priv, port, pipe);
+       intel_encoder = get_saved_enc(i915, port, pipe);
        if (!intel_encoder) {
-               drm_dbg_kms(&dev_priv->drm, "Not valid for port %c\n",
+               drm_dbg_kms(&i915->drm, "Not valid for port %c\n",
                            port_name(port));
-               mutex_unlock(&dev_priv->display.audio.mutex);
+               mutex_unlock(&i915->display.audio.mutex);
                return ret;
        }
 
@@ -1238,7 +1232,7 @@ static int i915_audio_component_get_eld(struct device *kdev, int port,
                memcpy(buf, eld, min(max_bytes, ret));
        }
 
-       mutex_unlock(&dev_priv->display.audio.mutex);
+       mutex_unlock(&i915->display.audio.mutex);
        return ret;
 }
 
@@ -1256,25 +1250,25 @@ static int i915_audio_component_bind(struct device *i915_kdev,
                                     struct device *hda_kdev, void *data)
 {
        struct i915_audio_component *acomp = data;
-       struct drm_i915_private *dev_priv = kdev_to_i915(i915_kdev);
+       struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
        int i;
 
-       if (drm_WARN_ON(&dev_priv->drm, acomp->base.ops || acomp->base.dev))
+       if (drm_WARN_ON(&i915->drm, acomp->base.ops || acomp->base.dev))
                return -EEXIST;
 
-       if (drm_WARN_ON(&dev_priv->drm,
+       if (drm_WARN_ON(&i915->drm,
                        !device_link_add(hda_kdev, i915_kdev,
                                         DL_FLAG_STATELESS)))
                return -ENOMEM;
 
-       drm_modeset_lock_all(&dev_priv->drm);
+       drm_modeset_lock_all(&i915->drm);
        acomp->base.ops = &i915_audio_component_ops;
        acomp->base.dev = i915_kdev;
        BUILD_BUG_ON(MAX_PORTS != I915_MAX_PORTS);
        for (i = 0; i < ARRAY_SIZE(acomp->aud_sample_rate); i++)
                acomp->aud_sample_rate[i] = 0;
-       dev_priv->display.audio.component = acomp;
-       drm_modeset_unlock_all(&dev_priv->drm);
+       i915->display.audio.component = acomp;
+       drm_modeset_unlock_all(&i915->drm);
 
        return 0;
 }
@@ -1283,19 +1277,19 @@ static void i915_audio_component_unbind(struct device *i915_kdev,
                                        struct device *hda_kdev, void *data)
 {
        struct i915_audio_component *acomp = data;
-       struct drm_i915_private *dev_priv = kdev_to_i915(i915_kdev);
+       struct drm_i915_private *i915 = kdev_to_i915(i915_kdev);
 
-       drm_modeset_lock_all(&dev_priv->drm);
+       drm_modeset_lock_all(&i915->drm);
        acomp->base.ops = NULL;
        acomp->base.dev = NULL;
-       dev_priv->display.audio.component = NULL;
-       drm_modeset_unlock_all(&dev_priv->drm);
+       i915->display.audio.component = NULL;
+       drm_modeset_unlock_all(&i915->drm);
 
        device_link_remove(hda_kdev, i915_kdev);
 
-       if (dev_priv->display.audio.power_refcount)
-               drm_err(&dev_priv->drm, "audio power refcount %d after unbind\n",
-                       dev_priv->display.audio.power_refcount);
+       if (i915->display.audio.power_refcount)
+               drm_err(&i915->drm, "audio power refcount %d after unbind\n",
+                       i915->display.audio.power_refcount);
 }
 
 static const struct component_ops i915_audio_component_bind_ops = {
@@ -1314,7 +1308,7 @@ static const struct component_ops i915_audio_component_bind_ops = {
 
 /**
  * i915_audio_component_init - initialize and register the audio component
- * @dev_priv: i915 device instance
+ * @i915: i915 device instance
  *
  * This will register with the component framework a child component which
  * will bind dynamically to the snd_hda_intel driver's corresponding master
@@ -1328,83 +1322,83 @@ static const struct component_ops i915_audio_component_bind_ops = {
  * We ignore any error during registration and continue with reduced
  * functionality (i.e. without HDMI audio).
  */
-static void i915_audio_component_init(struct drm_i915_private *dev_priv)
+static void i915_audio_component_init(struct drm_i915_private *i915)
 {
        u32 aud_freq, aud_freq_init;
        int ret;
 
-       ret = component_add_typed(dev_priv->drm.dev,
+       ret = component_add_typed(i915->drm.dev,
                                  &i915_audio_component_bind_ops,
                                  I915_COMPONENT_AUDIO);
        if (ret < 0) {
-               drm_err(&dev_priv->drm,
+               drm_err(&i915->drm,
                        "failed to add audio component (%d)\n", ret);
                /* continue with reduced functionality */
                return;
        }
 
-       if (DISPLAY_VER(dev_priv) >= 9) {
-               aud_freq_init = intel_de_read(dev_priv, AUD_FREQ_CNTRL);
+       if (DISPLAY_VER(i915) >= 9) {
+               aud_freq_init = intel_de_read(i915, AUD_FREQ_CNTRL);
 
-               if (DISPLAY_VER(dev_priv) >= 12)
+               if (DISPLAY_VER(i915) >= 12)
                        aud_freq = AUD_FREQ_GEN12;
                else
                        aud_freq = aud_freq_init;
 
                /* use BIOS provided value for TGL and RKL unless it is a known bad value */
-               if ((IS_TIGERLAKE(dev_priv) || IS_ROCKETLAKE(dev_priv)) &&
+               if ((IS_TIGERLAKE(i915) || IS_ROCKETLAKE(i915)) &&
                    aud_freq_init != AUD_FREQ_TGL_BROKEN)
                        aud_freq = aud_freq_init;
 
-               drm_dbg_kms(&dev_priv->drm, "use AUD_FREQ_CNTRL of 0x%x (init value 0x%x)\n",
+               drm_dbg_kms(&i915->drm, "use AUD_FREQ_CNTRL of 0x%x (init value 0x%x)\n",
                            aud_freq, aud_freq_init);
 
-               dev_priv->display.audio.freq_cntrl = aud_freq;
+               i915->display.audio.freq_cntrl = aud_freq;
        }
 
        /* init with current cdclk */
-       intel_audio_cdclk_change_post(dev_priv);
+       intel_audio_cdclk_change_post(i915);
 
-       dev_priv->display.audio.component_registered = true;
+       i915->display.audio.component_registered = true;
 }
 
 /**
  * i915_audio_component_cleanup - deregister the audio component
- * @dev_priv: i915 device instance
+ * @i915: i915 device instance
  *
  * Deregisters the audio component, breaking any existing binding to the
  * corresponding snd_hda_intel driver's master component.
  */
-static void i915_audio_component_cleanup(struct drm_i915_private *dev_priv)
+static void i915_audio_component_cleanup(struct drm_i915_private *i915)
 {
-       if (!dev_priv->display.audio.component_registered)
+       if (!i915->display.audio.component_registered)
                return;
 
-       component_del(dev_priv->drm.dev, &i915_audio_component_bind_ops);
-       dev_priv->display.audio.component_registered = false;
+       component_del(i915->drm.dev, &i915_audio_component_bind_ops);
+       i915->display.audio.component_registered = false;
 }
 
 /**
  * intel_audio_init() - Initialize the audio driver either using
  * component framework or using lpe audio bridge
- * @dev_priv: the i915 drm device private data
+ * @i915: the i915 drm device private data
  *
  */
-void intel_audio_init(struct drm_i915_private *dev_priv)
+void intel_audio_init(struct drm_i915_private *i915)
 {
-       if (intel_lpe_audio_init(dev_priv) < 0)
-               i915_audio_component_init(dev_priv);
+       if (intel_lpe_audio_init(i915) < 0)
+               i915_audio_component_init(i915);
 }
 
 /**
  * intel_audio_deinit() - deinitialize the audio driver
- * @dev_priv: the i915 drm device private data
+ * @i915: the i915 drm device private data
  *
  */
-void intel_audio_deinit(struct drm_i915_private *dev_priv)
+void intel_audio_deinit(struct drm_i915_private *i915)
 {
-       if (dev_priv->display.audio.lpe.platdev != NULL)
-               intel_lpe_audio_teardown(dev_priv);
+       if (i915->display.audio.lpe.platdev != NULL)
+               intel_lpe_audio_teardown(i915);
        else
-               i915_audio_component_cleanup(dev_priv);
+               i915_audio_component_cleanup(i915);
 }
index d1e5844..4f432c2 100644 (file)
@@ -8,16 +8,11 @@
 
 #include "i915_reg_defs.h"
 
-#define G4X_AUD_VID_DID                        _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x62020)
-#define   INTEL_AUDIO_DEVCL            0x808629FB
-#define   INTEL_AUDIO_DEVBLC           0x80862801
-#define   INTEL_AUDIO_DEVCTG           0x80862802
-
 #define G4X_AUD_CNTL_ST                        _MMIO(0x620B4)
-#define   G4X_ELDV_DEVCL_DEVBLC                (1 << 13)
-#define   G4X_ELDV_DEVCTG              (1 << 14)
-#define   G4X_ELD_ADDR_MASK            (0xf << 5)
-#define   G4X_ELD_ACK                  (1 << 4)
+#define   G4X_ELD_VALID                        REG_BIT(14)
+#define   G4X_ELD_BUFFER_SIZE_MASK     REG_GENMASK(13, 9)
+#define   G4X_ELD_ADDRESS_MASK         REG_GENMASK(8, 5)
+#define   G4X_ELD_ACK                  REG_BIT(4)
 #define G4X_HDMIW_HDMIEDID             _MMIO(0x6210C)
 
 #define _IBX_HDMIW_HDMIEDID_A          0xE2050
 #define _IBX_AUD_CNTL_ST_B             0xE21B4
 #define IBX_AUD_CNTL_ST(pipe)          _MMIO_PIPE(pipe, _IBX_AUD_CNTL_ST_A, \
                                                  _IBX_AUD_CNTL_ST_B)
-#define   IBX_ELD_BUFFER_SIZE_MASK     (0x1f << 10)
-#define   IBX_ELD_ADDRESS_MASK         (0x1f << 5)
-#define   IBX_ELD_ACK                  (1 << 4)
+#define   IBX_ELD_BUFFER_SIZE_MASK     REG_GENMASK(14, 10)
+#define   IBX_ELD_ADDRESS_MASK         REG_GENMASK(9, 5)
+#define   IBX_ELD_ACK                  REG_BIT(4)
 #define IBX_AUD_CNTL_ST2               _MMIO(0xE20C0)
-#define   IBX_CP_READY(port)           ((1 << 1) << (((port) - 1) * 4))
-#define   IBX_ELD_VALID(port)          ((1 << 0) << (((port) - 1) * 4))
+#define   IBX_CP_READY(port)           REG_BIT(((port) - 1) * 4 + 1)
+#define   IBX_ELD_VALID(port)          REG_BIT(((port) - 1) * 4 + 0)
 
 #define _CPT_HDMIW_HDMIEDID_A          0xE5050
 #define _CPT_HDMIW_HDMIEDID_B          0xE5150
 #define _VLV_AUD_CONFIG_A              (VLV_DISPLAY_BASE + 0x62000)
 #define _VLV_AUD_CONFIG_B              (VLV_DISPLAY_BASE + 0x62100)
 #define VLV_AUD_CFG(pipe)              _MMIO_PIPE(pipe, _VLV_AUD_CONFIG_A, _VLV_AUD_CONFIG_B)
-
-#define   AUD_CONFIG_N_VALUE_INDEX             (1 << 29)
-#define   AUD_CONFIG_N_PROG_ENABLE             (1 << 28)
-#define   AUD_CONFIG_UPPER_N_SHIFT             20
-#define   AUD_CONFIG_UPPER_N_MASK              (0xff << 20)
-#define   AUD_CONFIG_LOWER_N_SHIFT             4
-#define   AUD_CONFIG_LOWER_N_MASK              (0xfff << 4)
-#define   AUD_CONFIG_N_MASK                    (AUD_CONFIG_UPPER_N_MASK | AUD_CONFIG_LOWER_N_MASK)
-#define   AUD_CONFIG_N(n) \
-       (((((n) >> 12) & 0xff) << AUD_CONFIG_UPPER_N_SHIFT) |   \
-        (((n) & 0xfff) << AUD_CONFIG_LOWER_N_SHIFT))
-#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_SHIFT    16
-#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK     (0xf << 16)
-#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_25175    (0 << 16)
-#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_25200    (1 << 16)
-#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_27000    (2 << 16)
-#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_27027    (3 << 16)
-#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_54000    (4 << 16)
-#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_54054    (5 << 16)
-#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_74176    (6 << 16)
-#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_74250    (7 << 16)
-#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_148352   (8 << 16)
-#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_148500   (9 << 16)
-#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_296703   (10 << 16)
-#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_297000   (11 << 16)
-#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_593407   (12 << 16)
-#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_594000   (13 << 16)
-#define   AUD_CONFIG_DISABLE_NCTS              (1 << 3)
+#define   AUD_CONFIG_N_VALUE_INDEX             REG_BIT(29)
+#define   AUD_CONFIG_N_PROG_ENABLE             REG_BIT(28)
+#define   AUD_CONFIG_UPPER_N_MASK              REG_GENMASK(27, 20)
+#define   AUD_CONFIG_LOWER_N_MASK              REG_GENMASK(15, 4)
+#define   AUD_CONFIG_N_MASK                    (AUD_CONFIG_UPPER_N_MASK | \
+                                                AUD_CONFIG_LOWER_N_MASK)
+#define   AUD_CONFIG_N(n)                      (REG_FIELD_PREP(AUD_CONFIG_UPPER_N_MASK, (n) >> 12) | \
+                                                REG_FIELD_PREP(AUD_CONFIG_LOWER_N_MASK, (n) & 0xfff))
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK     REG_GENMASK(19, 16)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_25175    REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 0)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_25200    REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 1)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_27000    REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 2)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_27027    REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 3)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_54000    REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 4)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_54054    REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 5)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_74176    REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 6)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_74250    REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 7)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_148352   REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 8)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_148500   REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 9)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_296703   REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 10)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_297000   REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 11)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_593407   REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 12)
+#define   AUD_CONFIG_PIXEL_CLOCK_HDMI_594000   REG_FIELD_PREP(AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK, 13)
+#define   AUD_CONFIG_DISABLE_NCTS              REG_BIT(3)
 
 #define _HSW_AUD_CONFIG_A              0x65000
 #define _HSW_AUD_CONFIG_B              0x65100
 #define _HSW_AUD_M_CTS_ENABLE_A                0x65028
 #define _HSW_AUD_M_CTS_ENABLE_B                0x65128
 #define HSW_AUD_M_CTS_ENABLE(trans)    _MMIO_TRANS(trans, _HSW_AUD_M_CTS_ENABLE_A, _HSW_AUD_M_CTS_ENABLE_B)
-#define   AUD_M_CTS_M_VALUE_INDEX      (1 << 21)
-#define   AUD_M_CTS_M_PROG_ENABLE      (1 << 20)
-#define   AUD_CONFIG_M_MASK            0xfffff
+#define   AUD_M_CTS_M_VALUE_INDEX      REG_BIT(21)
+#define   AUD_M_CTS_M_PROG_ENABLE      REG_BIT(20)
+#define   AUD_CONFIG_M_MASK            REG_GENMASK(19, 0)
 
 #define _HSW_AUD_DIP_ELD_CTRL_ST_A     0x650b4
 #define _HSW_AUD_DIP_ELD_CTRL_ST_B     0x651b4
 #define AUD_DP_2DOT0_CTRL(trans)       _MMIO_TRANS(trans, _AUD_TCA_DP_2DOT0_CTRL, _AUD_TCB_DP_2DOT0_CTRL)
 #define  AUD_ENABLE_SDP_SPLIT          REG_BIT(31)
 
-#define HSW_AUD_CHICKENBIT                     _MMIO(0x65f10)
-#define   SKL_AUD_CODEC_WAKE_SIGNAL            (1 << 15)
+#define HSW_AUD_CHICKENBIT             _MMIO(0x65f10)
+#define   SKL_AUD_CODEC_WAKE_SIGNAL    REG_BIT(15)
 
 #define AUD_FREQ_CNTRL                 _MMIO(0x65900)
-#define AUD_PIN_BUF_CTL                _MMIO(0x48414)
+#define AUD_PIN_BUF_CTL                        _MMIO(0x48414)
 #define   AUD_PIN_BUF_ENABLE           REG_BIT(31)
 
 #define AUD_TS_CDCLK_M                 _MMIO(0x65ea0)
index 28bdb93..c2987f2 100644 (file)
@@ -2188,7 +2188,7 @@ static u8 map_ddc_pin(struct drm_i915_private *i915, u8 vbt_pin)
        const u8 *ddc_pin_map;
        int n_entries;
 
-       if (IS_ALDERLAKE_P(i915)) {
+       if (HAS_PCH_MTP(i915) || IS_ALDERLAKE_P(i915)) {
                ddc_pin_map = adlp_ddc_pin_map;
                n_entries = ARRAY_SIZE(adlp_ddc_pin_map);
        } else if (IS_ALDERLAKE_S(i915)) {
@@ -2676,6 +2676,14 @@ static void print_ddi_port(const struct intel_bios_encoder_data *devdata,
                drm_dbg_kms(&i915->drm,
                            "Port %c VBT DP max link rate: %d\n",
                            port_name(port), dp_max_link_rate);
+
+       /*
+        * FIXME need to implement support for VBT
+        * vswing/preemph tables should this ever trigger.
+        */
+       drm_WARN(&i915->drm, child->use_vbt_vswing,
+                "Port %c asks to use VBT vswing/preemph tables\n",
+                port_name(port));
 }
 
 static void parse_ddi_port(struct intel_bios_encoder_data *devdata)
index ed05070..eada931 100644 (file)
@@ -1220,11 +1220,6 @@ static void skl_cdclk_uninit_hw(struct drm_i915_private *dev_priv)
        skl_set_cdclk(dev_priv, &cdclk_config, INVALID_PIPE);
 }
 
-static bool has_cdclk_squasher(struct drm_i915_private *i915)
-{
-       return IS_DG2(i915);
-}
-
 struct intel_cdclk_vals {
        u32 cdclk;
        u16 refclk;
@@ -1520,7 +1515,7 @@ static void bxt_get_cdclk(struct drm_i915_private *dev_priv,
                return;
        }
 
-       if (has_cdclk_squasher(dev_priv))
+       if (HAS_CDCLK_SQUASH(dev_priv))
                squash_ctl = intel_de_read(dev_priv, CDCLK_SQUASH_CTL);
 
        if (squash_ctl & CDCLK_SQUASH_ENABLE) {
@@ -1689,6 +1684,38 @@ static u32 cdclk_squash_waveform(struct drm_i915_private *dev_priv,
        return 0xffff;
 }
 
+static void icl_cdclk_pll_update(struct drm_i915_private *i915, int vco)
+{
+       if (i915->display.cdclk.hw.vco != 0 &&
+           i915->display.cdclk.hw.vco != vco)
+               icl_cdclk_pll_disable(i915);
+
+       if (i915->display.cdclk.hw.vco != vco)
+               icl_cdclk_pll_enable(i915, vco);
+}
+
+static void bxt_cdclk_pll_update(struct drm_i915_private *i915, int vco)
+{
+       if (i915->display.cdclk.hw.vco != 0 &&
+           i915->display.cdclk.hw.vco != vco)
+               bxt_de_pll_disable(i915);
+
+       if (i915->display.cdclk.hw.vco != vco)
+               bxt_de_pll_enable(i915, vco);
+}
+
+static void dg2_cdclk_squash_program(struct drm_i915_private *i915,
+                                    u16 waveform)
+{
+       u32 squash_ctl = 0;
+
+       if (waveform)
+               squash_ctl = CDCLK_SQUASH_ENABLE |
+                            CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform;
+
+       intel_de_write(i915, CDCLK_SQUASH_CTL, squash_ctl);
+}
+
 static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
                          const struct intel_cdclk_config *cdclk_config,
                          enum pipe pipe)
@@ -1724,21 +1751,10 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
        if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->display.cdclk.hw.vco > 0 && vco > 0) {
                if (dev_priv->display.cdclk.hw.vco != vco)
                        adlp_cdclk_pll_crawl(dev_priv, vco);
-       } else if (DISPLAY_VER(dev_priv) >= 11) {
-               if (dev_priv->display.cdclk.hw.vco != 0 &&
-                   dev_priv->display.cdclk.hw.vco != vco)
-                       icl_cdclk_pll_disable(dev_priv);
-
-               if (dev_priv->display.cdclk.hw.vco != vco)
-                       icl_cdclk_pll_enable(dev_priv, vco);
-       } else {
-               if (dev_priv->display.cdclk.hw.vco != 0 &&
-                   dev_priv->display.cdclk.hw.vco != vco)
-                       bxt_de_pll_disable(dev_priv);
-
-               if (dev_priv->display.cdclk.hw.vco != vco)
-                       bxt_de_pll_enable(dev_priv, vco);
-       }
+       } else if (DISPLAY_VER(dev_priv) >= 11)
+               icl_cdclk_pll_update(dev_priv, vco);
+       else
+               bxt_cdclk_pll_update(dev_priv, vco);
 
        waveform = cdclk_squash_waveform(dev_priv, cdclk);
 
@@ -1747,15 +1763,8 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
        else
                clock = cdclk;
 
-       if (has_cdclk_squasher(dev_priv)) {
-               u32 squash_ctl = 0;
-
-               if (waveform)
-                       squash_ctl = CDCLK_SQUASH_ENABLE |
-                               CDCLK_SQUASH_WINDOW_SIZE(0xf) | waveform;
-
-               intel_de_write(dev_priv, CDCLK_SQUASH_CTL, squash_ctl);
-       }
+       if (HAS_CDCLK_SQUASH(dev_priv))
+               dg2_cdclk_squash_program(dev_priv, waveform);
 
        val = bxt_cdclk_cd2x_div_sel(dev_priv, clock, vco) |
                bxt_cdclk_cd2x_pipe(dev_priv, pipe) |
@@ -1845,7 +1854,7 @@ static void bxt_sanitize_cdclk(struct drm_i915_private *dev_priv)
        expected = skl_cdclk_decimal(cdclk);
 
        /* Figure out what CD2X divider we should be using for this cdclk */
-       if (has_cdclk_squasher(dev_priv))
+       if (HAS_CDCLK_SQUASH(dev_priv))
                clock = dev_priv->display.cdclk.hw.vco / 2;
        else
                clock = dev_priv->display.cdclk.hw.cdclk;
@@ -1976,7 +1985,7 @@ static bool intel_cdclk_can_squash(struct drm_i915_private *dev_priv,
         * the moment all platforms with squasher use a fixed cd2x
         * divider.
         */
-       if (!has_cdclk_squasher(dev_priv))
+       if (!HAS_CDCLK_SQUASH(dev_priv))
                return false;
 
        return a->cdclk != b->cdclk &&
@@ -2028,7 +2037,7 @@ static bool intel_cdclk_can_cd2x_update(struct drm_i915_private *dev_priv,
         * the moment all platforms with squasher use a fixed cd2x
         * divider.
         */
-       if (has_cdclk_squasher(dev_priv))
+       if (HAS_CDCLK_SQUASH(dev_priv))
                return false;
 
        return a->cdclk != b->cdclk &&
@@ -2464,10 +2473,6 @@ static int bdw_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
        if (min_cdclk < 0)
                return min_cdclk;
 
-       /*
-        * FIXME should also account for plane ratio
-        * once 64bpp pixel formats are supported.
-        */
        cdclk = bdw_calc_cdclk(min_cdclk);
 
        cdclk_state->logical.cdclk = cdclk;
@@ -2534,10 +2539,6 @@ static int skl_modeset_calc_cdclk(struct intel_cdclk_state *cdclk_state)
 
        vco = skl_dpll0_vco(cdclk_state);
 
-       /*
-        * FIXME should also account for plane ratio
-        * once 64bpp pixel formats are supported.
-        */
        cdclk = skl_calc_cdclk(min_cdclk, vco);
 
        cdclk_state->logical.vco = vco;
@@ -2762,12 +2763,12 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
                                   &old_cdclk_state->actual,
                                   &new_cdclk_state->actual)) {
                drm_dbg_kms(&dev_priv->drm,
-                           "Can change cdclk via squasher\n");
+                           "Can change cdclk via squashing\n");
        } else if (intel_cdclk_can_crawl(dev_priv,
                                         &old_cdclk_state->actual,
                                         &new_cdclk_state->actual)) {
                drm_dbg_kms(&dev_priv->drm,
-                           "Can change cdclk via crawl\n");
+                           "Can change cdclk via crawling\n");
        } else if (pipe != INVALID_PIPE) {
                new_cdclk_state->pipe = pipe;
 
@@ -2777,7 +2778,7 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
        } else if (intel_cdclk_needs_modeset(&old_cdclk_state->actual,
                                             &new_cdclk_state->actual)) {
                /* All pipes must be switched off while we change the cdclk. */
-               ret = intel_modeset_all_pipes(state);
+               ret = intel_modeset_all_pipes(state, "CDCLK change");
                if (ret)
                        return ret;
 
index 6bda427..4bb113c 100644 (file)
@@ -25,9 +25,7 @@
 #include "intel_color.h"
 #include "intel_de.h"
 #include "intel_display_types.h"
-#include "intel_dpll.h"
 #include "intel_dsb.h"
-#include "vlv_dsi_pll.h"
 
 struct intel_color_funcs {
        int (*color_check)(struct intel_crtc_state *crtc_state);
@@ -559,6 +557,32 @@ static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state)
                          crtc_state->csc_mode);
 }
 
+static struct drm_property_blob *
+create_linear_lut(struct drm_i915_private *i915, int lut_size)
+{
+       struct drm_property_blob *blob;
+       struct drm_color_lut *lut;
+       int i;
+
+       blob = drm_property_create_blob(&i915->drm,
+                                       sizeof(struct drm_color_lut) * lut_size,
+                                       NULL);
+       if (IS_ERR(blob))
+               return blob;
+
+       lut = blob->data;
+
+       for (i = 0; i < lut_size; i++) {
+               u16 val = 0xffff * i / (lut_size - 1);
+
+               lut[i].red = val;
+               lut[i].green = val;
+               lut[i].blue = val;
+       }
+
+       return blob;
+}
+
 static void i9xx_load_lut_8(struct intel_crtc *crtc,
                            const struct drm_property_blob *blob)
 {
@@ -580,12 +604,9 @@ static void i9xx_load_lut_8(struct intel_crtc *crtc,
 static void i9xx_load_luts(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-       const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
+       const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
 
-       assert_pll_enabled(dev_priv, crtc->pipe);
-
-       i9xx_load_lut_8(crtc, gamma_lut);
+       i9xx_load_lut_8(crtc, post_csc_lut);
 }
 
 static void i965_load_lut_10p6(struct intel_crtc *crtc,
@@ -611,18 +632,12 @@ static void i965_load_lut_10p6(struct intel_crtc *crtc,
 static void i965_load_luts(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-       const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
-
-       if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
-               assert_dsi_pll_enabled(dev_priv);
-       else
-               assert_pll_enabled(dev_priv, crtc->pipe);
+       const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
 
        if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
-               i9xx_load_lut_8(crtc, gamma_lut);
+               i9xx_load_lut_8(crtc, post_csc_lut);
        else
-               i965_load_lut_10p6(crtc, gamma_lut);
+               i965_load_lut_10p6(crtc, post_csc_lut);
 }
 
 static void ilk_load_lut_8(struct intel_crtc *crtc,
@@ -659,14 +674,16 @@ static void ilk_load_lut_10(struct intel_crtc *crtc,
 static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-       const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
+       const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
+       const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
+       const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut;
 
        switch (crtc_state->gamma_mode) {
        case GAMMA_MODE_MODE_8BIT:
-               ilk_load_lut_8(crtc, gamma_lut);
+               ilk_load_lut_8(crtc, blob);
                break;
        case GAMMA_MODE_MODE_10BIT:
-               ilk_load_lut_10(crtc, gamma_lut);
+               ilk_load_lut_10(crtc, blob);
                break;
        default:
                MISSING_CASE(crtc_state->gamma_mode);
@@ -773,19 +790,19 @@ static void ivb_load_lut_ext_max(const struct intel_crtc_state *crtc_state)
 static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-       const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
-       const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
-       const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
+       const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
+       const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
+       const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut;
 
        switch (crtc_state->gamma_mode) {
        case GAMMA_MODE_MODE_8BIT:
                ilk_load_lut_8(crtc, blob);
                break;
        case GAMMA_MODE_MODE_SPLIT:
-               ivb_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
+               ivb_load_lut_10(crtc, pre_csc_lut, PAL_PREC_SPLIT_MODE |
                                PAL_PREC_INDEX_VALUE(0));
                ivb_load_lut_ext_max(crtc_state);
-               ivb_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
+               ivb_load_lut_10(crtc, post_csc_lut, PAL_PREC_SPLIT_MODE |
                                PAL_PREC_INDEX_VALUE(512));
                break;
        case GAMMA_MODE_MODE_10BIT:
@@ -802,19 +819,19 @@ static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
 static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-       const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
-       const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
-       const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
+       const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
+       const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
+       const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut;
 
        switch (crtc_state->gamma_mode) {
        case GAMMA_MODE_MODE_8BIT:
                ilk_load_lut_8(crtc, blob);
                break;
        case GAMMA_MODE_MODE_SPLIT:
-               bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
+               bdw_load_lut_10(crtc, pre_csc_lut, PAL_PREC_SPLIT_MODE |
                                PAL_PREC_INDEX_VALUE(0));
                ivb_load_lut_ext_max(crtc_state);
-               bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
+               bdw_load_lut_10(crtc, post_csc_lut, PAL_PREC_SPLIT_MODE |
                                PAL_PREC_INDEX_VALUE(512));
                break;
        case GAMMA_MODE_MODE_10BIT:
@@ -837,13 +854,14 @@ static int glk_degamma_lut_size(struct drm_i915_private *i915)
                return 35;
 }
 
-static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
+static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state,
+                                const struct drm_property_blob *blob)
 {
        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_color_lut *lut = blob->data;
+       int i, lut_size = drm_color_lut_size(blob);
        enum pipe pipe = crtc->pipe;
-       int i, lut_size = INTEL_INFO(dev_priv)->display.color.degamma_lut_size;
-       const struct drm_color_lut *lut = crtc_state->hw.degamma_lut->data;
 
        /*
         * When setting the auto-increment bit, the hardware seems to
@@ -879,59 +897,21 @@ static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
        intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0);
 }
 
-static void glk_load_degamma_lut_linear(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);
-       enum pipe pipe = crtc->pipe;
-       int i, lut_size = INTEL_INFO(dev_priv)->display.color.degamma_lut_size;
-
-       /*
-        * When setting the auto-increment bit, the hardware seems to
-        * ignore the index bits, so we need to reset it to index 0
-        * separately.
-        */
-       intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0);
-       intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe),
-                         PRE_CSC_GAMC_AUTO_INCREMENT);
-
-       for (i = 0; i < lut_size; i++) {
-               u32 v = (i << 16) / (lut_size - 1);
-
-               intel_de_write_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe), v);
-       }
-
-       /* Clamp values > 1.0. */
-       while (i++ < 35)
-               intel_de_write_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe), 1 << 16);
-
-       intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe), 0);
-}
-
 static void glk_load_luts(const struct intel_crtc_state *crtc_state)
 {
-       const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
+       const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
+       const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
-       /*
-        * On GLK+ both pipe CSC and degamma LUT are controlled
-        * by csc_enable. Hence for the cases where the CSC is
-        * needed but degamma LUT is not we need to load a
-        * linear degamma LUT. In fact we'll just always load
-        * the degama LUT so that we don't have to reload
-        * it every time the pipe CSC is being enabled.
-        */
-       if (crtc_state->hw.degamma_lut)
-               glk_load_degamma_lut(crtc_state);
-       else
-               glk_load_degamma_lut_linear(crtc_state);
+       if (pre_csc_lut)
+               glk_load_degamma_lut(crtc_state, pre_csc_lut);
 
        switch (crtc_state->gamma_mode) {
        case GAMMA_MODE_MODE_8BIT:
-               ilk_load_lut_8(crtc, gamma_lut);
+               ilk_load_lut_8(crtc, post_csc_lut);
                break;
        case GAMMA_MODE_MODE_10BIT:
-               bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
+               bdw_load_lut_10(crtc, post_csc_lut, PAL_PREC_INDEX_VALUE(0));
                ivb_load_lut_ext_max(crtc_state);
                break;
        default:
@@ -971,7 +951,7 @@ static void
 icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-       const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
+       const struct drm_property_blob *blob = crtc_state->post_csc_lut;
        const struct drm_color_lut *lut = blob->data;
        enum pipe pipe = crtc->pipe;
        int i;
@@ -1000,7 +980,7 @@ static void
 icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-       const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
+       const struct drm_property_blob *blob = crtc_state->post_csc_lut;
        const struct drm_color_lut *lut = blob->data;
        const struct drm_color_lut *entry;
        enum pipe pipe = crtc->pipe;
@@ -1054,22 +1034,23 @@ icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
 
 static void icl_load_luts(const struct intel_crtc_state *crtc_state)
 {
-       const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
+       const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
+       const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
-       if (crtc_state->hw.degamma_lut)
-               glk_load_degamma_lut(crtc_state);
+       if (pre_csc_lut)
+               glk_load_degamma_lut(crtc_state, pre_csc_lut);
 
        switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
        case GAMMA_MODE_MODE_8BIT:
-               ilk_load_lut_8(crtc, gamma_lut);
+               ilk_load_lut_8(crtc, post_csc_lut);
                break;
        case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
                icl_program_gamma_superfine_segment(crtc_state);
                icl_program_gamma_multi_segment(crtc_state);
                break;
        case GAMMA_MODE_MODE_10BIT:
-               bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
+               bdw_load_lut_10(crtc, post_csc_lut, PAL_PREC_INDEX_VALUE(0));
                ivb_load_lut_ext_max(crtc_state);
                break;
        default:
@@ -1145,18 +1126,18 @@ static void chv_load_luts(const struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-       const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
-       const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
+       const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
+       const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
        const struct drm_property_blob *ctm = crtc_state->hw.ctm;
 
        if (crtc_state->cgm_mode & CGM_PIPE_MODE_CSC)
                chv_load_cgm_csc(crtc, ctm);
 
        if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA)
-               chv_load_cgm_degamma(crtc, degamma_lut);
+               chv_load_cgm_degamma(crtc, pre_csc_lut);
 
        if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
-               chv_load_cgm_gamma(crtc, gamma_lut);
+               chv_load_cgm_gamma(crtc, post_csc_lut);
        else
                i965_load_luts(crtc_state);
 
@@ -1194,8 +1175,8 @@ static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state
        const struct intel_crtc_state *old_crtc_state =
                intel_atomic_get_old_crtc_state(state, crtc);
 
-       return !old_crtc_state->hw.gamma_lut &&
-               !old_crtc_state->hw.degamma_lut;
+       return !old_crtc_state->post_csc_lut &&
+               !old_crtc_state->pre_csc_lut;
 }
 
 static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
@@ -1214,25 +1195,7 @@ static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
        if (old_crtc_state->cgm_mode || new_crtc_state->cgm_mode)
                return false;
 
-       return !old_crtc_state->hw.gamma_lut;
-}
-
-static bool glk_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
-{
-       struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
-       struct intel_atomic_state *state =
-               to_intel_atomic_state(new_crtc_state->uapi.state);
-       const struct intel_crtc_state *old_crtc_state =
-               intel_atomic_get_old_crtc_state(state, crtc);
-
-       /*
-        * The hardware degamma is active whenever the pipe
-        * CSC is active. Thus even if the old state has no
-        * software degamma we need to avoid clobbering the
-        * linear hardware degamma mid scanout.
-        */
-       return !old_crtc_state->csc_enable &&
-               !old_crtc_state->hw.gamma_lut;
+       return !old_crtc_state->post_csc_lut;
 }
 
 int intel_color_check(struct intel_crtc_state *crtc_state)
@@ -1295,6 +1258,10 @@ intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
                        return PTR_ERR(plane_state);
 
                new_crtc_state->update_planes |= BIT(plane->id);
+
+               /* plane control register changes blocked by CxSR */
+               if (HAS_GMCH(dev_priv))
+                       new_crtc_state->disable_cxsr = true;
        }
 
        return 0;
@@ -1361,6 +1328,40 @@ static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state)
                return GAMMA_MODE_MODE_10BIT; /* i965+ only */
 }
 
+void intel_color_assert_luts(const struct intel_crtc_state *crtc_state)
+{
+       struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+
+       /* make sure {pre,post}_csc_lut were correctly assigned */
+       if (DISPLAY_VER(i915) >= 11 || HAS_GMCH(i915)) {
+               drm_WARN_ON(&i915->drm,
+                           crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut);
+               drm_WARN_ON(&i915->drm,
+                           crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
+       } else if (DISPLAY_VER(i915) == 10) {
+               drm_WARN_ON(&i915->drm,
+                           crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut &&
+                           crtc_state->pre_csc_lut != i915->display.color.glk_linear_degamma_lut);
+               drm_WARN_ON(&i915->drm,
+                           crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
+       } else {
+               drm_WARN_ON(&i915->drm,
+                           crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut &&
+                           crtc_state->pre_csc_lut != crtc_state->hw.gamma_lut);
+               drm_WARN_ON(&i915->drm,
+                           crtc_state->post_csc_lut != crtc_state->hw.degamma_lut &&
+                           crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
+       }
+}
+
+static void intel_assign_luts(struct intel_crtc_state *crtc_state)
+{
+       drm_property_replace_blob(&crtc_state->pre_csc_lut,
+                                 crtc_state->hw.degamma_lut);
+       drm_property_replace_blob(&crtc_state->post_csc_lut,
+                                 crtc_state->hw.gamma_lut);
+}
+
 static int i9xx_color_check(struct intel_crtc_state *crtc_state)
 {
        int ret;
@@ -1379,6 +1380,8 @@ static int i9xx_color_check(struct intel_crtc_state *crtc_state)
        if (ret)
                return ret;
 
+       intel_assign_luts(crtc_state);
+
        crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
 
        return 0;
@@ -1433,6 +1436,8 @@ static int chv_color_check(struct intel_crtc_state *crtc_state)
        if (ret)
                return ret;
 
+       intel_assign_luts(crtc_state);
+
        crtc_state->preload_luts = chv_can_preload_luts(crtc_state);
 
        return 0;
@@ -1458,10 +1463,29 @@ static u32 ilk_csc_mode(const struct intel_crtc_state *crtc_state)
        if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
                return CSC_BLACK_SCREEN_OFFSET;
 
+       if (crtc_state->hw.degamma_lut)
+               return CSC_MODE_YUV_TO_RGB;
+
        return CSC_MODE_YUV_TO_RGB |
                CSC_POSITION_BEFORE_GAMMA;
 }
 
+static void ilk_assign_luts(struct intel_crtc_state *crtc_state)
+{
+       if (crtc_state->hw.degamma_lut ||
+           crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) {
+               drm_property_replace_blob(&crtc_state->pre_csc_lut,
+                                         crtc_state->hw.degamma_lut);
+               drm_property_replace_blob(&crtc_state->post_csc_lut,
+                                         crtc_state->hw.gamma_lut);
+       } else {
+               drm_property_replace_blob(&crtc_state->pre_csc_lut,
+                                         crtc_state->hw.gamma_lut);
+               drm_property_replace_blob(&crtc_state->post_csc_lut,
+                                         NULL);
+       }
+}
+
 static int ilk_color_check(struct intel_crtc_state *crtc_state)
 {
        int ret;
@@ -1489,6 +1513,8 @@ static int ilk_color_check(struct intel_crtc_state *crtc_state)
        if (ret)
                return ret;
 
+       ilk_assign_luts(crtc_state);
+
        crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
 
        return 0;
@@ -1556,6 +1582,8 @@ static int ivb_color_check(struct intel_crtc_state *crtc_state)
        if (ret)
                return ret;
 
+       ilk_assign_luts(crtc_state);
+
        crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
 
        return 0;
@@ -1570,6 +1598,23 @@ static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state)
                return GAMMA_MODE_MODE_10BIT;
 }
 
+static void glk_assign_luts(struct intel_crtc_state *crtc_state)
+{
+       struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+
+       intel_assign_luts(crtc_state);
+
+       /*
+        * On GLK+ both pipe CSC and degamma LUT are controlled
+        * by csc_enable. Hence for the cases where the CSC is
+        * needed but degamma LUT is not we need to load a
+        * linear degamma LUT.
+        */
+       if (crtc_state->csc_enable && !crtc_state->pre_csc_lut)
+               drm_property_replace_blob(&crtc_state->pre_csc_lut,
+                                         i915->display.color.glk_linear_degamma_lut);
+}
+
 static int glk_color_check(struct intel_crtc_state *crtc_state)
 {
        struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
@@ -1604,7 +1649,9 @@ static int glk_color_check(struct intel_crtc_state *crtc_state)
        if (ret)
                return ret;
 
-       crtc_state->preload_luts = glk_can_preload_luts(crtc_state);
+       glk_assign_luts(crtc_state);
+
+       crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
 
        return 0;
 }
@@ -1664,6 +1711,8 @@ static int icl_color_check(struct intel_crtc_state *crtc_state)
 
        crtc_state->csc_mode = icl_csc_mode(crtc_state);
 
+       intel_assign_luts(crtc_state);
+
        crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
 
        return 0;
@@ -1869,7 +1918,7 @@ static void i9xx_read_luts(struct intel_crtc_state *crtc_state)
        if (!crtc_state->gamma_enable)
                return;
 
-       crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc);
+       crtc_state->post_csc_lut = i9xx_read_lut_8(crtc);
 }
 
 static struct drm_property_blob *i965_read_lut_10p6(struct intel_crtc *crtc)
@@ -1910,9 +1959,9 @@ static void i965_read_luts(struct intel_crtc_state *crtc_state)
                return;
 
        if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
-               crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc);
+               crtc_state->post_csc_lut = i9xx_read_lut_8(crtc);
        else
-               crtc_state->hw.gamma_lut = i965_read_lut_10p6(crtc);
+               crtc_state->post_csc_lut = i965_read_lut_10p6(crtc);
 }
 
 static struct drm_property_blob *chv_read_cgm_gamma(struct intel_crtc *crtc)
@@ -1946,7 +1995,7 @@ static void chv_read_luts(struct intel_crtc_state *crtc_state)
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
        if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
-               crtc_state->hw.gamma_lut = chv_read_cgm_gamma(crtc);
+               crtc_state->post_csc_lut = chv_read_cgm_gamma(crtc);
        else
                i965_read_luts(crtc_state);
 }
@@ -2013,10 +2062,10 @@ static void ilk_read_luts(struct intel_crtc_state *crtc_state)
 
        switch (crtc_state->gamma_mode) {
        case GAMMA_MODE_MODE_8BIT:
-               crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
+               crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
                break;
        case GAMMA_MODE_MODE_10BIT:
-               crtc_state->hw.gamma_lut = ilk_read_lut_10(crtc);
+               crtc_state->post_csc_lut = ilk_read_lut_10(crtc);
                break;
        default:
                MISSING_CASE(crtc_state->gamma_mode);
@@ -2068,10 +2117,10 @@ static void glk_read_luts(struct intel_crtc_state *crtc_state)
 
        switch (crtc_state->gamma_mode) {
        case GAMMA_MODE_MODE_8BIT:
-               crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
+               crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
                break;
        case GAMMA_MODE_MODE_10BIT:
-               crtc_state->hw.gamma_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
+               crtc_state->post_csc_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
                break;
        default:
                MISSING_CASE(crtc_state->gamma_mode);
@@ -2126,13 +2175,13 @@ static void icl_read_luts(struct intel_crtc_state *crtc_state)
 
        switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
        case GAMMA_MODE_MODE_8BIT:
-               crtc_state->hw.gamma_lut = ilk_read_lut_8(crtc);
+               crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
                break;
        case GAMMA_MODE_MODE_10BIT:
-               crtc_state->hw.gamma_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
+               crtc_state->post_csc_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
                break;
        case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
-               crtc_state->hw.gamma_lut = icl_read_lut_multi_segment(crtc);
+               crtc_state->post_csc_lut = icl_read_lut_multi_segment(crtc);
                break;
        default:
                MISSING_CASE(crtc_state->gamma_mode);
@@ -2217,41 +2266,58 @@ static const struct intel_color_funcs ilk_color_funcs = {
        .read_luts = ilk_read_luts,
 };
 
-void intel_color_init(struct intel_crtc *crtc)
+void intel_color_crtc_init(struct intel_crtc *crtc)
 {
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        bool has_ctm = INTEL_INFO(dev_priv)->display.color.degamma_lut_size != 0;
 
        drm_mode_crtc_set_gamma_size(&crtc->base, 256);
 
-       if (HAS_GMCH(dev_priv)) {
-               if (IS_CHERRYVIEW(dev_priv)) {
-                       dev_priv->display.funcs.color = &chv_color_funcs;
-               } else if (DISPLAY_VER(dev_priv) >= 4) {
-                       dev_priv->display.funcs.color = &i965_color_funcs;
-               } else {
-                       dev_priv->display.funcs.color = &i9xx_color_funcs;
-               }
-       } else {
-               if (DISPLAY_VER(dev_priv) >= 11)
-                       dev_priv->display.funcs.color = &icl_color_funcs;
-               else if (DISPLAY_VER(dev_priv) == 10)
-                       dev_priv->display.funcs.color = &glk_color_funcs;
-               else if (DISPLAY_VER(dev_priv) == 9)
-                       dev_priv->display.funcs.color = &skl_color_funcs;
-               else if (DISPLAY_VER(dev_priv) == 8)
-                       dev_priv->display.funcs.color = &bdw_color_funcs;
-               else if (DISPLAY_VER(dev_priv) == 7) {
-                       if (IS_HASWELL(dev_priv))
-                               dev_priv->display.funcs.color = &hsw_color_funcs;
-                       else
-                               dev_priv->display.funcs.color = &ivb_color_funcs;
-               } else
-                       dev_priv->display.funcs.color = &ilk_color_funcs;
-       }
-
        drm_crtc_enable_color_mgmt(&crtc->base,
                                   INTEL_INFO(dev_priv)->display.color.degamma_lut_size,
                                   has_ctm,
                                   INTEL_INFO(dev_priv)->display.color.gamma_lut_size);
 }
+
+int intel_color_init(struct drm_i915_private *i915)
+{
+       struct drm_property_blob *blob;
+
+       if (DISPLAY_VER(i915) != 10)
+               return 0;
+
+       blob = create_linear_lut(i915, INTEL_INFO(i915)->display.color.degamma_lut_size);
+       if (IS_ERR(blob))
+               return PTR_ERR(blob);
+
+       i915->display.color.glk_linear_degamma_lut = blob;
+
+       return 0;
+}
+
+void intel_color_init_hooks(struct drm_i915_private *i915)
+{
+       if (HAS_GMCH(i915)) {
+               if (IS_CHERRYVIEW(i915))
+                       i915->display.funcs.color = &chv_color_funcs;
+               else if (DISPLAY_VER(i915) >= 4)
+                       i915->display.funcs.color = &i965_color_funcs;
+               else
+                       i915->display.funcs.color = &i9xx_color_funcs;
+       } else {
+               if (DISPLAY_VER(i915) >= 11)
+                       i915->display.funcs.color = &icl_color_funcs;
+               else if (DISPLAY_VER(i915) == 10)
+                       i915->display.funcs.color = &glk_color_funcs;
+               else if (DISPLAY_VER(i915) == 9)
+                       i915->display.funcs.color = &skl_color_funcs;
+               else if (DISPLAY_VER(i915) == 8)
+                       i915->display.funcs.color = &bdw_color_funcs;
+               else if (IS_HASWELL(i915))
+                       i915->display.funcs.color = &hsw_color_funcs;
+               else if (DISPLAY_VER(i915) == 7)
+                       i915->display.funcs.color = &ivb_color_funcs;
+               else
+                       i915->display.funcs.color = &ilk_color_funcs;
+       }
+}
index fd87342..2a5ada6 100644 (file)
 
 struct intel_crtc_state;
 struct intel_crtc;
+struct drm_i915_private;
 struct drm_property_blob;
 
-void intel_color_init(struct intel_crtc *crtc);
+void intel_color_init_hooks(struct drm_i915_private *i915);
+int intel_color_init(struct drm_i915_private *i915);
+void intel_color_crtc_init(struct intel_crtc *crtc);
 int intel_color_check(struct intel_crtc_state *crtc_state);
 void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state);
 void intel_color_commit_arm(const struct intel_crtc_state *crtc_state);
@@ -22,5 +25,6 @@ int intel_color_get_gamma_bit_precision(const struct intel_crtc_state *crtc_stat
 bool intel_color_lut_equal(struct drm_property_blob *blob1,
                           struct drm_property_blob *blob2,
                           u32 gamma_mode, u32 bit_precision);
+void intel_color_assert_luts(const struct intel_crtc_state *crtc_state);
 
 #endif /* __INTEL_COLOR_H__ */
index 64890f3..71d7aec 100644 (file)
@@ -53,7 +53,6 @@ static const struct icl_procmon {
 static const struct icl_procmon *
 icl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum phy phy)
 {
-       const struct icl_procmon *procmon;
        u32 val;
 
        val = intel_de_read(dev_priv, ICL_PORT_COMP_DW3(phy));
@@ -62,23 +61,16 @@ icl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum phy phy)
                MISSING_CASE(val);
                fallthrough;
        case VOLTAGE_INFO_0_85V | PROCESS_INFO_DOT_0:
-               procmon = &icl_procmon_values[PROCMON_0_85V_DOT_0];
-               break;
+               return &icl_procmon_values[PROCMON_0_85V_DOT_0];
        case VOLTAGE_INFO_0_95V | PROCESS_INFO_DOT_0:
-               procmon = &icl_procmon_values[PROCMON_0_95V_DOT_0];
-               break;
+               return &icl_procmon_values[PROCMON_0_95V_DOT_0];
        case VOLTAGE_INFO_0_95V | PROCESS_INFO_DOT_1:
-               procmon = &icl_procmon_values[PROCMON_0_95V_DOT_1];
-               break;
+               return &icl_procmon_values[PROCMON_0_95V_DOT_1];
        case VOLTAGE_INFO_1_05V | PROCESS_INFO_DOT_0:
-               procmon = &icl_procmon_values[PROCMON_1_05V_DOT_0];
-               break;
+               return &icl_procmon_values[PROCMON_1_05V_DOT_0];
        case VOLTAGE_INFO_1_05V | PROCESS_INFO_DOT_1:
-               procmon = &icl_procmon_values[PROCMON_1_05V_DOT_1];
-               break;
+               return &icl_procmon_values[PROCMON_1_05V_DOT_1];
        }
-
-       return procmon;
 }
 
 static void icl_set_procmon_ref_values(struct drm_i915_private *dev_priv,
index 6d5cbeb..6205ddd 100644 (file)
@@ -293,3 +293,21 @@ intel_attach_dp_colorspace_property(struct drm_connector *connector)
        if (!drm_mode_create_dp_colorspace_property(connector))
                drm_connector_attach_colorspace_property(connector);
 }
+
+void
+intel_attach_scaling_mode_property(struct drm_connector *connector)
+{
+       struct drm_i915_private *i915 = to_i915(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)
+               scaling_modes |= BIT(DRM_MODE_SCALE_CENTER);
+
+       drm_connector_attach_scaling_mode_property(connector, scaling_modes);
+
+       connector->state->scaling_mode = DRM_MODE_SCALE_ASPECT;
+}
index 661a37a..7d7b588 100644 (file)
@@ -32,5 +32,6 @@ void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
 void intel_attach_aspect_ratio_property(struct drm_connector *connector);
 void intel_attach_hdmi_colorspace_property(struct drm_connector *connector);
 void intel_attach_dp_colorspace_property(struct drm_connector *connector);
+void intel_attach_scaling_mode_property(struct drm_connector *connector);
 
 #endif /* __INTEL_CONNECTOR_H__ */
index 4a8ff2f..94d0a5e 100644 (file)
@@ -1044,17 +1044,14 @@ void intel_crt_init(struct drm_i915_private *dev_priv)
        intel_connector_attach_encoder(intel_connector, &crt->base);
 
        crt->base.type = INTEL_OUTPUT_ANALOG;
-       crt->base.cloneable = (1 << INTEL_OUTPUT_DVO) | (1 << INTEL_OUTPUT_HDMI);
+       crt->base.cloneable = BIT(INTEL_OUTPUT_DVO) | BIT(INTEL_OUTPUT_HDMI);
        if (IS_I830(dev_priv))
                crt->base.pipe_mask = BIT(PIPE_A);
        else
                crt->base.pipe_mask = ~0;
 
-       if (DISPLAY_VER(dev_priv) == 2)
-               connector->interlace_allowed = 0;
-       else
-               connector->interlace_allowed = 1;
-       connector->doublescan_allowed = 0;
+       if (DISPLAY_VER(dev_priv) != 2)
+               connector->interlace_allowed = true;
 
        crt->adpa_reg = adpa_reg;
 
index 6792a90..037fc14 100644 (file)
@@ -365,9 +365,8 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
                                                BIT(DRM_SCALING_FILTER_DEFAULT) |
                                                BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR));
 
-       intel_color_init(crtc);
-
-       intel_crtc_drrs_init(crtc);
+       intel_color_crtc_init(crtc);
+       intel_drrs_crtc_init(crtc);
        intel_crtc_crc_init(crtc);
 
        cpu_latency_qos_add_request(&crtc->vblank_pm_qos, PM_QOS_DEFAULT_VALUE);
@@ -387,8 +386,7 @@ static bool intel_crtc_needs_vblank_work(const struct intel_crtc_state *crtc_sta
        return crtc_state->hw.active &&
                !intel_crtc_needs_modeset(crtc_state) &&
                !crtc_state->preload_luts &&
-               (crtc_state->uapi.color_mgmt_changed ||
-                crtc_state->update_pipe);
+               intel_crtc_needs_color_update(crtc_state);
 }
 
 static void intel_crtc_vblank_work(struct kthread_work *base)
index e9212f6..e3273fe 100644 (file)
@@ -298,11 +298,13 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config,
                            pipe_config->csc_mode, pipe_config->gamma_mode,
                            pipe_config->gamma_enable, pipe_config->csc_enable);
 
-       drm_dbg_kms(&i915->drm, "degamma lut: %d entries, gamma lut: %d entries\n",
-                   pipe_config->hw.degamma_lut ?
-                   drm_color_lut_size(pipe_config->hw.degamma_lut) : 0,
-                   pipe_config->hw.gamma_lut ?
-                   drm_color_lut_size(pipe_config->hw.gamma_lut) : 0);
+       drm_dbg_kms(&i915->drm, "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) " : "",
+                   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);
 
 dump_planes:
        if (!state)
index 87899e8..96422c9 100644 (file)
@@ -631,8 +631,10 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
         *
         * FIXME bigjoiner fastpath would be good
         */
-       if (!crtc_state->hw.active || intel_crtc_needs_modeset(crtc_state) ||
-           crtc_state->update_pipe || crtc_state->bigjoiner_pipes)
+       if (!crtc_state->hw.active ||
+           intel_crtc_needs_modeset(crtc_state) ||
+           intel_crtc_needs_fastset(crtc_state) ||
+           crtc_state->bigjoiner_pipes)
                goto slow;
 
        /*
index da8472c..e95bde5 100644 (file)
@@ -43,6 +43,8 @@
 #include "intel_de.h"
 #include "intel_display_power.h"
 #include "intel_display_types.h"
+#include "intel_dkl_phy.h"
+#include "intel_dkl_phy_regs.h"
 #include "intel_dp.h"
 #include "intel_dp_link_training.h"
 #include "intel_dp_mst.h"
 #include "intel_hdmi.h"
 #include "intel_hotplug.h"
 #include "intel_lspcon.h"
+#include "intel_mg_phy_regs.h"
 #include "intel_pps.h"
 #include "intel_psr.h"
 #include "intel_quirks.h"
 #include "intel_snps_phy.h"
 #include "intel_sprite.h"
 #include "intel_tc.h"
-#include "intel_tc_phy_regs.h"
 #include "intel_vdsc.h"
 #include "intel_vrr.h"
 #include "skl_scaler.h"
@@ -1262,33 +1264,30 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder,
        for (ln = 0; ln < 2; ln++) {
                int level;
 
-               intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
-                              HIP_INDEX_VAL(tc_port, ln));
-
-               intel_de_write(dev_priv, DKL_TX_PMD_LANE_SUS(tc_port), 0);
+               intel_dkl_phy_write(dev_priv, DKL_TX_PMD_LANE_SUS(tc_port, ln), 0);
 
                level = intel_ddi_level(encoder, crtc_state, 2*ln+0);
 
-               intel_de_rmw(dev_priv, DKL_TX_DPCNTL0(tc_port),
-                            DKL_TX_PRESHOOT_COEFF_MASK |
-                            DKL_TX_DE_EMPAHSIS_COEFF_MASK |
-                            DKL_TX_VSWING_CONTROL_MASK,
-                            DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot) |
-                            DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) |
-                            DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing));
+               intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL0(tc_port, ln),
+                                 DKL_TX_PRESHOOT_COEFF_MASK |
+                                 DKL_TX_DE_EMPAHSIS_COEFF_MASK |
+                                 DKL_TX_VSWING_CONTROL_MASK,
+                                 DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot) |
+                                 DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) |
+                                 DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing));
 
                level = intel_ddi_level(encoder, crtc_state, 2*ln+1);
 
-               intel_de_rmw(dev_priv, DKL_TX_DPCNTL1(tc_port),
-                            DKL_TX_PRESHOOT_COEFF_MASK |
-                            DKL_TX_DE_EMPAHSIS_COEFF_MASK |
-                            DKL_TX_VSWING_CONTROL_MASK,
-                            DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot) |
-                            DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) |
-                            DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing));
+               intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL1(tc_port, ln),
+                                 DKL_TX_PRESHOOT_COEFF_MASK |
+                                 DKL_TX_DE_EMPAHSIS_COEFF_MASK |
+                                 DKL_TX_VSWING_CONTROL_MASK,
+                                 DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot) |
+                                 DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) |
+                                 DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing));
 
-               intel_de_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port),
-                            DKL_TX_DP20BITMODE, 0);
+               intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port, ln),
+                                 DKL_TX_DP20BITMODE, 0);
 
                if (IS_ALDERLAKE_P(dev_priv)) {
                        u32 val;
@@ -1306,10 +1305,10 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder,
                                val |= DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2(0);
                        }
 
-                       intel_de_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port),
-                                    DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK |
-                                    DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK,
-                                    val);
+                       intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port, ln),
+                                         DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK |
+                                         DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK,
+                                         val);
                }
        }
 }
@@ -2019,12 +2018,8 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port,
                return;
 
        if (DISPLAY_VER(dev_priv) >= 12) {
-               intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
-                              HIP_INDEX_VAL(tc_port, 0x0));
-               ln0 = intel_de_read(dev_priv, DKL_DP_MODE(tc_port));
-               intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
-                              HIP_INDEX_VAL(tc_port, 0x1));
-               ln1 = intel_de_read(dev_priv, DKL_DP_MODE(tc_port));
+               ln0 = intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port, 0));
+               ln1 = intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port, 1));
        } else {
                ln0 = intel_de_read(dev_priv, MG_DP_MODE(0, tc_port));
                ln1 = intel_de_read(dev_priv, MG_DP_MODE(1, tc_port));
@@ -2085,12 +2080,8 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port,
        }
 
        if (DISPLAY_VER(dev_priv) >= 12) {
-               intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
-                              HIP_INDEX_VAL(tc_port, 0x0));
-               intel_de_write(dev_priv, DKL_DP_MODE(tc_port), ln0);
-               intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
-                              HIP_INDEX_VAL(tc_port, 0x1));
-               intel_de_write(dev_priv, DKL_DP_MODE(tc_port), ln1);
+               intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 0), ln0);
+               intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port, 1), ln1);
        } else {
                intel_de_write(dev_priv, MG_DP_MODE(0, tc_port), ln0);
                intel_de_write(dev_priv, MG_DP_MODE(1, tc_port), ln1);
@@ -3094,10 +3085,8 @@ static void adlp_tbt_to_dp_alt_switch_wa(struct intel_encoder *encoder)
        enum tc_port tc_port = intel_port_to_tc(i915, encoder->port);
        int ln;
 
-       for (ln = 0; ln < 2; ln++) {
-               intel_de_write(i915, HIP_INDEX_REG(tc_port), HIP_INDEX_VAL(tc_port, ln));
-               intel_de_rmw(i915, DKL_PCS_DW5(tc_port), DKL_PCS_DW5_CORE_SOFTRESET, 0);
-       }
+       for (ln = 0; ln < 2; ln++)
+               intel_dkl_phy_rmw(i915, DKL_PCS_DW5(tc_port, ln), DKL_PCS_DW5_CORE_SOFTRESET, 0);
 }
 
 static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp,
@@ -3536,7 +3525,7 @@ static void icl_ddi_tc_get_clock(struct intel_encoder *encoder,
        if (drm_WARN_ON(&i915->drm, !pll))
                return;
 
-       if (intel_get_shared_dpll_id(i915, pll) == DPLL_ID_ICL_TBTPLL)
+       if (pll->info->id == DPLL_ID_ICL_TBTPLL)
                port_dpll_id = ICL_PORT_DPLL_DEFAULT;
        else
                port_dpll_id = ICL_PORT_DPLL_MG_PHY;
@@ -3549,7 +3538,7 @@ static void icl_ddi_tc_get_clock(struct intel_encoder *encoder,
 
        icl_set_active_port_dpll(crtc_state, port_dpll_id);
 
-       if (intel_get_shared_dpll_id(i915, crtc_state->shared_dpll) == DPLL_ID_ICL_TBTPLL)
+       if (crtc_state->shared_dpll->info->id == DPLL_ID_ICL_TBTPLL)
                crtc_state->port_clock = icl_calc_tbt_pll_link(i915, encoder->port);
        else
                crtc_state->port_clock = intel_dpll_get_freq(i915, crtc_state->shared_dpll,
@@ -3591,7 +3580,7 @@ static void intel_ddi_sync_state(struct intel_encoder *encoder,
        enum phy phy = intel_port_to_phy(i915, encoder->port);
 
        if (intel_phy_is_tc(i915, phy))
-               intel_tc_port_sanitize(enc_to_dig_port(encoder));
+               intel_tc_port_sanitize_mode(enc_to_dig_port(encoder));
 
        if (crtc_state && intel_crtc_has_dp_encoder(crtc_state))
                intel_dp_sync_state(encoder, crtc_state);
@@ -3801,11 +3790,17 @@ static void intel_ddi_encoder_destroy(struct drm_encoder *encoder)
 
 static void intel_ddi_encoder_reset(struct drm_encoder *encoder)
 {
+       struct drm_i915_private *i915 = to_i915(encoder->dev);
        struct intel_dp *intel_dp = enc_to_intel_dp(to_intel_encoder(encoder));
+       struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder));
+       enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
 
        intel_dp->reset_link_params = true;
 
        intel_pps_encoder_reset(intel_dp);
+
+       if (intel_phy_is_tc(i915, phy))
+               intel_tc_port_init_mode(dig_port);
 }
 
 static const struct drm_encoder_funcs intel_ddi_funcs = {
index 461c62c..b9393f9 100644 (file)
@@ -831,13 +831,27 @@ intel_plane_fence_y_offset(const struct intel_plane_state *plane_state)
 }
 
 static int
+intel_display_commit_duplicated_state(struct intel_atomic_state *state,
+                                     struct drm_modeset_acquire_ctx *ctx)
+{
+       struct drm_i915_private *i915 = to_i915(state->base.dev);
+       int ret;
+
+       ret = drm_atomic_helper_commit_duplicated_state(&state->base, ctx);
+
+       drm_WARN_ON(&i915->drm, ret == -EDEADLK);
+
+       return ret;
+}
+
+static int
 __intel_display_resume(struct drm_i915_private *i915,
                       struct drm_atomic_state *state,
                       struct drm_modeset_acquire_ctx *ctx)
 {
        struct drm_crtc_state *crtc_state;
        struct drm_crtc *crtc;
-       int i, ret;
+       int i;
 
        intel_modeset_setup_hw_state(i915, ctx);
        intel_vga_redisable(i915);
@@ -863,11 +877,7 @@ __intel_display_resume(struct drm_i915_private *i915,
        if (!HAS_GMCH(i915))
                to_intel_atomic_state(state)->skip_intermediate_wm = true;
 
-       ret = drm_atomic_helper_commit_duplicated_state(state, ctx);
-
-       drm_WARN_ON(&i915->drm, ret == -EDEADLK);
-
-       return ret;
+       return intel_display_commit_duplicated_state(to_intel_atomic_state(state), ctx);
 }
 
 static bool gpu_reset_clobbers_display(struct drm_i915_private *dev_priv)
@@ -878,7 +888,6 @@ static bool gpu_reset_clobbers_display(struct drm_i915_private *dev_priv)
 
 void intel_display_prepare_reset(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = &dev_priv->drm;
        struct drm_modeset_acquire_ctx *ctx = &dev_priv->reset_ctx;
        struct drm_atomic_state *state;
        int ret;
@@ -906,10 +915,10 @@ void intel_display_prepare_reset(struct drm_i915_private *dev_priv)
         * Need mode_config.mutex so that we don't
         * trample ongoing ->detect() and whatnot.
         */
-       mutex_lock(&dev->mode_config.mutex);
+       mutex_lock(&dev_priv->drm.mode_config.mutex);
        drm_modeset_acquire_init(ctx, 0);
        while (1) {
-               ret = drm_modeset_lock_all_ctx(dev, ctx);
+               ret = drm_modeset_lock_all_ctx(&dev_priv->drm, ctx);
                if (ret != -EDEADLK)
                        break;
 
@@ -919,7 +928,7 @@ void intel_display_prepare_reset(struct drm_i915_private *dev_priv)
         * Disabling the crtcs gracefully seems nicer. Also the
         * g33 docs say we should at least disable all the planes.
         */
-       state = drm_atomic_helper_duplicate_state(dev, ctx);
+       state = drm_atomic_helper_duplicate_state(&dev_priv->drm, ctx);
        if (IS_ERR(state)) {
                ret = PTR_ERR(state);
                drm_err(&dev_priv->drm, "Duplicating state failed with %i\n",
@@ -927,7 +936,7 @@ void intel_display_prepare_reset(struct drm_i915_private *dev_priv)
                return;
        }
 
-       ret = drm_atomic_helper_disable_all(dev, ctx);
+       ret = drm_atomic_helper_disable_all(&dev_priv->drm, ctx);
        if (ret) {
                drm_err(&dev_priv->drm, "Suspending crtc's failed with %i\n",
                        ret);
@@ -959,7 +968,7 @@ void intel_display_finish_reset(struct drm_i915_private *i915)
        /* reset doesn't touch the display */
        if (!gpu_reset_clobbers_display(i915)) {
                /* for testing only restore the display */
-               ret = __intel_display_resume(i915, state, ctx);
+               ret = intel_display_commit_duplicated_state(to_intel_atomic_state(state), ctx);
                if (ret)
                        drm_err(&i915->drm,
                                "Restoring old state failed with %i\n", ret);
@@ -1252,8 +1261,6 @@ static void intel_post_plane_update(struct intel_atomic_state *state,
        if (needs_cursorclk_wa(old_crtc_state) &&
            !needs_cursorclk_wa(new_crtc_state))
                icl_wa_cursorclkgating(dev_priv, pipe, false);
-
-       intel_drrs_activate(new_crtc_state);
 }
 
 static void intel_crtc_enable_flip_done(struct intel_atomic_state *state,
@@ -4572,8 +4579,8 @@ static bool encoders_cloneable(const struct intel_encoder *a,
                               const struct intel_encoder *b)
 {
        /* masks could be asymmetric, so check both ways */
-       return a == b || (a->cloneable & (1 << b->type) &&
-                         b->cloneable & (1 << a->type));
+       return a == b || (a->cloneable & BIT(b->type) &&
+                         b->cloneable & BIT(a->type));
 }
 
 static bool check_single_encoder_cloning(struct intel_atomic_state *state,
@@ -4824,14 +4831,14 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        struct intel_crtc_state *crtc_state =
                intel_atomic_get_new_crtc_state(state, crtc);
-       bool mode_changed = intel_crtc_needs_modeset(crtc_state);
        int ret;
 
        if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv) &&
-           mode_changed && !crtc_state->hw.active)
+           intel_crtc_needs_modeset(crtc_state) &&
+           !crtc_state->hw.active)
                crtc_state->update_wm_post = true;
 
-       if (mode_changed) {
+       if (intel_crtc_needs_modeset(crtc_state)) {
                ret = intel_dpll_crtc_get_shared_dpll(state, crtc);
                if (ret)
                        return ret;
@@ -4844,8 +4851,7 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
        if (c8_planes_changed(crtc_state))
                crtc_state->uapi.color_mgmt_changed = true;
 
-       if (mode_changed || crtc_state->update_pipe ||
-           crtc_state->uapi.color_mgmt_changed) {
+       if (intel_crtc_needs_color_update(crtc_state)) {
                ret = intel_color_check(crtc_state);
                if (ret)
                        return ret;
@@ -4871,7 +4877,8 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
        }
 
        if (DISPLAY_VER(dev_priv) >= 9) {
-               if (mode_changed || crtc_state->update_pipe) {
+               if (intel_crtc_needs_modeset(crtc_state) ||
+                   intel_crtc_needs_fastset(crtc_state)) {
                        ret = skl_update_scaler_crtc(crtc_state);
                        if (ret)
                                return ret;
@@ -5637,39 +5644,6 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
        PIPE_CONF_CHECK_I(name.y2); \
 } while (0)
 
-/* This is required for BDW+ where there is only one set of registers for
- * switching between high and low RR.
- * This macro can be used whenever a comparison has to be made between one
- * hw state and multiple sw state variables.
- */
-#define PIPE_CONF_CHECK_M_N_ALT(name, alt_name) do { \
-       if (!intel_compare_link_m_n(&current_config->name, \
-                                   &pipe_config->name) && \
-           !intel_compare_link_m_n(&current_config->alt_name, \
-                                   &pipe_config->name)) { \
-               pipe_config_mismatch(fastset, crtc, __stringify(name), \
-                                    "(expected tu %i data %i/%i link %i/%i, " \
-                                    "or tu %i data %i/%i link %i/%i, " \
-                                    "found tu %i, data %i/%i link %i/%i)", \
-                                    current_config->name.tu, \
-                                    current_config->name.data_m, \
-                                    current_config->name.data_n, \
-                                    current_config->name.link_m, \
-                                    current_config->name.link_n, \
-                                    current_config->alt_name.tu, \
-                                    current_config->alt_name.data_m, \
-                                    current_config->alt_name.data_n, \
-                                    current_config->alt_name.link_m, \
-                                    current_config->alt_name.link_n, \
-                                    pipe_config->name.tu, \
-                                    pipe_config->name.data_m, \
-                                    pipe_config->name.data_n, \
-                                    pipe_config->name.link_m, \
-                                    pipe_config->name.link_n); \
-               ret = false; \
-       } \
-} while (0)
-
 #define PIPE_CONF_CHECK_FLAGS(name, mask) do { \
        if ((current_config->name ^ pipe_config->name) & (mask)) { \
                pipe_config_mismatch(fastset, crtc, __stringify(name), \
@@ -5738,7 +5712,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 
        if (HAS_DOUBLE_BUFFERED_M_N(dev_priv)) {
                if (!fastset || !pipe_config->seamless_m_n)
-                       PIPE_CONF_CHECK_M_N_ALT(dp_m_n, dp_m2_n2);
+                       PIPE_CONF_CHECK_M_N(dp_m_n);
        } else {
                PIPE_CONF_CHECK_M_N(dp_m_n);
                PIPE_CONF_CHECK_M_N(dp_m2_n2);
@@ -5815,7 +5789,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 
                bp_gamma = intel_color_get_gamma_bit_precision(pipe_config);
                if (bp_gamma)
-                       PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, hw.gamma_lut, bp_gamma);
+                       PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, post_csc_lut, bp_gamma);
 
                if (current_config->active_planes) {
                        PIPE_CONF_CHECK_BOOL(has_psr);
@@ -5937,7 +5911,8 @@ intel_verify_planes(struct intel_atomic_state *state)
                             plane_state->uapi.visible);
 }
 
-int intel_modeset_all_pipes(struct intel_atomic_state *state)
+int intel_modeset_all_pipes(struct intel_atomic_state *state,
+                           const char *reason)
 {
        struct drm_i915_private *dev_priv = to_i915(state->base.dev);
        struct intel_crtc *crtc;
@@ -5958,7 +5933,11 @@ int intel_modeset_all_pipes(struct intel_atomic_state *state)
                    drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
                        continue;
 
+               drm_dbg_kms(&dev_priv->drm, "[CRTC:%d:%s] Full modeset due to %s\n",
+                           crtc->base.base.id, crtc->base.name, reason);
+
                crtc_state->uapi.mode_changed = true;
+               crtc_state->update_pipe = false;
 
                ret = drm_atomic_add_affected_connectors(&state->base,
                                                         &crtc->base);
@@ -6134,7 +6113,8 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta
                return;
 
        new_crtc_state->uapi.mode_changed = false;
-       new_crtc_state->update_pipe = true;
+       if (!intel_crtc_needs_modeset(new_crtc_state))
+               new_crtc_state->update_pipe = true;
 }
 
 static int intel_crtc_add_planes_to_state(struct intel_atomic_state *state,
@@ -6906,12 +6886,19 @@ static int intel_atomic_check(struct drm_device *dev,
 
        for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
                                            new_crtc_state, i) {
+               intel_color_assert_luts(new_crtc_state);
+
                ret = intel_async_flip_check_hw(state, crtc);
                if (ret)
                        goto fail;
 
+               /* Either full modeset or fastset (or neither), never both */
+               drm_WARN_ON(&dev_priv->drm,
+                           intel_crtc_needs_modeset(new_crtc_state) &&
+                           intel_crtc_needs_fastset(new_crtc_state));
+
                if (!intel_crtc_needs_modeset(new_crtc_state) &&
-                   !new_crtc_state->update_pipe)
+                   !intel_crtc_needs_fastset(new_crtc_state))
                        continue;
 
                intel_crtc_state_dump(new_crtc_state, state,
@@ -6947,12 +6934,8 @@ static int intel_atomic_prepare_commit(struct intel_atomic_state *state)
                return ret;
 
        for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
-               bool mode_changed = intel_crtc_needs_modeset(crtc_state);
-
-               if (mode_changed || crtc_state->update_pipe ||
-                   crtc_state->uapi.color_mgmt_changed) {
+               if (intel_crtc_needs_color_update(crtc_state))
                        intel_dsb_prepare(crtc_state);
-               }
        }
 
        return 0;
@@ -7033,14 +7016,13 @@ static void commit_pipe_pre_planes(struct intel_atomic_state *state,
         * CRTC was enabled.
         */
        if (!modeset) {
-               if (new_crtc_state->uapi.color_mgmt_changed ||
-                   new_crtc_state->update_pipe)
+               if (intel_crtc_needs_color_update(new_crtc_state))
                        intel_color_commit_arm(new_crtc_state);
 
                if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
                        bdw_set_pipemisc(new_crtc_state);
 
-               if (new_crtc_state->update_pipe)
+               if (intel_crtc_needs_fastset(new_crtc_state))
                        intel_pipe_fastset(old_crtc_state, new_crtc_state);
        }
 
@@ -7099,25 +7081,23 @@ static void intel_update_crtc(struct intel_atomic_state *state,
 
        if (!modeset) {
                if (new_crtc_state->preload_luts &&
-                   (new_crtc_state->uapi.color_mgmt_changed ||
-                    new_crtc_state->update_pipe))
+                   intel_crtc_needs_color_update(new_crtc_state))
                        intel_color_load_luts(new_crtc_state);
 
                intel_pre_plane_update(state, crtc);
 
-               if (new_crtc_state->update_pipe)
+               if (intel_crtc_needs_fastset(new_crtc_state))
                        intel_encoders_update_pipe(state, crtc);
 
                if (DISPLAY_VER(i915) >= 11 &&
-                   new_crtc_state->update_pipe)
+                   intel_crtc_needs_fastset(new_crtc_state))
                        icl_set_pipe_chicken(new_crtc_state);
        }
 
        intel_fbc_update(state, crtc);
 
        if (!modeset &&
-           (new_crtc_state->uapi.color_mgmt_changed ||
-            new_crtc_state->update_pipe))
+           intel_crtc_needs_color_update(new_crtc_state))
                intel_color_commit_noarm(new_crtc_state);
 
        intel_crtc_planes_update_noarm(state, crtc);
@@ -7139,7 +7119,7 @@ static void intel_update_crtc(struct intel_atomic_state *state,
         * valid pipe configuration from the BIOS we need to take care
         * of enabling them on the CRTC's first fastset.
         */
-       if (new_crtc_state->update_pipe && !modeset &&
+       if (intel_crtc_needs_fastset(new_crtc_state) && !modeset &&
            old_crtc_state->inherited)
                intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
 }
@@ -7162,9 +7142,7 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
        intel_fbc_disable(crtc);
        intel_disable_shared_dpll(old_crtc_state);
 
-       /* FIXME unify this for all platforms */
-       if (!new_crtc_state->hw.active &&
-           !HAS_GMCH(dev_priv))
+       if (!new_crtc_state->hw.active)
                intel_initial_watermarks(state, crtc);
 }
 
@@ -7499,9 +7477,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
        for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
                                            new_crtc_state, i) {
                if (intel_crtc_needs_modeset(new_crtc_state) ||
-                   new_crtc_state->update_pipe) {
+                   intel_crtc_needs_fastset(new_crtc_state))
                        intel_modeset_get_crtc_power_domains(new_crtc_state, &put_domains[crtc->pipe]);
-               }
        }
 
        intel_commit_modeset_disables(state);
@@ -7605,6 +7582,12 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
                intel_modeset_verify_crtc(crtc, state, old_crtc_state, new_crtc_state);
 
                /*
+                * Activate DRRS after state readout to avoid
+                * dp_m_n vs. dp_m2_n2 confusion on BDW+.
+                */
+               intel_drrs_activate(new_crtc_state);
+
+               /*
                 * DSB cleanup is done in cleanup_work aligning with framebuffer
                 * cleanup. So copy and reset the dsb structure to sync with
                 * commit_done and later do dsb cleanup in cleanup_work.
@@ -8344,6 +8327,7 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv)
        if (!HAS_DISPLAY(dev_priv))
                return;
 
+       intel_color_init_hooks(dev_priv);
        intel_init_cdclk_hooks(dev_priv);
        intel_audio_hooks_init(dev_priv);
 
@@ -8674,6 +8658,10 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915)
        if (ret)
                goto cleanup_vga_client_pw_domain_dmc;
 
+       ret = intel_color_init(i915);
+       if (ret)
+               goto cleanup_vga_client_pw_domain_dmc;
+
        ret = intel_dbuf_init(i915);
        if (ret)
                goto cleanup_vga_client_pw_domain_dmc;
index 884e8e6..c803330 100644 (file)
@@ -469,10 +469,6 @@ enum hpd_pin {
        list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \
                for_each_if((intel_encoder)->base.crtc == (__crtc))
 
-#define for_each_connector_on_encoder(dev, __encoder, intel_connector) \
-       list_for_each_entry((intel_connector), &(dev)->mode_config.connector_list, base.head) \
-               for_each_if((intel_connector)->base.encoder == (__encoder))
-
 #define for_each_old_intel_plane_in_state(__state, plane, old_plane_state, __i) \
        for ((__i) = 0; \
             (__i) < (__state)->base.dev->mode_config.num_total_plane && \
@@ -683,7 +679,8 @@ void intel_modeset_driver_remove(struct drm_i915_private *i915);
 void intel_modeset_driver_remove_noirq(struct drm_i915_private *i915);
 void intel_modeset_driver_remove_nogem(struct drm_i915_private *i915);
 void intel_display_resume(struct drm_device *dev);
-int intel_modeset_all_pipes(struct intel_atomic_state *state);
+int intel_modeset_all_pipes(struct intel_atomic_state *state,
+                           const char *reason);
 void intel_modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state,
                                          struct intel_power_domain_mask *old_domains);
 void intel_modeset_put_crtc_power_domains(struct intel_crtc *crtc,
index 96cf994..337d8e0 100644 (file)
@@ -28,6 +28,7 @@
 
 struct drm_i915_private;
 struct drm_property;
+struct drm_property_blob;
 struct i915_audio_component;
 struct i915_hdcp_comp_master;
 struct intel_atomic_state;
@@ -309,6 +310,10 @@ struct intel_display {
        } cdclk;
 
        struct {
+               struct drm_property_blob *glk_linear_degamma_lut;
+       } color;
+
+       struct {
                /* The current hardware dbuf configuration */
                u8 enabled_slices;
 
@@ -316,6 +321,14 @@ struct intel_display {
        } dbuf;
 
        struct {
+               /*
+                * dkl.phy_lock protects against concurrent access of the
+                * Dekel TypeC PHYs.
+                */
+               spinlock_t phy_lock;
+       } dkl;
+
+       struct {
                /* VLV/CHV/BXT/GLK DSI MMIO register base address */
                u32 mmio_base;
        } dsi;
index 7c7253a..cfc056a 100644 (file)
@@ -22,6 +22,7 @@
 #include "intel_fbdev.h"
 #include "intel_hdcp.h"
 #include "intel_hdmi.h"
+#include "intel_hotplug.h"
 #include "intel_panel.h"
 #include "intel_pm.h"
 #include "intel_psr.h"
@@ -127,7 +128,6 @@ static int i915_vbt(struct seq_file *m, void *unused)
 static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
 {
        struct drm_i915_private *dev_priv = node_to_i915(m->private);
-       struct drm_device *dev = &dev_priv->drm;
        struct intel_framebuffer *fbdev_fb = NULL;
        struct drm_framebuffer *drm_fb;
 
@@ -146,8 +146,8 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
        }
 #endif
 
-       mutex_lock(&dev->mode_config.fb_lock);
-       drm_for_each_fb(drm_fb, dev) {
+       mutex_lock(&dev_priv->drm.mode_config.fb_lock);
+       drm_for_each_fb(drm_fb, &dev_priv->drm) {
                struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb);
                if (fb == fbdev_fb)
                        continue;
@@ -162,7 +162,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
                i915_debugfs_describe_obj(m, intel_fb_obj(&fb->base));
                seq_putc(m, '\n');
        }
-       mutex_unlock(&dev->mode_config.fb_lock);
+       mutex_unlock(&dev_priv->drm.mode_config.fb_lock);
 
        return 0;
 }
@@ -897,7 +897,6 @@ 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 drm_i915_private *dev_priv = node_to_i915(m->private);
-       struct drm_device *dev = &dev_priv->drm;
        struct intel_crtc *crtc;
        struct drm_connector *connector;
        struct drm_connector_list_iter conn_iter;
@@ -905,22 +904,22 @@ static int i915_display_info(struct seq_file *m, void *unused)
 
        wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
 
-       drm_modeset_lock_all(dev);
+       drm_modeset_lock_all(&dev_priv->drm);
 
        seq_printf(m, "CRTC info\n");
        seq_printf(m, "---------\n");
-       for_each_intel_crtc(dev, crtc)
+       for_each_intel_crtc(&dev_priv->drm, crtc)
                intel_crtc_info(m, crtc);
 
        seq_printf(m, "\n");
        seq_printf(m, "Connector info\n");
        seq_printf(m, "--------------\n");
-       drm_connector_list_iter_begin(dev, &conn_iter);
+       drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
        drm_for_each_connector_iter(connector, &conn_iter)
                intel_connector_info(m, connector);
        drm_connector_list_iter_end(&conn_iter);
 
-       drm_modeset_unlock_all(dev);
+       drm_modeset_unlock_all(&dev_priv->drm);
 
        intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
 
@@ -930,10 +929,9 @@ static int i915_display_info(struct seq_file *m, void *unused)
 static int i915_shared_dplls_info(struct seq_file *m, void *unused)
 {
        struct drm_i915_private *dev_priv = node_to_i915(m->private);
-       struct drm_device *dev = &dev_priv->drm;
        int i;
 
-       drm_modeset_lock_all(dev);
+       drm_modeset_lock_all(&dev_priv->drm);
 
        seq_printf(m, "PLL refclks: non-SSC: %d kHz, SSC: %d kHz\n",
                   dev_priv->display.dpll.ref_clks.nssc,
@@ -978,7 +976,7 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
                seq_printf(m, " mg_pll_tdc_coldst_bias: 0x%08x\n",
                           pll->state.hw_state.mg_pll_tdc_coldst_bias);
        }
-       drm_modeset_unlock_all(dev);
+       drm_modeset_unlock_all(&dev_priv->drm);
 
        return 0;
 }
@@ -986,14 +984,13 @@ static int i915_shared_dplls_info(struct seq_file *m, void *unused)
 static int i915_ddb_info(struct seq_file *m, void *unused)
 {
        struct drm_i915_private *dev_priv = node_to_i915(m->private);
-       struct drm_device *dev = &dev_priv->drm;
        struct skl_ddb_entry *entry;
        struct intel_crtc *crtc;
 
        if (DISPLAY_VER(dev_priv) < 9)
                return -ENODEV;
 
-       drm_modeset_lock_all(dev);
+       drm_modeset_lock_all(&dev_priv->drm);
 
        seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
 
@@ -1017,53 +1014,7 @@ static int i915_ddb_info(struct seq_file *m, void *unused)
                           entry->end, skl_ddb_entry_size(entry));
        }
 
-       drm_modeset_unlock_all(dev);
-
-       return 0;
-}
-
-static int i915_drrs_status(struct seq_file *m, void *unused)
-{
-       struct drm_i915_private *dev_priv = node_to_i915(m->private);
-       struct drm_connector_list_iter conn_iter;
-       struct intel_connector *connector;
-       struct intel_crtc *crtc;
-
-       drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
-       for_each_intel_connector_iter(connector, &conn_iter) {
-               seq_printf(m, "[CONNECTOR:%d:%s] DRRS type: %s\n",
-                          connector->base.base.id, connector->base.name,
-                          intel_drrs_type_str(intel_panel_drrs_type(connector)));
-       }
-       drm_connector_list_iter_end(&conn_iter);
-
-       seq_puts(m, "\n");
-
-       for_each_intel_crtc(&dev_priv->drm, crtc) {
-               const struct intel_crtc_state *crtc_state =
-                       to_intel_crtc_state(crtc->base.state);
-
-               seq_printf(m, "[CRTC:%d:%s]:\n",
-                          crtc->base.base.id, crtc->base.name);
-
-               mutex_lock(&crtc->drrs.mutex);
-
-               /* DRRS Supported */
-               seq_printf(m, "\tDRRS Enabled: %s\n",
-                          str_yes_no(crtc_state->has_drrs));
-
-               seq_printf(m, "\tDRRS Active: %s\n",
-                          str_yes_no(intel_drrs_is_active(crtc)));
-
-               seq_printf(m, "\tBusy_frontbuffer_bits: 0x%X\n",
-                          crtc->drrs.busy_frontbuffer_bits);
-
-               seq_printf(m, "\tDRRS refresh rate: %s\n",
-                          crtc->drrs.refresh_rate == DRRS_REFRESH_RATE_LOW ?
-                          "low" : "high");
-
-               mutex_unlock(&crtc->drrs.mutex);
-       }
+       drm_modeset_unlock_all(&dev_priv->drm);
 
        return 0;
 }
@@ -1107,13 +1058,12 @@ static int i915_lpsp_status(struct seq_file *m, void *unused)
 static int i915_dp_mst_info(struct seq_file *m, void *unused)
 {
        struct drm_i915_private *dev_priv = node_to_i915(m->private);
-       struct drm_device *dev = &dev_priv->drm;
        struct intel_encoder *intel_encoder;
        struct intel_digital_port *dig_port;
        struct drm_connector *connector;
        struct drm_connector_list_iter conn_iter;
 
-       drm_connector_list_iter_begin(dev, &conn_iter);
+       drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
        drm_for_each_connector_iter(connector, &conn_iter) {
                if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
                        continue;
@@ -1200,12 +1150,11 @@ static ssize_t i915_displayport_test_active_write(struct file *file,
 static int i915_displayport_test_active_show(struct seq_file *m, void *data)
 {
        struct drm_i915_private *dev_priv = m->private;
-       struct drm_device *dev = &dev_priv->drm;
        struct drm_connector *connector;
        struct drm_connector_list_iter conn_iter;
        struct intel_dp *intel_dp;
 
-       drm_connector_list_iter_begin(dev, &conn_iter);
+       drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
        drm_for_each_connector_iter(connector, &conn_iter) {
                struct intel_encoder *encoder;
 
@@ -1250,12 +1199,11 @@ static const struct file_operations i915_displayport_test_active_fops = {
 static int i915_displayport_test_data_show(struct seq_file *m, void *data)
 {
        struct drm_i915_private *dev_priv = m->private;
-       struct drm_device *dev = &dev_priv->drm;
        struct drm_connector *connector;
        struct drm_connector_list_iter conn_iter;
        struct intel_dp *intel_dp;
 
-       drm_connector_list_iter_begin(dev, &conn_iter);
+       drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
        drm_for_each_connector_iter(connector, &conn_iter) {
                struct intel_encoder *encoder;
 
@@ -1304,12 +1252,11 @@ DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_data);
 static int i915_displayport_test_type_show(struct seq_file *m, void *data)
 {
        struct drm_i915_private *dev_priv = m->private;
-       struct drm_device *dev = &dev_priv->drm;
        struct drm_connector *connector;
        struct drm_connector_list_iter conn_iter;
        struct intel_dp *intel_dp;
 
-       drm_connector_list_iter_begin(dev, &conn_iter);
+       drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
        drm_for_each_connector_iter(connector, &conn_iter) {
                struct intel_encoder *encoder;
 
@@ -1336,7 +1283,6 @@ DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_type);
 static void wm_latency_show(struct seq_file *m, const u16 wm[8])
 {
        struct drm_i915_private *dev_priv = m->private;
-       struct drm_device *dev = &dev_priv->drm;
        int level;
        int num_levels;
 
@@ -1349,7 +1295,7 @@ static void wm_latency_show(struct seq_file *m, const u16 wm[8])
        else
                num_levels = ilk_wm_max_level(dev_priv) + 1;
 
-       drm_modeset_lock_all(dev);
+       drm_modeset_lock_all(&dev_priv->drm);
 
        for (level = 0; level < num_levels; level++) {
                unsigned int latency = wm[level];
@@ -1370,7 +1316,7 @@ 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);
+       drm_modeset_unlock_all(&dev_priv->drm);
 }
 
 static int pri_wm_latency_show(struct seq_file *m, void *data)
@@ -1453,7 +1399,6 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
 {
        struct seq_file *m = file->private_data;
        struct drm_i915_private *dev_priv = m->private;
-       struct drm_device *dev = &dev_priv->drm;
        u16 new[8] = { 0 };
        int num_levels;
        int level;
@@ -1483,12 +1428,12 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
        if (ret != num_levels)
                return -EINVAL;
 
-       drm_modeset_lock_all(dev);
+       drm_modeset_lock_all(&dev_priv->drm);
 
        for (level = 0; level < num_levels; level++)
                wm[level] = new[level];
 
-       drm_modeset_unlock_all(dev);
+       drm_modeset_unlock_all(&dev_priv->drm);
 
        return len;
 }
@@ -1566,209 +1511,6 @@ static const struct file_operations i915_cur_wm_latency_fops = {
        .write = cur_wm_latency_write
 };
 
-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;
-
-       /* 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);
-
-       seq_printf(m, "Threshold: %d\n", hotplug->hpd_storm_threshold);
-       seq_printf(m, "Detected: %s\n",
-                  str_yes_no(delayed_work_pending(&hotplug->reenable_work)));
-
-       return 0;
-}
-
-static ssize_t i915_hpd_storm_ctl_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_hotplug *hotplug = &dev_priv->display.hotplug;
-       unsigned int new_threshold;
-       int i;
-       char *newline;
-       char tmp[16];
-
-       if (len >= sizeof(tmp))
-               return -EINVAL;
-
-       if (copy_from_user(tmp, ubuf, len))
-               return -EFAULT;
-
-       tmp[len] = '\0';
-
-       /* Strip newline, if any */
-       newline = strchr(tmp, '\n');
-       if (newline)
-               *newline = '\0';
-
-       if (strcmp(tmp, "reset") == 0)
-               new_threshold = HPD_STORM_DEFAULT_THRESHOLD;
-       else if (kstrtouint(tmp, 10, &new_threshold) != 0)
-               return -EINVAL;
-
-       if (new_threshold > 0)
-               drm_dbg_kms(&dev_priv->drm,
-                           "Setting HPD storm detection threshold to %d\n",
-                           new_threshold);
-       else
-               drm_dbg_kms(&dev_priv->drm, "Disabling HPD storm detection\n");
-
-       spin_lock_irq(&dev_priv->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);
-
-       /* Re-enable hpd immediately if we were in an irq storm */
-       flush_delayed_work(&dev_priv->display.hotplug.reenable_work);
-
-       return len;
-}
-
-static int i915_hpd_storm_ctl_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, i915_hpd_storm_ctl_show, inode->i_private);
-}
-
-static const struct file_operations i915_hpd_storm_ctl_fops = {
-       .owner = THIS_MODULE,
-       .open = i915_hpd_storm_ctl_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-       .write = i915_hpd_storm_ctl_write
-};
-
-static int i915_hpd_short_storm_ctl_show(struct seq_file *m, void *data)
-{
-       struct drm_i915_private *dev_priv = m->private;
-
-       seq_printf(m, "Enabled: %s\n",
-                  str_yes_no(dev_priv->display.hotplug.hpd_short_storm_enabled));
-
-       return 0;
-}
-
-static int
-i915_hpd_short_storm_ctl_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, i915_hpd_short_storm_ctl_show,
-                          inode->i_private);
-}
-
-static ssize_t i915_hpd_short_storm_ctl_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_hotplug *hotplug = &dev_priv->display.hotplug;
-       char *newline;
-       char tmp[16];
-       int i;
-       bool new_state;
-
-       if (len >= sizeof(tmp))
-               return -EINVAL;
-
-       if (copy_from_user(tmp, ubuf, len))
-               return -EFAULT;
-
-       tmp[len] = '\0';
-
-       /* Strip newline, if any */
-       newline = strchr(tmp, '\n');
-       if (newline)
-               *newline = '\0';
-
-       /* Reset to the "default" state for this system */
-       if (strcmp(tmp, "reset") == 0)
-               new_state = !HAS_DP_MST(dev_priv);
-       else if (kstrtobool(tmp, &new_state) != 0)
-               return -EINVAL;
-
-       drm_dbg_kms(&dev_priv->drm, "%sabling HPD short storm detection\n",
-                   new_state ? "En" : "Dis");
-
-       spin_lock_irq(&dev_priv->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);
-
-       /* Re-enable hpd immediately if we were in an irq storm */
-       flush_delayed_work(&dev_priv->display.hotplug.reenable_work);
-
-       return len;
-}
-
-static const struct file_operations i915_hpd_short_storm_ctl_fops = {
-       .owner = THIS_MODULE,
-       .open = i915_hpd_short_storm_ctl_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-       .write = i915_hpd_short_storm_ctl_write,
-};
-
-static int i915_drrs_ctl_set(void *data, u64 val)
-{
-       struct drm_i915_private *dev_priv = data;
-       struct drm_device *dev = &dev_priv->drm;
-       struct intel_crtc *crtc;
-
-       for_each_intel_crtc(dev, crtc) {
-               struct intel_crtc_state *crtc_state;
-               struct drm_crtc_commit *commit;
-               int ret;
-
-               ret = drm_modeset_lock_single_interruptible(&crtc->base.mutex);
-               if (ret)
-                       return ret;
-
-               crtc_state = to_intel_crtc_state(crtc->base.state);
-
-               if (!crtc_state->hw.active ||
-                   !crtc_state->has_drrs)
-                       goto out;
-
-               commit = crtc_state->uapi.commit;
-               if (commit) {
-                       ret = wait_for_completion_interruptible(&commit->hw_done);
-                       if (ret)
-                               goto out;
-               }
-
-               drm_dbg(&dev_priv->drm,
-                       "Manually %sactivating DRRS\n", val ? "" : "de");
-
-               if (val)
-                       intel_drrs_activate(crtc_state);
-               else
-                       intel_drrs_deactivate(crtc_state);
-
-out:
-               drm_modeset_unlock(&crtc->base.mutex);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(i915_drrs_ctl_fops, NULL, i915_drrs_ctl_set, "%llu\n");
-
 static ssize_t
 i915_fifo_underrun_reset_write(struct file *filp,
                               const char __user *ubuf,
@@ -1776,7 +1518,6 @@ i915_fifo_underrun_reset_write(struct file *filp,
 {
        struct drm_i915_private *dev_priv = filp->private_data;
        struct intel_crtc *crtc;
-       struct drm_device *dev = &dev_priv->drm;
        int ret;
        bool reset;
 
@@ -1787,7 +1528,7 @@ i915_fifo_underrun_reset_write(struct file *filp,
        if (!reset)
                return cnt;
 
-       for_each_intel_crtc(dev, crtc) {
+       for_each_intel_crtc(&dev_priv->drm, crtc) {
                struct drm_crtc_commit *commit;
                struct intel_crtc_state *crtc_state;
 
@@ -1842,7 +1583,6 @@ static const struct drm_info_list intel_display_debugfs_list[] = {
        {"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},
-       {"i915_drrs_status", i915_drrs_status, 0},
        {"i915_lpsp_status", i915_lpsp_status, 0},
 };
 
@@ -1857,9 +1597,6 @@ static const struct {
        {"i915_dp_test_data", &i915_displayport_test_data_fops},
        {"i915_dp_test_type", &i915_displayport_test_type_fops},
        {"i915_dp_test_active", &i915_displayport_test_active_fops},
-       {"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops},
-       {"i915_hpd_short_storm_ctl", &i915_hpd_short_storm_ctl_fops},
-       {"i915_drrs_ctl", &i915_drrs_ctl_fops},
        {"i915_edp_psr_debug", &i915_edp_psr_debug_fops},
 };
 
@@ -1882,6 +1619,7 @@ void intel_display_debugfs_register(struct drm_i915_private *i915)
 
        intel_dmc_debugfs_register(i915);
        intel_fbc_debugfs_register(i915);
+       intel_hpd_debugfs_register(i915);
        skl_watermark_ipc_debugfs_register(i915);
 }
 
@@ -2195,6 +1933,8 @@ void intel_connector_debugfs_add(struct intel_connector *intel_connector)
        if (!root)
                return;
 
+       intel_drrs_connector_debugfs_add(intel_connector);
+
        if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
                debugfs_create_file("i915_panel_timings", S_IRUGO, root,
                                    connector, &i915_panel_fops);
@@ -2247,6 +1987,7 @@ void intel_crtc_debugfs_add(struct drm_crtc *crtc)
                return;
 
        crtc_updates_add(crtc);
+       intel_drrs_crtc_debugfs_add(to_intel_crtc(crtc));
        intel_fbc_crtc_debugfs_add(to_intel_crtc(crtc));
 
        debugfs_create_file("i915_current_bpc", 0444, crtc->debugfs_entry, crtc,
index 1e608b9..4c1de91 100644 (file)
@@ -1148,10 +1148,9 @@ static void hsw_assert_cdclk(struct drm_i915_private *dev_priv)
 
 static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = &dev_priv->drm;
        struct intel_crtc *crtc;
 
-       for_each_intel_crtc(dev, crtc)
+       for_each_intel_crtc(&dev_priv->drm, crtc)
                I915_STATE_WARN(crtc->active, "CRTC for pipe %c enabled\n",
                                pipe_name(crtc->pipe));
 
index df7ee49..8710dd4 100644 (file)
@@ -12,6 +12,8 @@
 #include "intel_de.h"
 #include "intel_display_power_well.h"
 #include "intel_display_types.h"
+#include "intel_dkl_phy.h"
+#include "intel_dkl_phy_regs.h"
 #include "intel_dmc.h"
 #include "intel_dpio_phy.h"
 #include "intel_dpll.h"
@@ -529,11 +531,9 @@ icl_tc_phy_aux_power_well_enable(struct drm_i915_private *dev_priv,
                enum tc_port tc_port;
 
                tc_port = TGL_AUX_PW_TO_TC_PORT(i915_power_well_instance(power_well)->hsw.idx);
-               intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
-                              HIP_INDEX_VAL(tc_port, 0x2));
 
-               if (intel_de_wait_for_set(dev_priv, DKL_CMN_UC_DW_27(tc_port),
-                                         DKL_CMN_UC_DW27_UC_HEALTH, 1))
+               if (wait_for(intel_dkl_phy_read(dev_priv, DKL_CMN_UC_DW_27(tc_port)) &
+                            DKL_CMN_UC_DW27_UC_HEALTH, 1))
                        drm_warn(&dev_priv->drm,
                                 "Timeout waiting TC uC health\n");
        }
index 298d00a..7f18c05 100644 (file)
@@ -1001,11 +1001,15 @@ struct intel_crtc_state {
         */
        struct {
                bool active, enable;
+               /* logical state of LUTs */
                struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
                struct drm_display_mode mode, pipe_mode, adjusted_mode;
                enum drm_scaling_filter scaling_filter;
        } hw;
 
+       /* actual state of LUTs */
+       struct drm_property_blob *pre_csc_lut, *post_csc_lut;
+
        /**
         * quirks - bitfield with hw state readout quirks
         *
@@ -2040,15 +2044,16 @@ static inline bool
 intel_crtc_has_type(const struct intel_crtc_state *crtc_state,
                    enum intel_output_type type)
 {
-       return crtc_state->output_types & (1 << type);
+       return crtc_state->output_types & BIT(type);
 }
+
 static inline bool
 intel_crtc_has_dp_encoder(const struct intel_crtc_state *crtc_state)
 {
        return crtc_state->output_types &
-               ((1 << INTEL_OUTPUT_DP) |
-                (1 << INTEL_OUTPUT_DP_MST) |
-                (1 << INTEL_OUTPUT_EDP));
+               (BIT(INTEL_OUTPUT_DP) |
+                BIT(INTEL_OUTPUT_DP_MST) |
+                BIT(INTEL_OUTPUT_EDP));
 }
 
 static inline bool
@@ -2057,6 +2062,20 @@ intel_crtc_needs_modeset(const struct intel_crtc_state *crtc_state)
        return drm_atomic_crtc_needs_modeset(&crtc_state->uapi);
 }
 
+static inline bool
+intel_crtc_needs_fastset(const struct intel_crtc_state *crtc_state)
+{
+       return crtc_state->update_pipe;
+}
+
+static inline bool
+intel_crtc_needs_color_update(const struct intel_crtc_state *crtc_state)
+{
+       return crtc_state->uapi.color_mgmt_changed ||
+               intel_crtc_needs_fastset(crtc_state) ||
+               intel_crtc_needs_modeset(crtc_state);
+}
+
 static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state)
 {
        return i915_ggtt_offset(plane_state->ggtt_vma);
diff --git a/drivers/gpu/drm/i915/display/intel_dkl_phy.c b/drivers/gpu/drm/i915/display/intel_dkl_phy.c
new file mode 100644 (file)
index 0000000..57cc3ed
--- /dev/null
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright Â© 2022 Intel Corporation
+ */
+
+#include "i915_drv.h"
+#include "i915_reg.h"
+
+#include "intel_de.h"
+#include "intel_display.h"
+#include "intel_dkl_phy.h"
+#include "intel_dkl_phy_regs.h"
+
+static void
+dkl_phy_set_hip_idx(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg)
+{
+       enum tc_port tc_port = DKL_REG_TC_PORT(reg);
+
+       drm_WARN_ON(&i915->drm, tc_port < TC_PORT_1 || tc_port >= I915_MAX_TC_PORTS);
+
+       intel_de_write(i915,
+                      HIP_INDEX_REG(tc_port),
+                      HIP_INDEX_VAL(tc_port, reg.bank_idx));
+}
+
+/**
+ * intel_dkl_phy_read - read a Dekel PHY register
+ * @i915: i915 device instance
+ * @reg: Dekel PHY register
+ *
+ * Read the @reg Dekel PHY register.
+ *
+ * Returns the read value.
+ */
+u32
+intel_dkl_phy_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg)
+{
+       u32 val;
+
+       spin_lock(&i915->display.dkl.phy_lock);
+
+       dkl_phy_set_hip_idx(i915, reg);
+       val = intel_de_read(i915, DKL_REG_MMIO(reg));
+
+       spin_unlock(&i915->display.dkl.phy_lock);
+
+       return val;
+}
+
+/**
+ * intel_dkl_phy_write - write a Dekel PHY register
+ * @i915: i915 device instance
+ * @reg: Dekel PHY register
+ * @val: value to write
+ *
+ * Write @val to the @reg Dekel PHY register.
+ */
+void
+intel_dkl_phy_write(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 val)
+{
+       spin_lock(&i915->display.dkl.phy_lock);
+
+       dkl_phy_set_hip_idx(i915, reg);
+       intel_de_write(i915, DKL_REG_MMIO(reg), val);
+
+       spin_unlock(&i915->display.dkl.phy_lock);
+}
+
+/**
+ * intel_dkl_phy_rmw - read-modify-write a Dekel PHY register
+ * @i915: i915 device instance
+ * @reg: Dekel PHY register
+ * @clear: mask to clear
+ * @set: mask to set
+ *
+ * Read the @reg Dekel PHY register, clearing then setting the @clear/@set bits in it, and writing
+ * this value back to the register if the value differs from the read one.
+ */
+void
+intel_dkl_phy_rmw(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 clear, u32 set)
+{
+       spin_lock(&i915->display.dkl.phy_lock);
+
+       dkl_phy_set_hip_idx(i915, reg);
+       intel_de_rmw(i915, DKL_REG_MMIO(reg), clear, set);
+
+       spin_unlock(&i915->display.dkl.phy_lock);
+}
+
+/**
+ * intel_dkl_phy_posting_read - do a posting read from a Dekel PHY register
+ * @i915: i915 device instance
+ * @reg: Dekel PHY register
+ *
+ * Read the @reg Dekel PHY register without returning the read value.
+ */
+void
+intel_dkl_phy_posting_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg)
+{
+       spin_lock(&i915->display.dkl.phy_lock);
+
+       dkl_phy_set_hip_idx(i915, reg);
+       intel_de_posting_read(i915, DKL_REG_MMIO(reg));
+
+       spin_unlock(&i915->display.dkl.phy_lock);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_dkl_phy.h b/drivers/gpu/drm/i915/display/intel_dkl_phy.h
new file mode 100644 (file)
index 0000000..570ee36
--- /dev/null
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright Â© 2022 Intel Corporation
+ */
+
+#ifndef __INTEL_DKL_PHY_H__
+#define __INTEL_DKL_PHY_H__
+
+#include <linux/types.h>
+
+#include "intel_dkl_phy_regs.h"
+
+struct drm_i915_private;
+
+u32
+intel_dkl_phy_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg);
+void
+intel_dkl_phy_write(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 val);
+void
+intel_dkl_phy_rmw(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 clear, u32 set);
+void
+intel_dkl_phy_posting_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg);
+
+#endif /* __INTEL_DKL_PHY_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dkl_phy_regs.h b/drivers/gpu/drm/i915/display/intel_dkl_phy_regs.h
new file mode 100644 (file)
index 0000000..56085b3
--- /dev/null
@@ -0,0 +1,204 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright Â© 2022 Intel Corporation
+ */
+
+#ifndef __INTEL_DKL_PHY_REGS__
+#define __INTEL_DKL_PHY_REGS__
+
+#include <linux/types.h>
+
+struct intel_dkl_phy_reg {
+       u32 reg:24;
+       u32 bank_idx:4;
+};
+
+#define _DKL_PHY1_BASE                                 0x168000
+#define _DKL_PHY2_BASE                                 0x169000
+#define _DKL_PHY3_BASE                                 0x16A000
+#define _DKL_PHY4_BASE                                 0x16B000
+#define _DKL_PHY5_BASE                                 0x16C000
+#define _DKL_PHY6_BASE                                 0x16D000
+
+#define DKL_REG_TC_PORT(__reg) \
+       (TC_PORT_1 + ((__reg).reg - _DKL_PHY1_BASE) / (_DKL_PHY2_BASE - _DKL_PHY1_BASE))
+
+/* DEKEL PHY MMIO Address = Phy base + (internal address & ~index_mask) */
+#define DKL_REG_MMIO(__reg)                            _MMIO((__reg).reg)
+
+#define _DKL_REG_PHY_BASE(tc_port)                     _PORT(tc_port, \
+                                                             _DKL_PHY1_BASE, \
+                                                             _DKL_PHY2_BASE)
+
+#define _DKL_BANK_SHIFT                                        12
+#define _DKL_REG_BANK_OFFSET(phy_offset) \
+       ((phy_offset) & ((1 << _DKL_BANK_SHIFT) - 1))
+#define _DKL_REG_BANK_IDX(phy_offset) \
+       (((phy_offset) >> _DKL_BANK_SHIFT) & 0xf)
+
+#define _DKL_REG(tc_port, phy_offset)  \
+       ((const struct intel_dkl_phy_reg) { \
+               .reg = _DKL_REG_PHY_BASE(tc_port) + \
+                      _DKL_REG_BANK_OFFSET(phy_offset), \
+               .bank_idx = _DKL_REG_BANK_IDX(phy_offset), \
+       })
+
+#define _DKL_REG_LN(tc_port, ln_idx, ln0_offs, ln1_offs) \
+       _DKL_REG(tc_port, (ln0_offs) + (ln_idx) * ((ln1_offs) - (ln0_offs)))
+
+#define _DKL_PCS_DW5_LN0                               0x0014
+#define _DKL_PCS_DW5_LN1                               0x1014
+#define DKL_PCS_DW5(tc_port, ln)                       _DKL_REG_LN(tc_port, ln, \
+                                                                   _DKL_PCS_DW5_LN0, \
+                                                                   _DKL_PCS_DW5_LN1)
+#define   DKL_PCS_DW5_CORE_SOFTRESET                   REG_BIT(11)
+
+#define _DKL_PLL_DIV0                                  0x2200
+#define DKL_PLL_DIV0(tc_port)                          _DKL_REG(tc_port, \
+                                                                _DKL_PLL_DIV0)
+#define   DKL_PLL_DIV0_AFC_STARTUP_MASK                        REG_GENMASK(27, 25)
+#define   DKL_PLL_DIV0_AFC_STARTUP(val)                        REG_FIELD_PREP(DKL_PLL_DIV0_AFC_STARTUP_MASK, (val))
+#define   DKL_PLL_DIV0_INTEG_COEFF(x)                  ((x) << 16)
+#define   DKL_PLL_DIV0_INTEG_COEFF_MASK                        (0x1F << 16)
+#define   DKL_PLL_DIV0_PROP_COEFF(x)                   ((x) << 12)
+#define   DKL_PLL_DIV0_PROP_COEFF_MASK                 (0xF << 12)
+#define   DKL_PLL_DIV0_FBPREDIV_SHIFT                  (8)
+#define   DKL_PLL_DIV0_FBPREDIV(x)                     ((x) << DKL_PLL_DIV0_FBPREDIV_SHIFT)
+#define   DKL_PLL_DIV0_FBPREDIV_MASK                   (0xF << DKL_PLL_DIV0_FBPREDIV_SHIFT)
+#define   DKL_PLL_DIV0_FBDIV_INT(x)                    ((x) << 0)
+#define   DKL_PLL_DIV0_FBDIV_INT_MASK                  (0xFF << 0)
+#define   DKL_PLL_DIV0_MASK                            (DKL_PLL_DIV0_INTEG_COEFF_MASK | \
+                                                        DKL_PLL_DIV0_PROP_COEFF_MASK | \
+                                                        DKL_PLL_DIV0_FBPREDIV_MASK | \
+                                                        DKL_PLL_DIV0_FBDIV_INT_MASK)
+
+#define _DKL_PLL_DIV1                                  0x2204
+#define DKL_PLL_DIV1(tc_port)                          _DKL_REG(tc_port, \
+                                                                _DKL_PLL_DIV1)
+#define   DKL_PLL_DIV1_IREF_TRIM(x)                    ((x) << 16)
+#define   DKL_PLL_DIV1_IREF_TRIM_MASK                  (0x1F << 16)
+#define   DKL_PLL_DIV1_TDC_TARGET_CNT(x)               ((x) << 0)
+#define   DKL_PLL_DIV1_TDC_TARGET_CNT_MASK             (0xFF << 0)
+
+#define _DKL_PLL_SSC                                   0x2210
+#define DKL_PLL_SSC(tc_port)                           _DKL_REG(tc_port, \
+                                                                _DKL_PLL_SSC)
+#define   DKL_PLL_SSC_IREF_NDIV_RATIO(x)               ((x) << 29)
+#define   DKL_PLL_SSC_IREF_NDIV_RATIO_MASK             (0x7 << 29)
+#define   DKL_PLL_SSC_STEP_LEN(x)                      ((x) << 16)
+#define   DKL_PLL_SSC_STEP_LEN_MASK                    (0xFF << 16)
+#define   DKL_PLL_SSC_STEP_NUM(x)                      ((x) << 11)
+#define   DKL_PLL_SSC_STEP_NUM_MASK                    (0x7 << 11)
+#define   DKL_PLL_SSC_EN                               (1 << 9)
+
+#define _DKL_PLL_BIAS                                  0x2214
+#define DKL_PLL_BIAS(tc_port)                          _DKL_REG(tc_port, \
+                                                                _DKL_PLL_BIAS)
+#define   DKL_PLL_BIAS_FRAC_EN_H                       (1 << 30)
+#define   DKL_PLL_BIAS_FBDIV_SHIFT                     (8)
+#define   DKL_PLL_BIAS_FBDIV_FRAC(x)                   ((x) << DKL_PLL_BIAS_FBDIV_SHIFT)
+#define   DKL_PLL_BIAS_FBDIV_FRAC_MASK                 (0x3FFFFF << DKL_PLL_BIAS_FBDIV_SHIFT)
+
+#define _DKL_PLL_TDC_COLDST_BIAS                       0x2218
+#define DKL_PLL_TDC_COLDST_BIAS(tc_port)               _DKL_REG(tc_port, \
+                                                                _DKL_PLL_TDC_COLDST_BIAS)
+#define   DKL_PLL_TDC_SSC_STEP_SIZE(x)                 ((x) << 8)
+#define   DKL_PLL_TDC_SSC_STEP_SIZE_MASK               (0xFF << 8)
+#define   DKL_PLL_TDC_FEED_FWD_GAIN(x)                 ((x) << 0)
+#define   DKL_PLL_TDC_FEED_FWD_GAIN_MASK               (0xFF << 0)
+
+#define _DKL_REFCLKIN_CTL                              0x212C
+#define DKL_REFCLKIN_CTL(tc_port)                      _DKL_REG(tc_port, \
+                                                                _DKL_REFCLKIN_CTL)
+/* Bits are the same as MG_REFCLKIN_CTL */
+
+#define _DKL_CLKTOP2_HSCLKCTL                          0x20D4
+#define DKL_CLKTOP2_HSCLKCTL(rc_port)                  _DKL_REG(tc_port, \
+                                                                _DKL_CLKTOP2_HSCLKCTL)
+/* Bits are the same as MG_CLKTOP2_HSCLKCTL */
+
+#define _DKL_CLKTOP2_CORECLKCTL1                       0x20D8
+#define DKL_CLKTOP2_CORECLKCTL1(tc_port)               _DKL_REG(tc_port, \
+                                                                _DKL_CLKTOP2_CORECLKCTL1)
+/* Bits are the same as MG_CLKTOP2_CORECLKCTL1 */
+
+#define _DKL_TX_DPCNTL0_LN0                            0x02C0
+#define _DKL_TX_DPCNTL0_LN1                            0x12C0
+#define DKL_TX_DPCNTL0(tc_port, ln)                    _DKL_REG_LN(tc_port, ln, \
+                                                                   _DKL_TX_DPCNTL0_LN0, \
+                                                                   _DKL_TX_DPCNTL0_LN1)
+#define  DKL_TX_PRESHOOT_COEFF(x)                      ((x) << 13)
+#define  DKL_TX_PRESHOOT_COEFF_MASK                    (0x1f << 13)
+#define  DKL_TX_DE_EMPHASIS_COEFF(x)                   ((x) << 8)
+#define  DKL_TX_DE_EMPAHSIS_COEFF_MASK                 (0x1f << 8)
+#define  DKL_TX_VSWING_CONTROL(x)                      ((x) << 0)
+#define  DKL_TX_VSWING_CONTROL_MASK                    (0x7 << 0)
+
+#define _DKL_TX_DPCNTL1_LN0                            0x02C4
+#define _DKL_TX_DPCNTL1_LN1                            0x12C4
+#define DKL_TX_DPCNTL1(tc_port, ln)                    _DKL_REG_LN(tc_port, ln, \
+                                                                   _DKL_TX_DPCNTL1_LN0, \
+                                                                   _DKL_TX_DPCNTL1_LN1)
+/* Bits are the same as DKL_TX_DPCNTRL0 */
+
+#define _DKL_TX_DPCNTL2_LN0                            0x02C8
+#define _DKL_TX_DPCNTL2_LN1                            0x12C8
+#define DKL_TX_DPCNTL2(tc_port, ln)                    _DKL_REG_LN(tc_port, ln, \
+                                                                   _DKL_TX_DPCNTL2_LN0, \
+                                                                   _DKL_TX_DPCNTL2_LN1)
+#define  DKL_TX_DP20BITMODE                            REG_BIT(2)
+#define  DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK     REG_GENMASK(4, 3)
+#define  DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1(val)     REG_FIELD_PREP(DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK, (val))
+#define  DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK     REG_GENMASK(6, 5)
+#define  DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2(val)     REG_FIELD_PREP(DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK, (val))
+
+#define _DKL_TX_FW_CALIB_LN0                           0x02F8
+#define _DKL_TX_FW_CALIB_LN1                           0x12F8
+#define DKL_TX_FW_CALIB(tc_port, ln)                   _DKL_REG_LN(tc_port, ln, \
+                                                                   _DKL_TX_FW_CALIB_LN0, \
+                                                                   _DKL_TX_FW_CALIB_LN1)
+#define  DKL_TX_CFG_DISABLE_WAIT_INIT                  (1 << 7)
+
+#define _DKL_TX_PMD_LANE_SUS_LN0                       0x0D00
+#define _DKL_TX_PMD_LANE_SUS_LN1                       0x1D00
+#define DKL_TX_PMD_LANE_SUS(tc_port, ln)               _DKL_REG_LN(tc_port, ln, \
+                                                                   _DKL_TX_PMD_LANE_SUS_LN0, \
+                                                                   _DKL_TX_PMD_LANE_SUS_LN1)
+
+#define _DKL_TX_DW17_LN0                               0x0DC4
+#define _DKL_TX_DW17_LN1                               0x1DC4
+#define DKL_TX_DW17(tc_port, ln)                       _DKL_REG_LN(tc_port, ln, \
+                                                                   _DKL_TX_DW17_LN0, \
+                                                                   _DKL_TX_DW17_LN1)
+
+#define _DKL_TX_DW18_LN0                               0x0DC8
+#define _DKL_TX_DW18_LN1                               0x1DC8
+#define DKL_TX_DW18(tc_port, ln)                       _DKL_REG_LN(tc_port, ln, \
+                                                                   _DKL_TX_DW18_LN0, \
+                                                                   _DKL_TX_DW18_LN1)
+
+#define _DKL_DP_MODE_LN0                               0x00A0
+#define _DKL_DP_MODE_LN1                               0x10A0
+#define DKL_DP_MODE(tc_port, ln)                       _DKL_REG_LN(tc_port, ln, \
+                                                                   _DKL_DP_MODE_LN0, \
+                                                                   _DKL_DP_MODE_LN1)
+
+#define _DKL_CMN_UC_DW27                               0x236C
+#define DKL_CMN_UC_DW_27(tc_port)                      _DKL_REG(tc_port, \
+                                                                _DKL_CMN_UC_DW27)
+#define  DKL_CMN_UC_DW27_UC_HEALTH                     (0x1 << 15)
+
+/*
+ * Each Dekel PHY is addressed through a 4KB aperture. Each PHY has more than
+ * 4KB of register space, so a separate index is programmed in HIP_INDEX_REG0
+ * or HIP_INDEX_REG1, based on the port number, to set the upper 2 address
+ * bits that point the 4KB window into the full PHY register space.
+ */
+#define _HIP_INDEX_REG0                                        0x1010A0
+#define _HIP_INDEX_REG1                                        0x1010A4
+#define HIP_INDEX_REG(tc_port)                         _MMIO((tc_port) < 4 ? _HIP_INDEX_REG0 \
+                                                             : _HIP_INDEX_REG1)
+#define _HIP_INDEX_SHIFT(tc_port)                      (8 * ((tc_port) % 4))
+#define HIP_INDEX_VAL(tc_port, val)                    ((val) << _HIP_INDEX_SHIFT(tc_port))
+
+#endif /* __INTEL_DKL_PHY_REGS__ */
index e52ecc0..081a4d0 100644 (file)
@@ -1065,12 +1065,13 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused)
        seq_printf(m, "fw loaded: %s\n",
                   str_yes_no(intel_dmc_has_payload(i915)));
        seq_printf(m, "path: %s\n", dmc->fw_path);
-       seq_printf(m, "Pipe A fw support: %s\n",
+       seq_printf(m, "Pipe A fw needed: %s\n",
                   str_yes_no(GRAPHICS_VER(i915) >= 12));
        seq_printf(m, "Pipe A fw loaded: %s\n",
                   str_yes_no(dmc->dmc_info[DMC_FW_PIPEA].payload));
-       seq_printf(m, "Pipe B fw support: %s\n",
-                  str_yes_no(IS_ALDERLAKE_P(i915)));
+       seq_printf(m, "Pipe B fw needed: %s\n",
+                  str_yes_no(IS_ALDERLAKE_P(i915) ||
+                             DISPLAY_VER(i915) >= 14));
        seq_printf(m, "Pipe B fw loaded: %s\n",
                   str_yes_no(dmc->dmc_info[DMC_FW_PIPEB].payload));
 
@@ -1081,22 +1082,19 @@ static int intel_dmc_debugfs_status_show(struct seq_file *m, void *unused)
                   DMC_VERSION_MINOR(dmc->version));
 
        if (DISPLAY_VER(i915) >= 12) {
-               if (IS_DGFX(i915)) {
+               i915_reg_t dc3co_reg;
+
+               if (IS_DGFX(i915) || DISPLAY_VER(i915) >= 14) {
+                       dc3co_reg = DG1_DMC_DEBUG3;
                        dc5_reg = DG1_DMC_DEBUG_DC5_COUNT;
                } else {
+                       dc3co_reg = TGL_DMC_DEBUG3;
                        dc5_reg = TGL_DMC_DEBUG_DC5_COUNT;
                        dc6_reg = TGL_DMC_DEBUG_DC6_COUNT;
                }
 
-               /*
-                * NOTE: DMC_DEBUG3 is a general purpose reg.
-                * According to B.Specs:49196 DMC f/w reuses DC5/6 counter
-                * reg for DC3CO debugging and validation,
-                * but TGL DMC f/w is using DMC_DEBUG3 reg for DC3CO counter.
-                */
                seq_printf(m, "DC3CO count: %d\n",
-                          intel_de_read(i915, IS_DGFX(i915) ?
-                                        DG1_DMC_DEBUG3 : TGL_DMC_DEBUG3));
+                          intel_de_read(i915, dc3co_reg));
        } else {
                dc5_reg = IS_BROXTON(i915) ? BXT_DMC_DC3_DC5_COUNT :
                        SKL_DMC_DC3_DC5_COUNT;
index c9be61d..7400d6b 100644 (file)
@@ -2306,6 +2306,7 @@ bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
 {
        struct drm_i915_private *i915 = to_i915(encoder->base.dev);
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+       bool fastset = true;
 
        /*
         * If BIOS has set an unsupported or non-standard link rate for some
@@ -2313,9 +2314,10 @@ bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
         */
        if (intel_dp_rate_index(intel_dp->source_rates, intel_dp->num_source_rates,
                                crtc_state->port_clock) < 0) {
-               drm_dbg_kms(&i915->drm, "Forcing full modeset due to unsupported link rate\n");
+               drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] Forcing full modeset due to unsupported link rate\n",
+                           encoder->base.base.id, encoder->base.name);
                crtc_state->uapi.connectors_changed = true;
-               return false;
+               fastset = false;
        }
 
        /*
@@ -2326,18 +2328,20 @@ bool intel_dp_initial_fastset_check(struct intel_encoder *encoder,
         * Remove once we have readout for DSC.
         */
        if (crtc_state->dsc.compression_enable) {
-               drm_dbg_kms(&i915->drm, "Forcing full modeset due to DSC being enabled\n");
+               drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] Forcing full modeset due to DSC being enabled\n",
+                           encoder->base.base.id, encoder->base.name);
                crtc_state->uapi.mode_changed = true;
-               return false;
+               fastset = false;
        }
 
        if (CAN_PSR(intel_dp)) {
-               drm_dbg_kms(&i915->drm, "Forcing full modeset to compute PSR state\n");
+               drm_dbg_kms(&i915->drm, "[ENCODER:%d:%s] Forcing full modeset to compute PSR state\n",
+                           encoder->base.base.id, encoder->base.name);
                crtc_state->uapi.mode_changed = true;
-               return false;
+               fastset = false;
        }
 
-       return true;
+       return fastset;
 }
 
 static void intel_dp_get_pcon_dsc_cap(struct intel_dp *intel_dp)
@@ -2686,7 +2690,6 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
                           str_enable_disable(tmp));
 }
 
-
 bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp)
 {
        u8 dprx = 0;
@@ -3957,6 +3960,8 @@ intel_dp_handle_hdmi_link_status_change(struct intel_dp *intel_dp)
 
                drm_dp_pcon_hdmi_frl_link_error_count(&intel_dp->aux, &intel_dp->attached_connector->base);
 
+               intel_dp->frl.is_trained = false;
+
                /* Restart FRL training or fall back to TMDS mode */
                intel_dp_check_frl_training(intel_dp);
        }
@@ -5172,19 +5177,6 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect
        if (has_gamut_metadata_dip(dev_priv, port))
                drm_connector_attach_hdr_output_metadata_property(connector);
 
-       if (intel_dp_is_edp(intel_dp)) {
-               u32 allowed_scalers;
-
-               allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT) | BIT(DRM_MODE_SCALE_FULLSCREEN);
-               if (!HAS_GMCH(dev_priv))
-                       allowed_scalers |= BIT(DRM_MODE_SCALE_CENTER);
-
-               drm_connector_attach_scaling_mode_property(connector, allowed_scalers);
-
-               connector->state->scaling_mode = DRM_MODE_SCALE_ASPECT;
-
-       }
-
        if (HAS_VRR(dev_priv))
                drm_connector_attach_vrr_capable_property(connector);
 }
@@ -5197,8 +5189,7 @@ intel_edp_add_properties(struct intel_dp *intel_dp)
        const struct drm_display_mode *fixed_mode =
                intel_panel_preferred_fixed_mode(connector);
 
-       if (!fixed_mode)
-               return;
+       intel_attach_scaling_mode_property(&connector->base);
 
        drm_connector_set_panel_orientation_with_quirk(&connector->base,
                                                       i915->display.vbt.orientation,
@@ -5206,16 +5197,43 @@ intel_edp_add_properties(struct intel_dp *intel_dp)
                                                       fixed_mode->vdisplay);
 }
 
+static void intel_edp_backlight_setup(struct intel_dp *intel_dp,
+                                     struct intel_connector *connector)
+{
+       struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+       enum pipe pipe = INVALID_PIPE;
+
+       if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) {
+               /*
+                * Figure out the current pipe for the initial backlight setup.
+                * If the current pipe isn't valid, try the PPS pipe, and if that
+                * fails just assume pipe A.
+                */
+               pipe = vlv_active_pipe(intel_dp);
+
+               if (pipe != PIPE_A && pipe != PIPE_B)
+                       pipe = intel_dp->pps.pps_pipe;
+
+               if (pipe != PIPE_A && pipe != PIPE_B)
+                       pipe = PIPE_A;
+
+               drm_dbg_kms(&i915->drm,
+                           "[CONNECTOR:%d:%s] using pipe %c for initial backlight setup\n",
+                           connector->base.base.id, connector->base.name,
+                           pipe_name(pipe));
+       }
+
+       intel_backlight_setup(connector, pipe);
+}
+
 static bool intel_edp_init_connector(struct intel_dp *intel_dp,
                                     struct intel_connector *intel_connector)
 {
        struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-       struct drm_device *dev = &dev_priv->drm;
        struct drm_connector *connector = &intel_connector->base;
        struct drm_display_mode *fixed_mode;
        struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
        bool has_dpcd;
-       enum pipe pipe = INVALID_PIPE;
        struct edid *edid;
 
        if (!intel_dp_is_edp(intel_dp))
@@ -5228,7 +5246,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
         * with an already powered-on LVDS power sequencer.
         */
        if (intel_get_lvds_encoder(dev_priv)) {
-               drm_WARN_ON(dev,
+               drm_WARN_ON(&dev_priv->drm,
                            !(HAS_PCH_IBX(dev_priv) || HAS_PCH_CPT(dev_priv)));
                drm_info(&dev_priv->drm,
                         "LVDS was detected, not registering eDP\n");
@@ -5244,11 +5262,12 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
        if (!has_dpcd) {
                /* if this fails, presume the device is a ghost */
                drm_info(&dev_priv->drm,
-                        "failed to retrieve link info, disabling eDP\n");
+                        "[ENCODER:%d:%s] failed to retrieve link info, disabling eDP\n",
+                        encoder->base.base.id, encoder->base.name);
                goto out_vdd_off;
        }
 
-       mutex_lock(&dev->mode_config.mutex);
+       mutex_lock(&dev_priv->drm.mode_config.mutex);
        edid = drm_get_edid(connector, &intel_dp->aux.ddc);
        if (!edid) {
                /* Fallback to EDID from ACPI OpRegion, if any */
@@ -5273,9 +5292,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
        intel_bios_init_panel(dev_priv, &intel_connector->panel,
                              encoder->devdata, IS_ERR(edid) ? NULL : edid);
 
-       intel_panel_add_edid_fixed_modes(intel_connector,
-                                        intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE,
-                                        intel_vrr_is_capable(intel_connector));
+       intel_panel_add_edid_fixed_modes(intel_connector, true);
 
        /* MSO requires information from the EDID */
        intel_edp_mso_init(intel_dp);
@@ -5288,30 +5305,18 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
        if (!intel_panel_preferred_fixed_mode(intel_connector))
                intel_panel_add_vbt_lfp_fixed_mode(intel_connector);
 
-       mutex_unlock(&dev->mode_config.mutex);
+       mutex_unlock(&dev_priv->drm.mode_config.mutex);
 
-       if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
-               /*
-                * Figure out the current pipe for the initial backlight setup.
-                * If the current pipe isn't valid, try the PPS pipe, and if that
-                * fails just assume pipe A.
-                */
-               pipe = vlv_active_pipe(intel_dp);
-
-               if (pipe != PIPE_A && pipe != PIPE_B)
-                       pipe = intel_dp->pps.pps_pipe;
-
-               if (pipe != PIPE_A && pipe != PIPE_B)
-                       pipe = PIPE_A;
-
-               drm_dbg_kms(&dev_priv->drm,
-                           "using pipe %c for initial backlight setup\n",
-                           pipe_name(pipe));
+       if (!intel_panel_preferred_fixed_mode(intel_connector)) {
+               drm_info(&dev_priv->drm,
+                        "[ENCODER:%d:%s] failed to find fixed mode for the panel, disabling eDP\n",
+                        encoder->base.base.id, encoder->base.name);
+               goto out_vdd_off;
        }
 
        intel_panel_init(intel_connector);
 
-       intel_backlight_setup(intel_connector, pipe);
+       intel_edp_backlight_setup(intel_dp, intel_connector);
 
        intel_edp_add_properties(intel_dp);
 
@@ -5413,7 +5418,6 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
 
        if (!HAS_GMCH(dev_priv))
                connector->interlace_allowed = true;
-       connector->doublescan_allowed = 0;
 
        intel_connector->polled = DRM_CONNECTOR_POLL_HPD;
 
index 8868912..35360dd 100644 (file)
 #include "intel_hdcp.h"
 #include "intel_hdcp_regs.h"
 
-static unsigned int transcoder_to_stream_enc_status(enum transcoder cpu_transcoder)
+static u32 transcoder_to_stream_enc_status(enum transcoder cpu_transcoder)
 {
-       u32 stream_enc_mask;
-
        switch (cpu_transcoder) {
        case TRANSCODER_A:
-               stream_enc_mask = HDCP_STATUS_STREAM_A_ENC;
-               break;
+               return HDCP_STATUS_STREAM_A_ENC;
        case TRANSCODER_B:
-               stream_enc_mask = HDCP_STATUS_STREAM_B_ENC;
-               break;
+               return HDCP_STATUS_STREAM_B_ENC;
        case TRANSCODER_C:
-               stream_enc_mask = HDCP_STATUS_STREAM_C_ENC;
-               break;
+               return HDCP_STATUS_STREAM_C_ENC;
        case TRANSCODER_D:
-               stream_enc_mask = HDCP_STATUS_STREAM_D_ENC;
-               break;
+               return HDCP_STATUS_STREAM_D_ENC;
        default:
-               stream_enc_mask = 0;
+               return 0;
        }
-
-       return stream_enc_mask;
 }
 
 static void intel_dp_hdcp_wait_for_cp_irq(struct intel_hdcp *hdcp, int timeout)
index 03604a3..cd4e610 100644 (file)
@@ -793,7 +793,35 @@ static bool intel_dp_mst_get_hw_state(struct intel_connector *connector)
        return false;
 }
 
-static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port, const char *pathprop)
+static int intel_dp_mst_add_properties(struct intel_dp *intel_dp,
+                                      struct drm_connector *connector,
+                                      const char *pathprop)
+{
+       struct drm_i915_private *i915 = to_i915(connector->dev);
+
+       drm_object_attach_property(&connector->base,
+                                  i915->drm.mode_config.path_property, 0);
+       drm_object_attach_property(&connector->base,
+                                  i915->drm.mode_config.tile_property, 0);
+
+       intel_attach_force_audio_property(connector);
+       intel_attach_broadcast_rgb_property(connector);
+
+       /*
+        * Reuse the prop from the SST connector because we're
+        * not allowed to create new props after device registration.
+        */
+       connector->max_bpc_property =
+               intel_dp->attached_connector->base.max_bpc_property;
+       if (connector->max_bpc_property)
+               drm_connector_attach_max_bpc_property(connector, 6, 12);
+
+       return drm_connector_set_path_property(connector, pathprop);
+}
+
+static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
+                                                       struct drm_dp_mst_port *port,
+                                                       const char *pathprop)
 {
        struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr);
        struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
@@ -833,28 +861,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
                        goto err;
        }
 
-       drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0);
-       drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0);
-
-       ret = drm_connector_set_path_property(connector, pathprop);
+       ret = intel_dp_mst_add_properties(intel_dp, connector, pathprop);
        if (ret)
                goto err;
 
-       intel_attach_force_audio_property(connector);
-       intel_attach_broadcast_rgb_property(connector);
-
        ret = intel_dp_hdcp_init(dig_port, intel_connector);
        if (ret)
                drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP MST init failed, skipping.\n",
                            connector->name, connector->base.id);
-       /*
-        * Reuse the prop from the SST connector because we're
-        * not allowed to create new props after device registration.
-        */
-       connector->max_bpc_property =
-               intel_dp->attached_connector->base.max_bpc_property;
-       if (connector->max_bpc_property)
-               drm_connector_attach_max_bpc_property(connector, 6, 12);
 
        return connector;
 
index e5fb66a..7c6c094 100644 (file)
 
 #include "intel_de.h"
 #include "intel_display_types.h"
+#include "intel_dkl_phy.h"
+#include "intel_dkl_phy_regs.h"
 #include "intel_dpio_phy.h"
 #include "intel_dpll.h"
 #include "intel_dpll_mgr.h"
+#include "intel_mg_phy_regs.h"
 #include "intel_pch_refclk.h"
 #include "intel_tc.h"
-#include "intel_tc_phy_regs.h"
 
 /**
  * DOC: Display PLLs
@@ -152,28 +154,6 @@ intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
        return &dev_priv->display.dpll.shared_dplls[id];
 }
 
-/**
- * intel_get_shared_dpll_id - get the id of a DPLL
- * @dev_priv: i915 device instance
- * @pll: the DPLL
- *
- * Returns:
- * The id of @pll
- */
-enum intel_dpll_id
-intel_get_shared_dpll_id(struct drm_i915_private *dev_priv,
-                        struct intel_shared_dpll *pll)
-{
-       long pll_idx = pll - dev_priv->display.dpll.shared_dplls;
-
-       if (drm_WARN_ON(&dev_priv->drm,
-                       pll_idx < 0 ||
-                       pll_idx >= dev_priv->display.dpll.num_shared_dpll))
-               return -1;
-
-       return pll_idx;
-}
-
 /* For ILK+ */
 void assert_shared_dpll(struct drm_i915_private *dev_priv,
                        struct intel_shared_dpll *pll,
@@ -384,20 +364,30 @@ intel_reference_shared_dpll(struct intel_atomic_state *state,
        if (shared_dpll[id].pipe_mask == 0)
                shared_dpll[id].hw_state = *pll_state;
 
-       drm_dbg(&i915->drm, "using %s for pipe %c\n", pll->info->name,
-               pipe_name(crtc->pipe));
+       drm_WARN_ON(&i915->drm, (shared_dpll[id].pipe_mask & BIT(crtc->pipe)) != 0);
 
        shared_dpll[id].pipe_mask |= BIT(crtc->pipe);
+
+       drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] reserving %s\n",
+                   crtc->base.base.id, crtc->base.name, pll->info->name);
 }
 
 static void intel_unreference_shared_dpll(struct intel_atomic_state *state,
                                          const struct intel_crtc *crtc,
                                          const struct intel_shared_dpll *pll)
 {
+       struct drm_i915_private *i915 = to_i915(state->base.dev);
        struct intel_shared_dpll_state *shared_dpll;
+       const enum intel_dpll_id id = pll->info->id;
 
        shared_dpll = intel_atomic_get_shared_dpll_state(&state->base);
-       shared_dpll[pll->info->id].pipe_mask &= ~BIT(crtc->pipe);
+
+       drm_WARN_ON(&i915->drm, (shared_dpll[id].pipe_mask & BIT(crtc->pipe)) == 0);
+
+       shared_dpll[id].pipe_mask &= ~BIT(crtc->pipe);
+
+       drm_dbg_kms(&i915->drm, "[CRTC:%d:%s] releasing %s\n",
+                   crtc->base.base.id, crtc->base.name, pll->info->name);
 }
 
 static void intel_put_dpll(struct intel_atomic_state *state,
@@ -708,8 +698,6 @@ struct hsw_wrpll_rnp {
 
 static unsigned hsw_wrpll_get_budget_for_freq(int clock)
 {
-       unsigned budget;
-
        switch (clock) {
        case 25175000:
        case 25200000:
@@ -742,21 +730,18 @@ static unsigned hsw_wrpll_get_budget_for_freq(int clock)
        case 222750000:
        case 296703000:
        case 297000000:
-               budget = 0;
-               break;
+               return 0;
        case 233500000:
        case 245250000:
        case 247750000:
        case 253250000:
        case 298000000:
-               budget = 1500;
-               break;
+               return 1500;
        case 169128000:
        case 169500000:
        case 179500000:
        case 202000000:
-               budget = 2000;
-               break;
+               return 2000;
        case 256250000:
        case 262500000:
        case 270000000:
@@ -766,18 +751,13 @@ static unsigned hsw_wrpll_get_budget_for_freq(int clock)
        case 281250000:
        case 286000000:
        case 291750000:
-               budget = 4000;
-               break;
+               return 4000;
        case 267250000:
        case 268500000:
-               budget = 5000;
-               break;
+               return 5000;
        default:
-               budget = 1000;
-               break;
+               return 1000;
        }
-
-       return budget;
 }
 
 static void hsw_wrpll_update_rnp(u64 freq2k, unsigned int budget,
@@ -3508,15 +3488,12 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *dev_priv,
         * All registers read here have the same HIP_INDEX_REG even though
         * they are on different building blocks
         */
-       intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
-                      HIP_INDEX_VAL(tc_port, 0x2));
-
-       hw_state->mg_refclkin_ctl = intel_de_read(dev_priv,
-                                                 DKL_REFCLKIN_CTL(tc_port));
+       hw_state->mg_refclkin_ctl = intel_dkl_phy_read(dev_priv,
+                                                      DKL_REFCLKIN_CTL(tc_port));
        hw_state->mg_refclkin_ctl &= MG_REFCLKIN_CTL_OD_2_MUX_MASK;
 
        hw_state->mg_clktop2_hsclkctl =
-               intel_de_read(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port));
+               intel_dkl_phy_read(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port));
        hw_state->mg_clktop2_hsclkctl &=
                MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
                MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
@@ -3524,32 +3501,32 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *dev_priv,
                MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK;
 
        hw_state->mg_clktop2_coreclkctl1 =
-               intel_de_read(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port));
+               intel_dkl_phy_read(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port));
        hw_state->mg_clktop2_coreclkctl1 &=
                MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
 
-       hw_state->mg_pll_div0 = intel_de_read(dev_priv, DKL_PLL_DIV0(tc_port));
+       hw_state->mg_pll_div0 = intel_dkl_phy_read(dev_priv, DKL_PLL_DIV0(tc_port));
        val = DKL_PLL_DIV0_MASK;
        if (dev_priv->display.vbt.override_afc_startup)
                val |= DKL_PLL_DIV0_AFC_STARTUP_MASK;
        hw_state->mg_pll_div0 &= val;
 
-       hw_state->mg_pll_div1 = intel_de_read(dev_priv, DKL_PLL_DIV1(tc_port));
+       hw_state->mg_pll_div1 = intel_dkl_phy_read(dev_priv, DKL_PLL_DIV1(tc_port));
        hw_state->mg_pll_div1 &= (DKL_PLL_DIV1_IREF_TRIM_MASK |
                                  DKL_PLL_DIV1_TDC_TARGET_CNT_MASK);
 
-       hw_state->mg_pll_ssc = intel_de_read(dev_priv, DKL_PLL_SSC(tc_port));
+       hw_state->mg_pll_ssc = intel_dkl_phy_read(dev_priv, DKL_PLL_SSC(tc_port));
        hw_state->mg_pll_ssc &= (DKL_PLL_SSC_IREF_NDIV_RATIO_MASK |
                                 DKL_PLL_SSC_STEP_LEN_MASK |
                                 DKL_PLL_SSC_STEP_NUM_MASK |
                                 DKL_PLL_SSC_EN);
 
-       hw_state->mg_pll_bias = intel_de_read(dev_priv, DKL_PLL_BIAS(tc_port));
+       hw_state->mg_pll_bias = intel_dkl_phy_read(dev_priv, DKL_PLL_BIAS(tc_port));
        hw_state->mg_pll_bias &= (DKL_PLL_BIAS_FRAC_EN_H |
                                  DKL_PLL_BIAS_FBDIV_FRAC_MASK);
 
        hw_state->mg_pll_tdc_coldst_bias =
-               intel_de_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port));
+               intel_dkl_phy_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port));
        hw_state->mg_pll_tdc_coldst_bias &= (DKL_PLL_TDC_SSC_STEP_SIZE_MASK |
                                             DKL_PLL_TDC_FEED_FWD_GAIN_MASK);
 
@@ -3737,61 +3714,58 @@ static void dkl_pll_write(struct drm_i915_private *dev_priv,
         * All registers programmed here have the same HIP_INDEX_REG even
         * though on different building block
         */
-       intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
-                      HIP_INDEX_VAL(tc_port, 0x2));
-
        /* All the registers are RMW */
-       val = intel_de_read(dev_priv, DKL_REFCLKIN_CTL(tc_port));
+       val = intel_dkl_phy_read(dev_priv, DKL_REFCLKIN_CTL(tc_port));
        val &= ~MG_REFCLKIN_CTL_OD_2_MUX_MASK;
        val |= hw_state->mg_refclkin_ctl;
-       intel_de_write(dev_priv, DKL_REFCLKIN_CTL(tc_port), val);
+       intel_dkl_phy_write(dev_priv, DKL_REFCLKIN_CTL(tc_port), val);
 
-       val = intel_de_read(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port));
+       val = intel_dkl_phy_read(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port));
        val &= ~MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK;
        val |= hw_state->mg_clktop2_coreclkctl1;
-       intel_de_write(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port), val);
+       intel_dkl_phy_write(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port), val);
 
-       val = intel_de_read(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port));
+       val = intel_dkl_phy_read(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port));
        val &= ~(MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK |
                 MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK |
                 MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK |
                 MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK);
        val |= hw_state->mg_clktop2_hsclkctl;
-       intel_de_write(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port), val);
+       intel_dkl_phy_write(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port), val);
 
        val = DKL_PLL_DIV0_MASK;
        if (dev_priv->display.vbt.override_afc_startup)
                val |= DKL_PLL_DIV0_AFC_STARTUP_MASK;
-       intel_de_rmw(dev_priv, DKL_PLL_DIV0(tc_port), val,
-                    hw_state->mg_pll_div0);
+       intel_dkl_phy_rmw(dev_priv, DKL_PLL_DIV0(tc_port), val,
+                         hw_state->mg_pll_div0);
 
-       val = intel_de_read(dev_priv, DKL_PLL_DIV1(tc_port));
+       val = intel_dkl_phy_read(dev_priv, DKL_PLL_DIV1(tc_port));
        val &= ~(DKL_PLL_DIV1_IREF_TRIM_MASK |
                 DKL_PLL_DIV1_TDC_TARGET_CNT_MASK);
        val |= hw_state->mg_pll_div1;
-       intel_de_write(dev_priv, DKL_PLL_DIV1(tc_port), val);
+       intel_dkl_phy_write(dev_priv, DKL_PLL_DIV1(tc_port), val);
 
-       val = intel_de_read(dev_priv, DKL_PLL_SSC(tc_port));
+       val = intel_dkl_phy_read(dev_priv, DKL_PLL_SSC(tc_port));
        val &= ~(DKL_PLL_SSC_IREF_NDIV_RATIO_MASK |
                 DKL_PLL_SSC_STEP_LEN_MASK |
                 DKL_PLL_SSC_STEP_NUM_MASK |
                 DKL_PLL_SSC_EN);
        val |= hw_state->mg_pll_ssc;
-       intel_de_write(dev_priv, DKL_PLL_SSC(tc_port), val);
+       intel_dkl_phy_write(dev_priv, DKL_PLL_SSC(tc_port), val);
 
-       val = intel_de_read(dev_priv, DKL_PLL_BIAS(tc_port));
+       val = intel_dkl_phy_read(dev_priv, DKL_PLL_BIAS(tc_port));
        val &= ~(DKL_PLL_BIAS_FRAC_EN_H |
                 DKL_PLL_BIAS_FBDIV_FRAC_MASK);
        val |= hw_state->mg_pll_bias;
-       intel_de_write(dev_priv, DKL_PLL_BIAS(tc_port), val);
+       intel_dkl_phy_write(dev_priv, DKL_PLL_BIAS(tc_port), val);
 
-       val = intel_de_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port));
+       val = intel_dkl_phy_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port));
        val &= ~(DKL_PLL_TDC_SSC_STEP_SIZE_MASK |
                 DKL_PLL_TDC_FEED_FWD_GAIN_MASK);
        val |= hw_state->mg_pll_tdc_coldst_bias;
-       intel_de_write(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port), val);
+       intel_dkl_phy_write(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port), val);
 
-       intel_de_posting_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port));
+       intel_dkl_phy_posting_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port));
 }
 
 static void icl_pll_power_enable(struct drm_i915_private *dev_priv,
@@ -4193,6 +4167,8 @@ void intel_shared_dpll_init(struct drm_i915_private *dev_priv)
        const struct dpll_info *dpll_info;
        int i;
 
+       mutex_init(&dev_priv->display.dpll.lock);
+
        if (IS_DG2(dev_priv))
                /* No shared DPLLs on DG2; port PLLs are part of the PHY */
                dpll_mgr = NULL;
@@ -4237,7 +4213,6 @@ void intel_shared_dpll_init(struct drm_i915_private *dev_priv)
 
        dev_priv->display.dpll.mgr = dpll_mgr;
        dev_priv->display.dpll.num_shared_dpll = i;
-       mutex_init(&dev_priv->display.dpll.lock);
 }
 
 /**
index 3247dc3..3854f1b 100644 (file)
@@ -328,9 +328,6 @@ struct intel_shared_dpll {
 struct intel_shared_dpll *
 intel_get_shared_dpll_by_id(struct drm_i915_private *dev_priv,
                            enum intel_dpll_id id);
-enum intel_dpll_id
-intel_get_shared_dpll_id(struct drm_i915_private *dev_priv,
-                        struct intel_shared_dpll *pll);
 void assert_shared_dpll(struct drm_i915_private *dev_priv,
                        struct intel_shared_dpll *pll,
                        bool state);
index 7da4a9c..e27408e 100644 (file)
@@ -284,16 +284,124 @@ void intel_drrs_flush(struct drm_i915_private *dev_priv,
 }
 
 /**
- * intel_crtc_drrs_init - Init DRRS for CRTC
+ * intel_drrs_crtc_init - Init DRRS for CRTC
  * @crtc: crtc
  *
  * This function is called only once at driver load to initialize basic
  * DRRS stuff.
  *
  */
-void intel_crtc_drrs_init(struct intel_crtc *crtc)
+void intel_drrs_crtc_init(struct intel_crtc *crtc)
 {
        INIT_DELAYED_WORK(&crtc->drrs.work, intel_drrs_downclock_work);
        mutex_init(&crtc->drrs.mutex);
        crtc->drrs.cpu_transcoder = INVALID_TRANSCODER;
 }
+
+static int intel_drrs_debugfs_status_show(struct seq_file *m, void *unused)
+{
+       struct intel_crtc *crtc = m->private;
+       const struct intel_crtc_state *crtc_state;
+       int ret;
+
+       ret = drm_modeset_lock_single_interruptible(&crtc->base.mutex);
+       if (ret)
+               return ret;
+
+       crtc_state = to_intel_crtc_state(crtc->base.state);
+
+       mutex_lock(&crtc->drrs.mutex);
+
+       seq_printf(m, "DRRS enabled: %s\n",
+                  str_yes_no(crtc_state->has_drrs));
+
+       seq_printf(m, "DRRS active: %s\n",
+                  str_yes_no(intel_drrs_is_active(crtc)));
+
+       seq_printf(m, "DRRS refresh rate: %s\n",
+                  crtc->drrs.refresh_rate == DRRS_REFRESH_RATE_LOW ?
+                  "low" : "high");
+
+       seq_printf(m, "DRRS busy frontbuffer bits: 0x%x\n",
+                  crtc->drrs.busy_frontbuffer_bits);
+
+       mutex_unlock(&crtc->drrs.mutex);
+
+       drm_modeset_unlock(&crtc->base.mutex);
+
+       return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(intel_drrs_debugfs_status);
+
+static int intel_drrs_debugfs_ctl_set(void *data, u64 val)
+{
+       struct intel_crtc *crtc = data;
+       struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+       struct intel_crtc_state *crtc_state;
+       struct drm_crtc_commit *commit;
+       int ret;
+
+       ret = drm_modeset_lock_single_interruptible(&crtc->base.mutex);
+       if (ret)
+               return ret;
+
+       crtc_state = to_intel_crtc_state(crtc->base.state);
+
+       if (!crtc_state->hw.active ||
+           !crtc_state->has_drrs)
+               goto out;
+
+       commit = crtc_state->uapi.commit;
+       if (commit) {
+               ret = wait_for_completion_interruptible(&commit->hw_done);
+               if (ret)
+                       goto out;
+       }
+
+       drm_dbg(&i915->drm,
+               "Manually %sactivating DRRS\n", val ? "" : "de");
+
+       if (val)
+               intel_drrs_activate(crtc_state);
+       else
+               intel_drrs_deactivate(crtc_state);
+
+out:
+       drm_modeset_unlock(&crtc->base.mutex);
+
+       return ret;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(intel_drrs_debugfs_ctl_fops,
+                       NULL, intel_drrs_debugfs_ctl_set, "%llu\n");
+
+void intel_drrs_crtc_debugfs_add(struct intel_crtc *crtc)
+{
+       debugfs_create_file("i915_drrs_status", 0444, crtc->base.debugfs_entry,
+                           crtc, &intel_drrs_debugfs_status_fops);
+
+       debugfs_create_file("i915_drrs_ctl", 0644, crtc->base.debugfs_entry,
+                           crtc, &intel_drrs_debugfs_ctl_fops);
+}
+
+static int intel_drrs_debugfs_type_show(struct seq_file *m, void *unused)
+{
+       struct intel_connector *connector = m->private;
+
+       seq_printf(m, "DRRS type: %s\n",
+                  intel_drrs_type_str(intel_panel_drrs_type(connector)));
+
+       return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(intel_drrs_debugfs_type);
+
+void intel_drrs_connector_debugfs_add(struct intel_connector *connector)
+{
+       if (intel_panel_drrs_type(connector) == DRRS_TYPE_NONE)
+               return;
+
+       debugfs_create_file("i915_drrs_type", 0444, connector->base.debugfs_entry,
+                           connector, &intel_drrs_debugfs_type_fops);
+}
index 3ad1be1..8ef5f93 100644 (file)
@@ -23,6 +23,8 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv,
                           unsigned int frontbuffer_bits);
 void intel_drrs_flush(struct drm_i915_private *dev_priv,
                      unsigned int frontbuffer_bits);
-void intel_crtc_drrs_init(struct intel_crtc *crtc);
+void intel_drrs_crtc_init(struct intel_crtc *crtc);
+void intel_drrs_crtc_debugfs_add(struct intel_crtc *crtc);
+void intel_drrs_connector_debugfs_add(struct intel_connector *connector);
 
 #endif /* __INTEL_DRRS_H__ */
index 5572e43..5950872 100644 (file)
@@ -491,8 +491,8 @@ void intel_dvo_init(struct drm_i915_private *dev_priv)
                intel_encoder->pipe_mask = ~0;
 
                if (dvo->type != INTEL_DVO_CHIP_LVDS)
-                       intel_encoder->cloneable = (1 << INTEL_OUTPUT_ANALOG) |
-                               (1 << INTEL_OUTPUT_DVO);
+                       intel_encoder->cloneable = BIT(INTEL_OUTPUT_ANALOG) |
+                               BIT(INTEL_OUTPUT_DVO);
 
                switch (dvo->type) {
                case INTEL_DVO_CHIP_TMDS:
@@ -515,8 +515,6 @@ void intel_dvo_init(struct drm_i915_private *dev_priv)
                drm_connector_helper_add(connector,
                                         &intel_dvo_connector_helper_funcs);
                connector->display_info.subpixel_order = SubPixelHorizontalRGB;
-               connector->interlace_allowed = false;
-               connector->doublescan_allowed = false;
 
                intel_connector_attach_encoder(intel_connector, intel_encoder);
                if (dvo->type == INTEL_DVO_CHIP_LVDS) {
index eefa33c..63137ae 100644 (file)
@@ -301,6 +301,19 @@ static bool plane_caps_contain_all(u8 caps, u8 mask)
 }
 
 /**
+ * intel_fb_is_tiled_modifier: Check if a modifier is a tiled modifier type
+ * @modifier: Modifier to check
+ *
+ * Returns:
+ * Returns %true if @modifier is a tiled modifier.
+ */
+bool intel_fb_is_tiled_modifier(u64 modifier)
+{
+       return plane_caps_contain_any(lookup_modifier(modifier)->plane_caps,
+                                     INTEL_PLANE_CAP_TILING_MASK);
+}
+
+/**
  * intel_fb_is_ccs_modifier: Check if a modifier is a CCS modifier type
  * @modifier: Modifier to check
  *
index 12386f1..4662b81 100644 (file)
@@ -29,6 +29,7 @@ struct intel_plane_state;
 #define INTEL_PLANE_CAP_TILING_Yf      BIT(5)
 #define INTEL_PLANE_CAP_TILING_4       BIT(6)
 
+bool intel_fb_is_tiled_modifier(u64 modifier);
 bool intel_fb_is_ccs_modifier(u64 modifier);
 bool intel_fb_is_rc_ccs_cc_modifier(u64 modifier);
 bool intel_fb_is_mc_ccs_modifier(u64 modifier);
index f381753..3f24f32 100644 (file)
@@ -670,6 +670,7 @@ static void intel_fbc_nuke(struct intel_fbc *fbc)
 {
        struct drm_i915_private *i915 = fbc->i915;
 
+       lockdep_assert_held(&fbc->lock);
        drm_WARN_ON(&i915->drm, fbc->flip_pending);
 
        trace_intel_fbc_nuke(fbc->state.plane);
@@ -679,6 +680,8 @@ static void intel_fbc_nuke(struct intel_fbc *fbc)
 
 static void intel_fbc_activate(struct intel_fbc *fbc)
 {
+       lockdep_assert_held(&fbc->lock);
+
        intel_fbc_hw_activate(fbc);
        intel_fbc_nuke(fbc);
 
@@ -687,9 +690,7 @@ static void intel_fbc_activate(struct intel_fbc *fbc)
 
 static void intel_fbc_deactivate(struct intel_fbc *fbc, const char *reason)
 {
-       struct drm_i915_private *i915 = fbc->i915;
-
-       drm_WARN_ON(&i915->drm, !mutex_is_locked(&fbc->lock));
+       lockdep_assert_held(&fbc->lock);
 
        if (fbc->active)
                intel_fbc_hw_deactivate(fbc);
@@ -1009,7 +1010,8 @@ static bool intel_fbc_is_fence_ok(const struct intel_plane_state *plane_state)
 {
        struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
 
-       /* The use of a CPU fence is one of two ways to detect writes by the
+       /*
+        * The use of a CPU fence is one of two ways to detect writes by the
         * CPU to the scanout and trigger updates to the FBC.
         *
         * The other method is by software tracking (see
@@ -1019,12 +1021,6 @@ static bool intel_fbc_is_fence_ok(const struct intel_plane_state *plane_state)
         * Note that is possible for a tiled surface to be unmappable (and
         * so have no fence associated with it) due to aperture constraints
         * at the time of pinning.
-        *
-        * FIXME with 90/270 degree rotation we should use the fence on
-        * the normal GTT view (the rotated view doesn't even have a
-        * fence). Would need changes to the FBC fence Y offset as well.
-        * For now this will effectively disable FBC with 90/270 degree
-        * rotation.
         */
        return DISPLAY_VER(i915) >= 9 ||
                (plane_state->flags & PLANE_HAS_FENCE &&
@@ -1227,6 +1223,8 @@ static bool __intel_fbc_pre_update(struct intel_atomic_state *state,
        struct intel_fbc *fbc = plane->fbc;
        bool need_vblank_wait = false;
 
+       lockdep_assert_held(&fbc->lock);
+
        fbc->flip_pending = true;
 
        if (intel_fbc_can_flip_nuke(state, crtc, plane))
@@ -1284,7 +1282,7 @@ static void __intel_fbc_disable(struct intel_fbc *fbc)
        struct drm_i915_private *i915 = fbc->i915;
        struct intel_plane *plane = fbc->state.plane;
 
-       drm_WARN_ON(&i915->drm, !mutex_is_locked(&fbc->lock));
+       lockdep_assert_held(&fbc->lock);
        drm_WARN_ON(&i915->drm, fbc->active);
 
        drm_dbg_kms(&i915->drm, "Disabling FBC on [PLANE:%d:%s]\n",
@@ -1299,9 +1297,9 @@ static void __intel_fbc_disable(struct intel_fbc *fbc)
 
 static void __intel_fbc_post_update(struct intel_fbc *fbc)
 {
-       struct drm_i915_private *i915 = fbc->i915;
+       lockdep_assert_held(&fbc->lock);
 
-       drm_WARN_ON(&i915->drm, !mutex_is_locked(&fbc->lock));
+       fbc->flip_pending = false;
 
        if (!fbc->busy_bits)
                intel_fbc_activate(fbc);
@@ -1324,10 +1322,8 @@ void intel_fbc_post_update(struct intel_atomic_state *state,
 
                mutex_lock(&fbc->lock);
 
-               if (fbc->state.plane == plane) {
-                       fbc->flip_pending = false;
+               if (fbc->state.plane == plane)
                        __intel_fbc_post_update(fbc);
-               }
 
                mutex_unlock(&fbc->lock);
        }
@@ -1437,6 +1433,8 @@ static void __intel_fbc_enable(struct intel_atomic_state *state,
                intel_atomic_get_new_plane_state(state, plane);
        struct intel_fbc *fbc = plane->fbc;
 
+       lockdep_assert_held(&fbc->lock);
+
        if (fbc->state.plane) {
                if (fbc->state.plane != plane)
                        return;
@@ -1522,7 +1520,8 @@ void intel_fbc_update(struct intel_atomic_state *state,
 
                mutex_lock(&fbc->lock);
 
-               if (crtc_state->update_pipe && plane_state->no_fbc_reason) {
+               if (intel_crtc_needs_fastset(crtc_state) &&
+                   plane_state->no_fbc_reason) {
                        if (fbc->state.plane == plane)
                                __intel_fbc_disable(fbc);
                } else {
index 112aa04..ab385d1 100644 (file)
@@ -175,7 +175,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
        }
 
        if (IS_ERR(obj)) {
-               drm_err(&dev_priv->drm, "failed to allocate framebuffer\n");
+               drm_err(&dev_priv->drm, "failed to allocate framebuffer (%pe)\n", obj);
                return PTR_ERR(obj);
        }
 
@@ -256,7 +256,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
 
        info = drm_fb_helper_alloc_fbi(helper);
        if (IS_ERR(info)) {
-               drm_err(&dev_priv->drm, "Failed to allocate fb_info\n");
+               drm_err(&dev_priv->drm, "Failed to allocate fb_info (%pe)\n", info);
                ret = PTR_ERR(info);
                goto out_unpin;
        }
@@ -291,7 +291,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
        vaddr = i915_vma_pin_iomap(vma);
        if (IS_ERR(vaddr)) {
                drm_err(&dev_priv->drm,
-                       "Failed to remap framebuffer into virtual memory\n");
+                       "Failed to remap framebuffer into virtual memory (%pe)\n", vaddr);
                ret = PTR_ERR(vaddr);
                goto out_unpin;
        }
index 18451f5..02f8374 100644 (file)
@@ -2950,9 +2950,8 @@ void intel_hdmi_init_connector(struct intel_digital_port *dig_port,
                                    ddc);
        drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
 
-       connector->interlace_allowed = 1;
-       connector->doublescan_allowed = 0;
-       connector->stereo_allowed = 1;
+       connector->interlace_allowed = true;
+       connector->stereo_allowed = true;
 
        if (DISPLAY_VER(dev_priv) >= 10)
                connector->ycbcr_420_allowed = true;
index f7a2f48..907ab75 100644 (file)
@@ -90,6 +90,9 @@ enum hpd_pin intel_hpd_pin_default(struct drm_i915_private *dev_priv,
        return HPD_PORT_A + port - PORT_A;
 }
 
+/* Threshold == 5 for long IRQs, 50 for short */
+#define HPD_STORM_DEFAULT_THRESHOLD    50
+
 #define HPD_STORM_DETECT_PERIOD                1000
 #define HPD_STORM_REENABLE_DELAY       (2 * 60 * 1000)
 #define HPD_RETRY_DELAY                        1000
@@ -175,14 +178,13 @@ static bool intel_hpd_irq_storm_detect(struct drm_i915_private *dev_priv,
 static void
 intel_hpd_irq_storm_switch_to_polling(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = &dev_priv->drm;
        struct drm_connector_list_iter conn_iter;
        struct intel_connector *connector;
        bool hpd_disabled = false;
 
        lockdep_assert_held(&dev_priv->irq_lock);
 
-       drm_connector_list_iter_begin(dev, &conn_iter);
+       drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
        for_each_intel_connector_iter(connector, &conn_iter) {
                enum hpd_pin pin;
 
@@ -208,7 +210,7 @@ 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_enable(dev);
+               drm_kms_helper_poll_enable(&dev_priv->drm);
                mod_delayed_work(system_wq, &dev_priv->display.hotplug.reenable_work,
                                 msecs_to_jiffies(HPD_STORM_REENABLE_DELAY));
        }
@@ -219,7 +221,6 @@ 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 drm_device *dev = &dev_priv->drm;
        struct drm_connector_list_iter conn_iter;
        struct intel_connector *connector;
        intel_wakeref_t wakeref;
@@ -229,7 +230,7 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
 
        spin_lock_irq(&dev_priv->irq_lock);
 
-       drm_connector_list_iter_begin(dev, &conn_iter);
+       drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
        for_each_intel_connector_iter(connector, &conn_iter) {
                pin = intel_connector_hpd_pin(connector);
                if (pin == HPD_NONE ||
@@ -367,14 +368,13 @@ 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 drm_device *dev = &dev_priv->drm;
        struct drm_connector_list_iter conn_iter;
        struct intel_connector *connector;
        u32 changed = 0, retry = 0;
        u32 hpd_event_bits;
        u32 hpd_retry_bits;
 
-       mutex_lock(&dev->mode_config.mutex);
+       mutex_lock(&dev_priv->drm.mode_config.mutex);
        drm_dbg_kms(&dev_priv->drm, "running encoder hotplug functions\n");
 
        spin_lock_irq(&dev_priv->irq_lock);
@@ -389,7 +389,7 @@ static void i915_hotplug_work_func(struct work_struct *work)
 
        spin_unlock_irq(&dev_priv->irq_lock);
 
-       drm_connector_list_iter_begin(dev, &conn_iter);
+       drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
        for_each_intel_connector_iter(connector, &conn_iter) {
                enum hpd_pin pin;
                u32 hpd_bit;
@@ -426,10 +426,10 @@ static void i915_hotplug_work_func(struct work_struct *work)
                }
        }
        drm_connector_list_iter_end(&conn_iter);
-       mutex_unlock(&dev->mode_config.mutex);
+       mutex_unlock(&dev_priv->drm.mode_config.mutex);
 
        if (changed)
-               drm_kms_helper_hotplug_event(dev);
+               drm_kms_helper_hotplug_event(&dev_priv->drm);
 
        /* Remove shared HPD pins that have changed */
        retry &= ~changed;
@@ -612,16 +612,15 @@ 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 drm_device *dev = &dev_priv->drm;
        struct drm_connector_list_iter conn_iter;
        struct intel_connector *connector;
        bool enabled;
 
-       mutex_lock(&dev->mode_config.mutex);
+       mutex_lock(&dev_priv->drm.mode_config.mutex);
 
        enabled = READ_ONCE(dev_priv->display.hotplug.poll_enabled);
 
-       drm_connector_list_iter_begin(dev, &conn_iter);
+       drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
        for_each_intel_connector_iter(connector, &conn_iter) {
                enum hpd_pin pin;
 
@@ -638,16 +637,16 @@ static void i915_hpd_poll_init_work(struct work_struct *work)
        drm_connector_list_iter_end(&conn_iter);
 
        if (enabled)
-               drm_kms_helper_poll_enable(dev);
+               drm_kms_helper_poll_enable(&dev_priv->drm);
 
-       mutex_unlock(&dev->mode_config.mutex);
+       mutex_unlock(&dev_priv->drm.mode_config.mutex);
 
        /*
         * We might have missed any hotplugs that happened while we were
         * in the middle of disabling polling
         */
        if (!enabled)
-               drm_helper_hpd_irq_event(dev);
+               drm_helper_hpd_irq_event(&dev_priv->drm);
 }
 
 /**
@@ -711,14 +710,23 @@ void intel_hpd_poll_disable(struct drm_i915_private *dev_priv)
        schedule_work(&dev_priv->display.hotplug.poll_init_work);
 }
 
-void intel_hpd_init_work(struct drm_i915_private *dev_priv)
+void intel_hpd_init_early(struct drm_i915_private *i915)
 {
-       INIT_DELAYED_WORK(&dev_priv->display.hotplug.hotplug_work,
+       INIT_DELAYED_WORK(&i915->display.hotplug.hotplug_work,
                          i915_hotplug_work_func);
-       INIT_WORK(&dev_priv->display.hotplug.dig_port_work, i915_digport_work_func);
-       INIT_WORK(&dev_priv->display.hotplug.poll_init_work, i915_hpd_poll_init_work);
-       INIT_DELAYED_WORK(&dev_priv->display.hotplug.reenable_work,
+       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,
                          intel_hpd_irq_storm_reenable_work);
+
+       i915->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);
 }
 
 void intel_hpd_cancel_work(struct drm_i915_private *dev_priv)
@@ -767,3 +775,169 @@ void intel_hpd_enable(struct drm_i915_private *dev_priv, enum hpd_pin pin)
        dev_priv->display.hotplug.stats[pin].state = HPD_ENABLED;
        spin_unlock_irq(&dev_priv->irq_lock);
 }
+
+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;
+
+       /* 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);
+
+       seq_printf(m, "Threshold: %d\n", hotplug->hpd_storm_threshold);
+       seq_printf(m, "Detected: %s\n",
+                  str_yes_no(delayed_work_pending(&hotplug->reenable_work)));
+
+       return 0;
+}
+
+static ssize_t i915_hpd_storm_ctl_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_hotplug *hotplug = &dev_priv->display.hotplug;
+       unsigned int new_threshold;
+       int i;
+       char *newline;
+       char tmp[16];
+
+       if (len >= sizeof(tmp))
+               return -EINVAL;
+
+       if (copy_from_user(tmp, ubuf, len))
+               return -EFAULT;
+
+       tmp[len] = '\0';
+
+       /* Strip newline, if any */
+       newline = strchr(tmp, '\n');
+       if (newline)
+               *newline = '\0';
+
+       if (strcmp(tmp, "reset") == 0)
+               new_threshold = HPD_STORM_DEFAULT_THRESHOLD;
+       else if (kstrtouint(tmp, 10, &new_threshold) != 0)
+               return -EINVAL;
+
+       if (new_threshold > 0)
+               drm_dbg_kms(&dev_priv->drm,
+                           "Setting HPD storm detection threshold to %d\n",
+                           new_threshold);
+       else
+               drm_dbg_kms(&dev_priv->drm, "Disabling HPD storm detection\n");
+
+       spin_lock_irq(&dev_priv->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);
+
+       /* Re-enable hpd immediately if we were in an irq storm */
+       flush_delayed_work(&dev_priv->display.hotplug.reenable_work);
+
+       return len;
+}
+
+static int i915_hpd_storm_ctl_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, i915_hpd_storm_ctl_show, inode->i_private);
+}
+
+static const struct file_operations i915_hpd_storm_ctl_fops = {
+       .owner = THIS_MODULE,
+       .open = i915_hpd_storm_ctl_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+       .write = i915_hpd_storm_ctl_write
+};
+
+static int i915_hpd_short_storm_ctl_show(struct seq_file *m, void *data)
+{
+       struct drm_i915_private *dev_priv = m->private;
+
+       seq_printf(m, "Enabled: %s\n",
+                  str_yes_no(dev_priv->display.hotplug.hpd_short_storm_enabled));
+
+       return 0;
+}
+
+static int
+i915_hpd_short_storm_ctl_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, i915_hpd_short_storm_ctl_show,
+                          inode->i_private);
+}
+
+static ssize_t i915_hpd_short_storm_ctl_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_hotplug *hotplug = &dev_priv->display.hotplug;
+       char *newline;
+       char tmp[16];
+       int i;
+       bool new_state;
+
+       if (len >= sizeof(tmp))
+               return -EINVAL;
+
+       if (copy_from_user(tmp, ubuf, len))
+               return -EFAULT;
+
+       tmp[len] = '\0';
+
+       /* Strip newline, if any */
+       newline = strchr(tmp, '\n');
+       if (newline)
+               *newline = '\0';
+
+       /* Reset to the "default" state for this system */
+       if (strcmp(tmp, "reset") == 0)
+               new_state = !HAS_DP_MST(dev_priv);
+       else if (kstrtobool(tmp, &new_state) != 0)
+               return -EINVAL;
+
+       drm_dbg_kms(&dev_priv->drm, "%sabling HPD short storm detection\n",
+                   new_state ? "En" : "Dis");
+
+       spin_lock_irq(&dev_priv->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);
+
+       /* Re-enable hpd immediately if we were in an irq storm */
+       flush_delayed_work(&dev_priv->display.hotplug.reenable_work);
+
+       return len;
+}
+
+static const struct file_operations i915_hpd_short_storm_ctl_fops = {
+       .owner = THIS_MODULE,
+       .open = i915_hpd_short_storm_ctl_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+       .write = i915_hpd_short_storm_ctl_write,
+};
+
+void intel_hpd_debugfs_register(struct drm_i915_private *i915)
+{
+       struct drm_minor *minor = i915->drm.primary;
+
+       debugfs_create_file("i915_hpd_storm_ctl", 0644, minor->debugfs_root,
+                           i915, &i915_hpd_storm_ctl_fops);
+       debugfs_create_file("i915_hpd_short_storm_ctl", 0644, minor->debugfs_root,
+                           i915, &i915_hpd_short_storm_ctl_fops);
+}
index b87e95d..424ae5d 100644 (file)
@@ -22,11 +22,12 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
                           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_work(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);
 enum hpd_pin intel_hpd_pin_default(struct drm_i915_private *dev_priv,
                                   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);
 
 #endif /* __INTEL_HOTPLUG_H__ */
index dca6003..6a7ac60 100644 (file)
@@ -80,8 +80,7 @@
 static struct platform_device *
 lpe_audio_platdev_create(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = &dev_priv->drm;
-       struct pci_dev *pdev = to_pci_dev(dev->dev);
+       struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
        struct platform_device_info pinfo = {};
        struct resource *rsc;
        struct platform_device *platdev;
@@ -108,7 +107,7 @@ lpe_audio_platdev_create(struct drm_i915_private *dev_priv)
        rsc[1].flags    = IORESOURCE_MEM;
        rsc[1].name     = "hdmi-lpe-audio-mmio";
 
-       pinfo.parent = dev->dev;
+       pinfo.parent = dev_priv->drm.dev;
        pinfo.name = "hdmi-lpe-audio";
        pinfo.id = -1;
        pinfo.res = rsc;
index 9aa38e8..246787b 100644 (file)
@@ -78,9 +78,9 @@ struct intel_lvds_encoder {
        struct intel_connector *attached_connector;
 };
 
-static struct intel_lvds_encoder *to_lvds_encoder(struct drm_encoder *encoder)
+static struct intel_lvds_encoder *to_lvds_encoder(struct intel_encoder *encoder)
 {
-       return container_of(encoder, struct intel_lvds_encoder, base.base);
+       return container_of(encoder, struct intel_lvds_encoder, base);
 }
 
 bool intel_lvds_port_enabled(struct drm_i915_private *dev_priv,
@@ -103,7 +103,7 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder,
                                    enum pipe *pipe)
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-       struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
+       struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
        intel_wakeref_t wakeref;
        bool ret;
 
@@ -123,7 +123,7 @@ static void intel_lvds_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_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
+       struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
        u32 tmp, flags = 0;
 
        pipe_config->output_types |= BIT(INTEL_OUTPUT_LVDS);
@@ -229,7 +229,7 @@ static void intel_pre_enable_lvds(struct intel_atomic_state *state,
                                  const struct intel_crtc_state *pipe_config,
                                  const struct drm_connector_state *conn_state)
 {
-       struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
+       struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
        const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
@@ -312,7 +312,7 @@ static void intel_enable_lvds(struct intel_atomic_state *state,
                              const struct drm_connector_state *conn_state)
 {
        struct drm_device *dev = encoder->base.dev;
-       struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
+       struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
        struct drm_i915_private *dev_priv = to_i915(dev);
 
        intel_de_write(dev_priv, lvds_encoder->reg,
@@ -334,7 +334,7 @@ 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_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
+       struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(encoder);
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 
        intel_de_write(dev_priv, PP_CONTROL(0),
@@ -413,7 +413,7 @@ static int intel_lvds_compute_config(struct intel_encoder *intel_encoder,
 {
        struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
        struct intel_lvds_encoder *lvds_encoder =
-               to_lvds_encoder(&intel_encoder->base);
+               to_lvds_encoder(intel_encoder);
        struct intel_connector *intel_connector =
                lvds_encoder->attached_connector;
        struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
@@ -775,7 +775,7 @@ bool intel_is_dual_link_lvds(struct drm_i915_private *dev_priv)
 {
        struct intel_encoder *encoder = intel_get_lvds_encoder(dev_priv);
 
-       return encoder && to_lvds_encoder(&encoder->base)->is_dual_link;
+       return encoder && to_lvds_encoder(encoder)->is_dual_link;
 }
 
 static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder)
@@ -814,6 +814,11 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder)
        return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP;
 }
 
+static void intel_lvds_add_properties(struct drm_connector *connector)
+{
+       intel_attach_scaling_mode_property(connector);
+}
+
 /**
  * intel_lvds_init - setup LVDS connectors on this device
  * @dev_priv: i915 device
@@ -823,7 +828,6 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder)
  */
 void intel_lvds_init(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = &dev_priv->drm;
        struct intel_lvds_encoder *lvds_encoder;
        struct intel_encoder *intel_encoder;
        struct intel_connector *intel_connector;
@@ -833,11 +837,10 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
        i915_reg_t lvds_reg;
        u32 lvds;
        u8 pin;
-       u32 allowed_scalers;
 
        /* Skip init on machines we know falsely report LVDS */
        if (dmi_check_system(intel_no_lvds)) {
-               drm_WARN(dev, !dev_priv->display.vbt.int_lvds_support,
+               drm_WARN(&dev_priv->drm, !dev_priv->display.vbt.int_lvds_support,
                         "Useless DMI match. Internal LVDS support disabled by VBT\n");
                return;
        }
@@ -886,10 +889,10 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
        intel_encoder = &lvds_encoder->base;
        encoder = &intel_encoder->base;
        connector = &intel_connector->base;
-       drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs,
+       drm_connector_init(&dev_priv->drm, &intel_connector->base, &intel_lvds_connector_funcs,
                           DRM_MODE_CONNECTOR_LVDS);
 
-       drm_encoder_init(dev, &intel_encoder->base, &intel_lvds_enc_funcs,
+       drm_encoder_init(&dev_priv->drm, &intel_encoder->base, &intel_lvds_enc_funcs,
                         DRM_MODE_ENCODER_LVDS, "LVDS");
 
        intel_encoder->enable = intel_enable_lvds;
@@ -920,17 +923,10 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
 
        drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
        connector->display_info.subpixel_order = SubPixelHorizontalRGB;
-       connector->interlace_allowed = false;
-       connector->doublescan_allowed = false;
 
        lvds_encoder->reg = lvds_reg;
 
-       /* create the scaling mode property */
-       allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT);
-       allowed_scalers |= BIT(DRM_MODE_SCALE_FULLSCREEN);
-       allowed_scalers |= BIT(DRM_MODE_SCALE_CENTER);
-       drm_connector_attach_scaling_mode_property(connector, allowed_scalers);
-       connector->state->scaling_mode = DRM_MODE_SCALE_ASPECT;
+       intel_lvds_add_properties(connector);
 
        intel_lvds_pps_get_hw_state(dev_priv, &lvds_encoder->init_pps);
        lvds_encoder->init_lvds_val = lvds;
@@ -947,7 +943,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
         * Attempt to get the fixed panel mode from DDC.  Assume that the
         * preferred mode is the right one.
         */
-       mutex_lock(&dev->mode_config.mutex);
+       mutex_lock(&dev_priv->drm.mode_config.mutex);
        if (vga_switcheroo_handler_flags() & VGA_SWITCHEROO_CAN_SWITCH_DDC)
                edid = drm_get_edid_switcheroo(connector,
                                    intel_gmbus_get_adapter(dev_priv, pin));
@@ -971,9 +967,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
                              IS_ERR(edid) ? NULL : edid);
 
        /* Try EDID first */
-       intel_panel_add_edid_fixed_modes(intel_connector,
-                                        intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE,
-                                        false);
+       intel_panel_add_edid_fixed_modes(intel_connector, true);
 
        /* Failed to get EDID, what about VBT? */
        if (!intel_panel_preferred_fixed_mode(intel_connector))
@@ -987,7 +981,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
        if (!intel_panel_preferred_fixed_mode(intel_connector))
                intel_panel_add_encoder_fixed_mode(intel_connector, intel_encoder);
 
-       mutex_unlock(&dev->mode_config.mutex);
+       mutex_unlock(&dev_priv->drm.mode_config.mutex);
 
        /* If we still don't have a mode after all that, give up. */
        if (!intel_panel_preferred_fixed_mode(intel_connector))
@@ -3,8 +3,8 @@
  * Copyright Â© 2022 Intel Corporation
  */
 
-#ifndef __INTEL_TC_PHY_REGS__
-#define __INTEL_TC_PHY_REGS__
+#ifndef __INTEL_MG_PHY_REGS__
+#define __INTEL_MG_PHY_REGS__
 
 #include "i915_reg_defs.h"
 
                                                   _MG_PLL_TDC_COLDST_BIAS_PORT1, \
                                                   _MG_PLL_TDC_COLDST_BIAS_PORT2)
 
-#endif /* __INTEL_TC_PHY_REGS__ */
+#endif /* __INTEL_MG_PHY_REGS__ */
index cbfabd5..9d8ca23 100644 (file)
@@ -155,6 +155,12 @@ 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;
 
+       /* assume 1:1 mapping */
+       drm_property_replace_blob(&crtc_state->hw.degamma_lut,
+                                 crtc_state->pre_csc_lut);
+       drm_property_replace_blob(&crtc_state->hw.gamma_lut,
+                                 crtc_state->post_csc_lut);
+
        drm_property_replace_blob(&crtc_state->uapi.degamma_lut,
                                  crtc_state->hw.degamma_lut);
        drm_property_replace_blob(&crtc_state->uapi.gamma_lut,
@@ -205,13 +211,21 @@ static bool intel_crtc_has_encoders(struct intel_crtc *crtc)
 
 static struct intel_connector *intel_encoder_find_connector(struct intel_encoder *encoder)
 {
-       struct drm_device *dev = encoder->base.dev;
+       struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+       struct drm_connector_list_iter conn_iter;
        struct intel_connector *connector;
+       struct intel_connector *found_connector = NULL;
 
-       for_each_connector_on_encoder(dev, &encoder->base, connector)
-               return connector;
+       drm_connector_list_iter_begin(&i915->drm, &conn_iter);
+       for_each_intel_connector_iter(connector, &conn_iter) {
+               if (&encoder->base == connector->base.encoder) {
+                       found_connector = connector;
+                       break;
+               }
+       }
+       drm_connector_list_iter_end(&conn_iter);
 
-       return NULL;
+       return found_connector;
 }
 
 static void intel_sanitize_fifo_underrun_reporting(const struct intel_crtc_state *crtc_state)
index 0fdcf2e..842d70f 100644 (file)
@@ -227,7 +227,8 @@ void intel_modeset_verify_crtc(struct intel_crtc *crtc,
                               struct intel_crtc_state *old_crtc_state,
                               struct intel_crtc_state *new_crtc_state)
 {
-       if (!intel_crtc_needs_modeset(new_crtc_state) && !new_crtc_state->update_pipe)
+       if (!intel_crtc_needs_modeset(new_crtc_state) &&
+           !intel_crtc_needs_fastset(new_crtc_state))
                return;
 
        intel_wm_state_verify(crtc, new_crtc_state);
index caa07ef..e018474 100644 (file)
@@ -463,7 +463,6 @@ static u32 asle_set_backlight(struct drm_i915_private *dev_priv, u32 bclp)
        struct intel_connector *connector;
        struct drm_connector_list_iter conn_iter;
        struct opregion_asle *asle = dev_priv->display.opregion.asle;
-       struct drm_device *dev = &dev_priv->drm;
 
        drm_dbg(&dev_priv->drm, "bclp = 0x%08x\n", bclp);
 
@@ -480,7 +479,7 @@ static u32 asle_set_backlight(struct drm_i915_private *dev_priv, u32 bclp)
        if (bclp > 255)
                return ASLC_BACKLIGHT_FAILED;
 
-       drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+       drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, NULL);
 
        /*
         * Update backlight on all connectors that support backlight (usually
@@ -488,13 +487,13 @@ static u32 asle_set_backlight(struct drm_i915_private *dev_priv, u32 bclp)
         */
        drm_dbg_kms(&dev_priv->drm, "updating opregion backlight %d/255\n",
                    bclp);
-       drm_connector_list_iter_begin(dev, &conn_iter);
+       drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
        for_each_intel_connector_iter(connector, &conn_iter)
                intel_backlight_set_acpi(connector->base.state, bclp, 255);
        drm_connector_list_iter_end(&conn_iter);
        asle->cblv = DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID;
 
-       drm_modeset_unlock(&dev->mode_config.connection_mutex);
+       drm_modeset_unlock(&dev_priv->drm.mode_config.connection_mutex);
 
 
        return 0;
index a3a3f9f..69ce777 100644 (file)
@@ -85,9 +85,10 @@ static bool is_alt_drrs_mode(const struct drm_display_mode *mode,
 static bool is_alt_fixed_mode(const struct drm_display_mode *mode,
                              const struct drm_display_mode *preferred_mode)
 {
-       return drm_mode_match(mode, preferred_mode,
-                             DRM_MODE_MATCH_FLAGS |
-                             DRM_MODE_MATCH_3D_FLAGS) &&
+       u32 sync_flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC |
+               DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC;
+
+       return (mode->flags & ~sync_flags) == (preferred_mode->flags & ~sync_flags) &&
                mode->hdisplay == preferred_mode->hdisplay &&
                mode->vdisplay == preferred_mode->vdisplay;
 }
@@ -147,12 +148,24 @@ int intel_panel_get_modes(struct intel_connector *connector)
        return num_modes;
 }
 
-enum drrs_type intel_panel_drrs_type(struct intel_connector *connector)
+static bool has_drrs_modes(struct intel_connector *connector)
 {
-       if (list_empty(&connector->panel.fixed_modes) ||
-           list_is_singular(&connector->panel.fixed_modes))
-               return DRRS_TYPE_NONE;
+       const struct drm_display_mode *mode1;
+
+       list_for_each_entry(mode1, &connector->panel.fixed_modes, head) {
+               const struct drm_display_mode *mode2 = mode1;
+
+               list_for_each_entry_continue(mode2, &connector->panel.fixed_modes, head) {
+                       if (is_alt_drrs_mode(mode1, mode2))
+                               return true;
+               }
+       }
+
+       return false;
+}
 
+enum drrs_type intel_panel_drrs_type(struct intel_connector *connector)
+{
        return connector->panel.vbt.drrs_type;
 }
 
@@ -254,10 +267,10 @@ static void intel_panel_destroy_probed_modes(struct intel_connector *connector)
 }
 
 void intel_panel_add_edid_fixed_modes(struct intel_connector *connector,
-                                     bool has_drrs, bool has_vrr)
+                                     bool use_alt_fixed_modes)
 {
        intel_panel_add_edid_preferred_mode(connector);
-       if (intel_panel_preferred_fixed_mode(connector) && (has_drrs || has_vrr))
+       if (intel_panel_preferred_fixed_mode(connector) && use_alt_fixed_modes)
                intel_panel_add_edid_alt_fixed_modes(connector);
        intel_panel_destroy_probed_modes(connector);
 }
@@ -653,6 +666,9 @@ int intel_panel_init(struct intel_connector *connector)
 
        intel_backlight_init_funcs(panel);
 
+       if (!has_drrs_modes(connector))
+               connector->panel.vbt.drrs_type = DRRS_TYPE_NONE;
+
        drm_dbg_kms(connector->base.dev,
                    "[CONNECTOR:%d:%s] DRRS type: %s\n",
                    connector->base.base.id, connector->base.name,
index eff3ffd..5c5b5b7 100644 (file)
@@ -44,7 +44,7 @@ int intel_panel_fitting(struct intel_crtc_state *crtc_state,
 int intel_panel_compute_config(struct intel_connector *connector,
                               struct drm_display_mode *adjusted_mode);
 void intel_panel_add_edid_fixed_modes(struct intel_connector *connector,
-                                     bool has_drrs, bool has_vrr);
+                                     bool use_alt_fixed_modes);
 void intel_panel_add_vbt_lfp_fixed_mode(struct intel_connector *connector);
 void intel_panel_add_vbt_sdvo_fixed_mode(struct intel_connector *connector);
 void intel_panel_add_encoder_fixed_mode(struct intel_connector *connector,
index 8ac263f..1c74388 100644 (file)
@@ -75,7 +75,6 @@ static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv,
                                     enum pipe pipe,
                                     enum intel_pipe_crc_source *source)
 {
-       struct drm_device *dev = &dev_priv->drm;
        struct intel_encoder *encoder;
        struct intel_crtc *crtc;
        struct intel_digital_port *dig_port;
@@ -83,8 +82,8 @@ static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv,
 
        *source = INTEL_PIPE_CRC_SOURCE_PIPE;
 
-       drm_modeset_lock_all(dev);
-       for_each_intel_encoder(dev, encoder) {
+       drm_modeset_lock_all(&dev_priv->drm);
+       for_each_intel_encoder(&dev_priv->drm, encoder) {
                if (!encoder->base.crtc)
                        continue;
 
@@ -111,7 +110,7 @@ static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv,
                                *source = INTEL_PIPE_CRC_SOURCE_DP_D;
                                break;
                        default:
-                               drm_WARN(dev, 1, "nonexisting DP port %c\n",
+                               drm_WARN(&dev_priv->drm, 1, "nonexisting DP port %c\n",
                                         port_name(dig_port->base.port));
                                break;
                        }
@@ -120,7 +119,7 @@ static int i9xx_pipe_crc_auto_source(struct drm_i915_private *dev_priv,
                        break;
                }
        }
-       drm_modeset_unlock_all(dev);
+       drm_modeset_unlock_all(&dev_priv->drm);
 
        return ret;
 }
index d4cce62..904a104 100644 (file)
@@ -533,7 +533,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
 
        val |= psr_compute_idle_frames(intel_dp) << EDP_PSR2_IDLE_FRAME_SHIFT;
 
-       if (!IS_ALDERLAKE_P(dev_priv))
+       if (DISPLAY_VER(dev_priv) <= 13 && !IS_ALDERLAKE_P(dev_priv))
                val |= EDP_SU_TRACK_ENABLE;
 
        if (DISPLAY_VER(dev_priv) >= 10 && DISPLAY_VER(dev_priv) <= 12)
@@ -616,7 +616,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
 static bool
 transcoder_has_psr2(struct drm_i915_private *dev_priv, enum transcoder trans)
 {
-       if (IS_ALDERLAKE_P(dev_priv))
+       if (IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(dev_priv) >= 14)
                return trans == TRANSCODER_A || trans == TRANSCODER_B;
        else if (DISPLAY_VER(dev_priv) >= 12)
                return trans == TRANSCODER_A;
@@ -696,7 +696,7 @@ dc3co_is_pipe_port_compatible(struct intel_dp *intel_dp,
        struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
        enum port port = dig_port->base.port;
 
-       if (IS_ALDERLAKE_P(dev_priv))
+       if (IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(dev_priv) >= 14)
                return pipe <= PIPE_B && port <= PORT_B;
        else
                return pipe == PIPE_A && port == PORT_A;
@@ -795,11 +795,11 @@ static bool psr2_granularity_check(struct intel_dp *intel_dp,
                return intel_dp->psr.su_y_granularity == 4;
 
        /*
-        * adl_p has 1 line granularity. For other platforms with SW tracking we
-        * can adjust the y coordinates to match sink requirement if multiple of
-        * 4.
+        * adl_p and display 14+ platforms has 1 line granularity.
+        * 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))
+       if (IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(dev_priv) >= 14)
                y_granularity = intel_dp->psr.su_y_granularity;
        else if (intel_dp->psr.su_y_granularity <= 2)
                y_granularity = 4;
@@ -883,7 +883,8 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
         * resolution requires DSC to be enabled, priority is given to DSC
         * over PSR2.
         */
-       if (crtc_state->dsc.compression_enable) {
+       if (crtc_state->dsc.compression_enable &&
+           (DISPLAY_VER(dev_priv) <= 13 && !IS_ALDERLAKE_P(dev_priv))) {
                drm_dbg_kms(&dev_priv->drm,
                            "PSR2 cannot be enabled since DSC is enabled\n");
                return false;
@@ -1474,7 +1475,7 @@ static u32 man_trk_ctl_enable_bit_get(struct drm_i915_private *dev_priv)
 
 static u32 man_trk_ctl_single_full_frame_bit_get(struct drm_i915_private *dev_priv)
 {
-       return IS_ALDERLAKE_P(dev_priv) ?
+       return IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(dev_priv) >= 14 ?
               ADLP_PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME :
               PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME;
 }
@@ -1627,7 +1628,7 @@ static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state,
        if (clip->y1 == -1)
                goto exit;
 
-       if (IS_ALDERLAKE_P(dev_priv)) {
+       if (IS_ALDERLAKE_P(dev_priv) || DISPLAY_VER(dev_priv) >= 14) {
                val |= ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(clip->y1);
                val |= ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(clip->y2 - 1);
        } else {
@@ -1664,7 +1665,15 @@ static void intel_psr2_sel_fetch_pipe_alignment(const struct intel_crtc_state *c
                                                struct drm_rect *pipe_clip)
 {
        struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
-       const u16 y_alignment = crtc_state->su_y_granularity;
+       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(dev_priv) >= 14))
+               y_alignment = vdsc_cfg->slice_height;
+       else
+               y_alignment = crtc_state->su_y_granularity;
 
        pipe_clip->y1 -= pipe_clip->y1 % y_alignment;
        if (pipe_clip->y2 % y_alignment)
@@ -2054,13 +2063,12 @@ static bool __psr_wait_for_idle_locked(struct intel_dp *intel_dp)
 static int intel_psr_fastset_force(struct drm_i915_private *dev_priv)
 {
        struct drm_connector_list_iter conn_iter;
-       struct drm_device *dev = &dev_priv->drm;
        struct drm_modeset_acquire_ctx ctx;
        struct drm_atomic_state *state;
        struct drm_connector *conn;
        int err = 0;
 
-       state = drm_atomic_state_alloc(dev);
+       state = drm_atomic_state_alloc(&dev_priv->drm);
        if (!state)
                return -ENOMEM;
 
@@ -2069,7 +2077,7 @@ static int intel_psr_fastset_force(struct drm_i915_private *dev_priv)
 
 retry:
 
-       drm_connector_list_iter_begin(dev, &conn_iter);
+       drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
        drm_for_each_connector_iter(conn, &conn_iter) {
                struct drm_connector_state *conn_state;
                struct drm_crtc_state *crtc_state;
index f5b744b..48b7b1a 100644 (file)
@@ -199,7 +199,7 @@ to_intel_sdvo_connector(struct drm_connector *connector)
        container_of((conn_state), struct intel_sdvo_connector_state, base.base)
 
 static bool
-intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, u16 flags);
+intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo);
 static bool
 intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
                              struct intel_sdvo_connector *intel_sdvo_connector,
@@ -1297,13 +1297,28 @@ static bool intel_sdvo_limited_color_range(struct intel_encoder *encoder,
        return intel_hdmi_limited_color_range(crtc_state, conn_state);
 }
 
+static bool intel_sdvo_has_audio(struct intel_encoder *encoder,
+                                const struct intel_crtc_state *crtc_state,
+                                const struct drm_connector_state *conn_state)
+{
+       struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
+       const struct intel_digital_connector_state *intel_conn_state =
+               to_intel_digital_connector_state(conn_state);
+
+       if (!crtc_state->has_hdmi_sink)
+               return false;
+
+       if (intel_conn_state->force_audio == HDMI_AUDIO_AUTO)
+               return intel_sdvo->has_hdmi_audio;
+       else
+               return intel_conn_state->force_audio == HDMI_AUDIO_ON;
+}
+
 static int intel_sdvo_compute_config(struct intel_encoder *encoder,
                                     struct intel_crtc_state *pipe_config,
                                     struct drm_connector_state *conn_state)
 {
        struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
-       struct intel_sdvo_connector_state *intel_sdvo_state =
-               to_intel_sdvo_connector_state(conn_state);
        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;
@@ -1362,13 +1377,7 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
 
        pipe_config->has_hdmi_sink = intel_has_hdmi_sink(intel_sdvo, conn_state);
 
-       if (pipe_config->has_hdmi_sink) {
-               if (intel_sdvo_state->base.force_audio == HDMI_AUDIO_AUTO)
-                       pipe_config->has_audio = intel_sdvo->has_hdmi_audio;
-               else
-                       pipe_config->has_audio =
-                               intel_sdvo_state->base.force_audio == HDMI_AUDIO_ON;
-       }
+       pipe_config->has_audio = intel_sdvo_has_audio(encoder, pipe_config, conn_state);
 
        pipe_config->limited_color_range =
                intel_sdvo_limited_color_range(encoder, pipe_config,
@@ -2290,17 +2299,12 @@ static int intel_sdvo_get_tv_modes(struct drm_connector *connector)
 
 static int intel_sdvo_get_lvds_modes(struct drm_connector *connector)
 {
-       struct intel_sdvo *intel_sdvo = intel_attached_sdvo(to_intel_connector(connector));
        struct drm_i915_private *dev_priv = to_i915(connector->dev);
-       int num_modes = 0;
 
        drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s]\n",
                    connector->base.id, connector->name);
 
-       num_modes += intel_panel_get_modes(to_intel_connector(connector));
-       num_modes += intel_ddc_get_modes(connector, &intel_sdvo->ddc);
-
-       return num_modes;
+       return intel_panel_get_modes(to_intel_connector(connector));
 }
 
 static int intel_sdvo_get_modes(struct drm_connector *connector)
@@ -2627,7 +2631,7 @@ intel_sdvo_unselect_i2c_bus(struct intel_sdvo *sdvo)
 }
 
 static bool
-intel_sdvo_is_hdmi_connector(struct intel_sdvo *intel_sdvo, int device)
+intel_sdvo_is_hdmi_connector(struct intel_sdvo *intel_sdvo)
 {
        return intel_sdvo_check_supp_encode(intel_sdvo);
 }
@@ -2689,9 +2693,8 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector,
        drm_connector_helper_add(drm_connector,
                                 &intel_sdvo_connector_helper_funcs);
 
-       connector->base.base.interlace_allowed = 1;
-       connector->base.base.doublescan_allowed = 0;
        connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB;
+       connector->base.base.interlace_allowed = true;
        connector->base.get_hw_state = intel_sdvo_connector_get_hw_state;
 
        intel_connector_attach_encoder(&connector->base, &encoder->base);
@@ -2733,7 +2736,7 @@ static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void)
 }
 
 static bool
-intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
+intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, u16 type)
 {
        struct drm_encoder *encoder = &intel_sdvo->base.base;
        struct drm_connector *connector;
@@ -2741,19 +2744,13 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
        struct intel_connector *intel_connector;
        struct intel_sdvo_connector *intel_sdvo_connector;
 
-       DRM_DEBUG_KMS("initialising DVI device %d\n", device);
+       DRM_DEBUG_KMS("initialising DVI type 0x%x\n", type);
 
        intel_sdvo_connector = intel_sdvo_connector_alloc();
        if (!intel_sdvo_connector)
                return false;
 
-       if (device == 0) {
-               intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0;
-               intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0;
-       } else if (device == 1) {
-               intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1;
-               intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1;
-       }
+       intel_sdvo_connector->output_flag = type;
 
        intel_connector = &intel_sdvo_connector->base;
        connector = &intel_connector->base;
@@ -2773,7 +2770,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
        encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
        connector->connector_type = DRM_MODE_CONNECTOR_DVID;
 
-       if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) {
+       if (intel_sdvo_is_hdmi_connector(intel_sdvo)) {
                connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
                intel_sdvo_connector->is_hdmi = true;
        }
@@ -2790,14 +2787,14 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
 }
 
 static bool
-intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
+intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, u16 type)
 {
        struct drm_encoder *encoder = &intel_sdvo->base.base;
        struct drm_connector *connector;
        struct intel_connector *intel_connector;
        struct intel_sdvo_connector *intel_sdvo_connector;
 
-       DRM_DEBUG_KMS("initialising TV type %d\n", type);
+       DRM_DEBUG_KMS("initialising TV type 0x%x\n", type);
 
        intel_sdvo_connector = intel_sdvo_connector_alloc();
        if (!intel_sdvo_connector)
@@ -2808,7 +2805,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
        encoder->encoder_type = DRM_MODE_ENCODER_TVDAC;
        connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
 
-       intel_sdvo->controlled_output |= type;
        intel_sdvo_connector->output_flag = type;
 
        if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
@@ -2830,14 +2826,14 @@ err:
 }
 
 static bool
-intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
+intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, u16 type)
 {
        struct drm_encoder *encoder = &intel_sdvo->base.base;
        struct drm_connector *connector;
        struct intel_connector *intel_connector;
        struct intel_sdvo_connector *intel_sdvo_connector;
 
-       DRM_DEBUG_KMS("initialising analog device %d\n", device);
+       DRM_DEBUG_KMS("initialising analog type 0x%x\n", type);
 
        intel_sdvo_connector = intel_sdvo_connector_alloc();
        if (!intel_sdvo_connector)
@@ -2849,13 +2845,7 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
        encoder->encoder_type = DRM_MODE_ENCODER_DAC;
        connector->connector_type = DRM_MODE_CONNECTOR_VGA;
 
-       if (device == 0) {
-               intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0;
-               intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0;
-       } else if (device == 1) {
-               intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1;
-               intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
-       }
+       intel_sdvo_connector->output_flag = type;
 
        if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
                kfree(intel_sdvo_connector);
@@ -2866,7 +2856,7 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
 }
 
 static bool
-intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
+intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, u16 type)
 {
        struct drm_encoder *encoder = &intel_sdvo->base.base;
        struct drm_i915_private *i915 = to_i915(encoder->dev);
@@ -2874,7 +2864,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
        struct intel_connector *intel_connector;
        struct intel_sdvo_connector *intel_sdvo_connector;
 
-       DRM_DEBUG_KMS("initialising LVDS device %d\n", device);
+       DRM_DEBUG_KMS("initialising LVDS type 0x%x\n", type);
 
        intel_sdvo_connector = intel_sdvo_connector_alloc();
        if (!intel_sdvo_connector)
@@ -2885,13 +2875,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
        encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
        connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
 
-       if (device == 0) {
-               intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0;
-               intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0;
-       } else if (device == 1) {
-               intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1;
-               intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
-       }
+       intel_sdvo_connector->output_flag = type;
 
        if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) {
                kfree(intel_sdvo_connector);
@@ -2910,8 +2894,12 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
        intel_panel_add_vbt_sdvo_fixed_mode(intel_connector);
 
        if (!intel_panel_preferred_fixed_mode(intel_connector)) {
+               mutex_lock(&i915->drm.mode_config.mutex);
+
                intel_ddc_get_modes(connector, &intel_sdvo->ddc);
-               intel_panel_add_edid_fixed_modes(intel_connector, false, false);
+               intel_panel_add_edid_fixed_modes(intel_connector, false);
+
+               mutex_unlock(&i915->drm.mode_config.mutex);
        }
 
        intel_panel_init(intel_connector);
@@ -2926,58 +2914,78 @@ err:
        return false;
 }
 
-static bool
-intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, u16 flags)
+static u16 intel_sdvo_filter_output_flags(u16 flags)
 {
+       flags &= SDVO_OUTPUT_MASK;
+
        /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/
+       if (!(flags & SDVO_OUTPUT_TMDS0))
+               flags &= ~SDVO_OUTPUT_TMDS1;
 
-       if (flags & SDVO_OUTPUT_TMDS0)
-               if (!intel_sdvo_dvi_init(intel_sdvo, 0))
-                       return false;
+       if (!(flags & SDVO_OUTPUT_RGB0))
+               flags &= ~SDVO_OUTPUT_RGB1;
 
-       if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK)
-               if (!intel_sdvo_dvi_init(intel_sdvo, 1))
-                       return false;
+       if (!(flags & SDVO_OUTPUT_LVDS0))
+               flags &= ~SDVO_OUTPUT_LVDS1;
 
-       /* TV has no XXX1 function block */
-       if (flags & SDVO_OUTPUT_SVID0)
-               if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_SVID0))
-                       return false;
+       return flags;
+}
 
-       if (flags & SDVO_OUTPUT_CVBS0)
-               if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_CVBS0))
-                       return false;
+static bool intel_sdvo_output_init(struct intel_sdvo *sdvo, u16 type)
+{
+       if (type & SDVO_TMDS_MASK)
+               return intel_sdvo_dvi_init(sdvo, type);
+       else if (type & SDVO_TV_MASK)
+               return intel_sdvo_tv_init(sdvo, type);
+       else if (type & SDVO_RGB_MASK)
+               return intel_sdvo_analog_init(sdvo, type);
+       else if (type & SDVO_LVDS_MASK)
+               return intel_sdvo_lvds_init(sdvo, type);
+       else
+               return false;
+}
 
-       if (flags & SDVO_OUTPUT_YPRPB0)
-               if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_YPRPB0))
-                       return false;
+static bool
+intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo)
+{
+       static const u16 probe_order[] = {
+               SDVO_OUTPUT_TMDS0,
+               SDVO_OUTPUT_TMDS1,
+               /* TV has no XXX1 function block */
+               SDVO_OUTPUT_SVID0,
+               SDVO_OUTPUT_CVBS0,
+               SDVO_OUTPUT_YPRPB0,
+               SDVO_OUTPUT_RGB0,
+               SDVO_OUTPUT_RGB1,
+               SDVO_OUTPUT_LVDS0,
+               SDVO_OUTPUT_LVDS1,
+       };
+       struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev);
+       u16 flags;
+       int i;
 
-       if (flags & SDVO_OUTPUT_RGB0)
-               if (!intel_sdvo_analog_init(intel_sdvo, 0))
-                       return false;
+       flags = intel_sdvo_filter_output_flags(intel_sdvo->caps.output_flags);
 
-       if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK)
-               if (!intel_sdvo_analog_init(intel_sdvo, 1))
-                       return false;
+       if (flags == 0) {
+               DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%04x)\n",
+                             SDVO_NAME(intel_sdvo), intel_sdvo->caps.output_flags);
+               return false;
+       }
 
-       if (flags & SDVO_OUTPUT_LVDS0)
-               if (!intel_sdvo_lvds_init(intel_sdvo, 0))
-                       return false;
+       intel_sdvo->controlled_output = flags;
 
-       if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK)
-               if (!intel_sdvo_lvds_init(intel_sdvo, 1))
-                       return false;
+       intel_sdvo_select_ddc_bus(i915, intel_sdvo);
 
-       if ((flags & SDVO_OUTPUT_MASK) == 0) {
-               unsigned char bytes[2];
+       for (i = 0; i < ARRAY_SIZE(probe_order); i++) {
+               u16 type = flags & probe_order[i];
 
-               intel_sdvo->controlled_output = 0;
-               memcpy(bytes, &intel_sdvo->caps.output_flags, 2);
-               DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n",
-                             SDVO_NAME(intel_sdvo),
-                             bytes[0], bytes[1]);
-               return false;
+               if (!type)
+                       continue;
+
+               if (!intel_sdvo_output_init(intel_sdvo, type))
+                       return false;
        }
+
        intel_sdvo->base.pipe_mask = ~0;
 
        return true;
@@ -3353,8 +3361,7 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv,
        intel_sdvo->colorimetry_cap =
                intel_sdvo_get_colorimetry_cap(intel_sdvo);
 
-       if (intel_sdvo_output_setup(intel_sdvo,
-                                   intel_sdvo->caps.output_flags) != true) {
+       if (!intel_sdvo_output_setup(intel_sdvo)) {
                drm_dbg_kms(&dev_priv->drm,
                            "SDVO output failed to setup on %s\n",
                            SDVO_NAME(intel_sdvo));
@@ -3383,8 +3390,6 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv,
         */
        intel_sdvo->base.cloneable = 0;
 
-       intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo);
-
        /* Set the input timing to the screen. Assume always input 0. */
        if (!intel_sdvo_set_target_input(intel_sdvo))
                goto err_output;
@@ -3407,9 +3412,12 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv,
                        (intel_sdvo->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N',
                        /* check currently supported outputs */
                        intel_sdvo->caps.output_flags &
-                       (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N',
+                       (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0 |
+                        SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_SVID0 |
+                        SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB0) ? 'Y' : 'N',
                        intel_sdvo->caps.output_flags &
-                       (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
+                       (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1 |
+                        SDVO_OUTPUT_LVDS1) ? 'Y' : 'N');
        return true;
 
 err_output:
index e5af955..70624b4 100644 (file)
@@ -8,9 +8,10 @@
 #include "intel_display.h"
 #include "intel_display_power_map.h"
 #include "intel_display_types.h"
+#include "intel_dkl_phy_regs.h"
 #include "intel_dp_mst.h"
+#include "intel_mg_phy_regs.h"
 #include "intel_tc.h"
-#include "intel_tc_phy_regs.h"
 
 static const char *tc_port_mode_name(enum tc_port_mode mode)
 {
@@ -408,14 +409,9 @@ static bool adl_tc_phy_take_ownership(struct intel_digital_port *dig_port,
        struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
        struct intel_uncore *uncore = &i915->uncore;
        enum port port = dig_port->base.port;
-       u32 val;
 
-       val = intel_uncore_read(uncore, DDI_BUF_CTL(port));
-       if (take)
-               val |= DDI_BUF_CTL_TC_PHY_OWNERSHIP;
-       else
-               val &= ~DDI_BUF_CTL_TC_PHY_OWNERSHIP;
-       intel_uncore_write(uncore, DDI_BUF_CTL(port), val);
+       intel_uncore_rmw(uncore, DDI_BUF_CTL(port), DDI_BUF_CTL_TC_PHY_OWNERSHIP,
+                        take ? DDI_BUF_CTL_TC_PHY_OWNERSHIP : 0);
 
        return true;
 }
@@ -687,18 +683,58 @@ static void
 intel_tc_port_link_init_refcount(struct intel_digital_port *dig_port,
                                 int refcount)
 {
+       dig_port->tc_link_refcount = refcount;
+}
+
+/**
+ * intel_tc_port_init_mode: Read out HW state and init the given port's TypeC mode
+ * @dig_port: digital port
+ *
+ * Read out the HW state and initialize the TypeC mode of @dig_port. The mode
+ * will be locked until intel_tc_port_sanitize_mode() is called.
+ */
+void intel_tc_port_init_mode(struct intel_digital_port *dig_port)
+{
        struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+       intel_wakeref_t tc_cold_wref;
+       enum intel_display_power_domain domain;
+
+       mutex_lock(&dig_port->tc_lock);
 
+       drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_DISCONNECTED);
+       drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref);
        drm_WARN_ON(&i915->drm, dig_port->tc_link_refcount);
-       dig_port->tc_link_refcount = refcount;
+
+       tc_cold_wref = tc_cold_block(dig_port, &domain);
+
+       dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port);
+       /* Prevent changing dig_port->tc_mode until intel_tc_port_sanitize_mode() is called. */
+       intel_tc_port_link_init_refcount(dig_port, 1);
+       dig_port->tc_lock_wakeref = tc_cold_block(dig_port, &dig_port->tc_lock_power_domain);
+
+       tc_cold_unblock(dig_port, domain, tc_cold_wref);
+
+       drm_dbg_kms(&i915->drm, "Port %s: init mode (%s)\n",
+                   dig_port->tc_port_name,
+                   tc_port_mode_name(dig_port->tc_mode));
+
+       mutex_unlock(&dig_port->tc_lock);
 }
 
-void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
+/**
+ * intel_tc_port_sanitize_mode: Sanitize the given port's TypeC mode
+ * @dig_port: digital port
+ *
+ * Sanitize @dig_port's TypeC mode wrt. the encoder's state right after driver
+ * loading and system resume:
+ * If the encoder is enabled keep the TypeC mode/PHY connected state locked until
+ * the encoder is disabled.
+ * If the encoder is disabled make sure the PHY is disconnected.
+ */
+void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port)
 {
        struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
        struct intel_encoder *encoder = &dig_port->base;
-       intel_wakeref_t tc_cold_wref;
-       enum intel_display_power_domain domain;
        int active_links = 0;
 
        mutex_lock(&dig_port->tc_lock);
@@ -708,21 +744,14 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
        else if (encoder->base.crtc)
                active_links = to_intel_crtc(encoder->base.crtc)->active;
 
-       drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_DISCONNECTED);
-       drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref);
-
-       tc_cold_wref = tc_cold_block(dig_port, &domain);
+       drm_WARN_ON(&i915->drm, dig_port->tc_link_refcount != 1);
+       intel_tc_port_link_init_refcount(dig_port, active_links);
 
-       dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port);
        if (active_links) {
                if (!icl_tc_phy_is_connected(dig_port))
                        drm_dbg_kms(&i915->drm,
                                    "Port %s: PHY disconnected with %d active link(s)\n",
                                    dig_port->tc_port_name, active_links);
-               intel_tc_port_link_init_refcount(dig_port, active_links);
-
-               dig_port->tc_lock_wakeref = tc_cold_block(dig_port,
-                                                         &dig_port->tc_lock_power_domain);
        } else {
                /*
                 * TBT-alt is the default mode in any case the PHY ownership is not
@@ -736,9 +765,10 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
                                    dig_port->tc_port_name,
                                    tc_port_mode_name(dig_port->tc_mode));
                icl_tc_phy_disconnect(dig_port);
-       }
 
-       tc_cold_unblock(dig_port, domain, tc_cold_wref);
+               tc_cold_unblock(dig_port, dig_port->tc_lock_power_domain,
+                               fetch_and_zero(&dig_port->tc_lock_wakeref));
+       }
 
        drm_dbg_kms(&i915->drm, "Port %s: sanitize mode (%s)\n",
                    dig_port->tc_port_name,
@@ -923,4 +953,6 @@ void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy)
        dig_port->tc_mode = TC_PORT_DISCONNECTED;
        dig_port->tc_link_refcount = 0;
        tc_port_load_fia_params(i915, dig_port);
+
+       intel_tc_port_init_mode(dig_port);
 }
index 6b47b29..d54082e 100644 (file)
@@ -24,7 +24,8 @@ int intel_tc_port_fia_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);
 
-void intel_tc_port_sanitize(struct intel_digital_port *dig_port);
+void intel_tc_port_init_mode(struct intel_digital_port *dig_port);
+void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port);
 void intel_tc_port_lock(struct intel_digital_port *dig_port);
 void intel_tc_port_unlock(struct intel_digital_port *dig_port);
 void intel_tc_port_flush_work(struct intel_digital_port *dig_port);
index dcf89d7..cf7d5c1 100644 (file)
@@ -1880,18 +1880,56 @@ static const struct drm_encoder_funcs intel_tv_enc_funcs = {
        .destroy = intel_encoder_destroy,
 };
 
+static void intel_tv_add_properties(struct drm_connector *connector)
+{
+       struct drm_i915_private *i915 = to_i915(connector->dev);
+       struct drm_connector_state *conn_state = connector->state;
+       const char *tv_format_names[ARRAY_SIZE(tv_modes)];
+       int i;
+
+       /* BIOS margin values */
+       conn_state->tv.margins.left = 54;
+       conn_state->tv.margins.top = 36;
+       conn_state->tv.margins.right = 46;
+       conn_state->tv.margins.bottom = 37;
+
+       conn_state->tv.mode = 0;
+
+       /* Create TV properties then attach current values */
+       for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
+               /* 1080p50/1080p60 not supported on gen3 */
+               if (DISPLAY_VER(i915) == 3 && tv_modes[i].oversample == 1)
+                       break;
+
+               tv_format_names[i] = tv_modes[i].name;
+       }
+       drm_mode_create_tv_properties(&i915->drm, i, tv_format_names);
+
+       drm_object_attach_property(&connector->base,
+                                  i915->drm.mode_config.tv_mode_property,
+                                  conn_state->tv.mode);
+       drm_object_attach_property(&connector->base,
+                                  i915->drm.mode_config.tv_left_margin_property,
+                                  conn_state->tv.margins.left);
+       drm_object_attach_property(&connector->base,
+                                  i915->drm.mode_config.tv_top_margin_property,
+                                  conn_state->tv.margins.top);
+       drm_object_attach_property(&connector->base,
+                                  i915->drm.mode_config.tv_right_margin_property,
+                                  conn_state->tv.margins.right);
+       drm_object_attach_property(&connector->base,
+                                  i915->drm.mode_config.tv_bottom_margin_property,
+                                  conn_state->tv.margins.bottom);
+}
+
 void
 intel_tv_init(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = &dev_priv->drm;
        struct drm_connector *connector;
        struct intel_tv *intel_tv;
        struct intel_encoder *intel_encoder;
        struct intel_connector *intel_connector;
        u32 tv_dac_on, tv_dac_off, save_tv_dac;
-       const char *tv_format_names[ARRAY_SIZE(tv_modes)];
-       int i, initial_mode = 0;
-       struct drm_connector_state *state;
 
        if ((intel_de_read(dev_priv, TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
                return;
@@ -1937,7 +1975,6 @@ intel_tv_init(struct drm_i915_private *dev_priv)
 
        intel_encoder = &intel_tv->base;
        connector = &intel_connector->base;
-       state = connector->state;
 
        /*
         * The documentation, for the older chipsets at least, recommend
@@ -1951,10 +1988,10 @@ intel_tv_init(struct drm_i915_private *dev_priv)
         */
        intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
 
-       drm_connector_init(dev, connector, &intel_tv_connector_funcs,
+       drm_connector_init(&dev_priv->drm, connector, &intel_tv_connector_funcs,
                           DRM_MODE_CONNECTOR_SVIDEO);
 
-       drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs,
+       drm_encoder_init(&dev_priv->drm, &intel_encoder->base, &intel_tv_enc_funcs,
                         DRM_MODE_ENCODER_TVDAC, "TV");
 
        intel_encoder->compute_config = intel_tv_compute_config;
@@ -1974,41 +2011,7 @@ intel_tv_init(struct drm_i915_private *dev_priv)
        intel_encoder->cloneable = 0;
        intel_tv->type = DRM_MODE_CONNECTOR_Unknown;
 
-       /* BIOS margin values */
-       state->tv.margins.left = 54;
-       state->tv.margins.top = 36;
-       state->tv.margins.right = 46;
-       state->tv.margins.bottom = 37;
-
-       state->tv.mode = initial_mode;
-
        drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
-       connector->interlace_allowed = false;
-       connector->doublescan_allowed = false;
 
-       /* Create TV properties then attach current values */
-       for (i = 0; i < ARRAY_SIZE(tv_modes); i++) {
-               /* 1080p50/1080p60 not supported on gen3 */
-               if (DISPLAY_VER(dev_priv) == 3 &&
-                   tv_modes[i].oversample == 1)
-                       break;
-
-               tv_format_names[i] = tv_modes[i].name;
-       }
-       drm_mode_create_tv_properties(dev, i, tv_format_names);
-
-       drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property,
-                                  state->tv.mode);
-       drm_object_attach_property(&connector->base,
-                                  dev->mode_config.tv_left_margin_property,
-                                  state->tv.margins.left);
-       drm_object_attach_property(&connector->base,
-                                  dev->mode_config.tv_top_margin_property,
-                                  state->tv.margins.top);
-       drm_object_attach_property(&connector->base,
-                                  dev->mode_config.tv_right_margin_property,
-                                  state->tv.margins.right);
-       drm_object_attach_property(&connector->base,
-                                  dev->mode_config.tv_bottom_margin_property,
-                                  state->tv.margins.bottom);
+       intel_tv_add_properties(connector);
 }
index 18178b0..d58e667 100644 (file)
@@ -1706,26 +1706,10 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
                return -EINVAL;
        }
 
-       wp->y_tiled = modifier == I915_FORMAT_MOD_Y_TILED ||
-                     modifier == I915_FORMAT_MOD_4_TILED ||
-                     modifier == I915_FORMAT_MOD_Yf_TILED ||
-                     modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
-                     modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
-                     modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
-                     modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
-                     modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC ||
-                     modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS ||
-                     modifier == I915_FORMAT_MOD_4_TILED_DG2_MC_CCS ||
-                     modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
        wp->x_tiled = modifier == I915_FORMAT_MOD_X_TILED;
-       wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
-                        modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
-                        modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
-                        modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
-                        modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC ||
-                        modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS ||
-                        modifier == I915_FORMAT_MOD_4_TILED_DG2_MC_CCS ||
-                        modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
+       wp->y_tiled = modifier != I915_FORMAT_MOD_X_TILED &&
+               intel_fb_is_tiled_modifier(modifier);
+       wp->rc_surface = intel_fb_is_ccs_modifier(modifier);
        wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier);
 
        wp->width = width;
@@ -2498,7 +2482,7 @@ skl_compute_ddb(struct intel_atomic_state *state)
 
                if (old_dbuf_state->joined_mbus != new_dbuf_state->joined_mbus) {
                        /* TODO: Implement vblank synchronized MBUS joining changes */
-                       ret = intel_modeset_all_pipes(state);
+                       ret = intel_modeset_all_pipes(state, "MBUS joining change");
                        if (ret)
                                return ret;
                }
index b3f5ca2..5a741ea 100644 (file)
@@ -1659,19 +1659,10 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = {
 
 static void vlv_dsi_add_properties(struct intel_connector *connector)
 {
-       struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
        const struct drm_display_mode *fixed_mode =
                intel_panel_preferred_fixed_mode(connector);
-       u32 allowed_scalers;
 
-       allowed_scalers = BIT(DRM_MODE_SCALE_ASPECT) | BIT(DRM_MODE_SCALE_FULLSCREEN);
-       if (!HAS_GMCH(dev_priv))
-               allowed_scalers |= BIT(DRM_MODE_SCALE_CENTER);
-
-       drm_connector_attach_scaling_mode_property(&connector->base,
-                                                  allowed_scalers);
-
-       connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT;
+       intel_attach_scaling_mode_property(&connector->base);
 
        drm_connector_set_panel_orientation_with_quirk(&connector->base,
                                                       intel_dsi_get_panel_orientation(connector),
@@ -1854,7 +1845,6 @@ static void vlv_dphy_param_init(struct intel_dsi *intel_dsi)
 
 void vlv_dsi_init(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = &dev_priv->drm;
        struct intel_dsi *intel_dsi;
        struct intel_encoder *intel_encoder;
        struct drm_encoder *encoder;
@@ -1891,7 +1881,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
 
        connector = &intel_connector->base;
 
-       drm_encoder_init(dev, encoder, &intel_dsi_funcs, DRM_MODE_ENCODER_DSI,
+       drm_encoder_init(&dev_priv->drm, encoder, &intel_dsi_funcs, DRM_MODE_ENCODER_DSI,
                         "DSI %c", port_name(port));
 
        intel_encoder->compute_config = intel_dsi_compute_config;
@@ -1974,20 +1964,18 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
        intel_dsi_vbt_gpio_init(intel_dsi,
                                intel_dsi_get_hw_state(intel_encoder, &pipe));
 
-       drm_connector_init(dev, connector, &intel_dsi_connector_funcs,
+       drm_connector_init(&dev_priv->drm, connector, &intel_dsi_connector_funcs,
                           DRM_MODE_CONNECTOR_DSI);
 
        drm_connector_helper_add(connector, &intel_dsi_connector_helper_funcs);
 
        connector->display_info.subpixel_order = SubPixelHorizontalRGB; /*XXX*/
-       connector->interlace_allowed = false;
-       connector->doublescan_allowed = false;
 
        intel_connector_attach_encoder(intel_connector, intel_encoder);
 
-       mutex_lock(&dev->mode_config.mutex);
+       mutex_lock(&dev_priv->drm.mode_config.mutex);
        intel_panel_add_vbt_lfp_fixed_mode(intel_connector);
-       mutex_unlock(&dev->mode_config.mutex);
+       mutex_unlock(&dev_priv->drm.mode_config.mutex);
 
        if (!intel_panel_preferred_fixed_mode(intel_connector)) {
                drm_dbg_kms(&dev_priv->drm, "no fixed mode\n");
index 0512afd..b3b398f 100644 (file)
@@ -113,7 +113,7 @@ bool i915_gem_clflush_object(struct drm_i915_gem_object *obj,
                clflush = clflush_work_create(obj);
        if (clflush) {
                i915_sw_fence_await_reservation(&clflush->base.chain,
-                                               obj->base.resv, NULL, true,
+                                               obj->base.resv, true,
                                                i915_fence_timeout(i915),
                                                I915_FENCE_GFP);
                dma_resv_add_fence(obj->base.resv, &clflush->base.dma,
index 2275ee4..5a3a258 100644 (file)
@@ -39,6 +39,9 @@
 #define FORCEWAKE_ACK_RENDER_GEN9              _MMIO(0xd84)
 #define FORCEWAKE_ACK_MEDIA_GEN9               _MMIO(0xd88)
 
+#define GMD_ID_GRAPHICS                                _MMIO(0xd8c)
+#define GMD_ID_MEDIA                           _MMIO(MTL_MEDIA_GSI_BASE + 0xd8c)
+
 #define MCFG_MCR_SELECTOR                      _MMIO(0xfd0)
 #define SF_MCR_SELECTOR                                _MMIO(0xfd8)
 #define GEN8_MCR_SELECTOR                      _MMIO(0xfdc)
index 6d2003d..a821e3d 100644 (file)
@@ -2293,11 +2293,11 @@ rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
        }
 
        if (IS_DG1_GRAPHICS_STEP(i915, STEP_A0, STEP_B0) ||
-           IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) {
+           IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915) || IS_ALDERLAKE_P(i915)) {
                /*
                 * Wa_1607030317:tgl
                 * Wa_1607186500:tgl
-                * Wa_1607297627:tgl,rkl,dg1[a0]
+                * Wa_1607297627:tgl,rkl,dg1[a0],adlp
                 *
                 * On TGL and RKL there are multiple entries for this WA in the
                 * BSpec; some indicate this is an A0-only WA, others indicate
index c459eb3..298ed36 100644 (file)
@@ -337,7 +337,8 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
        if (i915_inject_probe_failure(dev_priv))
                return -ENODEV;
 
-       intel_device_info_subplatform_init(dev_priv);
+       intel_device_info_runtime_init_early(dev_priv);
+
        intel_step_init(dev_priv);
 
        intel_uncore_mmio_debug_init_early(dev_priv);
@@ -353,6 +354,7 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv)
        mutex_init(&dev_priv->display.wm.wm_mutex);
        mutex_init(&dev_priv->display.pps.mutex);
        mutex_init(&dev_priv->display.hdcp.comp_mutex);
+       spin_lock_init(&dev_priv->display.dkl.phy_lock);
 
        i915_memcpy_init_early(dev_priv);
        intel_runtime_pm_init_early(&dev_priv->runtime_pm);
@@ -738,7 +740,6 @@ static void i915_driver_hw_remove(struct drm_i915_private *dev_priv)
  */
 static void i915_driver_register(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = &dev_priv->drm;
        struct intel_gt *gt;
        unsigned int i;
 
@@ -748,7 +749,7 @@ 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, 0)) {
+       if (drm_dev_register(&dev_priv->drm, 0)) {
                drm_err(&dev_priv->drm,
                        "Failed to register driver for userspace access!\n");
                return;
@@ -893,10 +894,6 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (IS_ERR(i915))
                return PTR_ERR(i915);
 
-       /* Disable nuclear pageflip by default on pre-ILK */
-       if (!i915->params.nuclear_pageflip && DISPLAY_VER(i915) < 5)
-               i915->drm.driver_features &= ~DRIVER_ATOMIC;
-
        ret = pci_enable_device(pdev);
        if (ret)
                goto out_fini;
@@ -1092,32 +1089,30 @@ static void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
 
 static void intel_suspend_encoders(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = &dev_priv->drm;
        struct intel_encoder *encoder;
 
        if (!HAS_DISPLAY(dev_priv))
                return;
 
-       drm_modeset_lock_all(dev);
-       for_each_intel_encoder(dev, encoder)
+       drm_modeset_lock_all(&dev_priv->drm);
+       for_each_intel_encoder(&dev_priv->drm, encoder)
                if (encoder->suspend)
                        encoder->suspend(encoder);
-       drm_modeset_unlock_all(dev);
+       drm_modeset_unlock_all(&dev_priv->drm);
 }
 
 static void intel_shutdown_encoders(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = &dev_priv->drm;
        struct intel_encoder *encoder;
 
        if (!HAS_DISPLAY(dev_priv))
                return;
 
-       drm_modeset_lock_all(dev);
-       for_each_intel_encoder(dev, encoder)
+       drm_modeset_lock_all(&dev_priv->drm);
+       for_each_intel_encoder(&dev_priv->drm, encoder)
                if (encoder->shutdown)
                        encoder->shutdown(encoder);
-       drm_modeset_unlock_all(dev);
+       drm_modeset_unlock_all(&dev_priv->drm);
 }
 
 void i915_driver_shutdown(struct drm_i915_private *i915)
index bdc81db..349ff7d 100644 (file)
@@ -75,9 +75,6 @@ struct intel_limit;
 struct intel_overlay_error_state;
 struct vlv_s0ix_state;
 
-/* Threshold == 5 for long IRQs, 50 for short */
-#define HPD_STORM_DEFAULT_THRESHOLD 50
-
 #define I915_GEM_GPU_DOMAINS \
        (I915_GEM_DOMAIN_RENDER | \
         I915_GEM_DOMAIN_SAMPLER | \
@@ -871,6 +868,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define HAS_DOUBLE_BUFFERED_M_N(dev_priv)      (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
 
 #define HAS_CDCLK_CRAWL(dev_priv)       (INTEL_INFO(dev_priv)->display.has_cdclk_crawl)
+#define HAS_CDCLK_SQUASH(dev_priv)      (INTEL_INFO(dev_priv)->display.has_cdclk_squash)
 #define HAS_DDI(dev_priv)               (INTEL_INFO(dev_priv)->display.has_ddi)
 #define HAS_FPGA_DBG_UNCLAIMED(dev_priv) (INTEL_INFO(dev_priv)->display.has_fpga_dbg)
 #define HAS_PSR(dev_priv)               (INTEL_INFO(dev_priv)->display.has_psr)
@@ -938,6 +936,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 
 #define HAS_GMCH(dev_priv) (INTEL_INFO(dev_priv)->display.has_gmch)
 
+#define HAS_GMD_ID(i915)       (INTEL_INFO(i915)->has_gmd_id)
+
 #define HAS_LSPCON(dev_priv) (IS_DISPLAY_VER(dev_priv, 9, 10))
 
 #define HAS_L3_CCS_READ(i915) (INTEL_INFO(i915)->has_l3_ccs_read)
index 86a42d9..d688598 100644 (file)
@@ -325,15 +325,10 @@ i915_hotplug_interrupt_update_locked(struct drm_i915_private *dev_priv,
                                     u32 mask,
                                     u32 bits)
 {
-       u32 val;
-
        lockdep_assert_held(&dev_priv->irq_lock);
        drm_WARN_ON(&dev_priv->drm, bits & ~mask);
 
-       val = intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_EN);
-       val &= ~mask;
-       val |= bits;
-       intel_uncore_write(&dev_priv->uncore, PORT_HOTPLUG_EN, val);
+       intel_uncore_rmw(&dev_priv->uncore, PORT_HOTPLUG_EN, mask, bits);
 }
 
 /**
@@ -1057,8 +1052,8 @@ static void ivb_parity_work(struct work_struct *work)
        if (drm_WARN_ON(&dev_priv->drm, !dev_priv->l3_parity.which_slice))
                goto out;
 
-       misccpctl = intel_uncore_read(&dev_priv->uncore, GEN7_MISCCPCTL);
-       intel_uncore_write(&dev_priv->uncore, GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
+       misccpctl = intel_uncore_rmw(&dev_priv->uncore, GEN7_MISCCPCTL,
+                                    GEN7_DOP_CLOCK_GATE_ENABLE, 0);
        intel_uncore_posting_read(&dev_priv->uncore, GEN7_MISCCPCTL);
 
        while ((slice = ffs(dev_priv->l3_parity.which_slice)) != 0) {
@@ -1689,8 +1684,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
                 * bits this time around.
                 */
                intel_uncore_write(&dev_priv->uncore, VLV_MASTER_IER, 0);
-               ier = intel_uncore_read(&dev_priv->uncore, VLV_IER);
-               intel_uncore_write(&dev_priv->uncore, VLV_IER, 0);
+               ier = intel_uncore_rmw(&dev_priv->uncore, VLV_IER, ~0, 0);
 
                if (gt_iir)
                        intel_uncore_write(&dev_priv->uncore, GTIIR, gt_iir);
@@ -1775,8 +1769,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
                 * bits this time around.
                 */
                intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, 0);
-               ier = intel_uncore_read(&dev_priv->uncore, VLV_IER);
-               intel_uncore_write(&dev_priv->uncore, VLV_IER, 0);
+               ier = intel_uncore_rmw(&dev_priv->uncore, VLV_IER, ~0, 0);
 
                gen8_gt_irq_handler(to_gt(dev_priv), master_ctl);
 
@@ -1981,8 +1974,7 @@ static void icp_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
        if (ddi_hotplug_trigger) {
                u32 dig_hotplug_reg;
 
-               dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, SHOTPLUG_CTL_DDI);
-               intel_uncore_write(&dev_priv->uncore, SHOTPLUG_CTL_DDI, dig_hotplug_reg);
+               dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_DDI, 0, 0);
 
                intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
                                   ddi_hotplug_trigger, dig_hotplug_reg,
@@ -1993,8 +1985,7 @@ static void icp_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
        if (tc_hotplug_trigger) {
                u32 dig_hotplug_reg;
 
-               dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, SHOTPLUG_CTL_TC);
-               intel_uncore_write(&dev_priv->uncore, SHOTPLUG_CTL_TC, dig_hotplug_reg);
+               dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_TC, 0, 0);
 
                intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
                                   tc_hotplug_trigger, dig_hotplug_reg,
@@ -2019,8 +2010,7 @@ static 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_read(&dev_priv->uncore, PCH_PORT_HOTPLUG);
-               intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, dig_hotplug_reg);
+               dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG, 0, 0);
 
                intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
                                   hotplug_trigger, dig_hotplug_reg,
@@ -2031,8 +2021,7 @@ static void spt_irq_handler(struct drm_i915_private *dev_priv, u32 pch_iir)
        if (hotplug2_trigger) {
                u32 dig_hotplug_reg;
 
-               dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG2);
-               intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG2, dig_hotplug_reg);
+               dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG2, 0, 0);
 
                intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
                                   hotplug2_trigger, dig_hotplug_reg,
@@ -2052,8 +2041,7 @@ static void ilk_hpd_irq_handler(struct drm_i915_private *dev_priv,
 {
        u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0;
 
-       dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL);
-       intel_uncore_write(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL, dig_hotplug_reg);
+       dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL, 0, 0);
 
        intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
                           hotplug_trigger, dig_hotplug_reg,
@@ -2232,8 +2220,7 @@ static void bxt_hpd_irq_handler(struct drm_i915_private *dev_priv,
 {
        u32 dig_hotplug_reg, pin_mask = 0, long_mask = 0;
 
-       dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG);
-       intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, dig_hotplug_reg);
+       dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG, 0, 0);
 
        intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
                           hotplug_trigger, dig_hotplug_reg,
@@ -2252,8 +2239,7 @@ static 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_read(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL);
-               intel_uncore_write(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL, dig_hotplug_reg);
+               dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL, 0, 0);
 
                intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
                                   trigger_tc, dig_hotplug_reg,
@@ -2264,8 +2250,7 @@ static void gen11_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 iir)
        if (trigger_tbt) {
                u32 dig_hotplug_reg;
 
-               dig_hotplug_reg = intel_uncore_read(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL);
-               intel_uncore_write(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL, dig_hotplug_reg);
+               dig_hotplug_reg = intel_uncore_rmw(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL, 0, 0);
 
                intel_get_hpd_pins(dev_priv, &pin_mask, &long_mask,
                                   trigger_tbt, dig_hotplug_reg,
@@ -2355,8 +2340,7 @@ gen8_de_misc_irq_handler(struct drm_i915_private *dev_priv, u32 iir)
                        else
                                iir_reg = EDP_PSR_IIR;
 
-                       psr_iir = intel_uncore_read(&dev_priv->uncore, iir_reg);
-                       intel_uncore_write(&dev_priv->uncore, iir_reg, psr_iir);
+                       psr_iir = intel_uncore_rmw(&dev_priv->uncore, iir_reg, 0, 0);
 
                        if (psr_iir)
                                found = true;
@@ -2426,8 +2410,7 @@ static void gen11_dsi_te_interrupt_handler(struct drm_i915_private *dev_priv,
 
        /* clear TE in dsi IIR */
        port = (te_trigger & DSI1_TE) ? PORT_B : PORT_A;
-       tmp = intel_uncore_read(&dev_priv->uncore, DSI_INTR_IDENT_REG(port));
-       intel_uncore_write(&dev_priv->uncore, DSI_INTR_IDENT_REG(port), tmp);
+       tmp = intel_uncore_rmw(&dev_priv->uncore, DSI_INTR_IDENT_REG(port), 0, 0);
 }
 
 static u32 gen8_de_pipe_flip_done_mask(struct drm_i915_private *i915)
@@ -2884,7 +2867,6 @@ static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc,
 {
        struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
        enum port port;
-       u32 tmp;
 
        if (!(intel_crtc->mode_flags &
            (I915_MODE_FLAG_DSI_USE_TE1 | I915_MODE_FLAG_DSI_USE_TE0)))
@@ -2896,16 +2878,10 @@ static bool gen11_dsi_configure_te(struct intel_crtc *intel_crtc,
        else
                port = PORT_A;
 
-       tmp =  intel_uncore_read(&dev_priv->uncore, DSI_INTR_MASK_REG(port));
-       if (enable)
-               tmp &= ~DSI_TE_EVENT;
-       else
-               tmp |= DSI_TE_EVENT;
-
-       intel_uncore_write(&dev_priv->uncore, DSI_INTR_MASK_REG(port), tmp);
+       intel_uncore_rmw(&dev_priv->uncore, DSI_INTR_MASK_REG(port), DSI_TE_EVENT,
+                        enable ? 0 : DSI_TE_EVENT);
 
-       tmp = intel_uncore_read(&dev_priv->uncore, DSI_INTR_IDENT_REG(port));
-       intel_uncore_write(&dev_priv->uncore, DSI_INTR_IDENT_REG(port), tmp);
+       intel_uncore_rmw(&dev_priv->uncore, DSI_INTR_IDENT_REG(port), 0, 0);
 
        return true;
 }
@@ -3020,7 +2996,7 @@ static void vlv_display_irq_reset(struct drm_i915_private *dev_priv)
                intel_uncore_write(uncore, DPINVGTT, DPINVGTT_STATUS_MASK_VLV);
 
        i915_hotplug_interrupt_update_locked(dev_priv, 0xffffffff, 0);
-       intel_uncore_write(uncore, PORT_HOTPLUG_STAT, intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT));
+       intel_uncore_rmw(uncore, PORT_HOTPLUG_STAT, 0, 0);
 
        i9xx_pipestat_irq_reset(dev_priv);
 
@@ -3118,7 +3094,7 @@ static void gen8_irq_reset(struct drm_i915_private *dev_priv)
 {
        struct intel_uncore *uncore = &dev_priv->uncore;
 
-       gen8_master_intr_disable(dev_priv->uncore.regs);
+       gen8_master_intr_disable(uncore->regs);
 
        gen8_gt_irq_reset(to_gt(dev_priv));
        gen8_display_irq_reset(dev_priv);
@@ -3250,7 +3226,7 @@ static void cherryview_irq_reset(struct drm_i915_private *dev_priv)
 {
        struct intel_uncore *uncore = &dev_priv->uncore;
 
-       intel_uncore_write(&dev_priv->uncore, GEN8_MASTER_IRQ, 0);
+       intel_uncore_write(uncore, GEN8_MASTER_IRQ, 0);
        intel_uncore_posting_read(&dev_priv->uncore, GEN8_MASTER_IRQ);
 
        gen8_gt_irq_reset(to_gt(dev_priv));
@@ -3290,23 +3266,20 @@ static u32 ibx_hotplug_enables(struct drm_i915_private *i915,
 
 static void ibx_hpd_detection_setup(struct drm_i915_private *dev_priv)
 {
-       u32 hotplug;
-
        /*
         * 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+.
         */
-       hotplug = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG);
-       hotplug &= ~(PORTA_HOTPLUG_ENABLE |
-                    PORTB_HOTPLUG_ENABLE |
-                    PORTC_HOTPLUG_ENABLE |
-                    PORTD_HOTPLUG_ENABLE |
-                    PORTB_PULSE_DURATION_MASK |
-                    PORTC_PULSE_DURATION_MASK |
-                    PORTD_PULSE_DURATION_MASK);
-       hotplug |= intel_hpd_hotplug_enables(dev_priv, ibx_hotplug_enables);
-       intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, hotplug);
+       intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG,
+                        PORTA_HOTPLUG_ENABLE |
+                        PORTB_HOTPLUG_ENABLE |
+                        PORTC_HOTPLUG_ENABLE |
+                        PORTD_HOTPLUG_ENABLE |
+                        PORTB_PULSE_DURATION_MASK |
+                        PORTC_PULSE_DURATION_MASK |
+                        PORTD_PULSE_DURATION_MASK,
+                        intel_hpd_hotplug_enables(dev_priv, ibx_hotplug_enables));
 }
 
 static void ibx_hpd_irq_setup(struct drm_i915_private *dev_priv)
@@ -3353,30 +3326,24 @@ static u32 icp_tc_hotplug_enables(struct drm_i915_private *i915,
 
 static void icp_ddi_hpd_detection_setup(struct drm_i915_private *dev_priv)
 {
-       u32 hotplug;
-
-       hotplug = intel_uncore_read(&dev_priv->uncore, SHOTPLUG_CTL_DDI);
-       hotplug &= ~(SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_A) |
-                    SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_B) |
-                    SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_C) |
-                    SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_D));
-       hotplug |= intel_hpd_hotplug_enables(dev_priv, icp_ddi_hotplug_enables);
-       intel_uncore_write(&dev_priv->uncore, SHOTPLUG_CTL_DDI, hotplug);
+       intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_DDI,
+                        SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_A) |
+                        SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_B) |
+                        SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_C) |
+                        SHOTPLUG_CTL_DDI_HPD_ENABLE(HPD_PORT_D),
+                        intel_hpd_hotplug_enables(dev_priv, icp_ddi_hotplug_enables));
 }
 
 static void icp_tc_hpd_detection_setup(struct drm_i915_private *dev_priv)
 {
-       u32 hotplug;
-
-       hotplug = intel_uncore_read(&dev_priv->uncore, SHOTPLUG_CTL_TC);
-       hotplug &= ~(ICP_TC_HPD_ENABLE(HPD_PORT_TC1) |
-                    ICP_TC_HPD_ENABLE(HPD_PORT_TC2) |
-                    ICP_TC_HPD_ENABLE(HPD_PORT_TC3) |
-                    ICP_TC_HPD_ENABLE(HPD_PORT_TC4) |
-                    ICP_TC_HPD_ENABLE(HPD_PORT_TC5) |
-                    ICP_TC_HPD_ENABLE(HPD_PORT_TC6));
-       hotplug |= intel_hpd_hotplug_enables(dev_priv, icp_tc_hotplug_enables);
-       intel_uncore_write(&dev_priv->uncore, SHOTPLUG_CTL_TC, hotplug);
+       intel_uncore_rmw(&dev_priv->uncore, SHOTPLUG_CTL_TC,
+                        ICP_TC_HPD_ENABLE(HPD_PORT_TC1) |
+                        ICP_TC_HPD_ENABLE(HPD_PORT_TC2) |
+                        ICP_TC_HPD_ENABLE(HPD_PORT_TC3) |
+                        ICP_TC_HPD_ENABLE(HPD_PORT_TC4) |
+                        ICP_TC_HPD_ENABLE(HPD_PORT_TC5) |
+                        ICP_TC_HPD_ENABLE(HPD_PORT_TC6),
+                        intel_hpd_hotplug_enables(dev_priv, icp_tc_hotplug_enables));
 }
 
 static void icp_hpd_irq_setup(struct drm_i915_private *dev_priv)
@@ -3411,62 +3378,54 @@ static u32 gen11_hotplug_enables(struct drm_i915_private *i915,
        }
 }
 
-static void dg1_hpd_irq_setup(struct drm_i915_private *dev_priv)
+static void dg1_hpd_invert(struct drm_i915_private *i915)
 {
-       u32 val;
-
-       val = intel_uncore_read(&dev_priv->uncore, SOUTH_CHICKEN1);
-       val |= (INVERT_DDIA_HPD |
-               INVERT_DDIB_HPD |
-               INVERT_DDIC_HPD |
-               INVERT_DDID_HPD);
-       intel_uncore_write(&dev_priv->uncore, SOUTH_CHICKEN1, val);
+       u32 val = (INVERT_DDIA_HPD |
+                  INVERT_DDIB_HPD |
+                  INVERT_DDIC_HPD |
+                  INVERT_DDID_HPD);
+       intel_uncore_rmw(&i915->uncore, SOUTH_CHICKEN1, 0, val);
+}
 
+static void dg1_hpd_irq_setup(struct drm_i915_private *dev_priv)
+{
+       dg1_hpd_invert(dev_priv);
        icp_hpd_irq_setup(dev_priv);
 }
 
 static void gen11_tc_hpd_detection_setup(struct drm_i915_private *dev_priv)
 {
-       u32 hotplug;
-
-       hotplug = intel_uncore_read(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL);
-       hotplug &= ~(GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC1) |
-                    GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC2) |
-                    GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC3) |
-                    GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC4) |
-                    GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC5) |
-                    GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC6));
-       hotplug |= intel_hpd_hotplug_enables(dev_priv, gen11_hotplug_enables);
-       intel_uncore_write(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL, hotplug);
+       intel_uncore_rmw(&dev_priv->uncore, GEN11_TC_HOTPLUG_CTL,
+                        GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC1) |
+                        GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC2) |
+                        GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC3) |
+                        GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC4) |
+                        GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC5) |
+                        GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC6),
+                        intel_hpd_hotplug_enables(dev_priv, gen11_hotplug_enables));
 }
 
 static void gen11_tbt_hpd_detection_setup(struct drm_i915_private *dev_priv)
 {
-       u32 hotplug;
-
-       hotplug = intel_uncore_read(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL);
-       hotplug &= ~(GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC1) |
-                    GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC2) |
-                    GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC3) |
-                    GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC4) |
-                    GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC5) |
-                    GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC6));
-       hotplug |= intel_hpd_hotplug_enables(dev_priv, gen11_hotplug_enables);
-       intel_uncore_write(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL, hotplug);
+       intel_uncore_rmw(&dev_priv->uncore, GEN11_TBT_HOTPLUG_CTL,
+                        GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC1) |
+                        GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC2) |
+                        GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC3) |
+                        GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC4) |
+                        GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC5) |
+                        GEN11_HOTPLUG_CTL_ENABLE(HPD_PORT_TC6),
+                        intel_hpd_hotplug_enables(dev_priv, gen11_hotplug_enables));
 }
 
 static void gen11_hpd_irq_setup(struct drm_i915_private *dev_priv)
 {
        u32 hotplug_irqs, enabled_irqs;
-       u32 val;
 
        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);
 
-       val = intel_uncore_read(&dev_priv->uncore, GEN11_DE_HPD_IMR);
-       val &= ~hotplug_irqs;
-       val |= ~enabled_irqs & hotplug_irqs;
-       intel_uncore_write(&dev_priv->uncore, GEN11_DE_HPD_IMR, val);
+       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);
 
        gen11_tc_hpd_detection_setup(dev_priv);
@@ -3506,29 +3465,22 @@ static u32 spt_hotplug2_enables(struct drm_i915_private *i915,
 
 static void spt_hpd_detection_setup(struct drm_i915_private *dev_priv)
 {
-       u32 val, hotplug;
-
        /* Display WA #1179 WaHardHangonHotPlug: cnp */
        if (HAS_PCH_CNP(dev_priv)) {
-               val = intel_uncore_read(&dev_priv->uncore, SOUTH_CHICKEN1);
-               val &= ~CHASSIS_CLK_REQ_DURATION_MASK;
-               val |= CHASSIS_CLK_REQ_DURATION(0xf);
-               intel_uncore_write(&dev_priv->uncore, SOUTH_CHICKEN1, val);
+               intel_uncore_rmw(&dev_priv->uncore, SOUTH_CHICKEN1, CHASSIS_CLK_REQ_DURATION_MASK,
+                                CHASSIS_CLK_REQ_DURATION(0xf));
        }
 
        /* Enable digital hotplug on the PCH */
-       hotplug = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG);
-       hotplug &= ~(PORTA_HOTPLUG_ENABLE |
-                    PORTB_HOTPLUG_ENABLE |
-                    PORTC_HOTPLUG_ENABLE |
-                    PORTD_HOTPLUG_ENABLE);
-       hotplug |= intel_hpd_hotplug_enables(dev_priv, spt_hotplug_enables);
-       intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, hotplug);
+       intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG,
+                        PORTA_HOTPLUG_ENABLE |
+                        PORTB_HOTPLUG_ENABLE |
+                        PORTC_HOTPLUG_ENABLE |
+                        PORTD_HOTPLUG_ENABLE,
+                        intel_hpd_hotplug_enables(dev_priv, spt_hotplug_enables));
 
-       hotplug = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG2);
-       hotplug &= ~PORTE_HOTPLUG_ENABLE;
-       hotplug |= intel_hpd_hotplug_enables(dev_priv, spt_hotplug2_enables);
-       intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG2, hotplug);
+       intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG2, PORTE_HOTPLUG_ENABLE,
+                        intel_hpd_hotplug_enables(dev_priv, spt_hotplug2_enables));
 }
 
 static void spt_hpd_irq_setup(struct drm_i915_private *dev_priv)
@@ -3560,18 +3512,14 @@ static u32 ilk_hotplug_enables(struct drm_i915_private *i915,
 
 static void ilk_hpd_detection_setup(struct drm_i915_private *dev_priv)
 {
-       u32 hotplug;
-
        /*
         * 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+.
         */
-       hotplug = intel_uncore_read(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL);
-       hotplug &= ~(DIGITAL_PORTA_HOTPLUG_ENABLE |
-                    DIGITAL_PORTA_PULSE_DURATION_MASK);
-       hotplug |= intel_hpd_hotplug_enables(dev_priv, ilk_hotplug_enables);
-       intel_uncore_write(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL, hotplug);
+       intel_uncore_rmw(&dev_priv->uncore, DIGITAL_PORT_HOTPLUG_CNTRL,
+                        DIGITAL_PORTA_HOTPLUG_ENABLE | DIGITAL_PORTA_PULSE_DURATION_MASK,
+                        intel_hpd_hotplug_enables(dev_priv, ilk_hotplug_enables));
 }
 
 static void ilk_hpd_irq_setup(struct drm_i915_private *dev_priv)
@@ -3619,17 +3567,12 @@ static u32 bxt_hotplug_enables(struct drm_i915_private *i915,
 
 static void bxt_hpd_detection_setup(struct drm_i915_private *dev_priv)
 {
-       u32 hotplug;
-
-       hotplug = intel_uncore_read(&dev_priv->uncore, PCH_PORT_HOTPLUG);
-       hotplug &= ~(PORTA_HOTPLUG_ENABLE |
-                    PORTB_HOTPLUG_ENABLE |
-                    PORTC_HOTPLUG_ENABLE |
-                    BXT_DDIA_HPD_INVERT |
-                    BXT_DDIB_HPD_INVERT |
-                    BXT_DDIC_HPD_INVERT);
-       hotplug |= intel_hpd_hotplug_enables(dev_priv, bxt_hotplug_enables);
-       intel_uncore_write(&dev_priv->uncore, PCH_PORT_HOTPLUG, hotplug);
+       intel_uncore_rmw(&dev_priv->uncore, PCH_PORT_HOTPLUG,
+                        PORTA_HOTPLUG_ENABLE |
+                        PORTB_HOTPLUG_ENABLE |
+                        PORTC_HOTPLUG_ENABLE |
+                        BXT_DDI_HPD_INVERT_MASK,
+                        intel_hpd_hotplug_enables(dev_priv, bxt_hotplug_enables));
 }
 
 static void bxt_hpd_irq_setup(struct drm_i915_private *dev_priv)
@@ -4009,9 +3952,7 @@ static void i9xx_error_irq_ack(struct drm_i915_private *dev_priv,
 {
        u32 emr;
 
-       *eir = intel_uncore_read(&dev_priv->uncore, EIR);
-
-       intel_uncore_write(&dev_priv->uncore, EIR, *eir);
+       *eir = intel_uncore_rmw(&dev_priv->uncore, EIR, 0, 0);
 
        *eir_stuck = intel_uncore_read(&dev_priv->uncore, EIR);
        if (*eir_stuck == 0)
@@ -4027,8 +3968,7 @@ static void i9xx_error_irq_ack(struct drm_i915_private *dev_priv,
         * (or by a GPU reset) so we mask any bit that
         * remains set.
         */
-       emr = intel_uncore_read(&dev_priv->uncore, EMR);
-       intel_uncore_write(&dev_priv->uncore, EMR, 0xffffffff);
+       emr = intel_uncore_rmw(&dev_priv->uncore, EMR, ~0, 0xffffffff);
        intel_uncore_write(&dev_priv->uncore, EMR, emr | *eir_stuck);
 }
 
@@ -4095,7 +4035,7 @@ static void i915_irq_reset(struct drm_i915_private *dev_priv)
 
        if (I915_HAS_HOTPLUG(dev_priv)) {
                i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
-               intel_uncore_write(&dev_priv->uncore, PORT_HOTPLUG_STAT, intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT));
+               intel_uncore_rmw(&dev_priv->uncore, PORT_HOTPLUG_STAT, 0, 0);
        }
 
        i9xx_pipestat_irq_reset(dev_priv);
@@ -4109,8 +4049,8 @@ static void i915_irq_postinstall(struct drm_i915_private *dev_priv)
        struct intel_uncore *uncore = &dev_priv->uncore;
        u32 enable_mask;
 
-       intel_uncore_write(&dev_priv->uncore, EMR, ~(I915_ERROR_PAGE_TABLE |
-                         I915_ERROR_MEMORY_REFRESH));
+       intel_uncore_write(uncore, EMR, ~(I915_ERROR_PAGE_TABLE |
+                                         I915_ERROR_MEMORY_REFRESH));
 
        /* Unmask the interrupts that we always want on. */
        dev_priv->irq_mask =
@@ -4205,7 +4145,7 @@ static void i965_irq_reset(struct drm_i915_private *dev_priv)
        struct intel_uncore *uncore = &dev_priv->uncore;
 
        i915_hotplug_interrupt_update(dev_priv, 0xffffffff, 0);
-       intel_uncore_write(&dev_priv->uncore, PORT_HOTPLUG_STAT, intel_uncore_read(&dev_priv->uncore, PORT_HOTPLUG_STAT));
+       intel_uncore_rmw(uncore, PORT_HOTPLUG_STAT, 0, 0);
 
        i9xx_pipestat_irq_reset(dev_priv);
 
@@ -4232,7 +4172,7 @@ static void i965_irq_postinstall(struct drm_i915_private *dev_priv)
                error_mask = ~(I915_ERROR_PAGE_TABLE |
                               I915_ERROR_MEMORY_REFRESH);
        }
-       intel_uncore_write(&dev_priv->uncore, EMR, error_mask);
+       intel_uncore_write(uncore, EMR, error_mask);
 
        /* Unmask the interrupts that we always want on. */
        dev_priv->irq_mask =
@@ -4383,7 +4323,6 @@ void intel_hpd_irq_setup(struct drm_i915_private *i915)
  */
 void intel_irq_init(struct drm_i915_private *dev_priv)
 {
-       struct drm_device *dev = &dev_priv->drm;
        int i;
 
        INIT_WORK(&dev_priv->l3_parity.error_work, ivb_parity_work);
@@ -4399,9 +4338,9 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
 
        intel_hpd_init_pins(dev_priv);
 
-       intel_hpd_init_work(dev_priv);
+       intel_hpd_init_early(dev_priv);
 
-       dev->vblank_disable_immediate = true;
+       dev_priv->drm.vblank_disable_immediate = true;
 
        /* Most platforms treat the display irq block as an always-on
         * power domain. vlv/chv can disable it at runtime and need
@@ -4413,15 +4352,6 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
        if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
                dev_priv->display_irqs_enabled = false;
 
-       dev_priv->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.
-        */
-       dev_priv->display.hotplug.hpd_short_storm_enabled = !HAS_DP_MST(dev_priv);
-
        if (HAS_GMCH(dev_priv)) {
                if (I915_HAS_HOTPLUG(dev_priv))
                        dev_priv->display.funcs.hotplug = &i915_hpd_funcs;
index cd4487a..9486127 100644 (file)
@@ -1066,6 +1066,7 @@ static const struct intel_device_info xehpsdv_info = {
        .has_heci_pxp = 1, \
        .needs_compact_pt = 1, \
        .has_media_ratio_mode = 1, \
+       .display.has_cdclk_squash = 1, \
        .__runtime.platform_engine_mask = \
                BIT(RCS0) | BIT(BCS0) | \
                BIT(VECS0) | BIT(VECS1) | \
@@ -1144,6 +1145,7 @@ static const struct intel_device_info mtl_info = {
        .display.has_modular_fia = 1,
        .extra_gt_list = xelpmp_extra_gt,
        .has_flat_ccs = 0,
+       .has_gmd_id = 1,
        .has_snoop = 1,
        .__runtime.memory_regions = REGION_SMEM | REGION_STOLEN_LMEM,
        .__runtime.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(CCS0),
index 0b287a5..2a887cd 100644 (file)
 #define ICL_DSSM_CDCLK_PLL_REFCLK_19_2MHz      (1 << 29)
 #define ICL_DSSM_CDCLK_PLL_REFCLK_38_4MHz      (2 << 29)
 
+#define GMD_ID_DISPLAY                         _MMIO(0x510a0)
+#define   GMD_ID_ARCH_MASK                     REG_GENMASK(31, 22)
+#define   GMD_ID_RELEASE_MASK                  REG_GENMASK(21, 14)
+#define   GMD_ID_STEP                          REG_GENMASK(5, 0)
+
 /*GEN11 chicken */
 #define _PIPEA_CHICKEN                         0x70038
 #define _PIPEB_CHICKEN                         0x71038
@@ -7413,182 +7418,6 @@ enum skl_power_gate {
                                                   _ADLS_DPLL4_CFGCR1, \
                                                   _ADLS_DPLL3_CFGCR1)
 
-#define _DKL_PHY1_BASE                 0x168000
-#define _DKL_PHY2_BASE                 0x169000
-#define _DKL_PHY3_BASE                 0x16A000
-#define _DKL_PHY4_BASE                 0x16B000
-#define _DKL_PHY5_BASE                 0x16C000
-#define _DKL_PHY6_BASE                 0x16D000
-
-/* DEKEL PHY MMIO Address = Phy base + (internal address & ~index_mask) */
-#define _DKL_PCS_DW5                   0x14
-#define DKL_PCS_DW5(tc_port)           _MMIO(_PORT(tc_port, _DKL_PHY1_BASE, \
-                                                   _DKL_PHY2_BASE) + \
-                                                   _DKL_PCS_DW5)
-#define   DKL_PCS_DW5_CORE_SOFTRESET   REG_BIT(11)
-
-#define _DKL_PLL_DIV0                  0x200
-#define   DKL_PLL_DIV0_AFC_STARTUP_MASK        REG_GENMASK(27, 25)
-#define   DKL_PLL_DIV0_AFC_STARTUP(val)        REG_FIELD_PREP(DKL_PLL_DIV0_AFC_STARTUP_MASK, (val))
-#define   DKL_PLL_DIV0_INTEG_COEFF(x)  ((x) << 16)
-#define   DKL_PLL_DIV0_INTEG_COEFF_MASK        (0x1F << 16)
-#define   DKL_PLL_DIV0_PROP_COEFF(x)   ((x) << 12)
-#define   DKL_PLL_DIV0_PROP_COEFF_MASK (0xF << 12)
-#define   DKL_PLL_DIV0_FBPREDIV_SHIFT   (8)
-#define   DKL_PLL_DIV0_FBPREDIV(x)     ((x) << DKL_PLL_DIV0_FBPREDIV_SHIFT)
-#define   DKL_PLL_DIV0_FBPREDIV_MASK   (0xF << DKL_PLL_DIV0_FBPREDIV_SHIFT)
-#define   DKL_PLL_DIV0_FBDIV_INT(x)    ((x) << 0)
-#define   DKL_PLL_DIV0_FBDIV_INT_MASK  (0xFF << 0)
-#define   DKL_PLL_DIV0_MASK            (DKL_PLL_DIV0_INTEG_COEFF_MASK | \
-                                        DKL_PLL_DIV0_PROP_COEFF_MASK | \
-                                        DKL_PLL_DIV0_FBPREDIV_MASK | \
-                                        DKL_PLL_DIV0_FBDIV_INT_MASK)
-#define DKL_PLL_DIV0(tc_port)          _MMIO(_PORT(tc_port, _DKL_PHY1_BASE, \
-                                                   _DKL_PHY2_BASE) + \
-                                                   _DKL_PLL_DIV0)
-
-#define _DKL_PLL_DIV1                          0x204
-#define   DKL_PLL_DIV1_IREF_TRIM(x)            ((x) << 16)
-#define   DKL_PLL_DIV1_IREF_TRIM_MASK          (0x1F << 16)
-#define   DKL_PLL_DIV1_TDC_TARGET_CNT(x)       ((x) << 0)
-#define   DKL_PLL_DIV1_TDC_TARGET_CNT_MASK     (0xFF << 0)
-#define DKL_PLL_DIV1(tc_port)          _MMIO(_PORT(tc_port, _DKL_PHY1_BASE, \
-                                                   _DKL_PHY2_BASE) + \
-                                                   _DKL_PLL_DIV1)
-
-#define _DKL_PLL_SSC                           0x210
-#define   DKL_PLL_SSC_IREF_NDIV_RATIO(x)       ((x) << 29)
-#define   DKL_PLL_SSC_IREF_NDIV_RATIO_MASK     (0x7 << 29)
-#define   DKL_PLL_SSC_STEP_LEN(x)              ((x) << 16)
-#define   DKL_PLL_SSC_STEP_LEN_MASK            (0xFF << 16)
-#define   DKL_PLL_SSC_STEP_NUM(x)              ((x) << 11)
-#define   DKL_PLL_SSC_STEP_NUM_MASK            (0x7 << 11)
-#define   DKL_PLL_SSC_EN                       (1 << 9)
-#define DKL_PLL_SSC(tc_port)           _MMIO(_PORT(tc_port, _DKL_PHY1_BASE, \
-                                                   _DKL_PHY2_BASE) + \
-                                                   _DKL_PLL_SSC)
-
-#define _DKL_PLL_BIAS                  0x214
-#define   DKL_PLL_BIAS_FRAC_EN_H       (1 << 30)
-#define   DKL_PLL_BIAS_FBDIV_SHIFT     (8)
-#define   DKL_PLL_BIAS_FBDIV_FRAC(x)   ((x) << DKL_PLL_BIAS_FBDIV_SHIFT)
-#define   DKL_PLL_BIAS_FBDIV_FRAC_MASK (0x3FFFFF << DKL_PLL_BIAS_FBDIV_SHIFT)
-#define DKL_PLL_BIAS(tc_port)          _MMIO(_PORT(tc_port, _DKL_PHY1_BASE, \
-                                                   _DKL_PHY2_BASE) + \
-                                                   _DKL_PLL_BIAS)
-
-#define _DKL_PLL_TDC_COLDST_BIAS               0x218
-#define   DKL_PLL_TDC_SSC_STEP_SIZE(x)         ((x) << 8)
-#define   DKL_PLL_TDC_SSC_STEP_SIZE_MASK       (0xFF << 8)
-#define   DKL_PLL_TDC_FEED_FWD_GAIN(x)         ((x) << 0)
-#define   DKL_PLL_TDC_FEED_FWD_GAIN_MASK       (0xFF << 0)
-#define DKL_PLL_TDC_COLDST_BIAS(tc_port) _MMIO(_PORT(tc_port, \
-                                                    _DKL_PHY1_BASE, \
-                                                    _DKL_PHY2_BASE) + \
-                                                    _DKL_PLL_TDC_COLDST_BIAS)
-
-#define _DKL_REFCLKIN_CTL              0x12C
-/* Bits are the same as MG_REFCLKIN_CTL */
-#define DKL_REFCLKIN_CTL(tc_port)      _MMIO(_PORT(tc_port, \
-                                                   _DKL_PHY1_BASE, \
-                                                   _DKL_PHY2_BASE) + \
-                                             _DKL_REFCLKIN_CTL)
-
-#define _DKL_CLKTOP2_HSCLKCTL          0xD4
-/* Bits are the same as MG_CLKTOP2_HSCLKCTL */
-#define DKL_CLKTOP2_HSCLKCTL(tc_port)  _MMIO(_PORT(tc_port, \
-                                                   _DKL_PHY1_BASE, \
-                                                   _DKL_PHY2_BASE) + \
-                                             _DKL_CLKTOP2_HSCLKCTL)
-
-#define _DKL_CLKTOP2_CORECLKCTL1               0xD8
-/* Bits are the same as MG_CLKTOP2_CORECLKCTL1 */
-#define DKL_CLKTOP2_CORECLKCTL1(tc_port)       _MMIO(_PORT(tc_port, \
-                                                           _DKL_PHY1_BASE, \
-                                                           _DKL_PHY2_BASE) + \
-                                                     _DKL_CLKTOP2_CORECLKCTL1)
-
-#define _DKL_TX_DPCNTL0                                0x2C0
-#define  DKL_TX_PRESHOOT_COEFF(x)                      ((x) << 13)
-#define  DKL_TX_PRESHOOT_COEFF_MASK                    (0x1f << 13)
-#define  DKL_TX_DE_EMPHASIS_COEFF(x)           ((x) << 8)
-#define  DKL_TX_DE_EMPAHSIS_COEFF_MASK         (0x1f << 8)
-#define  DKL_TX_VSWING_CONTROL(x)                      ((x) << 0)
-#define  DKL_TX_VSWING_CONTROL_MASK                    (0x7 << 0)
-#define DKL_TX_DPCNTL0(tc_port) _MMIO(_PORT(tc_port, \
-                                                    _DKL_PHY1_BASE, \
-                                                    _DKL_PHY2_BASE) + \
-                                                    _DKL_TX_DPCNTL0)
-
-#define _DKL_TX_DPCNTL1                                0x2C4
-/* Bits are the same as DKL_TX_DPCNTRL0 */
-#define DKL_TX_DPCNTL1(tc_port) _MMIO(_PORT(tc_port, \
-                                                    _DKL_PHY1_BASE, \
-                                                    _DKL_PHY2_BASE) + \
-                                                    _DKL_TX_DPCNTL1)
-
-#define _DKL_TX_DPCNTL2                                        0x2C8
-#define  DKL_TX_DP20BITMODE                            REG_BIT(2)
-#define  DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK     REG_GENMASK(4, 3)
-#define  DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1(val)     REG_FIELD_PREP(DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK, (val))
-#define  DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK     REG_GENMASK(6, 5)
-#define  DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2(val)     REG_FIELD_PREP(DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK, (val))
-#define DKL_TX_DPCNTL2(tc_port) _MMIO(_PORT(tc_port, \
-                                                    _DKL_PHY1_BASE, \
-                                                    _DKL_PHY2_BASE) + \
-                                                    _DKL_TX_DPCNTL2)
-
-#define _DKL_TX_FW_CALIB                               0x2F8
-#define  DKL_TX_CFG_DISABLE_WAIT_INIT                  (1 << 7)
-#define DKL_TX_FW_CALIB(tc_port) _MMIO(_PORT(tc_port, \
-                                                    _DKL_PHY1_BASE, \
-                                                    _DKL_PHY2_BASE) + \
-                                                    _DKL_TX_FW_CALIB)
-
-#define _DKL_TX_PMD_LANE_SUS                           0xD00
-#define DKL_TX_PMD_LANE_SUS(tc_port) _MMIO(_PORT(tc_port, \
-                                                         _DKL_PHY1_BASE, \
-                                                         _DKL_PHY2_BASE) + \
-                                                         _DKL_TX_PMD_LANE_SUS)
-
-#define _DKL_TX_DW17                                   0xDC4
-#define DKL_TX_DW17(tc_port) _MMIO(_PORT(tc_port, \
-                                                    _DKL_PHY1_BASE, \
-                                                    _DKL_PHY2_BASE) + \
-                                                    _DKL_TX_DW17)
-
-#define _DKL_TX_DW18                                   0xDC8
-#define DKL_TX_DW18(tc_port) _MMIO(_PORT(tc_port, \
-                                                    _DKL_PHY1_BASE, \
-                                                    _DKL_PHY2_BASE) + \
-                                                    _DKL_TX_DW18)
-
-#define _DKL_DP_MODE                                   0xA0
-#define DKL_DP_MODE(tc_port) _MMIO(_PORT(tc_port, \
-                                                    _DKL_PHY1_BASE, \
-                                                    _DKL_PHY2_BASE) + \
-                                                    _DKL_DP_MODE)
-
-#define _DKL_CMN_UC_DW27                       0x36C
-#define  DKL_CMN_UC_DW27_UC_HEALTH             (0x1 << 15)
-#define DKL_CMN_UC_DW_27(tc_port)              _MMIO(_PORT(tc_port, \
-                                                           _DKL_PHY1_BASE, \
-                                                           _DKL_PHY2_BASE) + \
-                                                           _DKL_CMN_UC_DW27)
-
-/*
- * Each Dekel PHY is addressed through a 4KB aperture. Each PHY has more than
- * 4KB of register space, so a separate index is programmed in HIP_INDEX_REG0
- * or HIP_INDEX_REG1, based on the port number, to set the upper 2 address
- * bits that point the 4KB window into the full PHY register space.
- */
-#define _HIP_INDEX_REG0                        0x1010A0
-#define _HIP_INDEX_REG1                        0x1010A4
-#define HIP_INDEX_REG(tc_port)         _MMIO((tc_port) < 4 ? _HIP_INDEX_REG0 \
-                                             : _HIP_INDEX_REG1)
-#define _HIP_INDEX_SHIFT(tc_port)      (8 * ((tc_port) % 4))
-#define HIP_INDEX_VAL(tc_port, val)    ((val) << _HIP_INDEX_SHIFT(tc_port))
-
 /* BXT display engine PLL */
 #define BXT_DE_PLL_CTL                 _MMIO(0x6d000)
 #define   BXT_DE_PLL_RATIO(x)          (x)     /* {60,65,100} * 19.2MHz */
@@ -8341,6 +8170,11 @@ enum skl_power_gate {
 #define GEN12_CULLBIT2                 _MMIO(0x7030)
 #define GEN12_STATE_ACK_DEBUG          _MMIO(0x20BC)
 
+#define _MTL_CLKGATE_DIS_TRANS_A                       0x604E8
+#define _MTL_CLKGATE_DIS_TRANS_B                       0x614E8
+#define MTL_CLKGATE_DIS_TRANS(trans)                   _MMIO_TRANS2(trans, _MTL_CLKGATE_DIS_TRANS_A)
+#define  MTL_CLKGATE_DIS_TRANS_DMASC_GATING_DIS                REG_BIT(7)
+
 #define MTL_LATENCY_LP0_LP1            _MMIO(0x45780)
 #define MTL_LATENCY_LP2_LP3            _MMIO(0x45784)
 #define MTL_LATENCY_LP4_LP5            _MMIO(0x45788)
@@ -8364,4 +8198,6 @@ enum skl_power_gate {
 #define   MTL_TRAS_MASK                        REG_GENMASK(16, 8)
 #define   MTL_TRDPRE_MASK              REG_GENMASK(7, 0)
 
+#define MTL_MEDIA_GSI_BASE             0x380000
+
 #endif /* _I915_REG_H_ */
index 6fc0d1b..cc2a882 100644 (file)
@@ -571,7 +571,6 @@ int __i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
 
 int i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
                                    struct dma_resv *resv,
-                                   const struct dma_fence_ops *exclude,
                                    bool write,
                                    unsigned long timeout,
                                    gfp_t gfp)
index 619fc5a..f752bfc 100644 (file)
@@ -91,7 +91,6 @@ int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
 
 int i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
                                    struct dma_resv *resv,
-                                   const struct dma_fence_ops *exclude,
                                    bool write,
                                    unsigned long timeout,
                                    gfp_t gfp);
index 20575eb..1dc1fb2 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "display/intel_cdclk.h"
 #include "display/intel_de.h"
+#include "gt/intel_gt_regs.h"
 #include "intel_device_info.h"
 #include "i915_drv.h"
 #include "i915_utils.h"
@@ -231,7 +232,7 @@ static bool find_devid(u16 id, const u16 *p, unsigned int num)
        return false;
 }
 
-void intel_device_info_subplatform_init(struct drm_i915_private *i915)
+static void intel_device_info_subplatform_init(struct drm_i915_private *i915)
 {
        const struct intel_device_info *info = INTEL_INFO(i915);
        const struct intel_runtime_info *rinfo = RUNTIME_INFO(i915);
@@ -288,6 +289,78 @@ void intel_device_info_subplatform_init(struct drm_i915_private *i915)
        RUNTIME_INFO(i915)->platform_mask[pi] |= mask;
 }
 
+static void ip_ver_read(struct drm_i915_private *i915, u32 offset, struct intel_ip_version *ip)
+{
+       struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
+       void __iomem *addr;
+       u32 val;
+       u8 expected_ver = ip->ver;
+       u8 expected_rel = ip->rel;
+
+       addr = pci_iomap_range(pdev, 0, offset, sizeof(u32));
+       if (drm_WARN_ON(&i915->drm, !addr))
+               return;
+
+       val = ioread32(addr);
+       pci_iounmap(pdev, addr);
+
+       ip->ver = REG_FIELD_GET(GMD_ID_ARCH_MASK, val);
+       ip->rel = REG_FIELD_GET(GMD_ID_RELEASE_MASK, val);
+       ip->step = REG_FIELD_GET(GMD_ID_STEP, val);
+
+       /* Sanity check against expected versions from device info */
+       if (IP_VER(ip->ver, ip->rel) < IP_VER(expected_ver, expected_rel))
+               drm_dbg(&i915->drm,
+                       "Hardware reports GMD IP version %u.%u (REG[0x%x] = 0x%08x) but minimum expected is %u.%u\n",
+                       ip->ver, ip->rel, offset, val, expected_ver, expected_rel);
+}
+
+/*
+ * Setup the graphics version for the current device.  This must be done before
+ * any code that performs checks on GRAPHICS_VER or DISPLAY_VER, so this
+ * function should be called very early in the driver initialization sequence.
+ *
+ * Regular MMIO access is not yet setup at the point this function is called so
+ * we peek at the appropriate MMIO offset directly.  The GMD_ID register is
+ * part of an 'always on' power well by design, so we don't need to worry about
+ * forcewake while reading it.
+ */
+static void intel_ipver_early_init(struct drm_i915_private *i915)
+{
+       struct intel_runtime_info *runtime = RUNTIME_INFO(i915);
+
+       if (!HAS_GMD_ID(i915)) {
+               drm_WARN_ON(&i915->drm, RUNTIME_INFO(i915)->graphics.ip.ver > 12);
+               /*
+                * On older platforms, graphics and media share the same ip
+                * version and release.
+                */
+               RUNTIME_INFO(i915)->media.ip =
+                       RUNTIME_INFO(i915)->graphics.ip;
+               return;
+       }
+
+       ip_ver_read(i915, i915_mmio_reg_offset(GMD_ID_GRAPHICS),
+                   &runtime->graphics.ip);
+       ip_ver_read(i915, i915_mmio_reg_offset(GMD_ID_DISPLAY),
+                   &runtime->display.ip);
+       ip_ver_read(i915, i915_mmio_reg_offset(GMD_ID_MEDIA),
+                   &runtime->media.ip);
+}
+
+/**
+ * intel_device_info_runtime_init_early - initialize early runtime info
+ * @i915: the i915 device
+ *
+ * Determine early intel_device_info fields at runtime. This function needs
+ * to be called before the MMIO has been setup.
+ */
+void intel_device_info_runtime_init_early(struct drm_i915_private *i915)
+{
+       intel_ipver_early_init(i915);
+       intel_device_info_subplatform_init(i915);
+}
+
 /**
  * intel_device_info_runtime_init - initialize runtime info
  * @dev_priv: the i915 device
@@ -442,6 +515,11 @@ void intel_device_info_runtime_init(struct drm_i915_private *dev_priv)
                runtime->has_dmc = false;
                runtime->has_dsc = false;
        }
+
+       /* Disable nuclear pageflip by default on pre-g4x */
+       if (!dev_priv->params.nuclear_pageflip &&
+           DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
+               dev_priv->drm.driver_features &= ~DRIVER_ATOMIC;
 }
 
 void intel_driver_caps_print(const struct intel_driver_caps *caps,
index d638235..7b5dd8e 100644 (file)
@@ -153,6 +153,7 @@ enum intel_ppgtt_type {
        func(has_4tile); \
        func(has_flat_ccs); \
        func(has_global_mocs); \
+       func(has_gmd_id); \
        func(has_gt_uc); \
        func(has_heci_pxp); \
        func(has_heci_gscfi); \
@@ -180,6 +181,7 @@ enum intel_ppgtt_type {
        /* Keep in alphabetical order */ \
        func(cursor_needs_physical); \
        func(has_cdclk_crawl); \
+       func(has_cdclk_squash); \
        func(has_ddi); \
        func(has_dp_mst); \
        func(has_dsb); \
@@ -195,20 +197,25 @@ enum intel_ppgtt_type {
        func(overlay_needs_physical); \
        func(supports_tv);
 
-struct ip_version {
+struct intel_ip_version {
        u8 ver;
        u8 rel;
+       u8 step;
 };
 
 struct intel_runtime_info {
+       /*
+        * Single "graphics" IP version that represents
+        * render, compute and copy behavior.
+        */
        struct {
-               struct ip_version ip;
+               struct intel_ip_version ip;
        } graphics;
        struct {
-               struct ip_version ip;
+               struct intel_ip_version ip;
        } media;
        struct {
-               struct ip_version ip;
+               struct intel_ip_version ip;
        } display;
 
        /*
@@ -308,7 +315,7 @@ struct intel_driver_caps {
 
 const char *intel_platform_name(enum intel_platform platform);
 
-void intel_device_info_subplatform_init(struct drm_i915_private *dev_priv);
+void intel_device_info_runtime_init_early(struct drm_i915_private *dev_priv);
 void intel_device_info_runtime_init(struct drm_i915_private *dev_priv);
 
 void intel_device_info_print(const struct intel_device_info *info,
index 8f86f56..19d4a88 100644 (file)
@@ -895,19 +895,14 @@ static void pnv_update_wm(struct drm_i915_private *dev_priv)
                wm = intel_calculate_wm(pixel_rate, &pnv_cursor_wm,
                                        pnv_display_wm.fifo_size,
                                        4, latency->cursor_sr);
-               reg = intel_uncore_read(&dev_priv->uncore, DSPFW3);
-               reg &= ~DSPFW_CURSOR_SR_MASK;
-               reg |= FW_WM(wm, CURSOR_SR);
-               intel_uncore_write(&dev_priv->uncore, DSPFW3, reg);
+               intel_uncore_rmw(&dev_priv->uncore, DSPFW3, DSPFW_CURSOR_SR_MASK,
+                                FW_WM(wm, CURSOR_SR));
 
                /* Display HPLL off SR */
                wm = intel_calculate_wm(pixel_rate, &pnv_display_hplloff_wm,
                                        pnv_display_hplloff_wm.fifo_size,
                                        cpp, latency->display_hpll_disable);
-               reg = intel_uncore_read(&dev_priv->uncore, DSPFW3);
-               reg &= ~DSPFW_HPLL_SR_MASK;
-               reg |= FW_WM(wm, HPLL_SR);
-               intel_uncore_write(&dev_priv->uncore, DSPFW3, reg);
+               intel_uncore_rmw(&dev_priv->uncore, DSPFW3, DSPFW_HPLL_SR_MASK, FW_WM(wm, HPLL_SR));
 
                /* cursor HPLL off SR */
                wm = intel_calculate_wm(pixel_rate, &pnv_cursor_hplloff_wm,
@@ -1337,34 +1332,14 @@ static bool g4x_compute_fbc_en(const struct g4x_wm_state *wm_state,
        return true;
 }
 
-static int g4x_compute_pipe_wm(struct intel_atomic_state *state,
-                              struct intel_crtc *crtc)
+static int _g4x_compute_pipe_wm(struct intel_crtc_state *crtc_state)
 {
-       struct intel_crtc_state *crtc_state =
-               intel_atomic_get_new_crtc_state(state, crtc);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
        struct g4x_wm_state *wm_state = &crtc_state->wm.g4x.optimal;
        u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
        const struct g4x_pipe_wm *raw;
-       const struct intel_plane_state *old_plane_state;
-       const struct intel_plane_state *new_plane_state;
-       struct intel_plane *plane;
        enum plane_id plane_id;
-       int i, level;
-       unsigned int dirty = 0;
-
-       for_each_oldnew_intel_plane_in_state(state, plane,
-                                            old_plane_state,
-                                            new_plane_state, i) {
-               if (new_plane_state->hw.crtc != &crtc->base &&
-                   old_plane_state->hw.crtc != &crtc->base)
-                       continue;
-
-               if (g4x_raw_plane_wm_compute(crtc_state, new_plane_state))
-                       dirty |= BIT(plane->id);
-       }
-
-       if (!dirty)
-               return 0;
+       int level;
 
        level = G4X_WM_LEVEL_NORMAL;
        if (!g4x_raw_crtc_wm_is_valid(crtc_state, level))
@@ -1417,6 +1392,34 @@ static int g4x_compute_pipe_wm(struct intel_atomic_state *state,
        return 0;
 }
 
+static int g4x_compute_pipe_wm(struct intel_atomic_state *state,
+                              struct intel_crtc *crtc)
+{
+       struct intel_crtc_state *crtc_state =
+               intel_atomic_get_new_crtc_state(state, crtc);
+       const struct intel_plane_state *old_plane_state;
+       const struct intel_plane_state *new_plane_state;
+       struct intel_plane *plane;
+       unsigned int dirty = 0;
+       int i;
+
+       for_each_oldnew_intel_plane_in_state(state, plane,
+                                            old_plane_state,
+                                            new_plane_state, i) {
+               if (new_plane_state->hw.crtc != &crtc->base &&
+                   old_plane_state->hw.crtc != &crtc->base)
+                       continue;
+
+               if (g4x_raw_plane_wm_compute(crtc_state, new_plane_state))
+                       dirty |= BIT(plane->id);
+       }
+
+       if (!dirty)
+               return 0;
+
+       return _g4x_compute_pipe_wm(crtc_state);
+}
+
 static int g4x_compute_intermediate_wm(struct intel_atomic_state *state,
                                       struct intel_crtc *crtc)
 {
@@ -1857,64 +1860,17 @@ static bool vlv_raw_crtc_wm_is_valid(const struct intel_crtc_state *crtc_state,
                vlv_raw_plane_wm_is_valid(crtc_state, PLANE_CURSOR, level);
 }
 
-static int vlv_compute_pipe_wm(struct intel_atomic_state *state,
-                              struct intel_crtc *crtc)
+static int _vlv_compute_pipe_wm(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_crtc_state *crtc_state =
-               intel_atomic_get_new_crtc_state(state, crtc);
        struct vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal;
        const struct vlv_fifo_state *fifo_state =
                &crtc_state->wm.vlv.fifo_state;
        u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
        int num_active_planes = hweight8(active_planes);
-       bool needs_modeset = drm_atomic_crtc_needs_modeset(&crtc_state->uapi);
-       const struct intel_plane_state *old_plane_state;
-       const struct intel_plane_state *new_plane_state;
-       struct intel_plane *plane;
        enum plane_id plane_id;
-       int level, ret, i;
-       unsigned int dirty = 0;
-
-       for_each_oldnew_intel_plane_in_state(state, plane,
-                                            old_plane_state,
-                                            new_plane_state, i) {
-               if (new_plane_state->hw.crtc != &crtc->base &&
-                   old_plane_state->hw.crtc != &crtc->base)
-                       continue;
-
-               if (vlv_raw_plane_wm_compute(crtc_state, new_plane_state))
-                       dirty |= BIT(plane->id);
-       }
-
-       /*
-        * DSPARB registers may have been reset due to the
-        * power well being turned off. Make sure we restore
-        * them to a consistent state even if no primary/sprite
-        * planes are initially active.
-        */
-       if (needs_modeset)
-               crtc_state->fifo_changed = true;
-
-       if (!dirty)
-               return 0;
-
-       /* cursor changes don't warrant a FIFO recompute */
-       if (dirty & ~BIT(PLANE_CURSOR)) {
-               const struct intel_crtc_state *old_crtc_state =
-                       intel_atomic_get_old_crtc_state(state, crtc);
-               const struct vlv_fifo_state *old_fifo_state =
-                       &old_crtc_state->wm.vlv.fifo_state;
-
-               ret = vlv_compute_fifo(crtc_state);
-               if (ret)
-                       return ret;
-
-               if (needs_modeset ||
-                   memcmp(old_fifo_state, fifo_state,
-                          sizeof(*fifo_state)) != 0)
-                       crtc_state->fifo_changed = true;
-       }
+       int level;
 
        /* initially allow all levels */
        wm_state->num_levels = intel_wm_num_levels(dev_priv);
@@ -1961,6 +1917,67 @@ static int vlv_compute_pipe_wm(struct intel_atomic_state *state,
        return 0;
 }
 
+static int vlv_compute_pipe_wm(struct intel_atomic_state *state,
+                              struct intel_crtc *crtc)
+{
+       struct intel_crtc_state *crtc_state =
+               intel_atomic_get_new_crtc_state(state, crtc);
+       bool needs_modeset = drm_atomic_crtc_needs_modeset(&crtc_state->uapi);
+       const struct intel_plane_state *old_plane_state;
+       const struct intel_plane_state *new_plane_state;
+       struct intel_plane *plane;
+       unsigned int dirty = 0;
+       int i;
+
+       for_each_oldnew_intel_plane_in_state(state, plane,
+                                            old_plane_state,
+                                            new_plane_state, i) {
+               if (new_plane_state->hw.crtc != &crtc->base &&
+                   old_plane_state->hw.crtc != &crtc->base)
+                       continue;
+
+               if (vlv_raw_plane_wm_compute(crtc_state, new_plane_state))
+                       dirty |= BIT(plane->id);
+       }
+
+       /*
+        * DSPARB registers may have been reset due to the
+        * power well being turned off. Make sure we restore
+        * them to a consistent state even if no primary/sprite
+        * planes are initially active. We also force a FIFO
+        * recomputation so that we are sure to sanitize the
+        * FIFO setting we took over from the BIOS even if there
+        * are no active planes on the crtc.
+        */
+       if (needs_modeset)
+               dirty = ~0;
+
+       if (!dirty)
+               return 0;
+
+       /* cursor changes don't warrant a FIFO recompute */
+       if (dirty & ~BIT(PLANE_CURSOR)) {
+               const struct intel_crtc_state *old_crtc_state =
+                       intel_atomic_get_old_crtc_state(state, crtc);
+               const struct vlv_fifo_state *old_fifo_state =
+                       &old_crtc_state->wm.vlv.fifo_state;
+               const struct vlv_fifo_state *new_fifo_state =
+                       &crtc_state->wm.vlv.fifo_state;
+               int ret;
+
+               ret = vlv_compute_fifo(crtc_state);
+               if (ret)
+                       return ret;
+
+               if (needs_modeset ||
+                   memcmp(old_fifo_state, new_fifo_state,
+                          sizeof(*new_fifo_state)) != 0)
+                       crtc_state->fifo_changed = true;
+       }
+
+       return _vlv_compute_pipe_wm(crtc_state);
+}
+
 #define VLV_FIFO(plane, value) \
        (((value) << DSPARB_ ## plane ## _SHIFT_VLV) & DSPARB_ ## plane ## _MASK_VLV)
 
@@ -3458,7 +3475,6 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv,
 {
        struct ilk_wm_values *previous = &dev_priv->display.wm.hw;
        unsigned int dirty;
-       u32 val;
 
        dirty = ilk_compute_wm_dirty(dev_priv, previous, results);
        if (!dirty)
@@ -3474,32 +3490,20 @@ static void ilk_write_wm_values(struct drm_i915_private *dev_priv,
                intel_uncore_write(&dev_priv->uncore, WM0_PIPE_ILK(PIPE_C), results->wm_pipe[2]);
 
        if (dirty & WM_DIRTY_DDB) {
-               if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
-                       val = intel_uncore_read(&dev_priv->uncore, WM_MISC);
-                       if (results->partitioning == INTEL_DDB_PART_1_2)
-                               val &= ~WM_MISC_DATA_PARTITION_5_6;
-                       else
-                               val |= WM_MISC_DATA_PARTITION_5_6;
-                       intel_uncore_write(&dev_priv->uncore, WM_MISC, val);
-               } else {
-                       val = intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL2);
-                       if (results->partitioning == INTEL_DDB_PART_1_2)
-                               val &= ~DISP_DATA_PARTITION_5_6;
-                       else
-                               val |= DISP_DATA_PARTITION_5_6;
-                       intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL2, val);
-               }
-       }
-
-       if (dirty & WM_DIRTY_FBC) {
-               val = intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL);
-               if (results->enable_fbc_wm)
-                       val &= ~DISP_FBC_WM_DIS;
+               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);
                else
-                       val |= DISP_FBC_WM_DIS;
-               intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL, val);
+                       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);
        }
 
+       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);
+
        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]);
@@ -3824,6 +3828,8 @@ void g4x_wm_get_hw_state(struct drm_i915_private *dev_priv)
                                             plane_id, USHRT_MAX);
                g4x_raw_fbc_wm_set(crtc_state, level, USHRT_MAX);
 
+               g4x_invalidate_wms(crtc, active, level);
+
                crtc_state->wm.g4x.optimal = *active;
                crtc_state->wm.g4x.intermediate = *active;
 
@@ -3860,37 +3866,30 @@ void g4x_wm_sanitize(struct drm_i915_private *dev_priv)
                        to_intel_crtc_state(crtc->base.state);
                struct intel_plane_state *plane_state =
                        to_intel_plane_state(plane->base.state);
-               struct g4x_wm_state *wm_state = &crtc_state->wm.g4x.optimal;
                enum plane_id plane_id = plane->id;
-               int level;
+               int level, num_levels = intel_wm_num_levels(dev_priv);
 
                if (plane_state->uapi.visible)
                        continue;
 
-               for (level = 0; level < 3; level++) {
+               for (level = 0; level < num_levels; level++) {
                        struct g4x_pipe_wm *raw =
                                &crtc_state->wm.g4x.raw[level];
 
                        raw->plane[plane_id] = 0;
-                       wm_state->wm.plane[plane_id] = 0;
-               }
 
-               if (plane_id == PLANE_PRIMARY) {
-                       for (level = 0; level < 3; level++) {
-                               struct g4x_pipe_wm *raw =
-                                       &crtc_state->wm.g4x.raw[level];
+                       if (plane_id == PLANE_PRIMARY)
                                raw->fbc = 0;
-                       }
-
-                       wm_state->sr.fbc = 0;
-                       wm_state->hpll.fbc = 0;
-                       wm_state->fbc_en = false;
                }
        }
 
        for_each_intel_crtc(&dev_priv->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);
 
                crtc_state->wm.g4x.intermediate =
                        crtc_state->wm.g4x.optimal;
@@ -4016,30 +4015,27 @@ void vlv_wm_sanitize(struct drm_i915_private *dev_priv)
                        to_intel_crtc_state(crtc->base.state);
                struct intel_plane_state *plane_state =
                        to_intel_plane_state(plane->base.state);
-               struct vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal;
-               const struct vlv_fifo_state *fifo_state =
-                       &crtc_state->wm.vlv.fifo_state;
                enum plane_id plane_id = plane->id;
-               int level;
+               int level, num_levels = intel_wm_num_levels(dev_priv);
 
                if (plane_state->uapi.visible)
                        continue;
 
-               for (level = 0; level < wm_state->num_levels; level++) {
+               for (level = 0; level < num_levels; level++) {
                        struct g4x_pipe_wm *raw =
                                &crtc_state->wm.vlv.raw[level];
 
                        raw->plane[plane_id] = 0;
-
-                       wm_state->wm[level].plane[plane_id] =
-                               vlv_invert_wm_value(raw->plane[plane_id],
-                                                   fifo_state->plane[plane_id]);
                }
        }
 
        for_each_intel_crtc(&dev_priv->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);
 
                crtc_state->wm.vlv.intermediate =
                        crtc_state->wm.vlv.optimal;
@@ -4117,7 +4113,7 @@ static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv)
                           intel_uncore_read(&dev_priv->uncore, DSPCNTR(pipe)) |
                           DISP_TRICKLE_FEED_DISABLE);
 
-               intel_uncore_write(&dev_priv->uncore, DSPSURF(pipe), intel_uncore_read(&dev_priv->uncore, DSPSURF(pipe)));
+               intel_uncore_rmw(&dev_priv->uncore, DSPSURF(pipe), 0, 0);
                intel_uncore_posting_read(&dev_priv->uncore, DSPSURF(pipe));
        }
 }
@@ -4325,8 +4321,8 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv,
        u32 val;
 
        /* WaTempDisableDOPClkGating:bdw */
-       misccpctl = intel_uncore_read(&dev_priv->uncore, GEN7_MISCCPCTL);
-       intel_uncore_write(&dev_priv->uncore, GEN7_MISCCPCTL, misccpctl & ~GEN7_DOP_CLOCK_GATE_ENABLE);
+       misccpctl = intel_uncore_rmw(&dev_priv->uncore, GEN7_MISCCPCTL,
+                                    GEN7_DOP_CLOCK_GATE_ENABLE, 0);
 
        val = intel_uncore_read(&dev_priv->uncore, GEN8_L3SQCREG1);
        val &= ~L3_PRIO_CREDITS_MASK;
@@ -4605,8 +4601,6 @@ static void hsw_init_clock_gating(struct drm_i915_private *dev_priv)
 
 static void ivb_init_clock_gating(struct drm_i915_private *dev_priv)
 {
-       u32 snpcr;
-
        intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE);
 
        /* WaFbcAsynchFlipDisableFbcQueue:ivb */
@@ -4644,10 +4638,8 @@ static void ivb_init_clock_gating(struct drm_i915_private *dev_priv)
 
        g4x_disable_trickle_feed(dev_priv);
 
-       snpcr = intel_uncore_read(&dev_priv->uncore, GEN6_MBCUNIT_SNPCR);
-       snpcr &= ~GEN6_MBC_SNPCR_MASK;
-       snpcr |= GEN6_MBC_SNPCR_MED;
-       intel_uncore_write(&dev_priv->uncore, GEN6_MBCUNIT_SNPCR, snpcr);
+       intel_uncore_rmw(&dev_priv->uncore, GEN6_MBCUNIT_SNPCR, GEN6_MBC_SNPCR_MASK,
+                        GEN6_MBC_SNPCR_MED);
 
        if (!HAS_PCH_NOP(dev_priv))
                cpt_init_clock_gating(dev_priv);
index 6ed5786..744cca5 100644 (file)
@@ -591,8 +591,15 @@ void intel_runtime_pm_enable(struct intel_runtime_pm *rpm)
                pm_runtime_use_autosuspend(kdev);
        }
 
-       /* Enable by default */
-       pm_runtime_allow(kdev);
+       /*
+        *  FIXME: Temp hammer to keep autosupend disable on lmem supported platforms.
+        *  As per PCIe specs 5.3.1.4.1, all iomem read write request over a PCIe
+        *  function will be unsupported in case PCIe endpoint function is in D3.
+        *  Let's keep i915 autosuspend control 'on' till we fix all known issue
+        *  with lmem access in D3.
+        */
+       if (!IS_DGFX(i915))
+               pm_runtime_allow(kdev);
 
        /*
         * The core calls the driver load handler with an RPM reference held.
index 42b3133..75d7a86 100644 (file)
@@ -135,6 +135,19 @@ static const struct intel_step_info adlp_n_revids[] = {
        [0x0] = { COMMON_GT_MEDIA_STEP(A0), .display_step = STEP_D0 },
 };
 
+static u8 gmd_to_intel_step(struct drm_i915_private *i915,
+                           struct intel_ip_version *gmd)
+{
+       u8 step = gmd->step + STEP_A0;
+
+       if (step >= STEP_FUTURE) {
+               drm_dbg(&i915->drm, "Using future steppings\n");
+               return STEP_FUTURE;
+       }
+
+       return step;
+}
+
 static void pvc_step_init(struct drm_i915_private *i915, int pci_revid);
 
 void intel_step_init(struct drm_i915_private *i915)
@@ -144,6 +157,18 @@ void intel_step_init(struct drm_i915_private *i915)
        int revid = INTEL_REVID(i915);
        struct intel_step_info step = {};
 
+       if (HAS_GMD_ID(i915)) {
+               step.graphics_step = gmd_to_intel_step(i915,
+                                                      &RUNTIME_INFO(i915)->graphics.ip);
+               step.media_step = gmd_to_intel_step(i915,
+                                                   &RUNTIME_INFO(i915)->media.ip);
+               step.display_step = gmd_to_intel_step(i915,
+                                                     &RUNTIME_INFO(i915)->display.ip);
+               RUNTIME_INFO(i915)->step = step;
+
+               return;
+       }
+
        if (IS_PONTEVECCHIO(i915)) {
                pvc_step_init(i915, revid);
                return;
index a6b12bf..96dfca4 100644 (file)
 struct drm_i915_private;
 
 struct intel_step_info {
+       /*
+        * It is expected to have 4 number steps per letter. Deviation from
+        * the expectation breaks gmd_to_intel_step().
+        */
        u8 graphics_step;       /* Represents the compute tile on Xe_HPC */
        u8 display_step;
        u8 media_step;
@@ -23,21 +27,43 @@ struct intel_step_info {
        func(A0)                        \
        func(A1)                        \
        func(A2)                        \
+       func(A3)                        \
        func(B0)                        \
        func(B1)                        \
        func(B2)                        \
        func(B3)                        \
        func(C0)                        \
        func(C1)                        \
+       func(C2)                        \
+       func(C3)                        \
        func(D0)                        \
        func(D1)                        \
+       func(D2)                        \
+       func(D3)                        \
        func(E0)                        \
+       func(E1)                        \
+       func(E2)                        \
+       func(E3)                        \
        func(F0)                        \
+       func(F1)                        \
+       func(F2)                        \
+       func(F3)                        \
        func(G0)                        \
+       func(G1)                        \
+       func(G2)                        \
+       func(G3)                        \
        func(H0)                        \
+       func(H1)                        \
+       func(H2)                        \
+       func(H3)                        \
        func(I0)                        \
        func(I1)                        \
-       func(J0)
+       func(I2)                        \
+       func(I3)                        \
+       func(J0)                        \
+       func(J1)                        \
+       func(J2)                        \
+       func(J3)
 
 /*
  * Symbolic steppings that do not match the hardware. These are valid both as gt
index 5022bac..ddafa4a 100644 (file)
@@ -431,15 +431,15 @@ intel_uncore_read64_2x32(struct intel_uncore *uncore,
 #define intel_uncore_write64_fw(...) __raw_uncore_write64(__VA_ARGS__)
 #define intel_uncore_posting_read_fw(...) ((void)intel_uncore_read_fw(__VA_ARGS__))
 
-static inline void intel_uncore_rmw(struct intel_uncore *uncore,
-                                   i915_reg_t reg, u32 clear, u32 set)
+static inline u32 intel_uncore_rmw(struct intel_uncore *uncore,
+                                  i915_reg_t reg, u32 clear, u32 set)
 {
        u32 old, val;
 
        old = intel_uncore_read(uncore, reg);
        val = (old & ~clear) | set;
-       if (val != old)
-               intel_uncore_write(uncore, reg, val);
+       intel_uncore_write(uncore, reg, val);
+       return old;
 }
 
 static inline void intel_uncore_rmw_fw(struct intel_uncore *uncore,
index 1bb5b52..c4f5c99 100644 (file)
@@ -77,6 +77,7 @@ static int pxp_create_arb_session(struct intel_pxp *pxp)
                drm_err(&gt->i915->drm, "arb session failed to go in play\n");
                return ret;
        }
+       drm_dbg(&gt->i915->drm, "PXP ARB session is alive\n");
 
        if (!++pxp->key_instance)
                ++pxp->key_instance;
index 4b6f565..a909050 100644 (file)
@@ -174,6 +174,9 @@ int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp *pxp,
 
        if (ret)
                drm_err(&i915->drm, "Failed to send tee msg ret=[%d]\n", ret);
+       else if (msg_out.header.status != 0x0)
+               drm_warn(&i915->drm, "PXP firmware failed arb session init request ret=[0x%08x]\n",
+                        msg_out.header.status);
 
        return ret;
 }
index 664fde2..02e63ed 100644 (file)
@@ -194,7 +194,6 @@ static void vlv_restore_gunit_s0ix_state(struct drm_i915_private *i915)
 {
        struct vlv_s0ix_state *s = i915->vlv_s0ix_state;
        struct intel_uncore *uncore = &i915->uncore;
-       u32 val;
        int i;
 
        if (!s)
@@ -262,15 +261,11 @@ static void vlv_restore_gunit_s0ix_state(struct drm_i915_private *i915)
         * be restored, as they are used to control the s0ix suspend/resume
         * sequence by the caller.
         */
-       val = intel_uncore_read(uncore, VLV_GTLC_WAKE_CTRL);
-       val &= VLV_GTLC_ALLOWWAKEREQ;
-       val |= s->gtlc_wake_ctrl & ~VLV_GTLC_ALLOWWAKEREQ;
-       intel_uncore_write(uncore, VLV_GTLC_WAKE_CTRL, val);
+       intel_uncore_rmw(uncore, VLV_GTLC_WAKE_CTRL, ~VLV_GTLC_ALLOWWAKEREQ,
+                        s->gtlc_wake_ctrl & ~VLV_GTLC_ALLOWWAKEREQ);
 
-       val = intel_uncore_read(uncore, VLV_GTLC_SURVIVABILITY_REG);
-       val &= VLV_GFX_CLK_FORCE_ON_BIT;
-       val |= s->gtlc_survive & ~VLV_GFX_CLK_FORCE_ON_BIT;
-       intel_uncore_write(uncore, VLV_GTLC_SURVIVABILITY_REG, val);
+       intel_uncore_rmw(uncore, VLV_GTLC_SURVIVABILITY_REG, ~VLV_GFX_CLK_FORCE_ON_BIT,
+                        s->gtlc_survive & ~VLV_GFX_CLK_FORCE_ON_BIT);
 
        intel_uncore_write(uncore, VLV_PMWGICZ, s->pmwgicz);
 
@@ -308,14 +303,10 @@ static int vlv_wait_for_pw_status(struct drm_i915_private *i915,
 static int vlv_force_gfx_clock(struct drm_i915_private *i915, bool force_on)
 {
        struct intel_uncore *uncore = &i915->uncore;
-       u32 val;
        int err;
 
-       val = intel_uncore_read(uncore, VLV_GTLC_SURVIVABILITY_REG);
-       val &= ~VLV_GFX_CLK_FORCE_ON_BIT;
-       if (force_on)
-               val |= VLV_GFX_CLK_FORCE_ON_BIT;
-       intel_uncore_write(uncore, VLV_GTLC_SURVIVABILITY_REG, val);
+       intel_uncore_rmw(uncore, VLV_GTLC_SURVIVABILITY_REG, VLV_GFX_CLK_FORCE_ON_BIT,
+                        force_on ? VLV_GFX_CLK_FORCE_ON_BIT : 0);
 
        if (!force_on)
                return 0;
@@ -340,11 +331,8 @@ static int vlv_allow_gt_wake(struct drm_i915_private *i915, bool allow)
        u32 val;
        int err;
 
-       val = intel_uncore_read(uncore, VLV_GTLC_WAKE_CTRL);
-       val &= ~VLV_GTLC_ALLOWWAKEREQ;
-       if (allow)
-               val |= VLV_GTLC_ALLOWWAKEREQ;
-       intel_uncore_write(uncore, VLV_GTLC_WAKE_CTRL, val);
+       intel_uncore_rmw(uncore, VLV_GTLC_WAKE_CTRL, VLV_GTLC_ALLOWWAKEREQ,
+                        allow ? VLV_GTLC_ALLOWWAKEREQ : 0);
        intel_uncore_posting_read(uncore, VLV_GTLC_WAKE_CTRL);
 
        mask = VLV_GTLC_ALLOWWAKEACK;