Commit 81619f4a authored by José Roberto de Souza's avatar José Roberto de Souza Committed by Rodrigo Vivi

drm/i915/display: Implement HOBL

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

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

v5:
- not reducing lane or link rate when link training fails with HOBL
active
- duplicated the HOBL voltage swing entry to match DP spec requirement

v6:
- removed the optional VS 3 & pre-emp 0 from HOBL table
- changed from u8:1 to bool to store hobl_failed/active

BSpec: 49291
BSpec: 49399
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Animesh Manna <animesh.manna@intel.com>
Cc: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: default avatarJosé Roberto de Souza <jose.souza@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200715175637.33763-1-jose.souza@intel.comSigned-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
parent f2bde254
...@@ -706,6 +706,28 @@ static const struct cnl_ddi_buf_trans tgl_combo_phy_ddi_translations_dp_hbr2[] = ...@@ -706,6 +706,28 @@ static const struct cnl_ddi_buf_trans tgl_combo_phy_ddi_translations_dp_hbr2[] =
{ 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */ { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
}; };
/*
* Cloned the HOBL entry to comply with the voltage and pre-emphasis entries
* that DisplayPort specification requires
*/
static const struct cnl_ddi_buf_trans tgl_combo_phy_ddi_translations_edp_hbr2_hobl[] = {
/* VS pre-emp */
{ 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 0 0 */
{ 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 0 1 */
{ 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 0 2 */
{ 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 0 3 */
{ 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 1 0 */
{ 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 1 1 */
{ 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 1 2 */
{ 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 2 0 */
{ 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 2 1 */
};
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 * static const struct ddi_buf_trans *
bdw_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries) bdw_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries)
{ {
...@@ -1050,6 +1072,18 @@ static const struct cnl_ddi_buf_trans * ...@@ -1050,6 +1072,18 @@ static const struct cnl_ddi_buf_trans *
tgl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate, tgl_get_combo_buf_trans(struct intel_encoder *encoder, int type, int rate,
int *n_entries) 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_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 (type == INTEL_OUTPUT_HDMI || type == INTEL_OUTPUT_EDP) { if (type == INTEL_OUTPUT_HDMI || type == INTEL_OUTPUT_EDP) {
return icl_get_combo_buf_trans(encoder, type, rate, n_entries); return icl_get_combo_buf_trans(encoder, type, rate, n_entries);
} else if (rate > 270000) { } else if (rate > 270000) {
...@@ -2392,6 +2426,15 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder, ...@@ -2392,6 +2426,15 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
level = n_entries - 1; level = n_entries - 1;
} }
if (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 */ /* Set PORT_TX_DW5 */
val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy)); val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy));
val &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK | val &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK |
......
...@@ -1375,6 +1375,9 @@ struct intel_dp { ...@@ -1375,6 +1375,9 @@ struct intel_dp {
/* Display stream compression testing */ /* Display stream compression testing */
bool force_dsc_en; bool force_dsc_en;
bool hobl_failed;
bool hobl_active;
}; };
enum lspcon_vendor { enum lspcon_vendor {
......
...@@ -410,10 +410,17 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) ...@@ -410,10 +410,17 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
intel_connector->base.base.id, intel_connector->base.base.id,
intel_connector->base.name, intel_connector->base.name,
intel_dp->link_rate, intel_dp->lane_count); intel_dp->link_rate, intel_dp->lane_count);
if (!intel_dp_get_link_train_fallback_values(intel_dp,
intel_dp->link_rate, if (intel_dp->hobl_active) {
intel_dp->lane_count)) drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
/* Schedule a Hotplug Uevent to userspace to start modeset */ "Link Training failed with HOBL active, not enabling it from now on");
schedule_work(&intel_connector->modeset_retry_work); intel_dp->hobl_failed = true;
return; } else if (intel_dp_get_link_train_fallback_values(intel_dp,
intel_dp->link_rate,
intel_dp->lane_count)) {
return;
}
/* Schedule a Hotplug Uevent to userspace to start modeset */
schedule_work(&intel_connector->modeset_retry_work);
} }
...@@ -1898,6 +1898,8 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) ...@@ -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_3_1_0 (0xb << 4)
#define PWR_DOWN_LN_MASK (0xf << 4) #define PWR_DOWN_LN_MASK (0xf << 4)
#define PWR_DOWN_LN_SHIFT 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_PORT_CL_DW12(phy) _MMIO(_ICL_PORT_CL_DW(12, phy))
#define ICL_LANE_ENABLE_AUX (1 << 0) #define ICL_LANE_ENABLE_AUX (1 << 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment