aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/display/intel_ddi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_ddi.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.c1009
1 files changed, 662 insertions, 347 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index cdcb7b1034ae..92940a0c5ef8 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -28,6 +28,7 @@
#include <drm/drm_scdc_helper.h>
#include "i915_drv.h"
+#include "i915_trace.h"
#include "intel_audio.h"
#include "intel_combo_phy.h"
#include "intel_connector.h"
@@ -582,6 +583,34 @@ static const struct cnl_ddi_buf_trans ehl_combo_phy_ddi_translations_dp[] = {
{ 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
};
+static const struct cnl_ddi_buf_trans jsl_combo_phy_ddi_translations_edp_hbr[] = {
+ /* NT mV Trans mV db */
+ { 0x8, 0x7F, 0x3F, 0x00, 0x00 }, /* 200 200 0.0 */
+ { 0x8, 0x7F, 0x38, 0x00, 0x07 }, /* 200 250 1.9 */
+ { 0x1, 0x7F, 0x33, 0x00, 0x0C }, /* 200 300 3.5 */
+ { 0xA, 0x35, 0x36, 0x00, 0x09 }, /* 200 350 4.9 */
+ { 0x8, 0x7F, 0x3F, 0x00, 0x00 }, /* 250 250 0.0 */
+ { 0x1, 0x7F, 0x38, 0x00, 0x07 }, /* 250 300 1.6 */
+ { 0xA, 0x35, 0x35, 0x00, 0x0A }, /* 250 350 2.9 */
+ { 0x1, 0x7F, 0x3F, 0x00, 0x00 }, /* 300 300 0.0 */
+ { 0xA, 0x35, 0x38, 0x00, 0x07 }, /* 300 350 1.3 */
+ { 0xA, 0x35, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
+};
+
+static const struct cnl_ddi_buf_trans jsl_combo_phy_ddi_translations_edp_hbr2[] = {
+ /* NT mV Trans mV db */
+ { 0x8, 0x7F, 0x3F, 0x00, 0x00 }, /* 200 200 0.0 */
+ { 0x8, 0x7F, 0x3F, 0x00, 0x00 }, /* 200 250 1.9 */
+ { 0x1, 0x7F, 0x3D, 0x00, 0x02 }, /* 200 300 3.5 */
+ { 0xA, 0x35, 0x38, 0x00, 0x07 }, /* 200 350 4.9 */
+ { 0x8, 0x7F, 0x3F, 0x00, 0x00 }, /* 250 250 0.0 */
+ { 0x1, 0x7F, 0x3F, 0x00, 0x00 }, /* 250 300 1.6 */
+ { 0xA, 0x35, 0x3A, 0x00, 0x05 }, /* 250 350 2.9 */
+ { 0x1, 0x7F, 0x3F, 0x00, 0x00 }, /* 300 300 0.0 */
+ { 0xA, 0x35, 0x38, 0x00, 0x07 }, /* 300 350 1.3 */
+ { 0xA, 0x35, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
+};
+
struct icl_mg_phy_ddi_buf_trans {
u32 cri_txdeemph_override_11_6;
u32 cri_txdeemph_override_5_0;
@@ -1034,133 +1063,286 @@ cnl_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries)
}
static const struct cnl_ddi_buf_trans *
-icl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate,
- int *n_entries)
+icl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
+ return icl_combo_phy_ddi_translations_hdmi;
+}
+
+static const struct cnl_ddi_buf_trans *
+icl_get_combo_buf_trans_dp(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hbr2);
+ return icl_combo_phy_ddi_translations_dp_hbr2;
+}
+
+static const struct cnl_ddi_buf_trans *
+icl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- if (type == INTEL_OUTPUT_HDMI) {
- *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
- return icl_combo_phy_ddi_translations_hdmi;
- } else if (rate > 540000 && type == INTEL_OUTPUT_EDP) {
+ if (crtc_state->port_clock > 540000) {
*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3);
return icl_combo_phy_ddi_translations_edp_hbr3;
- } else if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) {
+ } else if (dev_priv->vbt.edp.low_vswing) {
*n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr2);
return icl_combo_phy_ddi_translations_edp_hbr2;
}
- *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hbr2);
- return icl_combo_phy_ddi_translations_dp_hbr2;
+ return icl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+}
+
+static const struct cnl_ddi_buf_trans *
+icl_get_combo_buf_trans(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return icl_get_combo_buf_trans_hdmi(encoder, crtc_state, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
+ return icl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
+ else
+ return icl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
}
static const struct icl_mg_phy_ddi_buf_trans *
-icl_get_mg_buf_trans(struct intel_encoder *encoder, int type, int rate,
- int *n_entries)
+icl_get_mg_buf_trans_hdmi(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
{
- if (type == INTEL_OUTPUT_HDMI) {
- *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hdmi);
- return icl_mg_phy_ddi_translations_hdmi;
- } else if (rate > 270000) {
+ *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hdmi);
+ return icl_mg_phy_ddi_translations_hdmi;
+}
+
+static const struct icl_mg_phy_ddi_buf_trans *
+icl_get_mg_buf_trans_dp(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ if (crtc_state->port_clock > 270000) {
*n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_hbr2_hbr3);
return icl_mg_phy_ddi_translations_hbr2_hbr3;
+ } else {
+ *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_rbr_hbr);
+ return icl_mg_phy_ddi_translations_rbr_hbr;
}
+}
+
+static const struct icl_mg_phy_ddi_buf_trans *
+icl_get_mg_buf_trans(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return icl_get_mg_buf_trans_hdmi(encoder, crtc_state, n_entries);
+ else
+ return icl_get_mg_buf_trans_dp(encoder, crtc_state, n_entries);
+}
- *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_rbr_hbr);
- return icl_mg_phy_ddi_translations_rbr_hbr;
+static const struct cnl_ddi_buf_trans *
+ehl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
+ return icl_combo_phy_ddi_translations_hdmi;
}
static const struct cnl_ddi_buf_trans *
-ehl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate,
- int *n_entries)
+ehl_get_combo_buf_trans_dp(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ *n_entries = ARRAY_SIZE(ehl_combo_phy_ddi_translations_dp);
+ return ehl_combo_phy_ddi_translations_dp;
+}
+
+static const struct cnl_ddi_buf_trans *
+ehl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- switch (type) {
- case INTEL_OUTPUT_HDMI:
- *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
- return icl_combo_phy_ddi_translations_hdmi;
- case INTEL_OUTPUT_EDP:
- if (dev_priv->vbt.edp.low_vswing) {
- if (rate > 540000) {
- *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3);
- return icl_combo_phy_ddi_translations_edp_hbr3;
- } else {
- *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr2);
- return icl_combo_phy_ddi_translations_edp_hbr2;
- }
- }
- /* fall through */
- default:
- /* All combo DP and eDP ports that do not support low_vswing */
- *n_entries = ARRAY_SIZE(ehl_combo_phy_ddi_translations_dp);
- return ehl_combo_phy_ddi_translations_dp;
+ if (dev_priv->vbt.edp.low_vswing) {
+ *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr2);
+ return icl_combo_phy_ddi_translations_edp_hbr2;
}
+
+ return ehl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
}
static const struct cnl_ddi_buf_trans *
-tgl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate,
+ehl_get_combo_buf_trans(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
int *n_entries)
{
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return ehl_get_combo_buf_trans_hdmi(encoder, crtc_state, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
+ return ehl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
+ else
+ return ehl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+}
+
+static const struct cnl_ddi_buf_trans *
+jsl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
+ return icl_combo_phy_ddi_translations_hdmi;
+}
+
+static const struct cnl_ddi_buf_trans *
+jsl_get_combo_buf_trans_dp(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_dp_hbr2);
+ return icl_combo_phy_ddi_translations_dp_hbr2;
+}
+
+static const struct cnl_ddi_buf_trans *
+jsl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- switch (type) {
- case INTEL_OUTPUT_HDMI:
- *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
- return icl_combo_phy_ddi_translations_hdmi;
- case INTEL_OUTPUT_EDP:
- if (dev_priv->vbt.edp.hobl) {
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
- if (!intel_dp->hobl_failed && rate <= 540000) {
- /* Same table applies to TGL, RKL and DG1 */
- *n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_edp_hbr2_hobl);
- return tgl_combo_phy_ddi_translations_edp_hbr2_hobl;
- }
+ if (dev_priv->vbt.edp.low_vswing) {
+ if (crtc_state->port_clock > 270000) {
+ *n_entries = ARRAY_SIZE(jsl_combo_phy_ddi_translations_edp_hbr2);
+ return jsl_combo_phy_ddi_translations_edp_hbr2;
+ } else {
+ *n_entries = ARRAY_SIZE(jsl_combo_phy_ddi_translations_edp_hbr);
+ return jsl_combo_phy_ddi_translations_edp_hbr;
}
+ }
- if (rate > 540000) {
- *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3);
- return icl_combo_phy_ddi_translations_edp_hbr3;
- } else if (dev_priv->vbt.edp.low_vswing) {
- *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr2);
- return icl_combo_phy_ddi_translations_edp_hbr2;
- }
- /* fall through */
- default:
- /* All combo DP and eDP ports that do not support low_vswing */
- if (rate > 270000) {
- if (IS_TGL_U(dev_priv) || IS_TGL_Y(dev_priv)) {
- *n_entries = ARRAY_SIZE(tgl_uy_combo_phy_ddi_translations_dp_hbr2);
- return tgl_uy_combo_phy_ddi_translations_dp_hbr2;
- }
+ return jsl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+}
+
+static const struct cnl_ddi_buf_trans *
+jsl_get_combo_buf_trans(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return jsl_get_combo_buf_trans_hdmi(encoder, crtc_state, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
+ return jsl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
+ else
+ return jsl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+}
+static const struct cnl_ddi_buf_trans *
+tgl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_hdmi);
+ return icl_combo_phy_ddi_translations_hdmi;
+}
+
+static const struct cnl_ddi_buf_trans *
+tgl_get_combo_buf_trans_dp(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+ if (crtc_state->port_clock > 270000) {
+ if (IS_TGL_U(dev_priv) || IS_TGL_Y(dev_priv)) {
+ *n_entries = ARRAY_SIZE(tgl_uy_combo_phy_ddi_translations_dp_hbr2);
+ return tgl_uy_combo_phy_ddi_translations_dp_hbr2;
+ } else {
*n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr2);
return tgl_combo_phy_ddi_translations_dp_hbr2;
}
-
+ } else {
*n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr);
return tgl_combo_phy_ddi_translations_dp_hbr;
}
}
+static const struct cnl_ddi_buf_trans *
+tgl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+ if (crtc_state->port_clock > 540000) {
+ *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr3);
+ return icl_combo_phy_ddi_translations_edp_hbr3;
+ } else if (dev_priv->vbt.edp.hobl && !intel_dp->hobl_failed) {
+ *n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_edp_hbr2_hobl);
+ return tgl_combo_phy_ddi_translations_edp_hbr2_hobl;
+ } else if (dev_priv->vbt.edp.low_vswing) {
+ *n_entries = ARRAY_SIZE(icl_combo_phy_ddi_translations_edp_hbr2);
+ return icl_combo_phy_ddi_translations_edp_hbr2;
+ }
+
+ return tgl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+}
+
+static const struct cnl_ddi_buf_trans *
+tgl_get_combo_buf_trans(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return tgl_get_combo_buf_trans_hdmi(encoder, crtc_state, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
+ return tgl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
+ else
+ return tgl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+}
+
static const struct tgl_dkl_phy_ddi_buf_trans *
-tgl_get_dkl_buf_trans(struct intel_encoder *encoder, int type, int rate,
- int *n_entries)
+tgl_get_dkl_buf_trans_hdmi(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ *n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
+ return tgl_dkl_phy_hdmi_ddi_trans;
+}
+
+static const struct tgl_dkl_phy_ddi_buf_trans *
+tgl_get_dkl_buf_trans_dp(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
{
- if (type == INTEL_OUTPUT_HDMI) {
- *n_entries = ARRAY_SIZE(tgl_dkl_phy_hdmi_ddi_trans);
- return tgl_dkl_phy_hdmi_ddi_trans;
- } else if (rate > 270000) {
+ if (crtc_state->port_clock > 270000) {
*n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans_hbr2);
return tgl_dkl_phy_dp_ddi_trans_hbr2;
+ } else {
+ *n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans);
+ return tgl_dkl_phy_dp_ddi_trans;
}
+}
- *n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans);
- return tgl_dkl_phy_dp_ddi_trans;
+static const struct tgl_dkl_phy_ddi_buf_trans *
+tgl_get_dkl_buf_trans(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return tgl_get_dkl_buf_trans_hdmi(encoder, crtc_state, n_entries);
+ else
+ return tgl_get_dkl_buf_trans_dp(encoder, crtc_state, n_entries);
}
-static int intel_ddi_hdmi_level(struct intel_encoder *encoder)
+static int intel_ddi_hdmi_level(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
int n_entries, level, default_entry;
@@ -1168,19 +1350,15 @@ static int intel_ddi_hdmi_level(struct intel_encoder *encoder)
if (INTEL_GEN(dev_priv) >= 12) {
if (intel_phy_is_combo(dev_priv, phy))
- tgl_get_combo_buf_trans(encoder, INTEL_OUTPUT_HDMI,
- 0, &n_entries);
+ tgl_get_combo_buf_trans_hdmi(encoder, crtc_state, &n_entries);
else
- tgl_get_dkl_buf_trans(encoder, INTEL_OUTPUT_HDMI, 0,
- &n_entries);
+ tgl_get_dkl_buf_trans_hdmi(encoder, crtc_state, &n_entries);
default_entry = n_entries - 1;
} else if (INTEL_GEN(dev_priv) == 11) {
if (intel_phy_is_combo(dev_priv, phy))
- icl_get_combo_buf_trans(encoder, INTEL_OUTPUT_HDMI,
- 0, &n_entries);
+ icl_get_combo_buf_trans_hdmi(encoder, crtc_state, &n_entries);
else
- icl_get_mg_buf_trans(encoder, INTEL_OUTPUT_HDMI, 0,
- &n_entries);
+ icl_get_mg_buf_trans_hdmi(encoder, crtc_state, &n_entries);
default_entry = n_entries - 1;
} else if (IS_CANNONLAKE(dev_priv)) {
cnl_get_buf_trans_hdmi(encoder, &n_entries);
@@ -1507,14 +1685,15 @@ void hsw_fdi_link_train(struct intel_encoder *encoder,
DP_TP_CTL_ENABLE);
}
-static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
+static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state)
{
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
intel_dp->DP = dig_port->saved_port_bits |
DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
- intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
+ intel_dp->DP |= DDI_PORT_WIDTH(crtc_state->lane_count);
}
static int icl_calc_tbt_pll_link(struct drm_i915_private *dev_priv,
@@ -1577,7 +1756,8 @@ static void intel_ddi_clock_get(struct intel_encoder *encoder,
encoder->port);
else
pipe_config->port_clock =
- intel_dpll_get_freq(dev_priv, pipe_config->shared_dpll);
+ intel_dpll_get_freq(dev_priv, pipe_config->shared_dpll,
+ &pipe_config->dpll_hw_state);
ddi_dotclock_get(pipe_config);
}
@@ -2117,13 +2297,6 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
intel_phy_is_tc(dev_priv, phy))
intel_display_power_get(dev_priv,
intel_ddi_main_link_aux_domain(dig_port));
-
- /*
- * VDSC power is needed when DSC is enabled
- */
- if (crtc_state->dsc.compression_enable)
- intel_display_power_get(dev_priv,
- intel_dsc_power_domain(crtc_state));
}
void intel_ddi_enable_pipe_clock(struct intel_encoder *encoder,
@@ -2178,13 +2351,14 @@ static void _skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
}
static void skl_ddi_set_iboost(struct intel_encoder *encoder,
- int level, enum intel_output_type type)
+ const struct intel_crtc_state *crtc_state,
+ int level)
{
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
u8 iboost;
- if (type == INTEL_OUTPUT_HDMI)
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
iboost = intel_bios_hdmi_boost_level(encoder);
else
iboost = intel_bios_dp_boost_level(encoder);
@@ -2193,14 +2367,12 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder,
const struct ddi_buf_trans *ddi_translations;
int n_entries;
- if (type == INTEL_OUTPUT_HDMI)
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
ddi_translations = intel_ddi_get_buf_trans_hdmi(encoder, &n_entries);
- else if (type == INTEL_OUTPUT_EDP)
- ddi_translations = intel_ddi_get_buf_trans_edp(encoder,
- &n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
+ ddi_translations = intel_ddi_get_buf_trans_edp(encoder, &n_entries);
else
- ddi_translations = intel_ddi_get_buf_trans_dp(encoder,
- &n_entries);
+ ddi_translations = intel_ddi_get_buf_trans_dp(encoder, &n_entries);
if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations))
return;
@@ -2223,16 +2395,17 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder,
}
static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder,
- int level, enum intel_output_type type)
+ const struct intel_crtc_state *crtc_state,
+ int level)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
const struct bxt_ddi_buf_trans *ddi_translations;
enum port port = encoder->port;
int n_entries;
- if (type == INTEL_OUTPUT_HDMI)
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
ddi_translations = bxt_get_buf_trans_hdmi(encoder, &n_entries);
- else if (type == INTEL_OUTPUT_EDP)
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
ddi_translations = bxt_get_buf_trans_edp(encoder, &n_entries);
else
ddi_translations = bxt_get_buf_trans_dp(encoder, &n_entries);
@@ -2249,7 +2422,8 @@ static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder,
ddi_translations[level].deemphasis);
}
-static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp)
+static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
{
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -2259,33 +2433,30 @@ static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp)
if (INTEL_GEN(dev_priv) >= 12) {
if (intel_phy_is_combo(dev_priv, phy))
- tgl_get_combo_buf_trans(encoder, encoder->type,
- intel_dp->link_rate, &n_entries);
+ tgl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
else
- tgl_get_dkl_buf_trans(encoder, encoder->type,
- intel_dp->link_rate, &n_entries);
+ tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
} else if (INTEL_GEN(dev_priv) == 11) {
- if (IS_ELKHARTLAKE(dev_priv))
- ehl_get_combo_buf_trans(encoder, encoder->type,
- intel_dp->link_rate, &n_entries);
+ if (IS_PLATFORM(dev_priv, INTEL_JASPERLAKE))
+ jsl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
+ else if (IS_PLATFORM(dev_priv, INTEL_ELKHARTLAKE))
+ ehl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
else if (intel_phy_is_combo(dev_priv, phy))
- icl_get_combo_buf_trans(encoder, encoder->type,
- intel_dp->link_rate, &n_entries);
+ icl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
else
- icl_get_mg_buf_trans(encoder, encoder->type,
- intel_dp->link_rate, &n_entries);
+ icl_get_mg_buf_trans(encoder, crtc_state, &n_entries);
} else if (IS_CANNONLAKE(dev_priv)) {
- if (encoder->type == INTEL_OUTPUT_EDP)
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
cnl_get_buf_trans_edp(encoder, &n_entries);
else
cnl_get_buf_trans_dp(encoder, &n_entries);
} else if (IS_GEN9_LP(dev_priv)) {
- if (encoder->type == INTEL_OUTPUT_EDP)
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
bxt_get_buf_trans_edp(encoder, &n_entries);
else
bxt_get_buf_trans_dp(encoder, &n_entries);
} else {
- if (encoder->type == INTEL_OUTPUT_EDP)
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
intel_ddi_get_buf_trans_edp(encoder, &n_entries);
else
intel_ddi_get_buf_trans_dp(encoder, &n_entries);
@@ -2312,7 +2483,8 @@ static u8 intel_ddi_dp_preemph_max(struct intel_dp *intel_dp)
}
static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
- int level, enum intel_output_type type)
+ const struct intel_crtc_state *crtc_state,
+ int level)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
const struct cnl_ddi_buf_trans *ddi_translations;
@@ -2320,9 +2492,9 @@ static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
int n_entries, ln;
u32 val;
- if (type == INTEL_OUTPUT_HDMI)
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
ddi_translations = cnl_get_buf_trans_hdmi(encoder, &n_entries);
- else if (type == INTEL_OUTPUT_EDP)
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
ddi_translations = cnl_get_buf_trans_edp(encoder, &n_entries);
else
ddi_translations = cnl_get_buf_trans_dp(encoder, &n_entries);
@@ -2376,22 +2548,16 @@ static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
}
static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
- int level, enum intel_output_type type)
+ const struct intel_crtc_state *crtc_state,
+ int level)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum port port = encoder->port;
int width, rate, ln;
u32 val;
- if (type == INTEL_OUTPUT_HDMI) {
- width = 4;
- rate = 0; /* Rate is always < than 6GHz for HDMI */
- } else {
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
- width = intel_dp->lane_count;
- rate = intel_dp->link_rate;
- }
+ width = crtc_state->lane_count;
+ rate = crtc_state->port_clock;
/*
* 1. If port type is eDP or DP,
@@ -2399,10 +2565,10 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
* else clear to 0b.
*/
val = intel_de_read(dev_priv, CNL_PORT_PCS_DW1_LN0(port));
- if (type != INTEL_OUTPUT_HDMI)
- val |= COMMON_KEEPER_EN;
- else
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
val &= ~COMMON_KEEPER_EN;
+ else
+ val |= COMMON_KEEPER_EN;
intel_de_write(dev_priv, CNL_PORT_PCS_DW1_GRP(port), val);
/* 2. Program loadgen select */
@@ -2434,7 +2600,7 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
intel_de_write(dev_priv, CNL_PORT_TX_DW5_GRP(port), val);
/* 5. Program swing and de-emphasis */
- cnl_ddi_vswing_program(encoder, level, type);
+ cnl_ddi_vswing_program(encoder, crtc_state, level);
/* 6. Set training enable to trigger update */
val = intel_de_read(dev_priv, CNL_PORT_TX_DW5_LN0(port));
@@ -2443,23 +2609,23 @@ static void cnl_ddi_vswing_sequence(struct intel_encoder *encoder,
}
static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
- u32 level, int type, int rate)
+ const struct intel_crtc_state *crtc_state,
+ int level)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ const struct cnl_ddi_buf_trans *ddi_translations;
enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
- const struct cnl_ddi_buf_trans *ddi_translations = NULL;
- u32 n_entries, val;
- int ln;
+ int n_entries, ln;
+ u32 val;
if (INTEL_GEN(dev_priv) >= 12)
- ddi_translations = tgl_get_combo_buf_trans(encoder, type, rate,
- &n_entries);
- else if (IS_ELKHARTLAKE(dev_priv))
- ddi_translations = ehl_get_combo_buf_trans(encoder, type, rate,
- &n_entries);
+ ddi_translations = tgl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
+ else if (IS_PLATFORM(dev_priv, INTEL_JASPERLAKE))
+ ddi_translations = jsl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
+ else if (IS_PLATFORM(dev_priv, INTEL_ELKHARTLAKE))
+ ddi_translations = ehl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
else
- ddi_translations = icl_get_combo_buf_trans(encoder, type, rate,
- &n_entries);
+ ddi_translations = icl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
if (!ddi_translations)
return;
@@ -2470,7 +2636,7 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
level = n_entries - 1;
}
- if (type == INTEL_OUTPUT_EDP) {
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
val = EDP4K2K_MODE_OVRD_EN | EDP4K2K_MODE_OVRD_OPTIMIZED;
@@ -2518,25 +2684,16 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
}
static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
- u32 level,
- enum intel_output_type type)
+ const struct intel_crtc_state *crtc_state,
+ int level)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
- int width = 0;
- int rate = 0;
+ int width, rate, ln;
u32 val;
- int ln = 0;
- if (type == INTEL_OUTPUT_HDMI) {
- width = 4;
- /* Rate is always < than 6GHz for HDMI */
- } else {
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
- width = intel_dp->lane_count;
- rate = intel_dp->link_rate;
- }
+ width = crtc_state->lane_count;
+ rate = crtc_state->port_clock;
/*
* 1. If port type is eDP or DP,
@@ -2544,7 +2701,7 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
* else clear to 0b.
*/
val = intel_de_read(dev_priv, ICL_PORT_PCS_DW1_LN0(phy));
- if (type == INTEL_OUTPUT_HDMI)
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
val &= ~COMMON_KEEPER_EN;
else
val |= COMMON_KEEPER_EN;
@@ -2579,7 +2736,7 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
intel_de_write(dev_priv, ICL_PORT_TX_DW5_GRP(phy), val);
/* 5. Program swing and de-emphasis */
- icl_ddi_combo_vswing_program(encoder, level, type, rate);
+ icl_ddi_combo_vswing_program(encoder, crtc_state, level);
/* 6. Set training enable to trigger update */
val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy));
@@ -2588,23 +2745,16 @@ static void icl_combo_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
}
static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
- int link_clock, u32 level,
- enum intel_output_type type)
+ const struct intel_crtc_state *crtc_state,
+ int level)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port);
const struct icl_mg_phy_ddi_buf_trans *ddi_translations;
- u32 n_entries, val;
- int ln, rate = 0;
-
- if (type != INTEL_OUTPUT_HDMI) {
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
- rate = intel_dp->link_rate;
- }
+ int n_entries, ln;
+ u32 val;
- ddi_translations = icl_get_mg_buf_trans(encoder, type, rate,
- &n_entries);
+ 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,
@@ -2671,7 +2821,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
*/
for (ln = 0; ln < 2; ln++) {
val = intel_de_read(dev_priv, MG_CLKHUB(ln, tc_port));
- if (link_clock < 300000)
+ if (crtc_state->port_clock < 300000)
val |= CFG_LOW_RATE_LKREN_EN;
else
val &= ~CFG_LOW_RATE_LKREN_EN;
@@ -2682,7 +2832,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
for (ln = 0; ln < 2; ln++) {
val = intel_de_read(dev_priv, MG_TX1_DCC(ln, tc_port));
val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK;
- if (link_clock <= 500000) {
+ if (crtc_state->port_clock <= 500000) {
val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN;
} else {
val |= CFG_AMI_CK_DIV_OVERRIDE_EN |
@@ -2692,7 +2842,7 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
val = intel_de_read(dev_priv, MG_TX2_DCC(ln, tc_port));
val &= ~CFG_AMI_CK_DIV_OVERRIDE_VAL_MASK;
- if (link_clock <= 500000) {
+ if (crtc_state->port_clock <= 500000) {
val &= ~CFG_AMI_CK_DIV_OVERRIDE_EN;
} else {
val |= CFG_AMI_CK_DIV_OVERRIDE_EN |
@@ -2718,38 +2868,30 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
}
static void icl_ddi_vswing_sequence(struct intel_encoder *encoder,
- int link_clock,
- u32 level,
- enum intel_output_type type)
+ const struct intel_crtc_state *crtc_state,
+ int level)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
if (intel_phy_is_combo(dev_priv, phy))
- icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
+ icl_combo_phy_ddi_vswing_sequence(encoder, crtc_state, level);
else
- icl_mg_phy_ddi_vswing_sequence(encoder, link_clock, level,
- type);
+ icl_mg_phy_ddi_vswing_sequence(encoder, crtc_state, level);
}
static void
-tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock,
- u32 level, enum intel_output_type type)
+tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int level)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum tc_port tc_port = intel_port_to_tc(dev_priv, encoder->port);
const struct tgl_dkl_phy_ddi_buf_trans *ddi_translations;
- u32 n_entries, val, ln, dpcnt_mask, dpcnt_val;
- int rate = 0;
-
- if (type != INTEL_OUTPUT_HDMI) {
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
- rate = intel_dp->link_rate;
- }
+ u32 val, dpcnt_mask, dpcnt_val;
+ int n_entries, ln;
- ddi_translations = tgl_get_dkl_buf_trans(encoder, encoder->type, rate,
- &n_entries);
+ ddi_translations = tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
if (level >= n_entries)
level = n_entries - 1;
@@ -2785,20 +2927,20 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder, int link_clock,
}
static void tgl_ddi_vswing_sequence(struct intel_encoder *encoder,
- int link_clock,
- u32 level,
- enum intel_output_type type)
+ const struct intel_crtc_state *crtc_state,
+ int level)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
if (intel_phy_is_combo(dev_priv, phy))
- icl_combo_phy_ddi_vswing_sequence(encoder, level, type);
+ icl_combo_phy_ddi_vswing_sequence(encoder, crtc_state, level);
else
- tgl_dkl_phy_ddi_vswing_sequence(encoder, link_clock, level, type);
+ tgl_dkl_phy_ddi_vswing_sequence(encoder, crtc_state, level);
}
-static u32 translate_signal_level(struct intel_dp *intel_dp, int signal_levels)
+static int translate_signal_level(struct intel_dp *intel_dp,
+ u8 signal_levels)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
int i;
@@ -2815,55 +2957,58 @@ static u32 translate_signal_level(struct intel_dp *intel_dp, int signal_levels)
return 0;
}
-static u32 intel_ddi_dp_level(struct intel_dp *intel_dp)
+static int intel_ddi_dp_level(struct intel_dp *intel_dp)
{
u8 train_set = intel_dp->train_set[0];
- int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
- DP_TRAIN_PRE_EMPHASIS_MASK);
+ u8 signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
+ DP_TRAIN_PRE_EMPHASIS_MASK);
return translate_signal_level(intel_dp, signal_levels);
}
static void
-tgl_set_signal_levels(struct intel_dp *intel_dp)
+tgl_set_signal_levels(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
{
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
int level = intel_ddi_dp_level(intel_dp);
- tgl_ddi_vswing_sequence(encoder, intel_dp->link_rate,
- level, encoder->type);
+ tgl_ddi_vswing_sequence(encoder, crtc_state, level);
}
static void
-icl_set_signal_levels(struct intel_dp *intel_dp)
+icl_set_signal_levels(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
{
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
int level = intel_ddi_dp_level(intel_dp);
- icl_ddi_vswing_sequence(encoder, intel_dp->link_rate,
- level, encoder->type);
+ icl_ddi_vswing_sequence(encoder, crtc_state, level);
}
static void
-cnl_set_signal_levels(struct intel_dp *intel_dp)
+cnl_set_signal_levels(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
{
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
int level = intel_ddi_dp_level(intel_dp);
- cnl_ddi_vswing_sequence(encoder, level, encoder->type);
+ cnl_ddi_vswing_sequence(encoder, crtc_state, level);
}
static void
-bxt_set_signal_levels(struct intel_dp *intel_dp)
+bxt_set_signal_levels(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
{
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
int level = intel_ddi_dp_level(intel_dp);
- bxt_ddi_vswing_sequence(encoder, level, encoder->type);
+ bxt_ddi_vswing_sequence(encoder, crtc_state, level);
}
static void
-hsw_set_signal_levels(struct intel_dp *intel_dp)
+hsw_set_signal_levels(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
{
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -2880,7 +3025,7 @@ hsw_set_signal_levels(struct intel_dp *intel_dp)
intel_dp->DP |= signal_levels;
if (IS_GEN9_BC(dev_priv))
- skl_ddi_set_iboost(encoder, level, encoder->type);
+ skl_ddi_set_iboost(encoder, crtc_state, level);
intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
@@ -2903,6 +3048,40 @@ static u32 icl_dpclka_cfgcr0_clk_off(struct drm_i915_private *dev_priv,
return 0;
}
+static void dg1_map_plls_to_ports(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ struct intel_shared_dpll *pll = crtc_state->shared_dpll;
+ enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
+ u32 val;
+
+ /*
+ * If we fail this, something went very wrong: first 2 PLLs should be
+ * used by first 2 phys and last 2 PLLs by last phys
+ */
+ if (drm_WARN_ON(&dev_priv->drm,
+ (pll->info->id < DPLL_ID_DG1_DPLL2 && phy >= PHY_C) ||
+ (pll->info->id >= DPLL_ID_DG1_DPLL2 && phy < PHY_C)))
+ return;
+
+ mutex_lock(&dev_priv->dpll.lock);
+
+ val = intel_de_read(dev_priv, DG1_DPCLKA_CFGCR0(phy));
+ drm_WARN_ON(&dev_priv->drm,
+ (val & DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy)) == 0);
+
+ val &= ~DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
+ val |= DG1_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy);
+ intel_de_write(dev_priv, DG1_DPCLKA_CFGCR0(phy), val);
+ intel_de_posting_read(dev_priv, DG1_DPCLKA_CFGCR0(phy));
+
+ val &= ~DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
+ intel_de_write(dev_priv, DG1_DPCLKA_CFGCR0(phy), val);
+
+ mutex_unlock(&dev_priv->dpll.lock);
+}
+
static void icl_map_plls_to_ports(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
@@ -2950,6 +3129,19 @@ static void icl_map_plls_to_ports(struct intel_encoder *encoder,
mutex_unlock(&dev_priv->dpll.lock);
}
+static void dg1_unmap_plls_to_ports(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
+
+ mutex_lock(&dev_priv->dpll.lock);
+
+ intel_de_rmw(dev_priv, DG1_DPCLKA_CFGCR0(phy), 0,
+ DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
+
+ mutex_unlock(&dev_priv->dpll.lock);
+}
+
static void icl_unmap_plls_to_ports(struct intel_encoder *encoder)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
@@ -2965,6 +3157,37 @@ static void icl_unmap_plls_to_ports(struct intel_encoder *encoder)
mutex_unlock(&dev_priv->dpll.lock);
}
+static void dg1_sanitize_port_clk_off(struct drm_i915_private *dev_priv,
+ u32 port_mask, bool ddi_clk_needed)
+{
+ enum port port;
+ u32 val;
+
+ for_each_port_masked(port, port_mask) {
+ enum phy phy = intel_port_to_phy(dev_priv, port);
+ bool ddi_clk_off;
+
+ val = intel_de_read(dev_priv, DG1_DPCLKA_CFGCR0(phy));
+ ddi_clk_off = val & DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
+
+ if (ddi_clk_needed == !ddi_clk_off)
+ continue;
+
+ /*
+ * Punt on the case now where clock is gated, but it would
+ * be needed by the port. Something else is really broken then.
+ */
+ if (drm_WARN_ON(&dev_priv->drm, ddi_clk_needed))
+ continue;
+
+ drm_notice(&dev_priv->drm,
+ "PHY %c is disabled with an ungated DDI clock, gate it\n",
+ phy_name(phy));
+ val |= DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
+ intel_de_write(dev_priv, DG1_DPCLKA_CFGCR0(phy), val);
+ }
+}
+
static void icl_sanitize_port_clk_off(struct drm_i915_private *dev_priv,
u32 port_mask, bool ddi_clk_needed)
{
@@ -3047,7 +3270,10 @@ void icl_sanitize_encoder_pll_mapping(struct intel_encoder *encoder)
ddi_clk_needed = false;
}
- icl_sanitize_port_clk_off(dev_priv, port_mask, ddi_clk_needed);
+ if (IS_DG1(dev_priv))
+ dg1_sanitize_port_clk_off(dev_priv, port_mask, ddi_clk_needed);
+ else
+ icl_sanitize_port_clk_off(dev_priv, port_mask, ddi_clk_needed);
}
static void intel_ddi_clk_select(struct intel_encoder *encoder,
@@ -3068,7 +3294,7 @@ static void intel_ddi_clk_select(struct intel_encoder *encoder,
if (!intel_phy_is_combo(dev_priv, phy))
intel_de_write(dev_priv, DDI_CLK_SEL(port),
icl_pll_to_ddi_clk_sel(encoder, crtc_state));
- else if (IS_ELKHARTLAKE(dev_priv) && port >= PORT_C)
+ else if (IS_JSL_EHL(dev_priv) && port >= PORT_C)
/*
* MG does not exist but the programming is required
* to ungate DDIC and DDID
@@ -3117,7 +3343,7 @@ static void intel_ddi_clk_disable(struct intel_encoder *encoder)
if (INTEL_GEN(dev_priv) >= 11) {
if (!intel_phy_is_combo(dev_priv, phy) ||
- (IS_ELKHARTLAKE(dev_priv) && port >= PORT_C))
+ (IS_JSL_EHL(dev_priv) && port >= PORT_C))
intel_de_write(dev_priv, DDI_CLK_SEL(port),
DDI_CLK_SEL_NONE);
} else if (IS_CANNONLAKE(dev_priv)) {
@@ -3223,6 +3449,37 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port,
}
}
+static enum transcoder
+tgl_dp_tp_transcoder(const struct intel_crtc_state *crtc_state)
+{
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST))
+ return crtc_state->mst_master_transcoder;
+ else
+ return crtc_state->cpu_transcoder;
+}
+
+i915_reg_t dp_tp_ctl_reg(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+ if (INTEL_GEN(dev_priv) >= 12)
+ return TGL_DP_TP_CTL(tgl_dp_tp_transcoder(crtc_state));
+ else
+ return DP_TP_CTL(encoder->port);
+}
+
+i915_reg_t dp_tp_status_reg(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+ if (INTEL_GEN(dev_priv) >= 12)
+ return TGL_DP_TP_STATUS(tgl_dp_tp_transcoder(crtc_state));
+ else
+ return DP_TP_STATUS(encoder->port);
+}
+
static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
@@ -3247,11 +3504,12 @@ static void intel_ddi_enable_fec(struct intel_encoder *encoder,
return;
intel_dp = enc_to_intel_dp(encoder);
- val = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+ val = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
val |= DP_TP_CTL_FEC_ENABLE;
- intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, val);
+ intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), val);
- if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
+ 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");
@@ -3268,10 +3526,10 @@ static void intel_ddi_disable_fec_state(struct intel_encoder *encoder,
return;
intel_dp = enc_to_intel_dp(encoder);
- val = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+ val = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
val &= ~DP_TP_CTL_FEC_ENABLE;
- intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, val);
- intel_de_posting_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+ intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), val);
+ intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
}
static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
@@ -3285,13 +3543,10 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST);
int level = intel_ddi_dp_level(intel_dp);
- enum transcoder transcoder = crtc_state->cpu_transcoder;
- intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
- crtc_state->lane_count, is_mst);
-
- intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
- intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
+ intel_dp_set_link_params(intel_dp,
+ crtc_state->port_clock,
+ crtc_state->lane_count);
/*
* 1. Enable Power Wells
@@ -3360,8 +3615,7 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
*/
/* 7.e Configure voltage swing and related IO settings */
- tgl_ddi_vswing_sequence(encoder, crtc_state->port_clock, level,
- encoder->type);
+ tgl_ddi_vswing_sequence(encoder, crtc_state, level);
/*
* 7.f Combo PHY: Configure PORT_CL_DW10 Static Power Down to power up
@@ -3384,10 +3638,10 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
* We only configure what the register value will be here. Actual
* enabling happens during link training farther down.
*/
- intel_ddi_init_dp_buf_reg(encoder);
+ intel_ddi_init_dp_buf_reg(encoder, crtc_state);
if (!is_mst)
- intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+ intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true);
/*
@@ -3404,15 +3658,16 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
* Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent)
* (timeout after 800 us)
*/
- intel_dp_start_link_train(intel_dp);
+ intel_dp_start_link_train(intel_dp, crtc_state);
/* 7.k Set DP_TP_CTL link training to Normal */
if (!is_trans_port_sync_mode(crtc_state))
- intel_dp_stop_link_train(intel_dp);
+ intel_dp_stop_link_train(intel_dp, crtc_state);
/* 7.l Configure and enable FEC if needed */
intel_ddi_enable_fec(encoder, crtc_state);
- intel_dsc_enable(encoder, crtc_state);
+ if (!crtc_state->bigjoiner)
+ intel_dsc_enable(encoder, crtc_state);
}
static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
@@ -3434,8 +3689,9 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
else
drm_WARN_ON(&dev_priv->drm, is_mst && port == PORT_A);
- intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
- crtc_state->lane_count, is_mst);
+ intel_dp_set_link_params(intel_dp,
+ crtc_state->port_clock,
+ crtc_state->lane_count);
intel_edp_panel_on(intel_dp);
@@ -3449,12 +3705,11 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
icl_program_mg_dp_mode(dig_port, crtc_state);
if (INTEL_GEN(dev_priv) >= 11)
- icl_ddi_vswing_sequence(encoder, crtc_state->port_clock,
- level, encoder->type);
+ icl_ddi_vswing_sequence(encoder, crtc_state, level);
else if (IS_CANNONLAKE(dev_priv))
- cnl_ddi_vswing_sequence(encoder, level, encoder->type);
+ cnl_ddi_vswing_sequence(encoder, crtc_state, level);
else if (IS_GEN9_LP(dev_priv))
- bxt_ddi_vswing_sequence(encoder, level, encoder->type);
+ bxt_ddi_vswing_sequence(encoder, crtc_state, level);
else
intel_prepare_dp_ddi_buffers(encoder, crtc_state);
@@ -3467,24 +3722,25 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
lane_reversal);
}
- intel_ddi_init_dp_buf_reg(encoder);
+ intel_ddi_init_dp_buf_reg(encoder, crtc_state);
if (!is_mst)
- intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+ intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
intel_dp_configure_protocol_converter(intel_dp);
intel_dp_sink_set_decompression_state(intel_dp, crtc_state,
true);
intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
- intel_dp_start_link_train(intel_dp);
+ intel_dp_start_link_train(intel_dp, crtc_state);
if ((port != PORT_A || INTEL_GEN(dev_priv) >= 9) &&
!is_trans_port_sync_mode(crtc_state))
- intel_dp_stop_link_train(intel_dp);
+ intel_dp_stop_link_train(intel_dp, crtc_state);
intel_ddi_enable_fec(encoder, crtc_state);
if (!is_mst)
intel_ddi_enable_pipe_clock(encoder, crtc_state);
- intel_dsc_enable(encoder, crtc_state);
+ if (!crtc_state->bigjoiner)
+ intel_dsc_enable(encoder, crtc_state);
}
static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state,
@@ -3517,7 +3773,7 @@ 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);
+ 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);
@@ -3527,20 +3783,18 @@ 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->port_clock,
- level, INTEL_OUTPUT_HDMI);
+ tgl_ddi_vswing_sequence(encoder, crtc_state, level);
else if (INTEL_GEN(dev_priv) == 11)
- icl_ddi_vswing_sequence(encoder, crtc_state->port_clock,
- level, INTEL_OUTPUT_HDMI);
+ icl_ddi_vswing_sequence(encoder, crtc_state, level);
else if (IS_CANNONLAKE(dev_priv))
- cnl_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
+ cnl_ddi_vswing_sequence(encoder, crtc_state, level);
else if (IS_GEN9_LP(dev_priv))
- bxt_ddi_vswing_sequence(encoder, level, INTEL_OUTPUT_HDMI);
+ 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, level, INTEL_OUTPUT_HDMI);
+ skl_ddi_set_iboost(encoder, crtc_state, level);
intel_ddi_enable_pipe_clock(encoder, crtc_state);
@@ -3573,7 +3827,9 @@ static void intel_ddi_pre_enable(struct intel_atomic_state *state,
drm_WARN_ON(&dev_priv->drm, crtc_state->has_pch_encoder);
- if (INTEL_GEN(dev_priv) >= 11)
+ if (IS_DG1(dev_priv))
+ dg1_map_plls_to_ports(encoder, crtc_state);
+ else if (INTEL_GEN(dev_priv) >= 11)
icl_map_plls_to_ports(encoder, crtc_state);
intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
@@ -3612,12 +3868,10 @@ static void intel_disable_ddi_buf(struct intel_encoder *encoder,
}
if (intel_crtc_has_dp_encoder(crtc_state)) {
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
- val = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+ val = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
val &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
val |= DP_TP_CTL_LINK_TRAIN_PAT1;
- intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, val);
+ intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), val);
}
/* Disable FEC in DP Sink */
@@ -3647,7 +3901,7 @@ static void intel_ddi_post_disable_dp(struct intel_atomic_state *state,
* Power down sink before disabling the port, otherwise we end
* up getting interrupts from the sink on detecting link loss.
*/
- intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+ intel_dp_set_power(intel_dp, DP_SET_POWER_D3);
if (INTEL_GEN(dev_priv) >= 12) {
if (is_mst) {
@@ -3737,6 +3991,21 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
ilk_pfit_disable(old_crtc_state);
}
+ if (old_crtc_state->bigjoiner_linked_crtc) {
+ struct intel_atomic_state *state =
+ to_intel_atomic_state(old_crtc_state->uapi.state);
+ struct intel_crtc *slave =
+ old_crtc_state->bigjoiner_linked_crtc;
+ const struct intel_crtc_state *old_slave_crtc_state =
+ intel_atomic_get_old_crtc_state(state, slave);
+
+ intel_crtc_vblank_off(old_slave_crtc_state);
+ trace_intel_pipe_disable(slave);
+
+ intel_dsc_disable(old_slave_crtc_state);
+ skl_scaler_disable(old_slave_crtc_state);
+ }
+
/*
* When called from DP MST code:
* - old_conn_state will be NULL
@@ -3757,7 +4026,9 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
intel_ddi_post_disable_dp(state, encoder, old_crtc_state,
old_conn_state);
- if (INTEL_GEN(dev_priv) >= 11)
+ if (IS_DG1(dev_priv))
+ dg1_unmap_plls_to_ports(encoder);
+ else if (INTEL_GEN(dev_priv) >= 11)
icl_unmap_plls_to_ports(encoder);
if (intel_crtc_has_dp_encoder(old_crtc_state) || is_tc_port)
@@ -3830,12 +4101,14 @@ static void trans_port_sync_stop_link_train(struct intel_atomic_state *state,
crtc_state->cpu_transcoder)
continue;
- intel_dp_stop_link_train(enc_to_intel_dp(slave_encoder));
+ intel_dp_stop_link_train(enc_to_intel_dp(slave_encoder),
+ slave_crtc_state);
}
usleep_range(200, 400);
- intel_dp_stop_link_train(enc_to_intel_dp(encoder));
+ intel_dp_stop_link_train(enc_to_intel_dp(encoder),
+ crtc_state);
}
static void intel_enable_ddi_dp(struct intel_atomic_state *state,
@@ -3848,7 +4121,7 @@ static void intel_enable_ddi_dp(struct intel_atomic_state *state,
enum port port = encoder->port;
if (port == PORT_A && INTEL_GEN(dev_priv) < 9)
- intel_dp_stop_link_train(intel_dp);
+ intel_dp_stop_link_train(intel_dp, crtc_state);
intel_edp_backlight_on(crtc_state, conn_state);
intel_psr_enable(intel_dp, crtc_state, conn_state);
@@ -3951,7 +4224,8 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
{
drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
- intel_ddi_enable_transcoder_func(encoder, crtc_state);
+ if (!crtc_state->bigjoiner_slave)
+ intel_ddi_enable_transcoder_func(encoder, crtc_state);
intel_enable_pipe(crtc_state);
@@ -4109,15 +4383,16 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
crtc_state->lane_lat_optim_mask);
}
-static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
+static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
{
- struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
- struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
- enum port port = dig_port->base.port;
+ struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ enum port port = encoder->port;
u32 dp_tp_ctl, ddi_buf_ctl;
bool wait = false;
- dp_tp_ctl = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+ dp_tp_ctl = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
if (dp_tp_ctl & DP_TP_CTL_ENABLE) {
ddi_buf_ctl = intel_de_read(dev_priv, DDI_BUF_CTL(port));
@@ -4129,23 +4404,23 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
dp_tp_ctl &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
dp_tp_ctl |= DP_TP_CTL_LINK_TRAIN_PAT1;
- intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, dp_tp_ctl);
- intel_de_posting_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+ intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl);
+ intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
if (wait)
intel_wait_ddi_buf_idle(dev_priv, port);
}
dp_tp_ctl = DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT1;
- if (intel_dp->link_mst)
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)) {
dp_tp_ctl |= DP_TP_CTL_MODE_MST;
- else {
+ } else {
dp_tp_ctl |= DP_TP_CTL_MODE_SST;
if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
dp_tp_ctl |= DP_TP_CTL_ENHANCED_FRAME_ENABLE;
}
- intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, dp_tp_ctl);
- intel_de_posting_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+ intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), dp_tp_ctl);
+ intel_de_posting_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
intel_dp->DP |= DDI_BUF_CTL_ENABLE;
intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
@@ -4155,16 +4430,17 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
}
static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state,
u8 dp_train_pat)
{
- struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- u8 train_pat_mask = drm_dp_training_pattern_mask(intel_dp->dpcd);
+ struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
u32 temp;
- temp = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+ temp = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
temp &= ~DP_TP_CTL_LINK_TRAIN_MASK;
- switch (dp_train_pat & train_pat_mask) {
+ switch (intel_dp_training_pattern_symbol(dp_train_pat)) {
case DP_TRAINING_PATTERN_DISABLE:
temp |= DP_TP_CTL_LINK_TRAIN_NORMAL;
break;
@@ -4182,20 +4458,21 @@ static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
break;
}
- intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, temp);
+ intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), temp);
}
-static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp)
+static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp,
+ const struct intel_crtc_state *crtc_state)
{
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
enum port port = encoder->port;
u32 val;
- val = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
+ val = intel_de_read(dev_priv, dp_tp_ctl_reg(encoder, crtc_state));
val &= ~DP_TP_CTL_LINK_TRAIN_MASK;
val |= DP_TP_CTL_LINK_TRAIN_IDLE;
- intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, val);
+ intel_de_write(dev_priv, dp_tp_ctl_reg(encoder, crtc_state), val);
/*
* Until TGL on PORT_A we can have only eDP in SST mode. There the only
@@ -4207,7 +4484,8 @@ static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp)
if (port == PORT_A && INTEL_GEN(dev_priv) < 12)
return;
- if (intel_de_wait_for_set(dev_priv, intel_dp->regs.dp_tp_status,
+ if (intel_de_wait_for_set(dev_priv,
+ dp_tp_status_reg(encoder, crtc_state),
DP_TP_STATUS_IDLE_DONE, 1))
drm_err(&dev_priv->drm,
"Timed out waiting for DP idle patterns\n");
@@ -4231,7 +4509,7 @@ void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
{
if (INTEL_GEN(dev_priv) >= 12 && crtc_state->port_clock > 594000)
crtc_state->min_voltage_level = 2;
- else if (IS_ELKHARTLAKE(dev_priv) && crtc_state->port_clock > 594000)
+ else if (IS_JSL_EHL(dev_priv) && crtc_state->port_clock > 594000)
crtc_state->min_voltage_level = 3;
else if (INTEL_GEN(dev_priv) >= 11 && crtc_state->port_clock > 594000)
crtc_state->min_voltage_level = 1;
@@ -4299,21 +4577,14 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state)
crtc_state->sync_mode_slaves_mask);
}
-void intel_ddi_get_config(struct intel_encoder *encoder,
- struct intel_crtc_state *pipe_config)
+static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
+ struct intel_crtc_state *pipe_config)
{
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_dp *intel_dp = enc_to_intel_dp(encoder);
u32 temp, flags = 0;
- /* XXX: DSI transcoder paranoia */
- if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
- return;
-
- intel_dsc_get_config(encoder, pipe_config);
-
temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
if (temp & TRANS_DDI_PHSYNC)
flags |= DRM_MODE_FLAG_PHSYNC;
@@ -4375,12 +4646,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
intel_dp_get_m_n(intel_crtc, pipe_config);
if (INTEL_GEN(dev_priv) >= 11) {
- i915_reg_t dp_tp_ctl;
-
- if (IS_GEN(dev_priv, 11))
- dp_tp_ctl = DP_TP_CTL(encoder->port);
- else
- dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
+ i915_reg_t dp_tp_ctl = dp_tp_ctl_reg(encoder, pipe_config);
pipe_config->fec_enable =
intel_de_read(dev_priv, dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;
@@ -4412,15 +4678,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
default:
break;
}
+}
- if (INTEL_GEN(dev_priv) >= 12) {
- enum transcoder transcoder =
- intel_dp_mst_is_slave_trans(pipe_config) ?
- pipe_config->mst_master_transcoder :
- pipe_config->cpu_transcoder;
+void intel_ddi_get_config(struct intel_encoder *encoder,
+ struct intel_crtc_state *pipe_config)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
- intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
- intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
+ /* XXX: DSI transcoder paranoia */
+ if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
+ return;
+
+ if (pipe_config->bigjoiner_slave) {
+ /* read out pipe settings from master */
+ enum transcoder save = pipe_config->cpu_transcoder;
+
+ /* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */
+ WARN_ON(pipe_config->output_types);
+ pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;
+ intel_ddi_read_func_ctl(encoder, pipe_config);
+ pipe_config->cpu_transcoder = save;
+ } else {
+ intel_ddi_read_func_ctl(encoder, pipe_config);
}
pipe_config->has_audio =
@@ -4447,7 +4727,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
}
- intel_ddi_clock_get(encoder, pipe_config);
+ if (!pipe_config->bigjoiner_slave)
+ intel_ddi_clock_get(encoder, pipe_config);
if (IS_GEN9_LP(dev_priv))
pipe_config->lane_lat_optim_mask =
@@ -4477,6 +4758,22 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
intel_read_dp_sdp(encoder, pipe_config, DP_SDP_VSC);
}
+static void intel_ddi_sync_state(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state)
+{
+ if (intel_crtc_has_dp_encoder(crtc_state))
+ intel_dp_sync_state(encoder, crtc_state);
+}
+
+static bool intel_ddi_initial_fastset_check(struct intel_encoder *encoder,
+ struct intel_crtc_state *crtc_state)
+{
+ if (intel_crtc_has_dp_encoder(crtc_state))
+ return intel_dp_initial_fastset_check(encoder, crtc_state);
+
+ return true;
+}
+
static enum intel_output_type
intel_ddi_compute_output_type(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state,
@@ -4687,11 +4984,6 @@ intel_ddi_init_dp_connector(struct intel_digital_port *dig_port)
dig_port->dp.voltage_max = intel_ddi_dp_voltage_max;
dig_port->dp.preemph_max = intel_ddi_dp_preemph_max;
- if (INTEL_GEN(dev_priv) < 12) {
- dig_port->dp.regs.dp_tp_ctl = DP_TP_CTL(port);
- dig_port->dp.regs.dp_tp_status = DP_TP_STATUS(port);
- }
-
if (!intel_dp_init_connector(dig_port, connector)) {
kfree(connector);
return NULL;
@@ -4974,11 +5266,20 @@ static bool hti_uses_phy(struct drm_i915_private *i915, enum phy phy)
i915->hti_state & HDPORT_PHY_USED_HDMI(phy));
}
+static enum hpd_pin dg1_hpd_pin(struct drm_i915_private *dev_priv,
+ enum port port)
+{
+ if (port >= PORT_TC1)
+ return HPD_PORT_C + port - PORT_TC1;
+ else
+ return HPD_PORT_A + port - PORT_A;
+}
+
static enum hpd_pin tgl_hpd_pin(struct drm_i915_private *dev_priv,
enum port port)
{
- if (port >= PORT_D)
- return HPD_PORT_TC1 + port - PORT_D;
+ if (port >= PORT_TC1)
+ return HPD_PORT_TC1 + port - PORT_TC1;
else
return HPD_PORT_A + port - PORT_A;
}
@@ -4989,8 +5290,8 @@ static enum hpd_pin rkl_hpd_pin(struct drm_i915_private *dev_priv,
if (HAS_PCH_TGP(dev_priv))
return tgl_hpd_pin(dev_priv, port);
- if (port >= PORT_D)
- return HPD_PORT_C + port - PORT_D;
+ if (port >= PORT_TC1)
+ return HPD_PORT_C + port - PORT_TC1;
else
return HPD_PORT_A + port - PORT_A;
}
@@ -5025,11 +5326,14 @@ static enum hpd_pin cnl_hpd_pin(struct drm_i915_private *dev_priv,
return HPD_PORT_A + port - PORT_A;
}
+#define port_tc_name(port) ((port) - PORT_TC1 + '1')
+#define tc_port_name(tc_port) ((tc_port) - TC_PORT_1 + '1')
+
void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
{
struct intel_digital_port *dig_port;
struct intel_encoder *encoder;
- bool init_hdmi, init_dp, init_lspcon = false;
+ bool init_hdmi, init_dp;
enum phy phy = intel_port_to_phy(dev_priv, port);
/*
@@ -5055,7 +5359,6 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
* is initialized before lspcon.
*/
init_dp = true;
- init_lspcon = true;
init_hdmi = false;
drm_dbg_kms(&dev_priv->drm, "VBT says port %c has lspcon\n",
port_name(port));
@@ -5074,8 +5377,31 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
encoder = &dig_port->base;
- drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
- DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port));
+ if (INTEL_GEN(dev_priv) >= 12) {
+ enum tc_port tc_port = intel_port_to_tc(dev_priv, port);
+
+ drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
+ DRM_MODE_ENCODER_TMDS,
+ "DDI %s%c/PHY %s%c",
+ port >= PORT_TC1 ? "TC" : "",
+ port >= PORT_TC1 ? port_tc_name(port) : port_name(port),
+ tc_port != TC_PORT_NONE ? "TC" : "",
+ tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy));
+ } else if (INTEL_GEN(dev_priv) >= 11) {
+ enum tc_port tc_port = intel_port_to_tc(dev_priv, port);
+
+ drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
+ DRM_MODE_ENCODER_TMDS,
+ "DDI %c%s/PHY %s%c",
+ port_name(port),
+ port >= PORT_C ? " (TC)" : "",
+ tc_port != TC_PORT_NONE ? "TC" : "",
+ tc_port != TC_PORT_NONE ? tc_port_name(tc_port) : phy_name(phy));
+ } else {
+ drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs,
+ DRM_MODE_ENCODER_TMDS,
+ "DDI %c/PHY %c", port_name(port), phy_name(phy));
+ }
mutex_init(&dig_port->hdcp_mutex);
dig_port->num_hdcp_streams = 0;
@@ -5092,7 +5418,10 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
encoder->update_pipe = intel_ddi_update_pipe;
encoder->get_hw_state = intel_ddi_get_hw_state;
encoder->get_config = intel_ddi_get_config;
+ encoder->sync_state = intel_ddi_sync_state;
+ encoder->initial_fastset_check = intel_ddi_initial_fastset_check;
encoder->suspend = intel_dp_encoder_suspend;
+ encoder->shutdown = intel_dp_encoder_shutdown;
encoder->get_power_domains = intel_ddi_get_power_domains;
encoder->type = INTEL_OUTPUT_DDI;
@@ -5101,11 +5430,13 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
encoder->cloneable = 0;
encoder->pipe_mask = ~0;
- if (IS_ROCKETLAKE(dev_priv))
+ if (IS_DG1(dev_priv))
+ encoder->hpd_pin = dg1_hpd_pin(dev_priv, port);
+ else if (IS_ROCKETLAKE(dev_priv))
encoder->hpd_pin = rkl_hpd_pin(dev_priv, port);
else if (INTEL_GEN(dev_priv) >= 12)
encoder->hpd_pin = tgl_hpd_pin(dev_priv, port);
- else if (IS_ELKHARTLAKE(dev_priv))
+ else if (IS_JSL_EHL(dev_priv))
encoder->hpd_pin = ehl_hpd_pin(dev_priv, port);
else if (IS_GEN(dev_priv, 11))
encoder->hpd_pin = icl_hpd_pin(dev_priv, port);
@@ -5156,22 +5487,6 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
goto err;
}
- if (init_lspcon) {
- if (lspcon_init(dig_port))
- /* TODO: handle hdmi info frame part */
- drm_dbg_kms(&dev_priv->drm,
- "LSPCON init success on port %c\n",
- port_name(port));
- else
- /*
- * LSPCON init faied, but DP init was success, so
- * lets try to drive as DP++ port.
- */
- drm_err(&dev_priv->drm,
- "LSPCON init failed on port %c\n",
- port_name(port));
- }
-
if (INTEL_GEN(dev_priv) >= 11) {
if (intel_phy_is_tc(dev_priv, phy))
dig_port->connected = intel_tc_port_connected;