summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display')
-rw-r--r--drivers/gpu/drm/i915/display/icl_dsi.c6
-rw-r--r--drivers/gpu/drm/i915/display/intel_bios.c6
-rw-r--r--drivers/gpu/drm/i915/display/intel_cdclk.c21
-rw-r--r--drivers/gpu/drm/i915/display/intel_cdclk.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_combo_phy.c10
-rw-r--r--drivers/gpu/drm/i915/display/intel_csr.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.c115
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c126
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_debugfs.c10
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.c30
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_types.h6
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c124
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_link_training.c19
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.c60
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbc.c17
-rw-r--r--drivers/gpu/drm/i915/display/intel_frontbuffer.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp.c32
-rw-r--r--drivers/gpu/drm/i915/display/intel_lspcon.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_panel.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.c110
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.h5
-rw-r--r--drivers/gpu/drm/i915/display/intel_sdvo.c12
-rw-r--r--drivers/gpu/drm/i915/display/intel_sprite.c27
-rw-r--r--drivers/gpu/drm/i915/display/intel_tc.c2
25 files changed, 507 insertions, 248 deletions
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 8c55f5bee9ab..f4053dd6bde9 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -712,7 +712,7 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
switch (intel_dsi->pixel_format) {
default:
MISSING_CASE(intel_dsi->pixel_format);
- /* fallthrough */
+ fallthrough;
case MIPI_DSI_FMT_RGB565:
tmp |= PIX_FMT_RGB565;
break;
@@ -739,7 +739,7 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
switch (intel_dsi->video_mode_format) {
default:
MISSING_CASE(intel_dsi->video_mode_format);
- /* fallthrough */
+ fallthrough;
case VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS:
tmp |= VIDEO_MODE_SYNC_EVENT;
break;
@@ -792,7 +792,7 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
switch (pipe) {
default:
MISSING_CASE(pipe);
- /* fallthrough */
+ fallthrough;
case PIPE_A:
tmp |= TRANS_DDI_EDP_INPUT_A_ON;
break;
diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index c53c85d38fa5..a0a41ec5c341 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -905,7 +905,7 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
drm_dbg_kms(&dev_priv->drm,
"VBT tp1 wakeup time value %d is outside range[0-3], defaulting to max value 2500us\n",
psr_table->tp1_wakeup_time);
- /* fallthrough */
+ fallthrough;
case 2:
dev_priv->vbt.psr.tp1_wakeup_time_us = 2500;
break;
@@ -925,7 +925,7 @@ parse_psr(struct drm_i915_private *dev_priv, const struct bdb_header *bdb)
drm_dbg_kms(&dev_priv->drm,
"VBT tp2_tp3 wakeup time value %d is outside range[0-3], defaulting to max value 2500us\n",
psr_table->tp2_tp3_wakeup_time);
- /* fallthrough */
+ fallthrough;
case 2:
dev_priv->vbt.psr.tp2_tp3_wakeup_time_us = 2500;
break;
@@ -1775,7 +1775,7 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv,
switch (child->hdmi_max_data_rate) {
default:
MISSING_CASE(child->hdmi_max_data_rate);
- /* fall through */
+ fallthrough;
case HDMI_MAX_DATA_RATE_PLATFORM:
max_tmds_clock = 0;
break;
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index bb91dace304a..577c4441f32d 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -326,7 +326,7 @@ static void pnv_get_cdclk(struct drm_i915_private *dev_priv,
default:
drm_err(&dev_priv->drm,
"Unknown pnv display core clock 0x%04x\n", gcfgc);
- /* fall through */
+ fallthrough;
case GC_DISPLAY_CLOCK_133_MHZ_PNV:
cdclk_config->cdclk = 133333;
break;
@@ -766,7 +766,7 @@ static void bdw_set_cdclk(struct drm_i915_private *dev_priv,
switch (cdclk) {
default:
MISSING_CASE(cdclk);
- /* fall through */
+ fallthrough;
case 337500:
val |= LCPLL_CLK_FREQ_337_5_BDW;
break;
@@ -1042,7 +1042,7 @@ static void skl_set_cdclk(struct drm_i915_private *dev_priv,
drm_WARN_ON(&dev_priv->drm,
cdclk != dev_priv->cdclk.hw.bypass);
drm_WARN_ON(&dev_priv->drm, vco != 0);
- /* fall through */
+ fallthrough;
case 308571:
case 337500:
freq_select = CDCLK_FREQ_337_308;
@@ -1333,7 +1333,7 @@ static void icl_readout_refclk(struct drm_i915_private *dev_priv,
switch (dssm) {
default:
MISSING_CASE(dssm);
- /* fall through */
+ fallthrough;
case ICL_DSSM_CDCLK_PLL_REFCLK_24MHz:
cdclk_config->ref = 24000;
break;
@@ -1561,7 +1561,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
drm_WARN_ON(&dev_priv->drm,
cdclk != dev_priv->cdclk.hw.bypass);
drm_WARN_ON(&dev_priv->drm, vco != 0);
- /* fall through */
+ fallthrough;
case 2:
divider = BXT_CDCLK_CD2X_DIV_SEL_1;
break;
@@ -2677,7 +2677,7 @@ void intel_update_cdclk(struct drm_i915_private *dev_priv)
*/
if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
intel_de_write(dev_priv, GMBUSFREQ_VLV,
- DIV_ROUND_UP(dev_priv->cdclk.hw.cdclk, 1000));
+ DIV_ROUND_UP(dev_priv->cdclk.hw.cdclk, 1000));
}
static int cnp_rawclk(struct drm_i915_private *dev_priv)
@@ -2903,9 +2903,10 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
dev_priv->display.get_cdclk = i85x_get_cdclk;
else if (IS_I845G(dev_priv))
dev_priv->display.get_cdclk = fixed_200mhz_get_cdclk;
- else { /* 830 */
- drm_WARN(&dev_priv->drm, !IS_I830(dev_priv),
- "Unknown platform. Assuming 133 MHz CDCLK\n");
+ else if (IS_I830(dev_priv))
+ dev_priv->display.get_cdclk = fixed_133mhz_get_cdclk;
+
+ if (drm_WARN(&dev_priv->drm, !dev_priv->display.get_cdclk,
+ "Unknown platform. Assuming 133 MHz CDCLK\n"))
dev_priv->display.get_cdclk = fixed_133mhz_get_cdclk;
- }
}
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h b/drivers/gpu/drm/i915/display/intel_cdclk.h
index 5731806e4cee..6b31fde4be16 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.h
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.h
@@ -17,8 +17,8 @@ struct intel_atomic_state;
struct intel_crtc_state;
struct intel_cdclk_vals {
- u16 refclk;
u32 cdclk;
+ u16 refclk;
u8 divider; /* CD2X divider * 2 */
u8 ratio;
};
diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c b/drivers/gpu/drm/i915/display/intel_combo_phy.c
index eccaa79cb4a9..157d8c8c605a 100644
--- a/drivers/gpu/drm/i915/display/intel_combo_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c
@@ -52,7 +52,7 @@ cnl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum phy phy)
switch (val & (PROCESS_INFO_MASK | VOLTAGE_INFO_MASK)) {
default:
MISSING_CASE(val);
- /* fall through */
+ fallthrough;
case VOLTAGE_INFO_0_85V | PROCESS_INFO_DOT_0:
procmon = &cnl_procmon_values[PROCMON_0_85V_DOT_0];
break;
@@ -258,7 +258,7 @@ static bool phy_is_master(struct drm_i915_private *dev_priv, enum phy phy)
static bool icl_combo_phy_verify_state(struct drm_i915_private *dev_priv,
enum phy phy)
{
- bool ret;
+ bool ret = true;
u32 expected_val = 0;
if (!icl_combo_phy_enabled(dev_priv, phy))
@@ -276,7 +276,7 @@ static bool icl_combo_phy_verify_state(struct drm_i915_private *dev_priv,
DCC_MODE_SELECT_CONTINUOSLY);
}
- ret = cnl_verify_procmon_ref_values(dev_priv, phy);
+ ret &= cnl_verify_procmon_ref_values(dev_priv, phy);
if (phy_is_master(dev_priv, phy)) {
ret &= check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW8(phy),
@@ -320,7 +320,7 @@ void intel_combo_phy_power_up_lanes(struct drm_i915_private *dev_priv,
break;
default:
MISSING_CASE(lane_count);
- /* fall-through */
+ fallthrough;
case 4:
lane_mask = PWR_UP_ALL_LANES;
break;
@@ -337,7 +337,7 @@ void intel_combo_phy_power_up_lanes(struct drm_i915_private *dev_priv,
break;
default:
MISSING_CASE(lane_count);
- /* fall-through */
+ fallthrough;
case 4:
lane_mask = PWR_UP_ALL_LANES;
break;
diff --git a/drivers/gpu/drm/i915/display/intel_csr.c b/drivers/gpu/drm/i915/display/intel_csr.c
index f22a7645c249..d5db16764619 100644
--- a/drivers/gpu/drm/i915/display/intel_csr.c
+++ b/drivers/gpu/drm/i915/display/intel_csr.c
@@ -40,12 +40,12 @@
#define GEN12_CSR_MAX_FW_SIZE ICL_CSR_MAX_FW_SIZE
-#define RKL_CSR_PATH "i915/rkl_dmc_ver2_01.bin"
-#define RKL_CSR_VERSION_REQUIRED CSR_VERSION(2, 1)
+#define RKL_CSR_PATH "i915/rkl_dmc_ver2_02.bin"
+#define RKL_CSR_VERSION_REQUIRED CSR_VERSION(2, 2)
MODULE_FIRMWARE(RKL_CSR_PATH);
-#define TGL_CSR_PATH "i915/tgl_dmc_ver2_06.bin"
-#define TGL_CSR_VERSION_REQUIRED CSR_VERSION(2, 6)
+#define TGL_CSR_PATH "i915/tgl_dmc_ver2_08.bin"
+#define TGL_CSR_VERSION_REQUIRED CSR_VERSION(2, 8)
#define TGL_CSR_MAX_FW_SIZE 0x6000
MODULE_FIRMWARE(TGL_CSR_PATH);
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 2c484b55bcdf..19ac6b2a664c 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -706,6 +706,42 @@ 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_uy_combo_phy_ddi_translations_dp_hbr2[] = {
+ /* NT mV Trans mV db */
+ { 0xA, 0x35, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
+ { 0xA, 0x4F, 0x36, 0x00, 0x09 }, /* 350 500 3.1 */
+ { 0xC, 0x60, 0x32, 0x00, 0x0D }, /* 350 700 6.0 */
+ { 0xC, 0x7F, 0x2D, 0x00, 0x12 }, /* 350 900 8.2 */
+ { 0xC, 0x47, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */
+ { 0xC, 0x6F, 0x36, 0x00, 0x09 }, /* 500 700 2.9 */
+ { 0x6, 0x7D, 0x32, 0x00, 0x0D }, /* 500 900 5.1 */
+ { 0x6, 0x60, 0x3C, 0x00, 0x03 }, /* 650 700 0.6 */
+ { 0x6, 0x7F, 0x34, 0x00, 0x0B }, /* 600 900 3.5 */
+ { 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 *
bdw_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries)
{
@@ -1050,9 +1086,26 @@ 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_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) {
return icl_get_combo_buf_trans(encoder, type, rate, n_entries);
} else 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;
+ }
+
*n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr2);
return tgl_combo_phy_ddi_translations_dp_hbr2;
}
@@ -1888,7 +1941,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
default:
MISSING_CASE(tmp & TRANS_DDI_EDP_INPUT_MASK);
- /* fallthrough */
+ fallthrough;
case TRANS_DDI_EDP_INPUT_A_ON:
case TRANS_DDI_EDP_INPUT_A_ONOFF:
*pipe_mask = BIT(PIPE_A);
@@ -2392,6 +2445,15 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
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 */
val = intel_de_read(dev_priv, ICL_PORT_TX_DW5_LN0(phy));
val &= ~(SCALING_MODE_SEL_MASK | RTERM_SELECT_MASK |
@@ -2802,7 +2864,9 @@ hsw_set_signal_levels(struct intel_dp *intel_dp)
static u32 icl_dpclka_cfgcr0_clk_off(struct drm_i915_private *dev_priv,
enum phy phy)
{
- if (intel_phy_is_combo(dev_priv, phy)) {
+ if (IS_ROCKETLAKE(dev_priv)) {
+ return RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
+ } else if (intel_phy_is_combo(dev_priv, phy)) {
return ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy);
} else if (intel_phy_is_tc(dev_priv, phy)) {
enum tc_port tc_port = intel_port_to_tc(dev_priv,
@@ -2829,6 +2893,16 @@ static void icl_map_plls_to_ports(struct intel_encoder *encoder,
(val & icl_dpclka_cfgcr0_clk_off(dev_priv, phy)) == 0);
if (intel_phy_is_combo(dev_priv, phy)) {
+ u32 mask, sel;
+
+ if (IS_ROCKETLAKE(dev_priv)) {
+ mask = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
+ sel = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy);
+ } else {
+ mask = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
+ sel = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy);
+ }
+
/*
* Even though this register references DDIs, note that we
* want to pass the PHY rather than the port (DDI). For
@@ -2839,8 +2913,8 @@ static void icl_map_plls_to_ports(struct intel_encoder *encoder,
* Clock Select chooses the PLL for both DDIA and DDID and
* drives port A in all cases."
*/
- val &= ~ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
- val |= ICL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy);
+ val &= ~mask;
+ val |= sel;
intel_de_write(dev_priv, ICL_DPCLKA_CFGCR0, val);
intel_de_posting_read(dev_priv, ICL_DPCLKA_CFGCR0);
}
@@ -4037,8 +4111,7 @@ static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp)
intel_wait_ddi_buf_idle(dev_priv, port);
}
- dp_tp_ctl = DP_TP_CTL_ENABLE |
- DP_TP_CTL_LINK_TRAIN_PAT1 | DP_TP_CTL_SCRAMBLE_DISABLE;
+ dp_tp_ctl = DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_PAT1;
if (intel_dp->link_mst)
dp_tp_ctl |= DP_TP_CTL_MODE_MST;
else {
@@ -4061,16 +4134,10 @@ static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
u8 train_pat_mask = drm_dp_training_pattern_mask(intel_dp->dpcd);
- enum port port = dp_to_dig_port(intel_dp)->base.port;
u32 temp;
temp = intel_de_read(dev_priv, intel_dp->regs.dp_tp_ctl);
- if (dp_train_pat & DP_LINK_SCRAMBLING_DISABLE)
- temp |= DP_TP_CTL_SCRAMBLE_DISABLE;
- else
- temp &= ~DP_TP_CTL_SCRAMBLE_DISABLE;
-
temp &= ~DP_TP_CTL_LINK_TRAIN_MASK;
switch (dp_train_pat & train_pat_mask) {
case DP_TRAINING_PATTERN_DISABLE:
@@ -4091,9 +4158,6 @@ static void intel_ddi_set_link_train(struct intel_dp *intel_dp,
}
intel_de_write(dev_priv, intel_dp->regs.dp_tp_ctl, temp);
-
- intel_de_write(dev_priv, DDI_BUF_CTL(port), intel_dp->DP);
- intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
}
static void intel_ddi_set_idle_link_train(struct intel_dp *intel_dp)
@@ -4268,7 +4332,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
pipe_config->hdmi_scrambling = true;
if (temp & TRANS_DDI_HIGH_TMDS_CHAR_RATE)
pipe_config->hdmi_high_tmds_clock_ratio = true;
- /* fall through */
+ fallthrough;
case TRANS_DDI_MODE_SELECT_DVI:
pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI);
pipe_config->lane_count = 4;
@@ -4878,6 +4942,13 @@ intel_ddi_max_lanes(struct intel_digital_port *dig_port)
return max_lanes;
}
+static bool hti_uses_phy(struct drm_i915_private *i915, enum phy phy)
+{
+ return i915->hti_state & HDPORT_ENABLED &&
+ (i915->hti_state & HDPORT_PHY_USED_DP(phy) ||
+ i915->hti_state & HDPORT_PHY_USED_HDMI(phy));
+}
+
void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
{
struct intel_digital_port *dig_port;
@@ -4885,6 +4956,18 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
bool init_hdmi, init_dp, init_lspcon = false;
enum phy phy = intel_port_to_phy(dev_priv, port);
+ /*
+ * On platforms with HTI (aka HDPORT), if it's enabled at boot it may
+ * have taken over some of the PHYs and made them unavailable to the
+ * driver. In that case we should skip initializing the corresponding
+ * outputs.
+ */
+ if (hti_uses_phy(dev_priv, phy)) {
+ drm_dbg_kms(&dev_priv->drm, "PORT %c / PHY %c reserved by HTI\n",
+ port_name(port), phy_name(phy));
+ return;
+ }
+
init_hdmi = intel_bios_port_supports_dvi(dev_priv, port) ||
intel_bios_port_supports_hdmi(dev_priv, port);
init_dp = intel_bios_port_supports_dp(dev_priv, port);
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 729ec6e0d43a..ddb588f863f8 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -47,6 +47,7 @@
#include "display/intel_ddi.h"
#include "display/intel_dp.h"
#include "display/intel_dp_mst.h"
+#include "display/intel_dpll_mgr.h"
#include "display/intel_dsi.h"
#include "display/intel_dvo.h"
#include "display/intel_gmbus.h"
@@ -2029,12 +2030,12 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)
case I915_FORMAT_MOD_Y_TILED_CCS:
if (is_ccs_plane(fb, color_plane))
return 128;
- /* fall through */
+ fallthrough;
case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
if (is_ccs_plane(fb, color_plane))
return 64;
- /* fall through */
+ fallthrough;
case I915_FORMAT_MOD_Y_TILED:
if (IS_GEN(dev_priv, 2) || HAS_128_BYTE_Y_TILING(dev_priv))
return 128;
@@ -2043,7 +2044,7 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)
case I915_FORMAT_MOD_Yf_TILED_CCS:
if (is_ccs_plane(fb, color_plane))
return 128;
- /* fall through */
+ fallthrough;
case I915_FORMAT_MOD_Yf_TILED:
switch (cpp) {
case 1:
@@ -2185,7 +2186,7 @@ static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
if (is_semiplanar_uv_plane(fb, color_plane))
return intel_tile_row_size(fb, color_plane);
- /* Fall-through */
+ fallthrough;
case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
return 16 * 1024;
case I915_FORMAT_MOD_Y_TILED_CCS:
@@ -2194,7 +2195,7 @@ static unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
if (INTEL_GEN(dev_priv) >= 12 &&
is_semiplanar_uv_plane(fb, color_plane))
return intel_tile_row_size(fb, color_plane);
- /* Fall-through */
+ fallthrough;
case I915_FORMAT_MOD_Yf_TILED:
return 1 * 1024 * 1024;
default:
@@ -2310,7 +2311,7 @@ err:
void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags)
{
- i915_gem_object_lock(vma->obj);
+ i915_gem_object_lock(vma->obj, NULL);
if (flags & PLANE_HAS_FENCE)
i915_vma_unpin_fence(vma);
i915_gem_object_unpin_from_display_plane(vma);
@@ -3450,7 +3451,7 @@ initial_plane_vma(struct drm_i915_private *i915,
if (IS_ERR(vma))
goto err_obj;
- if (i915_ggtt_pin(vma, 0, PIN_MAPPABLE | PIN_OFFSET_FIXED | base))
+ if (i915_ggtt_pin(vma, NULL, 0, PIN_MAPPABLE | PIN_OFFSET_FIXED | base))
goto err_obj;
if (i915_gem_object_is_tiled(obj) &&
@@ -3761,6 +3762,44 @@ static int glk_max_plane_width(const struct drm_framebuffer *fb,
}
}
+static int icl_min_plane_width(const struct drm_framebuffer *fb)
+{
+ /* Wa_14011264657, Wa_14011050563: gen11+ */
+ switch (fb->format->format) {
+ case DRM_FORMAT_C8:
+ return 18;
+ case DRM_FORMAT_RGB565:
+ return 10;
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_ARGB8888:
+ case DRM_FORMAT_ABGR8888:
+ case DRM_FORMAT_XRGB2101010:
+ case DRM_FORMAT_XBGR2101010:
+ case DRM_FORMAT_ARGB2101010:
+ case DRM_FORMAT_ABGR2101010:
+ case DRM_FORMAT_XVYU2101010:
+ case DRM_FORMAT_Y212:
+ case DRM_FORMAT_Y216:
+ return 6;
+ case DRM_FORMAT_NV12:
+ return 20;
+ case DRM_FORMAT_P010:
+ case DRM_FORMAT_P012:
+ case DRM_FORMAT_P016:
+ return 12;
+ case DRM_FORMAT_XRGB16161616F:
+ case DRM_FORMAT_XBGR16161616F:
+ case DRM_FORMAT_ARGB16161616F:
+ case DRM_FORMAT_ABGR16161616F:
+ case DRM_FORMAT_XVYU12_16161616:
+ case DRM_FORMAT_XVYU16161616:
+ return 4;
+ default:
+ return 1;
+ }
+}
+
static int icl_max_plane_width(const struct drm_framebuffer *fb,
int color_plane,
unsigned int rotation)
@@ -3843,29 +3882,31 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
int y = plane_state->uapi.src.y1 >> 16;
int w = drm_rect_width(&plane_state->uapi.src) >> 16;
int h = drm_rect_height(&plane_state->uapi.src) >> 16;
- int max_width;
- int max_height;
- u32 alignment;
- u32 offset;
+ int max_width, min_width, max_height;
+ u32 alignment, offset;
int aux_plane = intel_main_to_aux_plane(fb, 0);
u32 aux_offset = plane_state->color_plane[aux_plane].offset;
- if (INTEL_GEN(dev_priv) >= 11)
+ if (INTEL_GEN(dev_priv) >= 11) {
max_width = icl_max_plane_width(fb, 0, rotation);
- else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
+ min_width = icl_min_plane_width(fb);
+ } else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
max_width = glk_max_plane_width(fb, 0, rotation);
- else
+ min_width = 1;
+ } else {
max_width = skl_max_plane_width(fb, 0, rotation);
+ min_width = 1;
+ }
if (INTEL_GEN(dev_priv) >= 11)
max_height = icl_max_plane_height();
else
max_height = skl_max_plane_height();
- if (w > max_width || h > max_height) {
+ if (w > max_width || w < min_width || h > max_height) {
drm_dbg_kms(&dev_priv->drm,
- "requested Y/RGB source size %dx%d too big (limit %dx%d)\n",
- w, h, max_width, max_height);
+ "requested Y/RGB source size %dx%d outside limits (min: %dx1 max: %dx%d)\n",
+ w, h, min_width, max_width, max_height);
return -EINVAL;
}
@@ -6211,7 +6252,7 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
case DRM_FORMAT_ARGB16161616F:
if (INTEL_GEN(dev_priv) >= 11)
break;
- /* fall through */
+ fallthrough;
default:
drm_dbg_kms(&dev_priv->drm,
"[PLANE:%d:%s] FB:%d unsupported scaling format 0x%x\n",
@@ -10802,9 +10843,18 @@ static void icl_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port,
u32 temp;
if (intel_phy_is_combo(dev_priv, phy)) {
- temp = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0) &
- ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
- id = temp >> ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy);
+ u32 mask, shift;
+
+ if (IS_ROCKETLAKE(dev_priv)) {
+ mask = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
+ shift = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy);
+ } else {
+ mask = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
+ shift = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy);
+ }
+
+ temp = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0) & mask;
+ id = temp >> shift;
port_dpll_id = ICL_PORT_DPLL_DEFAULT;
} else if (intel_phy_is_tc(dev_priv, phy)) {
u32 clk_sel = intel_de_read(dev_priv, DDI_CLK_SEL(port)) & DDI_CLK_SEL_MASK;
@@ -10896,7 +10946,7 @@ static void hsw_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port,
break;
default:
MISSING_CASE(ddi_pll_sel);
- /* fall through */
+ fallthrough;
case PORT_CLK_SEL_NONE:
return;
}
@@ -10956,10 +11006,10 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
drm_WARN(dev, 1,
"unknown pipe linked to transcoder %s\n",
transcoder_name(panel_transcoder));
- /* fall through */
+ fallthrough;
case TRANS_DDI_EDP_INPUT_A_ONOFF:
force_thru = true;
- /* fall through */
+ fallthrough;
case TRANS_DDI_EDP_INPUT_A_ON:
trans_pipe = PIPE_A;
break;
@@ -12760,6 +12810,9 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
}
+ if (!mode_changed)
+ intel_psr2_sel_fetch_update(state, crtc);
+
return 0;
}
@@ -13183,7 +13236,7 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state)
case INTEL_OUTPUT_DDI:
if (drm_WARN_ON(dev, !HAS_DDI(to_i915(dev))))
break;
- /* else, fall through */
+ fallthrough;
case INTEL_OUTPUT_DP:
case INTEL_OUTPUT_HDMI:
case INTEL_OUTPUT_EDP:
@@ -14930,7 +14983,7 @@ static int intel_atomic_check(struct drm_device *dev,
if (any_ms && !check_digital_port_conflicts(state)) {
drm_dbg_kms(&dev_priv->drm,
"rejecting conflicting digital port configuration\n");
- ret = EINVAL;
+ ret = -EINVAL;
goto fail;
}
@@ -14956,12 +15009,6 @@ static int intel_atomic_check(struct drm_device *dev,
if (dev_priv->wm.distrust_bios_wm)
any_ms = true;
- if (any_ms) {
- ret = intel_modeset_checks(state);
- if (ret)
- goto fail;
- }
-
intel_fbc_choose_crtc(dev_priv, state);
ret = calc_watermark_data(state);
if (ret)
@@ -14976,6 +15023,10 @@ static int intel_atomic_check(struct drm_device *dev,
goto fail;
if (any_ms) {
+ ret = intel_modeset_checks(state);
+ if (ret)
+ goto fail;
+
ret = intel_modeset_calc_cdclk(state);
if (ret)
return ret;
@@ -15136,6 +15187,8 @@ static void commit_pipe_config(struct intel_atomic_state *state,
if (new_crtc_state->update_pipe)
intel_pipe_fastset(old_crtc_state, new_crtc_state);
+
+ intel_psr2_program_trans_man_trk_ctl(new_crtc_state);
}
if (dev_priv->display.atomic_update_watermarks)
@@ -17139,7 +17192,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
if (!intel_fb->frontbuffer)
return -ENOMEM;
- i915_gem_object_lock(obj);
+ i915_gem_object_lock(obj, NULL);
tiling = i915_gem_object_get_tiling(obj);
stride = i915_gem_object_get_stride(obj);
i915_gem_object_unlock(obj);
@@ -17894,6 +17947,13 @@ int intel_modeset_init(struct drm_i915_private *i915)
if (i915->max_cdclk_freq == 0)
intel_update_max_cdclk(i915);
+ /*
+ * If the platform has HTI, we need to find out whether it has reserved
+ * any display resources before we create our display outputs.
+ */
+ if (INTEL_INFO(i915)->display.has_hti)
+ i915->hti_state = intel_de_read(i915, HDPORT_STATE);
+
/* Just disable it once at startup */
intel_vga_disable(i915);
intel_setup_outputs(i915);
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 3644752cc5ec..f549381048b3 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -417,6 +417,9 @@ static int i915_edp_psr_status(struct seq_file *m, void *data)
su_blocks = su_blocks >> PSR2_SU_STATUS_SHIFT(frame);
seq_printf(m, "%d\t%d\n", frame, su_blocks);
}
+
+ seq_printf(m, "PSR2 selective fetch: %s\n",
+ enableddisabled(psr->psr2_sel_fetch_enabled));
}
unlock:
@@ -2044,9 +2047,12 @@ DEFINE_SHOW_ATTRIBUTE(i915_hdcp_sink_capability);
static int i915_lpsp_capability_show(struct seq_file *m, void *data)
{
struct drm_connector *connector = m->private;
- struct intel_encoder *encoder =
- intel_attached_encoder(to_intel_connector(connector));
struct drm_i915_private *i915 = to_i915(connector->dev);
+ struct intel_encoder *encoder;
+
+ encoder = intel_attached_encoder(to_intel_connector(connector));
+ if (!encoder)
+ return -ENODEV;
if (connector->status != connector_status_connected)
return -ENODEV;
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index 0c713e83274d..7946c6af4b1e 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -3927,12 +3927,13 @@ tgl_tc_cold_request(struct drm_i915_private *i915, bool block)
int ret;
while (1) {
- u32 low_val = 0, high_val;
+ u32 low_val;
+ u32 high_val = 0;
if (block)
- high_val = TGL_PCODE_EXIT_TCCOLD_DATA_H_BLOCK_REQ;
+ low_val = TGL_PCODE_EXIT_TCCOLD_DATA_L_BLOCK_REQ;
else
- high_val = TGL_PCODE_EXIT_TCCOLD_DATA_H_UNBLOCK_REQ;
+ low_val = TGL_PCODE_EXIT_TCCOLD_DATA_L_UNBLOCK_REQ;
/*
* Spec states that we should timeout the request after 200us
@@ -3951,8 +3952,7 @@ tgl_tc_cold_request(struct drm_i915_private *i915, bool block)
if (++tries == 3)
break;
- if (ret == -EAGAIN)
- msleep(1);
+ msleep(1);
}
if (ret)
@@ -4147,6 +4147,12 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
},
},
{
+ .name = "TC cold off",
+ .domains = TGL_TC_COLD_OFF_POWER_DOMAINS,
+ .ops = &tgl_tc_cold_off_ops,
+ .id = DISP_PW_ID_NONE,
+ },
+ {
.name = "AUX A",
.domains = TGL_AUX_A_IO_POWER_DOMAINS,
.ops = &icl_aux_power_well_ops,
@@ -4332,12 +4338,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
.hsw.irq_pipe_mask = BIT(PIPE_D),
},
},
- {
- .name = "TC cold off",
- .domains = TGL_TC_COLD_OFF_POWER_DOMAINS,
- .ops = &tgl_tc_cold_off_ops,
- .id = DISP_PW_ID_NONE,
- },
};
static const struct i915_power_well_desc rkl_power_wells[] = {
@@ -5240,10 +5240,10 @@ struct buddy_page_mask {
};
static const struct buddy_page_mask tgl_buddy_page_masks[] = {
- { .num_channels = 1, .type = INTEL_DRAM_LPDDR4, .page_mask = 0xE },
{ .num_channels = 1, .type = INTEL_DRAM_DDR4, .page_mask = 0xF },
{ .num_channels = 2, .type = INTEL_DRAM_LPDDR4, .page_mask = 0x1C },
{ .num_channels = 2, .type = INTEL_DRAM_DDR4, .page_mask = 0x1F },
+ { .num_channels = 4, .type = INTEL_DRAM_LPDDR4, .page_mask = 0x38 },
{}
};
@@ -5302,6 +5302,12 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
+ /* Wa_14011294188:ehl,jsl,tgl,rkl */
+ if (INTEL_PCH_TYPE(dev_priv) >= PCH_JSP &&
+ INTEL_PCH_TYPE(dev_priv) < PCH_DG1)
+ intel_de_rmw(dev_priv, SOUTH_DSPCLK_GATE_D, 0,
+ PCH_DPMGUNIT_CLOCK_GATE_DISABLE);
+
/* 1. Enable PCH reset handshake. */
intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv));
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index e8f809161c75..9349b15afff6 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -931,6 +931,7 @@ struct intel_crtc_state {
bool has_psr;
bool has_psr2;
+ bool enable_psr2_sel_fetch;
u32 dc3co_exitline;
/*
@@ -1073,6 +1074,8 @@ struct intel_crtc_state {
/* For DSB related info */
struct intel_dsb *dsb;
+
+ u32 psr2_man_track_ctl;
};
enum intel_pipe_crc_source {
@@ -1375,6 +1378,9 @@ struct intel_dp {
/* Display stream compression testing */
bool force_dsc_en;
+
+ bool hobl_failed;
+ bool hobl_active;
};
enum lspcon_vendor {
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 79c27f91f42c..284b15f84592 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -4449,62 +4449,6 @@ intel_dp_link_down(struct intel_encoder *encoder,
}
}
-static void
-intel_dp_extended_receiver_capabilities(struct intel_dp *intel_dp)
-{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- u8 dpcd_ext[6];
-
- /*
- * Prior to DP1.3 the bit represented by
- * DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT was reserved.
- * if it is set DP_DPCD_REV at 0000h could be at a value less than
- * the true capability of the panel. The only way to check is to
- * then compare 0000h and 2200h.
- */
- if (!(intel_dp->dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
- DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT))
- return;
-
- if (drm_dp_dpcd_read(&intel_dp->aux, DP_DP13_DPCD_REV,
- &dpcd_ext, sizeof(dpcd_ext)) != sizeof(dpcd_ext)) {
- drm_err(&i915->drm,
- "DPCD failed read at extended capabilities\n");
- return;
- }
-
- if (intel_dp->dpcd[DP_DPCD_REV] > dpcd_ext[DP_DPCD_REV]) {
- drm_dbg_kms(&i915->drm,
- "DPCD extended DPCD rev less than base DPCD rev\n");
- return;
- }
-
- if (!memcmp(intel_dp->dpcd, dpcd_ext, sizeof(dpcd_ext)))
- return;
-
- drm_dbg_kms(&i915->drm, "Base DPCD: %*ph\n",
- (int)sizeof(intel_dp->dpcd), intel_dp->dpcd);
-
- memcpy(intel_dp->dpcd, dpcd_ext, sizeof(dpcd_ext));
-}
-
-bool
-intel_dp_read_dpcd(struct intel_dp *intel_dp)
-{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
-
- if (drm_dp_dpcd_read(&intel_dp->aux, 0x000, intel_dp->dpcd,
- sizeof(intel_dp->dpcd)) < 0)
- return false; /* aux transfer failed */
-
- intel_dp_extended_receiver_capabilities(intel_dp);
-
- drm_dbg_kms(&i915->drm, "DPCD: %*ph\n", (int)sizeof(intel_dp->dpcd),
- intel_dp->dpcd);
-
- return intel_dp->dpcd[DP_DPCD_REV] != 0;
-}
-
bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp)
{
u8 dprx = 0;
@@ -4563,7 +4507,7 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp)
/* this function is meant to be called only once */
drm_WARN_ON(&dev_priv->drm, intel_dp->dpcd[DP_DPCD_REV] != 0);
- if (!intel_dp_read_dpcd(intel_dp))
+ if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd) != 0)
return false;
drm_dp_read_desc(&intel_dp->aux, &intel_dp->desc,
@@ -4634,11 +4578,23 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp)
return true;
}
+static bool
+intel_dp_has_sink_count(struct intel_dp *intel_dp)
+{
+ if (!intel_dp->attached_connector)
+ return false;
+
+ return drm_dp_read_sink_count_cap(&intel_dp->attached_connector->base,
+ intel_dp->dpcd,
+ &intel_dp->desc);
+}
static bool
intel_dp_get_dpcd(struct intel_dp *intel_dp)
{
- if (!intel_dp_read_dpcd(intel_dp))
+ int ret;
+
+ if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd))
return false;
/*
@@ -4653,18 +4609,9 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
intel_dp_set_common_rates(intel_dp);
}
- /*
- * Some eDP panels do not set a valid value for sink count, that is why
- * it don't care about read it here and in intel_edp_init_dpcd().
- */
- if (!intel_dp_is_edp(intel_dp) &&
- !drm_dp_has_quirk(&intel_dp->desc, 0,
- DP_DPCD_QUIRK_NO_SINK_COUNT)) {
- u8 count;
- ssize_t r;
-
- r = drm_dp_dpcd_readb(&intel_dp->aux, DP_SINK_COUNT, &count);
- if (r < 1)
+ if (intel_dp_has_sink_count(intel_dp)) {
+ ret = drm_dp_read_sink_count(&intel_dp->aux);
+ if (ret < 0)
return false;
/*
@@ -4672,7 +4619,7 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
* a member variable in intel_dp will track any changes
* between short pulse interrupts.
*/
- intel_dp->sink_count = DP_GET_SINK_COUNT(count);
+ intel_dp->sink_count = ret;
/*
* SINK_COUNT == 0 and DOWNSTREAM_PORT_PRESENT == 1 implies that
@@ -4685,32 +4632,8 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
return false;
}
- if (!drm_dp_is_branch(intel_dp->dpcd))
- return true; /* native DP sink */
-
- if (intel_dp->dpcd[DP_DPCD_REV] == 0x10)
- return true; /* no per-port downstream info */
-
- if (drm_dp_dpcd_read(&intel_dp->aux, DP_DOWNSTREAM_PORT_0,
- intel_dp->downstream_ports,
- DP_MAX_DOWNSTREAM_PORTS) < 0)
- return false; /* downstream port status fetch failed */
-
- return true;
-}
-
-static bool
-intel_dp_sink_can_mst(struct intel_dp *intel_dp)
-{
- u8 mstm_cap;
-
- if (intel_dp->dpcd[DP_DPCD_REV] < 0x12)
- return false;
-
- if (drm_dp_dpcd_readb(&intel_dp->aux, DP_MSTM_CAP, &mstm_cap) != 1)
- return false;
-
- return mstm_cap & DP_MST_CAP;
+ return drm_dp_read_downstream_info(&intel_dp->aux, intel_dp->dpcd,
+ intel_dp->downstream_ports) == 0;
}
static bool
@@ -4720,7 +4643,7 @@ intel_dp_can_mst(struct intel_dp *intel_dp)
return i915->params.enable_dp_mst &&
intel_dp->can_mst &&
- intel_dp_sink_can_mst(intel_dp);
+ drm_dp_read_mst_cap(&intel_dp->aux, intel_dp->dpcd);
}
static void
@@ -4729,7 +4652,7 @@ intel_dp_configure_mst(struct intel_dp *intel_dp)
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct intel_encoder *encoder =
&dp_to_dig_port(intel_dp)->base;
- bool sink_can_mst = intel_dp_sink_can_mst(intel_dp);
+ bool sink_can_mst = drm_dp_read_mst_cap(&intel_dp->aux, intel_dp->dpcd);
drm_dbg_kms(&i915->drm,
"[ENCODER:%d:%s] MST support: port: %s, sink: %s, modparam: %s\n",
@@ -5963,9 +5886,8 @@ intel_dp_detect_dpcd(struct intel_dp *intel_dp)
return connector_status_connected;
/* If we're HPD-aware, SINK_COUNT changes dynamically */
- if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
+ if (intel_dp_has_sink_count(intel_dp) &&
intel_dp->downstream_ports[0] & DP_DS_PORT_HPD) {
-
return intel_dp->sink_count ?
connector_status_connected : connector_status_disconnected;
}
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index b901ab850cbd..0a3af3410d52 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -99,7 +99,6 @@ bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
bool
intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
-bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
int intel_dp_link_required(int pixel_clock, int bpp);
int intel_dp_max_data_rate(int max_link_clock, int max_lanes);
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 a23ed7290843..f2c8b56be9ea 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -410,10 +410,17 @@ 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_get_link_train_fallback_values(intel_dp,
- intel_dp->link_rate,
- intel_dp->lane_count))
- /* Schedule a Hotplug Uevent to userspace to start modeset */
- schedule_work(&intel_connector->modeset_retry_work);
- return;
+
+ if (intel_dp->hobl_active) {
+ drm_dbg_kms(&dp_to_i915(intel_dp)->drm,
+ "Link Training failed with HOBL active, not enabling it from now on");
+ intel_dp->hobl_failed = true;
+ } 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);
}
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index aeb6ee395cce..c9013f8f766f 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -892,7 +892,7 @@ static int hsw_ddi_wrpll_get_freq(struct drm_i915_private *dev_priv,
refclk = dev_priv->dpll.ref_clks.nssc;
break;
}
- /* fall through */
+ fallthrough;
case WRPLL_REF_PCH_SSC:
/*
* We could calculate spread here, but our checking
@@ -2977,7 +2977,7 @@ static bool icl_calc_tbt_pll(struct intel_crtc_state *crtc_state,
switch (dev_priv->dpll.ref_clks.nssc) {
default:
MISSING_CASE(dev_priv->dpll.ref_clks.nssc);
- /* fall-through */
+ fallthrough;
case 19200:
*pll_params = tgl_tbt_pll_19_2MHz_values;
break;
@@ -2992,7 +2992,7 @@ static bool icl_calc_tbt_pll(struct intel_crtc_state *crtc_state,
switch (dev_priv->dpll.ref_clks.nssc) {
default:
MISSING_CASE(dev_priv->dpll.ref_clks.nssc);
- /* fall-through */
+ fallthrough;
case 19200:
case 38400:
*pll_params = icl_tbt_pll_19_2MHz_values;
@@ -3120,7 +3120,7 @@ static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
switch (div1) {
default:
MISSING_CASE(div1);
- /* fall through */
+ fallthrough;
case 2:
hsdiv = MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_2;
break;
@@ -3475,6 +3475,14 @@ static void icl_update_active_dpll(struct intel_atomic_state *state,
icl_set_active_port_dpll(crtc_state, port_dpll_id);
}
+static u32 intel_get_hti_plls(struct drm_i915_private *i915)
+{
+ if (!(i915->hti_state & HDPORT_ENABLED))
+ return 0;
+
+ return REG_FIELD_GET(HDPORT_DPLL_USED_MASK, i915->hti_state);
+}
+
static bool icl_get_combo_phy_dpll(struct intel_atomic_state *state,
struct intel_crtc *crtc,
struct intel_encoder *encoder)
@@ -3504,13 +3512,22 @@ static bool icl_get_combo_phy_dpll(struct intel_atomic_state *state,
icl_calc_dpll_state(dev_priv, &pll_params, &port_dpll->hw_state);
- if (IS_ELKHARTLAKE(dev_priv) && port != PORT_A)
+ if (IS_ROCKETLAKE(dev_priv)) {
dpll_mask =
BIT(DPLL_ID_EHL_DPLL4) |
BIT(DPLL_ID_ICL_DPLL1) |
BIT(DPLL_ID_ICL_DPLL0);
- else
+ } else if (IS_ELKHARTLAKE(dev_priv) && port != PORT_A) {
+ dpll_mask =
+ BIT(DPLL_ID_EHL_DPLL4) |
+ BIT(DPLL_ID_ICL_DPLL1) |
+ BIT(DPLL_ID_ICL_DPLL0);
+ } else {
dpll_mask = BIT(DPLL_ID_ICL_DPLL1) | BIT(DPLL_ID_ICL_DPLL0);
+ }
+
+ /* Eliminate DPLLs from consideration if reserved by HTI */
+ dpll_mask &= ~intel_get_hti_plls(dev_priv);
port_dpll->pll = intel_find_shared_dpll(state, crtc,
&port_dpll->hw_state,
@@ -3791,7 +3808,12 @@ static bool icl_pll_get_hw_state(struct drm_i915_private *dev_priv,
if (!(val & PLL_ENABLE))
goto out;
- if (INTEL_GEN(dev_priv) >= 12) {
+ if (IS_ROCKETLAKE(dev_priv)) {
+ hw_state->cfgcr0 = intel_de_read(dev_priv,
+ RKL_DPLL_CFGCR0(id));
+ hw_state->cfgcr1 = intel_de_read(dev_priv,
+ RKL_DPLL_CFGCR1(id));
+ } else if (INTEL_GEN(dev_priv) >= 12) {
hw_state->cfgcr0 = intel_de_read(dev_priv,
TGL_DPLL_CFGCR0(id));
hw_state->cfgcr1 = intel_de_read(dev_priv,
@@ -3844,7 +3866,10 @@ static void icl_dpll_write(struct drm_i915_private *dev_priv,
const enum intel_dpll_id id = pll->info->id;
i915_reg_t cfgcr0_reg, cfgcr1_reg;
- if (INTEL_GEN(dev_priv) >= 12) {
+ if (IS_ROCKETLAKE(dev_priv)) {
+ cfgcr0_reg = RKL_DPLL_CFGCR0(id);
+ cfgcr1_reg = RKL_DPLL_CFGCR1(id);
+ } else if (INTEL_GEN(dev_priv) >= 12) {
cfgcr0_reg = TGL_DPLL_CFGCR0(id);
cfgcr1_reg = TGL_DPLL_CFGCR1(id);
} else {
@@ -4276,6 +4301,21 @@ static const struct intel_dpll_mgr tgl_pll_mgr = {
.dump_hw_state = icl_dump_hw_state,
};
+static const struct dpll_info rkl_plls[] = {
+ { "DPLL 0", &combo_pll_funcs, DPLL_ID_ICL_DPLL0, 0 },
+ { "DPLL 1", &combo_pll_funcs, DPLL_ID_ICL_DPLL1, 0 },
+ { "DPLL 4", &combo_pll_funcs, DPLL_ID_EHL_DPLL4, 0 },
+ { },
+};
+
+static const struct intel_dpll_mgr rkl_pll_mgr = {
+ .dpll_info = rkl_plls,
+ .get_dplls = icl_get_dplls,
+ .put_dplls = icl_put_dplls,
+ .update_ref_clks = icl_update_dpll_ref_clks,
+ .dump_hw_state = icl_dump_hw_state,
+};
+
/**
* intel_shared_dpll_init - Initialize shared DPLLs
* @dev: drm device
@@ -4289,7 +4329,9 @@ void intel_shared_dpll_init(struct drm_device *dev)
const struct dpll_info *dpll_info;
int i;
- if (INTEL_GEN(dev_priv) >= 12)
+ if (IS_ROCKETLAKE(dev_priv))
+ dpll_mgr = &rkl_pll_mgr;
+ else if (INTEL_GEN(dev_priv) >= 12)
dpll_mgr = &tgl_pll_mgr;
else if (IS_ELKHARTLAKE(dev_priv))
dpll_mgr = &ehl_pll_mgr;
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index 24c3a0f212c6..135f5e8a4d70 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -424,6 +424,14 @@ static void intel_fbc_deactivate(struct drm_i915_private *dev_priv,
fbc->no_fbc_reason = reason;
}
+static u64 intel_fbc_cfb_base_max(struct drm_i915_private *i915)
+{
+ if (INTEL_GEN(i915) >= 5 || IS_G4X(i915))
+ return BIT_ULL(28);
+ else
+ return BIT_ULL(32);
+}
+
static int find_compression_threshold(struct drm_i915_private *dev_priv,
struct drm_mm_node *node,
unsigned int size,
@@ -442,6 +450,8 @@ static int find_compression_threshold(struct drm_i915_private *dev_priv,
else
end = U64_MAX;
+ end = min(end, intel_fbc_cfb_base_max(dev_priv));
+
/* HACK: This code depends on what we will do in *_enable_fbc. If that
* code changes, this code needs to change as well.
*
@@ -1416,6 +1426,13 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv)
if (!HAS_FBC(dev_priv))
return 0;
+ /*
+ * Fbc is causing random underruns in CI execution on TGL platforms.
+ * Disabling the same while the problem is being debugged and analyzed.
+ */
+ if (IS_TIGERLAKE(dev_priv))
+ return 0;
+
if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9)
return 1;
diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
index 2979ed2588eb..d898b370d7a4 100644
--- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c
+++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c
@@ -232,6 +232,8 @@ static void frontbuffer_release(struct kref *ref)
RCU_INIT_POINTER(obj->frontbuffer, NULL);
spin_unlock(&to_i915(obj->base.dev)->fb_tracking.lock);
+ i915_active_fini(&front->write);
+
i915_gem_object_put(obj);
kfree_rcu(front, rcu);
}
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index 89a4d294822d..1a0d49af2a08 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -336,8 +336,10 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
/* Fill up the empty slots in sha_text and write it out */
sha_empty = sizeof(sha_text) - sha_leftovers;
- for (j = 0; j < sha_empty; j++)
- sha_text |= ksv[j] << ((sizeof(sha_text) - j - 1) * 8);
+ for (j = 0; j < sha_empty; j++) {
+ u8 off = ((sizeof(sha_text) - j - 1 - sha_leftovers) * 8);
+ sha_text |= ksv[j] << off;
+ }
ret = intel_write_sha_text(dev_priv, sha_text);
if (ret < 0)
@@ -435,7 +437,7 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
/* Write 32 bits of text */
intel_de_write(dev_priv, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_32);
- sha_text |= bstatus[0] << 24 | bstatus[1] << 16;
+ sha_text |= bstatus[0] << 8 | bstatus[1];
ret = intel_write_sha_text(dev_priv, sha_text);
if (ret < 0)
return ret;
@@ -450,17 +452,29 @@ int intel_hdcp_validate_v_prime(struct intel_connector *connector,
return ret;
sha_idx += sizeof(sha_text);
}
+
+ /*
+ * Terminate the SHA-1 stream by hand. For the other leftover
+ * cases this is appended by the hardware.
+ */
+ intel_de_write(dev_priv, HDCP_REP_CTL,
+ rep_ctl | HDCP_SHA1_TEXT_32);
+ sha_text = DRM_HDCP_SHA1_TERMINATOR << 24;
+ ret = intel_write_sha_text(dev_priv, sha_text);
+ if (ret < 0)
+ return ret;
+ sha_idx += sizeof(sha_text);
} else if (sha_leftovers == 3) {
- /* Write 32 bits of text */
+ /* Write 32 bits of text (filled from LSB) */
intel_de_write(dev_priv, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_32);
- sha_text |= bstatus[0] << 24;
+ sha_text |= bstatus[0];
ret = intel_write_sha_text(dev_priv, sha_text);
if (ret < 0)
return ret;
sha_idx += sizeof(sha_text);
- /* Write 8 bits of text, 24 bits of M0 */
+ /* Write 8 bits of text (filled from LSB), 24 bits of M0 */
intel_de_write(dev_priv, HDCP_REP_CTL,
rep_ctl | HDCP_SHA1_TEXT_8);
ret = intel_write_sha_text(dev_priv, bstatus[1]);
@@ -781,6 +795,7 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
struct intel_hdcp *hdcp = &connector->hdcp;
enum port port = dig_port->base.port;
enum transcoder cpu_transcoder = hdcp->cpu_transcoder;
+ u32 repeater_ctl;
int ret;
drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP is being disabled...\n",
@@ -796,6 +811,11 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
return -ETIMEDOUT;
}
+ repeater_ctl = intel_hdcp_get_repeater_ctl(dev_priv, cpu_transcoder,
+ port);
+ intel_de_write(dev_priv, HDCP_REP_CTL,
+ intel_de_read(dev_priv, HDCP_REP_CTL) & ~repeater_ctl);
+
ret = hdcp->shim->toggle_signalling(dig_port, false);
if (ret) {
drm_err(&dev_priv->drm, "Failed to disable HDCP signalling\n");
diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c
index b781bf469644..dc1b35559afd 100644
--- a/drivers/gpu/drm/i915/display/intel_lspcon.c
+++ b/drivers/gpu/drm/i915/display/intel_lspcon.c
@@ -571,7 +571,7 @@ bool lspcon_init(struct intel_digital_port *dig_port)
return false;
}
- if (!intel_dp_read_dpcd(dp)) {
+ if (drm_dp_read_dpcd_caps(&dp->aux, dp->dpcd) != 0) {
DRM_ERROR("LSPCON DPCD read failed\n");
return false;
}
diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
index bbde3b12c311..4072d7062efd 100644
--- a/drivers/gpu/drm/i915/display/intel_panel.c
+++ b/drivers/gpu/drm/i915/display/intel_panel.c
@@ -229,7 +229,7 @@ int intel_pch_panel_fitting(struct intel_crtc_state *crtc_state,
case DRM_MODE_SCALE_NONE:
WARN_ON(adjusted_mode->crtc_hdisplay != crtc_state->pipe_src_w);
WARN_ON(adjusted_mode->crtc_vdisplay != crtc_state->pipe_src_h);
- /* fall through */
+ fallthrough;
case DRM_MODE_SCALE_FULLSCREEN:
x = y = 0;
width = adjusted_mode->crtc_hdisplay;
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index bf9e320c547d..2b004ee9619c 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -553,6 +553,22 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
val |= EDP_PSR2_FAST_WAKE(7);
}
+ if (dev_priv->psr.psr2_sel_fetch_enabled) {
+ /* WA 1408330847 */
+ if (IS_TGL_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_A0) ||
+ IS_RKL_REVID(dev_priv, RKL_REVID_A0, RKL_REVID_A0))
+ intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
+ DIS_RAM_BYPASS_PSR2_MAN_TRACK,
+ DIS_RAM_BYPASS_PSR2_MAN_TRACK);
+
+ intel_de_write(dev_priv,
+ PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder),
+ PSR2_MAN_TRK_CTL_ENABLE);
+ } else if (HAS_PSR2_SEL_FETCH(dev_priv)) {
+ intel_de_write(dev_priv,
+ PSR2_MAN_TRK_CTL(dev_priv->psr.transcoder), 0);
+ }
+
/*
* PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and BSpec is
* recommending keep this bit unset while PSR2 is enabled.
@@ -663,6 +679,38 @@ tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp,
crtc_state->dc3co_exitline = crtc_vdisplay - exit_scanlines;
}
+static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state)
+{
+ struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+ struct intel_plane_state *plane_state;
+ struct intel_plane *plane;
+ int i;
+
+ if (!dev_priv->params.enable_psr2_sel_fetch) {
+ drm_dbg_kms(&dev_priv->drm,
+ "PSR2 sel fetch not enabled, disabled by parameter\n");
+ return false;
+ }
+
+ if (crtc_state->uapi.async_flip) {
+ drm_dbg_kms(&dev_priv->drm,
+ "PSR2 sel fetch not enabled, async flip enabled\n");
+ return false;
+ }
+
+ for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
+ if (plane_state->uapi.rotation != DRM_MODE_ROTATE_0) {
+ drm_dbg_kms(&dev_priv->drm,
+ "PSR2 sel fetch not enabled, plane rotated\n");
+ return false;
+ }
+ }
+
+ return crtc_state->enable_psr2_sel_fetch = true;
+}
+
static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state)
{
@@ -732,22 +780,17 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
return false;
}
- /*
- * Some platforms lack PSR2 HW tracking and instead require manual
- * tracking by software. In this case, the driver is required to track
- * the areas that need updates and program hardware to send selective
- * updates.
- *
- * So until the software tracking is implemented, PSR2 needs to be
- * disabled for platforms without PSR2 HW tracking.
- */
- if (!HAS_PSR_HW_TRACKING(dev_priv)) {
- drm_dbg_kms(&dev_priv->drm,
- "No PSR2 HW tracking in the platform\n");
- return false;
+ if (HAS_PSR2_SEL_FETCH(dev_priv)) {
+ if (!intel_psr2_sel_fetch_config_valid(intel_dp, crtc_state) &&
+ !HAS_PSR_HW_TRACKING(dev_priv)) {
+ drm_dbg_kms(&dev_priv->drm,
+ "PSR2 not enabled, selective fetch not valid and no HW tracking available\n");
+ return false;
+ }
}
- if (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v) {
+ if (!crtc_state->enable_psr2_sel_fetch &&
+ (crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v)) {
drm_dbg_kms(&dev_priv->drm,
"PSR2 not enabled, resolution %dx%d > max supported %dx%d\n",
crtc_hdisplay, crtc_vdisplay,
@@ -898,6 +941,11 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
val |= EXITLINE_ENABLE;
intel_de_write(dev_priv, EXITLINE(cpu_transcoder), val);
}
+
+ if (HAS_PSR_HW_TRACKING(dev_priv))
+ intel_de_rmw(dev_priv, CHICKEN_PAR1_1, IGNORE_PSR2_HW_TRACKING,
+ dev_priv->psr.psr2_sel_fetch_enabled ?
+ IGNORE_PSR2_HW_TRACKING : 0);
}
static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
@@ -919,6 +967,7 @@ static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
/* DC5/DC6 requires at least 6 idle frames */
val = usecs_to_jiffies(intel_get_frame_time_us(crtc_state) * 6);
dev_priv->psr.dc3co_exit_delay = val;
+ dev_priv->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch;
/*
* If a PSR error happened and the driver is reloaded, the EDP_PSR_IIR
@@ -1058,6 +1107,13 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
psr_status_mask, 2000))
drm_err(&dev_priv->drm, "Timed out waiting PSR idle state\n");
+ /* WA 1408330847 */
+ if (dev_priv->psr.psr2_sel_fetch_enabled &&
+ (IS_TGL_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_A0) ||
+ IS_RKL_REVID(dev_priv, RKL_REVID_A0, RKL_REVID_A0)))
+ intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
+ DIS_RAM_BYPASS_PSR2_MAN_TRACK, 0);
+
/* Disable PSR on Sink */
drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0);
@@ -1115,6 +1171,32 @@ static void psr_force_hw_tracking_exit(struct drm_i915_private *dev_priv)
intel_psr_exit(dev_priv);
}
+void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state)
+{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ struct i915_psr *psr = &dev_priv->psr;
+
+ if (!HAS_PSR2_SEL_FETCH(dev_priv) ||
+ !crtc_state->enable_psr2_sel_fetch)
+ return;
+
+ intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(psr->transcoder),
+ crtc_state->psr2_man_track_ctl);
+}
+
+void intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
+
+ if (!crtc_state->enable_psr2_sel_fetch)
+ return;
+
+ crtc_state->psr2_man_track_ctl = PSR2_MAN_TRK_CTL_ENABLE |
+ PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME;
+}
+
/**
* intel_psr_update - Update PSR state
* @intel_dp: Intel DP
diff --git a/drivers/gpu/drm/i915/display/intel_psr.h b/drivers/gpu/drm/i915/display/intel_psr.h
index b4515186d5f4..6a83c8e682e6 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.h
+++ b/drivers/gpu/drm/i915/display/intel_psr.h
@@ -13,6 +13,8 @@ struct drm_connector_state;
struct drm_i915_private;
struct intel_crtc_state;
struct intel_dp;
+struct intel_crtc;
+struct intel_atomic_state;
#define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support)
void intel_psr_init_dpcd(struct intel_dp *intel_dp);
@@ -43,5 +45,8 @@ void intel_psr_atomic_check(struct drm_connector *connector,
struct drm_connector_state *old_state,
struct drm_connector_state *new_state);
void intel_psr_set_force_mode_changed(struct intel_dp *intel_dp);
+void intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
+ struct intel_crtc *crtc);
+void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_state);
#endif /* __INTEL_PSR_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
index 2da4388e1540..5e9fb349c829 100644
--- a/drivers/gpu/drm/i915/display/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
@@ -1531,7 +1531,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
default:
drm_WARN(&dev_priv->drm, 1,
"unknown pixel multiplier specified\n");
- /* fall through */
+ fallthrough;
case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break;
case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break;
case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break;
@@ -2549,19 +2549,19 @@ intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo)
switch (sdvo->controlled_output) {
case SDVO_OUTPUT_LVDS1:
mask |= SDVO_OUTPUT_LVDS1;
- /* fall through */
+ fallthrough;
case SDVO_OUTPUT_LVDS0:
mask |= SDVO_OUTPUT_LVDS0;
- /* fall through */
+ fallthrough;
case SDVO_OUTPUT_TMDS1:
mask |= SDVO_OUTPUT_TMDS1;
- /* fall through */
+ fallthrough;
case SDVO_OUTPUT_TMDS0:
mask |= SDVO_OUTPUT_TMDS0;
- /* fall through */
+ fallthrough;
case SDVO_OUTPUT_RGB1:
mask |= SDVO_OUTPUT_RGB1;
- /* fall through */
+ fallthrough;
case SDVO_OUTPUT_RGB0:
mask |= SDVO_OUTPUT_RGB0;
break;
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index d03860fef2d7..6b72223981be 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -2147,7 +2147,7 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
case DRM_FORMAT_RGB565:
if (INTEL_GEN(dev_priv) >= 11)
break;
- /* fall through */
+ fallthrough;
case DRM_FORMAT_C8:
case DRM_FORMAT_XRGB16161616F:
case DRM_FORMAT_XBGR16161616F:
@@ -2702,7 +2702,7 @@ static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
if (modifier == DRM_FORMAT_MOD_LINEAR ||
modifier == I915_FORMAT_MOD_X_TILED)
return true;
- /* fall through */
+ fallthrough;
default:
return false;
}
@@ -2733,7 +2733,7 @@ static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
if (modifier == DRM_FORMAT_MOD_LINEAR ||
modifier == I915_FORMAT_MOD_X_TILED)
return true;
- /* fall through */
+ fallthrough;
default:
return false;
}
@@ -2768,7 +2768,7 @@ static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
if (modifier == DRM_FORMAT_MOD_LINEAR ||
modifier == I915_FORMAT_MOD_X_TILED)
return true;
- /* fall through */
+ fallthrough;
default:
return false;
}
@@ -2801,7 +2801,7 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
case DRM_FORMAT_ABGR8888:
if (is_ccs_modifier(modifier))
return true;
- /* fall through */
+ fallthrough;
case DRM_FORMAT_RGB565:
case DRM_FORMAT_XRGB2101010:
case DRM_FORMAT_XBGR2101010:
@@ -2819,7 +2819,7 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
case DRM_FORMAT_XVYU2101010:
if (modifier == I915_FORMAT_MOD_Yf_TILED)
return true;
- /* fall through */
+ fallthrough;
case DRM_FORMAT_C8:
case DRM_FORMAT_XBGR16161616F:
case DRM_FORMAT_ABGR16161616F:
@@ -2834,7 +2834,7 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
modifier == I915_FORMAT_MOD_X_TILED ||
modifier == I915_FORMAT_MOD_Y_TILED)
return true;
- /* fall through */
+ fallthrough;
default:
return false;
}
@@ -2843,8 +2843,9 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
static bool gen12_plane_supports_mc_ccs(struct drm_i915_private *dev_priv,
enum plane_id plane_id)
{
- /* Wa_14010477008:tgl[a0..c0] */
- if (IS_TGL_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_C0))
+ /* Wa_14010477008:tgl[a0..c0],rkl[all] */
+ if (IS_ROCKETLAKE(dev_priv) ||
+ IS_TGL_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_C0))
return false;
return plane_id < PLANE_SPRITE4;
@@ -2860,7 +2861,7 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
if (!gen12_plane_supports_mc_ccs(dev_priv, plane->id))
return false;
- /* fall through */
+ fallthrough;
case DRM_FORMAT_MOD_LINEAR:
case I915_FORMAT_MOD_X_TILED:
case I915_FORMAT_MOD_Y_TILED:
@@ -2877,7 +2878,7 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
case DRM_FORMAT_ABGR8888:
if (is_ccs_modifier(modifier))
return true;
- /* fall through */
+ fallthrough;
case DRM_FORMAT_YUYV:
case DRM_FORMAT_YVYU:
case DRM_FORMAT_UYVY:
@@ -2889,7 +2890,7 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
case DRM_FORMAT_P016:
if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)
return true;
- /* fall through */
+ fallthrough;
case DRM_FORMAT_RGB565:
case DRM_FORMAT_XRGB2101010:
case DRM_FORMAT_XBGR2101010:
@@ -2910,7 +2911,7 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
modifier == I915_FORMAT_MOD_X_TILED ||
modifier == I915_FORMAT_MOD_Y_TILED)
return true;
- /* fall through */
+ fallthrough;
default:
return false;
}
diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c
index 5b5dc86a5737..8f67aef18b2d 100644
--- a/drivers/gpu/drm/i915/display/intel_tc.c
+++ b/drivers/gpu/drm/i915/display/intel_tc.c
@@ -159,7 +159,7 @@ int intel_tc_port_fia_max_lane_count(struct intel_digital_port *dig_port)
switch (lane_mask) {
default:
MISSING_CASE(lane_mask);
- /* fall-through */
+ fallthrough;
case 0x1:
case 0x2:
case 0x4: