Merge tag 'topic/adl-s-enabling-2021-02-01-1' of git://anongit.freedesktop.org/drm...
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / display / intel_ddi.c
index 4aa94c6..5bc5033 100644 (file)
 #include "intel_hotplug.h"
 #include "intel_lspcon.h"
 #include "intel_panel.h"
+#include "intel_pps.h"
 #include "intel_psr.h"
 #include "intel_sprite.h"
 #include "intel_tc.h"
 #include "intel_vdsc.h"
+#include "intel_vrr.h"
 
 struct ddi_buf_trans {
        u32 trans1;     /* balance leg enable, de-emph level */
@@ -2099,9 +2101,9 @@ void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state
        }
 }
 
-int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
-                                    enum transcoder cpu_transcoder,
-                                    bool enable)
+int intel_ddi_toggle_hdcp_bits(struct intel_encoder *intel_encoder,
+                              enum transcoder cpu_transcoder,
+                              bool enable, u32 hdcp_mask)
 {
        struct drm_device *dev = intel_encoder->base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
@@ -2116,9 +2118,9 @@ int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder,
 
        tmp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
        if (enable)
-               tmp |= TRANS_DDI_HDCP_SIGNALLING;
+               tmp |= hdcp_mask;
        else
-               tmp &= ~TRANS_DDI_HDCP_SIGNALLING;
+               tmp &= ~hdcp_mask;
        intel_de_write(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder), tmp);
        intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref);
        return ret;
@@ -2701,15 +2703,11 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
                ddi_translations = ehl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
        else
                ddi_translations = icl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
-       if (!ddi_translations)
-               return;
 
-       if (level >= n_entries) {
-               drm_dbg_kms(&dev_priv->drm,
-                           "DDI translation not found for level %d. Using %d instead.",
-                           level, n_entries - 1);
+       if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations))
+               return;
+       if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries))
                level = n_entries - 1;
