Merge tag 'drm-intel-next-2021-01-04' of git://anongit.freedesktop.org/drm/drm-intel...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / i915 / display / intel_ddi.c
index 5e927c8ab95a3c8d1c8f65de078beb6c5a05e656..17eaa56c5a99e35ad9eadad35495496faab393d6 100644 (file)
@@ -2285,18 +2285,23 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
        dig_port = enc_to_dig_port(encoder);
 
        if (!intel_phy_is_tc(dev_priv, phy) ||
-           dig_port->tc_mode != TC_PORT_TBT_ALT)
-               intel_display_power_get(dev_priv,
-                                       dig_port->ddi_io_power_domain);
+           dig_port->tc_mode != TC_PORT_TBT_ALT) {
+               drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref);
+               dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv,
+                                                                  dig_port->ddi_io_power_domain);
+       }
 
        /*
         * AUX power is only needed for (e)DP mode, and for HDMI mode on TC
         * ports.
         */
        if (intel_crtc_has_dp_encoder(crtc_state) ||
-           intel_phy_is_tc(dev_priv, phy))
-               intel_display_power_get(dev_priv,
-                                       intel_ddi_main_link_aux_domain(dig_port));
+           intel_phy_is_tc(dev_priv, phy)) {
+               drm_WARN_ON(&dev_priv->drm, dig_port->aux_wakeref);
+               dig_port->aux_wakeref =
+                       intel_display_power_get(dev_priv,
+                                               intel_ddi_main_link_aux_domain(dig_port));
+       }
 }
 
 void intel_ddi_enable_pipe_clock(struct intel_encoder *encoder,
@@ -3507,12 +3512,6 @@ static void intel_ddi_enable_fec(struct intel_encoder *encoder,
        val = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
        val |= DP_TP_CTL_FEC_ENABLE;
        intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), val);
-
-       if (intel_de_wait_for_set(dev_priv,
-                                 dp_tp_status_reg(encoder, crtc_state),
-                                 DP_TP_STATUS_FEC_ENABLE_LIVE, 1))
-               drm_err(&dev_priv->drm,
-                       "Timed out waiting for FEC Enable Status\n");
 }
 
 static void intel_ddi_disable_fec_state(struct intel_encoder *encoder,
@@ -3577,9 +3576,11 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
 
        /* 5. If IO power is controlled through PWR_WELL_CTL, Enable IO Power */
        if (!intel_phy_is_tc(dev_priv, phy) ||
-           dig_port->tc_mode != TC_PORT_TBT_ALT)
-               intel_display_power_get(dev_priv,
-                                       dig_port->ddi_io_power_domain);
+           dig_port->tc_mode != TC_PORT_TBT_ALT) {
+               drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref);
+               dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv,
+                                                                  dig_port->ddi_io_power_domain);
+       }
 
        /* 6. Program DP_MODE */
        icl_program_mg_dp_mode(dig_port, crtc_state);
@@ -3702,9 +3703,11 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
        intel_ddi_clk_select(encoder, crtc_state);
 
        if (!intel_phy_is_tc(dev_priv, phy) ||
-           dig_port->tc_mode != TC_PORT_TBT_ALT)
-               intel_display_power_get(dev_priv,
-                                       dig_port->ddi_io_power_domain);
+           dig_port->tc_mode != TC_PORT_TBT_ALT) {
+               drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref);
+               dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv,
+                                                                  dig_port->ddi_io_power_domain);
+       }
 
        icl_program_mg_dp_mode(dig_port, crtc_state);
 
@@ -3782,7 +3785,9 @@ static void intel_ddi_pre_enable_hdmi(struct intel_atomic_state *state,
        intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
        intel_ddi_clk_select(encoder, crtc_state);
 
-       intel_display_power_get(dev_priv, dig_port->ddi_io_power_domain);
+       drm_WARN_ON(&dev_priv->drm, dig_port->ddi_io_wakeref);
+       dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv,
+                                                          dig_port->ddi_io_power_domain);
 
        icl_program_mg_dp_mode(dig_port, crtc_state);
 
