Merge tag 'drm-intel-next-fixes-2018-10-18' of git://anongit.freedesktop.org/drm...
authorDave Airlie <airlied@redhat.com>
Fri, 19 Oct 2018 04:28:10 +0000 (14:28 +1000)
committerDave Airlie <airlied@redhat.com>
Fri, 19 Oct 2018 04:28:11 +0000 (14:28 +1000)
- Fix GPU hang on MacBook2,1 when booting in EFI mode (Bugzilla #105637)
- Fix garbled console on Y tiled BIOS framebuffer configs (Bugzilla #108264)
- Fix black screen on certain eDP panels eg. Dell XPS 9350 (Bugzilla #107489 and #105338)
- MST fixes that Rodrigo dropped from drm-intel-fixes and bunch of Icelake fixes
- Then assorted proactive code fixes caught by CI or developers

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181018165725.GA2281@jlahtine-desk.ger.corp.intel.com
12 files changed:
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_csr.c
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_dp_link_training.c
drivers/gpu/drm/i915/intel_dp_mst.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_sprite.c
drivers/gpu/drm/i915/selftests/i915_gem_object.c

index b4744a68cd88d983bbfe0f1b1a1e45b64014c1f4..4f3ac0a128893405c61e7ea4769215ce9d2cdc4e 100644 (file)
@@ -4189,7 +4189,7 @@ i915_drop_caches_set(void *data, u64 val)
                                                     I915_WAIT_LOCKED,
                                                     MAX_SCHEDULE_TIMEOUT);
 
-               if (val & DROP_RESET_SEQNO) {
+               if (ret == 0 && val & DROP_RESET_SEQNO) {
                        intel_runtime_pm_get(i915);
                        ret = i915_gem_set_global_seqno(&i915->drm, 1);
                        intel_runtime_pm_put(i915);
index db9688d149127dba2eeb384b29a3dc7f9df2f5db..aa3969d52773639e6950f6416a173f4a9a2b4992 100644 (file)
@@ -1127,11 +1127,7 @@ i915_gem_shmem_pread(struct drm_i915_gem_object *obj,
        offset = offset_in_page(args->offset);
        for (idx = args->offset >> PAGE_SHIFT; remain; idx++) {
                struct page *page = i915_gem_object_get_page(obj, idx);
-               int length;
-
-               length = remain;
-               if (offset + length > PAGE_SIZE)
-                       length = PAGE_SIZE - offset;
+               unsigned int length = min_t(u64, remain, PAGE_SIZE - offset);
 
                ret = shmem_pread(page, offset, length, user_data,
                                  page_to_phys(page) & obj_do_bit17_swizzling,
@@ -1575,11 +1571,7 @@ i915_gem_shmem_pwrite(struct drm_i915_gem_object *obj,
        offset = offset_in_page(args->offset);
        for (idx = args->offset >> PAGE_SHIFT; remain; idx++) {
                struct page *page = i915_gem_object_get_page(obj, idx);
-               int length;
-
-               length = remain;
-               if (offset + length > PAGE_SIZE)
-                       length = PAGE_SIZE - offset;
+               unsigned int length = min_t(u64, remain, PAGE_SIZE - offset);
 
                ret = shmem_pwrite(page, offset, length, user_data,
                                   page_to_phys(page) & obj_do_bit17_swizzling,
index 4948b352bf4c89467132aadc625736b07e016a27..7c491ea3d052aaccfc5eab69e2ea8f6b31f6813e 100644 (file)
@@ -9339,6 +9339,9 @@ enum skl_power_gate {
 #define DPCLKA_CFGCR0_ICL                      _MMIO(0x164280)
 #define  DPCLKA_CFGCR0_DDI_CLK_OFF(port)       (1 << ((port) ==  PORT_F ? 23 : \
                                                      (port) + 10))
+#define  ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(port)   (1 << ((port) + 10))
+#define  ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port) (1 << ((tc_port) == PORT_TC4 ? \
+                                                     21 : (tc_port) + 12))
 #define  DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port) ((port) == PORT_F ? 21 : \
                                                (port) * 2)
 #define  DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port)  (3 << DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port))
index 4aa8f3d6b64c0b5f3390b462b36f4c0786c5dc47..d48186e9ddadf8027b78e6d87ec025b5ec3df027 100644 (file)
@@ -35,6 +35,7 @@
  */
 
 #define I915_CSR_ICL "i915/icl_dmc_ver1_07.bin"
+MODULE_FIRMWARE(I915_CSR_ICL);
 #define ICL_CSR_VERSION_REQUIRED       CSR_VERSION(1, 7)
 
 #define I915_CSR_GLK "i915/glk_dmc_ver1_04.bin"
index b6910c8b4e0878708a91c133e58975025f02e3fa..5186cd7075f919b047fb78701cb29a99b9bb8795 100644 (file)
@@ -916,7 +916,7 @@ static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port por
        level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
 
        if (IS_ICELAKE(dev_priv)) {
-               if (port == PORT_A || port == PORT_B)
+               if (intel_port_is_combophy(dev_priv, port))
                        icl_get_combo_buf_trans(dev_priv, port,
                                                INTEL_OUTPUT_HDMI, &n_entries);
                else
@@ -1535,7 +1535,7 @@ static void icl_ddi_clock_get(struct intel_encoder *encoder,
        uint32_t pll_id;
 
        pll_id = intel_get_shared_dpll_id(dev_priv, pipe_config->shared_dpll);
-       if (port == PORT_A || port == PORT_B) {
+       if (intel_port_is_combophy(dev_priv, port)) {
                if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_HDMI))
                        link_clock = cnl_calc_wrpll_link(dev_priv, pll_id);
                else
@@ -2235,7 +2235,7 @@ u8 intel_ddi_dp_voltage_max(struct intel_encoder *encoder)
        int n_entries;
 
        if (IS_ICELAKE(dev_priv)) {
-               if (port == PORT_A || port == PORT_B)
+               if (intel_port_is_combophy(dev_priv, port))
                        icl_get_combo_buf_trans(dev_priv, port, encoder->type,
                                                &n_entries);
                else
@@ -2669,9 +2669,10 @@ static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
                                    u32 level,
                                    enum intel_output_type type)
 {
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        enum port port = encoder->port;
 
-       if (port == PORT_A || port == PORT_B)
+       if (intel_port_is_combophy(dev_priv, port))
                icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
        else
                icl_mg_phy_ddi_vswing_sequence(encoder, link_clock, level);
@@ -2732,6 +2733,21 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
        return DDI_BUF_TRANS_SELECT(level);
 }
 
+static inline
+uint32_t icl_dpclka_cfgcr0_clk_off(struct drm_i915_private *dev_priv,
+                                  enum port port)
+{
+       if (intel_port_is_combophy(dev_priv, port)) {
+               return ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(port);
+       } else if (intel_port_is_tc(dev_priv, port)) {
+               enum tc_port tc_port = intel_port_to_tc(dev_priv, port);
+
+               return ICL_DPCLKA_CFGCR0_TC_CLK_OFF(tc_port);
+       }
+
+       return 0;
+}
+
 void icl_map_plls_to_ports(struct drm_crtc *crtc,
                           struct intel_crtc_state *crtc_state,
                           struct drm_atomic_state *old_state)
@@ -2755,16 +2771,16 @@ void icl_map_plls_to_ports(struct drm_crtc *crtc,
                mutex_lock(&dev_priv->dpll_lock);
 
                val = I915_READ(DPCLKA_CFGCR0_ICL);
-               WARN_ON((val & DPCLKA_CFGCR0_DDI_CLK_OFF(port)) == 0);
+               WARN_ON((val & icl_dpclka_cfgcr0_clk_off(dev_priv, port)) == 0);
 
-               if (port == PORT_A || port == PORT_B) {
+               if (intel_port_is_combophy(dev_priv, port)) {
                        val &= ~DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port);
                        val |= DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port);
                        I915_WRITE(DPCLKA_CFGCR0_ICL, val);
                        POSTING_READ(DPCLKA_CFGCR0_ICL);
                }
 
-               val &= ~DPCLKA_CFGCR0_DDI_CLK_OFF(port);
+               val &= ~icl_dpclka_cfgcr0_clk_off(dev_priv, port);
                I915_WRITE(DPCLKA_CFGCR0_ICL, val);
 
                mutex_unlock(&dev_priv->dpll_lock);
@@ -2792,7 +2808,7 @@ void icl_unmap_plls_to_ports(struct drm_crtc *crtc,
                mutex_lock(&dev_priv->dpll_lock);
                I915_WRITE(DPCLKA_CFGCR0_ICL,
                           I915_READ(DPCLKA_CFGCR0_ICL) |
-                          DPCLKA_CFGCR0_DDI_CLK_OFF(port));
+                          icl_dpclka_cfgcr0_clk_off(dev_priv, port));
                mutex_unlock(&dev_priv->dpll_lock);
        }
 }
@@ -2810,7 +2826,7 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder,
        mutex_lock(&dev_priv->dpll_lock);
 
        if (IS_ICELAKE(dev_priv)) {
-               if (port >= PORT_C)
+               if (!intel_port_is_combophy(dev_priv, port))
                        I915_WRITE(DDI_CLK_SEL(port),
                                   icl_pll_to_ddi_pll_sel(encoder, pll));
        } else if (IS_CANNONLAKE(dev_priv)) {
@@ -2852,7 +2868,7 @@ static void intel_ddi_clk_disable(struct intel_encoder *encoder)
        enum port port = encoder->port;
 
        if (IS_ICELAKE(dev_priv)) {
-               if (port >= PORT_C)
+               if (!intel_port_is_combophy(dev_priv, port))
                        I915_WRITE(DDI_CLK_SEL(port), DDI_CLK_SEL_NONE);
        } else if (IS_CANNONLAKE(dev_priv)) {
                I915_WRITE(DPCLKA_CFGCR0, I915_READ(DPCLKA_CFGCR0) |
index fbcc56caffb6596a75ddc8975a8c813caef2c909..9741cc419e1b2bc1f5eb4771ae75468f0099289d 100644 (file)
@@ -2722,6 +2722,17 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
        if (size_aligned * 2 > dev_priv->stolen_usable_size)
                return false;
 
+       switch (fb->modifier) {
+       case DRM_FORMAT_MOD_LINEAR:
+       case I915_FORMAT_MOD_X_TILED:
+       case I915_FORMAT_MOD_Y_TILED:
+               break;
+       default:
+               DRM_DEBUG_DRIVER("Unsupported modifier for initial FB: 0x%llx\n",
+                                fb->modifier);
+               return false;
+       }
+
        mutex_lock(&dev->struct_mutex);
        obj = i915_gem_object_create_stolen_for_preallocated(dev_priv,
                                                             base_aligned,
@@ -2731,8 +2742,17 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
        if (!obj)
                return false;
 
-       if (plane_config->tiling == I915_TILING_X)
-               obj->tiling_and_stride = fb->pitches[0] | I915_TILING_X;
+       switch (plane_config->tiling) {
+       case I915_TILING_NONE:
+               break;
+       case I915_TILING_X:
+       case I915_TILING_Y:
+               obj->tiling_and_stride = fb->pitches[0] | plane_config->tiling;
+               break;
+       default:
+               MISSING_CASE(plane_config->tiling);
+               return false;
+       }
 
        mode_cmd.pixel_format = fb->format->format;
        mode_cmd.width = fb->width;
@@ -2764,20 +2784,33 @@ intel_set_plane_visible(struct intel_crtc_state *crtc_state,
 
        plane_state->base.visible = visible;
 
-       /* FIXME pre-g4x don't work like this */
-       if (visible) {
+       if (visible)
                crtc_state->base.plane_mask |= drm_plane_mask(&plane->base);
-               crtc_state->active_planes |= BIT(plane->id);
-       } else {
+       else
                crtc_state->base.plane_mask &= ~drm_plane_mask(&plane->base);
-               crtc_state->active_planes &= ~BIT(plane->id);
-       }
 
        DRM_DEBUG_KMS("%s active planes 0x%x\n",
                      crtc_state->base.crtc->name,
                      crtc_state->active_planes);
 }
 
+static void fixup_active_planes(struct intel_crtc_state *crtc_state)
+{
+       struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+       struct drm_plane *plane;
+
+       /*
+        * Active_planes aliases if multiple "primary" or cursor planes
+        * have been used on the same (or wrong) pipe. plane_mask uses
+        * unique ids, hence we can use that to reconstruct active_planes.
+        */
+       crtc_state->active_planes = 0;
+
+       drm_for_each_plane_mask(plane, &dev_priv->drm,
+                               crtc_state->base.plane_mask)
+               crtc_state->active_planes |= BIT(to_intel_plane(plane)->id);
+}
+
 static void intel_plane_disable_noatomic(struct intel_crtc *crtc,
                                         struct intel_plane *plane)
 {
@@ -2787,6 +2820,7 @@ static void intel_plane_disable_noatomic(struct intel_crtc *crtc,
                to_intel_plane_state(plane->base.state);
 
        intel_set_plane_visible(crtc_state, plane_state, false);
+       fixup_active_planes(crtc_state);
 
        if (plane->id == PLANE_PRIMARY)
                intel_pre_disable_primary_noatomic(&crtc->base);
@@ -2805,7 +2839,6 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
        struct drm_i915_gem_object *obj;
        struct drm_plane *primary = intel_crtc->base.primary;
        struct drm_plane_state *plane_state = primary->state;
-       struct drm_crtc_state *crtc_state = intel_crtc->base.state;
        struct intel_plane *intel_plane = to_intel_plane(primary);
        struct intel_plane_state *intel_state =
                to_intel_plane_state(plane_state);
@@ -2900,10 +2933,6 @@ valid_fb:
        plane_state->fb = fb;
        plane_state->crtc = &intel_crtc->base;
 
-       intel_set_plane_visible(to_intel_crtc_state(crtc_state),
-                               to_intel_plane_state(plane_state),
-                               true);
-
        atomic_or(to_intel_plane(primary)->frontbuffer_bit,
                  &obj->frontbuffer_bits);
 }
@@ -3151,6 +3180,10 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
        plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation);
        plane_state->color_plane[1].stride = intel_fb_pitch(fb, 1, rotation);
 
+       ret = intel_plane_check_stride(plane_state);
+       if (ret)
+               return ret;
+
        if (!plane_state->base.visible)
                return 0;
 
@@ -3286,10 +3319,15 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
        int src_x = plane_state->base.src.x1 >> 16;
        int src_y = plane_state->base.src.y1 >> 16;
        u32 offset;
+       int ret;
 
        intel_fill_fb_ggtt_view(&plane_state->view, fb, rotation);
        plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation);
 
+       ret = intel_plane_check_stride(plane_state);
+       if (ret)
+               return ret;
+
        intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
 
        if (INTEL_GEN(dev_priv) >= 4)
@@ -5923,6 +5961,17 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
        I915_WRITE(BCLRPAT(crtc->pipe), 0);
 }
 
+bool intel_port_is_combophy(struct drm_i915_private *dev_priv, enum port port)
+{
+       if (port == PORT_NONE)
+               return false;
+
+       if (IS_ICELAKE(dev_priv))
+               return port <= PORT_B;
+
+       return false;
+}
+
 bool intel_port_is_tc(struct drm_i915_private *dev_priv, enum port port)
 {
        if (IS_ICELAKE(dev_priv))
@@ -8847,6 +8896,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
                fb->modifier = I915_FORMAT_MOD_X_TILED;
                break;
        case PLANE_CTL_TILED_Y:
+               plane_config->tiling = I915_TILING_Y;
                if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
                        fb->modifier = I915_FORMAT_MOD_Y_TILED_CCS;
                else
@@ -9683,10 +9733,15 @@ static int intel_cursor_check_surface(struct intel_plane_state *plane_state)
        unsigned int rotation = plane_state->base.rotation;
        int src_x, src_y;
        u32 offset;
+       int ret;
 
        intel_fill_fb_ggtt_view(&plane_state->view, fb, rotation);
        plane_state->color_plane[0].stride = intel_fb_pitch(fb, 0, rotation);
 
+       ret = intel_plane_check_stride(plane_state);
+       if (ret)
+               return ret;
+
        src_x = plane_state->base.src_x >> 16;
        src_y = plane_state->base.src_y >> 16;
 
@@ -15436,17 +15491,6 @@ void i830_disable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
        POSTING_READ(DPLL(pipe));
 }
 
-static bool intel_plane_mapping_ok(struct intel_crtc *crtc,
-                                  struct intel_plane *plane)
-{
-       enum pipe pipe;
-
-       if (!plane->get_hw_state(plane, &pipe))
-               return true;
-
-       return pipe == crtc->pipe;
-}
-
 static void
 intel_sanitize_plane_mapping(struct drm_i915_private *dev_priv)
 {
@@ -15458,13 +15502,20 @@ intel_sanitize_plane_mapping(struct drm_i915_private *dev_priv)
        for_each_intel_crtc(&dev_priv->drm, crtc) {
                struct intel_plane *plane =
                        to_intel_plane(crtc->base.primary);
+               struct intel_crtc *plane_crtc;
+               enum pipe pipe;
 
-               if (intel_plane_mapping_ok(crtc, plane))
+               if (!plane->get_hw_state(plane, &pipe))
+                       continue;
+
+               if (pipe == crtc->pipe)
                        continue;
 
                DRM_DEBUG_KMS("%s attached to the wrong pipe, disabling plane\n",
                              plane->base.name);
-               intel_plane_disable_noatomic(crtc, plane);
+
+               plane_crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
+               intel_plane_disable_noatomic(plane_crtc, plane);
        }
 }
 
@@ -15512,13 +15563,9 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc,
                           I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
        }
 
-       /* restore vblank interrupts to correct state */
-       drm_crtc_vblank_reset(&crtc->base);
        if (crtc->active) {
                struct intel_plane *plane;
 
-               drm_crtc_vblank_on(&crtc->base);
-
                /* Disable everything but the primary plane */
                for_each_intel_plane_on_crtc(dev, crtc, plane) {
                        const struct intel_plane_state *plane_state =
@@ -15636,23 +15683,32 @@ void i915_redisable_vga(struct drm_i915_private *dev_priv)
 }
 
 /* FIXME read out full plane state for all planes */
-static void readout_plane_state(struct intel_crtc *crtc)
+static void readout_plane_state(struct drm_i915_private *dev_priv)
 {
-       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-       struct intel_crtc_state *crtc_state =
-               to_intel_crtc_state(crtc->base.state);
        struct intel_plane *plane;
+       struct intel_crtc *crtc;
 
-       for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
+       for_each_intel_plane(&dev_priv->drm, plane) {
                struct intel_plane_state *plane_state =
                        to_intel_plane_state(plane->base.state);
-               enum pipe pipe;
+               struct intel_crtc_state *crtc_state;
+               enum pipe pipe = PIPE_A;
                bool visible;
 
                visible = plane->get_hw_state(plane, &pipe);
 
+               crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
+               crtc_state = to_intel_crtc_state(crtc->base.state);
+
                intel_set_plane_visible(crtc_state, plane_state, visible);
        }
+
+       for_each_intel_crtc(&dev_priv->drm, crtc) {
+               struct intel_crtc_state *crtc_state =
+                       to_intel_crtc_state(crtc->base.state);
+
+               fixup_active_planes(crtc_state);
+       }
 }
 
 static void intel_modeset_readout_hw_state(struct drm_device *dev)
@@ -15684,13 +15740,13 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
                if (crtc_state->base.active)
                        dev_priv->active_crtcs |= 1 << crtc->pipe;
 
-               readout_plane_state(crtc);
-
                DRM_DEBUG_KMS("[CRTC:%d:%s] hw state readout: %s\n",
                              crtc->base.base.id, crtc->base.name,
                              enableddisabled(crtc_state->base.active));
        }
 
+       readout_plane_state(dev_priv);
+
        for (i = 0; i < dev_priv->num_shared_dpll; i++) {
                struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
 
@@ -15860,7 +15916,6 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
                             struct drm_modeset_acquire_ctx *ctx)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
-       enum pipe pipe;
        struct intel_crtc *crtc;
        struct intel_encoder *encoder;
        int i;
@@ -15873,15 +15928,23 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
        /* HW state is read out, now we need to sanitize this mess. */
        get_encoder_power_domains(dev_priv);
 
-       intel_sanitize_plane_mapping(dev_priv);
+       /*
+        * intel_sanitize_plane_mapping() may need to do vblank
+        * waits, so we need vblank interrupts restored beforehand.
+        */
+       for_each_intel_crtc(&dev_priv->drm, crtc) {
+               drm_crtc_vblank_reset(&crtc->base);
 
-       for_each_intel_encoder(dev, encoder) {
-               intel_sanitize_encoder(encoder);
+               if (crtc->active)
+                       drm_crtc_vblank_on(&crtc->base);
        }
 
-       for_each_pipe(dev_priv, pipe) {
-               crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
+       intel_sanitize_plane_mapping(dev_priv);
 
+       for_each_intel_encoder(dev, encoder)
+               intel_sanitize_encoder(encoder);
+
+       for_each_intel_crtc(&dev_priv->drm, crtc) {
                intel_sanitize_crtc(crtc, ctx);
                intel_dump_pipe_config(crtc, crtc->config,
                                       "[setup_hw_state]");
index 6b4c19123f2afbbe47dcfcb51677daac9f4f3e1e..3fae4dab295f093892491ecd010970dc7fc28128 100644 (file)
@@ -557,6 +557,22 @@ static bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
        return true;
 }
 
+static bool intel_dp_can_link_train_fallback_for_edp(struct intel_dp *intel_dp,
+                                                    int link_rate,
+                                                    uint8_t lane_count)
+{
+       const struct drm_display_mode *fixed_mode =
+               intel_dp->attached_connector->panel.fixed_mode;
+       int mode_rate, max_rate;
+
+       mode_rate = intel_dp_link_required(fixed_mode->clock, 18);
+       max_rate = intel_dp_max_data_rate(link_rate, lane_count);
+       if (mode_rate > max_rate)
+               return false;
+
+       return true;
+}
+
 int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
                                            int link_rate, uint8_t lane_count)
 {
@@ -566,9 +582,23 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
                                    intel_dp->num_common_rates,
                                    link_rate);
        if (index > 0) {
+               if (intel_dp_is_edp(intel_dp) &&
+                   !intel_dp_can_link_train_fallback_for_edp(intel_dp,
+                                                             intel_dp->common_rates[index - 1],
+                                                             lane_count)) {
+                       DRM_DEBUG_KMS("Retrying Link training for eDP with same parameters\n");
+                       return 0;
+               }
                intel_dp->max_link_rate = intel_dp->common_rates[index - 1];
                intel_dp->max_link_lane_count = lane_count;
        } else if (lane_count > 1) {
+               if (intel_dp_is_edp(intel_dp) &&
+                   !intel_dp_can_link_train_fallback_for_edp(intel_dp,
+                                                             intel_dp_max_common_rate(intel_dp),
+                                                             lane_count >> 1)) {
+                       DRM_DEBUG_KMS("Retrying Link training for eDP with same parameters\n");
+                       return 0;
+               }
                intel_dp->max_link_rate = intel_dp_max_common_rate(intel_dp);
                intel_dp->max_link_lane_count = lane_count >> 1;
        } else {
@@ -3704,7 +3734,7 @@ intel_dp_set_signal_levels(struct intel_dp *intel_dp)
        uint32_t signal_levels, mask = 0;
        uint8_t train_set = intel_dp->train_set[0];
 
-       if (IS_GEN9_LP(dev_priv) || IS_CANNONLAKE(dev_priv)) {
+       if (IS_GEN9_LP(dev_priv) || INTEL_GEN(dev_priv) >= 10) {
                signal_levels = bxt_signal_levels(intel_dp);
        } else if (HAS_DDI(dev_priv)) {
                signal_levels = ddi_signal_levels(intel_dp);
index a9f40985a621209a4d192059eb0474a19748e206..30be0e39bd5fda1afd705f44f840260d6177abbf 100644 (file)
@@ -367,22 +367,14 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
        return;
 
  failure_handling:
-       /* Dont fallback and prune modes if its eDP */
-       if (!intel_dp_is_edp(intel_dp)) {
-               DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d",
-                             intel_connector->base.base.id,
-                             intel_connector->base.name,
-                             intel_dp->link_rate, intel_dp->lane_count);
-               if (!intel_dp_get_link_train_fallback_values(intel_dp,
-                                                            intel_dp->link_rate,
-                                                            intel_dp->lane_count))
-                       /* Schedule a Hotplug Uevent to userspace to start modeset */
-                       schedule_work(&intel_connector->modeset_retry_work);
-       } else {
-               DRM_ERROR("[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d",
-                         intel_connector->base.base.id,
-                         intel_connector->base.name,
-                         intel_dp->link_rate, intel_dp->lane_count);
-       }
+       DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Link Training failed at link rate = %d, lane count = %d",
+                     intel_connector->base.base.id,
+                     intel_connector->base.name,
+                     intel_dp->link_rate, intel_dp->lane_count);
+       if (!intel_dp_get_link_train_fallback_values(intel_dp,
+                                                    intel_dp->link_rate,
+                                                    intel_dp->lane_count))
+               /* Schedule a Hotplug Uevent to userspace to start modeset */
+               schedule_work(&intel_connector->modeset_retry_work);
        return;
 }
index 43db2e9ac575e220e7ad994c6af3374eec302f95..7f155b4f1a7d7ab9a3389181d411140951962d6e 100644 (file)
@@ -38,11 +38,11 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
        struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
        struct intel_digital_port *intel_dig_port = intel_mst->primary;
        struct intel_dp *intel_dp = &intel_dig_port->dp;
-       struct intel_connector *connector =
-               to_intel_connector(conn_state->connector);
+       struct drm_connector *connector = conn_state->connector;
+       void *port = to_intel_connector(connector)->port;
        struct drm_atomic_state *state = pipe_config->base.state;
        int bpp;
-       int lane_count, slots;
+       int lane_count, slots = 0;
        const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
        int mst_pbn;
        bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
@@ -70,17 +70,23 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
 
        pipe_config->port_clock = intel_dp_max_link_rate(intel_dp);
 
-       if (drm_dp_mst_port_has_audio(&intel_dp->mst_mgr, connector->port))
+       if (drm_dp_mst_port_has_audio(&intel_dp->mst_mgr, port))
                pipe_config->has_audio = true;
 
        mst_pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, bpp);
        pipe_config->pbn = mst_pbn;
 
-       slots = drm_dp_atomic_find_vcpi_slots(state, &intel_dp->mst_mgr,
-                                             connector->port, mst_pbn);
-       if (slots < 0) {
-               DRM_DEBUG_KMS("failed finding vcpi slots:%d\n", slots);
-               return false;
+       /* Zombie connectors can't have VCPI slots */
+       if (READ_ONCE(connector->registered)) {
+               slots = drm_dp_atomic_find_vcpi_slots(state,
+                                                     &intel_dp->mst_mgr,
+                                                     port,
+                                                     mst_pbn);
+               if (slots < 0) {
+                       DRM_DEBUG_KMS("failed finding vcpi slots:%d\n",
+                                     slots);
+                       return false;
+               }
        }
 
        intel_link_compute_m_n(bpp, lane_count,
@@ -307,9 +313,8 @@ static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector)
        struct edid *edid;
        int ret;
 
-       if (!intel_dp) {
+       if (!READ_ONCE(connector->registered))
                return intel_connector_update_modes(connector, NULL);
-       }
 
        edid = drm_dp_mst_get_edid(connector, &intel_dp->mst_mgr, intel_connector->port);
        ret = intel_connector_update_modes(connector, edid);
@@ -324,9 +329,10 @@ intel_dp_mst_detect(struct drm_connector *connector, bool force)
        struct intel_connector *intel_connector = to_intel_connector(connector);
        struct intel_dp *intel_dp = intel_connector->mst_port;
 
-       if (!intel_dp)
+       if (!READ_ONCE(connector->registered))
                return connector_status_disconnected;
-       return drm_dp_mst_detect_port(connector, &intel_dp->mst_mgr, intel_connector->port);
+       return drm_dp_mst_detect_port(connector, &intel_dp->mst_mgr,
+                                     intel_connector->port);
 }
 
 static void
@@ -366,7 +372,7 @@ intel_dp_mst_mode_valid(struct drm_connector *connector,
        int bpp = 24; /* MST uses fixed bpp */
        int max_rate, mode_rate, max_lanes, max_link_clock;
 
-       if (!intel_dp)
+       if (!READ_ONCE(connector->registered))
                return MODE_ERROR;
 
        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
@@ -398,8 +404,6 @@ static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *c
        struct intel_dp *intel_dp = intel_connector->mst_port;
        struct intel_crtc *crtc = to_intel_crtc(state->crtc);
 
-       if (!intel_dp)
-               return NULL;
        return &intel_dp->mst_encoders[crtc->pipe]->base.base;
 }
 
@@ -499,7 +503,6 @@ static void intel_dp_register_mst_connector(struct drm_connector *connector)
 static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
                                           struct drm_connector *connector)
 {
-       struct intel_connector *intel_connector = to_intel_connector(connector);
        struct drm_i915_private *dev_priv = to_i915(connector->dev);
 
        DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, connector->name);
@@ -508,10 +511,6 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
        if (dev_priv->fbdev)
                drm_fb_helper_remove_one_connector(&dev_priv->fbdev->helper,
                                                   connector);
-       /* prevent race with the check in ->detect */
-       drm_modeset_lock(&connector->dev->mode_config.connection_mutex, NULL);
-       intel_connector->mst_port = NULL;
-       drm_modeset_unlock(&connector->dev->mode_config.connection_mutex);
 
        drm_connector_put(connector);
 }
index bf1c38728a5907c927c4853f01811b1c76501cc9..f8dc84b2d2d3443dcd47232f013bddb4ae9731f8 100644 (file)
@@ -1517,6 +1517,7 @@ void intel_connector_attach_encoder(struct intel_connector *connector,
                                    struct intel_encoder *encoder);
 struct drm_display_mode *
 intel_encoder_current_mode(struct intel_encoder *encoder);
+bool intel_port_is_combophy(struct drm_i915_private *dev_priv, enum port port);
 bool intel_port_is_tc(struct drm_i915_private *dev_priv, enum port port);
 enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv,
                              enum port port);
@@ -2140,6 +2141,7 @@ unsigned int skl_plane_max_stride(struct intel_plane *plane,
                                  unsigned int rotation);
 int skl_plane_check(struct intel_crtc_state *crtc_state,
                    struct intel_plane_state *plane_state);
+int intel_plane_check_stride(const struct intel_plane_state *plane_state);
 int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state);
 int chv_plane_check_rotation(const struct intel_plane_state *plane_state);
 
index d4c8e10fc90b63a4b4344a3931d8d166f4353b03..5fd2f7bf3927191a22cdeba959c5fd7c4f6f512a 100644 (file)
@@ -230,6 +230,28 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
 #endif
 }
 
+int intel_plane_check_stride(const struct intel_plane_state *plane_state)
+{
+       struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
+       const struct drm_framebuffer *fb = plane_state->base.fb;
+       unsigned int rotation = plane_state->base.rotation;
+       u32 stride, max_stride;
+
+       /* FIXME other color planes? */
+       stride = plane_state->color_plane[0].stride;
+       max_stride = plane->max_stride(plane, fb->format->format,
+                                      fb->modifier, rotation);
+
+       if (stride > max_stride) {
+               DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n",
+                             fb->base.id, stride,
+                             plane->base.base.id, plane->base.name, max_stride);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
 {
        const struct drm_framebuffer *fb = plane_state->base.fb;
index 6d3516d5bff9e5154d83da66033950e132acc7b9..c3999dd2021e4b76816a50ab0df6396205df5e2b 100644 (file)
@@ -501,6 +501,8 @@ static bool assert_mmap_offset(struct drm_i915_private *i915,
 
 static void disable_retire_worker(struct drm_i915_private *i915)
 {
+       i915_gem_shrinker_unregister(i915);
+
        mutex_lock(&i915->drm.struct_mutex);
        if (!i915->gt.active_requests++) {
                intel_runtime_pm_get(i915);
@@ -613,6 +615,7 @@ out_park:
        else
                queue_delayed_work(i915->wq, &i915->gt.idle_work, 0);
        mutex_unlock(&i915->drm.struct_mutex);
+       i915_gem_shrinker_register(i915);
        return err;
 err_obj:
        i915_gem_object_put(obj);