[PATCH 4/5] drm/i915/display: Implement HOBL

José Roberto de Souza jose.souza at intel.com
Wed Jul 8 16:28:38 UTC 2020


Hours Of Battery Life is a new GEN12+ power-saving feature that allows
supported motherboards to use a special voltage swing table for eDP
panels that uses less power.

So here if supported by HW, OEM will set it in VBT and i915 will try
to train link with HOBL vswing table if link training fails it fall
back to the original table.

intel_ddi_dp_preemph_max() was optimized to only check the HOBL flag
instead of do something like is done in intel_ddi_dp_voltage_max()
because it is only called after the first entry of the voltage swing
table was loaded so the HOBL flag is valid at that point.

v3:
- removed a few parameters of icl_ddi_combo_vswing_program() that
can be taken from encoder(TODO)

v4:
- using the HOBL vswing table until training fails completely (Ville)

BSpec: 49291
BSpec: 49399
Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
Cc: Animesh Manna <animesh.manna at intel.com>
Cc: Manasi Navare <manasi.d.navare at intel.com>
Signed-off-by: José Roberto de Souza <jose.souza at intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c      | 39 ++++++++++++++++---
 .../drm/i915/display/intel_display_types.h    |  2 +
 .../drm/i915/display/intel_dp_link_training.c |  5 +++
 drivers/gpu/drm/i915/i915_reg.h               |  2 +
 4 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 3ba4cf6de993..69f08e4af4d6 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -706,6 +706,15 @@ static const struct cnl_ddi_buf_trans tgl_combo_phy_ddi_translations_dp_hbr2[] =
 	{ 0x6, 0x7F, 0x3F, 0x00, 0x00 },	/* 900   900      0.0   */
 };
 
+static const struct cnl_ddi_buf_trans tgl_combo_phy_ddi_translations_edp_hbr2_hobl[] = {
+	{ 0x6, 0x7F, 0x3F, 0x00, 0x00 }
+};
+
+static bool is_hobl_buf_trans(const struct cnl_ddi_buf_trans *table)
+{
+	return table == tgl_combo_phy_ddi_translations_edp_hbr2_hobl;
+}
+
 static const struct ddi_buf_trans *
 bdw_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries)
 {
@@ -1050,6 +1059,18 @@ static const struct cnl_ddi_buf_trans *
 tgl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate,
 			int *n_entries)
 {
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+	if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.hobl) {
+		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+		if (!intel_dp->hobl_disabled && 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 (type == INTEL_OUTPUT_HDMI || type == INTEL_OUTPUT_EDP) {
 		return icl_get_combo_buf_trans(encoder, type, rate, n_entries);
 	} else if (rate > 270000) {
@@ -2209,13 +2230,12 @@ static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp)
 		DP_TRAIN_VOLTAGE_SWING_MASK;
 }
 
-/*
- * We assume that the full set of pre-emphasis values can be
- * used on all DDI platforms. Should that change we need to
- * rethink this code.
- */
 static u8 intel_ddi_dp_preemph_max(struct intel_dp *intel_dp)
 {
+	/* HOBL voltage swing table only have one entry */
+	if (intel_dp->hobl_active)
+		return DP_TRAIN_PRE_EMPH_LEVEL_0;
+
 	return DP_TRAIN_PRE_EMPH_LEVEL_3;
 }
 
@@ -2378,6 +2398,15 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
 		level = n_entries - 1;
 	}
 
+	if (INTEL_GEN(dev_priv) >= 12 && type == INTEL_OUTPUT_EDP) {
+		struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+		val = EDP4K2K_MODE_OVRD_EN | EDP4K2K_MODE_OVRD_OPTIMIZED;
+		intel_dp->hobl_active = is_hobl_buf_trans(ddi_translations);
+		intel_de_rmw(dev_priv, ICL_PORT_CL_DW10(phy), val,
+			     intel_dp->hobl_active ? val : 0);
+	}
+
 	/* Set PORT_TX_DW5 */
 	val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy));
 	val &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK |
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index e8f809161c75..fd4f0e4d0be7 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1375,6 +1375,8 @@ struct intel_dp {
 
 	/* Display stream compression testing */
 	bool force_dsc_en;
+
+	u8 hobl_disabled : 1, hobl_active : 1, hobl_not_used : 6;
 };
 
 enum lspcon_vendor {
diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index 2493142a70e9..925822fd386d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -401,6 +401,11 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 		    intel_connector->base.base.id,
 		    intel_connector->base.name,
 		    intel_dp->link_rate, intel_dp->lane_count);
+	if (intel_dp->hobl_active) {
+		drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
+			    "Link Training failed with HOBL active, not enabling it for now on");
+		intel_dp->hobl_disabled = true;
+	}
 	if (!intel_dp_get_link_train_fallback_values(intel_dp,
 						     intel_dp->link_rate,
 						     intel_dp->lane_count))
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 86a23ced051b..ea16931c0fa4 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1898,6 +1898,8 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
 #define  PWR_DOWN_LN_3_1_0		(0xb << 4)
 #define  PWR_DOWN_LN_MASK		(0xf << 4)
 #define  PWR_DOWN_LN_SHIFT		4
+#define  EDP4K2K_MODE_OVRD_EN		(1 << 3)
+#define  EDP4K2K_MODE_OVRD_OPTIMIZED	(1 << 2)
 
 #define ICL_PORT_CL_DW12(phy)		_MMIO(_ICL_PORT_CL_DW(12, phy))
 #define   ICL_LANE_ENABLE_AUX		(1 << 0)
-- 
2.27.0



More information about the Intel-gfx-trybot mailing list