@@ -3940,8 +3945,9 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state,
 
        if (!intel_phy_is_tc(dev_priv, phy) ||
            dig_port->tc_mode != TC_PORT_TBT_ALT)
-               intel_display_power_put_unchecked(dev_priv,
-                                                 dig_port->ddi_io_power_domain);
+               intel_display_power_put(dev_priv,
+                                       dig_port->ddi_io_power_domain,
+                                       fetch_and_zero(&dig_port->ddi_io_wakeref));
 
        intel_ddi_clk_disable(encoder);
 }
@@ -3962,8 +3968,9 @@ static void intel_ddi_post_disable_hdmi(struct intel_atomic_state *state,
 
        intel_disable_ddi_buf(encoder, old_crtc_state);
 
-       intel_display_power_put_unchecked(dev_priv,
-                                         dig_port->ddi_io_power_domain);
+       intel_display_power_put(dev_priv,
+                               dig_port->ddi_io_power_domain,
+                               fetch_and_zero(&dig_port->ddi_io_wakeref));
 
        intel_ddi_clk_disable(encoder);
 
@@ -4036,8 +4043,9 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
                icl_unmap_plls_to_ports(encoder);
 
        if (intel_crtc_has_dp_encoder(old_crtc_state) || is_tc_port)
-               intel_display_power_put_unchecked(dev_priv,
-                                                 intel_ddi_main_link_aux_domain(dig_port));
+               intel_display_power_put(dev_priv,
+                                       intel_ddi_main_link_aux_domain(dig_port),
+                                       fetch_and_zero(&dig_port->aux_wakeref));
 
        if (is_tc_port)
                intel_tc_port_put_link(dig_port);
@@ -4122,6 +4130,7 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state,
 {
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+       struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
        enum port port = encoder->port;
 
        if (port == PORT_A && INTEL_GEN(dev_priv) < 9)
@@ -4129,7 +4138,10 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state,
 
        intel_edp_backlight_on(crtc_state, conn_state);
        intel_psr_enable(intel_dp, crtc_state, conn_state);
-       intel_dp_set_infoframes(encoder, true, crtc_state, conn_state);
+
+       if (!dig_port->lspcon.active || dig_port->dp.has_hdmi_sink)
+               intel_dp_set_infoframes(encoder, true, crtc_state, conn_state);
+
        intel_edp_drrs_enable(intel_dp, crtc_state);
 
        if (crtc_state->has_audio)
@@ -4372,9 +4384,12 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
        if (is_tc_port)
                intel_tc_port_get_link(dig_port, crtc_state->lane_count);
 
-       if (intel_crtc_has_dp_encoder(crtc_state) || is_tc_port)
-               intel_display_power_get(dev_priv,
-                                       intel_ddi_main_link_aux_domain(dig_port));
+       if (intel_crtc_has_dp_encoder(crtc_state) || is_tc_port) {
+               drm_WARN_ON(&dev_priv->drm, dig_port->aux_wakeref);
+               dig_port->aux_wakeref =
+                       intel_display_power_get(dev_priv,
+                                               intel_ddi_main_link_aux_domain(dig_port));
+       }
 
        if (is_tc_port && dig_port->tc_mode != TC_PORT_TBT_ALT)
                /*
@@ -4587,6 +4602,7 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
        struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
        enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
+       struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
        u32 temp, flags = 0;
 
        temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
@@ -4661,9 +4677,12 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
                                    pipe_config->fec_enable);
                }
 
-               pipe_config->infoframes.enable |=
-                       intel_hdmi_infoframes_enabled(encoder, pipe_config);
-
+               if (dig_port->lspcon.active && dig_port->dp.has_hdmi_sink)
+                       pipe_config->infoframes.enable |=
+                               intel_lspcon_infoframes_enabled(encoder, pipe_config);
+               else
+                       pipe_config->infoframes.enable |=
+                               intel_hdmi_infoframes_enabled(encoder, pipe_config);
                break;
        case TRANS_DDI_MODE_SELECT_DP_MST:
                pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);