-       }
 
        if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) {
                struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
@@ -2829,14 +2827,15 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
        int n_entries, ln;
        u32 val;
 
+       if (enc_to_dig_port(encoder)->tc_mode == TC_PORT_TBT_ALT)
+               return;
+
        ddi_translations = icl_get_mg_buf_trans(encoder, crtc_state, &n_entries);
-       /* The table does not have values for level 3 and level 9. */
-       if (level >= n_entries || level == 3 || level == 9) {
-               drm_dbg_kms(&dev_priv->drm,
-                           "DDI translation not found for level %d. Using %d instead.",
-                           level, n_entries - 2);
-               level = n_entries - 2;
-       }
+
+       if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations))
+               return;
+       if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries))
+               level = n_entries - 1;
 
        /* Set MG_TX_LINK_PARAMS cri_use_fs32 to 0. */
        for (ln = 0; ln < 2; ln++) {
@@ -2966,9 +2965,14 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
        u32 val, dpcnt_mask, dpcnt_val;
        int n_entries, ln;
 
+       if (enc_to_dig_port(encoder)->tc_mode == TC_PORT_TBT_ALT)
+               return;
+
        ddi_translations = tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
 
-       if (level >= n_entries)
+       if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations))
+               return;
+       if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries))
                level = n_entries - 1;
 
        dpcnt_mask = (DKL_TX_PRESHOOT_COEFF_MASK |
@@ -3459,10 +3463,12 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port,
 {
        struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
        enum tc_port tc_port = intel_port_to_tc(dev_priv, dig_port->base.port);
+       enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
        u32 ln0, ln1, pin_assignment;
        u8 width;
 
-       if (dig_port->tc_mode == TC_PORT_TBT_ALT)
+       if (!intel_phy_is_tc(dev_priv, phy) ||
+           dig_port->tc_mode == TC_PORT_TBT_ALT)
                return;
 
        if (INTEL_GEN(dev_priv) >= 12) {
@@ -3575,6 +3581,22 @@ i915_reg_t dp_tp_status_reg(struct intel_encoder *encoder,
                return DP_TP_STATUS(encoder->port);
 }
 
+static void intel_dp_sink_set_msa_timing_par_ignore_state(struct intel_dp *intel_dp,
+                                                         const struct intel_crtc_state *crtc_state,
+                                                         bool enable)
+{
+       struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+       if (!crtc_state->vrr.enable)
+               return;
+
+       if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_DOWNSPREAD_CTRL,
+                              enable ? DP_MSA_TIMING_PAR_IGNORE_EN : 0) <= 0)
+               drm_dbg_kms(&i915->drm,
+                           "Failed to set MSA_TIMING_PAR_IGNORE %s in the sink\n",
+                           enable ? "enable" : "disable");
+}
+
 static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp,
                                        const struct intel_crtc_state *crtc_state)
 {
@@ -3621,6 +3643,23 @@ static void intel_ddi_disable_fec_state(struct intel_encoder *encoder,
        intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
 }
 
+static void intel_ddi_power_up_lanes(struct intel_encoder *encoder,
+                                    const struct intel_crtc_state *crtc_state)
+{
+       struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+       struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+       enum phy phy = intel_port_to_phy(i915, encoder->port);
+
+       if (intel_phy_is_combo(i915, phy)) {
+               bool lane_reversal =
+                       dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL;
+
+               intel_combo_phy_power_up_lanes(i915, phy, false,
+                                              crtc_state->lane_count,
+                                              lane_reversal);
+       }
+}
+
 static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
                                  struct intel_encoder *encoder,
                                  const struct intel_crtc_state *crtc_state,
@@ -3645,7 +3684,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
         */
 
        /* 2. Enable Panel Power if PPS is required */
-       intel_edp_panel_on(intel_dp);
+       intel_pps_on(intel_dp);
 
        /*
         * 3. For non-TBT Type-C ports, set FIA lane count
@@ -3712,14 +3751,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
         * 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up
         * the used lanes of the DDI.
         */
-       if (intel_phy_is_combo(dev_priv, phy)) {
-               bool lane_reversal =
-                       dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL;
-
-               intel_combo_phy_power_up_lanes(dev_priv, phy, false,
-                                              crtc_state->lane_count,
-                                              lane_reversal);
-       }
+       intel_ddi_power_up_lanes(encoder, crtc_state);
 
        /*
         * 7.g Configure and enable DDI_BUF_CTL
@@ -3788,7 +3820,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
                                 crtc_state->port_clock,
                                 crtc_state->lane_count);
 
-       intel_edp_panel_on(intel_dp);
+       intel_pps_on(intel_dp);
 
        intel_ddi_clk_select(encoder, crtc_state);
 
@@ -3810,14 +3842,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
        else
                intel_prepare_dp_ddi_buffers(encoder, crtc_state);
 
-       if (intel_phy_is_combo(dev_priv, phy)) {
-               bool lane_reversal =
-                       dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL;
-
-               intel_combo_phy_power_up_lanes(dev_priv, phy, false,
-                                              crtc_state->lane_count,
-                                              lane_reversal);
-       }
+       intel_ddi_power_up_lanes(encoder, crtc_state);
 
        intel_ddi_init_dp_buf_reg(encoder, crtc_state);
        if (!is_mst)
@@ -3870,7 +3895,6 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state,
        struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
        struct intel_hdmi *intel_hdmi = &dig_port->hdmi;
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-       int level = intel_ddi_hdmi_level(encoder, crtc_state);
 
        intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
        intel_ddi_clk_select(encoder, crtc_state);
@@ -3881,20 +3905,6 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state,
 
        icl_program_mg_dp_mode(dig_port, crtc_state);
 
-       if (INTEL_GEN(dev_priv) >= 12)
-               tgl_ddi_vswing_sequence(encoder, crtc_state, level);
-       else if (INTEL_GEN(dev_priv) == 11)
-               icl_ddi_vswing_sequence(encoder, crtc_state, level);
-       else if (IS_CANNONLAKE(dev_priv))
-               cnl_ddi_vswing_sequence(encoder, crtc_state, level);
-       else if (IS_GEN9_LP(dev_priv))
-               bxt_ddi_vswing_sequence(encoder, crtc_state, level);
-       else
-               intel_prepare_hdmi_ddi_buffers(encoder, level);
-
-       if (IS_GEN9_BC(dev_priv))
-               skl_ddi_set_iboost(encoder, crtc_state, level);
-
        intel_ddi_enable_pipe_clock(encoder, crtc_state);
 
        dig_port->set_infoframes(encoder,
@@ -4030,8 +4040,8 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state,
        if (INTEL_GEN(dev_priv) >= 12)
                intel_ddi_disable_pipe_clock(old_crtc_state);
 
-       intel_edp_panel_vdd_on(intel_dp);
-       intel_edp_panel_off(intel_dp);
+       intel_pps_vdd_on(intel_dp);
+       intel_pps_off(intel_dp);
 
        if (!intel_phy_is_tc(dev_priv, phy) ||
            dig_port->tc_mode != TC_PORT_TBT_ALT)
@@ -4082,6 +4092,8 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
 
                intel_disable_pipe(old_crtc_state);
 
+               intel_vrr_disable(old_crtc_state);
+
                intel_ddi_disable_transcoder_func(old_crtc_state);
 
                intel_dsc_disable(old_crtc_state);
@@ -4268,6 +4280,7 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
        struct drm_connector *connector = conn_state->connector;
+       int level = intel_ddi_hdmi_level(encoder, crtc_state);
        enum port port = encoder->port;
 
        if (!intel_hdmi_handle_sink_scrambling(encoder, connector,
@@ -4277,6 +4290,20 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,
                            "[CONNECTOR:%d:%s] Failed to configure sink scrambling/TMDS bit clock ratio\n",
                            connector->base.id, connector->name);
 
+       if (INTEL_GEN(dev_priv) >= 12)
+               tgl_ddi_vswing_sequence(encoder, crtc_state, level);
+       else if (INTEL_GEN(dev_priv) == 11)
+               icl_ddi_vswing_sequence(encoder, crtc_state, level);
+       else if (IS_CANNONLAKE(dev_priv))
+               cnl_ddi_vswing_sequence(encoder, crtc_state, level);
+       else if (IS_GEN9_LP(dev_priv))
+               bxt_ddi_vswing_sequence(encoder, crtc_state, level);
+       else
+               intel_prepare_hdmi_ddi_buffers(encoder, level);
+
+       if (IS_GEN9_BC(dev_priv))
+               skl_ddi_set_iboost(encoder, crtc_state, level);
+
        /* Display WA #1143: skl,kbl,cfl */
        if (IS_GEN9_BC(dev_priv)) {
                /*
@@ -4312,6 +4339,8 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,
                intel_de_write(dev_priv, reg, val);
        }
 
+       intel_ddi_power_up_lanes(encoder, crtc_state);
+
        /* In HDMI/DVI mode, the port width, and swing/emphasis values
         * are ignored so nothing special needs to be done besides
         * enabling the port.
@@ -4333,6 +4362,8 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
        if (!crtc_state->bigjoiner_slave)
                intel_ddi_enable_transcoder_func(encoder, crtc_state);
 
+       intel_vrr_enable(encoder, crtc_state);
+
        intel_enable_pipe(crtc_state);
 
        intel_crtc_vblank_on(crtc_state);
@@ -4346,7 +4377,7 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
        if (conn_state->content_protection ==
            DRM_MODE_CONTENT_PROTECTION_DESIRED)
                intel_hdcp_enable(to_intel_connector(conn_state->connector),
-                                 crtc_state->cpu_transcoder,
+                                 crtc_state,
                                  (u8)conn_state->hdcp_content_type);
 }
 
@@ -4369,6 +4400,9 @@ static void intel_disable_ddi_dp(struct intel_atomic_state *state,
        /* Disable the decompression in DP Sink */
        intel_dp_sink_set_decompression_state(intel_dp, old_crtc_state,
                                              false);
+       /* Disable Ignore_MSA bit in DP Sink */
+       intel_dp_sink_set_msa_timing_par_ignore_state(intel_dp, old_crtc_state,
+                                                     false);
 }
 
 static void intel_disable_ddi_hdmi(struct intel_atomic_state *state,
@@ -5059,6 +5093,8 @@ static void intel_ddi_encoder_destroy(struct drm_encoder *encoder)
        intel_dp_encoder_flush_work(encoder);
 
        drm_encoder_cleanup(encoder);
+       if (dig_port)
+               kfree(dig_port->hdcp_port_data.streams);
        kfree(dig_port);
 }
 
@@ -5212,12 +5248,20 @@ intel_ddi_hotplug(struct intel_encoder *encoder,
 {
        struct drm_i915_private *i915 = to_i915(encoder->base.dev);
        struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+       struct intel_dp *intel_dp = &dig_port->dp;
        enum phy phy = intel_port_to_phy(i915, encoder->port);
        bool is_tc = intel_phy_is_tc(i915, phy);
        struct drm_modeset_acquire_ctx ctx;
        enum intel_hotplug_state state;
        int ret;
 
+       if (intel_dp->compliance.test_active &&
+           intel_dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) {
+               intel_dp_phy_test(encoder);
+               /* just do the PHY test and nothing else */
+               return INTEL_HOTPLUG_UNCHANGED;
+       }
+
        state = intel_encoder_hotplug(encoder, connector);
 
        drm_modeset_acquire_init(&ctx, 0);