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/i9xx_plane.c2
-rw-r--r--drivers/gpu/drm/i915/display/icl_dsi.c46
-rw-r--r--drivers/gpu/drm/i915/display/intel_acpi.c19
-rw-r--r--drivers/gpu/drm/i915/display/intel_acpi.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic_plane.c7
-rw-r--r--drivers/gpu/drm/i915/display/intel_atomic_plane.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_audio.c4
-rw-r--r--drivers/gpu/drm/i915/display/intel_bios.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_bw.c178
-rw-r--r--drivers/gpu/drm/i915/display/intel_cdclk.c107
-rw-r--r--drivers/gpu/drm/i915/display/intel_color.c5
-rw-r--r--drivers/gpu/drm/i915/display/intel_combo_phy.c106
-rw-r--r--drivers/gpu/drm/i915/display/intel_crt.c3
-rw-r--r--drivers/gpu/drm/i915/display/intel_crtc.c10
-rw-r--r--drivers/gpu/drm/i915/display/intel_cursor.c12
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.c630
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.h4
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c2475
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h70
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c385
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_debugfs.c118
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.c568
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.h15
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_types.h34
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.c232
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.h23
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c65
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_aux.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c329
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_mst.c43
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll.c12
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.c631
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.h3
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbc.c219
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbdev.c96
-rw-r--r--drivers/gpu/drm/i915/display/intel_fdi.c25
-rw-r--r--drivers/gpu/drm/i915/display/intel_gmbus.c4
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdmi.c53
-rw-r--r--drivers/gpu/drm/i915/display/intel_lvds.c4
-rw-r--r--drivers/gpu/drm/i915/display/intel_opregion.c3
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.c265
-rw-r--r--drivers/gpu/drm/i915/display/intel_quirks.c34
-rw-r--r--drivers/gpu/drm/i915/display/intel_sdvo.c4
-rw-r--r--drivers/gpu/drm/i915/display/intel_snps_phy.c862
-rw-r--r--drivers/gpu/drm/i915/display/intel_snps_phy.h35
-rw-r--r--drivers/gpu/drm/i915/display/intel_sprite.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_tc.c34
-rw-r--r--drivers/gpu/drm/i915/display/intel_tc.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_tv.c13
-rw-r--r--drivers/gpu/drm/i915/display/intel_vbt_defs.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_vdsc.c5
-rw-r--r--drivers/gpu/drm/i915/display/intel_vga.c12
-rw-r--r--drivers/gpu/drm/i915/display/skl_scaler.c49
-rw-r--r--drivers/gpu/drm/i915/display/skl_universal_plane.c28
-rw-r--r--drivers/gpu/drm/i915/display/vlv_dsi.c13
56 files changed, 4438 insertions, 3478 deletions
diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c
index 9643c45a2209..b1439ba78f67 100644
--- a/drivers/gpu/drm/i915/display/i9xx_plane.c
+++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
@@ -912,7 +912,7 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
zpos = 0;
drm_plane_create_zpos_immutable_property(&plane->base, zpos);
- drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
+ intel_plane_helper_add(plane);
return plane;
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 16812488c5dd..43ec7fcd3f5d 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -729,8 +729,8 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
- struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
- enum pipe pipe = intel_crtc->pipe;
+ struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+ enum pipe pipe = crtc->pipe;
u32 tmp;
enum port port;
enum transcoder dsi_trans;
@@ -1253,15 +1253,36 @@ static void gen11_dsi_pre_enable(struct intel_atomic_state *state,
gen11_dsi_set_transcoder_timings(encoder, pipe_config);
}
+/*
+ * Wa_1409054076:icl,jsl,ehl
+ * When pipe A is disabled and MIPI DSI is enabled on pipe B,
+ * the AMT KVMR feature will incorrectly see pipe A as enabled.
+ * Set 0x42080 bit 23=1 before enabling DSI on pipe B and leave
+ * it set while DSI is enabled on pipe B
+ */
+static void icl_apply_kvmr_pipe_a_wa(struct intel_encoder *encoder,
+ enum pipe pipe, bool enable)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+ if (DISPLAY_VER(dev_priv) == 11 && pipe == PIPE_B)
+ intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
+ IGNORE_KVMR_PIPE_A,
+ enable ? IGNORE_KVMR_PIPE_A : 0);
+}
static void gen11_dsi_enable(struct intel_atomic_state *state,
struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state)
{
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+ struct intel_crtc *crtc = to_intel_crtc(conn_state->crtc);
drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
+ /* Wa_1409054076:icl,jsl,ehl */
+ icl_apply_kvmr_pipe_a_wa(encoder, crtc->pipe, true);
+
/* step6d: enable dsi transcoder */
gen11_dsi_enable_transcoder(encoder);
@@ -1415,6 +1436,7 @@ static void gen11_dsi_disable(struct intel_atomic_state *state,
const struct drm_connector_state *old_conn_state)
{
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
+ struct intel_crtc *crtc = to_intel_crtc(old_conn_state->crtc);
/* step1: turn off backlight */
intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_OFF);
@@ -1423,6 +1445,9 @@ static void gen11_dsi_disable(struct intel_atomic_state *state,
/* step2d,e: disable transcoder and wait */
gen11_dsi_disable_transcoder(encoder);
+ /* Wa_1409054076:icl,jsl,ehl */
+ icl_apply_kvmr_pipe_a_wa(encoder, crtc->pipe, false);
+
/* step2f,g: powerdown panel */
gen11_dsi_powerdown_panel(encoder);
@@ -1548,6 +1573,22 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
pipe_config->mode_flags |= I915_MODE_FLAG_DSI_PERIODIC_CMD_MODE;
}
+static void gen11_dsi_sync_state(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ enum pipe pipe = intel_crtc->pipe;
+
+ /* wa verify 1409054076:icl,jsl,ehl */
+ if (DISPLAY_VER(dev_priv) == 11 && pipe == PIPE_B &&
+ !(intel_de_read(dev_priv, CHICKEN_PAR1_1) & IGNORE_KVMR_PIPE_A))
+ drm_dbg_kms(&dev_priv->drm,
+ "[ENCODER:%d:%s] BIOS left IGNORE_KVMR_PIPE_A cleared with pipe B enabled\n",
+ encoder->base.base.id,
+ encoder->base.name);
+}
+
static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state)
{
@@ -1966,6 +2007,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
encoder->post_disable = gen11_dsi_post_disable;
encoder->port = port;
encoder->get_config = gen11_dsi_get_config;
+ encoder->sync_state = gen11_dsi_sync_state;
encoder->update_pipe = intel_panel_update_backlight;
encoder->compute_config = gen11_dsi_compute_config;
encoder->get_hw_state = gen11_dsi_get_hw_state;
diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c
index 833d0c1be4f1..7cfe91fc05f2 100644
--- a/drivers/gpu/drm/i915/display/intel_acpi.c
+++ b/drivers/gpu/drm/i915/display/intel_acpi.c
@@ -19,6 +19,12 @@ static const guid_t intel_dsm_guid =
GUID_INIT(0x7ed873d3, 0xc2d0, 0x4e4f,
0xa8, 0x54, 0x0f, 0x13, 0x17, 0xb0, 0x1c, 0x2c);
+#define INTEL_DSM_FN_GET_BIOS_DATA_FUNCS_SUPPORTED 0 /* No args */
+
+static const guid_t intel_dsm_guid2 =
+ GUID_INIT(0x3e5b41c6, 0xeb1d, 0x4260,
+ 0x9d, 0x15, 0xc7, 0x1f, 0xba, 0xda, 0xe4, 0x14);
+
static char *intel_dsm_port_name(u8 id)
{
switch (id) {
@@ -176,6 +182,19 @@ void intel_unregister_dsm_handler(void)
{
}
+void intel_dsm_get_bios_data_funcs_supported(struct drm_i915_private *i915)
+{
+ struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
+ acpi_handle dhandle;
+
+ dhandle = ACPI_HANDLE(&pdev->dev);
+ if (!dhandle)
+ return;
+
+ acpi_evaluate_dsm(dhandle, &intel_dsm_guid2, INTEL_DSM_REVISION_ID,
+ INTEL_DSM_FN_GET_BIOS_DATA_FUNCS_SUPPORTED, NULL);
+}
+
/*
* ACPI Specification, Revision 5.0, Appendix B.3.2 _DOD (Enumerate All Devices
* Attached to the Display Adapter).
diff --git a/drivers/gpu/drm/i915/display/intel_acpi.h b/drivers/gpu/drm/i915/display/intel_acpi.h
index e8b068661d22..9f197401c313 100644
--- a/drivers/gpu/drm/i915/display/intel_acpi.h
+++ b/drivers/gpu/drm/i915/display/intel_acpi.h
@@ -11,11 +11,14 @@ struct drm_i915_private;
#ifdef CONFIG_ACPI
void intel_register_dsm_handler(void);
void intel_unregister_dsm_handler(void);
+void intel_dsm_get_bios_data_funcs_supported(struct drm_i915_private *i915);
void intel_acpi_device_id_update(struct drm_i915_private *i915);
#else
static inline void intel_register_dsm_handler(void) { return; }
static inline void intel_unregister_dsm_handler(void) { return; }
static inline
+void intel_dsm_get_bios_data_funcs_supported(struct drm_i915_private *i915) { return; }
+static inline
void intel_acpi_device_id_update(struct drm_i915_private *i915) { return; }
#endif /* CONFIG_ACPI */
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 36f52a1d7552..47234d898549 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -601,7 +601,12 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
return 0;
}
-const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
+static const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
.prepare_fb = intel_prepare_plane_fb,
.cleanup_fb = intel_cleanup_plane_fb,
};
+
+void intel_plane_helper_add(struct intel_plane *plane)
+{
+ drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
index dc4d05e75e1c..62e5a2a77fd4 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -17,8 +17,6 @@ struct intel_crtc_state;
struct intel_plane;
struct intel_plane_state;
-extern const struct drm_plane_helper_funcs intel_plane_helper_funcs;
-
unsigned int intel_adjusted_rate(const struct drm_rect *src,
const struct drm_rect *dst,
unsigned int rate);
@@ -65,5 +63,6 @@ int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
bool can_position);
void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state);
+void intel_plane_helper_add(struct intel_plane *plane);
#endif /* __INTEL_ATOMIC_PLANE_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c
index 5f4f316b3ab5..532237588511 100644
--- a/drivers/gpu/drm/i915/display/intel_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_audio.c
@@ -1001,7 +1001,7 @@ static unsigned long i915_audio_component_get_power(struct device *kdev)
/* Catch potential impedance mismatches before they occur! */
BUILD_BUG_ON(sizeof(intel_wakeref_t) > sizeof(unsigned long));
- ret = intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
+ ret = intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO_PLAYBACK);
if (dev_priv->audio_power_refcount++ == 0) {
if (DISPLAY_VER(dev_priv) >= 9) {
@@ -1034,7 +1034,7 @@ static void i915_audio_component_put_power(struct device *kdev,
if (IS_GEMINILAKE(dev_priv))
glk_force_audio_cdclk(dev_priv, false);
- intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO, cookie);
+ intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO_PLAYBACK, cookie);
}
static void i915_audio_component_codec_wake_override(struct device *kdev,
diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index aa667fa71158..e86e6ed2d3bf 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -1871,12 +1871,12 @@ intel_bios_encoder_supports_edp(const struct intel_bios_encoder_data *devdata)
static bool is_port_valid(struct drm_i915_private *i915, enum port port)
{
/*
- * On some ICL/CNL SKUs port F is not present, but broken VBTs mark
+ * On some ICL SKUs port F is not present, but broken VBTs mark
* the port as present. Only try to initialize port F for the
* SKUs that may actually have it.
*/
- if (port == PORT_F && (IS_ICELAKE(i915) || IS_CANNONLAKE(i915)))
- return IS_ICL_WITH_PORT_F(i915) || IS_CNL_WITH_PORT_F(i915);
+ if (port == PORT_F && IS_ICELAKE(i915))
+ return IS_ICL_WITH_PORT_F(i915);
return true;
}
@@ -1998,7 +1998,7 @@ static void parse_ddi_port(struct drm_i915_private *i915,
"Port %c VBT HDMI boost level: %d\n",
port_name(port), hdmi_boost_level);
- /* DP max link rate for CNL+ */
+ /* DP max link rate for GLK+ */
if (i915->vbt.version >= 216) {
if (i915->vbt.version >= 230)
info->dp_max_link_rate = parse_bdb_230_dp_max_link_rate(child->dp_max_link_rate);
diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index bfb398f0432e..e91e0e0191fb 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -17,12 +17,53 @@ struct intel_qgv_point {
u16 dclk, t_rp, t_rdpre, t_rc, t_ras, t_rcd;
};
+struct intel_psf_gv_point {
+ u8 clk; /* clock in multiples of 16.6666 MHz */
+};
+
struct intel_qgv_info {
struct intel_qgv_point points[I915_NUM_QGV_POINTS];
+ struct intel_psf_gv_point psf_points[I915_NUM_PSF_GV_POINTS];
u8 num_points;
+ u8 num_psf_points;
u8 t_bl;
};
+static int dg1_mchbar_read_qgv_point_info(struct drm_i915_private *dev_priv,
+ struct intel_qgv_point *sp,
+ int point)
+{
+ u32 dclk_ratio, dclk_reference;
+ u32 val;
+
+ val = intel_uncore_read(&dev_priv->uncore, SA_PERF_STATUS_0_0_0_MCHBAR_PC);
+ dclk_ratio = REG_FIELD_GET(DG1_QCLK_RATIO_MASK, val);
+ if (val & DG1_QCLK_REFERENCE)
+ dclk_reference = 6; /* 6 * 16.666 MHz = 100 MHz */
+ else
+ dclk_reference = 8; /* 8 * 16.666 MHz = 133 MHz */
+ sp->dclk = dclk_ratio * dclk_reference;
+
+ val = intel_uncore_read(&dev_priv->uncore, SKL_MC_BIOS_DATA_0_0_0_MCHBAR_PCU);
+ if (val & DG1_GEAR_TYPE)
+ sp->dclk *= 2;
+
+ if (sp->dclk == 0)
+ return -EINVAL;
+
+ val = intel_uncore_read(&dev_priv->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR);
+ sp->t_rp = REG_FIELD_GET(DG1_DRAM_T_RP_MASK, val);
+ sp->t_rdpre = REG_FIELD_GET(DG1_DRAM_T_RDPRE_MASK, val);
+
+ val = intel_uncore_read(&dev_priv->uncore, MCHBAR_CH0_CR_TC_PRE_0_0_0_MCHBAR_HIGH);
+ sp->t_rcd = REG_FIELD_GET(DG1_DRAM_T_RCD_MASK, val);
+ sp->t_ras = REG_FIELD_GET(DG1_DRAM_T_RAS_MASK, val);
+
+ sp->t_rc = sp->t_rp + sp->t_ras;
+
+ return 0;
+}
+
static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv,
struct intel_qgv_point *sp,
int point)
@@ -49,6 +90,28 @@ static int icl_pcode_read_qgv_point_info(struct drm_i915_private *dev_priv,
return 0;
}
+static int adls_pcode_read_psf_gv_point_info(struct drm_i915_private *dev_priv,
+ struct intel_psf_gv_point *points)
+{
+ u32 val = 0;
+ int ret;
+ int i;
+
+ ret = sandybridge_pcode_read(dev_priv,
+ ICL_PCODE_MEM_SUBSYSYSTEM_INFO |
+ ADL_PCODE_MEM_SS_READ_PSF_GV_INFO,
+ &val, NULL);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < I915_NUM_PSF_GV_POINTS; i++) {
+ points[i].clk = val & 0xff;
+ val >>= 8;
+ }
+
+ return 0;
+}
+
int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
u32 points_mask)
{
@@ -62,7 +125,7 @@ int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
1);
if (ret < 0) {
- drm_err(&dev_priv->drm, "Failed to disable qgv points (%d)\n", ret);
+ drm_err(&dev_priv->drm, "Failed to disable qgv points (%d) points: 0x%x\n", ret, points_mask);
return ret;
}
@@ -76,6 +139,7 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
int i, ret;
qi->num_points = dram_info->num_qgv_points;
+ qi->num_psf_points = dram_info->num_psf_gv_points;
if (DISPLAY_VER(dev_priv) == 12)
switch (dram_info->type) {
@@ -99,7 +163,11 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
for (i = 0; i < qi->num_points; i++) {
struct intel_qgv_point *sp = &qi->points[i];
- ret = icl_pcode_read_qgv_point_info(dev_priv, sp, i);
+ if (IS_DG1(dev_priv))
+ ret = dg1_mchbar_read_qgv_point_info(dev_priv, sp, i);
+ else
+ ret = icl_pcode_read_qgv_point_info(dev_priv, sp, i);
+
if (ret)
return ret;
@@ -109,6 +177,19 @@ static int icl_get_qgv_points(struct drm_i915_private *dev_priv,
sp->t_rcd, sp->t_rc);
}
+ if (qi->num_psf_points > 0) {
+ ret = adls_pcode_read_psf_gv_point_info(dev_priv, qi->psf_points);
+ if (ret) {
+ drm_err(&dev_priv->drm, "Failed to read PSF point data; PSF points will not be considered in bandwidth calculations.\n");
+ qi->num_psf_points = 0;
+ }
+
+ for (i = 0; i < qi->num_psf_points; i++)
+ drm_dbg_kms(&dev_priv->drm,
+ "PSF GV %d: CLK=%d \n",
+ i, qi->psf_points[i].clk);
+ }
+
return 0;
}
@@ -118,6 +199,16 @@ static int icl_calc_bw(int dclk, int num, int den)
return DIV_ROUND_CLOSEST(num * dclk * 100, den * 6);
}
+static int adl_calc_psf_bw(int clk)
+{
+ /*
+ * clk is multiples of 16.666MHz (100/6)
+ * According to BSpec PSF GV bandwidth is
+ * calculated as BW = 64 * clk * 16.666Mhz
+ */
+ return DIV_ROUND_CLOSEST(64 * clk * 100, 6);
+}
+
static int icl_sagv_max_dclk(const struct intel_qgv_info *qi)
{
u16 dclk = 0;
@@ -194,6 +285,7 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
bi->num_planes = (ipqdepth - clpchgroup) / clpchgroup + 1;
bi->num_qgv_points = qi.num_points;
+ bi->num_psf_gv_points = qi.num_psf_points;
for (j = 0; j < qi.num_points; j++) {
const struct intel_qgv_point *sp = &qi.points[j];
@@ -217,6 +309,16 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
i, j, bi->num_planes, bi->deratedbw[j]);
}
+ for (j = 0; j < qi.num_psf_points; j++) {
+ const struct intel_psf_gv_point *sp = &qi.psf_points[j];
+
+ bi->psf_bw[j] = adl_calc_psf_bw(sp->clk);
+
+ drm_dbg_kms(&dev_priv->drm,
+ "BW%d / PSF GV %d: num_planes=%d bw=%u\n",
+ i, j, bi->num_planes, bi->psf_bw[j]);
+ }
+
if (bi->num_planes == 1)
break;
}
@@ -234,6 +336,26 @@ static int icl_get_bw_info(struct drm_i915_private *dev_priv, const struct intel
return 0;
}
+static void dg2_get_bw_info(struct drm_i915_private *i915)
+{
+ struct intel_bw_info *bi = &i915->max_bw[0];
+
+ /*
+ * DG2 doesn't have SAGV or QGV points, just a constant max bandwidth
+ * that doesn't depend on the number of planes enabled. Create a
+ * single dummy QGV point to reflect that. DG2-G10 platforms have a
+ * constant 50 GB/s bandwidth, whereas DG2-G11 platforms have 38 GB/s.
+ */
+ bi->num_planes = 1;
+ bi->num_qgv_points = 1;
+ if (IS_DG2_G11(i915))
+ bi->deratedbw[0] = 38000;
+ else
+ bi->deratedbw[0] = 50000;
+
+ i915->sagv_status = I915_SAGV_NOT_CONTROLLED;
+}
+
static unsigned int icl_max_bw(struct drm_i915_private *dev_priv,
int num_planes, int qgv_point)
{
@@ -262,12 +384,23 @@ static unsigned int icl_max_bw(struct drm_i915_private *dev_priv,
return 0;
}
+static unsigned int adl_psf_bw(struct drm_i915_private *dev_priv,
+ int psf_gv_point)
+{
+ const struct intel_bw_info *bi =
+ &dev_priv->max_bw[0];
+
+ return bi->psf_bw[psf_gv_point];
+}
+
void intel_bw_init_hw(struct drm_i915_private *dev_priv)
{
if (!HAS_DISPLAY(dev_priv))
return;
- if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv))
+ if (IS_DG2(dev_priv))
+ dg2_get_bw_info(dev_priv);
+ else if (IS_ALDERLAKE_S(dev_priv) || IS_ALDERLAKE_P(dev_priv))
icl_get_bw_info(dev_priv, &adls_sa_info);
else if (IS_ROCKETLAKE(dev_priv))
icl_get_bw_info(dev_priv, &rkl_sa_info);
@@ -534,12 +667,24 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
u32 allowed_points = 0;
unsigned int max_bw_point = 0, max_bw = 0;
unsigned int num_qgv_points = dev_priv->max_bw[0].num_qgv_points;
- u32 mask = (1 << num_qgv_points) - 1;
+ unsigned int num_psf_gv_points = dev_priv->max_bw[0].num_psf_gv_points;
+ u32 mask = 0;
/* FIXME earlier gens need some checks too */
if (DISPLAY_VER(dev_priv) < 11)
return 0;
+ /*
+ * We can _not_ use the whole ADLS_QGV_PT_MASK here, as PCode rejects
+ * it with failure if we try masking any unadvertised points.
+ * So need to operate only with those returned from PCode.
+ */
+ if (num_qgv_points > 0)
+ mask |= REG_GENMASK(num_qgv_points - 1, 0);
+
+ if (num_psf_gv_points > 0)
+ mask |= REG_GENMASK(num_psf_gv_points - 1, 0) << ADLS_PSF_PT_SHIFT;
+
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
new_crtc_state, i) {
unsigned int old_data_rate =
@@ -602,23 +747,44 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
max_bw = max_data_rate;
}
if (max_data_rate >= data_rate)
- allowed_points |= BIT(i);
+ allowed_points |= REG_FIELD_PREP(ADLS_QGV_PT_MASK, BIT(i));
+
drm_dbg_kms(&dev_priv->drm, "QGV point %d: max bw %d required %d\n",
i, max_data_rate, data_rate);
}
+ for (i = 0; i < num_psf_gv_points; i++) {
+ unsigned int max_data_rate = adl_psf_bw(dev_priv, i);
+
+ if (max_data_rate >= data_rate)
+ allowed_points |= REG_FIELD_PREP(ADLS_PSF_PT_MASK, BIT(i));
+
+ drm_dbg_kms(&dev_priv->drm, "PSF GV point %d: max bw %d"
+ " required %d\n",
+ i, max_data_rate, data_rate);
+ }
+
/*
* BSpec states that we always should have at least one allowed point
* left, so if we couldn't - simply reject the configuration for obvious
* reasons.
*/
- if (allowed_points == 0) {
+ if ((allowed_points & ADLS_QGV_PT_MASK) == 0) {
drm_dbg_kms(&dev_priv->drm, "No QGV points provide sufficient memory"
" bandwidth %d for display configuration(%d active planes).\n",
data_rate, num_active_planes);
return -EINVAL;
}
+ if (num_psf_gv_points > 0) {
+ if ((allowed_points & ADLS_PSF_PT_MASK) == 0) {
+ drm_dbg_kms(&dev_priv->drm, "No PSF GV points provide sufficient memory"
+ " bandwidth %d for display configuration(%d active planes).\n",
+ data_rate, num_active_planes);
+ return -EINVAL;
+ }
+ }
+
/*
* Leave only single point with highest bandwidth, if
* we can't enable SAGV due to the increased memory latency it may
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 613ffcc68eba..34fa4130d5c4 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -1195,17 +1195,6 @@ static const struct intel_cdclk_vals glk_cdclk_table[] = {
{}
};
-static const struct intel_cdclk_vals cnl_cdclk_table[] = {
- { .refclk = 19200, .cdclk = 168000, .divider = 4, .ratio = 35 },
- { .refclk = 19200, .cdclk = 336000, .divider = 2, .ratio = 35 },
- { .refclk = 19200, .cdclk = 528000, .divider = 2, .ratio = 55 },
-
- { .refclk = 24000, .cdclk = 168000, .divider = 4, .ratio = 28 },
- { .refclk = 24000, .cdclk = 336000, .divider = 2, .ratio = 28 },
- { .refclk = 24000, .cdclk = 528000, .divider = 2, .ratio = 44 },
- {}
-};
-
static const struct intel_cdclk_vals icl_cdclk_table[] = {
{ .refclk = 19200, .cdclk = 172800, .divider = 2, .ratio = 18 },
{ .refclk = 19200, .cdclk = 192000, .divider = 2, .ratio = 20 },
@@ -1290,6 +1279,16 @@ static const struct intel_cdclk_vals adlp_cdclk_table[] = {
{}
};
+static const struct intel_cdclk_vals dg2_cdclk_table[] = {
+ { .refclk = 38400, .cdclk = 172800, .divider = 2, .ratio = 9 },
+ { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 10 },
+ { .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16 },
+ { .refclk = 38400, .cdclk = 326400, .divider = 4, .ratio = 34 },
+ { .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29 },
+ { .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34 },
+ {}
+};
+
static int bxt_calc_cdclk(struct drm_i915_private *dev_priv, int min_cdclk)
{
const struct intel_cdclk_vals *table = dev_priv->cdclk.table;
@@ -1329,16 +1328,6 @@ static u8 bxt_calc_voltage_level(int cdclk)
return DIV_ROUND_UP(cdclk, 25000);
}
-static u8 cnl_calc_voltage_level(int cdclk)
-{
- if (cdclk > 336000)
- return 2;
- else if (cdclk > 168000)
- return 1;
- else
- return 0;
-}
-
static u8 icl_calc_voltage_level(int cdclk)
{
if (cdclk > 556800)
@@ -1373,15 +1362,6 @@ static u8 tgl_calc_voltage_level(int cdclk)
return 0;
}
-static void cnl_readout_refclk(struct drm_i915_private *dev_priv,
- struct intel_cdclk_config *cdclk_config)
-{
- if (intel_de_read(dev_priv, SKL_DSSM) & CNL_DSSM_CDCLK_PLL_REFCLK_24MHz)
- cdclk_config->ref = 24000;
- else
- cdclk_config->ref = 19200;
-}
-
static void icl_readout_refclk(struct drm_i915_private *dev_priv,
struct intel_cdclk_config *cdclk_config)
{
@@ -1408,10 +1388,10 @@ static void bxt_de_pll_readout(struct drm_i915_private *dev_priv,
{
u32 val, ratio;
- if (DISPLAY_VER(dev_priv) >= 11)
+ if (IS_DG2(dev_priv))
+ cdclk_config->ref = 38400;
+ else if (DISPLAY_VER(dev_priv) >= 11)
icl_readout_refclk(dev_priv, cdclk_config);
- else if (IS_CANNONLAKE(dev_priv))
- cnl_readout_refclk(dev_priv, cdclk_config);
else
cdclk_config->ref = 19200;
@@ -1427,11 +1407,11 @@ static void bxt_de_pll_readout(struct drm_i915_private *dev_priv,
}
/*
- * CNL+ have the ratio directly in the PLL enable register, gen9lp had
- * it in a separate PLL control register.
+ * DISPLAY_VER >= 11 have the ratio directly in the PLL enable register,
+ * gen9lp had it in a separate PLL control register.
*/
- if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv))
- ratio = val & CNL_CDCLK_PLL_RATIO_MASK;
+ if (DISPLAY_VER(dev_priv) >= 11)
+ ratio = val & ICL_CDCLK_PLL_RATIO_MASK;
else
ratio = intel_de_read(dev_priv, BXT_DE_PLL_CTL) & BXT_DE_PLL_RATIO_MASK;
@@ -1518,7 +1498,7 @@ static void bxt_de_pll_enable(struct drm_i915_private *dev_priv, int vco)
dev_priv->cdclk.hw.vco = vco;
}
-static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
+static void icl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
{
intel_de_rmw(dev_priv, BXT_DE_PLL_ENABLE,
BXT_DE_PLL_PLL_ENABLE, 0);
@@ -1530,12 +1510,12 @@ static void cnl_cdclk_pll_disable(struct drm_i915_private *dev_priv)
dev_priv->cdclk.hw.vco = 0;
}
-static void cnl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco)
+static void icl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco)
{
int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->cdclk.hw.ref);
u32 val;
- val = CNL_CDCLK_PLL_RATIO(ratio);
+ val = ICL_CDCLK_PLL_RATIO(ratio);
intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);
val |= BXT_DE_PLL_PLL_ENABLE;
@@ -1548,18 +1528,13 @@ static void cnl_cdclk_pll_enable(struct drm_i915_private *dev_priv, int vco)
dev_priv->cdclk.hw.vco = vco;
}
-static bool has_cdclk_crawl(struct drm_i915_private *i915)
-{
- return INTEL_INFO(i915)->has_cdclk_crawl;
-}
-
static void adlp_cdclk_pll_crawl(struct drm_i915_private *dev_priv, int vco)
{
int ratio = DIV_ROUND_CLOSEST(vco, dev_priv->cdclk.hw.ref);
u32 val;
/* Write PLL ratio without disabling */
- val = CNL_CDCLK_PLL_RATIO(ratio) | BXT_DE_PLL_PLL_ENABLE;
+ val = ICL_CDCLK_PLL_RATIO(ratio) | BXT_DE_PLL_PLL_ENABLE;
intel_de_write(dev_priv, BXT_DE_PLL_ENABLE, val);
/* Submit freq change request */
@@ -1628,7 +1603,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
int ret;
/* Inform power controller of upcoming frequency change. */
- if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv))
+ if (DISPLAY_VER(dev_priv) >= 11)
ret = skl_pcode_request(dev_priv, SKL_PCODE_CDCLK_CONTROL,
SKL_CDCLK_PREPARE_FOR_CHANGE,
SKL_CDCLK_READY_FOR_CHANGE,
@@ -1649,16 +1624,16 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
return;
}
- if (has_cdclk_crawl(dev_priv) && dev_priv->cdclk.hw.vco > 0 && vco > 0) {
+ if (HAS_CDCLK_CRAWL(dev_priv) && dev_priv->cdclk.hw.vco > 0 && vco > 0) {
if (dev_priv->cdclk.hw.vco != vco)
adlp_cdclk_pll_crawl(dev_priv, vco);
- } else if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) {
+ } else if (DISPLAY_VER(dev_priv) >= 11) {
if (dev_priv->cdclk.hw.vco != 0 &&
dev_priv->cdclk.hw.vco != vco)
- cnl_cdclk_pll_disable(dev_priv);
+ icl_cdclk_pll_disable(dev_priv);
if (dev_priv->cdclk.hw.vco != vco)
- cnl_cdclk_pll_enable(dev_priv, vco);
+ icl_cdclk_pll_enable(dev_priv, vco);
} else {
if (dev_priv->cdclk.hw.vco != 0 &&
dev_priv->cdclk.hw.vco != vco)
@@ -1684,7 +1659,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
if (pipe != INVALID_PIPE)
intel_wait_for_vblank(dev_priv, pipe);
- if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) {
+ if (DISPLAY_VER(dev_priv) >= 11) {
ret = sandybridge_pcode_write(dev_priv, SKL_PCODE_CDCLK_CONTROL,
cdclk_config->voltage_level);
} else {
@@ -1709,7 +1684,7 @@ static void bxt_set_cdclk(struct drm_i915_private *dev_priv,
intel_update_cdclk(dev_priv);
- if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv))
+ if (DISPLAY_VER(dev_priv) >= 11)
/*
* Can't read out the voltage level :(
* Let's just assume everything is as expected.
@@ -1857,7 +1832,7 @@ static bool intel_cdclk_can_crawl(struct drm_i915_private *dev_priv,
{
int a_div, b_div;
- if (!has_cdclk_crawl(dev_priv))
+ if (!HAS_CDCLK_CRAWL(dev_priv))
return false;
/*
@@ -2118,7 +2093,7 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
crtc_state->port_clock >= 540000 &&
crtc_state->lane_count == 4) {
if (DISPLAY_VER(dev_priv) == 10) {
- /* Display WA #1145: glk,cnl */
+ /* Display WA #1145: glk */
min_cdclk = max(316800, min_cdclk);
} else if (DISPLAY_VER(dev_priv) == 9 || IS_BROADWELL(dev_priv)) {
/* Display WA #1144: skl,bxt */
@@ -2239,7 +2214,7 @@ static int intel_compute_min_cdclk(struct intel_cdclk_state *cdclk_state)
/*
* Account for port clock min voltage level requirements.
- * This only really does something on CNL+ but can be
+ * This only really does something on DISPLA_VER >= 11 but can be
* called on earlier platforms as well.
*
* Note that this functions assumes that 0 is
@@ -2653,8 +2628,6 @@ void intel_update_max_cdclk(struct drm_i915_private *dev_priv)
dev_priv->max_cdclk_freq = 648000;
else
dev_priv->max_cdclk_freq = 652800;
- } else if (IS_CANNONLAKE(dev_priv)) {
- dev_priv->max_cdclk_freq = 528000;
} else if (IS_GEMINILAKE(dev_priv)) {
dev_priv->max_cdclk_freq = 316800;
} else if (IS_BROXTON(dev_priv)) {
@@ -2878,13 +2851,19 @@ u32 intel_read_rawclk(struct drm_i915_private *dev_priv)
*/
void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
{
- if (IS_ALDERLAKE_P(dev_priv)) {
+ if (IS_DG2(dev_priv)) {
+ dev_priv->display.set_cdclk = bxt_set_cdclk;
+ dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
+ dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
+ dev_priv->display.calc_voltage_level = tgl_calc_voltage_level;
+ dev_priv->cdclk.table = dg2_cdclk_table;
+ } else if (IS_ALDERLAKE_P(dev_priv)) {
dev_priv->display.set_cdclk = bxt_set_cdclk;
dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
dev_priv->display.calc_voltage_level = tgl_calc_voltage_level;
- /* Wa_22011320316:adlp[a0] */
- if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A0))
+ /* Wa_22011320316:adl-p[a0] */
+ if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0))
dev_priv->cdclk.table = adlp_a_step_cdclk_table;
else
dev_priv->cdclk.table = adlp_cdclk_table;
@@ -2912,12 +2891,6 @@ void intel_init_cdclk_hooks(struct drm_i915_private *dev_priv)
dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
dev_priv->display.calc_voltage_level = icl_calc_voltage_level;
dev_priv->cdclk.table = icl_cdclk_table;
- } else if (IS_CANNONLAKE(dev_priv)) {
- dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
- dev_priv->display.set_cdclk = bxt_set_cdclk;
- dev_priv->display.modeset_calc_cdclk = bxt_modeset_calc_cdclk;
- dev_priv->display.calc_voltage_level = cnl_calc_voltage_level;
- dev_priv->cdclk.table = cnl_cdclk_table;
} else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
dev_priv->display.bw_calc_min_cdclk = skl_bw_calc_min_cdclk;
dev_priv->display.set_cdclk = bxt_set_cdclk;
diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c
index dab892d2251b..afcb4bf3826c 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -305,13 +305,12 @@ static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
ilk_csc_postoff_limited_range);
} else if (crtc_state->csc_enable) {
/*
- * On GLK+ both pipe CSC and degamma LUT are controlled
+ * On GLK both pipe CSC and degamma LUT are controlled
* by csc_enable. Hence for the cases where the degama
* LUT is needed but CSC is not we need to load an
* identity matrix.
*/
- drm_WARN_ON(&dev_priv->drm, !IS_CANNONLAKE(dev_priv) &&
- !IS_GEMINILAKE(dev_priv));
+ drm_WARN_ON(&dev_priv->drm, !IS_GEMINILAKE(dev_priv));
ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
ilk_csc_coeff_identity,
diff --git a/drivers/gpu/drm/i915/display/intel_combo_phy.c b/drivers/gpu/drm/i915/display/intel_combo_phy.c
index 487c54cd5982..bacdf8a16bcb 100644
--- a/drivers/gpu/drm/i915/display/intel_combo_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_combo_phy.c
@@ -23,9 +23,9 @@ enum {
PROCMON_1_05V_DOT_1,
};
-static const struct cnl_procmon {
+static const struct icl_procmon {
u32 dw1, dw9, dw10;
-} cnl_procmon_values[] = {
+} icl_procmon_values[] = {
[PROCMON_0_85V_DOT_0] =
{ .dw1 = 0x00000000, .dw9 = 0x62AB67BB, .dw10 = 0x51914F96, },
[PROCMON_0_95V_DOT_0] =
@@ -38,15 +38,10 @@ static const struct cnl_procmon {
{ .dw1 = 0x00440000, .dw9 = 0x9A00AB25, .dw10 = 0x8AE38FF1, },
};
-/*
- * CNL has just one set of registers, while gen11 has a set for each combo PHY.
- * The CNL registers are equivalent to the gen11 PHY A registers, that's why we
- * call the ICL macros even though the function has CNL on its name.
- */
-static const struct cnl_procmon *
-cnl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum phy phy)
+static const struct icl_procmon *
+icl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum phy phy)
{
- const struct cnl_procmon *procmon;
+ const struct icl_procmon *procmon;
u32 val;
val = intel_de_read(dev_priv, ICL_PORT_COMP_DW3(phy));
@@ -55,32 +50,32 @@ cnl_get_procmon_ref_values(struct drm_i915_private *dev_priv, enum phy phy)
MISSING_CASE(val);
fallthrough;
case VOLTAGE_INFO_0_85V | PROCESS_INFO_DOT_0:
- procmon = &cnl_procmon_values[PROCMON_0_85V_DOT_0];
+ procmon = &icl_procmon_values[PROCMON_0_85V_DOT_0];
break;
case VOLTAGE_INFO_0_95V | PROCESS_INFO_DOT_0:
- procmon = &cnl_procmon_values[PROCMON_0_95V_DOT_0];
+ procmon = &icl_procmon_values[PROCMON_0_95V_DOT_0];
break;
case VOLTAGE_INFO_0_95V | PROCESS_INFO_DOT_1:
- procmon = &cnl_procmon_values[PROCMON_0_95V_DOT_1];
+ procmon = &icl_procmon_values[PROCMON_0_95V_DOT_1];
break;
case VOLTAGE_INFO_1_05V | PROCESS_INFO_DOT_0:
- procmon = &cnl_procmon_values[PROCMON_1_05V_DOT_0];
+ procmon = &icl_procmon_values[PROCMON_1_05V_DOT_0];
break;
case VOLTAGE_INFO_1_05V | PROCESS_INFO_DOT_1:
- procmon = &cnl_procmon_values[PROCMON_1_05V_DOT_1];
+ procmon = &icl_procmon_values[PROCMON_1_05V_DOT_1];
break;
}
return procmon;
}
-static void cnl_set_procmon_ref_values(struct drm_i915_private *dev_priv,
+static void icl_set_procmon_ref_values(struct drm_i915_private *dev_priv,
enum phy phy)
{
- const struct cnl_procmon *procmon;
+ const struct icl_procmon *procmon;
u32 val;
- procmon = cnl_get_procmon_ref_values(dev_priv, phy);
+ procmon = icl_get_procmon_ref_values(dev_priv, phy);
val = intel_de_read(dev_priv, ICL_PORT_COMP_DW1(phy));
val &= ~((0xff << 16) | 0xff);
@@ -109,13 +104,13 @@ static bool check_phy_reg(struct drm_i915_private *dev_priv,
return true;
}
-static bool cnl_verify_procmon_ref_values(struct drm_i915_private *dev_priv,
+static bool icl_verify_procmon_ref_values(struct drm_i915_private *dev_priv,
enum phy phy)
{
- const struct cnl_procmon *procmon;
+ const struct icl_procmon *procmon;
bool ret;
- procmon = cnl_get_procmon_ref_values(dev_priv, phy);
+ procmon = icl_get_procmon_ref_values(dev_priv, phy);
ret = check_phy_reg(dev_priv, phy, ICL_PORT_COMP_DW1(phy),
(0xff << 16) | 0xff, procmon->dw1);
@@ -127,61 +122,6 @@ static bool cnl_verify_procmon_ref_values(struct drm_i915_private *dev_priv,
return ret;
}
-static bool cnl_combo_phy_enabled(struct drm_i915_private *dev_priv)
-{
- return !(intel_de_read(dev_priv, CHICKEN_MISC_2) & CNL_COMP_PWR_DOWN) &&
- (intel_de_read(dev_priv, CNL_PORT_COMP_DW0) & COMP_INIT);
-}
-
-static bool cnl_combo_phy_verify_state(struct drm_i915_private *dev_priv)
-{
- enum phy phy = PHY_A;
- bool ret;
-
- if (!cnl_combo_phy_enabled(dev_priv))
- return false;
-
- ret = cnl_verify_procmon_ref_values(dev_priv, phy);
-
- ret &= check_phy_reg(dev_priv, phy, CNL_PORT_CL1CM_DW5,
- CL_POWER_DOWN_ENABLE, CL_POWER_DOWN_ENABLE);
-
- return ret;
-}
-
-static void cnl_combo_phys_init(struct drm_i915_private *dev_priv)
-{
- u32 val;
-
- val = intel_de_read(dev_priv, CHICKEN_MISC_2);
- val &= ~CNL_COMP_PWR_DOWN;
- intel_de_write(dev_priv, CHICKEN_MISC_2, val);
-
- /* Dummy PORT_A to get the correct CNL register from the ICL macro */
- cnl_set_procmon_ref_values(dev_priv, PHY_A);
-
- val = intel_de_read(dev_priv, CNL_PORT_COMP_DW0);
- val |= COMP_INIT;
- intel_de_write(dev_priv, CNL_PORT_COMP_DW0, val);
-
- val = intel_de_read(dev_priv, CNL_PORT_CL1CM_DW5);
- val |= CL_POWER_DOWN_ENABLE;
- intel_de_write(dev_priv, CNL_PORT_CL1CM_DW5, val);
-}
-
-static void cnl_combo_phys_uninit(struct drm_i915_private *dev_priv)
-{
- u32 val;
-
- if (!cnl_combo_phy_verify_state(dev_priv))
- drm_warn(&dev_priv->drm,
- "Combo PHY HW state changed unexpectedly.\n");
-
- val = intel_de_read(dev_priv, CHICKEN_MISC_2);
- val |= CNL_COMP_PWR_DOWN;
- intel_de_write(dev_priv, CHICKEN_MISC_2, val);
-}
-
static bool has_phy_misc(struct drm_i915_private *i915, enum phy phy)
{
/*
@@ -291,7 +231,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 &= icl_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),
@@ -415,7 +355,7 @@ skip_phy_misc:
intel_de_write(dev_priv, ICL_PORT_PCS_DW1_GRP(phy), val);
}
- cnl_set_procmon_ref_values(dev_priv, phy);
+ icl_set_procmon_ref_values(dev_priv, phy);
if (phy_is_master(dev_priv, phy)) {
val = intel_de_read(dev_priv, ICL_PORT_COMP_DW8(phy));
@@ -474,16 +414,10 @@ skip_phy_misc:
void intel_combo_phy_init(struct drm_i915_private *i915)
{
- if (DISPLAY_VER(i915) >= 11)
- icl_combo_phys_init(i915);
- else if (IS_CANNONLAKE(i915))
- cnl_combo_phys_init(i915);
+ icl_combo_phys_init(i915);
}
void intel_combo_phy_uninit(struct drm_i915_private *i915)
{
- if (DISPLAY_VER(i915) >= 11)
- icl_combo_phys_uninit(i915);
- else if (IS_CANNONLAKE(i915))
- cnl_combo_phys_uninit(i915);
+ icl_combo_phys_uninit(i915);
}
diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c
index 648f1c0d3d39..408f82b0dc7d 100644
--- a/drivers/gpu/drm/i915/display/intel_crt.c
+++ b/drivers/gpu/drm/i915/display/intel_crt.c
@@ -38,6 +38,7 @@
#include "intel_crt.h"
#include "intel_crtc.h"
#include "intel_ddi.h"
+#include "intel_ddi_buf_trans.h"
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_fdi.h"
@@ -1081,6 +1082,8 @@ void intel_crt_init(struct drm_i915_private *dev_priv)
crt->base.enable_clock = hsw_ddi_enable_clock;
crt->base.disable_clock = hsw_ddi_disable_clock;
crt->base.is_clock_enabled = hsw_ddi_is_clock_enabled;
+
+ intel_ddi_buf_trans_init(&crt->base);
} else {
if (HAS_PCH_SPLIT(dev_priv)) {
crt->base.compute_config = pch_crt_compute_config;
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
index 95ff1707b4bd..254e67141a77 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -163,12 +163,12 @@ static void intel_crtc_free(struct intel_crtc *crtc)
kfree(crtc);
}
-static void intel_crtc_destroy(struct drm_crtc *crtc)
+static void intel_crtc_destroy(struct drm_crtc *_crtc)
{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_crtc *crtc = to_intel_crtc(_crtc);
- drm_crtc_cleanup(crtc);
- kfree(intel_crtc);
+ drm_crtc_cleanup(&crtc->base);
+ kfree(crtc);
}
static int intel_crtc_late_register(struct drm_crtc *crtc)
@@ -335,7 +335,7 @@ int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
dev_priv->plane_to_crtc_mapping[i9xx_plane] = crtc;
}
- if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv))
+ if (DISPLAY_VER(dev_priv) >= 11)
drm_crtc_create_scaling_filter_property(&crtc->base,
BIT(DRM_SCALING_FILTER_DEFAULT) |
BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR));
diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
index 966e020331fb..c7618fef0143 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -383,7 +383,7 @@ static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state,
if (plane_state->hw.rotation & DRM_MODE_ROTATE_180)
cntl |= MCURSOR_ROTATE_180;
- /* Wa_22012358565:adlp */
+ /* Wa_22012358565:adl-p */
if (DISPLAY_VER(dev_priv) == 13)
cntl |= MCURSOR_ARB_SLOTS(1);
@@ -629,12 +629,16 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
/*
* When crtc is inactive or there is a modeset pending,
- * wait for it to complete in the slowpath
+ * wait for it to complete in the slowpath.
+ * PSR2 selective fetch also requires the slow path as
+ * PSR2 plane and transcoder registers can only be updated during
+ * vblank.
*
* FIXME bigjoiner fastpath would be good
*/
if (!crtc_state->hw.active || intel_crtc_needs_modeset(crtc_state) ||
- crtc_state->update_pipe || crtc_state->bigjoiner)
+ crtc_state->update_pipe || crtc_state->bigjoiner ||
+ crtc_state->enable_psr2_sel_fetch)
goto slow;
/*
@@ -801,7 +805,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
if (DISPLAY_VER(dev_priv) >= 12)
drm_plane_enable_fb_damage_clips(&cursor->base);
- drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs);
+ intel_plane_helper_add(cursor);
return cursor;
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 00dade49665b..9903a78df896 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -51,6 +51,7 @@
#include "intel_panel.h"
#include "intel_pps.h"
#include "intel_psr.h"
+#include "intel_snps_phy.h"
#include "intel_sprite.h"
#include "intel_tc.h"
#include "intel_vdsc.h"
@@ -95,24 +96,18 @@ static int intel_ddi_hdmi_level(struct intel_encoder *encoder,
* values in advance. This function programs the correct values for
* DP/eDP/FDI use cases.
*/
-void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state)
+void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
u32 iboost_bit = 0;
int i, n_entries;
enum port port = encoder->port;
- const struct ddi_buf_trans *ddi_translations;
-
- if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG))
- ddi_translations = intel_ddi_get_buf_trans_fdi(dev_priv,
- &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);
+ const struct intel_ddi_buf_trans *ddi_translations;
+
+ ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries);
+ if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations))
+ return;
/* If we're boosting the current, set bit 31 of trans1 */
if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv) &&
@@ -121,9 +116,9 @@ void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder,
for (i = 0; i < n_entries; i++) {
intel_de_write(dev_priv, DDI_BUF_TRANS_LO(port, i),
- ddi_translations[i].trans1 | iboost_bit);
+ ddi_translations->entries[i].hsw.trans1 | iboost_bit);
intel_de_write(dev_priv, DDI_BUF_TRANS_HI(port, i),
- ddi_translations[i].trans2);
+ ddi_translations->entries[i].hsw.trans2);
}
}
@@ -132,17 +127,17 @@ void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder,
* values in advance. This function programs the correct values for
* HDMI/DVI use cases.
*/
-static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder,
- int level)
+static void hsw_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int level)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
u32 iboost_bit = 0;
int n_entries;
enum port port = encoder->port;
- const struct ddi_buf_trans *ddi_translations;
-
- ddi_translations = intel_ddi_get_buf_trans_hdmi(encoder, &n_entries);
+ const struct intel_ddi_buf_trans *ddi_translations;
+ ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries);
if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations))
return;
if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries))
@@ -155,9 +150,9 @@ static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder,
/* Entry 9 is for HDMI: */
intel_de_write(dev_priv, DDI_BUF_TRANS_LO(port, 9),
- ddi_translations[level].trans1 | iboost_bit);
+ ddi_translations->entries[level].hsw.trans1 | iboost_bit);
intel_de_write(dev_priv, DDI_BUF_TRANS_HI(port, 9),
- ddi_translations[level].trans2);
+ ddi_translations->entries[level].hsw.trans2);
}
void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
@@ -177,14 +172,18 @@ void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
static void intel_wait_ddi_buf_active(struct drm_i915_private *dev_priv,
enum port port)
{
+ int ret;
+
/* Wait > 518 usecs for DDI_BUF_CTL to be non idle */
if (DISPLAY_VER(dev_priv) < 10) {
usleep_range(518, 1000);
return;
}
- if (wait_for_us(!(intel_de_read(dev_priv, DDI_BUF_CTL(port)) &
- DDI_BUF_IS_IDLE), 500))
+ ret = _wait_for(!(intel_de_read(dev_priv, DDI_BUF_CTL(port)) &
+ DDI_BUF_IS_IDLE), IS_DG2(dev_priv) ? 1200 : 500, 10, 10);
+
+ if (ret)
drm_err(&dev_priv->drm, "Timeout waiting for DDI BUF %c to get active\n",
port_name(port));
}
@@ -828,7 +827,7 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
static enum intel_display_power_domain
intel_ddi_main_link_aux_domain(struct intel_digital_port *dig_port)
{
- /* CNL+ HW requires corresponding AUX IOs to be powered up for PSR with
+ /* ICL+ HW requires corresponding AUX IOs to be powered up for PSR with
* DC states enabled at the same time, while for driver initiated AUX
* transfers we need the same AUX IOs to be powered but with DC states
* disabled. Accordingly use the AUX power domain here which leaves DC
@@ -948,22 +947,16 @@ static void skl_ddi_set_iboost(struct intel_encoder *encoder,
iboost = intel_bios_encoder_dp_boost_level(encoder->devdata);
if (iboost == 0) {
- const struct ddi_buf_trans *ddi_translations;
+ const struct intel_ddi_buf_trans *ddi_translations;
int n_entries;
- if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
- ddi_translations = intel_ddi_get_buf_trans_hdmi(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 = encoder->get_buf_trans(encoder, crtc_state, &n_entries);
if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations))
return;
if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries))
level = n_entries - 1;
- iboost = ddi_translations[level].i_boost;
+ iboost = ddi_translations->entries[level].hsw.i_boost;
}
/* Make sure that the requested I_boost is valid */
@@ -983,21 +976,21 @@ static void bxt_ddi_vswing_sequence(struct intel_encoder *encoder,
int level)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- const struct bxt_ddi_buf_trans *ddi_translations;
+ const struct intel_ddi_buf_trans *ddi_translations;
enum port port = encoder->port;
int n_entries;
- ddi_translations = bxt_get_buf_trans(encoder, crtc_state, &n_entries);
+ ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries);
if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations))
return;
if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries))
level = n_entries - 1;
bxt_ddi_phy_set_signal_level(dev_priv, port,
- ddi_translations[level].margin,
- ddi_translations[level].scale,
- ddi_translations[level].enable,
- ddi_translations[level].deemphasis);
+ ddi_translations->entries[level].bxt.margin,
+ ddi_translations->entries[level].bxt.scale,
+ ddi_translations->entries[level].bxt.enable,
+ ddi_translations->entries[level].bxt.deemphasis);
}
static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp,
@@ -1005,36 +998,9 @@ static u8 intel_ddi_dp_voltage_max(struct intel_dp *intel_dp,
{
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;
- enum phy phy = intel_port_to_phy(dev_priv, port);
int n_entries;
- if (DISPLAY_VER(dev_priv) >= 12) {
- if (intel_phy_is_combo(dev_priv, phy))
- tgl_get_combo_buf_trans(encoder, crtc_state, &n_entries);
- else if (IS_ALDERLAKE_P(dev_priv))
- adlp_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
- else
- tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
- } else if (DISPLAY_VER(dev_priv) == 11) {
- 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, crtc_state, &n_entries);
- else
- icl_get_mg_buf_trans(encoder, crtc_state, &n_entries);
- } else if (IS_CANNONLAKE(dev_priv)) {
- cnl_get_buf_trans(encoder, crtc_state, &n_entries);
- } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
- bxt_get_buf_trans(encoder, crtc_state, &n_entries);
- } else {
- 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);
- }
+ encoder->get_buf_trans(encoder, crtc_state, &n_entries);
if (drm_WARN_ON(&dev_priv->drm, n_entries < 1))
n_entries = 1;
@@ -1056,146 +1022,17 @@ static u8 intel_ddi_dp_preemph_max(struct intel_dp *intel_dp)
return DP_TRAIN_PRE_EMPH_LEVEL_3;
}
-static void cnl_ddi_vswing_program(struct intel_encoder *encoder,
- 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 port port = encoder->port;
- int n_entries, ln;
- u32 val;
-
- ddi_translations = cnl_get_buf_trans(encoder, crtc_state, &n_entries);
-
- if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations))
- return;
- if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries))
- level = n_entries - 1;
-
- /* Set PORT_TX_DW5 Scaling Mode Sel to 010b. */
- val = intel_de_read(dev_priv, CNL_PORT_TX_DW5_LN0(port));
- val &= ~SCALING_MODE_SEL_MASK;
- val |= SCALING_MODE_SEL(2);
- intel_de_write(dev_priv, CNL_PORT_TX_DW5_GRP(port), val);
-
- /* Program PORT_TX_DW2 */
- val = intel_de_read(dev_priv, CNL_PORT_TX_DW2_LN0(port));
- val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
- RCOMP_SCALAR_MASK);
- val |= SWING_SEL_UPPER(ddi_translations[level].dw2_swing_sel);
- val |= SWING_SEL_LOWER(ddi_translations[level].dw2_swing_sel);
- /* Rcomp scalar is fixed as 0x98 for every table entry */
- val |= RCOMP_SCALAR(0x98);
- intel_de_write(dev_priv, CNL_PORT_TX_DW2_GRP(port), val);
-
- /* Program PORT_TX_DW4 */
- /* We cannot write to GRP. It would overrite individual loadgen */
- for (ln = 0; ln < 4; ln++) {
- val = intel_de_read(dev_priv, CNL_PORT_TX_DW4_LN(ln, port));
- val &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
- CURSOR_COEFF_MASK);
- val |= POST_CURSOR_1(ddi_translations[level].dw4_post_cursor_1);
- val |= POST_CURSOR_2(ddi_translations[level].dw4_post_cursor_2);
- val |= CURSOR_COEFF(ddi_translations[level].dw4_cursor_coeff);
- intel_de_write(dev_priv, CNL_PORT_TX_DW4_LN(ln, port), val);
- }
-
- /* Program PORT_TX_DW5 */
- /* All DW5 values are fixed for every table entry */
- val = intel_de_read(dev_priv, CNL_PORT_TX_DW5_LN0(port));
- val &= ~RTERM_SELECT_MASK;
- val |= RTERM_SELECT(6);
- val |= TAP3_DISABLE;
- intel_de_write(dev_priv, CNL_PORT_TX_DW5_GRP(port), val);
-
- /* Program PORT_TX_DW7 */
- val = intel_de_read(dev_priv, CNL_PORT_TX_DW7_LN0(port));
- val &= ~N_SCALAR_MASK;
- val |= N_SCALAR(ddi_translations[level].dw7_n_scalar);
- intel_de_write(dev_priv, CNL_PORT_TX_DW7_GRP(port), val);
-}
-
-static void cnl_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 port port = encoder->port;
- int width, rate, ln;
- u32 val;
-
- width = crtc_state->lane_count;
- rate = crtc_state->port_clock;
-
- /*
- * 1. If port type is eDP or DP,
- * set PORT_PCS_DW1 cmnkeeper_enable to 1b,
- * else clear to 0b.
- */
- val = intel_de_read(dev_priv, CNL_PORT_PCS_DW1_LN0(port));
- 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 */
- /*
- * Program PORT_TX_DW4_LN depending on Bit rate and used lanes
- * <= 6 GHz and 4 lanes (LN0=0, LN1=1, LN2=1, LN3=1)
- * <= 6 GHz and 1,2 lanes (LN0=0, LN1=1, LN2=1, LN3=0)
- * > 6 GHz (LN0=0, LN1=0, LN2=0, LN3=0)
- */
- for (ln = 0; ln <= 3; ln++) {
- val = intel_de_read(dev_priv, CNL_PORT_TX_DW4_LN(ln, port));
- val &= ~LOADGEN_SELECT;
-
- if ((rate <= 600000 && width == 4 && ln >= 1) ||
- (rate <= 600000 && width < 4 && (ln == 1 || ln == 2))) {
- val |= LOADGEN_SELECT;
- }
- intel_de_write(dev_priv, CNL_PORT_TX_DW4_LN(ln, port), val);
- }
-
- /* 3. Set PORT_CL_DW5 SUS Clock Config to 11b */
- val = intel_de_read(dev_priv, CNL_PORT_CL1CM_DW5);
- val |= SUS_CLOCK_CONFIG;
- intel_de_write(dev_priv, CNL_PORT_CL1CM_DW5, val);
-
- /* 4. Clear training enable to change swing values */
- val = intel_de_read(dev_priv, CNL_PORT_TX_DW5_LN0(port));
- val &= ~TX_TRAINING_EN;
- intel_de_write(dev_priv, CNL_PORT_TX_DW5_GRP(port), val);
-
- /* 5. Program swing and de-emphasis */
- 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));
- val |= TX_TRAINING_EN;
- intel_de_write(dev_priv, CNL_PORT_TX_DW5_GRP(port), val);
-}
-
static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
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;
+ const struct intel_ddi_buf_trans *ddi_translations;
enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
int n_entries, ln;
u32 val;
- if (DISPLAY_VER(dev_priv) >= 12)
- 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, crtc_state, &n_entries);
-
+ ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries);
if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations))
return;
if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries))
@@ -1223,8 +1060,8 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
val = intel_de_read(dev_priv, ICL_PORT_TX_DW2_LN0(phy));
val &= ~(SWING_SEL_LOWER_MASK | SWING_SEL_UPPER_MASK |
RCOMP_SCALAR_MASK);
- val |= SWING_SEL_UPPER(ddi_translations[level].dw2_swing_sel);
- val |= SWING_SEL_LOWER(ddi_translations[level].dw2_swing_sel);
+ val |= SWING_SEL_UPPER(ddi_translations->entries[level].icl.dw2_swing_sel);
+ val |= SWING_SEL_LOWER(ddi_translations->entries[level].icl.dw2_swing_sel);
/* Program Rcomp scalar for every table entry */
val |= RCOMP_SCALAR(0x98);
intel_de_write(dev_priv, ICL_PORT_TX_DW2_GRP(phy), val);
@@ -1235,16 +1072,16 @@ static void icl_ddi_combo_vswing_program(struct intel_encoder *encoder,
val = intel_de_read(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy));
val &= ~(POST_CURSOR_1_MASK | POST_CURSOR_2_MASK |
CURSOR_COEFF_MASK);
- val |= POST_CURSOR_1(ddi_translations[level].dw4_post_cursor_1);
- val |= POST_CURSOR_2(ddi_translations[level].dw4_post_cursor_2);
- val |= CURSOR_COEFF(ddi_translations[level].dw4_cursor_coeff);
+ val |= POST_CURSOR_1(ddi_translations->entries[level].icl.dw4_post_cursor_1);
+ val |= POST_CURSOR_2(ddi_translations->entries[level].icl.dw4_post_cursor_2);
+ val |= CURSOR_COEFF(ddi_translations->entries[level].icl.dw4_cursor_coeff);
intel_de_write(dev_priv, ICL_PORT_TX_DW4_LN(ln, phy), val);
}
/* Program PORT_TX_DW7 */
val = intel_de_read(dev_priv, ICL_PORT_TX_DW7_LN0(phy));
val &= ~N_SCALAR_MASK;
- val |= N_SCALAR(ddi_translations[level].dw7_n_scalar);
+ val |= N_SCALAR(ddi_translations->entries[level].icl.dw7_n_scalar);
intel_de_write(dev_priv, ICL_PORT_TX_DW7_GRP(phy), val);
}
@@ -1315,15 +1152,14 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
{
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;
+ const struct intel_ddi_buf_trans *ddi_translations;
int n_entries, ln;
u32 val;
if (enc_to_dig_port(encoder)->tc_mode == TC_PORT_TBT_ALT)
return;
- ddi_translations = icl_get_mg_buf_trans(encoder, crtc_state, &n_entries);
-
+ ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries);
if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations))
return;
if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries))
@@ -1345,13 +1181,13 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
val = intel_de_read(dev_priv, MG_TX1_SWINGCTRL(ln, tc_port));
val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK;
val |= CRI_TXDEEMPH_OVERRIDE_17_12(
- ddi_translations[level].cri_txdeemph_override_17_12);
+ ddi_translations->entries[level].mg.cri_txdeemph_override_17_12);
intel_de_write(dev_priv, MG_TX1_SWINGCTRL(ln, tc_port), val);
val = intel_de_read(dev_priv, MG_TX2_SWINGCTRL(ln, tc_port));
val &= ~CRI_TXDEEMPH_OVERRIDE_17_12_MASK;
val |= CRI_TXDEEMPH_OVERRIDE_17_12(
- ddi_translations[level].cri_txdeemph_override_17_12);
+ ddi_translations->entries[level].mg.cri_txdeemph_override_17_12);
intel_de_write(dev_priv, MG_TX2_SWINGCTRL(ln, tc_port), val);
}
@@ -1361,9 +1197,9 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK |
CRI_TXDEEMPH_OVERRIDE_5_0_MASK);
val |= CRI_TXDEEMPH_OVERRIDE_5_0(
- ddi_translations[level].cri_txdeemph_override_5_0) |
+ ddi_translations->entries[level].mg.cri_txdeemph_override_5_0) |
CRI_TXDEEMPH_OVERRIDE_11_6(
- ddi_translations[level].cri_txdeemph_override_11_6) |
+ ddi_translations->entries[level].mg.cri_txdeemph_override_11_6) |
CRI_TXDEEMPH_OVERRIDE_EN;
intel_de_write(dev_priv, MG_TX1_DRVCTRL(ln, tc_port), val);
@@ -1371,9 +1207,9 @@ static void icl_mg_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
val &= ~(CRI_TXDEEMPH_OVERRIDE_11_6_MASK |
CRI_TXDEEMPH_OVERRIDE_5_0_MASK);
val |= CRI_TXDEEMPH_OVERRIDE_5_0(
- ddi_translations[level].cri_txdeemph_override_5_0) |
+ ddi_translations->entries[level].mg.cri_txdeemph_override_5_0) |
CRI_TXDEEMPH_OVERRIDE_11_6(
- ddi_translations[level].cri_txdeemph_override_11_6) |
+ ddi_translations->entries[level].mg.cri_txdeemph_override_11_6) |
CRI_TXDEEMPH_OVERRIDE_EN;
intel_de_write(dev_priv, MG_TX2_DRVCTRL(ln, tc_port), val);
@@ -1453,18 +1289,14 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
{
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;
+ const struct intel_ddi_buf_trans *ddi_translations;
u32 val, dpcnt_mask, dpcnt_val;
int n_entries, ln;
if (enc_to_dig_port(encoder)->tc_mode == TC_PORT_TBT_ALT)
return;
- if (IS_ALDERLAKE_P(dev_priv))
- ddi_translations = adlp_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
- else
- ddi_translations = tgl_get_dkl_buf_trans(encoder, crtc_state, &n_entries);
-
+ ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries);
if (drm_WARN_ON_ONCE(&dev_priv->drm, !ddi_translations))
return;
if (drm_WARN_ON_ONCE(&dev_priv->drm, level >= n_entries))
@@ -1473,9 +1305,9 @@ tgl_dkl_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
dpcnt_mask = (DKL_TX_PRESHOOT_COEFF_MASK |
DKL_TX_DE_EMPAHSIS_COEFF_MASK |
DKL_TX_VSWING_CONTROL_MASK);
- dpcnt_val = DKL_TX_VSWING_CONTROL(ddi_translations[level].dkl_vswing_control);
- dpcnt_val |= DKL_TX_DE_EMPHASIS_COEFF(ddi_translations[level].dkl_de_emphasis_control);
- dpcnt_val |= DKL_TX_PRESHOOT_COEFF(ddi_translations[level].dkl_preshoot_control);
+ dpcnt_val = DKL_TX_VSWING_CONTROL(ddi_translations->entries[level].dkl.dkl_vswing_control);
+ dpcnt_val |= DKL_TX_DE_EMPHASIS_COEFF(ddi_translations->entries[level].dkl.dkl_de_emphasis_control);
+ dpcnt_val |= DKL_TX_PRESHOOT_COEFF(ddi_translations->entries[level].dkl.dkl_preshoot_control);
for (ln = 0; ln < 2; ln++) {
intel_de_write(dev_priv, HIP_INDEX_REG(tc_port),
@@ -1549,33 +1381,33 @@ static int intel_ddi_dp_level(struct intel_dp *intel_dp)
}
static void
-tgl_set_signal_levels(struct intel_dp *intel_dp,
+dg2_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, crtc_state, level);
+ intel_snps_phy_ddi_vswing_sequence(encoder, level);
}
static void
-icl_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);
- icl_ddi_vswing_sequence(encoder, crtc_state, level);
+ tgl_ddi_vswing_sequence(encoder, crtc_state, level);
}
static void
-cnl_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);
- cnl_ddi_vswing_sequence(encoder, crtc_state, level);
+ icl_ddi_vswing_sequence(encoder, crtc_state, level);
}
static void
@@ -1613,7 +1445,7 @@ hsw_set_signal_levels(struct intel_dp *intel_dp,
intel_de_posting_read(dev_priv, DDI_BUF_CTL(port));
}
-static void _cnl_ddi_enable_clock(struct drm_i915_private *i915, i915_reg_t reg,
+static void _icl_ddi_enable_clock(struct drm_i915_private *i915, i915_reg_t reg,
u32 clk_sel_mask, u32 clk_sel, u32 clk_off)
{
mutex_lock(&i915->dpll.lock);
@@ -1629,7 +1461,7 @@ static void _cnl_ddi_enable_clock(struct drm_i915_private *i915, i915_reg_t reg,
mutex_unlock(&i915->dpll.lock);
}
-static void _cnl_ddi_disable_clock(struct drm_i915_private *i915, i915_reg_t reg,
+static void _icl_ddi_disable_clock(struct drm_i915_private *i915, i915_reg_t reg,
u32 clk_off)
{
mutex_lock(&i915->dpll.lock);
@@ -1639,14 +1471,14 @@ static void _cnl_ddi_disable_clock(struct drm_i915_private *i915, i915_reg_t reg
mutex_unlock(&i915->dpll.lock);
}
-static bool _cnl_ddi_is_clock_enabled(struct drm_i915_private *i915, i915_reg_t reg,
+static bool _icl_ddi_is_clock_enabled(struct drm_i915_private *i915, i915_reg_t reg,
u32 clk_off)
{
return !(intel_de_read(i915, reg) & clk_off);
}
static struct intel_shared_dpll *
-_cnl_ddi_get_pll(struct drm_i915_private *i915, i915_reg_t reg,
+_icl_ddi_get_pll(struct drm_i915_private *i915, i915_reg_t reg,
u32 clk_sel_mask, u32 clk_sel_shift)
{
enum intel_dpll_id id;
@@ -1666,7 +1498,7 @@ static void adls_ddi_enable_clock(struct intel_encoder *encoder,
if (drm_WARN_ON(&i915->drm, !pll))
return;
- _cnl_ddi_enable_clock(i915, ADLS_DPCLKA_CFGCR(phy),
+ _icl_ddi_enable_clock(i915, ADLS_DPCLKA_CFGCR(phy),
ADLS_DPCLKA_CFGCR_DDI_CLK_SEL_MASK(phy),
pll->info->id << ADLS_DPCLKA_CFGCR_DDI_SHIFT(phy),
ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
@@ -1677,7 +1509,7 @@ static void adls_ddi_disable_clock(struct intel_encoder *encoder)
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(i915, encoder->port);
- _cnl_ddi_disable_clock(i915, ADLS_DPCLKA_CFGCR(phy),
+ _icl_ddi_disable_clock(i915, ADLS_DPCLKA_CFGCR(phy),
ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
}
@@ -1686,7 +1518,7 @@ static bool adls_ddi_is_clock_enabled(struct intel_encoder *encoder)
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(i915, encoder->port);
- return _cnl_ddi_is_clock_enabled(i915, ADLS_DPCLKA_CFGCR(phy),
+ return _icl_ddi_is_clock_enabled(i915, ADLS_DPCLKA_CFGCR(phy),
ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
}
@@ -1695,7 +1527,7 @@ static struct intel_shared_dpll *adls_ddi_get_pll(struct intel_encoder *encoder)
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(i915, encoder->port);
- return _cnl_ddi_get_pll(i915, ADLS_DPCLKA_CFGCR(phy),
+ return _icl_ddi_get_pll(i915, ADLS_DPCLKA_CFGCR(phy),
ADLS_DPCLKA_CFGCR_DDI_CLK_SEL_MASK(phy),
ADLS_DPCLKA_CFGCR_DDI_SHIFT(phy));
}
@@ -1710,7 +1542,7 @@ static void rkl_ddi_enable_clock(struct intel_encoder *encoder,
if (drm_WARN_ON(&i915->drm, !pll))
return;
- _cnl_ddi_enable_clock(i915, ICL_DPCLKA_CFGCR0,
+ _icl_ddi_enable_clock(i915, ICL_DPCLKA_CFGCR0,
RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy),
RKL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy),
RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
@@ -1721,7 +1553,7 @@ static void rkl_ddi_disable_clock(struct intel_encoder *encoder)
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(i915, encoder->port);
- _cnl_ddi_disable_clock(i915, ICL_DPCLKA_CFGCR0,
+ _icl_ddi_disable_clock(i915, ICL_DPCLKA_CFGCR0,
RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
}
@@ -1730,7 +1562,7 @@ static bool rkl_ddi_is_clock_enabled(struct intel_encoder *encoder)
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(i915, encoder->port);
- return _cnl_ddi_is_clock_enabled(i915, ICL_DPCLKA_CFGCR0,
+ return _icl_ddi_is_clock_enabled(i915, ICL_DPCLKA_CFGCR0,
RKL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
}
@@ -1739,7 +1571,7 @@ static struct intel_shared_dpll *rkl_ddi_get_pll(struct intel_encoder *encoder)
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(i915, encoder->port);
- return _cnl_ddi_get_pll(i915, ICL_DPCLKA_CFGCR0,
+ return _icl_ddi_get_pll(i915, ICL_DPCLKA_CFGCR0,
RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy),
RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy));
}
@@ -1763,7 +1595,7 @@ static void dg1_ddi_enable_clock(struct intel_encoder *encoder,
(pll->info->id >= DPLL_ID_DG1_DPLL2 && phy < PHY_C)))
return;
- _cnl_ddi_enable_clock(i915, DG1_DPCLKA_CFGCR0(phy),
+ _icl_ddi_enable_clock(i915, DG1_DPCLKA_CFGCR0(phy),
DG1_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy),
DG1_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy),
DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
@@ -1774,7 +1606,7 @@ static void dg1_ddi_disable_clock(struct intel_encoder *encoder)
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(i915, encoder->port);
- _cnl_ddi_disable_clock(i915, DG1_DPCLKA_CFGCR0(phy),
+ _icl_ddi_disable_clock(i915, DG1_DPCLKA_CFGCR0(phy),
DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
}
@@ -1783,7 +1615,7 @@ static bool dg1_ddi_is_clock_enabled(struct intel_encoder *encoder)
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(i915, encoder->port);
- return _cnl_ddi_is_clock_enabled(i915, DG1_DPCLKA_CFGCR0(phy),
+ return _icl_ddi_is_clock_enabled(i915, DG1_DPCLKA_CFGCR0(phy),
DG1_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
}
@@ -1820,7 +1652,7 @@ static void icl_ddi_combo_enable_clock(struct intel_encoder *encoder,
if (drm_WARN_ON(&i915->drm, !pll))
return;
- _cnl_ddi_enable_clock(i915, ICL_DPCLKA_CFGCR0,
+ _icl_ddi_enable_clock(i915, ICL_DPCLKA_CFGCR0,
ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy),
ICL_DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, phy),
ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
@@ -1831,7 +1663,7 @@ static void icl_ddi_combo_disable_clock(struct intel_encoder *encoder)
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(i915, encoder->port);
- _cnl_ddi_disable_clock(i915, ICL_DPCLKA_CFGCR0,
+ _icl_ddi_disable_clock(i915, ICL_DPCLKA_CFGCR0,
ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
}
@@ -1840,7 +1672,7 @@ static bool icl_ddi_combo_is_clock_enabled(struct intel_encoder *encoder)
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(i915, encoder->port);
- return _cnl_ddi_is_clock_enabled(i915, ICL_DPCLKA_CFGCR0,
+ return _icl_ddi_is_clock_enabled(i915, ICL_DPCLKA_CFGCR0,
ICL_DPCLKA_CFGCR0_DDI_CLK_OFF(phy));
}
@@ -1849,7 +1681,7 @@ struct intel_shared_dpll *icl_ddi_combo_get_pll(struct intel_encoder *encoder)
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
enum phy phy = intel_port_to_phy(i915, encoder->port);
- return _cnl_ddi_get_pll(i915, ICL_DPCLKA_CFGCR0,
+ return _icl_ddi_get_pll(i915, ICL_DPCLKA_CFGCR0,
ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy),
ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy));
}
@@ -1982,50 +1814,6 @@ static struct intel_shared_dpll *icl_ddi_tc_get_pll(struct intel_encoder *encode
return intel_get_shared_dpll_by_id(i915, id);
}
-static void cnl_ddi_enable_clock(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state)
-{
- struct drm_i915_private *i915 = to_i915(encoder->base.dev);
- const struct intel_shared_dpll *pll = crtc_state->shared_dpll;
- enum port port = encoder->port;
-
- if (drm_WARN_ON(&i915->drm, !pll))
- return;
-
- _cnl_ddi_enable_clock(i915, DPCLKA_CFGCR0,
- DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port),
- DPCLKA_CFGCR0_DDI_CLK_SEL(pll->info->id, port),
- DPCLKA_CFGCR0_DDI_CLK_OFF(port));
-}
-
-static void cnl_ddi_disable_clock(struct intel_encoder *encoder)
-{
- struct drm_i915_private *i915 = to_i915(encoder->base.dev);
- enum port port = encoder->port;
-
- _cnl_ddi_disable_clock(i915, DPCLKA_CFGCR0,
- DPCLKA_CFGCR0_DDI_CLK_OFF(port));
-}
-
-static bool cnl_ddi_is_clock_enabled(struct intel_encoder *encoder)
-{
- struct drm_i915_private *i915 = to_i915(encoder->base.dev);
- enum port port = encoder->port;
-
- return _cnl_ddi_is_clock_enabled(i915, DPCLKA_CFGCR0,
- DPCLKA_CFGCR0_DDI_CLK_OFF(port));
-}
-
-static struct intel_shared_dpll *cnl_ddi_get_pll(struct intel_encoder *encoder)
-{
- struct drm_i915_private *i915 = to_i915(encoder->base.dev);
- enum port port = encoder->port;
-
- return _cnl_ddi_get_pll(i915, DPCLKA_CFGCR0,
- DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(port),
- DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(port));
-}
-
static struct intel_shared_dpll *bxt_ddi_get_pll(struct intel_encoder *encoder)
{
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
@@ -2249,7 +2037,7 @@ void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder)
ddi_clk_needed = false;
}
- if (ddi_clk_needed || !encoder->disable_clock ||
+ if (ddi_clk_needed || !encoder->is_clock_enabled ||
!encoder->is_clock_enabled(encoder))
return;
@@ -2534,6 +2322,116 @@ static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state)
OVERLAP_PIXELS_MASK, dss1);
}
+static void dg2_ddi_pre_enable_dp(struct intel_atomic_state *state,
+ struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ const struct drm_connector_state *conn_state)
+{
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
+ 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);
+
+ intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
+ crtc_state->lane_count);
+
+ /*
+ * 1. Enable Power Wells
+ *
+ * This was handled at the beginning of intel_atomic_commit_tail(),
+ * before we called down into this function.
+ */
+
+ /* 2. Enable Panel Power if PPS is required */
+ intel_pps_on(intel_dp);
+
+ /*
+ * 3. Enable the port PLL.
+ */
+ intel_ddi_enable_clock(encoder, crtc_state);
+
+ /* 4. Enable IO power */
+ if (!intel_phy_is_tc(dev_priv, phy) ||
+ dig_port->tc_mode != TC_PORT_TBT_ALT)
+ dig_port->ddi_io_wakeref = intel_display_power_get(dev_priv,
+ dig_port->ddi_io_power_domain);
+
+ /*
+ * 5. The rest of the below are substeps under the bspec's "Enable and
+ * Train Display Port" step. Note that steps that are specific to
+ * MST will be handled by intel_mst_pre_enable_dp() before/after it
+ * calls into this function. Also intel_mst_pre_enable_dp() only calls
+ * us when active_mst_links==0, so any steps designated for "single
+ * stream or multi-stream master transcoder" can just be performed
+ * unconditionally here.
+ */
+
+ /*
+ * 5.a Configure Transcoder Clock Select to direct the Port clock to the
+ * Transcoder.
+ */
+ intel_ddi_enable_pipe_clock(encoder, crtc_state);
+
+ /* 5.b Not relevant to i915 for now */
+
+ /*
+ * 5.c Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST
+ * Transport Select
+ */
+ intel_ddi_config_transcoder_func(encoder, crtc_state);
+
+ /*
+ * 5.d Configure & enable DP_TP_CTL with link training pattern 1
+ * selected
+ *
+ * This will be handled by the intel_dp_start_link_train() farther
+ * down this function.
+ */
+
+ /* 5.e Configure voltage swing and related IO settings */
+ intel_snps_phy_ddi_vswing_sequence(encoder, level);
+
+ /*
+ * 5.f Configure and enable DDI_BUF_CTL
+ * 5.g Wait for DDI_BUF_CTL DDI Idle Status = 0b (Not Idle), timeout
+ * after 1200 us.
+ *
+ * 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, crtc_state);
+
+ if (!is_mst)
+ intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
+
+ intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true);
+ /*
+ * DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
+ * in the FEC_CONFIGURATION register to 1 before initiating link
+ * training
+ */
+ intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
+
+ /*
+ * 5.h Follow DisplayPort specification training sequence (see notes for
+ * failure handling)
+ * 5.i If DisplayPort multi-stream - Set DP_TP_CTL link training to Idle
+ * Pattern, wait for 5 idle patterns (DP_TP_STATUS Min_Idles_Sent)
+ * (timeout after 800 us)
+ */
+ intel_dp_start_link_train(intel_dp, crtc_state);
+
+ /* 5.j Set DP_TP_CTL link training to Normal */
+ if (!is_trans_port_sync_mode(crtc_state))
+ intel_dp_stop_link_train(intel_dp, crtc_state);
+
+ /* 5.k Configure and enable FEC if needed */
+ intel_ddi_enable_fec(encoder, crtc_state);
+ intel_dsc_enable(encoder, crtc_state);
+}
+
static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
@@ -2714,12 +2612,10 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
if (DISPLAY_VER(dev_priv) >= 11)
icl_ddi_vswing_sequence(encoder, crtc_state, level);
- else if (IS_CANNONLAKE(dev_priv))
- cnl_ddi_vswing_sequence(encoder, crtc_state, level);
else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
bxt_ddi_vswing_sequence(encoder, crtc_state, level);
else
- intel_prepare_dp_ddi_buffers(encoder, crtc_state);
+ hsw_prepare_dp_ddi_buffers(encoder, crtc_state);
intel_ddi_power_up_lanes(encoder, crtc_state);
@@ -2751,7 +2647,9 @@ static void intel_ddi_pre_enable_dp(struct intel_atomic_state *state,
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- if (DISPLAY_VER(dev_priv) >= 12)
+ if (IS_DG2(dev_priv))
+ dg2_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
+ else if (DISPLAY_VER(dev_priv) >= 12)
tgl_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
else
hsw_ddi_pre_enable_dp(state, encoder, crtc_state, conn_state);
@@ -2827,6 +2725,7 @@ static void intel_ddi_pre_enable(struct intel_atomic_state *state,
conn_state);
/* FIXME precompute everything properly */
+ /* FIXME how do we turn infoframes off again? */
if (dig_port->lspcon.active && dig_port->dp.has_hdmi_sink)
dig_port->set_infoframes(encoder,
crtc_state->has_infoframe,
@@ -3157,16 +3056,16 @@ static void intel_enable_ddi_hdmi(struct intel_atomic_state *state,
"[CONNECTOR:%d:%s] Failed to configure sink scrambling/TMDS bit clock ratio\n",
connector->base.id, connector->name);
- if (DISPLAY_VER(dev_priv) >= 12)
+ if (IS_DG2(dev_priv))
+ intel_snps_phy_ddi_vswing_sequence(encoder, U32_MAX);
+ else if (DISPLAY_VER(dev_priv) >= 12)
tgl_ddi_vswing_sequence(encoder, crtc_state, level);
else if (DISPLAY_VER(dev_priv) == 11)
icl_ddi_vswing_sequence(encoder, crtc_state, level);
- else if (IS_CANNONLAKE(dev_priv))
- cnl_ddi_vswing_sequence(encoder, crtc_state, level);
else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
bxt_ddi_vswing_sequence(encoder, crtc_state, level);
else
- intel_prepare_hdmi_ddi_buffers(encoder, level);
+ hsw_prepare_hdmi_ddi_buffers(encoder, crtc_state, level);
if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv))
skl_ddi_set_iboost(encoder, crtc_state, level);
@@ -3260,12 +3159,6 @@ static void intel_disable_ddi_dp(struct intel_atomic_state *state,
intel_dp->link_trained = false;
- if (old_crtc_state->has_audio)
- intel_audio_codec_disable(encoder,
- old_crtc_state, old_conn_state);
-
- intel_edp_drrs_disable(intel_dp, old_crtc_state);
- intel_psr_disable(intel_dp, old_crtc_state);
intel_edp_backlight_off(old_conn_state);
/* Disable the decompression in DP Sink */
intel_dp_sink_set_decompression_state(intel_dp, old_crtc_state,
@@ -3283,10 +3176,6 @@ static void intel_disable_ddi_hdmi(struct intel_atomic_state *state,
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct drm_connector *connector = old_conn_state->connector;
- if (old_crtc_state->has_audio)
- intel_audio_codec_disable(encoder,
- old_crtc_state, old_conn_state);
-
if (!intel_hdmi_handle_sink_scrambling(encoder, connector,
false, false))
drm_dbg_kms(&i915->drm,
@@ -3294,6 +3183,25 @@ static void intel_disable_ddi_hdmi(struct intel_atomic_state *state,
connector->base.id, connector->name);
}
+static void intel_pre_disable_ddi(struct intel_atomic_state *state,
+ struct intel_encoder *encoder,
+ const struct intel_crtc_state *old_crtc_state,
+ const struct drm_connector_state *old_conn_state)
+{
+ struct intel_dp *intel_dp;
+
+ if (old_crtc_state->has_audio)
+ intel_audio_codec_disable(encoder, old_crtc_state,
+ old_conn_state);
+
+ if (intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_HDMI))
+ return;
+
+ intel_dp = enc_to_intel_dp(encoder);
+ intel_edp_drrs_disable(intel_dp, old_crtc_state);
+ intel_psr_disable(intel_dp, old_crtc_state);
+}
+
static void intel_disable_ddi(struct intel_atomic_state *state,
struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state,
@@ -3510,7 +3418,7 @@ static bool intel_ddi_is_audio_enabled(struct drm_i915_private *dev_priv,
if (cpu_transcoder == TRANSCODER_EDP)
return false;
- if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO))
+ if (!intel_display_power_is_enabled(dev_priv, POWER_DOMAIN_AUDIO_MMIO))
return false;
return intel_de_read(dev_priv, HSW_AUD_PIN_ELD_CP_VLD) &
@@ -3526,8 +3434,6 @@ void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
crtc_state->min_voltage_level = 3;
else if (DISPLAY_VER(dev_priv) >= 11 && crtc_state->port_clock > 594000)
crtc_state->min_voltage_level = 1;
- else if (IS_CANNONLAKE(dev_priv) && crtc_state->port_clock > 594000)
- crtc_state->min_voltage_level = 2;
}
static enum transcoder bdw_transcoder_master_readout(struct drm_i915_private *dev_priv,
@@ -3594,7 +3500,7 @@ 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);
+ struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
u32 temp, flags = 0;
@@ -3657,7 +3563,7 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
pipe_config->output_types |= BIT(INTEL_OUTPUT_DP);
pipe_config->lane_count =
((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
- intel_dp_get_m_n(intel_crtc, pipe_config);
+ intel_dp_get_m_n(crtc, pipe_config);
if (DISPLAY_VER(dev_priv) >= 11) {
i915_reg_t dp_tp_ctl = dp_tp_ctl_reg(encoder, pipe_config);
@@ -3687,7 +3593,7 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
pipe_config->mst_master_transcoder =
REG_FIELD_GET(TRANS_DDI_MST_TRANSPORT_SELECT_MASK, temp);
- intel_dp_get_m_n(intel_crtc, pipe_config);
+ intel_dp_get_m_n(crtc, pipe_config);
pipe_config->infoframes.enable |=
intel_hdmi_infoframes_enabled(encoder, pipe_config);
@@ -3801,6 +3707,15 @@ void intel_ddi_get_clock(struct intel_encoder *encoder,
&crtc_state->dpll_hw_state);
}
+static void dg2_ddi_get_config(struct intel_encoder *encoder,
+ struct intel_crtc_state *crtc_state)
+{
+ intel_mpllb_readout_hw_state(encoder, &crtc_state->mpllb_state);
+ crtc_state->port_clock = intel_mpllb_calc_port_clock(encoder, &crtc_state->mpllb_state);
+
+ intel_ddi_get_config(encoder, crtc_state);
+}
+
static void adls_ddi_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state)
{
@@ -3868,13 +3783,6 @@ static void icl_ddi_tc_get_config(struct intel_encoder *encoder,
intel_ddi_get_config(encoder, crtc_state);
}
-static void cnl_ddi_get_config(struct intel_encoder *encoder,
- struct intel_crtc_state *crtc_state)
-{
- intel_ddi_get_clock(encoder, crtc_state, cnl_ddi_get_pll(encoder));
- intel_ddi_get_config(encoder, crtc_state);
-}
-
static void bxt_ddi_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state)
{
@@ -4121,12 +4029,12 @@ intel_ddi_init_dp_connector(struct intel_digital_port *dig_port)
dig_port->dp.set_link_train = intel_ddi_set_link_train;
dig_port->dp.set_idle_link_train = intel_ddi_set_idle_link_train;
- if (DISPLAY_VER(dev_priv) >= 12)
+ if (IS_DG2(dev_priv))
+ dig_port->dp.set_signal_levels = dg2_set_signal_levels;
+ else if (DISPLAY_VER(dev_priv) >= 12)
dig_port->dp.set_signal_levels = tgl_set_signal_levels;
else if (DISPLAY_VER(dev_priv) >= 11)
dig_port->dp.set_signal_levels = icl_set_signal_levels;
- else if (IS_CANNONLAKE(dev_priv))
- dig_port->dp.set_signal_levels = cnl_set_signal_levels;
else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
dig_port->dp.set_signal_levels = bxt_set_signal_levels;
else
@@ -4373,15 +4281,6 @@ static bool intel_ddi_a_force_4_lanes(struct intel_digital_port *dig_port)
if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
return true;
- /* Cannonlake: Most of SKUs don't support DDI_E, and the only
- * one who does also have a full A/E split called
- * DDI_F what makes DDI_E useless. However for this
- * case let's trust VBT info.
- */
- if (IS_CANNONLAKE(dev_priv) &&
- !intel_bios_is_port_present(dev_priv, PORT_E))
- return true;
-
return false;
}
@@ -4486,15 +4385,6 @@ static enum hpd_pin ehl_hpd_pin(struct drm_i915_private *dev_priv,
return HPD_PORT_A + port - PORT_A;
}
-static enum hpd_pin cnl_hpd_pin(struct drm_i915_private *dev_priv,
- enum port port)
-{
- if (port == PORT_F)
- return HPD_PORT_E;
-
- return HPD_PORT_A + port - PORT_A;
-}
-
static enum hpd_pin skl_hpd_pin(struct drm_i915_private *dev_priv, enum port port)
{
if (HAS_PCH_TGP(dev_priv))
@@ -4513,6 +4403,36 @@ static bool intel_ddi_is_tc(struct drm_i915_private *i915, enum port port)
return false;
}
+static void intel_ddi_encoder_suspend(struct intel_encoder *encoder)
+{
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ enum phy phy = intel_port_to_phy(i915, encoder->port);
+
+ intel_dp_encoder_suspend(encoder);
+
+ if (!intel_phy_is_tc(i915, phy))
+ return;
+
+ intel_tc_port_disconnect_phy(dig_port);
+}
+
+static void intel_ddi_encoder_shutdown(struct intel_encoder *encoder)
+{
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+ enum phy phy = intel_port_to_phy(i915, encoder->port);
+
+ intel_dp_encoder_shutdown(encoder);
+
+ if (!intel_phy_is_tc(i915, phy))
+ return;
+
+ intel_tc_port_disconnect_phy(dig_port);
+}
+
#define port_tc_name(port) ((port) - PORT_TC1 + '1')
#define tc_port_name(tc_port) ((tc_port) - TC_PORT_1 + '1')
@@ -4616,14 +4536,15 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
encoder->enable = intel_enable_ddi;
encoder->pre_pll_enable = intel_ddi_pre_pll_enable;
encoder->pre_enable = intel_ddi_pre_enable;
+ encoder->pre_disable = intel_pre_disable_ddi;
encoder->disable = intel_disable_ddi;
encoder->post_disable = intel_ddi_post_disable;
encoder->update_pipe = intel_ddi_update_pipe;
encoder->get_hw_state = intel_ddi_get_hw_state;
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->suspend = intel_ddi_encoder_suspend;
+ encoder->shutdown = intel_ddi_encoder_shutdown;
encoder->get_power_domains = intel_ddi_get_power_domains;
encoder->type = INTEL_OUTPUT_DDI;
@@ -4632,7 +4553,11 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
encoder->cloneable = 0;
encoder->pipe_mask = ~0;
- if (IS_ALDERLAKE_S(dev_priv)) {
+ if (IS_DG2(dev_priv)) {
+ encoder->enable_clock = intel_mpllb_enable;
+ encoder->disable_clock = intel_mpllb_disable;
+ encoder->get_config = dg2_ddi_get_config;
+ } else if (IS_ALDERLAKE_S(dev_priv)) {
encoder->enable_clock = adls_ddi_enable_clock;
encoder->disable_clock = adls_ddi_disable_clock;
encoder->is_clock_enabled = adls_ddi_is_clock_enabled;
@@ -4671,11 +4596,6 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
encoder->is_clock_enabled = icl_ddi_combo_is_clock_enabled;
encoder->get_config = icl_ddi_combo_get_config;
}
- } else if (IS_CANNONLAKE(dev_priv)) {
- encoder->enable_clock = cnl_ddi_enable_clock;
- encoder->disable_clock = cnl_ddi_disable_clock;
- encoder->is_clock_enabled = cnl_ddi_is_clock_enabled;
- encoder->get_config = cnl_ddi_get_config;
} else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
/* BXT/GLK have fixed PLL->port mapping */
encoder->get_config = bxt_ddi_get_config;
@@ -4691,6 +4611,8 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
encoder->get_config = hsw_ddi_get_config;
}
+ intel_ddi_buf_trans_init(encoder);
+
if (DISPLAY_VER(dev_priv) >= 13)
encoder->hpd_pin = xelpd_hpd_pin(dev_priv, port);
else if (IS_DG1(dev_priv))
@@ -4703,8 +4625,6 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
encoder->hpd_pin = ehl_hpd_pin(dev_priv, port);
else if (DISPLAY_VER(dev_priv) == 11)
encoder->hpd_pin = icl_hpd_pin(dev_priv, port);
- else if (IS_CANNONLAKE(dev_priv))
- encoder->hpd_pin = cnl_hpd_pin(dev_priv, port);
else if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv))
encoder->hpd_pin = skl_hpd_pin(dev_priv, port);
else
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h
index 59c6b01d4199..7d448485d887 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.h
+++ b/drivers/gpu/drm/i915/display/intel_ddi.h
@@ -40,8 +40,8 @@ bool hsw_ddi_is_clock_enabled(struct intel_encoder *encoder);
void hsw_ddi_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state);
struct intel_shared_dpll *icl_ddi_combo_get_pll(struct intel_encoder *encoder);
-void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state);
+void hsw_prepare_dp_ddi_buffers(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state);
void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv,
enum port port);
void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port);
diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
index 8bfd00f49f2a..ba2c08f1a797 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
@@ -13,1095 +13,1160 @@
* them for both DP and FDI transports, allowing those ports to
* automatically adapt to HDMI connections as well
*/
-static const struct ddi_buf_trans hsw_ddi_translations_dp[] = {
- { 0x00FFFFFF, 0x0006000E, 0x0 },
- { 0x00D75FFF, 0x0005000A, 0x0 },
- { 0x00C30FFF, 0x00040006, 0x0 },
- { 0x80AAAFFF, 0x000B0000, 0x0 },
- { 0x00FFFFFF, 0x0005000A, 0x0 },
- { 0x00D75FFF, 0x000C0004, 0x0 },
- { 0x80C30FFF, 0x000B0000, 0x0 },
- { 0x00FFFFFF, 0x00040006, 0x0 },
- { 0x80D75FFF, 0x000B0000, 0x0 },
-};
-
-static const struct ddi_buf_trans hsw_ddi_translations_fdi[] = {
- { 0x00FFFFFF, 0x0007000E, 0x0 },
- { 0x00D75FFF, 0x000F000A, 0x0 },
- { 0x00C30FFF, 0x00060006, 0x0 },
- { 0x00AAAFFF, 0x001E0000, 0x0 },
- { 0x00FFFFFF, 0x000F000A, 0x0 },
- { 0x00D75FFF, 0x00160004, 0x0 },
- { 0x00C30FFF, 0x001E0000, 0x0 },
- { 0x00FFFFFF, 0x00060006, 0x0 },
- { 0x00D75FFF, 0x001E0000, 0x0 },
-};
-
-static const struct ddi_buf_trans hsw_ddi_translations_hdmi[] = {
- /* Idx NT mV d T mV d db */
- { 0x00FFFFFF, 0x0006000E, 0x0 },/* 0: 400 400 0 */
- { 0x00E79FFF, 0x000E000C, 0x0 },/* 1: 400 500 2 */
- { 0x00D75FFF, 0x0005000A, 0x0 },/* 2: 400 600 3.5 */
- { 0x00FFFFFF, 0x0005000A, 0x0 },/* 3: 600 600 0 */
- { 0x00E79FFF, 0x001D0007, 0x0 },/* 4: 600 750 2 */
- { 0x00D75FFF, 0x000C0004, 0x0 },/* 5: 600 900 3.5 */
- { 0x00FFFFFF, 0x00040006, 0x0 },/* 6: 800 800 0 */
- { 0x80E79FFF, 0x00030002, 0x0 },/* 7: 800 1000 2 */
- { 0x00FFFFFF, 0x00140005, 0x0 },/* 8: 850 850 0 */
- { 0x00FFFFFF, 0x000C0004, 0x0 },/* 9: 900 900 0 */
- { 0x00FFFFFF, 0x001C0003, 0x0 },/* 10: 950 950 0 */
- { 0x80FFFFFF, 0x00030002, 0x0 },/* 11: 1000 1000 0 */
-};
-
-static const struct ddi_buf_trans bdw_ddi_translations_edp[] = {
- { 0x00FFFFFF, 0x00000012, 0x0 },
- { 0x00EBAFFF, 0x00020011, 0x0 },
- { 0x00C71FFF, 0x0006000F, 0x0 },
- { 0x00AAAFFF, 0x000E000A, 0x0 },
- { 0x00FFFFFF, 0x00020011, 0x0 },
- { 0x00DB6FFF, 0x0005000F, 0x0 },
- { 0x00BEEFFF, 0x000A000C, 0x0 },
- { 0x00FFFFFF, 0x0005000F, 0x0 },
- { 0x00DB6FFF, 0x000A000C, 0x0 },
-};
-
-static const struct ddi_buf_trans bdw_ddi_translations_dp[] = {
- { 0x00FFFFFF, 0x0007000E, 0x0 },
- { 0x00D75FFF, 0x000E000A, 0x0 },
- { 0x00BEFFFF, 0x00140006, 0x0 },
- { 0x80B2CFFF, 0x001B0002, 0x0 },
- { 0x00FFFFFF, 0x000E000A, 0x0 },
- { 0x00DB6FFF, 0x00160005, 0x0 },
- { 0x80C71FFF, 0x001A0002, 0x0 },
- { 0x00F7DFFF, 0x00180004, 0x0 },
- { 0x80D75FFF, 0x001B0002, 0x0 },
-};
-
-static const struct ddi_buf_trans bdw_ddi_translations_fdi[] = {
- { 0x00FFFFFF, 0x0001000E, 0x0 },
- { 0x00D75FFF, 0x0004000A, 0x0 },
- { 0x00C30FFF, 0x00070006, 0x0 },
- { 0x00AAAFFF, 0x000C0000, 0x0 },
- { 0x00FFFFFF, 0x0004000A, 0x0 },
- { 0x00D75FFF, 0x00090004, 0x0 },
- { 0x00C30FFF, 0x000C0000, 0x0 },
- { 0x00FFFFFF, 0x00070006, 0x0 },
- { 0x00D75FFF, 0x000C0000, 0x0 },
-};
-
-static const struct ddi_buf_trans bdw_ddi_translations_hdmi[] = {
- /* Idx NT mV d T mV df db */
- { 0x00FFFFFF, 0x0007000E, 0x0 },/* 0: 400 400 0 */
- { 0x00D75FFF, 0x000E000A, 0x0 },/* 1: 400 600 3.5 */
- { 0x00BEFFFF, 0x00140006, 0x0 },/* 2: 400 800 6 */
- { 0x00FFFFFF, 0x0009000D, 0x0 },/* 3: 450 450 0 */
- { 0x00FFFFFF, 0x000E000A, 0x0 },/* 4: 600 600 0 */
- { 0x00D7FFFF, 0x00140006, 0x0 },/* 5: 600 800 2.5 */
- { 0x80CB2FFF, 0x001B0002, 0x0 },/* 6: 600 1000 4.5 */
- { 0x00FFFFFF, 0x00140006, 0x0 },/* 7: 800 800 0 */
- { 0x80E79FFF, 0x001B0002, 0x0 },/* 8: 800 1000 2 */
- { 0x80FFFFFF, 0x001B0002, 0x0 },/* 9: 1000 1000 0 */
+static const union intel_ddi_buf_trans_entry _hsw_ddi_translations_dp[] = {
+ { .hsw = { 0x00FFFFFF, 0x0006000E, 0x0 } },
+ { .hsw = { 0x00D75FFF, 0x0005000A, 0x0 } },
+ { .hsw = { 0x00C30FFF, 0x00040006, 0x0 } },
+ { .hsw = { 0x80AAAFFF, 0x000B0000, 0x0 } },
+ { .hsw = { 0x00FFFFFF, 0x0005000A, 0x0 } },
+ { .hsw = { 0x00D75FFF, 0x000C0004, 0x0 } },
+ { .hsw = { 0x80C30FFF, 0x000B0000, 0x0 } },
+ { .hsw = { 0x00FFFFFF, 0x00040006, 0x0 } },
+ { .hsw = { 0x80D75FFF, 0x000B0000, 0x0 } },
+};
+
+static const struct intel_ddi_buf_trans hsw_ddi_translations_dp = {
+ .entries = _hsw_ddi_translations_dp,
+ .num_entries = ARRAY_SIZE(_hsw_ddi_translations_dp),
+};
+
+static const union intel_ddi_buf_trans_entry _hsw_ddi_translations_fdi[] = {
+ { .hsw = { 0x00FFFFFF, 0x0007000E, 0x0 } },
+ { .hsw = { 0x00D75FFF, 0x000F000A, 0x0 } },
+ { .hsw = { 0x00C30FFF, 0x00060006, 0x0 } },
+ { .hsw = { 0x00AAAFFF, 0x001E0000, 0x0 } },
+ { .hsw = { 0x00FFFFFF, 0x000F000A, 0x0 } },
+ { .hsw = { 0x00D75FFF, 0x00160004, 0x0 } },
+ { .hsw = { 0x00C30FFF, 0x001E0000, 0x0 } },
+ { .hsw = { 0x00FFFFFF, 0x00060006, 0x0 } },
+ { .hsw = { 0x00D75FFF, 0x001E0000, 0x0 } },
+};
+
+static const struct intel_ddi_buf_trans hsw_ddi_translations_fdi = {
+ .entries = _hsw_ddi_translations_fdi,
+ .num_entries = ARRAY_SIZE(_hsw_ddi_translations_fdi),
+};
+
+static const union intel_ddi_buf_trans_entry _hsw_ddi_translations_hdmi[] = {
+ /* Idx NT mV d T mV d db */
+ { .hsw = { 0x00FFFFFF, 0x0006000E, 0x0 } }, /* 0: 400 400 0 */
+ { .hsw = { 0x00E79FFF, 0x000E000C, 0x0 } }, /* 1: 400 500 2 */
+ { .hsw = { 0x00D75FFF, 0x0005000A, 0x0 } }, /* 2: 400 600 3.5 */
+ { .hsw = { 0x00FFFFFF, 0x0005000A, 0x0 } }, /* 3: 600 600 0 */
+ { .hsw = { 0x00E79FFF, 0x001D0007, 0x0 } }, /* 4: 600 750 2 */
+ { .hsw = { 0x00D75FFF, 0x000C0004, 0x0 } }, /* 5: 600 900 3.5 */
+ { .hsw = { 0x00FFFFFF, 0x00040006, 0x0 } }, /* 6: 800 800 0 */
+ { .hsw = { 0x80E79FFF, 0x00030002, 0x0 } }, /* 7: 800 1000 2 */
+ { .hsw = { 0x00FFFFFF, 0x00140005, 0x0 } }, /* 8: 850 850 0 */
+ { .hsw = { 0x00FFFFFF, 0x000C0004, 0x0 } }, /* 9: 900 900 0 */
+ { .hsw = { 0x00FFFFFF, 0x001C0003, 0x0 } }, /* 10: 950 950 0 */
+ { .hsw = { 0x80FFFFFF, 0x00030002, 0x0 } }, /* 11: 1000 1000 0 */
+};
+
+static const struct intel_ddi_buf_trans hsw_ddi_translations_hdmi = {
+ .entries = _hsw_ddi_translations_hdmi,
+ .num_entries = ARRAY_SIZE(_hsw_ddi_translations_hdmi),
+ .hdmi_default_entry = 6,
+};
+
+static const union intel_ddi_buf_trans_entry _bdw_ddi_translations_edp[] = {
+ { .hsw = { 0x00FFFFFF, 0x00000012, 0x0 } },
+ { .hsw = { 0x00EBAFFF, 0x00020011, 0x0 } },
+ { .hsw = { 0x00C71FFF, 0x0006000F, 0x0 } },
+ { .hsw = { 0x00AAAFFF, 0x000E000A, 0x0 } },
+ { .hsw = { 0x00FFFFFF, 0x00020011, 0x0 } },
+ { .hsw = { 0x00DB6FFF, 0x0005000F, 0x0 } },
+ { .hsw = { 0x00BEEFFF, 0x000A000C, 0x0 } },
+ { .hsw = { 0x00FFFFFF, 0x0005000F, 0x0 } },
+ { .hsw = { 0x00DB6FFF, 0x000A000C, 0x0 } },
+};
+
+static const struct intel_ddi_buf_trans bdw_ddi_translations_edp = {
+ .entries = _bdw_ddi_translations_edp,
+ .num_entries = ARRAY_SIZE(_bdw_ddi_translations_edp),
+};
+
+static const union intel_ddi_buf_trans_entry _bdw_ddi_translations_dp[] = {
+ { .hsw = { 0x00FFFFFF, 0x0007000E, 0x0 } },
+ { .hsw = { 0x00D75FFF, 0x000E000A, 0x0 } },
+ { .hsw = { 0x00BEFFFF, 0x00140006, 0x0 } },
+ { .hsw = { 0x80B2CFFF, 0x001B0002, 0x0 } },
+ { .hsw = { 0x00FFFFFF, 0x000E000A, 0x0 } },
+ { .hsw = { 0x00DB6FFF, 0x00160005, 0x0 } },
+ { .hsw = { 0x80C71FFF, 0x001A0002, 0x0 } },
+ { .hsw = { 0x00F7DFFF, 0x00180004, 0x0 } },
+ { .hsw = { 0x80D75FFF, 0x001B0002, 0x0 } },
+};
+
+static const struct intel_ddi_buf_trans bdw_ddi_translations_dp = {
+ .entries = _bdw_ddi_translations_dp,
+ .num_entries = ARRAY_SIZE(_bdw_ddi_translations_dp),
+};
+
+static const union intel_ddi_buf_trans_entry _bdw_ddi_translations_fdi[] = {
+ { .hsw = { 0x00FFFFFF, 0x0001000E, 0x0 } },
+ { .hsw = { 0x00D75FFF, 0x0004000A, 0x0 } },
+ { .hsw = { 0x00C30FFF, 0x00070006, 0x0 } },
+ { .hsw = { 0x00AAAFFF, 0x000C0000, 0x0 } },
+ { .hsw = { 0x00FFFFFF, 0x0004000A, 0x0 } },
+ { .hsw = { 0x00D75FFF, 0x00090004, 0x0 } },
+ { .hsw = { 0x00C30FFF, 0x000C0000, 0x0 } },
+ { .hsw = { 0x00FFFFFF, 0x00070006, 0x0 } },
+ { .hsw = { 0x00D75FFF, 0x000C0000, 0x0 } },
+};
+
+static const struct intel_ddi_buf_trans bdw_ddi_translations_fdi = {
+ .entries = _bdw_ddi_translations_fdi,
+ .num_entries = ARRAY_SIZE(_bdw_ddi_translations_fdi),
+};
+
+static const union intel_ddi_buf_trans_entry _bdw_ddi_translations_hdmi[] = {
+ /* Idx NT mV d T mV df db */
+ { .hsw = { 0x00FFFFFF, 0x0007000E, 0x0 } }, /* 0: 400 400 0 */
+ { .hsw = { 0x00D75FFF, 0x000E000A, 0x0 } }, /* 1: 400 600 3.5 */
+ { .hsw = { 0x00BEFFFF, 0x00140006, 0x0 } }, /* 2: 400 800 6 */
+ { .hsw = { 0x00FFFFFF, 0x0009000D, 0x0 } }, /* 3: 450 450 0 */
+ { .hsw = { 0x00FFFFFF, 0x000E000A, 0x0 } }, /* 4: 600 600 0 */
+ { .hsw = { 0x00D7FFFF, 0x00140006, 0x0 } }, /* 5: 600 800 2.5 */
+ { .hsw = { 0x80CB2FFF, 0x001B0002, 0x0 } }, /* 6: 600 1000 4.5 */
+ { .hsw = { 0x00FFFFFF, 0x00140006, 0x0 } }, /* 7: 800 800 0 */
+ { .hsw = { 0x80E79FFF, 0x001B0002, 0x0 } }, /* 8: 800 1000 2 */
+ { .hsw = { 0x80FFFFFF, 0x001B0002, 0x0 } }, /* 9: 1000 1000 0 */
+};
+
+static const struct intel_ddi_buf_trans bdw_ddi_translations_hdmi = {
+ .entries = _bdw_ddi_translations_hdmi,
+ .num_entries = ARRAY_SIZE(_bdw_ddi_translations_hdmi),
+ .hdmi_default_entry = 7,
};
/* Skylake H and S */
-static const struct ddi_buf_trans skl_ddi_translations_dp[] = {
- { 0x00002016, 0x000000A0, 0x0 },
- { 0x00005012, 0x0000009B, 0x0 },
- { 0x00007011, 0x00000088, 0x0 },
- { 0x80009010, 0x000000C0, 0x1 },
- { 0x00002016, 0x0000009B, 0x0 },
- { 0x00005012, 0x00000088, 0x0 },
- { 0x80007011, 0x000000C0, 0x1 },
- { 0x00002016, 0x000000DF, 0x0 },
- { 0x80005012, 0x000000C0, 0x1 },
+static const union intel_ddi_buf_trans_entry _skl_ddi_translations_dp[] = {
+ { .hsw = { 0x00002016, 0x000000A0, 0x0 } },
+ { .hsw = { 0x00005012, 0x0000009B, 0x0 } },
+ { .hsw = { 0x00007011, 0x00000088, 0x0 } },
+ { .hsw = { 0x80009010, 0x000000C0, 0x1 } },
+ { .hsw = { 0x00002016, 0x0000009B, 0x0 } },
+ { .hsw = { 0x00005012, 0x00000088, 0x0 } },
+ { .hsw = { 0x80007011, 0x000000C0, 0x1 } },
+ { .hsw = { 0x00002016, 0x000000DF, 0x0 } },
+ { .hsw = { 0x80005012, 0x000000C0, 0x1 } },
+};
+
+static const struct intel_ddi_buf_trans skl_ddi_translations_dp = {
+ .entries = _skl_ddi_translations_dp,
+ .num_entries = ARRAY_SIZE(_skl_ddi_translations_dp),
};
/* Skylake U */
-static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = {
- { 0x0000201B, 0x000000A2, 0x0 },
- { 0x00005012, 0x00000088, 0x0 },
- { 0x80007011, 0x000000CD, 0x1 },
- { 0x80009010, 0x000000C0, 0x1 },
- { 0x0000201B, 0x0000009D, 0x0 },
- { 0x80005012, 0x000000C0, 0x1 },
- { 0x80007011, 0x000000C0, 0x1 },
- { 0x00002016, 0x00000088, 0x0 },
- { 0x80005012, 0x000000C0, 0x1 },
+static const union intel_ddi_buf_trans_entry _skl_u_ddi_translations_dp[] = {
+ { .hsw = { 0x0000201B, 0x000000A2, 0x0 } },
+ { .hsw = { 0x00005012, 0x00000088, 0x0 } },
+ { .hsw = { 0x80007011, 0x000000CD, 0x1 } },
+ { .hsw = { 0x80009010, 0x000000C0, 0x1 } },
+ { .hsw = { 0x0000201B, 0x0000009D, 0x0 } },
+ { .hsw = { 0x80005012, 0x000000C0, 0x1 } },
+ { .hsw = { 0x80007011, 0x000000C0, 0x1 } },
+ { .hsw = { 0x00002016, 0x00000088, 0x0 } },
+ { .hsw = { 0x80005012, 0x000000C0, 0x1 } },
+};
+
+static const struct intel_ddi_buf_trans skl_u_ddi_translations_dp = {
+ .entries = _skl_u_ddi_translations_dp,
+ .num_entries = ARRAY_SIZE(_skl_u_ddi_translations_dp),
};
/* Skylake Y */
-static const struct ddi_buf_trans skl_y_ddi_translations_dp[] = {
- { 0x00000018, 0x000000A2, 0x0 },
- { 0x00005012, 0x00000088, 0x0 },
- { 0x80007011, 0x000000CD, 0x3 },
- { 0x80009010, 0x000000C0, 0x3 },
- { 0x00000018, 0x0000009D, 0x0 },
- { 0x80005012, 0x000000C0, 0x3 },
- { 0x80007011, 0x000000C0, 0x3 },
- { 0x00000018, 0x00000088, 0x0 },
- { 0x80005012, 0x000000C0, 0x3 },
+static const union intel_ddi_buf_trans_entry _skl_y_ddi_translations_dp[] = {
+ { .hsw = { 0x00000018, 0x000000A2, 0x0 } },
+ { .hsw = { 0x00005012, 0x00000088, 0x0 } },
+ { .hsw = { 0x80007011, 0x000000CD, 0x3 } },
+ { .hsw = { 0x80009010, 0x000000C0, 0x3 } },
+ { .hsw = { 0x00000018, 0x0000009D, 0x0 } },
+ { .hsw = { 0x80005012, 0x000000C0, 0x3 } },
+ { .hsw = { 0x80007011, 0x000000C0, 0x3 } },
+ { .hsw = { 0x00000018, 0x00000088, 0x0 } },
+ { .hsw = { 0x80005012, 0x000000C0, 0x3 } },
+};
+
+static const struct intel_ddi_buf_trans skl_y_ddi_translations_dp = {
+ .entries = _skl_y_ddi_translations_dp,
+ .num_entries = ARRAY_SIZE(_skl_y_ddi_translations_dp),
};
/* Kabylake H and S */
-static const struct ddi_buf_trans kbl_ddi_translations_dp[] = {
- { 0x00002016, 0x000000A0, 0x0 },
- { 0x00005012, 0x0000009B, 0x0 },
- { 0x00007011, 0x00000088, 0x0 },
- { 0x80009010, 0x000000C0, 0x1 },
- { 0x00002016, 0x0000009B, 0x0 },
- { 0x00005012, 0x00000088, 0x0 },
- { 0x80007011, 0x000000C0, 0x1 },
- { 0x00002016, 0x00000097, 0x0 },
- { 0x80005012, 0x000000C0, 0x1 },
+static const union intel_ddi_buf_trans_entry _kbl_ddi_translations_dp[] = {
+ { .hsw = { 0x00002016, 0x000000A0, 0x0 } },
+ { .hsw = { 0x00005012, 0x0000009B, 0x0 } },
+ { .hsw = { 0x00007011, 0x00000088, 0x0 } },
+ { .hsw = { 0x80009010, 0x000000C0, 0x1 } },
+ { .hsw = { 0x00002016, 0x0000009B, 0x0 } },
+ { .hsw = { 0x00005012, 0x00000088, 0x0 } },
+ { .hsw = { 0x80007011, 0x000000C0, 0x1 } },
+ { .hsw = { 0x00002016, 0x00000097, 0x0 } },
+ { .hsw = { 0x80005012, 0x000000C0, 0x1 } },
+};
+
+static const struct intel_ddi_buf_trans kbl_ddi_translations_dp = {
+ .entries = _kbl_ddi_translations_dp,
+ .num_entries = ARRAY_SIZE(_kbl_ddi_translations_dp),
};
/* Kabylake U */
-static const struct ddi_buf_trans kbl_u_ddi_translations_dp[] = {
- { 0x0000201B, 0x000000A1, 0x0 },
- { 0x00005012, 0x00000088, 0x0 },
- { 0x80007011, 0x000000CD, 0x3 },
- { 0x80009010, 0x000000C0, 0x3 },
- { 0x0000201B, 0x0000009D, 0x0 },
- { 0x80005012, 0x000000C0, 0x3 },
- { 0x80007011, 0x000000C0, 0x3 },
- { 0x00002016, 0x0000004F, 0x0 },
- { 0x80005012, 0x000000C0, 0x3 },
+static const union intel_ddi_buf_trans_entry _kbl_u_ddi_translations_dp[] = {
+ { .hsw = { 0x0000201B, 0x000000A1, 0x0 } },
+ { .hsw = { 0x00005012, 0x00000088, 0x0 } },
+ { .hsw = { 0x80007011, 0x000000CD, 0x3 } },
+ { .hsw = { 0x80009010, 0x000000C0, 0x3 } },
+ { .hsw = { 0x0000201B, 0x0000009D, 0x0 } },
+ { .hsw = { 0x80005012, 0x000000C0, 0x3 } },
+ { .hsw = { 0x80007011, 0x000000C0, 0x3 } },
+ { .hsw = { 0x00002016, 0x0000004F, 0x0 } },
+ { .hsw = { 0x80005012, 0x000000C0, 0x3 } },
+};
+
+static const struct intel_ddi_buf_trans kbl_u_ddi_translations_dp = {
+ .entries = _kbl_u_ddi_translations_dp,
+ .num_entries = ARRAY_SIZE(_kbl_u_ddi_translations_dp),
};
/* Kabylake Y */
-static const struct ddi_buf_trans kbl_y_ddi_translations_dp[] = {
- { 0x00001017, 0x000000A1, 0x0 },
- { 0x00005012, 0x00000088, 0x0 },
- { 0x80007011, 0x000000CD, 0x3 },
- { 0x8000800F, 0x000000C0, 0x3 },
- { 0x00001017, 0x0000009D, 0x0 },
- { 0x80005012, 0x000000C0, 0x3 },
- { 0x80007011, 0x000000C0, 0x3 },
- { 0x00001017, 0x0000004C, 0x0 },
- { 0x80005012, 0x000000C0, 0x3 },
+static const union intel_ddi_buf_trans_entry _kbl_y_ddi_translations_dp[] = {
+ { .hsw = { 0x00001017, 0x000000A1, 0x0 } },
+ { .hsw = { 0x00005012, 0x00000088, 0x0 } },
+ { .hsw = { 0x80007011, 0x000000CD, 0x3 } },
+ { .hsw = { 0x8000800F, 0x000000C0, 0x3 } },
+ { .hsw = { 0x00001017, 0x0000009D, 0x0 } },
+ { .hsw = { 0x80005012, 0x000000C0, 0x3 } },
+ { .hsw = { 0x80007011, 0x000000C0, 0x3 } },
+ { .hsw = { 0x00001017, 0x0000004C, 0x0 } },
+ { .hsw = { 0x80005012, 0x000000C0, 0x3 } },
+};
+
+static const struct intel_ddi_buf_trans kbl_y_ddi_translations_dp = {
+ .entries = _kbl_y_ddi_translations_dp,
+ .num_entries = ARRAY_SIZE(_kbl_y_ddi_translations_dp),
};
/*
* Skylake/Kabylake H and S
* eDP 1.4 low vswing translation parameters
*/
-static const struct ddi_buf_trans skl_ddi_translations_edp[] = {
- { 0x00000018, 0x000000A8, 0x0 },
- { 0x00004013, 0x000000A9, 0x0 },
- { 0x00007011, 0x000000A2, 0x0 },
- { 0x00009010, 0x0000009C, 0x0 },
- { 0x00000018, 0x000000A9, 0x0 },
- { 0x00006013, 0x000000A2, 0x0 },
- { 0x00007011, 0x000000A6, 0x0 },
- { 0x00000018, 0x000000AB, 0x0 },
- { 0x00007013, 0x0000009F, 0x0 },
- { 0x00000018, 0x000000DF, 0x0 },
+static const union intel_ddi_buf_trans_entry _skl_ddi_translations_edp[] = {
+ { .hsw = { 0x00000018, 0x000000A8, 0x0 } },
+ { .hsw = { 0x00004013, 0x000000A9, 0x0 } },
+ { .hsw = { 0x00007011, 0x000000A2, 0x0 } },
+ { .hsw = { 0x00009010, 0x0000009C, 0x0 } },
+ { .hsw = { 0x00000018, 0x000000A9, 0x0 } },
+ { .hsw = { 0x00006013, 0x000000A2, 0x0 } },
+ { .hsw = { 0x00007011, 0x000000A6, 0x0 } },
+ { .hsw = { 0x00000018, 0x000000AB, 0x0 } },
+ { .hsw = { 0x00007013, 0x0000009F, 0x0 } },
+ { .hsw = { 0x00000018, 0x000000DF, 0x0 } },
+};
+
+static const struct intel_ddi_buf_trans skl_ddi_translations_edp = {
+ .entries = _skl_ddi_translations_edp,
+ .num_entries = ARRAY_SIZE(_skl_ddi_translations_edp),
};
/*
* Skylake/Kabylake U
* eDP 1.4 low vswing translation parameters
*/
-static const struct ddi_buf_trans skl_u_ddi_translations_edp[] = {
- { 0x00000018, 0x000000A8, 0x0 },
- { 0x00004013, 0x000000A9, 0x0 },
- { 0x00007011, 0x000000A2, 0x0 },
- { 0x00009010, 0x0000009C, 0x0 },
- { 0x00000018, 0x000000A9, 0x0 },
- { 0x00006013, 0x000000A2, 0x0 },
- { 0x00007011, 0x000000A6, 0x0 },
- { 0x00002016, 0x000000AB, 0x0 },
- { 0x00005013, 0x0000009F, 0x0 },
- { 0x00000018, 0x000000DF, 0x0 },
+static const union intel_ddi_buf_trans_entry _skl_u_ddi_translations_edp[] = {
+ { .hsw = { 0x00000018, 0x000000A8, 0x0 } },
+ { .hsw = { 0x00004013, 0x000000A9, 0x0 } },
+ { .hsw = { 0x00007011, 0x000000A2, 0x0 } },
+ { .hsw = { 0x00009010, 0x0000009C, 0x0 } },
+ { .hsw = { 0x00000018, 0x000000A9, 0x0 } },
+ { .hsw = { 0x00006013, 0x000000A2, 0x0 } },
+ { .hsw = { 0x00007011, 0x000000A6, 0x0 } },
+ { .hsw = { 0x00002016, 0x000000AB, 0x0 } },
+ { .hsw = { 0x00005013, 0x0000009F, 0x0 } },
+ { .hsw = { 0x00000018, 0x000000DF, 0x0 } },
+};
+
+static const struct intel_ddi_buf_trans skl_u_ddi_translations_edp = {
+ .entries = _skl_u_ddi_translations_edp,
+ .num_entries = ARRAY_SIZE(_skl_u_ddi_translations_edp),
};
/*
* Skylake/Kabylake Y
* eDP 1.4 low vswing translation parameters
*/
-static const struct ddi_buf_trans skl_y_ddi_translations_edp[] = {
- { 0x00000018, 0x000000A8, 0x0 },
- { 0x00004013, 0x000000AB, 0x0 },
- { 0x00007011, 0x000000A4, 0x0 },
- { 0x00009010, 0x000000DF, 0x0 },
- { 0x00000018, 0x000000AA, 0x0 },
- { 0x00006013, 0x000000A4, 0x0 },
- { 0x00007011, 0x0000009D, 0x0 },
- { 0x00000018, 0x000000A0, 0x0 },
- { 0x00006012, 0x000000DF, 0x0 },
- { 0x00000018, 0x0000008A, 0x0 },
+static const union intel_ddi_buf_trans_entry _skl_y_ddi_translations_edp[] = {
+ { .hsw = { 0x00000018, 0x000000A8, 0x0 } },
+ { .hsw = { 0x00004013, 0x000000AB, 0x0 } },
+ { .hsw = { 0x00007011, 0x000000A4, 0x0 } },
+ { .hsw = { 0x00009010, 0x000000DF, 0x0 } },
+ { .hsw = { 0x00000018, 0x000000AA, 0x0 } },
+ { .hsw = { 0x00006013, 0x000000A4, 0x0 } },
+ { .hsw = { 0x00007011, 0x0000009D, 0x0 } },
+ { .hsw = { 0x00000018, 0x000000A0, 0x0 } },
+ { .hsw = { 0x00006012, 0x000000DF, 0x0 } },
+ { .hsw = { 0x00000018, 0x0000008A, 0x0 } },
+};
+
+static const struct intel_ddi_buf_trans skl_y_ddi_translations_edp = {
+ .entries = _skl_y_ddi_translations_edp,
+ .num_entries = ARRAY_SIZE(_skl_y_ddi_translations_edp),
};
/* Skylake/Kabylake U, H and S */
-static const struct ddi_buf_trans skl_ddi_translations_hdmi[] = {
- { 0x00000018, 0x000000AC, 0x0 },
- { 0x00005012, 0x0000009D, 0x0 },
- { 0x00007011, 0x00000088, 0x0 },
- { 0x00000018, 0x000000A1, 0x0 },
- { 0x00000018, 0x00000098, 0x0 },
- { 0x00004013, 0x00000088, 0x0 },
- { 0x80006012, 0x000000CD, 0x1 },
- { 0x00000018, 0x000000DF, 0x0 },
- { 0x80003015, 0x000000CD, 0x1 }, /* Default */
- { 0x80003015, 0x000000C0, 0x1 },
- { 0x80000018, 0x000000C0, 0x1 },
+static const union intel_ddi_buf_trans_entry _skl_ddi_translations_hdmi[] = {
+ { .hsw = { 0x00000018, 0x000000AC, 0x0 } },
+ { .hsw = { 0x00005012, 0x0000009D, 0x0 } },
+ { .hsw = { 0x00007011, 0x00000088, 0x0 } },
+ { .hsw = { 0x00000018, 0x000000A1, 0x0 } },
+ { .hsw = { 0x00000018, 0x00000098, 0x0 } },
+ { .hsw = { 0x00004013, 0x00000088, 0x0 } },
+ { .hsw = { 0x80006012, 0x000000CD, 0x1 } },
+ { .hsw = { 0x00000018, 0x000000DF, 0x0 } },
+ { .hsw = { 0x80003015, 0x000000CD, 0x1 } }, /* Default */
+ { .hsw = { 0x80003015, 0x000000C0, 0x1 } },
+ { .hsw = { 0x80000018, 0x000000C0, 0x1 } },
+};
+
+static const struct intel_ddi_buf_trans skl_ddi_translations_hdmi = {
+ .entries = _skl_ddi_translations_hdmi,
+ .num_entries = ARRAY_SIZE(_skl_ddi_translations_hdmi),
+ .hdmi_default_entry = 8,
};
/* Skylake/Kabylake Y */
-static const struct ddi_buf_trans skl_y_ddi_translations_hdmi[] = {
- { 0x00000018, 0x000000A1, 0x0 },
- { 0x00005012, 0x000000DF, 0x0 },
- { 0x80007011, 0x000000CB, 0x3 },
- { 0x00000018, 0x000000A4, 0x0 },
- { 0x00000018, 0x0000009D, 0x0 },
- { 0x00004013, 0x00000080, 0x0 },
- { 0x80006013, 0x000000C0, 0x3 },
- { 0x00000018, 0x0000008A, 0x0 },
- { 0x80003015, 0x000000C0, 0x3 }, /* Default */
- { 0x80003015, 0x000000C0, 0x3 },
- { 0x80000018, 0x000000C0, 0x3 },
-};
-
-
-static const struct bxt_ddi_buf_trans bxt_ddi_translations_dp[] = {
- /* Idx NT mV diff db */
- { 52, 0x9A, 0, 128, }, /* 0: 400 0 */
- { 78, 0x9A, 0, 85, }, /* 1: 400 3.5 */
- { 104, 0x9A, 0, 64, }, /* 2: 400 6 */
- { 154, 0x9A, 0, 43, }, /* 3: 400 9.5 */
- { 77, 0x9A, 0, 128, }, /* 4: 600 0 */
- { 116, 0x9A, 0, 85, }, /* 5: 600 3.5 */
- { 154, 0x9A, 0, 64, }, /* 6: 600 6 */
- { 102, 0x9A, 0, 128, }, /* 7: 800 0 */
- { 154, 0x9A, 0, 85, }, /* 8: 800 3.5 */
- { 154, 0x9A, 1, 128, }, /* 9: 1200 0 */
-};
-
-static const struct bxt_ddi_buf_trans bxt_ddi_translations_edp[] = {
+static const union intel_ddi_buf_trans_entry _skl_y_ddi_translations_hdmi[] = {
+ { .hsw = { 0x00000018, 0x000000A1, 0x0 } },
+ { .hsw = { 0x00005012, 0x000000DF, 0x0 } },
+ { .hsw = { 0x80007011, 0x000000CB, 0x3 } },
+ { .hsw = { 0x00000018, 0x000000A4, 0x0 } },
+ { .hsw = { 0x00000018, 0x0000009D, 0x0 } },
+ { .hsw = { 0x00004013, 0x00000080, 0x0 } },
+ { .hsw = { 0x80006013, 0x000000C0, 0x3 } },
+ { .hsw = { 0x00000018, 0x0000008A, 0x0 } },
+ { .hsw = { 0x80003015, 0x000000C0, 0x3 } }, /* Default */
+ { .hsw = { 0x80003015, 0x000000C0, 0x3 } },
+ { .hsw = { 0x80000018, 0x000000C0, 0x3 } },
+};
+
+static const struct intel_ddi_buf_trans skl_y_ddi_translations_hdmi = {
+ .entries = _skl_y_ddi_translations_hdmi,
+ .num_entries = ARRAY_SIZE(_skl_y_ddi_translations_hdmi),
+ .hdmi_default_entry = 8,
+};
+
+static const union intel_ddi_buf_trans_entry _bxt_ddi_translations_dp[] = {
+ /* Idx NT mV diff db */
+ { .bxt = { 52, 0x9A, 0, 128, } }, /* 0: 400 0 */
+ { .bxt = { 78, 0x9A, 0, 85, } }, /* 1: 400 3.5 */
+ { .bxt = { 104, 0x9A, 0, 64, } }, /* 2: 400 6 */
+ { .bxt = { 154, 0x9A, 0, 43, } }, /* 3: 400 9.5 */
+ { .bxt = { 77, 0x9A, 0, 128, } }, /* 4: 600 0 */
+ { .bxt = { 116, 0x9A, 0, 85, } }, /* 5: 600 3.5 */
+ { .bxt = { 154, 0x9A, 0, 64, } }, /* 6: 600 6 */
+ { .bxt = { 102, 0x9A, 0, 128, } }, /* 7: 800 0 */
+ { .bxt = { 154, 0x9A, 0, 85, } }, /* 8: 800 3.5 */
+ { .bxt = { 154, 0x9A, 1, 128, } }, /* 9: 1200 0 */
+};
+
+static const struct intel_ddi_buf_trans bxt_ddi_translations_dp = {
+ .entries = _bxt_ddi_translations_dp,
+ .num_entries = ARRAY_SIZE(_bxt_ddi_translations_dp),
+};
+
+static const union intel_ddi_buf_trans_entry _bxt_ddi_translations_edp[] = {
/* Idx NT mV diff db */
- { 26, 0, 0, 128, }, /* 0: 200 0 */
- { 38, 0, 0, 112, }, /* 1: 200 1.5 */
- { 48, 0, 0, 96, }, /* 2: 200 4 */
- { 54, 0, 0, 69, }, /* 3: 200 6 */
- { 32, 0, 0, 128, }, /* 4: 250 0 */
- { 48, 0, 0, 104, }, /* 5: 250 1.5 */
- { 54, 0, 0, 85, }, /* 6: 250 4 */
- { 43, 0, 0, 128, }, /* 7: 300 0 */
- { 54, 0, 0, 101, }, /* 8: 300 1.5 */
- { 48, 0, 0, 128, }, /* 9: 300 0 */
+ { .bxt = { 26, 0, 0, 128, } }, /* 0: 200 0 */
+ { .bxt = { 38, 0, 0, 112, } }, /* 1: 200 1.5 */
+ { .bxt = { 48, 0, 0, 96, } }, /* 2: 200 4 */
+ { .bxt = { 54, 0, 0, 69, } }, /* 3: 200 6 */
+ { .bxt = { 32, 0, 0, 128, } }, /* 4: 250 0 */
+ { .bxt = { 48, 0, 0, 104, } }, /* 5: 250 1.5 */
+ { .bxt = { 54, 0, 0, 85, } }, /* 6: 250 4 */
+ { .bxt = { 43, 0, 0, 128, } }, /* 7: 300 0 */
+ { .bxt = { 54, 0, 0, 101, } }, /* 8: 300 1.5 */
+ { .bxt = { 48, 0, 0, 128, } }, /* 9: 300 0 */
+};
+
+static const struct intel_ddi_buf_trans bxt_ddi_translations_edp = {
+ .entries = _bxt_ddi_translations_edp,
+ .num_entries = ARRAY_SIZE(_bxt_ddi_translations_edp),
};
/* BSpec has 2 recommended values - entries 0 and 8.
* Using the entry with higher vswing.
*/
-static const struct bxt_ddi_buf_trans bxt_ddi_translations_hdmi[] = {
- /* Idx NT mV diff db */
- { 52, 0x9A, 0, 128, }, /* 0: 400 0 */
- { 52, 0x9A, 0, 85, }, /* 1: 400 3.5 */
- { 52, 0x9A, 0, 64, }, /* 2: 400 6 */
- { 42, 0x9A, 0, 43, }, /* 3: 400 9.5 */
- { 77, 0x9A, 0, 128, }, /* 4: 600 0 */
- { 77, 0x9A, 0, 85, }, /* 5: 600 3.5 */
- { 77, 0x9A, 0, 64, }, /* 6: 600 6 */
- { 102, 0x9A, 0, 128, }, /* 7: 800 0 */
- { 102, 0x9A, 0, 85, }, /* 8: 800 3.5 */
- { 154, 0x9A, 1, 128, }, /* 9: 1200 0 */
-};
-
-/* Voltage Swing Programming for VccIO 0.85V for DP */
-static const struct cnl_ddi_buf_trans cnl_ddi_translations_dp_0_85V[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x5D, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
- { 0xA, 0x6A, 0x38, 0x00, 0x07 }, /* 350 500 3.1 */
- { 0xB, 0x7A, 0x32, 0x00, 0x0D }, /* 350 700 6.0 */
- { 0x6, 0x7C, 0x2D, 0x00, 0x12 }, /* 350 900 8.2 */
- { 0xA, 0x69, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */
- { 0xB, 0x7A, 0x36, 0x00, 0x09 }, /* 500 700 2.9 */
- { 0x6, 0x7C, 0x30, 0x00, 0x0F }, /* 500 900 5.1 */
- { 0xB, 0x7D, 0x3C, 0x00, 0x03 }, /* 650 725 0.9 */
- { 0x6, 0x7C, 0x34, 0x00, 0x0B }, /* 600 900 3.5 */
- { 0x6, 0x7B, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
-};
-
-/* Voltage Swing Programming for VccIO 0.85V for HDMI */
-static const struct cnl_ddi_buf_trans cnl_ddi_translations_hdmi_0_85V[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x60, 0x3F, 0x00, 0x00 }, /* 450 450 0.0 */
- { 0xB, 0x73, 0x36, 0x00, 0x09 }, /* 450 650 3.2 */
- { 0x6, 0x7F, 0x31, 0x00, 0x0E }, /* 450 850 5.5 */
- { 0xB, 0x73, 0x3F, 0x00, 0x00 }, /* 650 650 0.0 */
- { 0x6, 0x7F, 0x37, 0x00, 0x08 }, /* 650 850 2.3 */
- { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 850 850 0.0 */
- { 0x6, 0x7F, 0x35, 0x00, 0x0A }, /* 600 850 3.0 */
-};
-
-/* Voltage Swing Programming for VccIO 0.85V for eDP */
-static const struct cnl_ddi_buf_trans cnl_ddi_translations_edp_0_85V[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x66, 0x3A, 0x00, 0x05 }, /* 384 500 2.3 */
- { 0x0, 0x7F, 0x38, 0x00, 0x07 }, /* 153 200 2.3 */
- { 0x8, 0x7F, 0x38, 0x00, 0x07 }, /* 192 250 2.3 */
- { 0x1, 0x7F, 0x38, 0x00, 0x07 }, /* 230 300 2.3 */
- { 0x9, 0x7F, 0x38, 0x00, 0x07 }, /* 269 350 2.3 */
- { 0xA, 0x66, 0x3C, 0x00, 0x03 }, /* 446 500 1.0 */
- { 0xB, 0x70, 0x3C, 0x00, 0x03 }, /* 460 600 2.3 */
- { 0xC, 0x75, 0x3C, 0x00, 0x03 }, /* 537 700 2.3 */
- { 0x2, 0x7F, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */
-};
-
-/* Voltage Swing Programming for VccIO 0.95V for DP */
-static const struct cnl_ddi_buf_trans cnl_ddi_translations_dp_0_95V[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x5D, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
- { 0xA, 0x6A, 0x38, 0x00, 0x07 }, /* 350 500 3.1 */
- { 0xB, 0x7A, 0x32, 0x00, 0x0D }, /* 350 700 6.0 */
- { 0x6, 0x7C, 0x2D, 0x00, 0x12 }, /* 350 900 8.2 */
- { 0xA, 0x69, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */
- { 0xB, 0x7A, 0x36, 0x00, 0x09 }, /* 500 700 2.9 */
- { 0x6, 0x7C, 0x30, 0x00, 0x0F }, /* 500 900 5.1 */
- { 0xB, 0x7D, 0x3C, 0x00, 0x03 }, /* 650 725 0.9 */
- { 0x6, 0x7C, 0x34, 0x00, 0x0B }, /* 600 900 3.5 */
- { 0x6, 0x7B, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
-};
-
-/* Voltage Swing Programming for VccIO 0.95V for HDMI */
-static const struct cnl_ddi_buf_trans cnl_ddi_translations_hdmi_0_95V[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x5C, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */
- { 0xB, 0x69, 0x37, 0x00, 0x08 }, /* 400 600 3.5 */
- { 0x5, 0x76, 0x31, 0x00, 0x0E }, /* 400 800 6.0 */
- { 0xA, 0x5E, 0x3F, 0x00, 0x00 }, /* 450 450 0.0 */
- { 0xB, 0x69, 0x3F, 0x00, 0x00 }, /* 600 600 0.0 */
- { 0xB, 0x79, 0x35, 0x00, 0x0A }, /* 600 850 3.0 */
- { 0x6, 0x7D, 0x32, 0x00, 0x0D }, /* 600 1000 4.4 */
- { 0x5, 0x76, 0x3F, 0x00, 0x00 }, /* 800 800 0.0 */
- { 0x6, 0x7D, 0x39, 0x00, 0x06 }, /* 800 1000 1.9 */
- { 0x6, 0x7F, 0x39, 0x00, 0x06 }, /* 850 1050 1.8 */
- { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 1050 1050 0.0 */
-};
-
-/* Voltage Swing Programming for VccIO 0.95V for eDP */
-static const struct cnl_ddi_buf_trans cnl_ddi_translations_edp_0_95V[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x61, 0x3A, 0x00, 0x05 }, /* 384 500 2.3 */
- { 0x0, 0x7F, 0x38, 0x00, 0x07 }, /* 153 200 2.3 */
- { 0x8, 0x7F, 0x38, 0x00, 0x07 }, /* 192 250 2.3 */
- { 0x1, 0x7F, 0x38, 0x00, 0x07 }, /* 230 300 2.3 */
- { 0x9, 0x7F, 0x38, 0x00, 0x07 }, /* 269 350 2.3 */
- { 0xA, 0x61, 0x3C, 0x00, 0x03 }, /* 446 500 1.0 */
- { 0xB, 0x68, 0x39, 0x00, 0x06 }, /* 460 600 2.3 */
- { 0xC, 0x6E, 0x39, 0x00, 0x06 }, /* 537 700 2.3 */
- { 0x4, 0x7F, 0x3A, 0x00, 0x05 }, /* 460 600 2.3 */
- { 0x2, 0x7F, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */
-};
-
-/* Voltage Swing Programming for VccIO 1.05V for DP */
-static const struct cnl_ddi_buf_trans cnl_ddi_translations_dp_1_05V[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x58, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */
- { 0xB, 0x64, 0x37, 0x00, 0x08 }, /* 400 600 3.5 */
- { 0x5, 0x70, 0x31, 0x00, 0x0E }, /* 400 800 6.0 */
- { 0x6, 0x7F, 0x2C, 0x00, 0x13 }, /* 400 1050 8.4 */
- { 0xB, 0x64, 0x3F, 0x00, 0x00 }, /* 600 600 0.0 */
- { 0x5, 0x73, 0x35, 0x00, 0x0A }, /* 600 850 3.0 */
- { 0x6, 0x7F, 0x30, 0x00, 0x0F }, /* 550 1050 5.6 */
- { 0x5, 0x76, 0x3E, 0x00, 0x01 }, /* 850 900 0.5 */
- { 0x6, 0x7F, 0x36, 0x00, 0x09 }, /* 750 1050 2.9 */
- { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 1050 1050 0.0 */
-};
-
-/* Voltage Swing Programming for VccIO 1.05V for HDMI */
-static const struct cnl_ddi_buf_trans cnl_ddi_translations_hdmi_1_05V[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x58, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */
- { 0xB, 0x64, 0x37, 0x00, 0x08 }, /* 400 600 3.5 */
- { 0x5, 0x70, 0x31, 0x00, 0x0E }, /* 400 800 6.0 */
- { 0xA, 0x5B, 0x3F, 0x00, 0x00 }, /* 450 450 0.0 */
- { 0xB, 0x64, 0x3F, 0x00, 0x00 }, /* 600 600 0.0 */
- { 0x5, 0x73, 0x35, 0x00, 0x0A }, /* 600 850 3.0 */
- { 0x6, 0x7C, 0x32, 0x00, 0x0D }, /* 600 1000 4.4 */
- { 0x5, 0x70, 0x3F, 0x00, 0x00 }, /* 800 800 0.0 */
- { 0x6, 0x7C, 0x39, 0x00, 0x06 }, /* 800 1000 1.9 */
- { 0x6, 0x7F, 0x39, 0x00, 0x06 }, /* 850 1050 1.8 */
- { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 1050 1050 0.0 */
-};
-
-/* Voltage Swing Programming for VccIO 1.05V for eDP */
-static const struct cnl_ddi_buf_trans cnl_ddi_translations_edp_1_05V[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x5E, 0x3A, 0x00, 0x05 }, /* 384 500 2.3 */
- { 0x0, 0x7F, 0x38, 0x00, 0x07 }, /* 153 200 2.3 */
- { 0x8, 0x7F, 0x38, 0x00, 0x07 }, /* 192 250 2.3 */
- { 0x1, 0x7F, 0x38, 0x00, 0x07 }, /* 230 300 2.3 */
- { 0x9, 0x7F, 0x38, 0x00, 0x07 }, /* 269 350 2.3 */
- { 0xA, 0x5E, 0x3C, 0x00, 0x03 }, /* 446 500 1.0 */
- { 0xB, 0x64, 0x39, 0x00, 0x06 }, /* 460 600 2.3 */
- { 0xE, 0x6A, 0x39, 0x00, 0x06 }, /* 537 700 2.3 */
- { 0x2, 0x7F, 0x3F, 0x00, 0x00 }, /* 400 400 0.0 */
+static const union intel_ddi_buf_trans_entry _bxt_ddi_translations_hdmi[] = {
+ /* Idx NT mV diff db */
+ { .bxt = { 52, 0x9A, 0, 128, } }, /* 0: 400 0 */
+ { .bxt = { 52, 0x9A, 0, 85, } }, /* 1: 400 3.5 */
+ { .bxt = { 52, 0x9A, 0, 64, } }, /* 2: 400 6 */
+ { .bxt = { 42, 0x9A, 0, 43, } }, /* 3: 400 9.5 */
+ { .bxt = { 77, 0x9A, 0, 128, } }, /* 4: 600 0 */
+ { .bxt = { 77, 0x9A, 0, 85, } }, /* 5: 600 3.5 */
+ { .bxt = { 77, 0x9A, 0, 64, } }, /* 6: 600 6 */
+ { .bxt = { 102, 0x9A, 0, 128, } }, /* 7: 800 0 */
+ { .bxt = { 102, 0x9A, 0, 85, } }, /* 8: 800 3.5 */
+ { .bxt = { 154, 0x9A, 1, 128, } }, /* 9: 1200 0 */
+};
+
+static const struct intel_ddi_buf_trans bxt_ddi_translations_hdmi = {
+ .entries = _bxt_ddi_translations_hdmi,
+ .num_entries = ARRAY_SIZE(_bxt_ddi_translations_hdmi),
+ .hdmi_default_entry = ARRAY_SIZE(_bxt_ddi_translations_hdmi) - 1,
};
/* icl_combo_phy_ddi_translations */
-static const struct cnl_ddi_buf_trans icl_combo_phy_ddi_translations_dp_hbr2[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x35, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
- { 0xA, 0x4F, 0x37, 0x00, 0x08 }, /* 350 500 3.1 */
- { 0xC, 0x71, 0x2F, 0x00, 0x10 }, /* 350 700 6.0 */
- { 0x6, 0x7F, 0x2B, 0x00, 0x14 }, /* 350 900 8.2 */
- { 0xA, 0x4C, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */
- { 0xC, 0x73, 0x34, 0x00, 0x0B }, /* 500 700 2.9 */
- { 0x6, 0x7F, 0x2F, 0x00, 0x10 }, /* 500 900 5.1 */
- { 0xC, 0x6C, 0x3C, 0x00, 0x03 }, /* 650 700 0.6 */
- { 0x6, 0x7F, 0x35, 0x00, 0x0A }, /* 600 900 3.5 */
- { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
-};
-
-static const struct cnl_ddi_buf_trans icl_combo_phy_ddi_translations_edp_hbr2[] = {
- /* NT mV Trans mV db */
- { 0x0, 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 */
- { 0x9, 0x7F, 0x31, 0x00, 0x0E }, /* 200 350 4.9 */
- { 0x8, 0x7F, 0x3F, 0x00, 0x00 }, /* 250 250 0.0 */
- { 0x1, 0x7F, 0x38, 0x00, 0x07 }, /* 250 300 1.6 */
- { 0x9, 0x7F, 0x35, 0x00, 0x0A }, /* 250 350 2.9 */
- { 0x1, 0x7F, 0x3F, 0x00, 0x00 }, /* 300 300 0.0 */
- { 0x9, 0x7F, 0x38, 0x00, 0x07 }, /* 300 350 1.3 */
- { 0x9, 0x7F, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
-};
-
-static const struct cnl_ddi_buf_trans icl_combo_phy_ddi_translations_edp_hbr3[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x35, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
- { 0xA, 0x4F, 0x37, 0x00, 0x08 }, /* 350 500 3.1 */
- { 0xC, 0x71, 0x2F, 0x00, 0x10 }, /* 350 700 6.0 */
- { 0x6, 0x7F, 0x2B, 0x00, 0x14 }, /* 350 900 8.2 */
- { 0xA, 0x4C, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */
- { 0xC, 0x73, 0x34, 0x00, 0x0B }, /* 500 700 2.9 */
- { 0x6, 0x7F, 0x2F, 0x00, 0x10 }, /* 500 900 5.1 */
- { 0xC, 0x6C, 0x3C, 0x00, 0x03 }, /* 650 700 0.6 */
- { 0x6, 0x7F, 0x35, 0x00, 0x0A }, /* 600 900 3.5 */
- { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
-};
-
-static const struct cnl_ddi_buf_trans icl_combo_phy_ddi_translations_hdmi[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x60, 0x3F, 0x00, 0x00 }, /* 450 450 0.0 */
- { 0xB, 0x73, 0x36, 0x00, 0x09 }, /* 450 650 3.2 */
- { 0x6, 0x7F, 0x31, 0x00, 0x0E }, /* 450 850 5.5 */
- { 0xB, 0x73, 0x3F, 0x00, 0x00 }, /* 650 650 0.0 ALS */
- { 0x6, 0x7F, 0x37, 0x00, 0x08 }, /* 650 850 2.3 */
- { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 850 850 0.0 */
- { 0x6, 0x7F, 0x35, 0x00, 0x0A }, /* 600 850 3.0 */
-};
-
-static const struct cnl_ddi_buf_trans ehl_combo_phy_ddi_translations_dp[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x33, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
- { 0xA, 0x47, 0x36, 0x00, 0x09 }, /* 350 500 3.1 */
- { 0xC, 0x64, 0x34, 0x00, 0x0B }, /* 350 700 6.0 */
- { 0x6, 0x7F, 0x30, 0x00, 0x0F }, /* 350 900 8.2 */
- { 0xA, 0x46, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */
- { 0xC, 0x64, 0x38, 0x00, 0x07 }, /* 500 700 2.9 */
- { 0x6, 0x7F, 0x32, 0x00, 0x0D }, /* 500 900 5.1 */
- { 0xC, 0x61, 0x3F, 0x00, 0x00 }, /* 650 700 0.6 */
- { 0x6, 0x7F, 0x38, 0x00, 0x07 }, /* 600 900 3.5 */
- { 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 */
-};
-
-static const struct cnl_ddi_buf_trans dg1_combo_phy_ddi_translations_dp_rbr_hbr[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x32, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
- { 0xA, 0x48, 0x35, 0x00, 0x0A }, /* 350 500 3.1 */
- { 0xC, 0x63, 0x2F, 0x00, 0x10 }, /* 350 700 6.0 */
- { 0x6, 0x7F, 0x2C, 0x00, 0x13 }, /* 350 900 8.2 */
- { 0xA, 0x43, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */
- { 0xC, 0x60, 0x36, 0x00, 0x09 }, /* 500 700 2.9 */
- { 0x6, 0x7F, 0x30, 0x00, 0x0F }, /* 500 900 5.1 */
- { 0xC, 0x60, 0x3F, 0x00, 0x00 }, /* 650 700 0.6 */
- { 0x6, 0x7F, 0x37, 0x00, 0x08 }, /* 600 900 3.5 */
- { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
-};
-
-static const struct cnl_ddi_buf_trans dg1_combo_phy_ddi_translations_dp_hbr2_hbr3[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x32, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
- { 0xA, 0x48, 0x35, 0x00, 0x0A }, /* 350 500 3.1 */
- { 0xC, 0x63, 0x2F, 0x00, 0x10 }, /* 350 700 6.0 */
- { 0x6, 0x7F, 0x2C, 0x00, 0x13 }, /* 350 900 8.2 */
- { 0xA, 0x43, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */
- { 0xC, 0x60, 0x36, 0x00, 0x09 }, /* 500 700 2.9 */
- { 0x6, 0x7F, 0x30, 0x00, 0x0F }, /* 500 900 5.1 */
- { 0xC, 0x58, 0x3F, 0x00, 0x00 }, /* 650 700 0.6 */
- { 0x6, 0x7F, 0x35, 0x00, 0x0A }, /* 600 900 3.5 */
- { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
-};
-
-static const struct icl_mg_phy_ddi_buf_trans icl_mg_phy_ddi_translations_rbr_hbr[] = {
- /* Voltage swing pre-emphasis */
- { 0x18, 0x00, 0x00 }, /* 0 0 */
- { 0x1D, 0x00, 0x05 }, /* 0 1 */
- { 0x24, 0x00, 0x0C }, /* 0 2 */
- { 0x2B, 0x00, 0x14 }, /* 0 3 */
- { 0x21, 0x00, 0x00 }, /* 1 0 */
- { 0x2B, 0x00, 0x08 }, /* 1 1 */
- { 0x30, 0x00, 0x0F }, /* 1 2 */
- { 0x31, 0x00, 0x03 }, /* 2 0 */
- { 0x34, 0x00, 0x0B }, /* 2 1 */
- { 0x3F, 0x00, 0x00 }, /* 3 0 */
-};
-
-static const struct icl_mg_phy_ddi_buf_trans icl_mg_phy_ddi_translations_hbr2_hbr3[] = {
- /* Voltage swing pre-emphasis */
- { 0x18, 0x00, 0x00 }, /* 0 0 */
- { 0x1D, 0x00, 0x05 }, /* 0 1 */
- { 0x24, 0x00, 0x0C }, /* 0 2 */
- { 0x2B, 0x00, 0x14 }, /* 0 3 */
- { 0x26, 0x00, 0x00 }, /* 1 0 */
- { 0x2C, 0x00, 0x07 }, /* 1 1 */
- { 0x33, 0x00, 0x0C }, /* 1 2 */
- { 0x2E, 0x00, 0x00 }, /* 2 0 */
- { 0x36, 0x00, 0x09 }, /* 2 1 */
- { 0x3F, 0x00, 0x00 }, /* 3 0 */
-};
-
-static const struct icl_mg_phy_ddi_buf_trans icl_mg_phy_ddi_translations_hdmi[] = {
- /* HDMI Preset VS Pre-emph */
- { 0x1A, 0x0, 0x0 }, /* 1 400mV 0dB */
- { 0x20, 0x0, 0x0 }, /* 2 500mV 0dB */
- { 0x29, 0x0, 0x0 }, /* 3 650mV 0dB */
- { 0x32, 0x0, 0x0 }, /* 4 800mV 0dB */
- { 0x3F, 0x0, 0x0 }, /* 5 1000mV 0dB */
- { 0x3A, 0x0, 0x5 }, /* 6 Full -1.5 dB */
- { 0x39, 0x0, 0x6 }, /* 7 Full -1.8 dB */
- { 0x38, 0x0, 0x7 }, /* 8 Full -2 dB */
- { 0x37, 0x0, 0x8 }, /* 9 Full -2.5 dB */
- { 0x36, 0x0, 0x9 }, /* 10 Full -3 dB */
-};
-
-static const struct tgl_dkl_phy_ddi_buf_trans tgl_dkl_phy_dp_ddi_trans[] = {
- /* VS pre-emp Non-trans mV Pre-emph dB */
- { 0x7, 0x0, 0x00 }, /* 0 0 400mV 0 dB */
- { 0x5, 0x0, 0x05 }, /* 0 1 400mV 3.5 dB */
- { 0x2, 0x0, 0x0B }, /* 0 2 400mV 6 dB */
- { 0x0, 0x0, 0x18 }, /* 0 3 400mV 9.5 dB */
- { 0x5, 0x0, 0x00 }, /* 1 0 600mV 0 dB */
- { 0x2, 0x0, 0x08 }, /* 1 1 600mV 3.5 dB */
- { 0x0, 0x0, 0x14 }, /* 1 2 600mV 6 dB */
- { 0x2, 0x0, 0x00 }, /* 2 0 800mV 0 dB */
- { 0x0, 0x0, 0x0B }, /* 2 1 800mV 3.5 dB */
- { 0x0, 0x0, 0x00 }, /* 3 0 1200mV 0 dB HDMI default */
-};
-
-static const struct tgl_dkl_phy_ddi_buf_trans tgl_dkl_phy_dp_ddi_trans_hbr2[] = {
- /* VS pre-emp Non-trans mV Pre-emph dB */
- { 0x7, 0x0, 0x00 }, /* 0 0 400mV 0 dB */
- { 0x5, 0x0, 0x05 }, /* 0 1 400mV 3.5 dB */
- { 0x2, 0x0, 0x0B }, /* 0 2 400mV 6 dB */
- { 0x0, 0x0, 0x19 }, /* 0 3 400mV 9.5 dB */
- { 0x5, 0x0, 0x00 }, /* 1 0 600mV 0 dB */
- { 0x2, 0x0, 0x08 }, /* 1 1 600mV 3.5 dB */
- { 0x0, 0x0, 0x14 }, /* 1 2 600mV 6 dB */
- { 0x2, 0x0, 0x00 }, /* 2 0 800mV 0 dB */
- { 0x0, 0x0, 0x0B }, /* 2 1 800mV 3.5 dB */
- { 0x0, 0x0, 0x00 }, /* 3 0 1200mV 0 dB HDMI default */
-};
-
-static const struct tgl_dkl_phy_ddi_buf_trans tgl_dkl_phy_hdmi_ddi_trans[] = {
- /* HDMI Preset VS Pre-emph */
- { 0x7, 0x0, 0x0 }, /* 1 400mV 0dB */
- { 0x6, 0x0, 0x0 }, /* 2 500mV 0dB */
- { 0x4, 0x0, 0x0 }, /* 3 650mV 0dB */
- { 0x2, 0x0, 0x0 }, /* 4 800mV 0dB */
- { 0x0, 0x0, 0x0 }, /* 5 1000mV 0dB */
- { 0x0, 0x0, 0x5 }, /* 6 Full -1.5 dB */
- { 0x0, 0x0, 0x6 }, /* 7 Full -1.8 dB */
- { 0x0, 0x0, 0x7 }, /* 8 Full -2 dB */
- { 0x0, 0x0, 0x8 }, /* 9 Full -2.5 dB */
- { 0x0, 0x0, 0xA }, /* 10 Full -3 dB */
-};
-
-static const struct cnl_ddi_buf_trans tgl_combo_phy_ddi_translations_dp_hbr[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x32, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
- { 0xA, 0x4F, 0x37, 0x00, 0x08 }, /* 350 500 3.1 */
- { 0xC, 0x71, 0x2F, 0x00, 0x10 }, /* 350 700 6.0 */
- { 0x6, 0x7D, 0x2B, 0x00, 0x14 }, /* 350 900 8.2 */
- { 0xA, 0x4C, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */
- { 0xC, 0x73, 0x34, 0x00, 0x0B }, /* 500 700 2.9 */
- { 0x6, 0x7F, 0x2F, 0x00, 0x10 }, /* 500 900 5.1 */
- { 0xC, 0x6C, 0x3C, 0x00, 0x03 }, /* 650 700 0.6 */
- { 0x6, 0x7F, 0x35, 0x00, 0x0A }, /* 600 900 3.5 */
- { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
-};
-
-static const struct cnl_ddi_buf_trans tgl_combo_phy_ddi_translations_dp_hbr2[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x35, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
- { 0xA, 0x4F, 0x37, 0x00, 0x08 }, /* 350 500 3.1 */
- { 0xC, 0x63, 0x2F, 0x00, 0x10 }, /* 350 700 6.0 */
- { 0x6, 0x7F, 0x2B, 0x00, 0x14 }, /* 350 900 8.2 */
- { 0xA, 0x47, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */
- { 0xC, 0x63, 0x34, 0x00, 0x0B }, /* 500 700 2.9 */
- { 0x6, 0x7F, 0x2F, 0x00, 0x10 }, /* 500 900 5.1 */
- { 0xC, 0x61, 0x3C, 0x00, 0x03 }, /* 650 700 0.6 */
- { 0x6, 0x7B, 0x35, 0x00, 0x0A }, /* 600 900 3.5 */
- { 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 */
+static const union intel_ddi_buf_trans_entry _icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+ { .icl = { 0xA, 0x4F, 0x37, 0x00, 0x08 } }, /* 350 500 3.1 */
+ { .icl = { 0xC, 0x71, 0x2F, 0x00, 0x10 } }, /* 350 700 6.0 */
+ { .icl = { 0x6, 0x7F, 0x2B, 0x00, 0x14 } }, /* 350 900 8.2 */
+ { .icl = { 0xA, 0x4C, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */
+ { .icl = { 0xC, 0x73, 0x34, 0x00, 0x0B } }, /* 500 700 2.9 */
+ { .icl = { 0x6, 0x7F, 0x2F, 0x00, 0x10 } }, /* 500 900 5.1 */
+ { .icl = { 0xC, 0x6C, 0x3C, 0x00, 0x03 } }, /* 650 700 0.6 */
+ { .icl = { 0x6, 0x7F, 0x35, 0x00, 0x0A } }, /* 600 900 3.5 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */
+};
+
+static const struct intel_ddi_buf_trans icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3 = {
+ .entries = _icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3,
+ .num_entries = ARRAY_SIZE(_icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3),
+};
+
+static const union intel_ddi_buf_trans_entry _icl_combo_phy_ddi_translations_edp_hbr2[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0x0, 0x7F, 0x3F, 0x00, 0x00 } }, /* 200 200 0.0 */
+ { .icl = { 0x8, 0x7F, 0x38, 0x00, 0x07 } }, /* 200 250 1.9 */
+ { .icl = { 0x1, 0x7F, 0x33, 0x00, 0x0C } }, /* 200 300 3.5 */
+ { .icl = { 0x9, 0x7F, 0x31, 0x00, 0x0E } }, /* 200 350 4.9 */
+ { .icl = { 0x8, 0x7F, 0x3F, 0x00, 0x00 } }, /* 250 250 0.0 */
+ { .icl = { 0x1, 0x7F, 0x38, 0x00, 0x07 } }, /* 250 300 1.6 */
+ { .icl = { 0x9, 0x7F, 0x35, 0x00, 0x0A } }, /* 250 350 2.9 */
+ { .icl = { 0x1, 0x7F, 0x3F, 0x00, 0x00 } }, /* 300 300 0.0 */
+ { .icl = { 0x9, 0x7F, 0x38, 0x00, 0x07 } }, /* 300 350 1.3 */
+ { .icl = { 0x9, 0x7F, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+};
+
+static const struct intel_ddi_buf_trans icl_combo_phy_ddi_translations_edp_hbr2 = {
+ .entries = _icl_combo_phy_ddi_translations_edp_hbr2,
+ .num_entries = ARRAY_SIZE(_icl_combo_phy_ddi_translations_edp_hbr2),
+};
+
+static const union intel_ddi_buf_trans_entry _icl_combo_phy_ddi_translations_hdmi[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0xA, 0x60, 0x3F, 0x00, 0x00 } }, /* 450 450 0.0 */
+ { .icl = { 0xB, 0x73, 0x36, 0x00, 0x09 } }, /* 450 650 3.2 */
+ { .icl = { 0x6, 0x7F, 0x31, 0x00, 0x0E } }, /* 450 850 5.5 */
+ { .icl = { 0xB, 0x73, 0x3F, 0x00, 0x00 } }, /* 650 650 0.0 ALS */
+ { .icl = { 0x6, 0x7F, 0x37, 0x00, 0x08 } }, /* 650 850 2.3 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 850 850 0.0 */
+ { .icl = { 0x6, 0x7F, 0x35, 0x00, 0x0A } }, /* 600 850 3.0 */
+};
+
+static const struct intel_ddi_buf_trans icl_combo_phy_ddi_translations_hdmi = {
+ .entries = _icl_combo_phy_ddi_translations_hdmi,
+ .num_entries = ARRAY_SIZE(_icl_combo_phy_ddi_translations_hdmi),
+ .hdmi_default_entry = ARRAY_SIZE(_icl_combo_phy_ddi_translations_hdmi) - 1,
+};
+
+static const union intel_ddi_buf_trans_entry _ehl_combo_phy_ddi_translations_dp[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0xA, 0x33, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+ { .icl = { 0xA, 0x47, 0x36, 0x00, 0x09 } }, /* 350 500 3.1 */
+ { .icl = { 0xC, 0x64, 0x34, 0x00, 0x0B } }, /* 350 700 6.0 */
+ { .icl = { 0x6, 0x7F, 0x30, 0x00, 0x0F } }, /* 350 900 8.2 */
+ { .icl = { 0xA, 0x46, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */
+ { .icl = { 0xC, 0x64, 0x38, 0x00, 0x07 } }, /* 500 700 2.9 */
+ { .icl = { 0x6, 0x7F, 0x32, 0x00, 0x0D } }, /* 500 900 5.1 */
+ { .icl = { 0xC, 0x61, 0x3F, 0x00, 0x00 } }, /* 650 700 0.6 */
+ { .icl = { 0x6, 0x7F, 0x38, 0x00, 0x07 } }, /* 600 900 3.5 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */
+};
+
+static const struct intel_ddi_buf_trans ehl_combo_phy_ddi_translations_dp = {
+ .entries = _ehl_combo_phy_ddi_translations_dp,
+ .num_entries = ARRAY_SIZE(_ehl_combo_phy_ddi_translations_dp),
+};
+
+static const union intel_ddi_buf_trans_entry _ehl_combo_phy_ddi_translations_edp_hbr2[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0x8, 0x7F, 0x3F, 0x00, 0x00 } }, /* 200 200 0.0 */
+ { .icl = { 0x8, 0x7F, 0x3F, 0x00, 0x00 } }, /* 200 250 1.9 */
+ { .icl = { 0x1, 0x7F, 0x3D, 0x00, 0x02 } }, /* 200 300 3.5 */
+ { .icl = { 0xA, 0x35, 0x39, 0x00, 0x06 } }, /* 200 350 4.9 */
+ { .icl = { 0x8, 0x7F, 0x3F, 0x00, 0x00 } }, /* 250 250 0.0 */
+ { .icl = { 0x1, 0x7F, 0x3C, 0x00, 0x03 } }, /* 250 300 1.6 */
+ { .icl = { 0xA, 0x35, 0x39, 0x00, 0x06 } }, /* 250 350 2.9 */
+ { .icl = { 0x1, 0x7F, 0x3F, 0x00, 0x00 } }, /* 300 300 0.0 */
+ { .icl = { 0xA, 0x35, 0x38, 0x00, 0x07 } }, /* 300 350 1.3 */
+ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+};
+
+static const struct intel_ddi_buf_trans ehl_combo_phy_ddi_translations_edp_hbr2 = {
+ .entries = _ehl_combo_phy_ddi_translations_edp_hbr2,
+ .num_entries = ARRAY_SIZE(_ehl_combo_phy_ddi_translations_edp_hbr2),
+};
+
+static const union intel_ddi_buf_trans_entry _jsl_combo_phy_ddi_translations_edp_hbr[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0x8, 0x7F, 0x3F, 0x00, 0x00 } }, /* 200 200 0.0 */
+ { .icl = { 0x8, 0x7F, 0x38, 0x00, 0x07 } }, /* 200 250 1.9 */
+ { .icl = { 0x1, 0x7F, 0x33, 0x00, 0x0C } }, /* 200 300 3.5 */
+ { .icl = { 0xA, 0x35, 0x36, 0x00, 0x09 } }, /* 200 350 4.9 */
+ { .icl = { 0x8, 0x7F, 0x3F, 0x00, 0x00 } }, /* 250 250 0.0 */
+ { .icl = { 0x1, 0x7F, 0x38, 0x00, 0x07 } }, /* 250 300 1.6 */
+ { .icl = { 0xA, 0x35, 0x35, 0x00, 0x0A } }, /* 250 350 2.9 */
+ { .icl = { 0x1, 0x7F, 0x3F, 0x00, 0x00 } }, /* 300 300 0.0 */
+ { .icl = { 0xA, 0x35, 0x38, 0x00, 0x07 } }, /* 300 350 1.3 */
+ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+};
+
+static const struct intel_ddi_buf_trans jsl_combo_phy_ddi_translations_edp_hbr = {
+ .entries = _jsl_combo_phy_ddi_translations_edp_hbr,
+ .num_entries = ARRAY_SIZE(_jsl_combo_phy_ddi_translations_edp_hbr),
+};
+
+static const union intel_ddi_buf_trans_entry _jsl_combo_phy_ddi_translations_edp_hbr2[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0x8, 0x7F, 0x3F, 0x00, 0x00 } }, /* 200 200 0.0 */
+ { .icl = { 0x8, 0x7F, 0x3F, 0x00, 0x00 } }, /* 200 250 1.9 */
+ { .icl = { 0x1, 0x7F, 0x3D, 0x00, 0x02 } }, /* 200 300 3.5 */
+ { .icl = { 0xA, 0x35, 0x38, 0x00, 0x07 } }, /* 200 350 4.9 */
+ { .icl = { 0x8, 0x7F, 0x3F, 0x00, 0x00 } }, /* 250 250 0.0 */
+ { .icl = { 0x1, 0x7F, 0x3F, 0x00, 0x00 } }, /* 250 300 1.6 */
+ { .icl = { 0xA, 0x35, 0x3A, 0x00, 0x05 } }, /* 250 350 2.9 */
+ { .icl = { 0x1, 0x7F, 0x3F, 0x00, 0x00 } }, /* 300 300 0.0 */
+ { .icl = { 0xA, 0x35, 0x38, 0x00, 0x07 } }, /* 300 350 1.3 */
+ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+};
+
+static const struct intel_ddi_buf_trans jsl_combo_phy_ddi_translations_edp_hbr2 = {
+ .entries = _jsl_combo_phy_ddi_translations_edp_hbr2,
+ .num_entries = ARRAY_SIZE(_jsl_combo_phy_ddi_translations_edp_hbr2),
+};
+
+static const union intel_ddi_buf_trans_entry _dg1_combo_phy_ddi_translations_dp_rbr_hbr[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0xA, 0x32, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+ { .icl = { 0xA, 0x48, 0x35, 0x00, 0x0A } }, /* 350 500 3.1 */
+ { .icl = { 0xC, 0x63, 0x2F, 0x00, 0x10 } }, /* 350 700 6.0 */
+ { .icl = { 0x6, 0x7F, 0x2C, 0x00, 0x13 } }, /* 350 900 8.2 */
+ { .icl = { 0xA, 0x43, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */
+ { .icl = { 0xC, 0x60, 0x36, 0x00, 0x09 } }, /* 500 700 2.9 */
+ { .icl = { 0x6, 0x7F, 0x30, 0x00, 0x0F } }, /* 500 900 5.1 */
+ { .icl = { 0xC, 0x60, 0x3F, 0x00, 0x00 } }, /* 650 700 0.6 */
+ { .icl = { 0x6, 0x7F, 0x37, 0x00, 0x08 } }, /* 600 900 3.5 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */
+};
+
+static const struct intel_ddi_buf_trans dg1_combo_phy_ddi_translations_dp_rbr_hbr = {
+ .entries = _dg1_combo_phy_ddi_translations_dp_rbr_hbr,
+ .num_entries = ARRAY_SIZE(_dg1_combo_phy_ddi_translations_dp_rbr_hbr),
+};
+
+static const union intel_ddi_buf_trans_entry _dg1_combo_phy_ddi_translations_dp_hbr2_hbr3[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0xA, 0x32, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+ { .icl = { 0xA, 0x48, 0x35, 0x00, 0x0A } }, /* 350 500 3.1 */
+ { .icl = { 0xC, 0x63, 0x2F, 0x00, 0x10 } }, /* 350 700 6.0 */
+ { .icl = { 0x6, 0x7F, 0x2C, 0x00, 0x13 } }, /* 350 900 8.2 */
+ { .icl = { 0xA, 0x43, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */
+ { .icl = { 0xC, 0x60, 0x36, 0x00, 0x09 } }, /* 500 700 2.9 */
+ { .icl = { 0x6, 0x7F, 0x30, 0x00, 0x0F } }, /* 500 900 5.1 */
+ { .icl = { 0xC, 0x58, 0x3F, 0x00, 0x00 } }, /* 650 700 0.6 */
+ { .icl = { 0x6, 0x7F, 0x35, 0x00, 0x0A } }, /* 600 900 3.5 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */
+};
+
+static const struct intel_ddi_buf_trans dg1_combo_phy_ddi_translations_dp_hbr2_hbr3 = {
+ .entries = _dg1_combo_phy_ddi_translations_dp_hbr2_hbr3,
+ .num_entries = ARRAY_SIZE(_dg1_combo_phy_ddi_translations_dp_hbr2_hbr3),
+};
+
+static const union intel_ddi_buf_trans_entry _icl_mg_phy_ddi_translations_rbr_hbr[] = {
+ /* Voltage swing pre-emphasis */
+ { .mg = { 0x18, 0x00, 0x00 } }, /* 0 0 */
+ { .mg = { 0x1D, 0x00, 0x05 } }, /* 0 1 */
+ { .mg = { 0x24, 0x00, 0x0C } }, /* 0 2 */
+ { .mg = { 0x2B, 0x00, 0x14 } }, /* 0 3 */
+ { .mg = { 0x21, 0x00, 0x00 } }, /* 1 0 */
+ { .mg = { 0x2B, 0x00, 0x08 } }, /* 1 1 */
+ { .mg = { 0x30, 0x00, 0x0F } }, /* 1 2 */
+ { .mg = { 0x31, 0x00, 0x03 } }, /* 2 0 */
+ { .mg = { 0x34, 0x00, 0x0B } }, /* 2 1 */
+ { .mg = { 0x3F, 0x00, 0x00 } }, /* 3 0 */
+};
+
+static const struct intel_ddi_buf_trans icl_mg_phy_ddi_translations_rbr_hbr = {
+ .entries = _icl_mg_phy_ddi_translations_rbr_hbr,
+ .num_entries = ARRAY_SIZE(_icl_mg_phy_ddi_translations_rbr_hbr),
+};
+
+static const union intel_ddi_buf_trans_entry _icl_mg_phy_ddi_translations_hbr2_hbr3[] = {
+ /* Voltage swing pre-emphasis */
+ { .mg = { 0x18, 0x00, 0x00 } }, /* 0 0 */
+ { .mg = { 0x1D, 0x00, 0x05 } }, /* 0 1 */
+ { .mg = { 0x24, 0x00, 0x0C } }, /* 0 2 */
+ { .mg = { 0x2B, 0x00, 0x14 } }, /* 0 3 */
+ { .mg = { 0x26, 0x00, 0x00 } }, /* 1 0 */
+ { .mg = { 0x2C, 0x00, 0x07 } }, /* 1 1 */
+ { .mg = { 0x33, 0x00, 0x0C } }, /* 1 2 */
+ { .mg = { 0x2E, 0x00, 0x00 } }, /* 2 0 */
+ { .mg = { 0x36, 0x00, 0x09 } }, /* 2 1 */
+ { .mg = { 0x3F, 0x00, 0x00 } }, /* 3 0 */
+};
+
+static const struct intel_ddi_buf_trans icl_mg_phy_ddi_translations_hbr2_hbr3 = {
+ .entries = _icl_mg_phy_ddi_translations_hbr2_hbr3,
+ .num_entries = ARRAY_SIZE(_icl_mg_phy_ddi_translations_hbr2_hbr3),
+};
+
+static const union intel_ddi_buf_trans_entry _icl_mg_phy_ddi_translations_hdmi[] = {
+ /* HDMI Preset VS Pre-emph */
+ { .mg = { 0x1A, 0x0, 0x0 } }, /* 1 400mV 0dB */
+ { .mg = { 0x20, 0x0, 0x0 } }, /* 2 500mV 0dB */
+ { .mg = { 0x29, 0x0, 0x0 } }, /* 3 650mV 0dB */
+ { .mg = { 0x32, 0x0, 0x0 } }, /* 4 800mV 0dB */
+ { .mg = { 0x3F, 0x0, 0x0 } }, /* 5 1000mV 0dB */
+ { .mg = { 0x3A, 0x0, 0x5 } }, /* 6 Full -1.5 dB */
+ { .mg = { 0x39, 0x0, 0x6 } }, /* 7 Full -1.8 dB */
+ { .mg = { 0x38, 0x0, 0x7 } }, /* 8 Full -2 dB */
+ { .mg = { 0x37, 0x0, 0x8 } }, /* 9 Full -2.5 dB */
+ { .mg = { 0x36, 0x0, 0x9 } }, /* 10 Full -3 dB */
+};
+
+static const struct intel_ddi_buf_trans icl_mg_phy_ddi_translations_hdmi = {
+ .entries = _icl_mg_phy_ddi_translations_hdmi,
+ .num_entries = ARRAY_SIZE(_icl_mg_phy_ddi_translations_hdmi),
+ .hdmi_default_entry = ARRAY_SIZE(_icl_mg_phy_ddi_translations_hdmi) - 1,
+};
+
+static const union intel_ddi_buf_trans_entry _tgl_dkl_phy_ddi_translations_dp_hbr[] = {
+ /* VS pre-emp Non-trans mV Pre-emph dB */
+ { .dkl = { 0x7, 0x0, 0x00 } }, /* 0 0 400mV 0 dB */
+ { .dkl = { 0x5, 0x0, 0x05 } }, /* 0 1 400mV 3.5 dB */
+ { .dkl = { 0x2, 0x0, 0x0B } }, /* 0 2 400mV 6 dB */
+ { .dkl = { 0x0, 0x0, 0x18 } }, /* 0 3 400mV 9.5 dB */
+ { .dkl = { 0x5, 0x0, 0x00 } }, /* 1 0 600mV 0 dB */
+ { .dkl = { 0x2, 0x0, 0x08 } }, /* 1 1 600mV 3.5 dB */
+ { .dkl = { 0x0, 0x0, 0x14 } }, /* 1 2 600mV 6 dB */
+ { .dkl = { 0x2, 0x0, 0x00 } }, /* 2 0 800mV 0 dB */
+ { .dkl = { 0x0, 0x0, 0x0B } }, /* 2 1 800mV 3.5 dB */
+ { .dkl = { 0x0, 0x0, 0x00 } }, /* 3 0 1200mV 0 dB HDMI default */
+};
+
+static const struct intel_ddi_buf_trans tgl_dkl_phy_ddi_translations_dp_hbr = {
+ .entries = _tgl_dkl_phy_ddi_translations_dp_hbr,
+ .num_entries = ARRAY_SIZE(_tgl_dkl_phy_ddi_translations_dp_hbr),
+};
+
+static const union intel_ddi_buf_trans_entry _tgl_dkl_phy_ddi_translations_dp_hbr2[] = {
+ /* VS pre-emp Non-trans mV Pre-emph dB */
+ { .dkl = { 0x7, 0x0, 0x00 } }, /* 0 0 400mV 0 dB */
+ { .dkl = { 0x5, 0x0, 0x05 } }, /* 0 1 400mV 3.5 dB */
+ { .dkl = { 0x2, 0x0, 0x0B } }, /* 0 2 400mV 6 dB */
+ { .dkl = { 0x0, 0x0, 0x19 } }, /* 0 3 400mV 9.5 dB */
+ { .dkl = { 0x5, 0x0, 0x00 } }, /* 1 0 600mV 0 dB */
+ { .dkl = { 0x2, 0x0, 0x08 } }, /* 1 1 600mV 3.5 dB */
+ { .dkl = { 0x0, 0x0, 0x14 } }, /* 1 2 600mV 6 dB */
+ { .dkl = { 0x2, 0x0, 0x00 } }, /* 2 0 800mV 0 dB */
+ { .dkl = { 0x0, 0x0, 0x0B } }, /* 2 1 800mV 3.5 dB */
+ { .dkl = { 0x0, 0x0, 0x00 } }, /* 3 0 1200mV 0 dB HDMI default */
+};
+
+static const struct intel_ddi_buf_trans tgl_dkl_phy_ddi_translations_dp_hbr2 = {
+ .entries = _tgl_dkl_phy_ddi_translations_dp_hbr2,
+ .num_entries = ARRAY_SIZE(_tgl_dkl_phy_ddi_translations_dp_hbr2),
+};
+
+static const union intel_ddi_buf_trans_entry _tgl_dkl_phy_ddi_translations_hdmi[] = {
+ /* HDMI Preset VS Pre-emph */
+ { .dkl = { 0x7, 0x0, 0x0 } }, /* 1 400mV 0dB */
+ { .dkl = { 0x6, 0x0, 0x0 } }, /* 2 500mV 0dB */
+ { .dkl = { 0x4, 0x0, 0x0 } }, /* 3 650mV 0dB */
+ { .dkl = { 0x2, 0x0, 0x0 } }, /* 4 800mV 0dB */
+ { .dkl = { 0x0, 0x0, 0x0 } }, /* 5 1000mV 0dB */
+ { .dkl = { 0x0, 0x0, 0x5 } }, /* 6 Full -1.5 dB */
+ { .dkl = { 0x0, 0x0, 0x6 } }, /* 7 Full -1.8 dB */
+ { .dkl = { 0x0, 0x0, 0x7 } }, /* 8 Full -2 dB */
+ { .dkl = { 0x0, 0x0, 0x8 } }, /* 9 Full -2.5 dB */
+ { .dkl = { 0x0, 0x0, 0xA } }, /* 10 Full -3 dB */
+};
+
+static const struct intel_ddi_buf_trans tgl_dkl_phy_ddi_translations_hdmi = {
+ .entries = _tgl_dkl_phy_ddi_translations_hdmi,
+ .num_entries = ARRAY_SIZE(_tgl_dkl_phy_ddi_translations_hdmi),
+ .hdmi_default_entry = ARRAY_SIZE(_tgl_dkl_phy_ddi_translations_hdmi) - 1,
+};
+
+static const union intel_ddi_buf_trans_entry _tgl_combo_phy_ddi_translations_dp_hbr[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0xA, 0x32, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+ { .icl = { 0xA, 0x4F, 0x37, 0x00, 0x08 } }, /* 350 500 3.1 */
+ { .icl = { 0xC, 0x71, 0x2F, 0x00, 0x10 } }, /* 350 700 6.0 */
+ { .icl = { 0x6, 0x7D, 0x2B, 0x00, 0x14 } }, /* 350 900 8.2 */
+ { .icl = { 0xA, 0x4C, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */
+ { .icl = { 0xC, 0x73, 0x34, 0x00, 0x0B } }, /* 500 700 2.9 */
+ { .icl = { 0x6, 0x7F, 0x2F, 0x00, 0x10 } }, /* 500 900 5.1 */
+ { .icl = { 0xC, 0x6C, 0x3C, 0x00, 0x03 } }, /* 650 700 0.6 */
+ { .icl = { 0x6, 0x7F, 0x35, 0x00, 0x0A } }, /* 600 900 3.5 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */
+};
+
+static const struct intel_ddi_buf_trans tgl_combo_phy_ddi_translations_dp_hbr = {
+ .entries = _tgl_combo_phy_ddi_translations_dp_hbr,
+ .num_entries = ARRAY_SIZE(_tgl_combo_phy_ddi_translations_dp_hbr),
+};
+
+static const union intel_ddi_buf_trans_entry _tgl_combo_phy_ddi_translations_dp_hbr2[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+ { .icl = { 0xA, 0x4F, 0x37, 0x00, 0x08 } }, /* 350 500 3.1 */
+ { .icl = { 0xC, 0x63, 0x2F, 0x00, 0x10 } }, /* 350 700 6.0 */
+ { .icl = { 0x6, 0x7F, 0x2B, 0x00, 0x14 } }, /* 350 900 8.2 */
+ { .icl = { 0xA, 0x47, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */
+ { .icl = { 0xC, 0x63, 0x34, 0x00, 0x0B } }, /* 500 700 2.9 */
+ { .icl = { 0x6, 0x7F, 0x2F, 0x00, 0x10 } }, /* 500 900 5.1 */
+ { .icl = { 0xC, 0x61, 0x3C, 0x00, 0x03 } }, /* 650 700 0.6 */
+ { .icl = { 0x6, 0x7B, 0x35, 0x00, 0x0A } }, /* 600 900 3.5 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */
+};
+
+static const struct intel_ddi_buf_trans tgl_combo_phy_ddi_translations_dp_hbr2 = {
+ .entries = _tgl_combo_phy_ddi_translations_dp_hbr2,
+ .num_entries = ARRAY_SIZE(_tgl_combo_phy_ddi_translations_dp_hbr2),
+};
+
+static const union intel_ddi_buf_trans_entry _tgl_uy_combo_phy_ddi_translations_dp_hbr2[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+ { .icl = { 0xA, 0x4F, 0x36, 0x00, 0x09 } }, /* 350 500 3.1 */
+ { .icl = { 0xC, 0x60, 0x32, 0x00, 0x0D } }, /* 350 700 6.0 */
+ { .icl = { 0xC, 0x7F, 0x2D, 0x00, 0x12 } }, /* 350 900 8.2 */
+ { .icl = { 0xC, 0x47, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */
+ { .icl = { 0xC, 0x6F, 0x36, 0x00, 0x09 } }, /* 500 700 2.9 */
+ { .icl = { 0x6, 0x7D, 0x32, 0x00, 0x0D } }, /* 500 900 5.1 */
+ { .icl = { 0x6, 0x60, 0x3C, 0x00, 0x03 } }, /* 650 700 0.6 */
+ { .icl = { 0x6, 0x7F, 0x34, 0x00, 0x0B } }, /* 600 900 3.5 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */
+};
+
+static const struct intel_ddi_buf_trans tgl_uy_combo_phy_ddi_translations_dp_hbr2 = {
+ .entries = _tgl_uy_combo_phy_ddi_translations_dp_hbr2,
+ .num_entries = ARRAY_SIZE(_tgl_uy_combo_phy_ddi_translations_dp_hbr2),
};
/*
* 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 const struct cnl_ddi_buf_trans rkl_combo_phy_ddi_translations_dp_hbr[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x2F, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
- { 0xA, 0x4F, 0x37, 0x00, 0x08 }, /* 350 500 3.1 */
- { 0xC, 0x63, 0x2F, 0x00, 0x10 }, /* 350 700 6.0 */
- { 0x6, 0x7D, 0x2A, 0x00, 0x15 }, /* 350 900 8.2 */
- { 0xA, 0x4C, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */
- { 0xC, 0x73, 0x34, 0x00, 0x0B }, /* 500 700 2.9 */
- { 0x6, 0x7F, 0x2F, 0x00, 0x10 }, /* 500 900 5.1 */
- { 0xC, 0x6E, 0x3E, 0x00, 0x01 }, /* 650 700 0.6 */
- { 0x6, 0x7F, 0x35, 0x00, 0x0A }, /* 600 900 3.5 */
- { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
-};
-
-static const struct cnl_ddi_buf_trans rkl_combo_phy_ddi_translations_dp_hbr2_hbr3[] = {
- /* NT mV Trans mV db */
- { 0xA, 0x35, 0x3F, 0x00, 0x00 }, /* 350 350 0.0 */
- { 0xA, 0x50, 0x38, 0x00, 0x07 }, /* 350 500 3.1 */
- { 0xC, 0x61, 0x33, 0x00, 0x0C }, /* 350 700 6.0 */
- { 0x6, 0x7F, 0x2E, 0x00, 0x11 }, /* 350 900 8.2 */
- { 0xA, 0x47, 0x3F, 0x00, 0x00 }, /* 500 500 0.0 */
- { 0xC, 0x5F, 0x38, 0x00, 0x07 }, /* 500 700 2.9 */
- { 0x6, 0x7F, 0x2F, 0x00, 0x10 }, /* 500 900 5.1 */
- { 0xC, 0x5F, 0x3F, 0x00, 0x00 }, /* 650 700 0.6 */
- { 0x6, 0x7E, 0x36, 0x00, 0x09 }, /* 600 900 3.5 */
- { 0x6, 0x7F, 0x3F, 0x00, 0x00 }, /* 900 900 0.0 */
-};
-
-static const struct tgl_dkl_phy_ddi_buf_trans adlp_dkl_phy_dp_ddi_trans_hbr[] = {
- /* VS pre-emp Non-trans mV Pre-emph dB */
- { 0x7, 0x0, 0x01 }, /* 0 0 400mV 0 dB */
- { 0x5, 0x0, 0x06 }, /* 0 1 400mV 3.5 dB */
- { 0x2, 0x0, 0x0B }, /* 0 2 400mV 6 dB */
- { 0x0, 0x0, 0x17 }, /* 0 3 400mV 9.5 dB */
- { 0x5, 0x0, 0x00 }, /* 1 0 600mV 0 dB */
- { 0x2, 0x0, 0x08 }, /* 1 1 600mV 3.5 dB */
- { 0x0, 0x0, 0x14 }, /* 1 2 600mV 6 dB */
- { 0x2, 0x0, 0x00 }, /* 2 0 800mV 0 dB */
- { 0x0, 0x0, 0x0B }, /* 2 1 800mV 3.5 dB */
- { 0x0, 0x0, 0x00 }, /* 3 0 1200mV 0 dB */
-};
-
-static const struct tgl_dkl_phy_ddi_buf_trans adlp_dkl_phy_dp_ddi_trans_hbr2_hbr3[] = {
- /* VS pre-emp Non-trans mV Pre-emph dB */
- { 0x7, 0x0, 0x00 }, /* 0 0 400mV 0 dB */
- { 0x5, 0x0, 0x04 }, /* 0 1 400mV 3.5 dB */
- { 0x2, 0x0, 0x0A }, /* 0 2 400mV 6 dB */
- { 0x0, 0x0, 0x18 }, /* 0 3 400mV 9.5 dB */
- { 0x5, 0x0, 0x00 }, /* 1 0 600mV 0 dB */
- { 0x2, 0x0, 0x06 }, /* 1 1 600mV 3.5 dB */
- { 0x0, 0x0, 0x14 }, /* 1 2 600mV 6 dB */
- { 0x2, 0x0, 0x00 }, /* 2 0 800mV 0 dB */
- { 0x0, 0x0, 0x09 }, /* 2 1 800mV 3.5 dB */
- { 0x0, 0x0, 0x00 }, /* 3 0 1200mV 0 dB */
-};
-
-bool is_hobl_buf_trans(const struct cnl_ddi_buf_trans *table)
-{
- return table == tgl_combo_phy_ddi_translations_edp_hbr2_hobl;
-}
+static const union intel_ddi_buf_trans_entry _tgl_combo_phy_ddi_translations_edp_hbr2_hobl[] = {
+ /* VS pre-emp */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 0 0 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 0 1 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 0 2 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 0 3 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 1 0 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 1 1 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 1 2 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 2 0 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 2 1 */
+};
-static const struct ddi_buf_trans *
-bdw_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries)
-{
- struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+static const struct intel_ddi_buf_trans tgl_combo_phy_ddi_translations_edp_hbr2_hobl = {
+ .entries = _tgl_combo_phy_ddi_translations_edp_hbr2_hobl,
+ .num_entries = ARRAY_SIZE(_tgl_combo_phy_ddi_translations_edp_hbr2_hobl),
+};
- if (dev_priv->vbt.edp.low_vswing) {
- *n_entries = ARRAY_SIZE(bdw_ddi_translations_edp);
- return bdw_ddi_translations_edp;
- } else {
- *n_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
- return bdw_ddi_translations_dp;
- }
-}
+static const union intel_ddi_buf_trans_entry _rkl_combo_phy_ddi_translations_dp_hbr[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0xA, 0x2F, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+ { .icl = { 0xA, 0x4F, 0x37, 0x00, 0x08 } }, /* 350 500 3.1 */
+ { .icl = { 0xC, 0x63, 0x2F, 0x00, 0x10 } }, /* 350 700 6.0 */
+ { .icl = { 0x6, 0x7D, 0x2A, 0x00, 0x15 } }, /* 350 900 8.2 */
+ { .icl = { 0xA, 0x4C, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */
+ { .icl = { 0xC, 0x73, 0x34, 0x00, 0x0B } }, /* 500 700 2.9 */
+ { .icl = { 0x6, 0x7F, 0x2F, 0x00, 0x10 } }, /* 500 900 5.1 */
+ { .icl = { 0xC, 0x6E, 0x3E, 0x00, 0x01 } }, /* 650 700 0.6 */
+ { .icl = { 0x6, 0x7F, 0x35, 0x00, 0x0A } }, /* 600 900 3.5 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */
+};
-static const struct ddi_buf_trans *
-skl_get_buf_trans_dp(struct intel_encoder *encoder, int *n_entries)
-{
- struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+static const struct intel_ddi_buf_trans rkl_combo_phy_ddi_translations_dp_hbr = {
+ .entries = _rkl_combo_phy_ddi_translations_dp_hbr,
+ .num_entries = ARRAY_SIZE(_rkl_combo_phy_ddi_translations_dp_hbr),
+};
- if (IS_SKL_ULX(dev_priv)) {
- *n_entries = ARRAY_SIZE(skl_y_ddi_translations_dp);
- return skl_y_ddi_translations_dp;
- } else if (IS_SKL_ULT(dev_priv)) {
- *n_entries = ARRAY_SIZE(skl_u_ddi_translations_dp);
- return skl_u_ddi_translations_dp;
- } else {
- *n_entries = ARRAY_SIZE(skl_ddi_translations_dp);
- return skl_ddi_translations_dp;
- }
-}
+static const union intel_ddi_buf_trans_entry _rkl_combo_phy_ddi_translations_dp_hbr2_hbr3[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+ { .icl = { 0xA, 0x50, 0x38, 0x00, 0x07 } }, /* 350 500 3.1 */
+ { .icl = { 0xC, 0x61, 0x33, 0x00, 0x0C } }, /* 350 700 6.0 */
+ { .icl = { 0x6, 0x7F, 0x2E, 0x00, 0x11 } }, /* 350 900 8.2 */
+ { .icl = { 0xA, 0x47, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */
+ { .icl = { 0xC, 0x5F, 0x38, 0x00, 0x07 } }, /* 500 700 2.9 */
+ { .icl = { 0x6, 0x7F, 0x2F, 0x00, 0x10 } }, /* 500 900 5.1 */
+ { .icl = { 0xC, 0x5F, 0x3F, 0x00, 0x00 } }, /* 650 700 0.6 */
+ { .icl = { 0x6, 0x7E, 0x36, 0x00, 0x09 } }, /* 600 900 3.5 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */
+};
-static const struct ddi_buf_trans *
-kbl_get_buf_trans_dp(struct intel_encoder *encoder, int *n_entries)
-{
- struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+static const struct intel_ddi_buf_trans rkl_combo_phy_ddi_translations_dp_hbr2_hbr3 = {
+ .entries = _rkl_combo_phy_ddi_translations_dp_hbr2_hbr3,
+ .num_entries = ARRAY_SIZE(_rkl_combo_phy_ddi_translations_dp_hbr2_hbr3),
+};
- if (IS_KBL_ULX(dev_priv) ||
- IS_CFL_ULX(dev_priv) ||
- IS_CML_ULX(dev_priv)) {
- *n_entries = ARRAY_SIZE(kbl_y_ddi_translations_dp);
- return kbl_y_ddi_translations_dp;
- } else if (IS_KBL_ULT(dev_priv) ||
- IS_CFL_ULT(dev_priv) ||
- IS_CML_ULT(dev_priv)) {
- *n_entries = ARRAY_SIZE(kbl_u_ddi_translations_dp);
- return kbl_u_ddi_translations_dp;
- } else {
- *n_entries = ARRAY_SIZE(kbl_ddi_translations_dp);
- return kbl_ddi_translations_dp;
- }
-}
+static const union intel_ddi_buf_trans_entry _adls_combo_phy_ddi_translations_dp_hbr2_hbr3[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+ { .icl = { 0xA, 0x4F, 0x37, 0x00, 0x08 } }, /* 350 500 3.1 */
+ { .icl = { 0xC, 0x63, 0x31, 0x00, 0x0E } }, /* 350 700 6.0 */
+ { .icl = { 0x6, 0x7F, 0x2C, 0x00, 0x13 } }, /* 350 900 8.2 */
+ { .icl = { 0xA, 0x47, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */
+ { .icl = { 0xC, 0x63, 0x37, 0x00, 0x08 } }, /* 500 700 2.9 */
+ { .icl = { 0x6, 0x73, 0x32, 0x00, 0x0D } }, /* 500 900 5.1 */
+ { .icl = { 0xC, 0x58, 0x3F, 0x00, 0x00 } }, /* 650 700 0.6 */
+ { .icl = { 0x6, 0x7F, 0x35, 0x00, 0x0A } }, /* 600 900 3.5 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */
+};
-static const struct ddi_buf_trans *
-skl_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries)
-{
- struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+static const struct intel_ddi_buf_trans adls_combo_phy_ddi_translations_dp_hbr2_hbr3 = {
+ .entries = _adls_combo_phy_ddi_translations_dp_hbr2_hbr3,
+ .num_entries = ARRAY_SIZE(_adls_combo_phy_ddi_translations_dp_hbr2_hbr3),
+};
- if (dev_priv->vbt.edp.low_vswing) {
- if (IS_SKL_ULX(dev_priv) ||
- IS_KBL_ULX(dev_priv) ||
- IS_CFL_ULX(dev_priv) ||
- IS_CML_ULX(dev_priv)) {
- *n_entries = ARRAY_SIZE(skl_y_ddi_translations_edp);
- return skl_y_ddi_translations_edp;
- } else if (IS_SKL_ULT(dev_priv) ||
- IS_KBL_ULT(dev_priv) ||
- IS_CFL_ULT(dev_priv) ||
- IS_CML_ULT(dev_priv)) {
- *n_entries = ARRAY_SIZE(skl_u_ddi_translations_edp);
- return skl_u_ddi_translations_edp;
- } else {
- *n_entries = ARRAY_SIZE(skl_ddi_translations_edp);
- return skl_ddi_translations_edp;
- }
- }
+static const union intel_ddi_buf_trans_entry _adls_combo_phy_ddi_translations_edp_hbr2[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0x9, 0x73, 0x3D, 0x00, 0x02 } }, /* 200 200 0.0 */
+ { .icl = { 0x9, 0x7A, 0x3C, 0x00, 0x03 } }, /* 200 250 1.9 */
+ { .icl = { 0x9, 0x7F, 0x3B, 0x00, 0x04 } }, /* 200 300 3.5 */
+ { .icl = { 0x4, 0x6C, 0x33, 0x00, 0x0C } }, /* 200 350 4.9 */
+ { .icl = { 0x2, 0x73, 0x3A, 0x00, 0x05 } }, /* 250 250 0.0 */
+ { .icl = { 0x2, 0x7C, 0x38, 0x00, 0x07 } }, /* 250 300 1.6 */
+ { .icl = { 0x4, 0x5A, 0x36, 0x00, 0x09 } }, /* 250 350 2.9 */
+ { .icl = { 0x4, 0x57, 0x3D, 0x00, 0x02 } }, /* 300 300 0.0 */
+ { .icl = { 0x4, 0x65, 0x38, 0x00, 0x07 } }, /* 300 350 1.3 */
+ { .icl = { 0x4, 0x6C, 0x3A, 0x00, 0x05 } }, /* 350 350 0.0 */
+};
- if (IS_KABYLAKE(dev_priv) ||
- IS_COFFEELAKE(dev_priv) ||
- IS_COMETLAKE(dev_priv))
- return kbl_get_buf_trans_dp(encoder, n_entries);
- else
- return skl_get_buf_trans_dp(encoder, n_entries);
-}
+static const struct intel_ddi_buf_trans adls_combo_phy_ddi_translations_edp_hbr2 = {
+ .entries = _adls_combo_phy_ddi_translations_edp_hbr2,
+ .num_entries = ARRAY_SIZE(_adls_combo_phy_ddi_translations_edp_hbr2),
+};
-static const struct ddi_buf_trans *
-skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
-{
- if (IS_SKL_ULX(dev_priv) ||
- IS_KBL_ULX(dev_priv) ||
- IS_CFL_ULX(dev_priv) ||
- IS_CML_ULX(dev_priv)) {
- *n_entries = ARRAY_SIZE(skl_y_ddi_translations_hdmi);
- return skl_y_ddi_translations_hdmi;
- } else {
- *n_entries = ARRAY_SIZE(skl_ddi_translations_hdmi);
- return skl_ddi_translations_hdmi;
- }
-}
+static const union intel_ddi_buf_trans_entry _adls_combo_phy_ddi_translations_edp_hbr3[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+ { .icl = { 0xA, 0x4F, 0x37, 0x00, 0x08 } }, /* 350 500 3.1 */
+ { .icl = { 0xC, 0x63, 0x31, 0x00, 0x0E } }, /* 350 700 6.0 */
+ { .icl = { 0x6, 0x7F, 0x2C, 0x00, 0x13 } }, /* 350 900 8.2 */
+ { .icl = { 0xA, 0x47, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */
+ { .icl = { 0xC, 0x63, 0x37, 0x00, 0x08 } }, /* 500 700 2.9 */
+ { .icl = { 0x6, 0x73, 0x32, 0x00, 0x0D } }, /* 500 900 5.1 */
+ { .icl = { 0xC, 0x58, 0x3F, 0x00, 0x00 } }, /* 650 700 0.6 */
+ { .icl = { 0x6, 0x7F, 0x35, 0x00, 0x0A } }, /* 600 900 3.5 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */
+};
-static int skl_buf_trans_num_entries(enum port port, int n_entries)
-{
- /* Only DDIA and DDIE can select the 10th register with DP */
- if (port == PORT_A || port == PORT_E)
- return min(n_entries, 10);
- else
- return min(n_entries, 9);
-}
+static const struct intel_ddi_buf_trans adls_combo_phy_ddi_translations_edp_hbr3 = {
+ .entries = _adls_combo_phy_ddi_translations_edp_hbr3,
+ .num_entries = ARRAY_SIZE(_adls_combo_phy_ddi_translations_edp_hbr3),
+};
-const struct ddi_buf_trans *
-intel_ddi_get_buf_trans_dp(struct intel_encoder *encoder, int *n_entries)
-{
- struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+static const union intel_ddi_buf_trans_entry _adlp_combo_phy_ddi_translations_hdmi[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0x6, 0x60, 0x3F, 0x00, 0x00 } }, /* 400 400 0.0 */
+ { .icl = { 0x6, 0x68, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */
+ { .icl = { 0xA, 0x73, 0x3F, 0x00, 0x00 } }, /* 650 650 0.0 ALS */
+ { .icl = { 0xA, 0x78, 0x3F, 0x00, 0x00 } }, /* 800 800 0.0 */
+ { .icl = { 0xB, 0x7F, 0x3F, 0x00, 0x00 } }, /* 1000 1000 0.0 Re-timer */
+ { .icl = { 0xB, 0x7F, 0x3B, 0x00, 0x04 } }, /* Full Red -1.5 */
+ { .icl = { 0xB, 0x7F, 0x39, 0x00, 0x06 } }, /* Full Red -1.8 */
+ { .icl = { 0xB, 0x7F, 0x37, 0x00, 0x08 } }, /* Full Red -2.0 CRLS */
+ { .icl = { 0xB, 0x7F, 0x35, 0x00, 0x0A } }, /* Full Red -2.5 */
+ { .icl = { 0xB, 0x7F, 0x33, 0x00, 0x0C } }, /* Full Red -3.0 */
+};
- if (IS_KABYLAKE(dev_priv) ||
- IS_COFFEELAKE(dev_priv) ||
- IS_COMETLAKE(dev_priv)) {
- const struct ddi_buf_trans *ddi_translations =
- kbl_get_buf_trans_dp(encoder, n_entries);
- *n_entries = skl_buf_trans_num_entries(encoder->port, *n_entries);
- return ddi_translations;
- } else if (IS_SKYLAKE(dev_priv)) {
- const struct ddi_buf_trans *ddi_translations =
- skl_get_buf_trans_dp(encoder, n_entries);
- *n_entries = skl_buf_trans_num_entries(encoder->port, *n_entries);
- return ddi_translations;
- } else if (IS_BROADWELL(dev_priv)) {
- *n_entries = ARRAY_SIZE(bdw_ddi_translations_dp);
- return bdw_ddi_translations_dp;
- } else if (IS_HASWELL(dev_priv)) {
- *n_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
- return hsw_ddi_translations_dp;
- }
+static const struct intel_ddi_buf_trans adlp_combo_phy_ddi_translations_hdmi = {
+ .entries = _adlp_combo_phy_ddi_translations_hdmi,
+ .num_entries = ARRAY_SIZE(_adlp_combo_phy_ddi_translations_hdmi),
+ .hdmi_default_entry = ARRAY_SIZE(_adlp_combo_phy_ddi_translations_hdmi) - 1,
+};
- *n_entries = 0;
- return NULL;
-}
+static const union intel_ddi_buf_trans_entry _adlp_combo_phy_ddi_translations_dp_hbr[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+ { .icl = { 0xA, 0x4F, 0x37, 0x00, 0x08 } }, /* 350 500 3.1 */
+ { .icl = { 0xC, 0x71, 0x31, 0x00, 0x0E } }, /* 350 700 6.0 */
+ { .icl = { 0x6, 0x7F, 0x2C, 0x00, 0x13 } }, /* 350 900 8.2 */
+ { .icl = { 0xA, 0x4C, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */
+ { .icl = { 0xC, 0x73, 0x34, 0x00, 0x0B } }, /* 500 700 2.9 */
+ { .icl = { 0x6, 0x7F, 0x2F, 0x00, 0x10 } }, /* 500 900 5.1 */
+ { .icl = { 0xC, 0x73, 0x3E, 0x00, 0x01 } }, /* 650 700 0.6 */
+ { .icl = { 0x6, 0x7F, 0x35, 0x00, 0x0A } }, /* 600 900 3.5 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */
+};
-const struct ddi_buf_trans *
-intel_ddi_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries)
-{
- struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+static const struct intel_ddi_buf_trans adlp_combo_phy_ddi_translations_dp_hbr = {
+ .entries = _adlp_combo_phy_ddi_translations_dp_hbr,
+ .num_entries = ARRAY_SIZE(_adlp_combo_phy_ddi_translations_dp_hbr),
+};
- if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) {
- const struct ddi_buf_trans *ddi_translations =
- skl_get_buf_trans_edp(encoder, n_entries);
- *n_entries = skl_buf_trans_num_entries(encoder->port, *n_entries);
- return ddi_translations;
- } else if (IS_BROADWELL(dev_priv)) {
- return bdw_get_buf_trans_edp(encoder, n_entries);
- } else if (IS_HASWELL(dev_priv)) {
- *n_entries = ARRAY_SIZE(hsw_ddi_translations_dp);
- return hsw_ddi_translations_dp;
- }
+static const union intel_ddi_buf_trans_entry _adlp_combo_phy_ddi_translations_dp_hbr2_hbr3[] = {
+ /* NT mV Trans mV db */
+ { .icl = { 0xA, 0x35, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */
+ { .icl = { 0xA, 0x4F, 0x37, 0x00, 0x08 } }, /* 350 500 3.1 */
+ { .icl = { 0xC, 0x71, 0x2F, 0x00, 0x10 } }, /* 350 700 6.0 */
+ { .icl = { 0x6, 0x7F, 0x2B, 0x00, 0x14 } }, /* 350 900 8.2 */
+ { .icl = { 0xA, 0x4C, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */
+ { .icl = { 0xC, 0x73, 0x34, 0x00, 0x0B } }, /* 500 700 2.9 */
+ { .icl = { 0x6, 0x7F, 0x30, 0x00, 0x0F } }, /* 500 900 5.1 */
+ { .icl = { 0xC, 0x63, 0x3F, 0x00, 0x00 } }, /* 650 700 0.6 */
+ { .icl = { 0x6, 0x7F, 0x38, 0x00, 0x07 } }, /* 600 900 3.5 */
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */
+};
- *n_entries = 0;
- return NULL;
-}
+static const struct intel_ddi_buf_trans adlp_combo_phy_ddi_translations_dp_hbr2_hbr3 = {
+ .entries = _adlp_combo_phy_ddi_translations_dp_hbr2_hbr3,
+ .num_entries = ARRAY_SIZE(_adlp_combo_phy_ddi_translations_dp_hbr2_hbr3),
+};
-const struct ddi_buf_trans *
-intel_ddi_get_buf_trans_fdi(struct drm_i915_private *dev_priv,
- int *n_entries)
-{
- if (IS_BROADWELL(dev_priv)) {
- *n_entries = ARRAY_SIZE(bdw_ddi_translations_fdi);
- return bdw_ddi_translations_fdi;
- } else if (IS_HASWELL(dev_priv)) {
- *n_entries = ARRAY_SIZE(hsw_ddi_translations_fdi);
- return hsw_ddi_translations_fdi;
- }
+static const struct intel_ddi_buf_trans adlp_combo_phy_ddi_translations_edp_hbr3 = {
+ .entries = _icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3,
+ .num_entries = ARRAY_SIZE(_icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3),
+};
+
+static const struct intel_ddi_buf_trans adlp_combo_phy_ddi_translations_edp_up_to_hbr2 = {
+ .entries = _icl_combo_phy_ddi_translations_edp_hbr2,
+ .num_entries = ARRAY_SIZE(_icl_combo_phy_ddi_translations_edp_hbr2),
+};
- *n_entries = 0;
- return NULL;
+static const union intel_ddi_buf_trans_entry _adlp_dkl_phy_ddi_translations_dp_hbr[] = {
+ /* VS pre-emp Non-trans mV Pre-emph dB */
+ { .dkl = { 0x7, 0x0, 0x01 } }, /* 0 0 400mV 0 dB */
+ { .dkl = { 0x5, 0x0, 0x06 } }, /* 0 1 400mV 3.5 dB */
+ { .dkl = { 0x2, 0x0, 0x0B } }, /* 0 2 400mV 6 dB */
+ { .dkl = { 0x0, 0x0, 0x17 } }, /* 0 3 400mV 9.5 dB */
+ { .dkl = { 0x5, 0x0, 0x00 } }, /* 1 0 600mV 0 dB */
+ { .dkl = { 0x2, 0x0, 0x08 } }, /* 1 1 600mV 3.5 dB */
+ { .dkl = { 0x0, 0x0, 0x14 } }, /* 1 2 600mV 6 dB */
+ { .dkl = { 0x2, 0x0, 0x00 } }, /* 2 0 800mV 0 dB */
+ { .dkl = { 0x0, 0x0, 0x0B } }, /* 2 1 800mV 3.5 dB */
+ { .dkl = { 0x0, 0x0, 0x00 } }, /* 3 0 1200mV 0 dB */
+};
+
+static const struct intel_ddi_buf_trans adlp_dkl_phy_ddi_translations_dp_hbr = {
+ .entries = _adlp_dkl_phy_ddi_translations_dp_hbr,
+ .num_entries = ARRAY_SIZE(_adlp_dkl_phy_ddi_translations_dp_hbr),
+};
+
+static const union intel_ddi_buf_trans_entry _adlp_dkl_phy_ddi_translations_dp_hbr2_hbr3[] = {
+ /* VS pre-emp Non-trans mV Pre-emph dB */
+ { .dkl = { 0x7, 0x0, 0x00 } }, /* 0 0 400mV 0 dB */
+ { .dkl = { 0x5, 0x0, 0x04 } }, /* 0 1 400mV 3.5 dB */
+ { .dkl = { 0x2, 0x0, 0x0A } }, /* 0 2 400mV 6 dB */
+ { .dkl = { 0x0, 0x0, 0x18 } }, /* 0 3 400mV 9.5 dB */
+ { .dkl = { 0x5, 0x0, 0x00 } }, /* 1 0 600mV 0 dB */
+ { .dkl = { 0x2, 0x0, 0x06 } }, /* 1 1 600mV 3.5 dB */
+ { .dkl = { 0x0, 0x0, 0x14 } }, /* 1 2 600mV 6 dB */
+ { .dkl = { 0x2, 0x0, 0x00 } }, /* 2 0 800mV 0 dB */
+ { .dkl = { 0x0, 0x0, 0x09 } }, /* 2 1 800mV 3.5 dB */
+ { .dkl = { 0x0, 0x0, 0x00 } }, /* 3 0 1200mV 0 dB */
+};
+
+static const struct intel_ddi_buf_trans adlp_dkl_phy_ddi_translations_dp_hbr2_hbr3 = {
+ .entries = _adlp_dkl_phy_ddi_translations_dp_hbr2_hbr3,
+ .num_entries = ARRAY_SIZE(_adlp_dkl_phy_ddi_translations_dp_hbr2_hbr3),
+};
+
+bool is_hobl_buf_trans(const struct intel_ddi_buf_trans *table)
+{
+ return table == &tgl_combo_phy_ddi_translations_edp_hbr2_hobl;
}
-const struct ddi_buf_trans *
-intel_ddi_get_buf_trans_hdmi(struct intel_encoder *encoder,
- int *n_entries)
+static const struct intel_ddi_buf_trans *
+intel_get_buf_trans(const struct intel_ddi_buf_trans *ddi_translations, int *num_entries)
{
- struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ *num_entries = ddi_translations->num_entries;
+ return ddi_translations;
+}
- if (DISPLAY_VER(dev_priv) == 9 && !IS_BROXTON(dev_priv)) {
- return skl_get_buf_trans_hdmi(dev_priv, n_entries);
- } else if (IS_BROADWELL(dev_priv)) {
- *n_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi);
- return bdw_ddi_translations_hdmi;
- } else if (IS_HASWELL(dev_priv)) {
- *n_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi);
- return hsw_ddi_translations_hdmi;
- }
+static const struct intel_ddi_buf_trans *
+hsw_get_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_ANALOG))
+ return intel_get_buf_trans(&hsw_ddi_translations_fdi, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return intel_get_buf_trans(&hsw_ddi_translations_hdmi, n_entries);
+ else
+ return intel_get_buf_trans(&hsw_ddi_translations_dp, n_entries);
+}
- *n_entries = 0;
- return NULL;
+static const struct intel_ddi_buf_trans *
+bdw_get_buf_trans(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG))
+ return intel_get_buf_trans(&bdw_ddi_translations_fdi, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return intel_get_buf_trans(&bdw_ddi_translations_hdmi, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
+ i915->vbt.edp.low_vswing)
+ return intel_get_buf_trans(&bdw_ddi_translations_edp, n_entries);
+ else
+ return intel_get_buf_trans(&bdw_ddi_translations_dp, n_entries);
}
-static const struct bxt_ddi_buf_trans *
-bxt_get_buf_trans_dp(struct intel_encoder *encoder, int *n_entries)
+static int skl_buf_trans_num_entries(enum port port, int n_entries)
{
- *n_entries = ARRAY_SIZE(bxt_ddi_translations_dp);
- return bxt_ddi_translations_dp;
+ /* Only DDIA and DDIE can select the 10th register with DP */
+ if (port == PORT_A || port == PORT_E)
+ return min(n_entries, 10);
+ else
+ return min(n_entries, 9);
}
-static const struct bxt_ddi_buf_trans *
-bxt_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries)
+static const struct intel_ddi_buf_trans *
+_skl_get_buf_trans_dp(struct intel_encoder *encoder,
+ const struct intel_ddi_buf_trans *ddi_translations,
+ int *n_entries)
{
- struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ ddi_translations = intel_get_buf_trans(ddi_translations, n_entries);
+ *n_entries = skl_buf_trans_num_entries(encoder->port, *n_entries);
+ return ddi_translations;
+}
- if (dev_priv->vbt.edp.low_vswing) {
- *n_entries = ARRAY_SIZE(bxt_ddi_translations_edp);
- return bxt_ddi_translations_edp;
- }
+static const struct intel_ddi_buf_trans *
+skl_y_get_buf_trans(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
- return bxt_get_buf_trans_dp(encoder, n_entries);
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return intel_get_buf_trans(&skl_y_ddi_translations_hdmi, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
+ i915->vbt.edp.low_vswing)
+ return _skl_get_buf_trans_dp(encoder, &skl_y_ddi_translations_edp, n_entries);
+ else
+ return _skl_get_buf_trans_dp(encoder, &skl_y_ddi_translations_dp, n_entries);
}
-static const struct bxt_ddi_buf_trans *
-bxt_get_buf_trans_hdmi(struct intel_encoder *encoder, int *n_entries)
+static const struct intel_ddi_buf_trans *
+skl_u_get_buf_trans(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
{
- *n_entries = ARRAY_SIZE(bxt_ddi_translations_hdmi);
- return bxt_ddi_translations_hdmi;
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return intel_get_buf_trans(&skl_ddi_translations_hdmi, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
+ i915->vbt.edp.low_vswing)
+ return _skl_get_buf_trans_dp(encoder, &skl_u_ddi_translations_edp, n_entries);
+ else
+ return _skl_get_buf_trans_dp(encoder, &skl_u_ddi_translations_dp, n_entries);
}
-const struct bxt_ddi_buf_trans *
-bxt_get_buf_trans(struct intel_encoder *encoder,
+static const struct intel_ddi_buf_trans *
+skl_get_buf_trans(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries)
{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
- return bxt_get_buf_trans_hdmi(encoder, n_entries);
- if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
- return bxt_get_buf_trans_edp(encoder, n_entries);
- return bxt_get_buf_trans_dp(encoder, n_entries);
+ return intel_get_buf_trans(&skl_ddi_translations_hdmi, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
+ i915->vbt.edp.low_vswing)
+ return _skl_get_buf_trans_dp(encoder, &skl_ddi_translations_edp, n_entries);
+ else
+ return _skl_get_buf_trans_dp(encoder, &skl_ddi_translations_dp, n_entries);
}
-static const struct cnl_ddi_buf_trans *
-cnl_get_buf_trans_hdmi(struct intel_encoder *encoder, int *n_entries)
+static const struct intel_ddi_buf_trans *
+kbl_y_get_buf_trans(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);
- u32 voltage = intel_de_read(dev_priv, CNL_PORT_COMP_DW3) & VOLTAGE_INFO_MASK;
-
- if (voltage == VOLTAGE_INFO_0_85V) {
- *n_entries = ARRAY_SIZE(cnl_ddi_translations_hdmi_0_85V);
- return cnl_ddi_translations_hdmi_0_85V;
- } else if (voltage == VOLTAGE_INFO_0_95V) {
- *n_entries = ARRAY_SIZE(cnl_ddi_translations_hdmi_0_95V);
- return cnl_ddi_translations_hdmi_0_95V;
- } else if (voltage == VOLTAGE_INFO_1_05V) {
- *n_entries = ARRAY_SIZE(cnl_ddi_translations_hdmi_1_05V);
- return cnl_ddi_translations_hdmi_1_05V;
- } else {
- *n_entries = 1; /* shut up gcc */
- MISSING_CASE(voltage);
- }
- return NULL;
-}
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
-static const struct cnl_ddi_buf_trans *
-cnl_get_buf_trans_dp(struct intel_encoder *encoder, int *n_entries)
-{
- struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- u32 voltage = intel_de_read(dev_priv, CNL_PORT_COMP_DW3) & VOLTAGE_INFO_MASK;
-
- if (voltage == VOLTAGE_INFO_0_85V) {
- *n_entries = ARRAY_SIZE(cnl_ddi_translations_dp_0_85V);
- return cnl_ddi_translations_dp_0_85V;
- } else if (voltage == VOLTAGE_INFO_0_95V) {
- *n_entries = ARRAY_SIZE(cnl_ddi_translations_dp_0_95V);
- return cnl_ddi_translations_dp_0_95V;
- } else if (voltage == VOLTAGE_INFO_1_05V) {
- *n_entries = ARRAY_SIZE(cnl_ddi_translations_dp_1_05V);
- return cnl_ddi_translations_dp_1_05V;
- } else {
- *n_entries = 1; /* shut up gcc */
- MISSING_CASE(voltage);
- }
- return NULL;
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return intel_get_buf_trans(&skl_y_ddi_translations_hdmi, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
+ i915->vbt.edp.low_vswing)
+ return _skl_get_buf_trans_dp(encoder, &skl_y_ddi_translations_edp, n_entries);
+ else
+ return _skl_get_buf_trans_dp(encoder, &kbl_y_ddi_translations_dp, n_entries);
}
-static const struct cnl_ddi_buf_trans *
-cnl_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries)
+static const struct intel_ddi_buf_trans *
+kbl_u_get_buf_trans(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);
- u32 voltage = intel_de_read(dev_priv, CNL_PORT_COMP_DW3) & VOLTAGE_INFO_MASK;
-
- if (dev_priv->vbt.edp.low_vswing) {
- if (voltage == VOLTAGE_INFO_0_85V) {
- *n_entries = ARRAY_SIZE(cnl_ddi_translations_edp_0_85V);
- return cnl_ddi_translations_edp_0_85V;
- } else if (voltage == VOLTAGE_INFO_0_95V) {
- *n_entries = ARRAY_SIZE(cnl_ddi_translations_edp_0_95V);
- return cnl_ddi_translations_edp_0_95V;
- } else if (voltage == VOLTAGE_INFO_1_05V) {
- *n_entries = ARRAY_SIZE(cnl_ddi_translations_edp_1_05V);
- return cnl_ddi_translations_edp_1_05V;
- } else {
- *n_entries = 1; /* shut up gcc */
- MISSING_CASE(voltage);
- }
- return NULL;
- } else {
- return cnl_get_buf_trans_dp(encoder, n_entries);
- }
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return intel_get_buf_trans(&skl_ddi_translations_hdmi, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
+ i915->vbt.edp.low_vswing)
+ return _skl_get_buf_trans_dp(encoder, &skl_u_ddi_translations_edp, n_entries);
+ else
+ return _skl_get_buf_trans_dp(encoder, &kbl_u_ddi_translations_dp, n_entries);
}
-const struct cnl_ddi_buf_trans *
-cnl_get_buf_trans(struct intel_encoder *encoder,
+static const struct intel_ddi_buf_trans *
+kbl_get_buf_trans(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries)
{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
- return cnl_get_buf_trans_hdmi(encoder, n_entries);
- if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
- return cnl_get_buf_trans_edp(encoder, n_entries);
- return cnl_get_buf_trans_dp(encoder, n_entries);
+ return intel_get_buf_trans(&skl_ddi_translations_hdmi, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
+ i915->vbt.edp.low_vswing)
+ return _skl_get_buf_trans_dp(encoder, &skl_ddi_translations_edp, n_entries);
+ else
+ return _skl_get_buf_trans_dp(encoder, &kbl_ddi_translations_dp, n_entries);
}
-static const struct cnl_ddi_buf_trans *
-icl_get_combo_buf_trans_hdmi(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state,
- int *n_entries)
+static const struct intel_ddi_buf_trans *
+bxt_get_buf_trans(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;
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return intel_get_buf_trans(&bxt_ddi_translations_hdmi, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
+ i915->vbt.edp.low_vswing)
+ return intel_get_buf_trans(&bxt_ddi_translations_edp, n_entries);
+ else
+ return intel_get_buf_trans(&bxt_ddi_translations_dp, n_entries);
}
-static const struct cnl_ddi_buf_trans *
+static const struct intel_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;
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3,
+ n_entries);
}
-static const struct cnl_ddi_buf_trans *
+static const struct intel_ddi_buf_trans *
icl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries)
@@ -1109,294 +1174,391 @@ icl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
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;
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3,
+ n_entries);
} 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;
- } else if (IS_DG1(dev_priv) && crtc_state->port_clock > 270000) {
- *n_entries = ARRAY_SIZE(dg1_combo_phy_ddi_translations_dp_hbr2_hbr3);
- return dg1_combo_phy_ddi_translations_dp_hbr2_hbr3;
- } else if (IS_DG1(dev_priv)) {
- *n_entries = ARRAY_SIZE(dg1_combo_phy_ddi_translations_dp_rbr_hbr);
- return dg1_combo_phy_ddi_translations_dp_rbr_hbr;
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_edp_hbr2,
+ n_entries);
}
return icl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
}
-const struct cnl_ddi_buf_trans *
+static const struct intel_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);
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_hdmi, 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_hdmi(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state,
- int *n_entries)
-{
- *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 *
+static const struct intel_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;
+ return intel_get_buf_trans(&icl_mg_phy_ddi_translations_hbr2_hbr3,
+ n_entries);
} else {
- *n_entries = ARRAY_SIZE(icl_mg_phy_ddi_translations_rbr_hbr);
- return icl_mg_phy_ddi_translations_rbr_hbr;
+ return intel_get_buf_trans(&icl_mg_phy_ddi_translations_rbr_hbr,
+ n_entries);
}
}
-const struct icl_mg_phy_ddi_buf_trans *
+static const struct intel_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);
+ return intel_get_buf_trans(&icl_mg_phy_ddi_translations_hdmi, n_entries);
else
return icl_get_mg_buf_trans_dp(encoder, crtc_state, n_entries);
}
-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)
+static const struct intel_ddi_buf_trans *
+ehl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ if (crtc_state->port_clock > 270000)
+ return intel_get_buf_trans(&ehl_combo_phy_ddi_translations_edp_hbr2, n_entries);
+ else
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_edp_hbr2, n_entries);
+}
+
+static const struct intel_ddi_buf_trans *
+ehl_get_combo_buf_trans(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 (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_hdmi, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
+ dev_priv->vbt.edp.low_vswing)
+ return ehl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
+ else
+ return intel_get_buf_trans(&ehl_combo_phy_ddi_translations_dp, n_entries);
+}
+
+static const struct intel_ddi_buf_trans *
+jsl_get_combo_buf_trans_edp(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;
+ if (crtc_state->port_clock > 270000)
+ return intel_get_buf_trans(&jsl_combo_phy_ddi_translations_edp_hbr2, n_entries);
+ else
+ return intel_get_buf_trans(&jsl_combo_phy_ddi_translations_edp_hbr, n_entries);
+}
+
+static const struct intel_ddi_buf_trans *
+jsl_get_combo_buf_trans(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 (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_hdmi, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
+ dev_priv->vbt.edp.low_vswing)
+ return jsl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
+ else
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3, n_entries);
}
-static const struct cnl_ddi_buf_trans *
-ehl_get_combo_buf_trans_dp(struct intel_encoder *encoder,
+static const struct intel_ddi_buf_trans *
+tgl_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;
+ 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)) {
+ return intel_get_buf_trans(&tgl_uy_combo_phy_ddi_translations_dp_hbr2,
+ n_entries);
+ } else {
+ return intel_get_buf_trans(&tgl_combo_phy_ddi_translations_dp_hbr2,
+ n_entries);
+ }
+ } else {
+ return intel_get_buf_trans(&tgl_combo_phy_ddi_translations_dp_hbr,
+ n_entries);
+ }
}
-static const struct cnl_ddi_buf_trans *
-ehl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
+static const struct intel_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 (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;
+ if (crtc_state->port_clock > 540000) {
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3,
+ n_entries);
+ } else if (dev_priv->vbt.edp.hobl && !intel_dp->hobl_failed) {
+ return intel_get_buf_trans(&tgl_combo_phy_ddi_translations_edp_hbr2_hobl,
+ n_entries);
+ } else if (dev_priv->vbt.edp.low_vswing) {
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_edp_hbr2,
+ n_entries);
}
- return ehl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+ return tgl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
}
-const struct cnl_ddi_buf_trans *
-ehl_get_combo_buf_trans(struct intel_encoder *encoder,
+static const struct intel_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 ehl_get_combo_buf_trans_hdmi(encoder, crtc_state, n_entries);
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_hdmi, 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);
+ return tgl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
else
- return ehl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+ return tgl_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)
+static const struct intel_ddi_buf_trans *
+dg1_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_hdmi);
- return icl_combo_phy_ddi_translations_hdmi;
+ if (crtc_state->port_clock > 270000)
+ return intel_get_buf_trans(&dg1_combo_phy_ddi_translations_dp_hbr2_hbr3,
+ n_entries);
+ else
+ return intel_get_buf_trans(&dg1_combo_phy_ddi_translations_dp_rbr_hbr,
+ n_entries);
}
-static const struct cnl_ddi_buf_trans *
-jsl_get_combo_buf_trans_dp(struct intel_encoder *encoder,
+static const struct intel_ddi_buf_trans *
+dg1_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)
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3,
+ n_entries);
+ else if (dev_priv->vbt.edp.hobl && !intel_dp->hobl_failed)
+ return intel_get_buf_trans(&tgl_combo_phy_ddi_translations_edp_hbr2_hobl,
+ n_entries);
+ else if (dev_priv->vbt.edp.low_vswing)
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_edp_hbr2,
+ n_entries);
+ else
+ return dg1_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+}
+
+static const struct intel_ddi_buf_trans *
+dg1_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 intel_get_buf_trans(&icl_combo_phy_ddi_translations_hdmi, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
+ return dg1_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
+ else
+ return dg1_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+}
+
+static const struct intel_ddi_buf_trans *
+rkl_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;
+ if (crtc_state->port_clock > 270000)
+ return intel_get_buf_trans(&rkl_combo_phy_ddi_translations_dp_hbr2_hbr3, n_entries);
+ else
+ return intel_get_buf_trans(&rkl_combo_phy_ddi_translations_dp_hbr, n_entries);
}
-static const struct cnl_ddi_buf_trans *
-jsl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
+static const struct intel_ddi_buf_trans *
+rkl_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 (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 (crtc_state->port_clock > 540000) {
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_dp_hbr2_edp_hbr3,
+ n_entries);
+ } else if (dev_priv->vbt.edp.hobl && !intel_dp->hobl_failed) {
+ return intel_get_buf_trans(&tgl_combo_phy_ddi_translations_edp_hbr2_hobl,
+ n_entries);
+ } else if (dev_priv->vbt.edp.low_vswing) {
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_edp_hbr2,
+ n_entries);
}
- return jsl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+ return rkl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
}
-const struct cnl_ddi_buf_trans *
-jsl_get_combo_buf_trans(struct intel_encoder *encoder,
+static const struct intel_ddi_buf_trans *
+rkl_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);
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_hdmi, 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);
+ return rkl_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
else
- return jsl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+ return rkl_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,
+static const struct intel_ddi_buf_trans *
+adls_get_combo_buf_trans_dp(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries)
+{
+ if (crtc_state->port_clock > 270000)
+ return intel_get_buf_trans(&adls_combo_phy_ddi_translations_dp_hbr2_hbr3, n_entries);
+ else
+ return intel_get_buf_trans(&tgl_combo_phy_ddi_translations_dp_hbr, n_entries);
+}
+
+static const struct intel_ddi_buf_trans *
+adls_get_combo_buf_trans_edp(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;
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+ if (crtc_state->port_clock > 540000)
+ return intel_get_buf_trans(&adls_combo_phy_ddi_translations_edp_hbr3, n_entries);
+ else if (i915->vbt.edp.hobl && !intel_dp->hobl_failed)
+ return intel_get_buf_trans(&tgl_combo_phy_ddi_translations_edp_hbr2_hobl, n_entries);
+ else if (i915->vbt.edp.low_vswing)
+ return intel_get_buf_trans(&adls_combo_phy_ddi_translations_edp_hbr2, n_entries);
+ else
+ return adls_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
}
-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)
+static const struct intel_ddi_buf_trans *
+adls_get_combo_buf_trans(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_ROCKETLAKE(dev_priv)) {
- *n_entries = ARRAY_SIZE(rkl_combo_phy_ddi_translations_dp_hbr2_hbr3);
- return rkl_combo_phy_ddi_translations_dp_hbr2_hbr3;
- } else 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 {
- if (IS_ROCKETLAKE(dev_priv)) {
- *n_entries = ARRAY_SIZE(rkl_combo_phy_ddi_translations_dp_hbr);
- return rkl_combo_phy_ddi_translations_dp_hbr;
- } else {
- *n_entries = ARRAY_SIZE(tgl_combo_phy_ddi_translations_dp_hbr);
- return tgl_combo_phy_ddi_translations_dp_hbr;
- }
- }
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+ return intel_get_buf_trans(&icl_combo_phy_ddi_translations_hdmi, n_entries);
+ else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
+ return adls_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
+ else
+ return adls_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
}
-static const struct cnl_ddi_buf_trans *
-tgl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
+static const struct intel_ddi_buf_trans *
+adlp_get_combo_buf_trans_dp(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *n_entries)
{
+ if (crtc_state->port_clock > 270000)
+ return intel_get_buf_trans(&adlp_combo_phy_ddi_translations_dp_hbr2_hbr3, n_entries);
+ else
+ return intel_get_buf_trans(&adlp_combo_phy_ddi_translations_dp_hbr, n_entries);
+}
+
+static const struct intel_ddi_buf_trans *
+adlp_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;
+ return intel_get_buf_trans(&adlp_combo_phy_ddi_translations_edp_hbr3,
+ n_entries);
} 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;
+ return intel_get_buf_trans(&tgl_combo_phy_ddi_translations_edp_hbr2_hobl,
+ n_entries);
} 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 intel_get_buf_trans(&adlp_combo_phy_ddi_translations_edp_up_to_hbr2,
+ n_entries);
}
- return tgl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+ return adlp_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
}
-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)
+static const struct intel_ddi_buf_trans *
+adlp_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);
+ return intel_get_buf_trans(&adlp_combo_phy_ddi_translations_hdmi, 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);
+ return adlp_get_combo_buf_trans_edp(encoder, crtc_state, n_entries);
else
- return tgl_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
+ return adlp_get_combo_buf_trans_dp(encoder, crtc_state, n_entries);
}
-static const struct tgl_dkl_phy_ddi_buf_trans *
-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 *
+static const struct intel_ddi_buf_trans *
tgl_get_dkl_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(tgl_dkl_phy_dp_ddi_trans_hbr2);
- return tgl_dkl_phy_dp_ddi_trans_hbr2;
+ return intel_get_buf_trans(&tgl_dkl_phy_ddi_translations_dp_hbr2,
+ n_entries);
} else {
- *n_entries = ARRAY_SIZE(tgl_dkl_phy_dp_ddi_trans);
- return tgl_dkl_phy_dp_ddi_trans;
+ return intel_get_buf_trans(&tgl_dkl_phy_ddi_translations_dp_hbr,
+ n_entries);
}
}
-const struct tgl_dkl_phy_ddi_buf_trans *
+static const struct intel_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);
+ return intel_get_buf_trans(&tgl_dkl_phy_ddi_translations_hdmi, n_entries);
else
return tgl_get_dkl_buf_trans_dp(encoder, crtc_state, n_entries);
}
-static const struct tgl_dkl_phy_ddi_buf_trans *
+static const struct intel_ddi_buf_trans *
adlp_get_dkl_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(adlp_dkl_phy_dp_ddi_trans_hbr2_hbr3);
- return adlp_dkl_phy_dp_ddi_trans_hbr2_hbr3;
+ return intel_get_buf_trans(&adlp_dkl_phy_ddi_translations_dp_hbr2_hbr3,
+ n_entries);
+ } else {
+ return intel_get_buf_trans(&adlp_dkl_phy_ddi_translations_dp_hbr,
+ n_entries);
}
-
- *n_entries = ARRAY_SIZE(adlp_dkl_phy_dp_ddi_trans_hbr);
- return adlp_dkl_phy_dp_ddi_trans_hbr;
}
-const struct tgl_dkl_phy_ddi_buf_trans *
+static const struct intel_ddi_buf_trans *
adlp_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);
+ return intel_get_buf_trans(&tgl_dkl_phy_ddi_translations_hdmi, n_entries);
else
return adlp_get_dkl_buf_trans_dp(encoder, crtc_state, n_entries);
}
@@ -1406,43 +1568,68 @@ int intel_ddi_hdmi_num_entries(struct intel_encoder *encoder,
int *default_entry)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
+ const struct intel_ddi_buf_trans *ddi_translations;
int n_entries;
- if (DISPLAY_VER(dev_priv) >= 12) {
- if (intel_phy_is_combo(dev_priv, phy))
- tgl_get_combo_buf_trans_hdmi(encoder, crtc_state, &n_entries);
- else
- tgl_get_dkl_buf_trans_hdmi(encoder, crtc_state, &n_entries);
- *default_entry = n_entries - 1;
- } else if (DISPLAY_VER(dev_priv) == 11) {
- if (intel_phy_is_combo(dev_priv, phy))
- icl_get_combo_buf_trans_hdmi(encoder, crtc_state, &n_entries);
- else
- 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);
- *default_entry = n_entries - 1;
- } else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
- bxt_get_buf_trans_hdmi(encoder, &n_entries);
- *default_entry = n_entries - 1;
- } else if (DISPLAY_VER(dev_priv) == 9) {
- intel_ddi_get_buf_trans_hdmi(encoder, &n_entries);
- *default_entry = 8;
- } else if (IS_BROADWELL(dev_priv)) {
- intel_ddi_get_buf_trans_hdmi(encoder, &n_entries);
- *default_entry = 7;
- } else if (IS_HASWELL(dev_priv)) {
- intel_ddi_get_buf_trans_hdmi(encoder, &n_entries);
- *default_entry = 6;
- } else {
- drm_WARN(&dev_priv->drm, 1, "ddi translation table missing\n");
+ ddi_translations = encoder->get_buf_trans(encoder, crtc_state, &n_entries);
+
+ if (drm_WARN_ON(&dev_priv->drm, !ddi_translations)) {
+ *default_entry = 0;
return 0;
}
- if (drm_WARN_ON_ONCE(&dev_priv->drm, n_entries == 0))
- return 0;
+ *default_entry = ddi_translations->hdmi_default_entry;
return n_entries;
}
+
+void intel_ddi_buf_trans_init(struct intel_encoder *encoder)
+{
+ struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+ enum phy phy = intel_port_to_phy(i915, encoder->port);
+
+ if (IS_ALDERLAKE_P(i915)) {
+ if (intel_phy_is_combo(i915, phy))
+ encoder->get_buf_trans = adlp_get_combo_buf_trans;
+ else
+ encoder->get_buf_trans = adlp_get_dkl_buf_trans;
+ } else if (IS_ALDERLAKE_S(i915)) {
+ encoder->get_buf_trans = adls_get_combo_buf_trans;
+ } else if (IS_ROCKETLAKE(i915)) {
+ encoder->get_buf_trans = rkl_get_combo_buf_trans;
+ } else if (IS_DG1(i915)) {
+ encoder->get_buf_trans = dg1_get_combo_buf_trans;
+ } else if (DISPLAY_VER(i915) >= 12) {
+ if (intel_phy_is_combo(i915, phy))
+ encoder->get_buf_trans = tgl_get_combo_buf_trans;
+ else
+ encoder->get_buf_trans = tgl_get_dkl_buf_trans;
+ } else if (DISPLAY_VER(i915) == 11) {
+ if (IS_PLATFORM(i915, INTEL_JASPERLAKE))
+ encoder->get_buf_trans = jsl_get_combo_buf_trans;
+ else if (IS_PLATFORM(i915, INTEL_ELKHARTLAKE))
+ encoder->get_buf_trans = ehl_get_combo_buf_trans;
+ else if (intel_phy_is_combo(i915, phy))
+ encoder->get_buf_trans = icl_get_combo_buf_trans;
+ else
+ encoder->get_buf_trans = icl_get_mg_buf_trans;
+ } else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) {
+ encoder->get_buf_trans = bxt_get_buf_trans;
+ } else if (IS_CML_ULX(i915) || IS_CFL_ULX(i915) || IS_KBL_ULX(i915)) {
+ encoder->get_buf_trans = kbl_y_get_buf_trans;
+ } else if (IS_CML_ULT(i915) || IS_CFL_ULT(i915) || IS_KBL_ULT(i915)) {
+ encoder->get_buf_trans = kbl_u_get_buf_trans;
+ } else if (IS_COMETLAKE(i915) || IS_COFFEELAKE(i915) || IS_KABYLAKE(i915)) {
+ encoder->get_buf_trans = kbl_get_buf_trans;
+ } else if (IS_SKL_ULX(i915)) {
+ encoder->get_buf_trans = skl_y_get_buf_trans;
+ } else if (IS_SKL_ULT(i915)) {
+ encoder->get_buf_trans = skl_u_get_buf_trans;
+ } else if (IS_SKYLAKE(i915)) {
+ encoder->get_buf_trans = skl_get_buf_trans;
+ } else if (IS_BROADWELL(i915)) {
+ encoder->get_buf_trans = bdw_get_buf_trans;
+ } else {
+ encoder->get_buf_trans = hsw_get_buf_trans;
+ }
+}
diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h
index 4c2efab38642..2acd720f9d4f 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h
+++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.h
@@ -12,7 +12,7 @@ struct drm_i915_private;
struct intel_encoder;
struct intel_crtc_state;
-struct ddi_buf_trans {
+struct hsw_ddi_buf_trans {
u32 trans1; /* balance leg enable, de-emph level */
u32 trans2; /* vref sel, vswing */
u8 i_boost; /* SKL: I_boost; valid: 0x0, 0x1, 0x3, 0x7 */
@@ -25,7 +25,7 @@ struct bxt_ddi_buf_trans {
u8 deemphasis;
};
-struct cnl_ddi_buf_trans {
+struct icl_ddi_buf_trans {
u8 dw2_swing_sel;
u8 dw7_n_scalar;
u8 dw4_cursor_coeff;
@@ -45,60 +45,26 @@ struct tgl_dkl_phy_ddi_buf_trans {
u32 dkl_de_emphasis_control;
};
-bool is_hobl_buf_trans(const struct cnl_ddi_buf_trans *table);
+union intel_ddi_buf_trans_entry {
+ struct hsw_ddi_buf_trans hsw;
+ struct bxt_ddi_buf_trans bxt;
+ struct icl_ddi_buf_trans icl;
+ struct icl_mg_phy_ddi_buf_trans mg;
+ struct tgl_dkl_phy_ddi_buf_trans dkl;
+};
+
+struct intel_ddi_buf_trans {
+ const union intel_ddi_buf_trans_entry *entries;
+ u8 num_entries;
+ u8 hdmi_default_entry;
+};
+
+bool is_hobl_buf_trans(const struct intel_ddi_buf_trans *table);
int intel_ddi_hdmi_num_entries(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int *default_entry);
-const struct ddi_buf_trans *
-intel_ddi_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries);
-const struct ddi_buf_trans *
-intel_ddi_get_buf_trans_fdi(struct drm_i915_private *dev_priv,
- int *n_entries);
-const struct ddi_buf_trans *
-intel_ddi_get_buf_trans_hdmi(struct intel_encoder *encoder,
- int *n_entries);
-const struct ddi_buf_trans *
-intel_ddi_get_buf_trans_dp(struct intel_encoder *encoder, int *n_entries);
-
-const struct bxt_ddi_buf_trans *
-bxt_get_buf_trans(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state,
- int *n_entries);
-
-const struct tgl_dkl_phy_ddi_buf_trans *
-adlp_get_dkl_buf_trans(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state,
- int *n_entries);
-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);
-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);
-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);
-const struct cnl_ddi_buf_trans *
-ehl_get_combo_buf_trans(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state,
- int *n_entries);
-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);
-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);
-
-const struct cnl_ddi_buf_trans *
-cnl_get_buf_trans(struct intel_encoder *encoder,
- const struct intel_crtc_state *crtc_state,
- int *n_entries);
+void intel_ddi_buf_trans_init(struct intel_encoder *encoder);
#endif
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 0a8a2395c8ac..134a6acbd8fb 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -59,6 +59,7 @@
#include "display/intel_hdmi.h"
#include "display/intel_lvds.h"
#include "display/intel_sdvo.h"
+#include "display/intel_snps_phy.h"
#include "display/intel_tv.h"
#include "display/intel_vdsc.h"
#include "display/intel_vrr.h"
@@ -975,7 +976,7 @@ void intel_enable_pipe(const struct intel_crtc_state *new_crtc_state)
/* FIXME: assert CPU port conditions for SNB+ */
}
- /* Wa_22012358565:adlp */
+ /* Wa_22012358565:adl-p */
if (DISPLAY_VER(dev_priv) == 13)
intel_de_rmw(dev_priv, PIPE_ARB_CTL(pipe),
0, PIPE_ARB_USE_PROG_SLOTS);
@@ -1035,6 +1036,10 @@ void intel_disable_pipe(const struct intel_crtc_state *old_crtc_state)
if (!IS_I830(dev_priv))
val &= ~PIPECONF_ENABLE;
+ if (DISPLAY_VER(dev_priv) >= 12)
+ intel_de_rmw(dev_priv, CHICKEN_TRANS(cpu_transcoder),
+ FECSTALL_DIS_DPTSTREAM_DPTTG, 0);
+
intel_de_write(dev_priv, reg, val);
if ((val & PIPECONF_ENABLE) == 0)
intel_wait_for_pipe_off(old_crtc_state);
@@ -1331,6 +1336,9 @@ retry:
ret = i915_gem_object_lock(obj, &ww);
if (!ret && phys_cursor)
ret = i915_gem_object_attach_phys(obj, alignment);
+ else if (!ret && HAS_LMEM(dev_priv))
+ ret = i915_gem_object_migrate(obj, &ww, INTEL_REGION_LMEM);
+ /* TODO: Do we need to sync when migration becomes async? */
if (!ret)
ret = i915_gem_object_pin_pages(obj);
if (ret)
@@ -1914,20 +1922,50 @@ static void intel_dpt_unpin(struct i915_address_space *vm)
i915_vma_put(dpt->vma);
}
+static bool
+intel_reuse_initial_plane_obj(struct drm_i915_private *i915,
+ const struct intel_initial_plane_config *plane_config,
+ struct drm_framebuffer **fb,
+ struct i915_vma **vma)
+{
+ struct intel_crtc *crtc;
+
+ for_each_intel_crtc(&i915->drm, crtc) {
+ struct intel_crtc_state *crtc_state =
+ to_intel_crtc_state(crtc->base.state);
+ struct intel_plane *plane =
+ to_intel_plane(crtc->base.primary);
+ struct intel_plane_state *plane_state =
+ to_intel_plane_state(plane->base.state);
+
+ if (!crtc_state->uapi.active)
+ continue;
+
+ if (!plane_state->ggtt_vma)
+ continue;
+
+ if (intel_plane_ggtt_offset(plane_state) == plane_config->base) {
+ *fb = plane_state->hw.fb;
+ *vma = plane_state->ggtt_vma;
+ return true;
+ }
+ }
+
+ return false;
+}
+
static void
-intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
+intel_find_initial_plane_obj(struct intel_crtc *crtc,
struct intel_initial_plane_config *plane_config)
{
- struct drm_device *dev = intel_crtc->base.dev;
+ struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
- struct drm_crtc *c;
- struct drm_plane *primary = intel_crtc->base.primary;
- struct drm_plane_state *plane_state = primary->state;
- struct intel_plane *intel_plane = to_intel_plane(primary);
- struct intel_plane_state *intel_state =
- to_intel_plane_state(plane_state);
struct intel_crtc_state *crtc_state =
- to_intel_crtc_state(intel_crtc->base.state);
+ to_intel_crtc_state(crtc->base.state);
+ struct intel_plane *plane =
+ to_intel_plane(crtc->base.primary);
+ struct intel_plane_state *plane_state =
+ to_intel_plane_state(plane->base.state);
struct drm_framebuffer *fb;
struct i915_vma *vma;
@@ -1939,7 +1977,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
if (!plane_config->fb)
return;
- if (intel_alloc_initial_plane_obj(intel_crtc, plane_config)) {
+ if (intel_alloc_initial_plane_obj(crtc, plane_config)) {
fb = &plane_config->fb->base;
vma = plane_config->vma;
goto valid_fb;
@@ -1949,25 +1987,8 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
* Failed to alloc the obj, check to see if we should share
* an fb with another CRTC instead
*/
- for_each_crtc(dev, c) {
- struct intel_plane_state *state;
-
- if (c == &intel_crtc->base)
- continue;
-
- if (!to_intel_crtc_state(c->state)->uapi.active)
- continue;
-
- state = to_intel_plane_state(c->primary->state);
- if (!state->ggtt_vma)
- continue;
-
- if (intel_plane_ggtt_offset(state) == plane_config->base) {
- fb = state->hw.fb;
- vma = state->ggtt_vma;
- goto valid_fb;
- }
- }
+ if (intel_reuse_initial_plane_obj(dev_priv, plane_config, &fb, &vma))
+ goto valid_fb;
/*
* We've failed to reconstruct the BIOS FB. Current display state
@@ -1976,7 +1997,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
* simplest solution is to just disable the primary plane now and
* pretend the BIOS never had it enabled.
*/
- intel_plane_disable_noatomic(intel_crtc, intel_plane);
+ intel_plane_disable_noatomic(crtc, plane);
if (crtc_state->bigjoiner) {
struct intel_crtc *slave =
crtc_state->bigjoiner_linked_crtc;
@@ -1986,40 +2007,38 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
return;
valid_fb:
- plane_state->rotation = plane_config->rotation;
- intel_fb_fill_view(to_intel_framebuffer(fb), plane_state->rotation,
- &intel_state->view);
+ plane_state->uapi.rotation = plane_config->rotation;
+ intel_fb_fill_view(to_intel_framebuffer(fb),
+ plane_state->uapi.rotation, &plane_state->view);
__i915_vma_pin(vma);
- intel_state->ggtt_vma = i915_vma_get(vma);
- if (intel_plane_uses_fence(intel_state) && i915_vma_pin_fence(vma) == 0)
- if (vma->fence)
- intel_state->flags |= PLANE_HAS_FENCE;
+ plane_state->ggtt_vma = i915_vma_get(vma);
+ if (intel_plane_uses_fence(plane_state) &&
+ i915_vma_pin_fence(vma) == 0 && vma->fence)
+ plane_state->flags |= PLANE_HAS_FENCE;
- plane_state->src_x = 0;
- plane_state->src_y = 0;
- plane_state->src_w = fb->width << 16;
- plane_state->src_h = fb->height << 16;
+ plane_state->uapi.src_x = 0;
+ plane_state->uapi.src_y = 0;
+ plane_state->uapi.src_w = fb->width << 16;
+ plane_state->uapi.src_h = fb->height << 16;
- plane_state->crtc_x = 0;
- plane_state->crtc_y = 0;
- plane_state->crtc_w = fb->width;
- plane_state->crtc_h = fb->height;
+ plane_state->uapi.crtc_x = 0;
+ plane_state->uapi.crtc_y = 0;
+ plane_state->uapi.crtc_w = fb->width;
+ plane_state->uapi.crtc_h = fb->height;
if (plane_config->tiling)
dev_priv->preserve_bios_swizzle = true;
- plane_state->fb = fb;
+ plane_state->uapi.fb = fb;
drm_framebuffer_get(fb);
- plane_state->crtc = &intel_crtc->base;
- intel_plane_copy_uapi_to_hw_state(intel_state, intel_state,
- intel_crtc);
+ plane_state->uapi.crtc = &crtc->base;
+ intel_plane_copy_uapi_to_hw_state(plane_state, plane_state, crtc);
intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
- atomic_or(to_intel_plane(primary)->frontbuffer_bit,
- &to_intel_frontbuffer(fb)->bits);
+ atomic_or(plane->frontbuffer_bit, &to_intel_frontbuffer(fb)->bits);
}
unsigned int
@@ -2193,8 +2212,29 @@ unlock:
clear_bit_unlock(I915_RESET_MODESET, &dev_priv->gt.reset.flags);
}
-static void icl_set_pipe_chicken(struct intel_crtc *crtc)
+static bool underrun_recovery_supported(const struct intel_crtc_state *crtc_state)
{
+ if (crtc_state->pch_pfit.enabled &&
+ (crtc_state->pipe_src_w > drm_rect_width(&crtc_state->pch_pfit.dst) ||
+ crtc_state->pipe_src_h > drm_rect_height(&crtc_state->pch_pfit.dst) ||
+ crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420))
+ return false;
+
+ if (crtc_state->dsc.compression_enable)
+ return false;
+
+ if (crtc_state->has_psr2)
+ return false;
+
+ if (crtc_state->splitter.enable)
+ return false;
+
+ return true;
+}
+
+static void icl_set_pipe_chicken(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);
enum pipe pipe = crtc->pipe;
u32 tmp;
@@ -2215,19 +2255,19 @@ static void icl_set_pipe_chicken(struct intel_crtc *crtc)
*/
tmp |= PIXEL_ROUNDING_TRUNC_FB_PASSTHRU;
- /*
- * "The underrun recovery mechanism should be disabled
- * when the following is enabled for this pipe:
- * WiDi
- * Downscaling (this includes YUV420 fullblend)
- * COG
- * DSC
- * PSR2"
- *
- * FIXME: enable whenever possible...
- */
- if (IS_ALDERLAKE_P(dev_priv))
- tmp |= UNDERRUN_RECOVERY_DISABLE;
+ if (IS_DG2(dev_priv)) {
+ /*
+ * Underrun recovery must always be disabled on DG2. However
+ * the chicken bit meaning is inverted compared to other
+ * platforms.
+ */
+ tmp &= ~UNDERRUN_RECOVERY_ENABLE_DG2;
+ } else if (DISPLAY_VER(dev_priv) >= 13) {
+ if (underrun_recovery_supported(crtc_state))
+ tmp &= ~UNDERRUN_RECOVERY_DISABLE_ADLP;
+ else
+ tmp |= UNDERRUN_RECOVERY_DISABLE_ADLP;
+ }
intel_de_write(dev_priv, PIPE_CHICKEN(pipe), tmp);
}
@@ -2706,10 +2746,10 @@ void hsw_disable_ips(const struct intel_crtc_state *crtc_state)
intel_wait_for_vblank(dev_priv, crtc->pipe);
}
-static void intel_crtc_dpms_overlay_disable(struct intel_crtc *intel_crtc)
+static void intel_crtc_dpms_overlay_disable(struct intel_crtc *crtc)
{
- if (intel_crtc->overlay)
- (void) intel_overlay_switch_off(intel_crtc->overlay);
+ if (crtc->overlay)
+ (void) intel_overlay_switch_off(crtc->overlay);
/* Let userspace switch the overlay on again. In most cases userspace
* has to recompute where to put it anyway.
@@ -3177,6 +3217,28 @@ static void intel_encoders_enable(struct intel_atomic_state *state,
}
}
+static void intel_encoders_pre_disable(struct intel_atomic_state *state,
+ struct intel_crtc *crtc)
+{
+ const struct intel_crtc_state *old_crtc_state =
+ intel_atomic_get_old_crtc_state(state, crtc);
+ const struct drm_connector_state *old_conn_state;
+ struct drm_connector *conn;
+ int i;
+
+ for_each_old_connector_in_state(&state->base, conn, old_conn_state, i) {
+ struct intel_encoder *encoder =
+ to_intel_encoder(old_conn_state->best_encoder);
+
+ if (old_conn_state->crtc != &crtc->base)
+ continue;
+
+ if (encoder->pre_disable)
+ encoder->pre_disable(state, encoder, old_crtc_state,
+ old_conn_state);
+ }
+}
+
static void intel_encoders_disable(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
@@ -3386,13 +3448,17 @@ static void glk_pipe_scaler_clock_gating_wa(struct drm_i915_private *dev_priv,
intel_de_write(dev_priv, CLKGATE_DIS_PSL(pipe), val);
}
-static void icl_pipe_mbus_enable(struct intel_crtc *crtc)
+static void icl_pipe_mbus_enable(struct intel_crtc *crtc, bool joined_mbus)
{
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe;
u32 val;
- val = MBUS_DBOX_A_CREDIT(2);
+ /* Wa_22010947358:adl-p */
+ if (IS_ALDERLAKE_P(dev_priv))
+ val = joined_mbus ? MBUS_DBOX_A_CREDIT(6) : MBUS_DBOX_A_CREDIT(4);
+ else
+ val = MBUS_DBOX_A_CREDIT(2);
if (DISPLAY_VER(dev_priv) >= 12) {
val |= MBUS_DBOX_BW_CREDIT(2);
@@ -3460,7 +3526,8 @@ static void icl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
* Enable sequence steps 1-7 on bigjoiner master
*/
intel_encoders_pre_pll_enable(state, master);
- intel_enable_shared_dpll(master_crtc_state);
+ if (master_crtc_state->shared_dpll)
+ intel_enable_shared_dpll(master_crtc_state);
intel_encoders_pre_enable(state, master);
/* and DSC on slave */
@@ -3518,7 +3585,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
crtc->active = true;
- /* Display WA #1180: WaDisableScalarClockGating: glk, cnl */
+ /* Display WA #1180: WaDisableScalarClockGating: glk */
psl_clkgate_wa = DISPLAY_VER(dev_priv) == 10 &&
new_crtc_state->pch_pfit.enabled;
if (psl_clkgate_wa)
@@ -3542,13 +3609,17 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
hsw_set_linetime_wm(new_crtc_state);
if (DISPLAY_VER(dev_priv) >= 11)
- icl_set_pipe_chicken(crtc);
+ icl_set_pipe_chicken(new_crtc_state);
if (dev_priv->display.initial_watermarks)
dev_priv->display.initial_watermarks(state, crtc);
- if (DISPLAY_VER(dev_priv) >= 11)
- icl_pipe_mbus_enable(crtc);
+ if (DISPLAY_VER(dev_priv) >= 11) {
+ const struct intel_dbuf_state *dbuf_state =
+ intel_atomic_get_new_dbuf_state(state);
+
+ icl_pipe_mbus_enable(crtc, dbuf_state->joined_mbus);
+ }
if (new_crtc_state->bigjoiner_slave)
intel_crtc_vblank_on(new_crtc_state);
@@ -3682,6 +3753,13 @@ bool intel_phy_is_combo(struct drm_i915_private *dev_priv, enum phy phy)
{
if (phy == PHY_NONE)
return false;
+ else if (IS_DG2(dev_priv))
+ /*
+ * DG2 outputs labelled as "combo PHY" in the bspec use
+ * SNPS PHYs with completely different programming,
+ * hence we always return false here.
+ */
+ return false;
else if (IS_ALDERLAKE_S(dev_priv))
return phy <= PHY_E;
else if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv))
@@ -3696,7 +3774,10 @@ bool intel_phy_is_combo(struct drm_i915_private *dev_priv, enum phy phy)
bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy)
{
- if (IS_ALDERLAKE_P(dev_priv))
+ if (IS_DG2(dev_priv))
+ /* DG2's "TC1" output uses a SNPS PHY */
+ return false;
+ else if (IS_ALDERLAKE_P(dev_priv))
return phy >= PHY_F && phy <= PHY_I;
else if (IS_TIGERLAKE(dev_priv))
return phy >= PHY_D && phy <= PHY_I;
@@ -3706,6 +3787,20 @@ bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy)
return false;
}
+bool intel_phy_is_snps(struct drm_i915_private *dev_priv, enum phy phy)
+{
+ if (phy == PHY_NONE)
+ return false;
+ else if (IS_DG2(dev_priv))
+ /*
+ * All four "combo" ports and the TC1 port (PHY E) use
+ * Synopsis PHYs.
+ */
+ return phy <= PHY_E;
+
+ return false;
+}
+
enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port)
{
if (DISPLAY_VER(i915) >= 13 && port >= PORT_D_XELPD)
@@ -3850,7 +3945,7 @@ static u64 get_crtc_power_domains(struct intel_crtc_state *crtc_state)
}
if (HAS_DDI(dev_priv) && crtc_state->has_audio)
- mask |= BIT_ULL(POWER_DOMAIN_AUDIO);
+ mask |= BIT_ULL(POWER_DOMAIN_AUDIO_MMIO);
if (crtc_state->shared_dpll)
mask |= BIT_ULL(POWER_DOMAIN_DISPLAY_CORE);
@@ -6487,23 +6582,21 @@ int intel_get_load_detect_pipe(struct drm_connector *connector,
struct intel_load_detect_pipe *old,
struct drm_modeset_acquire_ctx *ctx)
{
- struct intel_crtc *intel_crtc;
- struct intel_encoder *intel_encoder =
+ struct intel_encoder *encoder =
intel_attached_encoder(to_intel_connector(connector));
- struct drm_crtc *possible_crtc;
- struct drm_encoder *encoder = &intel_encoder->base;
- struct drm_crtc *crtc = NULL;
- struct drm_device *dev = encoder->dev;
+ struct intel_crtc *possible_crtc;
+ struct intel_crtc *crtc = NULL;
+ struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct drm_mode_config *config = &dev->mode_config;
struct drm_atomic_state *state = NULL, *restore_state = NULL;
struct drm_connector_state *connector_state;
struct intel_crtc_state *crtc_state;
- int ret, i = -1;
+ int ret;
drm_dbg_kms(&dev_priv->drm, "[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
connector->base.id, connector->name,
- encoder->base.id, encoder->name);
+ encoder->base.base.id, encoder->base.name);
old->restore_state = NULL;
@@ -6521,9 +6614,9 @@ int intel_get_load_detect_pipe(struct drm_connector *connector,
/* See if we already have a CRTC for this connector */
if (connector->state->crtc) {
- crtc = connector->state->crtc;
+ crtc = to_intel_crtc(connector->state->crtc);
- ret = drm_modeset_lock(&crtc->mutex, ctx);
+ ret = drm_modeset_lock(&crtc->base.mutex, ctx);
if (ret)
goto fail;
@@ -6532,17 +6625,17 @@ int intel_get_load_detect_pipe(struct drm_connector *connector,
}
/* Find an unused one (if possible) */
- for_each_crtc(dev, possible_crtc) {
- i++;
- if (!(encoder->possible_crtcs & (1 << i)))
+ for_each_intel_crtc(dev, possible_crtc) {
+ if (!(encoder->base.possible_crtcs &
+ drm_crtc_mask(&possible_crtc->base)))
continue;
- ret = drm_modeset_lock(&possible_crtc->mutex, ctx);
+ ret = drm_modeset_lock(&possible_crtc->base.mutex, ctx);
if (ret)
goto fail;
- if (possible_crtc->state->enable) {
- drm_modeset_unlock(&possible_crtc->mutex);
+ if (possible_crtc->base.state->enable) {
+ drm_modeset_unlock(&possible_crtc->base.mutex);
continue;
}
@@ -6561,8 +6654,6 @@ int intel_get_load_detect_pipe(struct drm_connector *connector,
}
found:
- intel_crtc = to_intel_crtc(crtc);
-
state = drm_atomic_state_alloc(dev);
restore_state = drm_atomic_state_alloc(dev);
if (!state || !restore_state) {
@@ -6579,11 +6670,11 @@ found:
goto fail;
}
- ret = drm_atomic_set_crtc_for_connector(connector_state, crtc);
+ ret = drm_atomic_set_crtc_for_connector(connector_state, &crtc->base);
if (ret)
goto fail;
- crtc_state = intel_atomic_get_crtc_state(state, intel_crtc);
+ crtc_state = intel_atomic_get_crtc_state(state, crtc);
if (IS_ERR(crtc_state)) {
ret = PTR_ERR(crtc_state);
goto fail;
@@ -6596,15 +6687,15 @@ found:
if (ret)
goto fail;
- ret = intel_modeset_disable_planes(state, crtc);
+ ret = intel_modeset_disable_planes(state, &crtc->base);
if (ret)
goto fail;
ret = PTR_ERR_OR_ZERO(drm_atomic_get_connector_state(restore_state, connector));
if (!ret)
- ret = PTR_ERR_OR_ZERO(drm_atomic_get_crtc_state(restore_state, crtc));
+ ret = PTR_ERR_OR_ZERO(drm_atomic_get_crtc_state(restore_state, &crtc->base));
if (!ret)
- ret = drm_atomic_add_affected_planes(restore_state, crtc);
+ ret = drm_atomic_add_affected_planes(restore_state, &crtc->base);
if (ret) {
drm_dbg_kms(&dev_priv->drm,
"Failed to create a copy of old state to restore: %i\n",
@@ -6623,7 +6714,7 @@ found:
drm_atomic_state_put(state);
/* let the connector get through one full cycle before testing */
- intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
+ intel_wait_for_vblank(dev_priv, crtc->pipe);
return true;
fail:
@@ -7295,12 +7386,13 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
}
if (dev_priv->display.compute_pipe_wm) {
- ret = dev_priv->display.compute_pipe_wm(crtc_state);
+ ret = dev_priv->display.compute_pipe_wm(state, crtc);
if (ret) {
drm_dbg_kms(&dev_priv->drm,
"Target pipe watermarks are invalid\n");
return ret;
}
+
}
if (dev_priv->display.compute_intermediate_wm) {
@@ -7313,7 +7405,7 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
* old state and the new state. We can program these
* immediately.
*/
- ret = dev_priv->display.compute_intermediate_wm(crtc_state);
+ ret = dev_priv->display.compute_intermediate_wm(state, crtc);
if (ret) {
drm_dbg_kms(&dev_priv->drm,
"No valid intermediate pipe watermarks are possible\n");
@@ -8636,10 +8728,11 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
PIPE_CONF_CHECK_BOOL(double_wide);
- PIPE_CONF_CHECK_P(shared_dpll);
+ if (dev_priv->dpll.mgr)
+ PIPE_CONF_CHECK_P(shared_dpll);
/* FIXME do the readout properly and get rid of this quirk */
- if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {
+ if (dev_priv->dpll.mgr && !PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {
PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
@@ -8671,7 +8764,9 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_ssc);
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_bias);
PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);
+ }
+ if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {
PIPE_CONF_CHECK_X(dsi_pll.ctrl);
PIPE_CONF_CHECK_X(dsi_pll.div);
@@ -9009,6 +9104,10 @@ verify_crtc_state(struct intel_crtc *crtc,
if (!new_crtc_state->hw.active)
return;
+ if (new_crtc_state->bigjoiner_slave)
+ /* No PLLs set for slave */
+ pipe_config->shared_dpll = NULL;
+
intel_pipe_config_sanity_check(dev_priv, pipe_config);
if (!intel_pipe_config_compare(new_crtc_state,
@@ -9112,6 +9211,55 @@ verify_shared_dpll_state(struct intel_crtc *crtc,
}
static void
+verify_mpllb_state(struct intel_atomic_state *state,
+ struct intel_crtc_state *new_crtc_state)
+{
+ struct drm_i915_private *i915 = to_i915(state->base.dev);
+ struct intel_mpllb_state mpllb_hw_state = { 0 };
+ struct intel_mpllb_state *mpllb_sw_state = &new_crtc_state->mpllb_state;
+ struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
+ struct intel_encoder *encoder;
+
+ if (!IS_DG2(i915))
+ return;
+
+ if (!new_crtc_state->hw.active)
+ return;
+
+ if (new_crtc_state->bigjoiner_slave)
+ return;
+
+ encoder = intel_get_crtc_new_encoder(state, new_crtc_state);
+ intel_mpllb_readout_hw_state(encoder, &mpllb_hw_state);
+
+#define MPLLB_CHECK(name) do { \
+ if (mpllb_sw_state->name != mpllb_hw_state.name) { \
+ pipe_config_mismatch(false, crtc, "MPLLB:" __stringify(name), \
+ "(expected 0x%08x, found 0x%08x)", \
+ mpllb_sw_state->name, \
+ mpllb_hw_state.name); \
+ } \
+} while (0)
+
+ MPLLB_CHECK(mpllb_cp);
+ MPLLB_CHECK(mpllb_div);
+ MPLLB_CHECK(mpllb_div2);
+ MPLLB_CHECK(mpllb_fracn1);
+ MPLLB_CHECK(mpllb_fracn2);
+ MPLLB_CHECK(mpllb_sscen);
+ MPLLB_CHECK(mpllb_sscstep);
+
+ /*
+ * ref_control is handled by the hardware/firemware and never
+ * programmed by the software, but the proper values are supplied
+ * in the bspec for verification purposes.
+ */
+ MPLLB_CHECK(ref_control);
+
+#undef MPLLB_CHECK
+}
+
+static void
intel_modeset_verify_crtc(struct intel_crtc *crtc,
struct intel_atomic_state *state,
struct intel_crtc_state *old_crtc_state,
@@ -9124,6 +9272,7 @@ intel_modeset_verify_crtc(struct intel_crtc *crtc,
verify_connector_state(state, crtc);
verify_crtc_state(crtc, old_crtc_state, new_crtc_state);
verify_shared_dpll_state(crtc, old_crtc_state, new_crtc_state);
+ verify_mpllb_state(state, new_crtc_state);
}
static void
@@ -9749,7 +9898,7 @@ static int intel_atomic_check_async(struct intel_atomic_state *state)
/*
* FIXME: This check is kept generic for all platforms.
- * Need to verify this for all gen9 and gen10 platforms to enable
+ * Need to verify this for all gen9 platforms to enable
* this selectively if required.
*/
switch (new_plane_state->hw.fb->modifier) {
@@ -10160,7 +10309,7 @@ static void intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state,
hsw_set_linetime_wm(new_crtc_state);
if (DISPLAY_VER(dev_priv) >= 11)
- icl_set_pipe_chicken(crtc);
+ icl_set_pipe_chicken(new_crtc_state);
}
static void commit_pipe_pre_planes(struct intel_atomic_state *state,
@@ -10294,6 +10443,8 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
drm_WARN_ON(&dev_priv->drm, old_crtc_state->bigjoiner_slave);
+ intel_encoders_pre_disable(state, crtc);
+
intel_crtc_disable_planes(state, crtc);
/*
@@ -11328,7 +11479,12 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
if (!HAS_DISPLAY(dev_priv))
return;
- if (IS_ALDERLAKE_P(dev_priv)) {
+ if (IS_DG2(dev_priv)) {
+ intel_ddi_init(dev_priv, PORT_A);
+ intel_ddi_init(dev_priv, PORT_B);
+ intel_ddi_init(dev_priv, PORT_C);
+ intel_ddi_init(dev_priv, PORT_D_XELPD);
+ } else if (IS_ALDERLAKE_P(dev_priv)) {
intel_ddi_init(dev_priv, PORT_A);
intel_ddi_init(dev_priv, PORT_B);
intel_ddi_init(dev_priv, PORT_TC1);
@@ -11375,13 +11531,6 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
intel_ddi_init(dev_priv, PORT_B);
intel_ddi_init(dev_priv, PORT_C);
vlv_dsi_init(dev_priv);
- } else if (DISPLAY_VER(dev_priv) == 10) {
- intel_ddi_init(dev_priv, PORT_A);
- intel_ddi_init(dev_priv, PORT_B);
- intel_ddi_init(dev_priv, PORT_C);
- intel_ddi_init(dev_priv, PORT_D);
- intel_ddi_init(dev_priv, PORT_E);
- intel_ddi_init(dev_priv, PORT_F);
} else if (DISPLAY_VER(dev_priv) >= 9) {
intel_ddi_init(dev_priv, PORT_A);
intel_ddi_init(dev_priv, PORT_B);
@@ -11790,7 +11939,7 @@ intel_user_framebuffer_create(struct drm_device *dev,
/* object is backed with LMEM for discrete */
i915 = to_i915(obj->base.dev);
- if (HAS_LMEM(i915) && !i915_gem_object_is_lmem(obj)) {
+ if (HAS_LMEM(i915) && !i915_gem_object_can_migrate(obj, INTEL_REGION_LMEM)) {
/* object is "remote", not in local memory */
i915_gem_object_put(obj);
return ERR_PTR(-EREMOTE);
@@ -13136,7 +13285,7 @@ get_encoder_power_domains(struct drm_i915_private *dev_priv)
static void intel_early_display_was(struct drm_i915_private *dev_priv)
{
/*
- * Display WA #1185 WaDisableDARBFClkGating:cnl,glk,icl,ehl,tgl
+ * Display WA #1185 WaDisableDARBFClkGating:glk,icl,ehl,tgl
* Also known as Wa_14010480278.
*/
if (IS_DISPLAY_VER(dev_priv, 10, 12))
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index c9dbaf074d77..284936f0ddab 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -561,6 +561,7 @@ struct drm_display_mode *
intel_encoder_current_mode(struct intel_encoder *encoder);
bool intel_phy_is_combo(struct drm_i915_private *dev_priv, enum phy phy);
bool intel_phy_is_tc(struct drm_i915_private *dev_priv, enum phy phy);
+bool intel_phy_is_snps(struct drm_i915_private *dev_priv, enum phy phy);
enum tc_port intel_port_to_tc(struct drm_i915_private *dev_priv,
enum port port);
int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 88bb05d5c483..8fdacb252bb1 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -544,6 +544,11 @@ static int i915_dmc_info(struct seq_file *m, void *unused)
seq_printf(m, "fw loaded: %s\n", yesno(intel_dmc_has_payload(dev_priv)));
seq_printf(m, "path: %s\n", dmc->fw_path);
+ seq_printf(m, "Pipe A fw support: %s\n",
+ yesno(GRAPHICS_VER(dev_priv) >= 12));
+ seq_printf(m, "Pipe A fw loaded: %s\n", yesno(dmc->dmc_info[DMC_FW_PIPEA].payload));
+ seq_printf(m, "Pipe B fw support: %s\n", yesno(IS_ALDERLAKE_P(dev_priv)));
+ seq_printf(m, "Pipe B fw loaded: %s\n", yesno(dmc->dmc_info[DMC_FW_PIPEB].payload));
if (!intel_dmc_has_payload(dev_priv))
goto out;
@@ -582,7 +587,7 @@ static int i915_dmc_info(struct seq_file *m, void *unused)
out:
seq_printf(m, "program base: 0x%08x\n",
- intel_de_read(dev_priv, DMC_PROGRAM(0)));
+ intel_de_read(dev_priv, DMC_PROGRAM(dmc->dmc_info[DMC_FW_MAIN].start_mmioaddr, 0)));
seq_printf(m, "ssp base: 0x%08x\n",
intel_de_read(dev_priv, DMC_SSP_BASE));
seq_printf(m, "htp: 0x%08x\n", intel_de_read(dev_priv, DMC_HTP_SKL));
@@ -1225,7 +1230,7 @@ static int i915_ddb_info(struct seq_file *m, void *unused)
static void drrs_status_per_crtc(struct seq_file *m,
struct drm_device *dev,
- struct intel_crtc *intel_crtc)
+ struct intel_crtc *crtc)
{
struct drm_i915_private *dev_priv = to_i915(dev);
struct i915_drrs *drrs = &dev_priv->drrs;
@@ -1237,7 +1242,7 @@ static void drrs_status_per_crtc(struct seq_file *m,
drm_for_each_connector_iter(connector, &conn_iter) {
bool supported = false;
- if (connector->state->crtc != &intel_crtc->base)
+ if (connector->state->crtc != &crtc->base)
continue;
seq_printf(m, "%s:\n", connector->name);
@@ -1252,7 +1257,7 @@ static void drrs_status_per_crtc(struct seq_file *m,
seq_puts(m, "\n");
- if (to_intel_crtc_state(intel_crtc->base.state)->has_drrs) {
+ if (to_intel_crtc_state(crtc->base.state)->has_drrs) {
struct intel_panel *panel;
mutex_lock(&drrs->mutex);
@@ -1298,16 +1303,16 @@ static int i915_drrs_status(struct seq_file *m, void *unused)
{
struct drm_i915_private *dev_priv = node_to_i915(m->private);
struct drm_device *dev = &dev_priv->drm;
- struct intel_crtc *intel_crtc;
+ struct intel_crtc *crtc;
int active_crtc_cnt = 0;
drm_modeset_lock_all(dev);
- for_each_intel_crtc(dev, intel_crtc) {
- if (intel_crtc->base.state->active) {
+ for_each_intel_crtc(dev, crtc) {
+ if (crtc->base.state->active) {
active_crtc_cnt++;
seq_printf(m, "\nCRTC %d: ", active_crtc_cnt);
- drrs_status_per_crtc(m, dev, intel_crtc);
+ drrs_status_per_crtc(m, dev, crtc);
}
}
drm_modeset_unlock_all(dev);
@@ -2064,7 +2069,7 @@ i915_fifo_underrun_reset_write(struct file *filp,
size_t cnt, loff_t *ppos)
{
struct drm_i915_private *dev_priv = filp->private_data;
- struct intel_crtc *intel_crtc;
+ struct intel_crtc *crtc;
struct drm_device *dev = &dev_priv->drm;
int ret;
bool reset;
@@ -2076,15 +2081,15 @@ i915_fifo_underrun_reset_write(struct file *filp,
if (!reset)
return cnt;
- for_each_intel_crtc(dev, intel_crtc) {
+ for_each_intel_crtc(dev, crtc) {
struct drm_crtc_commit *commit;
struct intel_crtc_state *crtc_state;
- ret = drm_modeset_lock_single_interruptible(&intel_crtc->base.mutex);
+ ret = drm_modeset_lock_single_interruptible(&crtc->base.mutex);
if (ret)
return ret;
- crtc_state = to_intel_crtc_state(intel_crtc->base.state);
+ crtc_state = to_intel_crtc_state(crtc->base.state);
commit = crtc_state->uapi.commit;
if (commit) {
ret = wait_for_completion_interruptible(&commit->hw_done);
@@ -2095,12 +2100,12 @@ i915_fifo_underrun_reset_write(struct file *filp,
if (!ret && crtc_state->hw.active) {
drm_dbg_kms(&dev_priv->drm,
"Re-arming FIFO underruns on pipe %c\n",
- pipe_name(intel_crtc->pipe));
+ pipe_name(crtc->pipe));
- intel_crtc_arm_fifo_underrun(intel_crtc, crtc_state);
+ intel_crtc_arm_fifo_underrun(crtc, crtc_state);
}
- drm_modeset_unlock(&intel_crtc->base.mutex);
+ drm_modeset_unlock(&crtc->base.mutex);
if (ret)
return ret;
@@ -2251,6 +2256,11 @@ static int i915_lpsp_capability_show(struct seq_file *m, void *data)
if (connector->status != connector_status_connected)
return -ENODEV;
+ if (DISPLAY_VER(i915) >= 13) {
+ LPSP_CAPABLE(encoder->port <= PORT_B);
+ return 0;
+ }
+
switch (DISPLAY_VER(i915)) {
case 12:
/*
@@ -2385,6 +2395,73 @@ static const struct file_operations i915_dsc_fec_support_fops = {
.write = i915_dsc_fec_support_write
};
+static int i915_dsc_bpp_show(struct seq_file *m, void *data)
+{
+ struct drm_connector *connector = m->private;
+ struct drm_device *dev = connector->dev;
+ struct drm_crtc *crtc;
+ struct intel_crtc_state *crtc_state;
+ struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
+ int ret;
+
+ if (!encoder)
+ return -ENODEV;
+
+ ret = drm_modeset_lock_single_interruptible(&dev->mode_config.connection_mutex);
+ if (ret)
+ return ret;
+
+ crtc = connector->state->crtc;
+ if (connector->status != connector_status_connected || !crtc) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ crtc_state = to_intel_crtc_state(crtc->state);
+ seq_printf(m, "Compressed_BPP: %d\n", crtc_state->dsc.compressed_bpp);
+
+out: drm_modeset_unlock(&dev->mode_config.connection_mutex);
+
+ return ret;
+}
+
+static ssize_t i915_dsc_bpp_write(struct file *file,
+ const char __user *ubuf,
+ size_t len, loff_t *offp)
+{
+ struct drm_connector *connector =
+ ((struct seq_file *)file->private_data)->private;
+ struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ int dsc_bpp = 0;
+ int ret;
+
+ ret = kstrtoint_from_user(ubuf, len, 0, &dsc_bpp);
+ if (ret < 0)
+ return ret;
+
+ intel_dp->force_dsc_bpp = dsc_bpp;
+ *offp += len;
+
+ return len;
+}
+
+static int i915_dsc_bpp_open(struct inode *inode,
+ struct file *file)
+{
+ return single_open(file, i915_dsc_bpp_show,
+ inode->i_private);
+}
+
+static const struct file_operations i915_dsc_bpp_fops = {
+ .owner = THIS_MODULE,
+ .open = i915_dsc_bpp_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = i915_dsc_bpp_write
+};
+
/**
* intel_connector_debugfs_add - add i915 specific connector debugfs files
* @connector: pointer to a registered drm_connector
@@ -2423,10 +2500,17 @@ int intel_connector_debugfs_add(struct drm_connector *connector)
connector, &i915_hdcp_sink_capability_fops);
}
- if ((DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) && ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort && !to_intel_connector(connector)->mst_port) || connector->connector_type == DRM_MODE_CONNECTOR_eDP))
- debugfs_create_file("i915_dsc_fec_support", S_IRUGO, root,
+ if (DISPLAY_VER(dev_priv) >= 11 &&
+ ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort &&
+ !to_intel_connector(connector)->mst_port) ||
+ connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
+ debugfs_create_file("i915_dsc_fec_support", 0644, root,
connector, &i915_dsc_fec_support_fops);
+ debugfs_create_file("i915_dsc_bpp", 0644, root,
+ connector, &i915_dsc_bpp_fops);
+ }
+
/* Legacy panels doesn't lpsp on any platform */
if ((DISPLAY_VER(dev_priv) >= 9 || IS_HASWELL(dev_priv) ||
IS_BROADWELL(dev_priv)) &&
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index 86b7ac7b65ec..cce1a926fcc1 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -18,6 +18,7 @@
#include "intel_pm.h"
#include "intel_pps.h"
#include "intel_sideband.h"
+#include "intel_snps_phy.h"
#include "intel_tc.h"
#include "intel_vga.h"
@@ -106,8 +107,10 @@ intel_display_power_domain_str(enum intel_display_power_domain domain)
return "PORT_OTHER";
case POWER_DOMAIN_VGA:
return "VGA";
- case POWER_DOMAIN_AUDIO:
- return "AUDIO";
+ case POWER_DOMAIN_AUDIO_MMIO:
+ return "AUDIO_MMIO";
+ case POWER_DOMAIN_AUDIO_PLAYBACK:
+ return "AUDIO_PLAYBACK";
case POWER_DOMAIN_AUX_A:
return "AUX_A";
case POWER_DOMAIN_AUX_B:
@@ -341,6 +344,17 @@ static void hsw_wait_for_power_well_enable(struct drm_i915_private *dev_priv,
{
const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
int pw_idx = power_well->desc->hsw.idx;
+ int enable_delay = power_well->desc->hsw.fixed_enable_delay;
+
+ /*
+ * For some power wells we're not supposed to watch the status bit for
+ * an ack, but rather just wait a fixed amount of time and then
+ * proceed. This is only used on DG2.
+ */
+ if (IS_DG2(dev_priv) && enable_delay) {
+ usleep_range(enable_delay, 2 * enable_delay);
+ return;
+ }
/* Timeout for PW1:10 us, AUX:not specified, other PWs:20 us. */
if (intel_de_wait_for_set(dev_priv, regs->driver,
@@ -436,17 +450,6 @@ static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
hsw_wait_for_power_well_enable(dev_priv, power_well, false);
- /* Display WA #1178: cnl */
- if (IS_CANNONLAKE(dev_priv) &&
- pw_idx >= GLK_PW_CTL_IDX_AUX_B &&
- pw_idx <= CNL_PW_CTL_IDX_AUX_F) {
- u32 val;
-
- val = intel_de_read(dev_priv, CNL_AUX_ANAOVRD1(pw_idx));
- val |= CNL_AUX_ANAOVRD1_ENABLE | CNL_AUX_ANAOVRD1_LDO_BYPASS;
- intel_de_write(dev_priv, CNL_AUX_ANAOVRD1(pw_idx), val);
- }
-
if (power_well->desc->hsw.has_fuses) {
enum skl_power_gate pg;
@@ -961,8 +964,9 @@ static void bxt_disable_dc9(struct drm_i915_private *dev_priv)
static void assert_dmc_loaded(struct drm_i915_private *dev_priv)
{
drm_WARN_ONCE(&dev_priv->drm,
- !intel_de_read(dev_priv, DMC_PROGRAM(0)),
- "DMC program storage start is NULL\n");
+ !intel_de_read(dev_priv,
+ DMC_PROGRAM(dev_priv->dmc.dmc_info[DMC_FW_MAIN].start_mmioaddr, 0)),
+ "DMC program storage start is NULL\n");
drm_WARN_ONCE(&dev_priv->drm, !intel_de_read(dev_priv, DMC_SSP_BASE),
"DMC SSP Base Not fine\n");
drm_WARN_ONCE(&dev_priv->drm, !intel_de_read(dev_priv, DMC_HTP_SKL),
@@ -2507,7 +2511,8 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
BIT_ULL(POWER_DOMAIN_PORT_DSI) | \
BIT_ULL(POWER_DOMAIN_PORT_CRT) | \
BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_MMIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_PLAYBACK) | \
BIT_ULL(POWER_DOMAIN_AUX_B) | \
BIT_ULL(POWER_DOMAIN_AUX_C) | \
BIT_ULL(POWER_DOMAIN_GMBUS) | \
@@ -2557,7 +2562,8 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
BIT_ULL(POWER_DOMAIN_PORT_DSI) | \
BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_MMIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_PLAYBACK) | \
BIT_ULL(POWER_DOMAIN_AUX_B) | \
BIT_ULL(POWER_DOMAIN_AUX_C) | \
BIT_ULL(POWER_DOMAIN_AUX_D) | \
@@ -2590,7 +2596,8 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
BIT_ULL(POWER_DOMAIN_PORT_CRT) | /* DDI E */ \
BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_MMIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_PLAYBACK) | \
BIT_ULL(POWER_DOMAIN_INIT))
#define BDW_DISPLAY_POWER_DOMAINS ( \
@@ -2606,7 +2613,8 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
BIT_ULL(POWER_DOMAIN_PORT_CRT) | /* DDI E */ \
BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_MMIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_PLAYBACK) | \
BIT_ULL(POWER_DOMAIN_INIT))
#define SKL_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
@@ -2624,7 +2632,8 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
BIT_ULL(POWER_DOMAIN_AUX_B) | \
BIT_ULL(POWER_DOMAIN_AUX_C) | \
BIT_ULL(POWER_DOMAIN_AUX_D) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_MMIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_PLAYBACK) | \
BIT_ULL(POWER_DOMAIN_VGA) | \
BIT_ULL(POWER_DOMAIN_INIT))
#define SKL_DISPLAY_DDI_IO_A_E_POWER_DOMAINS ( \
@@ -2659,7 +2668,8 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
BIT_ULL(POWER_DOMAIN_AUX_B) | \
BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_MMIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_PLAYBACK) | \
BIT_ULL(POWER_DOMAIN_VGA) | \
BIT_ULL(POWER_DOMAIN_INIT))
#define BXT_DISPLAY_DC_OFF_POWER_DOMAINS ( \
@@ -2692,7 +2702,8 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
BIT_ULL(POWER_DOMAIN_AUX_B) | \
BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_MMIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_PLAYBACK) | \
BIT_ULL(POWER_DOMAIN_VGA) | \
BIT_ULL(POWER_DOMAIN_INIT))
#define GLK_DISPLAY_DDI_IO_A_POWER_DOMAINS ( \
@@ -2731,63 +2742,6 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
BIT_ULL(POWER_DOMAIN_GMBUS) | \
BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_A) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C) | \
- BIT_ULL(POWER_DOMAIN_TRANSCODER_C) | \
- BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) | \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_F_LANES) | \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_AUX_D) | \
- BIT_ULL(POWER_DOMAIN_AUX_F) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
- BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_DDI_A_IO_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_DDI_B_IO_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_DDI_C_IO_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_DDI_D_IO_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_D_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_AUX_A_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_AUX_IO_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_AUX_B_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_B) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_AUX_C_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_C) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_AUX_D_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_D) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_AUX_F_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_AUX_F) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_DDI_F_IO_POWER_DOMAINS ( \
- BIT_ULL(POWER_DOMAIN_PORT_DDI_F_IO) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-#define CNL_DISPLAY_DC_OFF_POWER_DOMAINS ( \
- CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS | \
- BIT_ULL(POWER_DOMAIN_GT_IRQ) | \
- BIT_ULL(POWER_DOMAIN_MODESET) | \
- BIT_ULL(POWER_DOMAIN_AUX_A) | \
- BIT_ULL(POWER_DOMAIN_INIT))
-
/*
* ICL PW_0/PG_0 domains (HW/DMC control):
* - PCI
@@ -2829,7 +2783,8 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
BIT_ULL(POWER_DOMAIN_AUX_E_TBT) | \
BIT_ULL(POWER_DOMAIN_AUX_F_TBT) | \
BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_MMIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_PLAYBACK) | \
BIT_ULL(POWER_DOMAIN_INIT))
/*
* - transcoder WD
@@ -2921,7 +2876,8 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
BIT_ULL(POWER_DOMAIN_AUX_TBT5) | \
BIT_ULL(POWER_DOMAIN_AUX_TBT6) | \
BIT_ULL(POWER_DOMAIN_VGA) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_MMIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_PLAYBACK) | \
BIT_ULL(POWER_DOMAIN_INIT))
#define TGL_PW_2_POWER_DOMAINS ( \
@@ -2991,7 +2947,8 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
RKL_PW_4_POWER_DOMAINS | \
BIT_ULL(POWER_DOMAIN_PIPE_B) | \
BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_MMIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_PLAYBACK) | \
BIT_ULL(POWER_DOMAIN_VGA) | \
BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
BIT_ULL(POWER_DOMAIN_PORT_DDI_LANES_TC1) | \
@@ -3029,6 +2986,35 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
BIT_ULL(POWER_DOMAIN_INIT))
/*
+ * DG1 onwards Audio MMIO/VERBS lies in PG0 power well.
+ */
+#define DG1_PW_3_POWER_DOMAINS ( \
+ TGL_PW_4_POWER_DOMAINS | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B) | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_B) | \
+ BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_LANES_TC1) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_LANES_TC2) | \
+ BIT_ULL(POWER_DOMAIN_AUX_USBC1) | \
+ BIT_ULL(POWER_DOMAIN_AUX_USBC2) | \
+ BIT_ULL(POWER_DOMAIN_VGA) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_PLAYBACK) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+
+#define DG1_PW_2_POWER_DOMAINS ( \
+ DG1_PW_3_POWER_DOMAINS | \
+ BIT_ULL(POWER_DOMAIN_TRANSCODER_VDSC_PW2) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+
+#define DG1_DISPLAY_DC_OFF_POWER_DOMAINS ( \
+ DG1_PW_3_POWER_DOMAINS | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_MMIO) | \
+ BIT_ULL(POWER_DOMAIN_MODESET) | \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+
+/*
* XE_LPD Power Domains
*
* Previous platforms required that PG(n-1) be enabled before PG(n). That
@@ -3073,7 +3059,7 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
XELPD_PW_B_POWER_DOMAINS | \
XELPD_PW_C_POWER_DOMAINS | \
XELPD_PW_D_POWER_DOMAINS | \
- BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_PLAYBACK) | \
BIT_ULL(POWER_DOMAIN_VGA) | \
BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) | \
BIT_ULL(POWER_DOMAIN_PORT_DDI_LANES_D_XELPD) | \
@@ -3114,6 +3100,7 @@ intel_display_power_put_mask_in_set(struct drm_i915_private *i915,
#define XELPD_DISPLAY_DC_OFF_POWER_DOMAINS ( \
XELPD_PW_2_POWER_DOMAINS | \
+ BIT_ULL(POWER_DOMAIN_AUDIO_MMIO) | \
BIT_ULL(POWER_DOMAIN_MODESET) | \
BIT_ULL(POWER_DOMAIN_AUX_A) | \
BIT_ULL(POWER_DOMAIN_AUX_B) | \
@@ -3694,148 +3681,6 @@ static const struct i915_power_well_desc glk_power_wells[] = {
},
};
-static const struct i915_power_well_desc cnl_power_wells[] = {
- {
- .name = "always-on",
- .always_on = true,
- .domains = POWER_DOMAIN_MASK,
- .ops = &i9xx_always_on_power_well_ops,
- .id = DISP_PW_ID_NONE,
- },
- {
- .name = "power well 1",
- /* Handled by the DMC firmware */
- .always_on = true,
- .domains = 0,
- .ops = &hsw_power_well_ops,
- .id = SKL_DISP_PW_1,
- {
- .hsw.regs = &hsw_power_well_regs,
- .hsw.idx = SKL_PW_CTL_IDX_PW_1,
- .hsw.has_fuses = true,
- },
- },
- {
- .name = "AUX A",
- .domains = CNL_DISPLAY_AUX_A_POWER_DOMAINS,
- .ops = &hsw_power_well_ops,
- .id = DISP_PW_ID_NONE,
- {
- .hsw.regs = &hsw_power_well_regs,
- .hsw.idx = GLK_PW_CTL_IDX_AUX_A,
- },
- },
- {
- .name = "AUX B",
- .domains = CNL_DISPLAY_AUX_B_POWER_DOMAINS,
- .ops = &hsw_power_well_ops,
- .id = DISP_PW_ID_NONE,
- {
- .hsw.regs = &hsw_power_well_regs,
- .hsw.idx = GLK_PW_CTL_IDX_AUX_B,
- },
- },
- {
- .name = "AUX C",
- .domains = CNL_DISPLAY_AUX_C_POWER_DOMAINS,
- .ops = &hsw_power_well_ops,
- .id = DISP_PW_ID_NONE,
- {
- .hsw.regs = &hsw_power_well_regs,
- .hsw.idx = GLK_PW_CTL_IDX_AUX_C,
- },
- },
- {
- .name = "AUX D",
- .domains = CNL_DISPLAY_AUX_D_POWER_DOMAINS,
- .ops = &hsw_power_well_ops,
- .id = DISP_PW_ID_NONE,
- {
- .hsw.regs = &hsw_power_well_regs,
- .hsw.idx = CNL_PW_CTL_IDX_AUX_D,
- },
- },
- {
- .name = "DC off",
- .domains = CNL_DISPLAY_DC_OFF_POWER_DOMAINS,
- .ops = &gen9_dc_off_power_well_ops,
- .id = SKL_DISP_DC_OFF,
- },
- {
- .name = "power well 2",
- .domains = CNL_DISPLAY_POWERWELL_2_POWER_DOMAINS,
- .ops = &hsw_power_well_ops,
- .id = SKL_DISP_PW_2,
- {
- .hsw.regs = &hsw_power_well_regs,
- .hsw.idx = SKL_PW_CTL_IDX_PW_2,
- .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
- .hsw.has_vga = true,
- .hsw.has_fuses = true,
- },
- },
- {
- .name = "DDI A IO power well",
- .domains = CNL_DISPLAY_DDI_A_IO_POWER_DOMAINS,
- .ops = &hsw_power_well_ops,
- .id = DISP_PW_ID_NONE,
- {
- .hsw.regs = &hsw_power_well_regs,
- .hsw.idx = GLK_PW_CTL_IDX_DDI_A,
- },
- },
- {
- .name = "DDI B IO power well",
- .domains = CNL_DISPLAY_DDI_B_IO_POWER_DOMAINS,
- .ops = &hsw_power_well_ops,
- .id = DISP_PW_ID_NONE,
- {
- .hsw.regs = &hsw_power_well_regs,
- .hsw.idx = SKL_PW_CTL_IDX_DDI_B,
- },
- },
- {
- .name = "DDI C IO power well",
- .domains = CNL_DISPLAY_DDI_C_IO_POWER_DOMAINS,
- .ops = &hsw_power_well_ops,
- .id = DISP_PW_ID_NONE,
- {
- .hsw.regs = &hsw_power_well_regs,
- .hsw.idx = SKL_PW_CTL_IDX_DDI_C,
- },
- },
- {
- .name = "DDI D IO power well",
- .domains = CNL_DISPLAY_DDI_D_IO_POWER_DOMAINS,
- .ops = &hsw_power_well_ops,
- .id = DISP_PW_ID_NONE,
- {
- .hsw.regs = &hsw_power_well_regs,
- .hsw.idx = SKL_PW_CTL_IDX_DDI_D,
- },
- },
- {
- .name = "DDI F IO power well",
- .domains = CNL_DISPLAY_DDI_F_IO_POWER_DOMAINS,
- .ops = &hsw_power_well_ops,
- .id = CNL_DISP_PW_DDI_F_IO,
- {
- .hsw.regs = &hsw_power_well_regs,
- .hsw.idx = CNL_PW_CTL_IDX_DDI_F,
- },
- },
- {
- .name = "AUX F",
- .domains = CNL_DISPLAY_AUX_F_POWER_DOMAINS,
- .ops = &hsw_power_well_ops,
- .id = CNL_DISP_PW_DDI_F_AUX,
- {
- .hsw.regs = &hsw_power_well_regs,
- .hsw.idx = CNL_PW_CTL_IDX_AUX_F,
- },
- },
-};
-
static const struct i915_power_well_ops icl_aux_power_well_ops = {
.sync_hw = hsw_power_well_sync_hw,
.enable = icl_aux_power_well_enable,
@@ -4642,6 +4487,165 @@ static const struct i915_power_well_desc rkl_power_wells[] = {
},
};
+static const struct i915_power_well_desc dg1_power_wells[] = {
+ {
+ .name = "always-on",
+ .always_on = true,
+ .domains = POWER_DOMAIN_MASK,
+ .ops = &i9xx_always_on_power_well_ops,
+ .id = DISP_PW_ID_NONE,
+ },
+ {
+ .name = "power well 1",
+ /* Handled by the DMC firmware */
+ .always_on = true,
+ .domains = 0,
+ .ops = &hsw_power_well_ops,
+ .id = SKL_DISP_PW_1,
+ {
+ .hsw.regs = &hsw_power_well_regs,
+ .hsw.idx = ICL_PW_CTL_IDX_PW_1,
+ .hsw.has_fuses = true,
+ },
+ },
+ {
+ .name = "DC off",
+ .domains = DG1_DISPLAY_DC_OFF_POWER_DOMAINS,
+ .ops = &gen9_dc_off_power_well_ops,
+ .id = SKL_DISP_DC_OFF,
+ },
+ {
+ .name = "power well 2",
+ .domains = DG1_PW_2_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = SKL_DISP_PW_2,
+ {
+ .hsw.regs = &hsw_power_well_regs,
+ .hsw.idx = ICL_PW_CTL_IDX_PW_2,
+ .hsw.has_fuses = true,
+ },
+ },
+ {
+ .name = "power well 3",
+ .domains = DG1_PW_3_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_3,
+ {
+ .hsw.regs = &hsw_power_well_regs,
+ .hsw.idx = ICL_PW_CTL_IDX_PW_3,
+ .hsw.irq_pipe_mask = BIT(PIPE_B),
+ .hsw.has_vga = true,
+ .hsw.has_fuses = true,
+ },
+ },
+ {
+ .name = "DDI A IO",
+ .domains = ICL_DDI_IO_A_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = DISP_PW_ID_NONE,
+ {
+ .hsw.regs = &icl_ddi_power_well_regs,
+ .hsw.idx = ICL_PW_CTL_IDX_DDI_A,
+ }
+ },
+ {
+ .name = "DDI B IO",
+ .domains = ICL_DDI_IO_B_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = DISP_PW_ID_NONE,
+ {
+ .hsw.regs = &icl_ddi_power_well_regs,
+ .hsw.idx = ICL_PW_CTL_IDX_DDI_B,
+ }
+ },
+ {
+ .name = "DDI IO TC1",
+ .domains = TGL_DDI_IO_TC1_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = DISP_PW_ID_NONE,
+ {
+ .hsw.regs = &icl_ddi_power_well_regs,
+ .hsw.idx = TGL_PW_CTL_IDX_DDI_TC1,
+ },
+ },
+ {
+ .name = "DDI IO TC2",
+ .domains = TGL_DDI_IO_TC2_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = DISP_PW_ID_NONE,
+ {
+ .hsw.regs = &icl_ddi_power_well_regs,
+ .hsw.idx = TGL_PW_CTL_IDX_DDI_TC2,
+ },
+ },
+ {
+ .name = "AUX A",
+ .domains = TGL_AUX_A_IO_POWER_DOMAINS,
+ .ops = &icl_aux_power_well_ops,
+ .id = DISP_PW_ID_NONE,
+ {
+ .hsw.regs = &icl_aux_power_well_regs,
+ .hsw.idx = ICL_PW_CTL_IDX_AUX_A,
+ },
+ },
+ {
+ .name = "AUX B",
+ .domains = TGL_AUX_B_IO_POWER_DOMAINS,
+ .ops = &icl_aux_power_well_ops,
+ .id = DISP_PW_ID_NONE,
+ {
+ .hsw.regs = &icl_aux_power_well_regs,
+ .hsw.idx = ICL_PW_CTL_IDX_AUX_B,
+ },
+ },
+ {
+ .name = "AUX USBC1",
+ .domains = TGL_AUX_IO_USBC1_POWER_DOMAINS,
+ .ops = &icl_aux_power_well_ops,
+ .id = DISP_PW_ID_NONE,
+ {
+ .hsw.regs = &icl_aux_power_well_regs,
+ .hsw.idx = TGL_PW_CTL_IDX_AUX_TC1,
+ .hsw.is_tc_tbt = false,
+ },
+ },
+ {
+ .name = "AUX USBC2",
+ .domains = TGL_AUX_IO_USBC2_POWER_DOMAINS,
+ .ops = &icl_aux_power_well_ops,
+ .id = DISP_PW_ID_NONE,
+ {
+ .hsw.regs = &icl_aux_power_well_regs,
+ .hsw.idx = TGL_PW_CTL_IDX_AUX_TC2,
+ .hsw.is_tc_tbt = false,
+ },
+ },
+ {
+ .name = "power well 4",
+ .domains = TGL_PW_4_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = DISP_PW_ID_NONE,
+ {
+ .hsw.regs = &hsw_power_well_regs,
+ .hsw.idx = ICL_PW_CTL_IDX_PW_4,
+ .hsw.has_fuses = true,
+ .hsw.irq_pipe_mask = BIT(PIPE_C),
+ }
+ },
+ {
+ .name = "power well 5",
+ .domains = TGL_PW_5_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = DISP_PW_ID_NONE,
+ {
+ .hsw.regs = &hsw_power_well_regs,
+ .hsw.idx = TGL_PW_CTL_IDX_PW_5,
+ .hsw.has_fuses = true,
+ .hsw.irq_pipe_mask = BIT(PIPE_D),
+ },
+ },
+};
+
static const struct i915_power_well_desc xelpd_power_wells[] = {
{
.name = "always-on",
@@ -4827,6 +4831,7 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = ICL_PW_CTL_IDX_AUX_A,
+ .hsw.fixed_enable_delay = 600,
},
},
{
@@ -4837,6 +4842,7 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = ICL_PW_CTL_IDX_AUX_B,
+ .hsw.fixed_enable_delay = 600,
},
},
{
@@ -4847,6 +4853,7 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = ICL_PW_CTL_IDX_AUX_C,
+ .hsw.fixed_enable_delay = 600,
},
},
{
@@ -4857,6 +4864,7 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = XELPD_PW_CTL_IDX_AUX_D,
+ .hsw.fixed_enable_delay = 600,
},
},
{
@@ -4877,6 +4885,7 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
{
.hsw.regs = &icl_aux_power_well_regs,
.hsw.idx = TGL_PW_CTL_IDX_AUX_TC1,
+ .hsw.fixed_enable_delay = 600,
},
},
{
@@ -5121,7 +5130,9 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
err = 0;
} else if (DISPLAY_VER(dev_priv) >= 13) {
err = set_power_wells(power_domains, xelpd_power_wells);
- } else if (IS_ALDERLAKE_S(dev_priv) || IS_DG1(dev_priv)) {
+ } else if (IS_DG1(dev_priv)) {
+ err = set_power_wells(power_domains, dg1_power_wells);
+ } else if (IS_ALDERLAKE_S(dev_priv)) {
err = set_power_wells_mask(power_domains, tgl_power_wells,
BIT_ULL(TGL_DISP_PW_TC_COLD_OFF));
} else if (IS_ROCKETLAKE(dev_priv)) {
@@ -5130,12 +5141,6 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
err = set_power_wells(power_domains, tgl_power_wells);
} else if (DISPLAY_VER(dev_priv) == 11) {
err = set_power_wells(power_domains, icl_power_wells);
- } else if (IS_CNL_WITH_PORT_F(dev_priv)) {
- err = set_power_wells(power_domains, cnl_power_wells);
- } else if (IS_CANNONLAKE(dev_priv)) {
- err = set_power_wells_mask(power_domains, cnl_power_wells,
- BIT_ULL(CNL_DISP_PW_DDI_F_IO) |
- BIT_ULL(CNL_DISP_PW_DDI_F_AUX));
} else if (IS_GEMINILAKE(dev_priv)) {
err = set_power_wells(power_domains, glk_power_wells);
} else if (IS_BROXTON(dev_priv)) {
@@ -5690,75 +5695,6 @@ static void bxt_display_core_uninit(struct drm_i915_private *dev_priv)
usleep_range(10, 30); /* 10 us delay per Bspec */
}
-static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume)
-{
- struct i915_power_domains *power_domains = &dev_priv->power_domains;
- struct i915_power_well *well;
-
- gen9_set_dc_state(dev_priv, DC_STATE_DISABLE);
-
- /* 1. Enable PCH Reset Handshake */
- intel_pch_reset_handshake(dev_priv, !HAS_PCH_NOP(dev_priv));
-
- if (!HAS_DISPLAY(dev_priv))
- return;
-
- /* 2-3. */
- intel_combo_phy_init(dev_priv);
-
- /*
- * 4. Enable Power Well 1 (PG1).
- * The AUX IO power wells will be enabled on demand.
- */
- mutex_lock(&power_domains->lock);
- well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
- intel_power_well_enable(dev_priv, well);
- mutex_unlock(&power_domains->lock);
-
- /* 5. Enable CD clock */
- intel_cdclk_init_hw(dev_priv);
-
- /* 6. Enable DBUF */
- gen9_dbuf_enable(dev_priv);
-
- if (resume && intel_dmc_has_payload(dev_priv))
- intel_dmc_load_program(dev_priv);
-}
-
-static void cnl_display_core_uninit(struct drm_i915_private *dev_priv)
-{
- struct i915_power_domains *power_domains = &dev_priv->power_domains;
- struct i915_power_well *well;
-
- if (!HAS_DISPLAY(dev_priv))
- return;
-
- gen9_disable_dc_states(dev_priv);
-
- /* 1. Disable all display engine functions -> aready done */
-
- /* 2. Disable DBUF */
- gen9_dbuf_disable(dev_priv);
-
- /* 3. Disable CD clock */
- intel_cdclk_uninit_hw(dev_priv);
-
- /*
- * 4. Disable Power Well 1 (PG1).
- * The AUX IO power wells are toggled on demand, so they are already
- * disabled at this point.
- */
- mutex_lock(&power_domains->lock);
- well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
- intel_power_well_disable(dev_priv, well);
- mutex_unlock(&power_domains->lock);
-
- usleep_range(10, 30); /* 10 us delay per Bspec */
-
- /* 5. */
- intel_combo_phy_uninit(dev_priv);
-}
-
struct buddy_page_mask {
u32 page_mask;
u8 type;
@@ -5797,9 +5733,14 @@ static void tgl_bw_buddy_init(struct drm_i915_private *dev_priv)
unsigned long abox_mask = INTEL_INFO(dev_priv)->abox_mask;
int config, i;
+ /* BW_BUDDY registers are not used on dgpu's beyond DG1 */
+ if (IS_DGFX(dev_priv) && !IS_DG1(dev_priv))
+ return;
+
if (IS_ALDERLAKE_S(dev_priv) ||
- IS_DG1_REVID(dev_priv, DG1_REVID_A0, DG1_REVID_A0) ||
- IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0))
+ IS_DG1_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0) ||
+ IS_RKL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0) ||
+ IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_C0))
/* Wa_1409767108:tgl,dg1,adl-s */
table = wa_1409767108_buddy_page_masks;
else
@@ -5821,10 +5762,11 @@ static void tgl_bw_buddy_init(struct drm_i915_private *dev_priv)
intel_de_write(dev_priv, BW_BUDDY_PAGE_MASK(i),
table[config].page_mask);
- /* Wa_22010178259:tgl,rkl */
- intel_de_rmw(dev_priv, BW_BUDDY_CTL(i),
- BW_BUDDY_TLB_REQ_TIMER_MASK,
- BW_BUDDY_TLB_REQ_TIMER(0x8));
+ /* Wa_22010178259:tgl,dg1,rkl,adl-s */
+ if (DISPLAY_VER(dev_priv) == 12)
+ intel_de_rmw(dev_priv, BW_BUDDY_CTL(i),
+ BW_BUDDY_TLB_REQ_TIMER_MASK,
+ BW_BUDDY_TLB_REQ_TIMER(0x8));
}
}
}
@@ -5878,11 +5820,15 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
if (DISPLAY_VER(dev_priv) >= 12)
tgl_bw_buddy_init(dev_priv);
+ /* 8. Ensure PHYs have completed calibration and adaptation */
+ if (IS_DG2(dev_priv))
+ intel_snps_phy_wait_for_calibration(dev_priv);
+
if (resume && intel_dmc_has_payload(dev_priv))
intel_dmc_load_program(dev_priv);
- /* Wa_14011508470 */
- if (DISPLAY_VER(dev_priv) == 12) {
+ /* Wa_14011508470:tgl,dg1,rkl,adl-s,adl-p */
+ if (DISPLAY_VER(dev_priv) >= 12) {
val = DCPR_CLEAR_MEMSTAT_DIS | DCPR_SEND_RESP_IMM |
DCPR_MASK_LPMODE | DCPR_MASK_MAXLATENCY_MEMUP_CLR;
intel_uncore_rmw(&dev_priv->uncore, GEN11_CHICKEN_DCPR_2, 0, val);
@@ -6097,8 +6043,6 @@ void intel_power_domains_init_hw(struct drm_i915_private *i915, bool resume)
if (DISPLAY_VER(i915) >= 11) {
icl_display_core_init(i915, resume);
- } else if (IS_CANNONLAKE(i915)) {
- cnl_display_core_init(i915, resume);
} else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915)) {
bxt_display_core_init(i915, resume);
} else if (DISPLAY_VER(i915) == 9) {
@@ -6258,8 +6202,6 @@ void intel_power_domains_suspend(struct drm_i915_private *i915,
if (DISPLAY_VER(i915) >= 11)
icl_display_core_uninit(i915);
- else if (IS_CANNONLAKE(i915))
- cnl_display_core_uninit(i915);
else if (IS_GEMINILAKE(i915) || IS_BROXTON(i915))
bxt_display_core_uninit(i915);
else if (DISPLAY_VER(i915) == 9)
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h
index 4f0917df4375..978531841fa3 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.h
+++ b/drivers/gpu/drm/i915/display/intel_display_power.h
@@ -76,7 +76,8 @@ enum intel_display_power_domain {
POWER_DOMAIN_PORT_CRT,
POWER_DOMAIN_PORT_OTHER,
POWER_DOMAIN_VGA,
- POWER_DOMAIN_AUDIO,
+ POWER_DOMAIN_AUDIO_MMIO,
+ POWER_DOMAIN_AUDIO_PLAYBACK,
POWER_DOMAIN_AUX_A,
POWER_DOMAIN_AUX_B,
POWER_DOMAIN_AUX_C,
@@ -142,8 +143,6 @@ enum i915_power_well_id {
SKL_DISP_PW_MISC_IO,
SKL_DISP_PW_1,
SKL_DISP_PW_2,
- CNL_DISP_PW_DDI_F_IO,
- CNL_DISP_PW_DDI_F_AUX,
ICL_DISP_PW_3,
SKL_DISP_DC_OFF,
TGL_DISP_PW_TC_COLD_OFF,
@@ -223,6 +222,12 @@ struct i915_power_well_desc {
u8 idx;
/* Mask of pipes whose IRQ logic is backed by the pw */
u8 irq_pipe_mask;
+ /*
+ * Instead of waiting for the status bit to ack enables,
+ * just wait a specific amount of time and then consider
+ * the well enabled.
+ */
+ u16 fixed_enable_delay;
/* The pw is backing the VGA functionality */
bool has_vga:1;
bool has_fuses:1;
@@ -386,6 +391,10 @@ intel_display_power_put_all_in_set(struct drm_i915_private *i915,
intel_display_power_put_mask_in_set(i915, power_domain_set, power_domain_set->mask);
}
+/*
+ * FIXME: We should probably switch this to a 0-based scheme to be consistent
+ * with how we now name/number DBUF_CTL instances.
+ */
enum dbuf_slice {
DBUF_S1,
DBUF_S2,
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 04613864cbe8..6beeeeba1bed 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -48,6 +48,7 @@
struct drm_printer;
struct __intel_global_objs_state;
+struct intel_ddi_buf_trans;
/*
* Display related stuff
@@ -195,6 +196,10 @@ struct intel_encoder {
void (*update_complete)(struct intel_atomic_state *,
struct intel_encoder *,
struct intel_crtc *);
+ void (*pre_disable)(struct intel_atomic_state *,
+ struct intel_encoder *,
+ const struct intel_crtc_state *,
+ const struct drm_connector_state *);
void (*disable)(struct intel_atomic_state *,
struct intel_encoder *,
const struct intel_crtc_state *,
@@ -263,6 +268,9 @@ struct intel_encoder {
* Returns whether the port clock is enabled or not.
*/
bool (*is_clock_enabled)(struct intel_encoder *encoder);
+ const struct intel_ddi_buf_trans *(*get_buf_trans)(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state,
+ int *n_entries);
enum hpd_pin hpd_pin;
enum intel_display_power_domain power_domain;
/* for communication with audio component; protected by av_mutex */
@@ -310,7 +318,7 @@ struct intel_panel {
/* DPCD backlight */
union {
struct {
- u8 pwmgen_bit_count;
+ struct drm_edp_backlight_info info;
} vesa;
struct {
bool sdr_uses_aux;
@@ -880,6 +888,18 @@ enum intel_output_format {
INTEL_OUTPUT_FORMAT_YCBCR444,
};
+struct intel_mpllb_state {
+ u32 clock; /* in KHz */
+ u32 ref_control;
+ u32 mpllb_cp;
+ u32 mpllb_div;
+ u32 mpllb_div2;
+ u32 mpllb_fracn1;
+ u32 mpllb_fracn2;
+ u32 mpllb_sscen;
+ u32 mpllb_sscstep;
+};
+
struct intel_crtc_state {
/*
* uapi (drm) state. This is the software state shown to userspace.
@@ -1014,7 +1034,10 @@ struct intel_crtc_state {
struct intel_shared_dpll *shared_dpll;
/* Actual register state of the dpll, for shared dpll cross-checking. */
- struct intel_dpll_hw_state dpll_hw_state;
+ union {
+ struct intel_dpll_hw_state dpll_hw_state;
+ struct intel_mpllb_state mpllb_state;
+ };
/*
* ICL reserved DPLLs for the CRTC/port. The active PLL is selected by
@@ -1040,7 +1063,9 @@ struct intel_crtc_state {
bool has_psr;
bool has_psr2;
bool enable_psr2_sel_fetch;
+ bool req_psr2_sdp_prior_scanline;
u32 dc3co_exitline;
+ u16 su_y_granularity;
/*
* Frequence the dpll for the port should run at. Differs from the
@@ -1493,12 +1518,14 @@ struct intel_psr {
bool colorimetry_support;
bool psr2_enabled;
bool psr2_sel_fetch_enabled;
+ bool req_psr2_sdp_prior_scanline;
u8 sink_sync_latency;
ktime_t last_entry_attempt;
ktime_t last_exit;
bool sink_not_reliable;
bool irq_aux_error;
- u16 su_x_granularity;
+ u16 su_w_granularity;
+ u16 su_y_granularity;
u32 dc3co_exitline;
u32 dc3co_exit_delay;
struct delayed_work dc3co_work;
@@ -1604,6 +1631,7 @@ struct intel_dp {
/* Display stream compression testing */
bool force_dsc_en;
+ int force_dsc_bpp;
bool hobl_failed;
bool hobl_active;
diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c
index 97308da28059..3c3c6cb5c0df 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -45,6 +45,10 @@
#define GEN12_DMC_MAX_FW_SIZE ICL_DMC_MAX_FW_SIZE
+#define ADLP_DMC_PATH DMC_PATH(adlp, 2, 10)
+#define ADLP_DMC_VERSION_REQUIRED DMC_VERSION(2, 10)
+MODULE_FIRMWARE(ADLP_DMC_PATH);
+
#define ADLS_DMC_PATH DMC_PATH(adls, 2, 01)
#define ADLS_DMC_VERSION_REQUIRED DMC_VERSION(2, 1)
MODULE_FIRMWARE(ADLS_DMC_PATH);
@@ -53,12 +57,12 @@ MODULE_FIRMWARE(ADLS_DMC_PATH);
#define DG1_DMC_VERSION_REQUIRED DMC_VERSION(2, 2)
MODULE_FIRMWARE(DG1_DMC_PATH);
-#define RKL_DMC_PATH DMC_PATH(rkl, 2, 02)
-#define RKL_DMC_VERSION_REQUIRED DMC_VERSION(2, 2)
+#define RKL_DMC_PATH DMC_PATH(rkl, 2, 03)
+#define RKL_DMC_VERSION_REQUIRED DMC_VERSION(2, 3)
MODULE_FIRMWARE(RKL_DMC_PATH);
-#define TGL_DMC_PATH DMC_PATH(tgl, 2, 08)
-#define TGL_DMC_VERSION_REQUIRED DMC_VERSION(2, 8)
+#define TGL_DMC_PATH DMC_PATH(tgl, 2, 12)
+#define TGL_DMC_VERSION_REQUIRED DMC_VERSION(2, 12)
MODULE_FIRMWARE(TGL_DMC_PATH);
#define ICL_DMC_PATH DMC_PATH(icl, 1, 09)
@@ -66,11 +70,6 @@ MODULE_FIRMWARE(TGL_DMC_PATH);
#define ICL_DMC_MAX_FW_SIZE 0x6000
MODULE_FIRMWARE(ICL_DMC_PATH);
-#define CNL_DMC_PATH DMC_PATH(cnl, 1, 07)
-#define CNL_DMC_VERSION_REQUIRED DMC_VERSION(1, 7)
-#define CNL_DMC_MAX_FW_SIZE GLK_DMC_MAX_FW_SIZE
-MODULE_FIRMWARE(CNL_DMC_PATH);
-
#define GLK_DMC_PATH DMC_PATH(glk, 1, 04)
#define GLK_DMC_VERSION_REQUIRED DMC_VERSION(1, 4)
#define GLK_DMC_MAX_FW_SIZE 0x4000
@@ -96,6 +95,7 @@ MODULE_FIRMWARE(BXT_DMC_PATH);
#define PACKAGE_V2_MAX_FW_INFO_ENTRIES 32
#define DMC_V1_MAX_MMIO_COUNT 8
#define DMC_V3_MAX_MMIO_COUNT 20
+#define DMC_V1_MMIO_START_RANGE 0x80000
struct intel_css_header {
/* 0x09 for DMC */
@@ -239,53 +239,18 @@ struct stepping_info {
bool intel_dmc_has_payload(struct drm_i915_private *i915)
{
- return i915->dmc.dmc_payload;
+ return i915->dmc.dmc_info[DMC_FW_MAIN].payload;
}
-static const struct stepping_info skl_stepping_info[] = {
- {'A', '0'}, {'B', '0'}, {'C', '0'},
- {'D', '0'}, {'E', '0'}, {'F', '0'},
- {'G', '0'}, {'H', '0'}, {'I', '0'},
- {'J', '0'}, {'K', '0'}
-};
-
-static const struct stepping_info bxt_stepping_info[] = {
- {'A', '0'}, {'A', '1'}, {'A', '2'},
- {'B', '0'}, {'B', '1'}, {'B', '2'}
-};
-
-static const struct stepping_info icl_stepping_info[] = {
- {'A', '0'}, {'A', '1'}, {'A', '2'},
- {'B', '0'}, {'B', '2'},
- {'C', '0'}
-};
-
-static const struct stepping_info no_stepping_info = { '*', '*' };
-
static const struct stepping_info *
-intel_get_stepping_info(struct drm_i915_private *dev_priv)
+intel_get_stepping_info(struct drm_i915_private *i915,
+ struct stepping_info *si)
{
- const struct stepping_info *si;
- unsigned int size;
-
- if (IS_ICELAKE(dev_priv)) {
- size = ARRAY_SIZE(icl_stepping_info);
- si = icl_stepping_info;
- } else if (IS_SKYLAKE(dev_priv)) {
- size = ARRAY_SIZE(skl_stepping_info);
- si = skl_stepping_info;
- } else if (IS_BROXTON(dev_priv)) {
- size = ARRAY_SIZE(bxt_stepping_info);
- si = bxt_stepping_info;
- } else {
- size = 0;
- si = NULL;
- }
-
- if (INTEL_REVID(dev_priv) < size)
- return si + INTEL_REVID(dev_priv);
+ const char *step_name = intel_step_name(RUNTIME_INFO(i915)->step.display_step);
- return &no_stepping_info;
+ si->stepping = step_name[0];
+ si->substepping = step_name[1];
+ return si;
}
static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv)
@@ -316,8 +281,8 @@ static void gen9_set_dc_state_debugmask(struct drm_i915_private *dev_priv)
*/
void intel_dmc_load_program(struct drm_i915_private *dev_priv)
{
- u32 *payload = dev_priv->dmc.dmc_payload;
- u32 i, fw_size;
+ struct intel_dmc *dmc = &dev_priv->dmc;
+ u32 id, i;
if (!HAS_DMC(dev_priv)) {
drm_err(&dev_priv->drm,
@@ -325,26 +290,31 @@ void intel_dmc_load_program(struct drm_i915_private *dev_priv)
return;
}
- if (!intel_dmc_has_payload(dev_priv)) {
+ if (!dev_priv->dmc.dmc_info[DMC_FW_MAIN].payload) {
drm_err(&dev_priv->drm,
"Tried to program CSR with empty payload\n");
return;
}
- fw_size = dev_priv->dmc.dmc_fw_size;
assert_rpm_wakelock_held(&dev_priv->runtime_pm);
preempt_disable();
- for (i = 0; i < fw_size; i++)
- intel_uncore_write_fw(&dev_priv->uncore, DMC_PROGRAM(i),
- payload[i]);
+ for (id = 0; id < DMC_FW_MAX; id++) {
+ for (i = 0; i < dmc->dmc_info[id].dmc_fw_size; i++) {
+ intel_uncore_write_fw(&dev_priv->uncore,
+ DMC_PROGRAM(dmc->dmc_info[id].start_mmioaddr, i),
+ dmc->dmc_info[id].payload[i]);
+ }
+ }
preempt_enable();
- for (i = 0; i < dev_priv->dmc.mmio_count; i++) {
- intel_de_write(dev_priv, dev_priv->dmc.mmioaddr[i],
- dev_priv->dmc.mmiodata[i]);
+ for (id = 0; id < DMC_FW_MAX; id++) {
+ for (i = 0; i < dmc->dmc_info[id].mmio_count; i++) {
+ intel_de_write(dev_priv, dmc->dmc_info[id].mmioaddr[i],
+ dmc->dmc_info[id].mmiodata[i]);
+ }
}
dev_priv->dmc.dc_state = 0;
@@ -352,62 +322,72 @@ void intel_dmc_load_program(struct drm_i915_private *dev_priv)
gen9_set_dc_state_debugmask(dev_priv);
}
+static bool fw_info_matches_stepping(const struct intel_fw_info *fw_info,
+ const struct stepping_info *si)
+{
+ if ((fw_info->substepping == '*' && si->stepping == fw_info->stepping) ||
+ (si->stepping == fw_info->stepping && si->substepping == fw_info->substepping) ||
+ /*
+ * If we don't find a more specific one from above two checks, we
+ * then check for the generic one to be sure to work even with
+ * "broken firmware"
+ */
+ (si->stepping == '*' && si->substepping == fw_info->substepping) ||
+ (fw_info->stepping == '*' && fw_info->substepping == '*'))
+ return true;
+
+ return false;
+}
+
/*
* Search fw_info table for dmc_offset to find firmware binary: num_entries is
* already sanitized.
*/
-static u32 find_dmc_fw_offset(const struct intel_fw_info *fw_info,
+static void dmc_set_fw_offset(struct intel_dmc *dmc,
+ const struct intel_fw_info *fw_info,
unsigned int num_entries,
const struct stepping_info *si,
u8 package_ver)
{
- u32 dmc_offset = DMC_DEFAULT_FW_OFFSET;
- unsigned int i;
+ unsigned int i, id;
+
+ struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), dmc);
for (i = 0; i < num_entries; i++) {
- if (package_ver > 1 && fw_info[i].dmc_id != 0)
- continue;
+ id = package_ver <= 1 ? DMC_FW_MAIN : fw_info[i].dmc_id;
- if (fw_info[i].substepping == '*' &&
- si->stepping == fw_info[i].stepping) {
- dmc_offset = fw_info[i].offset;
- break;
+ if (id >= DMC_FW_MAX) {
+ drm_dbg(&i915->drm, "Unsupported firmware id: %u\n", id);
+ continue;
}
- if (si->stepping == fw_info[i].stepping &&
- si->substepping == fw_info[i].substepping) {
- dmc_offset = fw_info[i].offset;
- break;
- }
+ /* More specific versions come first, so we don't even have to
+ * check for the stepping since we already found a previous FW
+ * for this id.
+ */
+ if (dmc->dmc_info[id].present)
+ continue;
- if (fw_info[i].stepping == '*' &&
- fw_info[i].substepping == '*') {
- /*
- * In theory we should stop the search as generic
- * entries should always come after the more specific
- * ones, but let's continue to make sure to work even
- * with "broken" firmwares. If we don't find a more
- * specific one, then we use this entry
- */
- dmc_offset = fw_info[i].offset;
+ if (fw_info_matches_stepping(&fw_info[i], si)) {
+ dmc->dmc_info[id].present = true;
+ dmc->dmc_info[id].dmc_offset = fw_info[i].offset;
}
}
-
- return dmc_offset;
}
static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
const struct intel_dmc_header_base *dmc_header,
- size_t rem_size)
+ size_t rem_size, u8 dmc_id)
{
struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), dmc);
+ struct dmc_fw_info *dmc_info = &dmc->dmc_info[dmc_id];
unsigned int header_len_bytes, dmc_header_size, payload_size, i;
const u32 *mmioaddr, *mmiodata;
- u32 mmio_count, mmio_count_max;
+ u32 mmio_count, mmio_count_max, start_mmioaddr;
u8 *payload;
- BUILD_BUG_ON(ARRAY_SIZE(dmc->mmioaddr) < DMC_V3_MAX_MMIO_COUNT ||
- ARRAY_SIZE(dmc->mmioaddr) < DMC_V1_MAX_MMIO_COUNT);
+ BUILD_BUG_ON(ARRAY_SIZE(dmc_info->mmioaddr) < DMC_V3_MAX_MMIO_COUNT ||
+ ARRAY_SIZE(dmc_info->mmioaddr) < DMC_V1_MAX_MMIO_COUNT);
/*
* Check if we can access common fields, we will checkc again below
@@ -430,6 +410,7 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
mmio_count_max = DMC_V3_MAX_MMIO_COUNT;
/* header_len is in dwords */
header_len_bytes = dmc_header->header_len * 4;
+ start_mmioaddr = v3->start_mmioaddr;
dmc_header_size = sizeof(*v3);
} else if (dmc_header->header_ver == 1) {
const struct intel_dmc_header_v1 *v1 =
@@ -443,6 +424,7 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
mmio_count = v1->mmio_count;
mmio_count_max = DMC_V1_MAX_MMIO_COUNT;
header_len_bytes = dmc_header->header_len;
+ start_mmioaddr = DMC_V1_MMIO_START_RANGE;
dmc_header_size = sizeof(*v1);
} else {
drm_err(&i915->drm, "Unknown DMC fw header version: %u\n",
@@ -463,16 +445,11 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
}
for (i = 0; i < mmio_count; i++) {
- if (mmioaddr[i] < DMC_MMIO_START_RANGE ||
- mmioaddr[i] > DMC_MMIO_END_RANGE) {
- drm_err(&i915->drm, "DMC firmware has wrong mmio address 0x%x\n",
- mmioaddr[i]);
- return 0;
- }
- dmc->mmioaddr[i] = _MMIO(mmioaddr[i]);
- dmc->mmiodata[i] = mmiodata[i];
+ dmc_info->mmioaddr[i] = _MMIO(mmioaddr[i]);
+ dmc_info->mmiodata[i] = mmiodata[i];
}
- dmc->mmio_count = mmio_count;
+ dmc_info->mmio_count = mmio_count;
+ dmc_info->start_mmioaddr = start_mmioaddr;
rem_size -= header_len_bytes;
@@ -485,14 +462,14 @@ static u32 parse_dmc_fw_header(struct intel_dmc *dmc,
drm_err(&i915->drm, "DMC FW too big (%u bytes)\n", payload_size);
return 0;
}
- dmc->dmc_fw_size = dmc_header->fw_size;
+ dmc_info->dmc_fw_size = dmc_header->fw_size;
- dmc->dmc_payload = kmalloc(payload_size, GFP_KERNEL);
- if (!dmc->dmc_payload)
+ dmc_info->payload = kmalloc(payload_size, GFP_KERNEL);
+ if (!dmc_info->payload)
return 0;
payload = (u8 *)(dmc_header) + header_len_bytes;
- memcpy(dmc->dmc_payload, payload, payload_size);
+ memcpy(dmc_info->payload, payload, payload_size);
return header_len_bytes + payload_size;
@@ -509,7 +486,7 @@ parse_dmc_fw_package(struct intel_dmc *dmc,
{
struct drm_i915_private *i915 = container_of(dmc, typeof(*i915), dmc);
u32 package_size = sizeof(struct intel_package_header);
- u32 num_entries, max_entries, dmc_offset;
+ u32 num_entries, max_entries;
const struct intel_fw_info *fw_info;
if (rem_size < package_size)
@@ -545,16 +522,11 @@ parse_dmc_fw_package(struct intel_dmc *dmc,
fw_info = (const struct intel_fw_info *)
((u8 *)package_header + sizeof(*package_header));
- dmc_offset = find_dmc_fw_offset(fw_info, num_entries, si,
- package_header->header_ver);
- if (dmc_offset == DMC_DEFAULT_FW_OFFSET) {
- drm_err(&i915->drm, "DMC firmware not supported for %c stepping\n",
- si->stepping);
- return 0;
- }
+ dmc_set_fw_offset(dmc, fw_info, num_entries, si,
+ package_header->header_ver);
/* dmc_offset is in dwords */
- return package_size + dmc_offset * 4;
+ return package_size;
error_truncated:
drm_err(&i915->drm, "Truncated DMC firmware, refusing.\n");
@@ -604,9 +576,11 @@ static void parse_dmc_fw(struct drm_i915_private *dev_priv,
struct intel_package_header *package_header;
struct intel_dmc_header_base *dmc_header;
struct intel_dmc *dmc = &dev_priv->dmc;
- const struct stepping_info *si = intel_get_stepping_info(dev_priv);
+ struct stepping_info display_info = { '*', '*'};
+ const struct stepping_info *si = intel_get_stepping_info(dev_priv, &display_info);
u32 readcount = 0;
- u32 r;
+ u32 r, offset;
+ int id;
if (!fw)
return;
@@ -627,9 +601,19 @@ static void parse_dmc_fw(struct drm_i915_private *dev_priv,
readcount += r;
- /* Extract dmc_header information */
- dmc_header = (struct intel_dmc_header_base *)&fw->data[readcount];
- parse_dmc_fw_header(dmc, dmc_header, fw->size - readcount);
+ for (id = 0; id < DMC_FW_MAX; id++) {
+ if (!dev_priv->dmc.dmc_info[id].present)
+ continue;
+
+ offset = readcount + dmc->dmc_info[id].dmc_offset * 4;
+ if (fw->size - offset < 0) {
+ drm_err(&dev_priv->drm, "Reading beyond the fw_size\n");
+ continue;
+ }
+
+ dmc_header = (struct intel_dmc_header_base *)&fw->data[offset];
+ parse_dmc_fw_header(dmc, dmc_header, fw->size - offset, id);
+ }
}
static void intel_dmc_runtime_pm_get(struct drm_i915_private *dev_priv)
@@ -705,7 +689,11 @@ void intel_dmc_ucode_init(struct drm_i915_private *dev_priv)
*/
intel_dmc_runtime_pm_get(dev_priv);
- if (IS_ALDERLAKE_S(dev_priv)) {
+ if (IS_ALDERLAKE_P(dev_priv)) {
+ dmc->fw_path = ADLP_DMC_PATH;
+ dmc->required_version = ADLP_DMC_VERSION_REQUIRED;
+ dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
+ } else if (IS_ALDERLAKE_S(dev_priv)) {
dmc->fw_path = ADLS_DMC_PATH;
dmc->required_version = ADLS_DMC_VERSION_REQUIRED;
dmc->max_fw_size = GEN12_DMC_MAX_FW_SIZE;
@@ -725,10 +713,6 @@ void intel_dmc_ucode_init(struct drm_i915_private *dev_priv)
dmc->fw_path = ICL_DMC_PATH;
dmc->required_version = ICL_DMC_VERSION_REQUIRED;
dmc->max_fw_size = ICL_DMC_MAX_FW_SIZE;
- } else if (IS_CANNONLAKE(dev_priv)) {
- dmc->fw_path = CNL_DMC_PATH;
- dmc->required_version = CNL_DMC_VERSION_REQUIRED;
- dmc->max_fw_size = CNL_DMC_MAX_FW_SIZE;
} else if (IS_GEMINILAKE(dev_priv)) {
dmc->fw_path = GLK_DMC_PATH;
dmc->required_version = GLK_DMC_VERSION_REQUIRED;
@@ -827,5 +811,5 @@ void intel_dmc_ucode_fini(struct drm_i915_private *dev_priv)
intel_dmc_ucode_suspend(dev_priv);
drm_WARN_ON(&dev_priv->drm, dev_priv->dmc.wakeref);
- kfree(dev_priv->dmc.dmc_payload);
+ kfree(dev_priv->dmc.dmc_info[DMC_FW_MAIN].payload);
}
diff --git a/drivers/gpu/drm/i915/display/intel_dmc.h b/drivers/gpu/drm/i915/display/intel_dmc.h
index 4c22f567b61b..c3c00ff03869 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.h
+++ b/drivers/gpu/drm/i915/display/intel_dmc.h
@@ -16,17 +16,30 @@ struct drm_i915_private;
#define DMC_VERSION_MAJOR(version) ((version) >> 16)
#define DMC_VERSION_MINOR(version) ((version) & 0xffff)
+enum {
+ DMC_FW_MAIN = 0,
+ DMC_FW_PIPEA,
+ DMC_FW_PIPEB,
+ DMC_FW_MAX
+};
+
struct intel_dmc {
struct work_struct work;
const char *fw_path;
u32 required_version;
u32 max_fw_size; /* bytes */
- u32 *dmc_payload;
- u32 dmc_fw_size; /* dwords */
u32 version;
- u32 mmio_count;
- i915_reg_t mmioaddr[20];
- u32 mmiodata[20];
+ struct dmc_fw_info {
+ u32 mmio_count;
+ i915_reg_t mmioaddr[20];
+ u32 mmiodata[20];
+ u32 dmc_offset;
+ u32 start_mmioaddr;
+ u32 dmc_fw_size; /*dwords */
+ u32 *payload;
+ bool present;
+ } dmc_info[DMC_FW_MAX];
+
u32 dc_state;
u32 target_dc_state;
u32 allowed_dc_mask;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 862c1df69cc2..04175f359fd6 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -222,29 +222,6 @@ bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp)
encoder->port != PORT_A);
}
-static int cnl_max_source_rate(struct intel_dp *intel_dp)
-{
- 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;
-
- u32 voltage = intel_de_read(dev_priv, CNL_PORT_COMP_DW3) & VOLTAGE_INFO_MASK;
-
- /* Low voltage SKUs are limited to max of 5.4G */
- if (voltage == VOLTAGE_INFO_0_85V)
- return 540000;
-
- /* For this SKU 8.1G is supported in all ports */
- if (IS_CNL_WITH_PORT_F(dev_priv))
- return 810000;
-
- /* For other SKUs, max rate on ports A and D is 5.4G */
- if (port == PORT_A || port == PORT_D)
- return 540000;
-
- return 810000;
-}
-
static int icl_max_source_rate(struct intel_dp *intel_dp)
{
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
@@ -270,7 +247,7 @@ static void
intel_dp_set_source_rates(struct intel_dp *intel_dp)
{
/* The values must be in increasing order */
- static const int cnl_rates[] = {
+ static const int icl_rates[] = {
162000, 216000, 270000, 324000, 432000, 540000, 648000, 810000
};
static const int bxt_rates[] = {
@@ -295,12 +272,10 @@ intel_dp_set_source_rates(struct intel_dp *intel_dp)
drm_WARN_ON(&dev_priv->drm,
intel_dp->source_rates || intel_dp->num_source_rates);
- if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) {
- source_rates = cnl_rates;
- size = ARRAY_SIZE(cnl_rates);
- if (DISPLAY_VER(dev_priv) == 10)
- max_rate = cnl_max_source_rate(intel_dp);
- else if (IS_JSL_EHL(dev_priv))
+ if (DISPLAY_VER(dev_priv) >= 11) {
+ source_rates = icl_rates;
+ size = ARRAY_SIZE(icl_rates);
+ if (IS_JSL_EHL(dev_priv))
max_rate = ehl_max_source_rate(intel_dp);
else
max_rate = icl_max_source_rate(intel_dp);
@@ -1274,6 +1249,23 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
pipe_config->pipe_bpp);
pipe_config->dsc.slice_count = dsc_dp_slice_count;
}
+
+ /* As of today we support DSC for only RGB */
+ if (intel_dp->force_dsc_bpp) {
+ if (intel_dp->force_dsc_bpp >= 8 &&
+ intel_dp->force_dsc_bpp < pipe_bpp) {
+ drm_dbg_kms(&dev_priv->drm,
+ "DSC BPP forced to %d",
+ intel_dp->force_dsc_bpp);
+ pipe_config->dsc.compressed_bpp =
+ intel_dp->force_dsc_bpp;
+ } else {
+ drm_dbg_kms(&dev_priv->drm,
+ "Invalid DSC BPP %d",
+ intel_dp->force_dsc_bpp);
+ }
+ }
+
/*
* VDSC engine operates at 1 Pixel per clock, so if peak pixel rate
* is greater than the maximum Cdclock and if slice count is even
@@ -3031,9 +3023,6 @@ void intel_read_dp_sdp(struct intel_encoder *encoder,
struct intel_crtc_state *crtc_state,
unsigned int type)
{
- if (encoder->type != INTEL_OUTPUT_DDI)
- return;
-
switch (type) {
case DP_SDP_VSC:
intel_read_dp_vsc_sdp(encoder, crtc_state,
@@ -3342,6 +3331,9 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
intel_dp_autotest_phy_ddi_enable(intel_dp, crtc_state);
+ drm_dp_dpcd_write(&intel_dp->aux, DP_TRAINING_LANE0_SET,
+ intel_dp->train_set, crtc_state->lane_count);
+
drm_dp_set_phy_test_pattern(&intel_dp->aux, data,
link_status[DP_DPCD_REV]);
}
@@ -4736,7 +4728,7 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
int refresh_rate)
{
struct intel_dp *intel_dp = dev_priv->drrs.dp;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
if (refresh_rate <= 0) {
@@ -4750,7 +4742,7 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
return;
}
- if (!intel_crtc) {
+ if (!crtc) {
drm_dbg_kms(&dev_priv->drm,
"DRRS: intel_crtc not initialized\n");
return;
@@ -5233,7 +5225,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
}
intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
- intel_connector->panel.backlight.power = intel_pps_backlight_power;
+ if (!(dev_priv->quirks & QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK))
+ intel_connector->panel.backlight.power = intel_pps_backlight_power;
intel_panel_setup_backlight(connector, pipe);
if (fixed_mode) {
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c
index 7c048d2ecf43..f483f479dd0b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c
@@ -158,7 +158,6 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp,
/*
* Max timeout values:
* SKL-GLK: 1.6ms
- * CNL: 3.2ms
* ICL+: 4ms
*/
ret = DP_AUX_CH_CTL_SEND_BUSY |
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
index 8e9ac9ba1d38..6ac568617ef3 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
@@ -107,7 +107,7 @@ intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector)
u8 tcon_cap[4];
ret = drm_dp_dpcd_read(aux, INTEL_EDP_HDR_TCON_CAP0, tcon_cap, sizeof(tcon_cap));
- if (ret < 0)
+ if (ret != sizeof(tcon_cap))
return false;
if (!(tcon_cap[1] & INTEL_EDP_HDR_TCON_BRIGHTNESS_NITS_CAP))
@@ -137,7 +137,7 @@ intel_dp_aux_hdr_get_backlight(struct intel_connector *connector, enum pipe pipe
u8 tmp;
u8 buf[2] = { 0 };
- if (drm_dp_dpcd_readb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &tmp) < 0) {
+ if (drm_dp_dpcd_readb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &tmp) != 1) {
drm_err(&i915->drm, "Failed to read current backlight mode from DPCD\n");
return 0;
}
@@ -153,7 +153,8 @@ intel_dp_aux_hdr_get_backlight(struct intel_connector *connector, enum pipe pipe
return panel->backlight.max;
}
- if (drm_dp_dpcd_read(&intel_dp->aux, INTEL_EDP_BRIGHTNESS_NITS_LSB, buf, sizeof(buf)) < 0) {
+ if (drm_dp_dpcd_read(&intel_dp->aux, INTEL_EDP_BRIGHTNESS_NITS_LSB, buf,
+ sizeof(buf)) != sizeof(buf)) {
drm_err(&i915->drm, "Failed to read brightness from DPCD\n");
return 0;
}
@@ -172,7 +173,8 @@ intel_dp_aux_hdr_set_aux_backlight(const struct drm_connector_state *conn_state,
buf[0] = level & 0xFF;
buf[1] = (level & 0xFF00) >> 8;
- if (drm_dp_dpcd_write(&intel_dp->aux, INTEL_EDP_BRIGHTNESS_NITS_LSB, buf, 4) < 0)
+ if (drm_dp_dpcd_write(&intel_dp->aux, INTEL_EDP_BRIGHTNESS_NITS_LSB, buf,
+ sizeof(buf)) != sizeof(buf))
drm_err(dev, "Failed to write brightness level to DPCD\n");
}
@@ -203,7 +205,7 @@ intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state,
u8 old_ctrl, ctrl;
ret = drm_dp_dpcd_readb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, &old_ctrl);
- if (ret < 0) {
+ if (ret != 1) {
drm_err(&i915->drm, "Failed to read current backlight control mode: %d\n", ret);
return;
}
@@ -221,7 +223,7 @@ intel_dp_aux_hdr_enable_backlight(const struct intel_crtc_state *crtc_state,
}
if (ctrl != old_ctrl)
- if (drm_dp_dpcd_writeb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, ctrl) < 0)
+ if (drm_dp_dpcd_writeb(&intel_dp->aux, INTEL_EDP_HDR_GETSET_CTRL_PARAMS, ctrl) != 1)
drm_err(&i915->drm, "Failed to configure DPCD brightness controls\n");
}
@@ -268,153 +270,19 @@ intel_dp_aux_hdr_setup_backlight(struct intel_connector *connector, enum pipe pi
}
/* VESA backlight callbacks */
-static void set_vesa_backlight_enable(struct intel_dp *intel_dp, bool enable)
-{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- u8 reg_val = 0;
-
- /* Early return when display use other mechanism to enable backlight. */
- if (!(intel_dp->edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP))
- return;
-
- if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
- &reg_val) < 0) {
- drm_dbg_kms(&i915->drm, "Failed to read DPCD register 0x%x\n",
- DP_EDP_DISPLAY_CONTROL_REGISTER);
- return;
- }
- if (enable)
- reg_val |= DP_EDP_BACKLIGHT_ENABLE;
- else
- reg_val &= ~(DP_EDP_BACKLIGHT_ENABLE);
-
- if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_EDP_DISPLAY_CONTROL_REGISTER,
- reg_val) != 1) {
- drm_dbg_kms(&i915->drm, "Failed to %s aux backlight\n",
- enabledisable(enable));
- }
-}
-
-static bool intel_dp_aux_vesa_backlight_dpcd_mode(struct intel_connector *connector)
-{
- struct intel_dp *intel_dp = intel_attached_dp(connector);
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- u8 mode_reg;
-
- if (drm_dp_dpcd_readb(&intel_dp->aux,
- DP_EDP_BACKLIGHT_MODE_SET_REGISTER,
- &mode_reg) != 1) {
- drm_dbg_kms(&i915->drm,
- "Failed to read the DPCD register 0x%x\n",
- DP_EDP_BACKLIGHT_MODE_SET_REGISTER);
- return false;
- }
-
- return (mode_reg & DP_EDP_BACKLIGHT_CONTROL_MODE_MASK) ==
- DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD;
-}
-
-/*
- * Read the current backlight value from DPCD register(s) based
- * on if 8-bit(MSB) or 16-bit(MSB and LSB) values are supported
- */
static u32 intel_dp_aux_vesa_get_backlight(struct intel_connector *connector, enum pipe unused)
{
- struct intel_dp *intel_dp = intel_attached_dp(connector);
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- u8 read_val[2] = { 0x0 };
- u16 level = 0;
-
- /*
- * If we're not in DPCD control mode yet, the programmed brightness
- * value is meaningless and we should assume max brightness
- */
- if (!intel_dp_aux_vesa_backlight_dpcd_mode(connector))
- return connector->panel.backlight.max;
-
- if (drm_dp_dpcd_read(&intel_dp->aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
- &read_val, sizeof(read_val)) < 0) {
- drm_dbg_kms(&i915->drm, "Failed to read DPCD register 0x%x\n",
- DP_EDP_BACKLIGHT_BRIGHTNESS_MSB);
- return 0;
- }
- level = read_val[0];
- if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT)
- level = (read_val[0] << 8 | read_val[1]);
-
- return level;
+ return connector->panel.backlight.level;
}
-/*
- * Sends the current backlight level over the aux channel, checking if its using
- * 8-bit or 16 bit value (MSB and LSB)
- */
static void
-intel_dp_aux_vesa_set_backlight(const struct drm_connector_state *conn_state,
- u32 level)
+intel_dp_aux_vesa_set_backlight(const struct drm_connector_state *conn_state, u32 level)
{
struct intel_connector *connector = to_intel_connector(conn_state->connector);
- struct intel_dp *intel_dp = intel_attached_dp(connector);
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- u8 vals[2] = { 0x0 };
-
- vals[0] = level;
-
- /* Write the MSB and/or LSB */
- if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_BYTE_COUNT) {
- vals[0] = (level & 0xFF00) >> 8;
- vals[1] = (level & 0xFF);
- }
- if (drm_dp_dpcd_write(&intel_dp->aux, DP_EDP_BACKLIGHT_BRIGHTNESS_MSB,
- vals, sizeof(vals)) < 0) {
- drm_dbg_kms(&i915->drm,
- "Failed to write aux backlight level\n");
- return;
- }
-}
-
-/*
- * Set PWM Frequency divider to match desired frequency in vbt.
- * The PWM Frequency is calculated as 27Mhz / (F x P).
- * - Where F = PWM Frequency Pre-Divider value programmed by field 7:0 of the
- * EDP_BACKLIGHT_FREQ_SET register (DPCD Address 00728h)
- * - Where P = 2^Pn, where Pn is the value programmed by field 4:0 of the
- * EDP_PWMGEN_BIT_COUNT register (DPCD Address 00724h)
- */
-static bool intel_dp_aux_vesa_set_pwm_freq(struct intel_connector *connector)
-{
- struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
- struct intel_dp *intel_dp = intel_attached_dp(connector);
- const u8 pn = connector->panel.backlight.edp.vesa.pwmgen_bit_count;
- int freq, fxp, f, fxp_actual, fxp_min, fxp_max;
-
- freq = dev_priv->vbt.backlight.pwm_freq_hz;
- if (!freq) {
- drm_dbg_kms(&dev_priv->drm,
- "Use panel default backlight frequency\n");
- return false;
- }
-
- fxp = DIV_ROUND_CLOSEST(KHz(DP_EDP_BACKLIGHT_FREQ_BASE_KHZ), freq);
- f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255);
- fxp_actual = f << pn;
-
- /* Ensure frequency is within 25% of desired value */
- fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4);
- fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4);
-
- if (fxp_min > fxp_actual || fxp_actual > fxp_max) {
- drm_dbg_kms(&dev_priv->drm, "Actual frequency out of range\n");
- return false;
- }
+ struct intel_panel *panel = &connector->panel;
+ struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
- if (drm_dp_dpcd_writeb(&intel_dp->aux,
- DP_EDP_BACKLIGHT_FREQ_SET, (u8) f) < 0) {
- drm_dbg_kms(&dev_priv->drm,
- "Failed to write aux backlight freq\n");
- return false;
- }
- return true;
+ drm_edp_backlight_set_level(&intel_dp->aux, &panel->backlight.edp.vesa.info, level);
}
static void
@@ -422,159 +290,46 @@ intel_dp_aux_vesa_enable_backlight(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state, u32 level)
{
struct intel_connector *connector = to_intel_connector(conn_state->connector);
- struct intel_dp *intel_dp = intel_attached_dp(connector);
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct intel_panel *panel = &connector->panel;
- u8 dpcd_buf, new_dpcd_buf, edp_backlight_mode;
- u8 pwmgen_bit_count = panel->backlight.edp.vesa.pwmgen_bit_count;
-
- if (drm_dp_dpcd_readb(&intel_dp->aux,
- DP_EDP_BACKLIGHT_MODE_SET_REGISTER, &dpcd_buf) != 1) {
- drm_dbg_kms(&i915->drm, "Failed to read DPCD register 0x%x\n",
- DP_EDP_BACKLIGHT_MODE_SET_REGISTER);
- return;
- }
-
- new_dpcd_buf = dpcd_buf;
- edp_backlight_mode = dpcd_buf & DP_EDP_BACKLIGHT_CONTROL_MODE_MASK;
-
- switch (edp_backlight_mode) {
- case DP_EDP_BACKLIGHT_CONTROL_MODE_PWM:
- case DP_EDP_BACKLIGHT_CONTROL_MODE_PRESET:
- case DP_EDP_BACKLIGHT_CONTROL_MODE_PRODUCT:
- new_dpcd_buf &= ~DP_EDP_BACKLIGHT_CONTROL_MODE_MASK;
- new_dpcd_buf |= DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD;
-
- if (drm_dp_dpcd_writeb(&intel_dp->aux,
- DP_EDP_PWMGEN_BIT_COUNT,
- pwmgen_bit_count) < 0)
- drm_dbg_kms(&i915->drm,
- "Failed to write aux pwmgen bit count\n");
-
- break;
-
- /* Do nothing when it is already DPCD mode */
- case DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD:
- default:
- break;
- }
-
- if (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_FREQ_AUX_SET_CAP)
- if (intel_dp_aux_vesa_set_pwm_freq(connector))
- new_dpcd_buf |= DP_EDP_BACKLIGHT_FREQ_AUX_SET_ENABLE;
-
- if (new_dpcd_buf != dpcd_buf) {
- if (drm_dp_dpcd_writeb(&intel_dp->aux,
- DP_EDP_BACKLIGHT_MODE_SET_REGISTER, new_dpcd_buf) < 0) {
- drm_dbg_kms(&i915->drm,
- "Failed to write aux backlight mode\n");
- }
- }
+ struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
- intel_dp_aux_vesa_set_backlight(conn_state, level);
- set_vesa_backlight_enable(intel_dp, true);
+ drm_edp_backlight_enable(&intel_dp->aux, &panel->backlight.edp.vesa.info, level);
}
static void intel_dp_aux_vesa_disable_backlight(const struct drm_connector_state *old_conn_state,
u32 level)
{
- set_vesa_backlight_enable(enc_to_intel_dp(to_intel_encoder(old_conn_state->best_encoder)),
- false);
-}
-
-static u32 intel_dp_aux_vesa_calc_max_backlight(struct intel_connector *connector)
-{
- struct drm_i915_private *i915 = to_i915(connector->base.dev);
- struct intel_dp *intel_dp = intel_attached_dp(connector);
+ struct intel_connector *connector = to_intel_connector(old_conn_state->connector);
struct intel_panel *panel = &connector->panel;
- u32 max_backlight = 0;
- int freq, fxp, fxp_min, fxp_max, fxp_actual, f = 1;
- u8 pn, pn_min, pn_max;
-
- if (drm_dp_dpcd_readb(&intel_dp->aux, DP_EDP_PWMGEN_BIT_COUNT, &pn) == 1) {
- pn &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
- max_backlight = (1 << pn) - 1;
- }
-
- /* Find desired value of (F x P)
- * Note that, if F x P is out of supported range, the maximum value or
- * minimum value will applied automatically. So no need to check that.
- */
- freq = i915->vbt.backlight.pwm_freq_hz;
- drm_dbg_kms(&i915->drm, "VBT defined backlight frequency %u Hz\n",
- freq);
- if (!freq) {
- drm_dbg_kms(&i915->drm,
- "Use panel default backlight frequency\n");
- return max_backlight;
- }
-
- fxp = DIV_ROUND_CLOSEST(KHz(DP_EDP_BACKLIGHT_FREQ_BASE_KHZ), freq);
-
- /* Use highest possible value of Pn for more granularity of brightness
- * adjustment while satifying the conditions below.
- * - Pn is in the range of Pn_min and Pn_max
- * - F is in the range of 1 and 255
- * - FxP is within 25% of desired value.
- * Note: 25% is arbitrary value and may need some tweak.
- */
- if (drm_dp_dpcd_readb(&intel_dp->aux,
- DP_EDP_PWMGEN_BIT_COUNT_CAP_MIN, &pn_min) != 1) {
- drm_dbg_kms(&i915->drm,
- "Failed to read pwmgen bit count cap min\n");
- return max_backlight;
- }
- if (drm_dp_dpcd_readb(&intel_dp->aux,
- DP_EDP_PWMGEN_BIT_COUNT_CAP_MAX, &pn_max) != 1) {
- drm_dbg_kms(&i915->drm,
- "Failed to read pwmgen bit count cap max\n");
- return max_backlight;
- }
- pn_min &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
- pn_max &= DP_EDP_PWMGEN_BIT_COUNT_MASK;
-
- fxp_min = DIV_ROUND_CLOSEST(fxp * 3, 4);
- fxp_max = DIV_ROUND_CLOSEST(fxp * 5, 4);
- if (fxp_min < (1 << pn_min) || (255 << pn_max) < fxp_max) {
- drm_dbg_kms(&i915->drm,
- "VBT defined backlight frequency out of range\n");
- return max_backlight;
- }
-
- for (pn = pn_max; pn >= pn_min; pn--) {
- f = clamp(DIV_ROUND_CLOSEST(fxp, 1 << pn), 1, 255);
- fxp_actual = f << pn;
- if (fxp_min <= fxp_actual && fxp_actual <= fxp_max)
- break;
- }
-
- drm_dbg_kms(&i915->drm, "Using eDP pwmgen bit count of %d\n", pn);
- if (drm_dp_dpcd_writeb(&intel_dp->aux,
- DP_EDP_PWMGEN_BIT_COUNT, pn) < 0) {
- drm_dbg_kms(&i915->drm,
- "Failed to write aux pwmgen bit count\n");
- return max_backlight;
- }
- panel->backlight.edp.vesa.pwmgen_bit_count = pn;
-
- max_backlight = (1 << pn) - 1;
+ struct intel_dp *intel_dp = enc_to_intel_dp(connector->encoder);
- return max_backlight;
+ drm_edp_backlight_disable(&intel_dp->aux, &panel->backlight.edp.vesa.info);
}
-static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector,
- enum pipe pipe)
+static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector, enum pipe pipe)
{
+ struct intel_dp *intel_dp = intel_attached_dp(connector);
struct intel_panel *panel = &connector->panel;
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ u16 current_level;
+ u8 current_mode;
+ int ret;
- panel->backlight.max = intel_dp_aux_vesa_calc_max_backlight(connector);
- if (!panel->backlight.max)
- return -ENODEV;
+ ret = drm_edp_backlight_init(&intel_dp->aux, &panel->backlight.edp.vesa.info,
+ i915->vbt.backlight.pwm_freq_hz, intel_dp->edp_dpcd,
+ &current_level, &current_mode);
+ if (ret < 0)
+ return ret;
+ panel->backlight.max = panel->backlight.edp.vesa.info.max;
panel->backlight.min = 0;
- panel->backlight.level = intel_dp_aux_vesa_get_backlight(connector, pipe);
- panel->backlight.enabled = intel_dp_aux_vesa_backlight_dpcd_mode(connector) &&
- panel->backlight.level != 0;
+ if (current_mode == DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) {
+ panel->backlight.level = current_level;
+ panel->backlight.enabled = panel->backlight.level != 0;
+ } else {
+ panel->backlight.level = panel->backlight.max;
+ panel->backlight.enabled = false;
+ }
return 0;
}
@@ -585,16 +340,12 @@ intel_dp_aux_supports_vesa_backlight(struct intel_connector *connector)
struct intel_dp *intel_dp = intel_attached_dp(connector);
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- /* Check the eDP Display control capabilities registers to determine if
- * the panel can support backlight control over the aux channel.
- *
- * TODO: We currently only support AUX only backlight configurations, not backlights which
+ /* TODO: We currently only support AUX only backlight configurations, not backlights which
* require a mix of PWM and AUX controls to work. In the mean time, these machines typically
* work just fine using normal PWM controls anyway.
*/
- if (intel_dp->edp_dpcd[1] & DP_EDP_TCON_BACKLIGHT_ADJUSTMENT_CAP &&
- (intel_dp->edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP) &&
- (intel_dp->edp_dpcd[2] & DP_EDP_BACKLIGHT_BRIGHTNESS_AUX_SET_CAP)) {
+ if ((intel_dp->edp_dpcd[1] & DP_EDP_BACKLIGHT_AUX_ENABLE_CAP) &&
+ drm_edp_backlight_supported(intel_dp->edp_dpcd)) {
drm_dbg_kms(&i915->drm, "AUX Backlight Control Supported!\n");
return true;
}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index b170e272bdee..8d13d7b26a25 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -308,9 +308,9 @@ intel_dp_mst_atomic_check(struct drm_connector *connector,
* connector
*/
if (new_crtc) {
- struct intel_crtc *intel_crtc = to_intel_crtc(new_crtc);
+ struct intel_crtc *crtc = to_intel_crtc(new_crtc);
struct intel_crtc_state *crtc_state =
- intel_atomic_get_new_crtc_state(state, intel_crtc);
+ intel_atomic_get_new_crtc_state(state, crtc);
if (!crtc_state ||
!drm_atomic_crtc_needs_modeset(&crtc_state->uapi) ||
@@ -348,6 +348,16 @@ static void wait_for_act_sent(struct intel_encoder *encoder,
drm_dp_check_act_status(&intel_dp->mst_mgr);
}
+static void intel_mst_pre_disable_dp(struct intel_atomic_state *state,
+ struct intel_encoder *encoder,
+ const struct intel_crtc_state *old_crtc_state,
+ const struct drm_connector_state *old_conn_state)
+{
+ if (old_crtc_state->has_audio)
+ intel_audio_codec_disable(encoder, old_crtc_state,
+ old_conn_state);
+}
+
static void intel_mst_disable_dp(struct intel_atomic_state *state,
struct intel_encoder *encoder,
const struct intel_crtc_state *old_crtc_state,
@@ -372,9 +382,6 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
if (ret) {
drm_dbg_kms(&i915->drm, "failed to update payload %d\n", ret);
}
- if (old_crtc_state->has_audio)
- intel_audio_codec_disable(encoder,
- old_crtc_state, old_conn_state);
}
static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
@@ -542,7 +549,7 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
struct intel_digital_port *dig_port = intel_mst->primary;
struct intel_dp *intel_dp = &dig_port->dp;
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- u32 val;
+ enum transcoder trans = pipe_config->cpu_transcoder;
drm_WARN_ON(&dev_priv->drm, pipe_config->has_pch_encoder);
@@ -550,12 +557,8 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
intel_ddi_enable_transcoder_func(encoder, pipe_config);
- val = intel_de_read(dev_priv,
- TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder));
- val |= TRANS_DDI_DP_VC_PAYLOAD_ALLOC;
- intel_de_write(dev_priv,
- TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder),
- val);
+ intel_de_rmw(dev_priv, TRANS_DDI_FUNC_CTL(trans), 0,
+ TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
drm_dbg_kms(&dev_priv->drm, "active links %d\n",
intel_dp->active_mst_links);
@@ -564,6 +567,10 @@ static void intel_mst_enable_dp(struct intel_atomic_state *state,
drm_dp_update_payload_part2(&intel_dp->mst_mgr);
+ if (DISPLAY_VER(dev_priv) >= 12 && pipe_config->fec_enable)
+ intel_de_rmw(dev_priv, CHICKEN_TRANS(trans), 0,
+ FECSTALL_DIS_DPTSTREAM_DPTTG);
+
intel_enable_pipe(pipe_config);
intel_crtc_vblank_on(pipe_config);
@@ -835,13 +842,10 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
intel_attach_force_audio_property(connector);
intel_attach_broadcast_rgb_property(connector);
- if (DISPLAY_VER(dev_priv) <= 12) {
- ret = intel_dp_hdcp_init(dig_port, intel_connector);
- if (ret)
- drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP MST init failed, skipping.\n",
- connector->name, connector->base.id);
- }
-
+ ret = intel_dp_hdcp_init(dig_port, intel_connector);
+ if (ret)
+ drm_dbg_kms(&dev_priv->drm, "[%s:%d] HDCP MST init failed, skipping.\n",
+ connector->name, connector->base.id);
/*
* Reuse the prop from the SST connector because we're
* not allowed to create new props after device registration.
@@ -906,6 +910,7 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *dig_port, enum pipe
intel_encoder->compute_config = intel_dp_mst_compute_config;
intel_encoder->compute_config_late = intel_dp_mst_compute_config_late;
+ intel_encoder->pre_disable = intel_mst_pre_disable_dp;
intel_encoder->disable = intel_mst_disable_dp;
intel_encoder->post_disable = intel_mst_post_disable_dp;
intel_encoder->update_pipe = intel_ddi_update_pipe;
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c
index 89635da9f6f6..14515e62c05e 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -11,6 +11,7 @@
#include "intel_lvds.h"
#include "intel_panel.h"
#include "intel_sideband.h"
+#include "display/intel_snps_phy.h"
struct intel_limit {
struct {
@@ -923,12 +924,13 @@ static int hsw_crtc_compute_clock(struct intel_crtc *crtc,
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_atomic_state *state =
to_intel_atomic_state(crtc_state->uapi.state);
+ struct intel_encoder *encoder =
+ intel_get_crtc_new_encoder(state, crtc_state);
- if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) ||
- DISPLAY_VER(dev_priv) >= 11) {
- struct intel_encoder *encoder =
- intel_get_crtc_new_encoder(state, crtc_state);
-
+ if (IS_DG2(dev_priv)) {
+ return intel_mpllb_calc_state(crtc_state, encoder);
+ } else if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) ||
+ DISPLAY_VER(dev_priv) >= 11) {
if (!intel_reserve_shared_dplls(state, crtc, encoder)) {
drm_dbg_kms(&dev_priv->drm,
"failed to find PLL for pipe %c\n",
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index 71ac57670043..5c91d125a337 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -168,7 +168,7 @@ intel_combo_pll_enable_reg(struct drm_i915_private *i915,
else if (IS_JSL_EHL(i915) && (pll->info->id == DPLL_ID_EHL_DPLL4))
return MG_PLL_ENABLE(0);
- return CNL_DPLL_ENABLE(pll->info->id);
+ return ICL_DPLL_ENABLE(pll->info->id);
}
static i915_reg_t
@@ -2346,160 +2346,7 @@ static const struct intel_dpll_mgr bxt_pll_mgr = {
.dump_hw_state = bxt_dump_hw_state,
};
-static void cnl_ddi_pll_enable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
-{
- const enum intel_dpll_id id = pll->info->id;
- u32 val;
-
- /* 1. Enable DPLL power in DPLL_ENABLE. */
- val = intel_de_read(dev_priv, CNL_DPLL_ENABLE(id));
- val |= PLL_POWER_ENABLE;
- intel_de_write(dev_priv, CNL_DPLL_ENABLE(id), val);
-
- /* 2. Wait for DPLL power state enabled in DPLL_ENABLE. */
- if (intel_de_wait_for_set(dev_priv, CNL_DPLL_ENABLE(id),
- PLL_POWER_STATE, 5))
- drm_err(&dev_priv->drm, "PLL %d Power not enabled\n", id);
-
- /*
- * 3. Configure DPLL_CFGCR0 to set SSC enable/disable,
- * select DP mode, and set DP link rate.
- */
- val = pll->state.hw_state.cfgcr0;
- intel_de_write(dev_priv, CNL_DPLL_CFGCR0(id), val);
-
- /* 4. Reab back to ensure writes completed */
- intel_de_posting_read(dev_priv, CNL_DPLL_CFGCR0(id));
-
- /* 3. Configure DPLL_CFGCR0 */
- /* Avoid touch CFGCR1 if HDMI mode is not enabled */
- if (pll->state.hw_state.cfgcr0 & DPLL_CFGCR0_HDMI_MODE) {
- val = pll->state.hw_state.cfgcr1;
- intel_de_write(dev_priv, CNL_DPLL_CFGCR1(id), val);
- /* 4. Reab back to ensure writes completed */
- intel_de_posting_read(dev_priv, CNL_DPLL_CFGCR1(id));
- }
-
- /*
- * 5. If the frequency will result in a change to the voltage
- * requirement, follow the Display Voltage Frequency Switching
- * Sequence Before Frequency Change
- *
- * Note: DVFS is actually handled via the cdclk code paths,
- * hence we do nothing here.
- */
-
- /* 6. Enable DPLL in DPLL_ENABLE. */
- val = intel_de_read(dev_priv, CNL_DPLL_ENABLE(id));
- val |= PLL_ENABLE;
- intel_de_write(dev_priv, CNL_DPLL_ENABLE(id), val);
-
- /* 7. Wait for PLL lock status in DPLL_ENABLE. */
- if (intel_de_wait_for_set(dev_priv, CNL_DPLL_ENABLE(id), PLL_LOCK, 5))
- drm_err(&dev_priv->drm, "PLL %d not locked\n", id);
-
- /*
- * 8. If the frequency will result in a change to the voltage
- * requirement, follow the Display Voltage Frequency Switching
- * Sequence After Frequency Change
- *
- * Note: DVFS is actually handled via the cdclk code paths,
- * hence we do nothing here.
- */
-
- /*
- * 9. turn on the clock for the DDI and map the DPLL to the DDI
- * Done at intel_ddi_clk_select
- */
-}
-
-static void cnl_ddi_pll_disable(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll)
-{
- const enum intel_dpll_id id = pll->info->id;
- u32 val;
-
- /*
- * 1. Configure DPCLKA_CFGCR0 to turn off the clock for the DDI.
- * Done at intel_ddi_post_disable
- */
-
- /*
- * 2. If the frequency will result in a change to the voltage
- * requirement, follow the Display Voltage Frequency Switching
- * Sequence Before Frequency Change
- *
- * Note: DVFS is actually handled via the cdclk code paths,
- * hence we do nothing here.
- */
-
- /* 3. Disable DPLL through DPLL_ENABLE. */
- val = intel_de_read(dev_priv, CNL_DPLL_ENABLE(id));
- val &= ~PLL_ENABLE;
- intel_de_write(dev_priv, CNL_DPLL_ENABLE(id), val);
-
- /* 4. Wait for PLL not locked status in DPLL_ENABLE. */
- if (intel_de_wait_for_clear(dev_priv, CNL_DPLL_ENABLE(id), PLL_LOCK, 5))
- drm_err(&dev_priv->drm, "PLL %d locked\n", id);
-
- /*
- * 5. If the frequency will result in a change to the voltage
- * requirement, follow the Display Voltage Frequency Switching
- * Sequence After Frequency Change
- *
- * Note: DVFS is actually handled via the cdclk code paths,
- * hence we do nothing here.
- */
-
- /* 6. Disable DPLL power in DPLL_ENABLE. */
- val = intel_de_read(dev_priv, CNL_DPLL_ENABLE(id));
- val &= ~PLL_POWER_ENABLE;
- intel_de_write(dev_priv, CNL_DPLL_ENABLE(id), val);
-
- /* 7. Wait for DPLL power state disabled in DPLL_ENABLE. */
- if (intel_de_wait_for_clear(dev_priv, CNL_DPLL_ENABLE(id),
- PLL_POWER_STATE, 5))
- drm_err(&dev_priv->drm, "PLL %d Power not disabled\n", id);
-}
-
-static bool cnl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv,
- struct intel_shared_dpll *pll,
- struct intel_dpll_hw_state *hw_state)
-{
- const enum intel_dpll_id id = pll->info->id;
- intel_wakeref_t wakeref;
- u32 val;
- bool ret;
-
- wakeref = intel_display_power_get_if_enabled(dev_priv,
- POWER_DOMAIN_DISPLAY_CORE);
- if (!wakeref)
- return false;
-
- ret = false;
-
- val = intel_de_read(dev_priv, CNL_DPLL_ENABLE(id));
- if (!(val & PLL_ENABLE))
- goto out;
-
- val = intel_de_read(dev_priv, CNL_DPLL_CFGCR0(id));
- hw_state->cfgcr0 = val;
-
- /* avoid reading back stale values if HDMI mode is not enabled */
- if (val & DPLL_CFGCR0_HDMI_MODE) {
- hw_state->cfgcr1 = intel_de_read(dev_priv,
- CNL_DPLL_CFGCR1(id));
- }
- ret = true;
-
-out:
- intel_display_power_put(dev_priv, POWER_DOMAIN_DISPLAY_CORE, wakeref);
-
- return ret;
-}
-
-static void cnl_wrpll_get_multipliers(int bestdiv, int *pdiv,
+static void icl_wrpll_get_multipliers(int bestdiv, int *pdiv,
int *qdiv, int *kdiv)
{
/* even dividers */
@@ -2538,7 +2385,7 @@ static void cnl_wrpll_get_multipliers(int bestdiv, int *pdiv,
}
}
-static void cnl_wrpll_params_populate(struct skl_wrpll_params *params,
+static void icl_wrpll_params_populate(struct skl_wrpll_params *params,
u32 dco_freq, u32 ref_freq,
int pdiv, int qdiv, int kdiv)
{
@@ -2586,349 +2433,19 @@ static void cnl_wrpll_params_populate(struct skl_wrpll_params *params,
params->dco_fraction = dco & 0x7fff;
}
-static bool
-__cnl_ddi_calculate_wrpll(struct intel_crtc_state *crtc_state,
- struct skl_wrpll_params *wrpll_params,
- int ref_clock)
-{
- u32 afe_clock = crtc_state->port_clock * 5;
- u32 dco_min = 7998000;
- u32 dco_max = 10000000;
- u32 dco_mid = (dco_min + dco_max) / 2;
- static const int dividers[] = { 2, 4, 6, 8, 10, 12, 14, 16,
- 18, 20, 24, 28, 30, 32, 36, 40,
- 42, 44, 48, 50, 52, 54, 56, 60,
- 64, 66, 68, 70, 72, 76, 78, 80,
- 84, 88, 90, 92, 96, 98, 100, 102,
- 3, 5, 7, 9, 15, 21 };
- u32 dco, best_dco = 0, dco_centrality = 0;
- u32 best_dco_centrality = U32_MAX; /* Spec meaning of 999999 MHz */
- int d, best_div = 0, pdiv = 0, qdiv = 0, kdiv = 0;
-
- for (d = 0; d < ARRAY_SIZE(dividers); d++) {
- dco = afe_clock * dividers[d];
-
- if ((dco <= dco_max) && (dco >= dco_min)) {
- dco_centrality = abs(dco - dco_mid);
-
- if (dco_centrality < best_dco_centrality) {
- best_dco_centrality = dco_centrality;
- best_div = dividers[d];
- best_dco = dco;
- }
- }
- }
-
- if (best_div == 0)
- return false;
-
- cnl_wrpll_get_multipliers(best_div, &pdiv, &qdiv, &kdiv);
- cnl_wrpll_params_populate(wrpll_params, best_dco, ref_clock,
- pdiv, qdiv, kdiv);
-
- return true;
-}
-
-static bool
-cnl_ddi_calculate_wrpll(struct intel_crtc_state *crtc_state,
- struct skl_wrpll_params *wrpll_params)
-{
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
-
- return __cnl_ddi_calculate_wrpll(crtc_state, wrpll_params,
- i915->dpll.ref_clks.nssc);
-}
-
-static bool cnl_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state)
-{
- u32 cfgcr0, cfgcr1;
- struct skl_wrpll_params wrpll_params = { 0, };
-
- cfgcr0 = DPLL_CFGCR0_HDMI_MODE;
-
- if (!cnl_ddi_calculate_wrpll(crtc_state, &wrpll_params))
- return false;
-
- cfgcr0 |= DPLL_CFGCR0_DCO_FRACTION(wrpll_params.dco_fraction) |
- wrpll_params.dco_integer;
-
- cfgcr1 = DPLL_CFGCR1_QDIV_RATIO(wrpll_params.qdiv_ratio) |
- DPLL_CFGCR1_QDIV_MODE(wrpll_params.qdiv_mode) |
- DPLL_CFGCR1_KDIV(wrpll_params.kdiv) |
- DPLL_CFGCR1_PDIV(wrpll_params.pdiv) |
- DPLL_CFGCR1_CENTRAL_FREQ;
-
- memset(&crtc_state->dpll_hw_state, 0,
- sizeof(crtc_state->dpll_hw_state));
-
- crtc_state->dpll_hw_state.cfgcr0 = cfgcr0;
- crtc_state->dpll_hw_state.cfgcr1 = cfgcr1;
- return true;
-}
-
/*
- * Display WA #22010492432: ehl, tgl
+ * Display WA #22010492432: ehl, tgl, adl-p
* Program half of the nominal DCO divider fraction value.
*/
static bool
ehl_combo_pll_div_frac_wa_needed(struct drm_i915_private *i915)
{
return ((IS_PLATFORM(i915, INTEL_ELKHARTLAKE) &&
- IS_JSL_EHL_REVID(i915, EHL_REVID_B0, REVID_FOREVER)) ||
- IS_TIGERLAKE(i915)) &&
+ IS_JSL_EHL_DISPLAY_STEP(i915, STEP_B0, STEP_FOREVER)) ||
+ IS_TIGERLAKE(i915) || IS_ALDERLAKE_P(i915)) &&
i915->dpll.ref_clks.nssc == 38400;
}
-static int __cnl_ddi_wrpll_get_freq(struct drm_i915_private *dev_priv,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state,
- int ref_clock)
-{
- u32 dco_fraction;
- u32 p0, p1, p2, dco_freq;
-
- p0 = pll_state->cfgcr1 & DPLL_CFGCR1_PDIV_MASK;
- p2 = pll_state->cfgcr1 & DPLL_CFGCR1_KDIV_MASK;
-
- if (pll_state->cfgcr1 & DPLL_CFGCR1_QDIV_MODE(1))
- p1 = (pll_state->cfgcr1 & DPLL_CFGCR1_QDIV_RATIO_MASK) >>
- DPLL_CFGCR1_QDIV_RATIO_SHIFT;
- else
- p1 = 1;
-
-
- switch (p0) {
- case DPLL_CFGCR1_PDIV_2:
- p0 = 2;
- break;
- case DPLL_CFGCR1_PDIV_3:
- p0 = 3;
- break;
- case DPLL_CFGCR1_PDIV_5:
- p0 = 5;
- break;
- case DPLL_CFGCR1_PDIV_7:
- p0 = 7;
- break;
- }
-
- switch (p2) {
- case DPLL_CFGCR1_KDIV_1:
- p2 = 1;
- break;
- case DPLL_CFGCR1_KDIV_2:
- p2 = 2;
- break;
- case DPLL_CFGCR1_KDIV_3:
- p2 = 3;
- break;
- }
-
- dco_freq = (pll_state->cfgcr0 & DPLL_CFGCR0_DCO_INTEGER_MASK) *
- ref_clock;
-
- dco_fraction = (pll_state->cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK) >>
- DPLL_CFGCR0_DCO_FRACTION_SHIFT;
-
- if (ehl_combo_pll_div_frac_wa_needed(dev_priv))
- dco_fraction *= 2;
-
- dco_freq += (dco_fraction * ref_clock) / 0x8000;
-
- if (drm_WARN_ON(&dev_priv->drm, p0 == 0 || p1 == 0 || p2 == 0))
- return 0;
-
- return dco_freq / (p0 * p1 * p2 * 5);
-}
-
-static int cnl_ddi_wrpll_get_freq(struct drm_i915_private *i915,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
-{
- return __cnl_ddi_wrpll_get_freq(i915, pll, pll_state,
- i915->dpll.ref_clks.nssc);
-}
-
-static bool
-cnl_ddi_dp_set_dpll_hw_state(struct intel_crtc_state *crtc_state)
-{
- u32 cfgcr0;
-
- cfgcr0 = DPLL_CFGCR0_SSC_ENABLE;
-
- switch (crtc_state->port_clock / 2) {
- case 81000:
- cfgcr0 |= DPLL_CFGCR0_LINK_RATE_810;
- break;
- case 135000:
- cfgcr0 |= DPLL_CFGCR0_LINK_RATE_1350;
- break;
- case 270000:
- cfgcr0 |= DPLL_CFGCR0_LINK_RATE_2700;
- break;
- /* eDP 1.4 rates */
- case 162000:
- cfgcr0 |= DPLL_CFGCR0_LINK_RATE_1620;
- break;
- case 108000:
- cfgcr0 |= DPLL_CFGCR0_LINK_RATE_1080;
- break;
- case 216000:
- cfgcr0 |= DPLL_CFGCR0_LINK_RATE_2160;
- break;
- case 324000:
- /* Some SKUs may require elevated I/O voltage to support this */
- cfgcr0 |= DPLL_CFGCR0_LINK_RATE_3240;
- break;
- case 405000:
- /* Some SKUs may require elevated I/O voltage to support this */
- cfgcr0 |= DPLL_CFGCR0_LINK_RATE_4050;
- break;
- }
-
- memset(&crtc_state->dpll_hw_state, 0,
- sizeof(crtc_state->dpll_hw_state));
-
- crtc_state->dpll_hw_state.cfgcr0 = cfgcr0;
-
- return true;
-}
-
-static int cnl_ddi_lcpll_get_freq(struct drm_i915_private *i915,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
-{
- int link_clock = 0;
-
- switch (pll_state->cfgcr0 & DPLL_CFGCR0_LINK_RATE_MASK) {
- case DPLL_CFGCR0_LINK_RATE_810:
- link_clock = 81000;
- break;
- case DPLL_CFGCR0_LINK_RATE_1080:
- link_clock = 108000;
- break;
- case DPLL_CFGCR0_LINK_RATE_1350:
- link_clock = 135000;
- break;
- case DPLL_CFGCR0_LINK_RATE_1620:
- link_clock = 162000;
- break;
- case DPLL_CFGCR0_LINK_RATE_2160:
- link_clock = 216000;
- break;
- case DPLL_CFGCR0_LINK_RATE_2700:
- link_clock = 270000;
- break;
- case DPLL_CFGCR0_LINK_RATE_3240:
- link_clock = 324000;
- break;
- case DPLL_CFGCR0_LINK_RATE_4050:
- link_clock = 405000;
- break;
- default:
- drm_WARN(&i915->drm, 1, "Unsupported link rate\n");
- break;
- }
-
- return link_clock * 2;
-}
-
-static bool cnl_get_dpll(struct intel_atomic_state *state,
- struct intel_crtc *crtc,
- struct intel_encoder *encoder)
-{
- struct intel_crtc_state *crtc_state =
- intel_atomic_get_new_crtc_state(state, crtc);
- struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
- struct intel_shared_dpll *pll;
- bool bret;
-
- if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
- bret = cnl_ddi_hdmi_pll_dividers(crtc_state);
- if (!bret) {
- drm_dbg_kms(&i915->drm,
- "Could not get HDMI pll dividers.\n");
- return false;
- }
- } else if (intel_crtc_has_dp_encoder(crtc_state)) {
- bret = cnl_ddi_dp_set_dpll_hw_state(crtc_state);
- if (!bret) {
- drm_dbg_kms(&i915->drm,
- "Could not set DP dpll HW state.\n");
- return false;
- }
- } else {
- drm_dbg_kms(&i915->drm,
- "Skip DPLL setup for output_types 0x%x\n",
- crtc_state->output_types);
- return false;
- }
-
- pll = intel_find_shared_dpll(state, crtc,
- &crtc_state->dpll_hw_state,
- BIT(DPLL_ID_SKL_DPLL2) |
- BIT(DPLL_ID_SKL_DPLL1) |
- BIT(DPLL_ID_SKL_DPLL0));
- if (!pll) {
- drm_dbg_kms(&i915->drm, "No PLL selected\n");
- return false;
- }
-
- intel_reference_shared_dpll(state, crtc,
- pll, &crtc_state->dpll_hw_state);
-
- crtc_state->shared_dpll = pll;
-
- return true;
-}
-
-static int cnl_ddi_pll_get_freq(struct drm_i915_private *i915,
- const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
-{
- if (pll_state->cfgcr0 & DPLL_CFGCR0_HDMI_MODE)
- return cnl_ddi_wrpll_get_freq(i915, pll, pll_state);
- else
- return cnl_ddi_lcpll_get_freq(i915, pll, pll_state);
-}
-
-static void cnl_update_dpll_ref_clks(struct drm_i915_private *i915)
-{
- /* No SSC reference */
- i915->dpll.ref_clks.nssc = i915->cdclk.hw.ref;
-}
-
-static void cnl_dump_hw_state(struct drm_i915_private *dev_priv,
- const struct intel_dpll_hw_state *hw_state)
-{
- drm_dbg_kms(&dev_priv->drm, "dpll_hw_state: "
- "cfgcr0: 0x%x, cfgcr1: 0x%x\n",
- hw_state->cfgcr0,
- hw_state->cfgcr1);
-}
-
-static const struct intel_shared_dpll_funcs cnl_ddi_pll_funcs = {
- .enable = cnl_ddi_pll_enable,
- .disable = cnl_ddi_pll_disable,
- .get_hw_state = cnl_ddi_pll_get_hw_state,
- .get_freq = cnl_ddi_pll_get_freq,
-};
-
-static const struct dpll_info cnl_plls[] = {
- { "DPLL 0", &cnl_ddi_pll_funcs, DPLL_ID_SKL_DPLL0, 0 },
- { "DPLL 1", &cnl_ddi_pll_funcs, DPLL_ID_SKL_DPLL1, 0 },
- { "DPLL 2", &cnl_ddi_pll_funcs, DPLL_ID_SKL_DPLL2, 0 },
- { },
-};
-
-static const struct intel_dpll_mgr cnl_pll_mgr = {
- .dpll_info = cnl_plls,
- .get_dplls = cnl_get_dpll,
- .put_dplls = intel_put_dpll,
- .update_ref_clks = cnl_update_dpll_ref_clks,
- .dump_hw_state = cnl_dump_hw_state,
-};
-
struct icl_combo_pll_params {
int clock;
struct skl_wrpll_params wrpll;
@@ -3105,17 +2622,104 @@ icl_calc_wrpll(struct intel_crtc_state *crtc_state,
struct skl_wrpll_params *wrpll_params)
{
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+ int ref_clock = icl_wrpll_ref_clock(i915);
+ u32 afe_clock = crtc_state->port_clock * 5;
+ u32 dco_min = 7998000;
+ u32 dco_max = 10000000;
+ u32 dco_mid = (dco_min + dco_max) / 2;
+ static const int dividers[] = { 2, 4, 6, 8, 10, 12, 14, 16,
+ 18, 20, 24, 28, 30, 32, 36, 40,
+ 42, 44, 48, 50, 52, 54, 56, 60,
+ 64, 66, 68, 70, 72, 76, 78, 80,
+ 84, 88, 90, 92, 96, 98, 100, 102,
+ 3, 5, 7, 9, 15, 21 };
+ u32 dco, best_dco = 0, dco_centrality = 0;
+ u32 best_dco_centrality = U32_MAX; /* Spec meaning of 999999 MHz */
+ int d, best_div = 0, pdiv = 0, qdiv = 0, kdiv = 0;
- return __cnl_ddi_calculate_wrpll(crtc_state, wrpll_params,
- icl_wrpll_ref_clock(i915));
+ for (d = 0; d < ARRAY_SIZE(dividers); d++) {
+ dco = afe_clock * dividers[d];
+
+ if (dco <= dco_max && dco >= dco_min) {
+ dco_centrality = abs(dco - dco_mid);
+
+ if (dco_centrality < best_dco_centrality) {
+ best_dco_centrality = dco_centrality;
+ best_div = dividers[d];
+ best_dco = dco;
+ }
+ }
+ }
+
+ if (best_div == 0)
+ return false;
+
+ icl_wrpll_get_multipliers(best_div, &pdiv, &qdiv, &kdiv);
+ icl_wrpll_params_populate(wrpll_params, best_dco, ref_clock,
+ pdiv, qdiv, kdiv);
+
+ return true;
}
static int icl_ddi_combo_pll_get_freq(struct drm_i915_private *i915,
const struct intel_shared_dpll *pll,
const struct intel_dpll_hw_state *pll_state)
{
- return __cnl_ddi_wrpll_get_freq(i915, pll, pll_state,
- icl_wrpll_ref_clock(i915));
+ int ref_clock = icl_wrpll_ref_clock(i915);
+ u32 dco_fraction;
+ u32 p0, p1, p2, dco_freq;
+
+ p0 = pll_state->cfgcr1 & DPLL_CFGCR1_PDIV_MASK;
+ p2 = pll_state->cfgcr1 & DPLL_CFGCR1_KDIV_MASK;
+
+ if (pll_state->cfgcr1 & DPLL_CFGCR1_QDIV_MODE(1))
+ p1 = (pll_state->cfgcr1 & DPLL_CFGCR1_QDIV_RATIO_MASK) >>
+ DPLL_CFGCR1_QDIV_RATIO_SHIFT;
+ else
+ p1 = 1;
+
+ switch (p0) {
+ case DPLL_CFGCR1_PDIV_2:
+ p0 = 2;
+ break;
+ case DPLL_CFGCR1_PDIV_3:
+ p0 = 3;
+ break;
+ case DPLL_CFGCR1_PDIV_5:
+ p0 = 5;
+ break;
+ case DPLL_CFGCR1_PDIV_7:
+ p0 = 7;
+ break;
+ }
+
+ switch (p2) {
+ case DPLL_CFGCR1_KDIV_1:
+ p2 = 1;
+ break;
+ case DPLL_CFGCR1_KDIV_2:
+ p2 = 2;
+ break;
+ case DPLL_CFGCR1_KDIV_3:
+ p2 = 3;
+ break;
+ }
+
+ dco_freq = (pll_state->cfgcr0 & DPLL_CFGCR0_DCO_INTEGER_MASK) *
+ ref_clock;
+
+ dco_fraction = (pll_state->cfgcr0 & DPLL_CFGCR0_DCO_FRACTION_MASK) >>
+ DPLL_CFGCR0_DCO_FRACTION_SHIFT;
+
+ if (ehl_combo_pll_div_frac_wa_needed(i915))
+ dco_fraction *= 2;
+
+ dco_freq += (dco_fraction * ref_clock) / 0x8000;
+
+ if (drm_WARN_ON(&i915->drm, p0 == 0 || p1 == 0 || p2 == 0))
+ return 0;
+
+ return dco_freq / (p0 * p1 * p2 * 5);
}
static void icl_calc_dpll_state(struct drm_i915_private *i915,
@@ -4131,6 +3735,31 @@ static void icl_pll_enable(struct drm_i915_private *dev_priv,
drm_err(&dev_priv->drm, "PLL %d not locked\n", pll->info->id);
}
+static void adlp_cmtg_clock_gating_wa(struct drm_i915_private *i915, struct intel_shared_dpll *pll)
+{
+ u32 val;
+
+ if (!IS_ADLP_DISPLAY_STEP(i915, STEP_A0, STEP_B0) ||
+ pll->info->id != DPLL_ID_ICL_DPLL0)
+ return;
+ /*
+ * Wa_16011069516:adl-p[a0]
+ *
+ * All CMTG regs are unreliable until CMTG clock gating is disabled,
+ * so we can only assume the default TRANS_CMTG_CHICKEN reg value and
+ * sanity check this assumption with a double read, which presumably
+ * returns the correct value even with clock gating on.
+ *
+ * Instead of the usual place for workarounds we apply this one here,
+ * since TRANS_CMTG_CHICKEN is only accessible while DPLL0 is enabled.
+ */
+ val = intel_de_read(i915, TRANS_CMTG_CHICKEN);
+ val = intel_de_read(i915, TRANS_CMTG_CHICKEN);
+ intel_de_write(i915, TRANS_CMTG_CHICKEN, DISABLE_DPT_CLK_GATING);
+ if (drm_WARN_ON(&i915->drm, val & ~DISABLE_DPT_CLK_GATING))
+ drm_dbg_kms(&i915->drm, "Unexpected flags in TRANS_CMTG_CHICKEN: %08x\n", val);
+}
+
static void combo_pll_enable(struct drm_i915_private *dev_priv,
struct intel_shared_dpll *pll)
{
@@ -4160,6 +3789,8 @@ static void combo_pll_enable(struct drm_i915_private *dev_priv,
icl_pll_enable(dev_priv, pll, enable_reg);
+ adlp_cmtg_clock_gating_wa(dev_priv, pll);
+
/* DVFS post sequence would be here. See the comment above. */
}
@@ -4462,7 +4093,10 @@ void intel_shared_dpll_init(struct drm_device *dev)
const struct dpll_info *dpll_info;
int i;
- if (IS_ALDERLAKE_P(dev_priv))
+ if (IS_DG2(dev_priv))
+ /* No shared DPLLs on DG2; port PLLs are part of the PHY */
+ dpll_mgr = NULL;
+ else if (IS_ALDERLAKE_P(dev_priv))
dpll_mgr = &adlp_pll_mgr;
else if (IS_ALDERLAKE_S(dev_priv))
dpll_mgr = &adls_pll_mgr;
@@ -4476,8 +4110,6 @@ void intel_shared_dpll_init(struct drm_device *dev)
dpll_mgr = &ehl_pll_mgr;
else if (DISPLAY_VER(dev_priv) >= 11)
dpll_mgr = &icl_pll_mgr;
- else if (IS_CANNONLAKE(dev_priv))
- dpll_mgr = &cnl_pll_mgr;
else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
dpll_mgr = &bxt_pll_mgr;
else if (DISPLAY_VER(dev_priv) == 9)
@@ -4668,7 +4300,12 @@ void intel_dpll_readout_hw_state(struct drm_i915_private *i915)
static void sanitize_dpll_state(struct drm_i915_private *i915,
struct intel_shared_dpll *pll)
{
- if (!pll->on || pll->active_mask)
+ if (!pll->on)
+ return;
+
+ adlp_cmtg_clock_gating_wa(i915, pll);
+
+ if (pll->active_mask)
return;
drm_dbg_kms(&i915->drm,
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
index 7fd031a70cfd..30e0aa5ca109 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
@@ -204,9 +204,8 @@ struct intel_dpll_hw_state {
/* HDMI only, 0 when used for DP */
u32 cfgcr1, cfgcr2;
- /* cnl */
+ /* icl */
u32 cfgcr0;
- /* CNL also uses cfgcr1 */
/* bxt */
u32 ebb0, ebb4, pll0, pll1, pll2, pll3, pll6, pll8, pll9, pll10, pcsdw12;
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index 1847a161cb37..ddfc17e21668 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -104,7 +104,7 @@ static void i8xx_fbc_activate(struct drm_i915_private *dev_priv)
int i;
u32 fbc_ctl;
- /* Note: fbc.threshold == 1 for i8xx */
+ /* Note: fbc.limit == 1 for i8xx */
cfb_pitch = params->cfb_size / FBC_LL_SIZE;
if (params->fb.stride < cfb_pitch)
cfb_pitch = params->fb.stride;
@@ -148,16 +148,35 @@ static bool i8xx_fbc_is_active(struct drm_i915_private *dev_priv)
return intel_de_read(dev_priv, FBC_CONTROL) & FBC_CTL_EN;
}
+static u32 g4x_dpfc_ctl_limit(struct drm_i915_private *i915)
+{
+ const struct intel_fbc_reg_params *params = &i915->fbc.params;
+ int limit = i915->fbc.limit;
+
+ if (params->fb.format->cpp[0] == 2)
+ limit <<= 1;
+
+ switch (limit) {
+ default:
+ MISSING_CASE(limit);
+ fallthrough;
+ case 1:
+ return DPFC_CTL_LIMIT_1X;
+ case 2:
+ return DPFC_CTL_LIMIT_2X;
+ case 4:
+ return DPFC_CTL_LIMIT_4X;
+ }
+}
+
static void g4x_fbc_activate(struct drm_i915_private *dev_priv)
{
struct intel_fbc_reg_params *params = &dev_priv->fbc.params;
u32 dpfc_ctl;
dpfc_ctl = DPFC_CTL_PLANE(params->crtc.i9xx_plane) | DPFC_SR_EN;
- if (params->fb.format->cpp[0] == 2)
- dpfc_ctl |= DPFC_CTL_LIMIT_2X;
- else
- dpfc_ctl |= DPFC_CTL_LIMIT_1X;
+
+ dpfc_ctl |= g4x_dpfc_ctl_limit(dev_priv);
if (params->fence_id >= 0) {
dpfc_ctl |= DPFC_CTL_FENCE_EN | params->fence_id;
@@ -235,24 +254,10 @@ static void ilk_fbc_activate(struct drm_i915_private *dev_priv)
{
struct intel_fbc_reg_params *params = &dev_priv->fbc.params;
u32 dpfc_ctl;
- int threshold = dev_priv->fbc.threshold;
dpfc_ctl = DPFC_CTL_PLANE(params->crtc.i9xx_plane);
- if (params->fb.format->cpp[0] == 2)
- threshold++;
- switch (threshold) {
- case 4:
- case 3:
- dpfc_ctl |= DPFC_CTL_LIMIT_4X;
- break;
- case 2:
- dpfc_ctl |= DPFC_CTL_LIMIT_2X;
- break;
- case 1:
- dpfc_ctl |= DPFC_CTL_LIMIT_1X;
- break;
- }
+ dpfc_ctl |= g4x_dpfc_ctl_limit(dev_priv);
if (params->fence_id >= 0) {
dpfc_ctl |= DPFC_CTL_FENCE_EN;
@@ -300,7 +305,6 @@ static void gen7_fbc_activate(struct drm_i915_private *dev_priv)
{
struct intel_fbc_reg_params *params = &dev_priv->fbc.params;
u32 dpfc_ctl;
- int threshold = dev_priv->fbc.threshold;
/* Display WA #0529: skl, kbl, bxt. */
if (DISPLAY_VER(dev_priv) == 9) {
@@ -318,21 +322,7 @@ static void gen7_fbc_activate(struct drm_i915_private *dev_priv)
if (IS_IVYBRIDGE(dev_priv))
dpfc_ctl |= IVB_DPFC_CTL_PLANE(params->crtc.i9xx_plane);
- if (params->fb.format->cpp[0] == 2)
- threshold++;
-
- switch (threshold) {
- case 4:
- case 3:
- dpfc_ctl |= DPFC_CTL_LIMIT_4X;
- break;
- case 2:
- dpfc_ctl |= DPFC_CTL_LIMIT_2X;
- break;
- case 1:
- dpfc_ctl |= DPFC_CTL_LIMIT_1X;
- break;
- }
+ dpfc_ctl |= g4x_dpfc_ctl_limit(dev_priv);
if (params->fence_id >= 0) {
dpfc_ctl |= IVB_DPFC_CTL_FENCE_EN;
@@ -433,13 +423,8 @@ static u64 intel_fbc_cfb_base_max(struct drm_i915_private *i915)
return BIT_ULL(32);
}
-static int find_compression_threshold(struct drm_i915_private *dev_priv,
- struct drm_mm_node *node,
- unsigned int size,
- unsigned int fb_cpp)
+static u64 intel_fbc_stolen_end(struct drm_i915_private *dev_priv)
{
- int compression_threshold = 1;
- int ret;
u64 end;
/* The FBC hardware for BDW/SKL doesn't have access to the stolen
@@ -452,51 +437,69 @@ 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));
+ return 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.
- *
- * The enable_fbc code will attempt to use one of our 2 compression
- * thresholds, therefore, in that case, we only have 1 resort.
+static int intel_fbc_max_limit(struct drm_i915_private *dev_priv, int fb_cpp)
+{
+ /*
+ * FIXME: FBC1 can have arbitrary cfb stride,
+ * so we could support different compression ratios.
*/
+ if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
+ return 1;
+
+ /* WaFbcOnly1to1Ratio:ctg */
+ if (IS_G4X(dev_priv))
+ return 1;
+
+ /* FBC2 can only do 1:1, 1:2, 1:4 */
+ return fb_cpp == 2 ? 2 : 4;
+}
+
+static int find_compression_limit(struct drm_i915_private *dev_priv,
+ unsigned int size,
+ unsigned int fb_cpp)
+{
+ struct intel_fbc *fbc = &dev_priv->fbc;
+ u64 end = intel_fbc_stolen_end(dev_priv);
+ int ret, limit = 1;
/* Try to over-allocate to reduce reallocations and fragmentation. */
- ret = i915_gem_stolen_insert_node_in_range(dev_priv, node, size <<= 1,
- 4096, 0, end);
+ ret = i915_gem_stolen_insert_node_in_range(dev_priv, &fbc->compressed_fb,
+ size <<= 1, 4096, 0, end);
if (ret == 0)
- return compression_threshold;
+ return limit;
-again:
- /* HW's ability to limit the CFB is 1:4 */
- if (compression_threshold > 4 ||
- (fb_cpp == 2 && compression_threshold == 2))
- return 0;
-
- ret = i915_gem_stolen_insert_node_in_range(dev_priv, node, size >>= 1,
- 4096, 0, end);
- if (ret && DISPLAY_VER(dev_priv) <= 4) {
- return 0;
- } else if (ret) {
- compression_threshold <<= 1;
- goto again;
- } else {
- return compression_threshold;
+ for (; limit <= intel_fbc_max_limit(dev_priv, fb_cpp); limit <<= 1) {
+ ret = i915_gem_stolen_insert_node_in_range(dev_priv, &fbc->compressed_fb,
+ size >>= 1, 4096, 0, end);
+ if (ret == 0)
+ return limit;
}
+
+ return 0;
}
static int intel_fbc_alloc_cfb(struct drm_i915_private *dev_priv,
unsigned int size, unsigned int fb_cpp)
{
struct intel_fbc *fbc = &dev_priv->fbc;
- struct drm_mm_node *compressed_llb;
int ret;
drm_WARN_ON(&dev_priv->drm,
drm_mm_node_allocated(&fbc->compressed_fb));
+ drm_WARN_ON(&dev_priv->drm,
+ drm_mm_node_allocated(&fbc->compressed_llb));
- ret = find_compression_threshold(dev_priv, &fbc->compressed_fb,
- size, fb_cpp);
+ if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv)) {
+ ret = i915_gem_stolen_insert_node(dev_priv, &fbc->compressed_llb,
+ 4096, 4096);
+ if (ret)
+ goto err;
+ }
+
+ ret = find_compression_limit(dev_priv, size, fb_cpp);
if (!ret)
goto err_llb;
else if (ret > 1) {
@@ -504,51 +507,46 @@ static int intel_fbc_alloc_cfb(struct drm_i915_private *dev_priv,
"Reducing the compressed framebuffer size. This may lead to less power savings than a non-reduced-size. Try to increase stolen memory size if available in BIOS.\n");
}
- fbc->threshold = ret;
+ fbc->limit = ret;
- if (DISPLAY_VER(dev_priv) >= 5)
+ drm_dbg_kms(&dev_priv->drm,
+ "reserved %llu bytes of contiguous stolen space for FBC, limit: %d\n",
+ fbc->compressed_fb.size, fbc->limit);
+
+ return 0;
+
+err_llb:
+ if (drm_mm_node_allocated(&fbc->compressed_llb))
+ i915_gem_stolen_remove_node(dev_priv, &fbc->compressed_llb);
+err:
+ if (drm_mm_initialized(&dev_priv->mm.stolen))
+ drm_info_once(&dev_priv->drm, "not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size);
+ return -ENOSPC;
+}
+
+static void intel_fbc_program_cfb(struct drm_i915_private *dev_priv)
+{
+ struct intel_fbc *fbc = &dev_priv->fbc;
+
+ if (DISPLAY_VER(dev_priv) >= 5) {
intel_de_write(dev_priv, ILK_DPFC_CB_BASE,
fbc->compressed_fb.start);
- else if (IS_GM45(dev_priv)) {
+ } else if (IS_GM45(dev_priv)) {
intel_de_write(dev_priv, DPFC_CB_BASE,
fbc->compressed_fb.start);
} else {
- compressed_llb = kzalloc(sizeof(*compressed_llb), GFP_KERNEL);
- if (!compressed_llb)
- goto err_fb;
-
- ret = i915_gem_stolen_insert_node(dev_priv, compressed_llb,
- 4096, 4096);
- if (ret)
- goto err_fb;
-
- fbc->compressed_llb = compressed_llb;
-
GEM_BUG_ON(range_overflows_end_t(u64, dev_priv->dsm.start,
fbc->compressed_fb.start,
U32_MAX));
GEM_BUG_ON(range_overflows_end_t(u64, dev_priv->dsm.start,
- fbc->compressed_llb->start,
+ fbc->compressed_llb.start,
U32_MAX));
+
intel_de_write(dev_priv, FBC_CFB_BASE,
dev_priv->dsm.start + fbc->compressed_fb.start);
intel_de_write(dev_priv, FBC_LL_BASE,
- dev_priv->dsm.start + compressed_llb->start);
+ dev_priv->dsm.start + fbc->compressed_llb.start);
}
-
- drm_dbg_kms(&dev_priv->drm,
- "reserved %llu bytes of contiguous stolen space for FBC, threshold: %d\n",
- fbc->compressed_fb.size, fbc->threshold);
-
- return 0;
-
-err_fb:
- kfree(compressed_llb);
- i915_gem_stolen_remove_node(dev_priv, &fbc->compressed_fb);
-err_llb:
- if (drm_mm_initialized(&dev_priv->mm.stolen))
- drm_info_once(&dev_priv->drm, "not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size);
- return -ENOSPC;
}
static void __intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv)
@@ -558,15 +556,10 @@ static void __intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv)
if (WARN_ON(intel_fbc_hw_is_active(dev_priv)))
return;
- if (!drm_mm_node_allocated(&fbc->compressed_fb))
- return;
-
- if (fbc->compressed_llb) {
- i915_gem_stolen_remove_node(dev_priv, fbc->compressed_llb);
- kfree(fbc->compressed_llb);
- }
-
- i915_gem_stolen_remove_node(dev_priv, &fbc->compressed_fb);
+ if (drm_mm_node_allocated(&fbc->compressed_llb))
+ i915_gem_stolen_remove_node(dev_priv, &fbc->compressed_llb);
+ if (drm_mm_node_allocated(&fbc->compressed_fb))
+ i915_gem_stolen_remove_node(dev_priv, &fbc->compressed_fb);
}
void intel_fbc_cleanup_cfb(struct drm_i915_private *dev_priv)
@@ -753,7 +746,7 @@ static bool intel_fbc_cfb_size_changed(struct drm_i915_private *dev_priv)
struct intel_fbc *fbc = &dev_priv->fbc;
return intel_fbc_calculate_cfb_size(dev_priv, &fbc->state_cache) >
- fbc->compressed_fb.size * fbc->threshold;
+ fbc->compressed_fb.size * fbc->limit;
}
static u16 intel_fbc_gen9_wa_cfb_stride(struct drm_i915_private *dev_priv)
@@ -763,7 +756,7 @@ static u16 intel_fbc_gen9_wa_cfb_stride(struct drm_i915_private *dev_priv)
if ((DISPLAY_VER(dev_priv) == 9) &&
cache->fb.modifier != I915_FORMAT_MOD_X_TILED)
- return DIV_ROUND_UP(cache->plane.src_w, 32 * fbc->threshold) * 8;
+ return DIV_ROUND_UP(cache->plane.src_w, 32 * fbc->limit) * 8;
else
return 0;
}
@@ -919,11 +912,11 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc)
}
/*
- * Tigerlake is not supporting FBC with PSR2.
+ * Display 12+ is not supporting FBC with PSR2.
* Recommendation is to keep this combination disabled
* Bspec: 50422 HSD: 14010260002
*/
- if (fbc->state_cache.psr2_active && IS_TIGERLAKE(dev_priv)) {
+ if (fbc->state_cache.psr2_active && DISPLAY_VER(dev_priv) >= 12) {
fbc->no_fbc_reason = "not supported with PSR2";
return false;
}
@@ -1302,6 +1295,8 @@ void intel_fbc_enable(struct intel_atomic_state *state,
fbc->no_fbc_reason = "FBC enabled but not active yet\n";
fbc->crtc = crtc;
+
+ intel_fbc_program_cfb(dev_priv);
out:
mutex_unlock(&fbc->lock);
}
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c
index 4af40229f5ec..df05d285f0bd 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -335,32 +335,43 @@ static void intel_fbdev_destroy(struct intel_fbdev *ifbdev)
* fbcon), so we just find the biggest and use that.
*/
static bool intel_fbdev_init_bios(struct drm_device *dev,
- struct intel_fbdev *ifbdev)
+ struct intel_fbdev *ifbdev)
{
struct drm_i915_private *i915 = to_i915(dev);
struct intel_framebuffer *fb = NULL;
- struct drm_crtc *crtc;
- struct intel_crtc *intel_crtc;
+ struct intel_crtc *crtc;
unsigned int max_size = 0;
/* Find the largest fb */
- for_each_crtc(dev, crtc) {
+ for_each_intel_crtc(dev, crtc) {
+ struct intel_crtc_state *crtc_state =
+ to_intel_crtc_state(crtc->base.state);
+ struct intel_plane *plane =
+ to_intel_plane(crtc->base.primary);
+ struct intel_plane_state *plane_state =
+ to_intel_plane_state(plane->base.state);
struct drm_i915_gem_object *obj =
- intel_fb_obj(crtc->primary->state->fb);
- intel_crtc = to_intel_crtc(crtc);
+ intel_fb_obj(plane_state->uapi.fb);
- if (!crtc->state->active || !obj) {
+ if (!crtc_state->uapi.active) {
drm_dbg_kms(&i915->drm,
- "pipe %c not active or no fb, skipping\n",
- pipe_name(intel_crtc->pipe));
+ "[CRTC:%d:%s] not active, skipping\n",
+ crtc->base.base.id, crtc->base.name);
+ continue;
+ }
+
+ if (!obj) {
+ drm_dbg_kms(&i915->drm,
+ "[PLANE:%d:%s] no fb, skipping\n",
+ plane->base.base.id, plane->base.name);
continue;
}
if (obj->base.size > max_size) {
drm_dbg_kms(&i915->drm,
- "found possible fb from plane %c\n",
- pipe_name(intel_crtc->pipe));
- fb = to_intel_framebuffer(crtc->primary->state->fb);
+ "found possible fb from [PLANE:%d:%s]\n",
+ plane->base.base.id, plane->base.name);
+ fb = to_intel_framebuffer(plane_state->uapi.fb);
max_size = obj->base.size;
}
}
@@ -372,60 +383,62 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
}
/* Now make sure all the pipes will fit into it */
- for_each_crtc(dev, crtc) {
+ for_each_intel_crtc(dev, crtc) {
+ struct intel_crtc_state *crtc_state =
+ to_intel_crtc_state(crtc->base.state);
+ struct intel_plane *plane =
+ to_intel_plane(crtc->base.primary);
unsigned int cur_size;
- intel_crtc = to_intel_crtc(crtc);
-
- if (!crtc->state->active) {
+ if (!crtc_state->uapi.active) {
drm_dbg_kms(&i915->drm,
- "pipe %c not active, skipping\n",
- pipe_name(intel_crtc->pipe));
+ "[CRTC:%d:%s] not active, skipping\n",
+ crtc->base.base.id, crtc->base.name);
continue;
}
- drm_dbg_kms(&i915->drm, "checking plane %c for BIOS fb\n",
- pipe_name(intel_crtc->pipe));
+ drm_dbg_kms(&i915->drm, "checking [PLANE:%d:%s] for BIOS fb\n",
+ plane->base.base.id, plane->base.name);
/*
* See if the plane fb we found above will fit on this
* pipe. Note we need to use the selected fb's pitch and bpp
* rather than the current pipe's, since they differ.
*/
- cur_size = crtc->state->adjusted_mode.crtc_hdisplay;
+ cur_size = crtc_state->uapi.adjusted_mode.crtc_hdisplay;
cur_size = cur_size * fb->base.format->cpp[0];
if (fb->base.pitches[0] < cur_size) {
drm_dbg_kms(&i915->drm,
- "fb not wide enough for plane %c (%d vs %d)\n",
- pipe_name(intel_crtc->pipe),
+ "fb not wide enough for [PLANE:%d:%s] (%d vs %d)\n",
+ plane->base.base.id, plane->base.name,
cur_size, fb->base.pitches[0]);
fb = NULL;
break;
}
- cur_size = crtc->state->adjusted_mode.crtc_vdisplay;
+ cur_size = crtc_state->uapi.adjusted_mode.crtc_vdisplay;
cur_size = intel_fb_align_height(&fb->base, 0, cur_size);
cur_size *= fb->base.pitches[0];
drm_dbg_kms(&i915->drm,
- "pipe %c area: %dx%d, bpp: %d, size: %d\n",
- pipe_name(intel_crtc->pipe),
- crtc->state->adjusted_mode.crtc_hdisplay,
- crtc->state->adjusted_mode.crtc_vdisplay,
+ "[CRTC:%d:%s] area: %dx%d, bpp: %d, size: %d\n",
+ crtc->base.base.id, crtc->base.name,
+ crtc_state->uapi.adjusted_mode.crtc_hdisplay,
+ crtc_state->uapi.adjusted_mode.crtc_vdisplay,
fb->base.format->cpp[0] * 8,
cur_size);
if (cur_size > max_size) {
drm_dbg_kms(&i915->drm,
- "fb not big enough for plane %c (%d vs %d)\n",
- pipe_name(intel_crtc->pipe),
+ "fb not big enough for [PLANE:%d:%s] (%d vs %d)\n",
+ plane->base.base.id, plane->base.name,
cur_size, max_size);
fb = NULL;
break;
}
drm_dbg_kms(&i915->drm,
- "fb big enough for plane %c (%d >= %d)\n",
- pipe_name(intel_crtc->pipe),
+ "fb big enough [PLANE:%d:%s] (%d >= %d)\n",
+ plane->base.base.id, plane->base.name,
max_size, cur_size);
}
@@ -441,15 +454,20 @@ static bool intel_fbdev_init_bios(struct drm_device *dev,
drm_framebuffer_get(&ifbdev->fb->base);
/* Final pass to check if any active pipes don't have fbs */
- for_each_crtc(dev, crtc) {
- intel_crtc = to_intel_crtc(crtc);
-
- if (!crtc->state->active)
+ for_each_intel_crtc(dev, crtc) {
+ struct intel_crtc_state *crtc_state =
+ to_intel_crtc_state(crtc->base.state);
+ struct intel_plane *plane =
+ to_intel_plane(crtc->base.primary);
+ struct intel_plane_state *plane_state =
+ to_intel_plane_state(plane->base.state);
+
+ if (!crtc_state->uapi.active)
continue;
- drm_WARN(dev, !crtc->primary->state->fb,
- "re-used BIOS config but lost an fb on crtc %d\n",
- crtc->base.id);
+ drm_WARN(dev, !plane_state->uapi.fb,
+ "re-used BIOS config but lost an fb on [PLANE:%d:%s]\n",
+ plane->base.base.id, plane->base.name);
}
diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c
index cef1061fd6cb..e10b9cd8e86e 100644
--- a/drivers/gpu/drm/i915/display/intel_fdi.c
+++ b/drivers/gpu/drm/i915/display/intel_fdi.c
@@ -4,7 +4,6 @@
*/
#include "intel_atomic.h"
#include "intel_ddi.h"
-#include "intel_ddi_buf_trans.h"
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_fdi.h"
@@ -96,10 +95,10 @@ static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
}
}
-int ilk_fdi_compute_config(struct intel_crtc *intel_crtc,
- struct intel_crtc_state *pipe_config)
+int ilk_fdi_compute_config(struct intel_crtc *crtc,
+ struct intel_crtc_state *pipe_config)
{
- struct drm_device *dev = intel_crtc->base.dev;
+ struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *i915 = to_i915(dev);
const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
int lane, link_bw, fdi_dotclock, ret;
@@ -125,7 +124,7 @@ retry:
intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
link_bw, &pipe_config->fdi_m_n, false, false);
- ret = ilk_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
+ ret = ilk_check_fdi_lanes(dev, crtc->pipe, pipe_config);
if (ret == -EDEADLK)
return ret;
@@ -569,9 +568,9 @@ void hsw_fdi_link_train(struct intel_encoder *encoder,
u32 temp, i, rx_ctl_val;
int n_entries;
- intel_ddi_get_buf_trans_fdi(dev_priv, &n_entries);
+ encoder->get_buf_trans(encoder, crtc_state, &n_entries);
- intel_prepare_dp_ddi_buffers(encoder, crtc_state);
+ hsw_prepare_dp_ddi_buffers(encoder, crtc_state);
/* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
* mode set "sequence for CRT port" document:
@@ -691,9 +690,9 @@ void hsw_fdi_link_train(struct intel_encoder *encoder,
void ilk_fdi_pll_enable(const struct intel_crtc_state *crtc_state)
{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
- enum pipe pipe = intel_crtc->pipe;
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ enum pipe pipe = crtc->pipe;
i915_reg_t reg;
u32 temp;
@@ -726,11 +725,11 @@ void ilk_fdi_pll_enable(const struct intel_crtc_state *crtc_state)
}
}
-void ilk_fdi_pll_disable(struct intel_crtc *intel_crtc)
+void ilk_fdi_pll_disable(struct intel_crtc *crtc)
{
- struct drm_device *dev = intel_crtc->base.dev;
+ struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
- enum pipe pipe = intel_crtc->pipe;
+ enum pipe pipe = crtc->pipe;
i915_reg_t reg;
u32 temp;
diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c b/drivers/gpu/drm/i915/display/intel_gmbus.c
index fcf47f98ea36..ceb1bf8a8c3c 100644
--- a/drivers/gpu/drm/i915/display/intel_gmbus.c
+++ b/drivers/gpu/drm/i915/display/intel_gmbus.c
@@ -600,7 +600,7 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num,
int i = 0, inc, try = 0;
int ret = 0;
- /* Display WA #0868: skl,bxt,kbl,cfl,glk,cnl */
+ /* Display WA #0868: skl,bxt,kbl,cfl,glk */
if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
bxt_gmbus_clock_gating(dev_priv, false);
else if (HAS_PCH_SPT(dev_priv) || HAS_PCH_CNP(dev_priv))
@@ -713,7 +713,7 @@ timeout:
ret = -EAGAIN;
out:
- /* Display WA #0868: skl,bxt,kbl,cfl,glk,cnl */
+ /* Display WA #0868: skl,bxt,kbl,cfl,glk */
if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
bxt_gmbus_clock_gating(dev_priv, true);
else if (HAS_PCH_SPT(dev_priv) || HAS_PCH_CNP(dev_priv))
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 7e51c98c475e..b04685bb6439 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -51,6 +51,7 @@
#include "intel_hdmi.h"
#include "intel_lspcon.h"
#include "intel_panel.h"
+#include "intel_snps_phy.h"
static struct drm_device *intel_hdmi_to_dev(struct intel_hdmi *intel_hdmi)
{
@@ -270,8 +271,8 @@ static void ibx_write_infoframe(struct intel_encoder *encoder,
{
const u32 *data = frame;
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
- i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ i915_reg_t reg = TVIDEO_DIP_CTL(crtc->pipe);
u32 val = intel_de_read(dev_priv, reg);
int i;
@@ -286,13 +287,13 @@ static void ibx_write_infoframe(struct intel_encoder *encoder,
intel_de_write(dev_priv, reg, val);
for (i = 0; i < len; i += 4) {
- intel_de_write(dev_priv, TVIDEO_DIP_DATA(intel_crtc->pipe),
+ intel_de_write(dev_priv, TVIDEO_DIP_DATA(crtc->pipe),
*data);
data++;
}
/* Write every possible data byte to force correct ECC calculation. */
for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
- intel_de_write(dev_priv, TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
+ intel_de_write(dev_priv, TVIDEO_DIP_DATA(crtc->pipe), 0);
val |= g4x_infoframe_enable(type);
val &= ~VIDEO_DIP_FREQ_MASK;
@@ -349,8 +350,8 @@ static void cpt_write_infoframe(struct intel_encoder *encoder,
{
const u32 *data = frame;
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
- i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ i915_reg_t reg = TVIDEO_DIP_CTL(crtc->pipe);
u32 val = intel_de_read(dev_priv, reg);
int i;
@@ -368,13 +369,13 @@ static void cpt_write_infoframe(struct intel_encoder *encoder,
intel_de_write(dev_priv, reg, val);
for (i = 0; i < len; i += 4) {
- intel_de_write(dev_priv, TVIDEO_DIP_DATA(intel_crtc->pipe),
+ intel_de_write(dev_priv, TVIDEO_DIP_DATA(crtc->pipe),
*data);
data++;
}
/* Write every possible data byte to force correct ECC calculation. */
for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
- intel_de_write(dev_priv, TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
+ intel_de_write(dev_priv, TVIDEO_DIP_DATA(crtc->pipe), 0);
val |= g4x_infoframe_enable(type);
val &= ~VIDEO_DIP_FREQ_MASK;
@@ -427,8 +428,8 @@ static void vlv_write_infoframe(struct intel_encoder *encoder,
{
const u32 *data = frame;
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
- i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ i915_reg_t reg = VLV_TVIDEO_DIP_CTL(crtc->pipe);
u32 val = intel_de_read(dev_priv, reg);
int i;
@@ -444,13 +445,13 @@ static void vlv_write_infoframe(struct intel_encoder *encoder,
for (i = 0; i < len; i += 4) {
intel_de_write(dev_priv,
- VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
+ VLV_TVIDEO_DIP_DATA(crtc->pipe), *data);
data++;
}
/* Write every possible data byte to force correct ECC calculation. */
for (; i < VIDEO_DIP_DATA_SIZE; i += 4)
intel_de_write(dev_priv,
- VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
+ VLV_TVIDEO_DIP_DATA(crtc->pipe), 0);
val |= g4x_infoframe_enable(type);
val &= ~VIDEO_DIP_FREQ_MASK;
@@ -1040,10 +1041,10 @@ static void ibx_set_infoframes(struct intel_encoder *encoder,
const struct drm_connector_state *conn_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct intel_hdmi *intel_hdmi = &dig_port->hdmi;
- i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
+ i915_reg_t reg = TVIDEO_DIP_CTL(crtc->pipe);
u32 val = intel_de_read(dev_priv, reg);
u32 port = VIDEO_DIP_PORT(encoder->port);
@@ -1099,9 +1100,9 @@ static void cpt_set_infoframes(struct intel_encoder *encoder,
const struct drm_connector_state *conn_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
- i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
+ i915_reg_t reg = TVIDEO_DIP_CTL(crtc->pipe);
u32 val = intel_de_read(dev_priv, reg);
assert_hdmi_port_disabled(intel_hdmi);
@@ -1148,9 +1149,9 @@ static void vlv_set_infoframes(struct intel_encoder *encoder,
const struct drm_connector_state *conn_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
- i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
+ i915_reg_t reg = VLV_TVIDEO_DIP_CTL(crtc->pipe);
u32 val = intel_de_read(dev_priv, reg);
u32 port = VIDEO_DIP_PORT(encoder->port);
@@ -1465,14 +1466,12 @@ static int kbl_repositioning_enc_en_signal(struct intel_connector *connector,
{
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
- struct drm_crtc *crtc = connector->base.state->crtc;
- struct intel_crtc *intel_crtc = container_of(crtc,
- struct intel_crtc, base);
+ struct intel_crtc *crtc = to_intel_crtc(connector->base.state->crtc);
u32 scanline;
int ret;
for (;;) {
- scanline = intel_de_read(dev_priv, PIPEDSL(intel_crtc->pipe));
+ scanline = intel_de_read(dev_priv, PIPEDSL(crtc->pipe));
if (scanline > 100 && scanline < 200)
break;
usleep_range(25, 50);
@@ -1852,6 +1851,16 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi,
if (IS_CHERRYVIEW(dev_priv) && clock > 216000 && clock < 240000)
return MODE_CLOCK_RANGE;
+ /*
+ * SNPS PHYs' MPLLB table-based programming can only handle a fixed
+ * set of link rates.
+ *
+ * FIXME: We will hopefully get an algorithmic way of programming
+ * the MPLLB for HDMI in the future.
+ */
+ if (IS_DG2(dev_priv))
+ return intel_snps_phy_check_hdmi_link_rate(clock);
+
return MODE_OK;
}
diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
index 7f40e9f60bc2..e0381b0fce91 100644
--- a/drivers/gpu/drm/i915/display/intel_lvds.c
+++ b/drivers/gpu/drm/i915/display/intel_lvds.c
@@ -411,12 +411,12 @@ static int intel_lvds_compute_config(struct intel_encoder *intel_encoder,
struct intel_connector *intel_connector =
lvds_encoder->attached_connector;
struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
- struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
+ struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
unsigned int lvds_bpp;
int ret;
/* Should never happen!! */
- if (DISPLAY_VER(dev_priv) < 4 && intel_crtc->pipe == 0) {
+ if (DISPLAY_VER(dev_priv) < 4 && crtc->pipe == 0) {
drm_err(&dev_priv->drm, "Can't support LVDS on pipe A\n");
return -EINVAL;
}
diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c
index dfd724e506b5..3855fba70980 100644
--- a/drivers/gpu/drm/i915/display/intel_opregion.c
+++ b/drivers/gpu/drm/i915/display/intel_opregion.c
@@ -1078,6 +1078,9 @@ void intel_opregion_resume(struct drm_i915_private *i915)
opregion->asle->ardy = ASLE_ARDY_READY;
}
+ /* Some platforms abuse the _DSM to enable MUX */
+ intel_dsm_get_bios_data_funcs_supported(i915);
+
intel_opregion_notify_adapter(i915, PCI_D0);
}
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 77865cf6641f..1b0daf649e82 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -32,6 +32,7 @@
#include "intel_dp_aux.h"
#include "intel_hdmi.h"
#include "intel_psr.h"
+#include "intel_snps_phy.h"
#include "intel_sprite.h"
#include "skl_universal_plane.h"
@@ -265,32 +266,44 @@ static u8 intel_dp_get_sink_sync_latency(struct intel_dp *intel_dp)
return val;
}
-static u16 intel_dp_get_su_x_granulartiy(struct intel_dp *intel_dp)
+static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
- u16 val;
ssize_t r;
+ u16 w;
+ u8 y;
+
+ /* If sink don't have specific granularity requirements set legacy ones */
+ if (!(intel_dp->psr_dpcd[1] & DP_PSR2_SU_GRANULARITY_REQUIRED)) {
+ /* As PSR2 HW sends full lines, we do not care about x granularity */
+ w = 4;
+ y = 4;
+ goto exit;
+ }
- /*
- * Returning the default X granularity if granularity not required or
- * if DPCD read fails
- */
- if (!(intel_dp->psr_dpcd[1] & DP_PSR2_SU_GRANULARITY_REQUIRED))
- return 4;
-
- r = drm_dp_dpcd_read(&intel_dp->aux, DP_PSR2_SU_X_GRANULARITY, &val, 2);
+ r = drm_dp_dpcd_read(&intel_dp->aux, DP_PSR2_SU_X_GRANULARITY, &w, 2);
if (r != 2)
drm_dbg_kms(&i915->drm,
"Unable to read DP_PSR2_SU_X_GRANULARITY\n");
-
/*
* Spec says that if the value read is 0 the default granularity should
* be used instead.
*/
- if (r != 2 || val == 0)
- val = 4;
+ if (r != 2 || w == 0)
+ w = 4;
- return val;
+ r = drm_dp_dpcd_read(&intel_dp->aux, DP_PSR2_SU_Y_GRANULARITY, &y, 1);
+ if (r != 1) {
+ drm_dbg_kms(&i915->drm,
+ "Unable to read DP_PSR2_SU_Y_GRANULARITY\n");
+ y = 4;
+ }
+ if (y == 0)
+ y = 1;
+
+exit:
+ intel_dp->psr.su_w_granularity = w;
+ intel_dp->psr.su_y_granularity = y;
}
void intel_psr_init_dpcd(struct intel_dp *intel_dp)
@@ -346,8 +359,7 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp)
if (intel_dp->psr.sink_psr2_support) {
intel_dp->psr.colorimetry_support =
intel_dp_get_colorimetry_status(intel_dp);
- intel_dp->psr.su_x_granularity =
- intel_dp_get_su_x_granulartiy(intel_dp);
+ intel_dp_get_su_granularity(intel_dp);
}
}
}
@@ -407,6 +419,9 @@ static void intel_psr_enable_sink(struct intel_dp *intel_dp)
dpcd_val |= DP_PSR_CRC_VERIFICATION;
}
+ if (intel_dp->psr.req_psr2_sdp_prior_scanline)
+ dpcd_val |= DP_PSR_SU_REGION_SCANLINE_CAPTURE;
+
drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, dpcd_val);
drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
@@ -520,18 +535,47 @@ static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp)
static void hsw_activate_psr2(struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- u32 val;
+ u32 val = EDP_PSR2_ENABLE;
- val = psr_compute_idle_frames(intel_dp) << EDP_PSR2_IDLE_FRAME_SHIFT;
+ val |= psr_compute_idle_frames(intel_dp) << EDP_PSR2_IDLE_FRAME_SHIFT;
+
+ if (!IS_ALDERLAKE_P(dev_priv))
+ val |= EDP_SU_TRACK_ENABLE;
- val |= EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE;
if (DISPLAY_VER(dev_priv) >= 10 && DISPLAY_VER(dev_priv) <= 12)
val |= EDP_Y_COORDINATE_ENABLE;
val |= EDP_PSR2_FRAME_BEFORE_SU(intel_dp->psr.sink_sync_latency + 1);
val |= intel_psr2_get_tp_time(intel_dp);
- if (DISPLAY_VER(dev_priv) >= 12) {
+ /* Wa_22012278275:adl-p */
+ if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_E0)) {
+ static const u8 map[] = {
+ 2, /* 5 lines */
+ 1, /* 6 lines */
+ 0, /* 7 lines */
+ 3, /* 8 lines */
+ 6, /* 9 lines */
+ 5, /* 10 lines */
+ 4, /* 11 lines */
+ 7, /* 12 lines */
+ };
+ /*
+ * Still using the default IO_BUFFER_WAKE and FAST_WAKE, see
+ * comments bellow for more information
+ */
+ u32 tmp, lines = 7;
+
+ val |= TGL_EDP_PSR2_BLOCK_COUNT_NUM_2;
+
+ tmp = map[lines - TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES];
+ tmp = tmp << TGL_EDP_PSR2_IO_BUFFER_WAKE_SHIFT;
+ val |= tmp;
+
+ tmp = map[lines - TGL_EDP_PSR2_FAST_WAKE_MIN_LINES];
+ tmp = tmp << TGL_EDP_PSR2_FAST_WAKE_MIN_SHIFT;
+ val |= tmp;
+ } else if (DISPLAY_VER(dev_priv) >= 12) {
/*
* TODO: 7 lines of IO_BUFFER_WAKE and FAST_WAKE are default
* values from BSpec. In order to setting an optimal power
@@ -547,10 +591,12 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
val |= EDP_PSR2_FAST_WAKE(7);
}
+ if (intel_dp->psr.req_psr2_sdp_prior_scanline)
+ val |= EDP_PSR2_SU_SDP_SCANLINE;
+
if (intel_dp->psr.psr2_sel_fetch_enabled) {
- /* WA 1408330847 */
- if (IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A0) ||
- IS_RKL_REVID(dev_priv, RKL_REVID_A0, RKL_REVID_A0))
+ /* Wa_1408330847 */
+ if (IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0))
intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
DIS_RAM_BYPASS_PSR2_MAN_TRACK,
DIS_RAM_BYPASS_PSR2_MAN_TRACK);
@@ -689,6 +735,10 @@ tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp,
if (!dc3co_is_pipe_port_compatible(intel_dp, crtc_state))
return;
+ /* Wa_16011303918:adl-p */
+ if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0))
+ return;
+
/*
* DC3CO Exit time 200us B.Spec 49196
* PSR2 transcoder Early Exit scanlines = ROUNDUP(200 / line time) + 1
@@ -733,7 +783,7 @@ static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
}
/* Wa_14010254185 Wa_14010103792 */
- if (IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B1)) {
+ if (IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_C0)) {
drm_dbg_kms(&dev_priv->drm,
"PSR2 sel fetch not enabled, missing the implementation of WAs\n");
return false;
@@ -742,6 +792,67 @@ static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
return crtc_state->enable_psr2_sel_fetch = true;
}
+static bool psr2_granularity_check(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+ const int crtc_hdisplay = crtc_state->hw.adjusted_mode.crtc_hdisplay;
+ const int crtc_vdisplay = crtc_state->hw.adjusted_mode.crtc_vdisplay;
+ u16 y_granularity = 0;
+
+ /* PSR2 HW only send full lines so we only need to validate the width */
+ if (crtc_hdisplay % intel_dp->psr.su_w_granularity)
+ return false;
+
+ if (crtc_vdisplay % intel_dp->psr.su_y_granularity)
+ return false;
+
+ /* HW tracking is only aligned to 4 lines */
+ if (!crtc_state->enable_psr2_sel_fetch)
+ return intel_dp->psr.su_y_granularity == 4;
+
+ /*
+ * adl_p has 1 line granularity. For other platforms with SW tracking we
+ * can adjust the y coordinates to match sink requirement if multiple of
+ * 4.
+ */
+ if (IS_ALDERLAKE_P(dev_priv))
+ y_granularity = intel_dp->psr.su_y_granularity;
+ else if (intel_dp->psr.su_y_granularity <= 2)
+ y_granularity = 4;
+ else if ((intel_dp->psr.su_y_granularity % 4) == 0)
+ y_granularity = intel_dp->psr.su_y_granularity;
+
+ if (y_granularity == 0 || crtc_vdisplay % y_granularity)
+ return false;
+
+ crtc_state->su_y_granularity = y_granularity;
+ return true;
+}
+
+static bool _compute_psr2_sdp_prior_scanline_indication(struct intel_dp *intel_dp,
+ struct intel_crtc_state *crtc_state)
+{
+ const struct drm_display_mode *adjusted_mode = &crtc_state->uapi.adjusted_mode;
+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+ u32 hblank_total, hblank_ns, req_ns;
+
+ hblank_total = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
+ hblank_ns = div_u64(1000000ULL * hblank_total, adjusted_mode->crtc_clock);
+
+ /* From spec: (72 / number of lanes) * 1000 / symbol clock frequency MHz */
+ req_ns = (72 / crtc_state->lane_count) * 1000 / (crtc_state->port_clock / 1000);
+
+ if ((hblank_ns - req_ns) > 100)
+ return true;
+
+ if (DISPLAY_VER(dev_priv) < 13 || intel_dp->edp_dpcd[0] < DP_EDP_14b)
+ return false;
+
+ crtc_state->req_psr2_sdp_prior_scanline = true;
+ return true;
+}
+
static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state)
{
@@ -760,7 +871,8 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
}
/* Wa_16011181250 */
- if (IS_ROCKETLAKE(dev_priv) || IS_ALDERLAKE_S(dev_priv)) {
+ if (IS_ROCKETLAKE(dev_priv) || IS_ALDERLAKE_S(dev_priv) ||
+ IS_DG2(dev_priv)) {
drm_dbg_kms(&dev_priv->drm, "PSR2 is defeatured for this platform\n");
return false;
}
@@ -824,19 +936,6 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
return false;
}
- /*
- * HW sends SU blocks of size four scan lines, which means the starting
- * X coordinate and Y granularity requirements will always be met. We
- * only need to validate the SU block width is a multiple of
- * x granularity.
- */
- if (crtc_hdisplay % intel_dp->psr.su_x_granularity) {
- drm_dbg_kms(&dev_priv->drm,
- "PSR2 not enabled, hdisplay(%d) not multiple of %d\n",
- crtc_hdisplay, intel_dp->psr.su_x_granularity);
- 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)) {
@@ -848,11 +947,16 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
/* Wa_2209313811 */
if (!crtc_state->enable_psr2_sel_fetch &&
- IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B1)) {
+ IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_C0)) {
drm_dbg_kms(&dev_priv->drm, "PSR2 HW tracking is not supported this Display stepping\n");
return false;
}
+ if (!psr2_granularity_check(intel_dp, crtc_state)) {
+ drm_dbg_kms(&dev_priv->drm, "PSR2 not enabled, SU granularity not compatible\n");
+ return false;
+ }
+
if (!crtc_state->enable_psr2_sel_fetch &&
(crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v)) {
drm_dbg_kms(&dev_priv->drm,
@@ -862,6 +966,20 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
return false;
}
+ if (!_compute_psr2_sdp_prior_scanline_indication(intel_dp, crtc_state)) {
+ drm_dbg_kms(&dev_priv->drm,
+ "PSR2 not enabled, PSR2 SDP indication do not fit in hblank\n");
+ return false;
+ }
+
+ /* Wa_16011303918:adl-p */
+ if (crtc_state->vrr.enable &&
+ IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0)) {
+ drm_dbg_kms(&dev_priv->drm,
+ "PSR2 not enabled, not compatible with HW stepping + VRR\n");
+ return false;
+ }
+
tgl_dc3co_exitline_compute_config(intel_dp, crtc_state);
return true;
}
@@ -1048,6 +1166,14 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp)
intel_de_rmw(dev_priv, CHICKEN_PAR1_1, IGNORE_PSR2_HW_TRACKING,
intel_dp->psr.psr2_sel_fetch_enabled ?
IGNORE_PSR2_HW_TRACKING : 0);
+
+ /* Wa_16011168373:adl-p */
+ if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0) &&
+ intel_dp->psr.psr2_enabled)
+ intel_de_rmw(dev_priv,
+ TRANS_SET_CONTEXT_LATENCY(intel_dp->psr.transcoder),
+ TRANS_SET_CONTEXT_LATENCY_MASK,
+ TRANS_SET_CONTEXT_LATENCY_VALUE(1));
}
static bool psr_interrupt_error_check(struct intel_dp *intel_dp)
@@ -1087,6 +1213,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
{
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+ enum phy phy = intel_port_to_phy(dev_priv, dig_port->base.port);
struct intel_encoder *encoder = &dig_port->base;
u32 val;
@@ -1101,6 +1228,8 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
intel_dp->psr.dc3co_exit_delay = val;
intel_dp->psr.dc3co_exitline = crtc_state->dc3co_exitline;
intel_dp->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch;
+ intel_dp->psr.req_psr2_sdp_prior_scanline =
+ crtc_state->req_psr2_sdp_prior_scanline;
if (!psr_interrupt_error_check(intel_dp))
return;
@@ -1110,6 +1239,7 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
intel_dp_compute_psr_vsc_sdp(intel_dp, crtc_state, conn_state,
&intel_dp->psr.vsc);
intel_write_dp_vsc_sdp(encoder, crtc_state, &intel_dp->psr.vsc);
+ intel_snps_phy_update_psr_power_state(dev_priv, phy, true);
intel_psr_enable_sink(intel_dp);
intel_psr_enable_source(intel_dp);
intel_dp->psr.enabled = true;
@@ -1206,6 +1336,8 @@ static void intel_psr_wait_exit_locked(struct intel_dp *intel_dp)
static void intel_psr_disable_locked(struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+ enum phy phy = intel_port_to_phy(dev_priv,
+ dp_to_dig_port(intel_dp)->base.port);
lockdep_assert_held(&intel_dp->psr.lock);
@@ -1218,13 +1350,21 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp)
intel_psr_exit(intel_dp);
intel_psr_wait_exit_locked(intel_dp);
- /* WA 1408330847 */
+ /* Wa_1408330847 */
if (intel_dp->psr.psr2_sel_fetch_enabled &&
- (IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A0) ||
- IS_RKL_REVID(dev_priv, RKL_REVID_A0, RKL_REVID_A0)))
+ IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0))
intel_de_rmw(dev_priv, CHICKEN_PAR1_1,
DIS_RAM_BYPASS_PSR2_MAN_TRACK, 0);
+ /* Wa_16011168373:adl-p */
+ if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0) &&
+ intel_dp->psr.psr2_enabled)
+ intel_de_rmw(dev_priv,
+ TRANS_SET_CONTEXT_LATENCY(intel_dp->psr.transcoder),
+ TRANS_SET_CONTEXT_LATENCY_MASK, 0);
+
+ intel_snps_phy_update_psr_power_state(dev_priv, phy, false);
+
/* Disable PSR on Sink */
drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0);
@@ -1397,21 +1537,32 @@ void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_st
static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state,
struct drm_rect *clip, bool full_update)
{
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 val = PSR2_MAN_TRK_CTL_ENABLE;
if (full_update) {
- val |= PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME;
+ if (IS_ALDERLAKE_P(dev_priv))
+ val |= ADLP_PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME;
+ else
+ val |= PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME;
+
goto exit;
}
if (clip->y1 == -1)
goto exit;
- drm_WARN_ON(crtc_state->uapi.crtc->dev, clip->y1 % 4 || clip->y2 % 4);
+ if (IS_ALDERLAKE_P(dev_priv)) {
+ val |= ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(clip->y1);
+ val |= ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(clip->y2);
+ } else {
+ drm_WARN_ON(crtc_state->uapi.crtc->dev, clip->y1 % 4 || clip->y2 % 4);
- val |= PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE;
- val |= PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(clip->y1 / 4 + 1);
- val |= PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(clip->y2 / 4 + 1);
+ val |= PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE;
+ val |= PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(clip->y1 / 4 + 1);
+ val |= PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(clip->y2 / 4 + 1);
+ }
exit:
crtc_state->psr2_man_track_ctl = val;
}
@@ -1432,6 +1583,20 @@ static void clip_area_update(struct drm_rect *overlap_damage_area,
overlap_damage_area->y2 = damage_area->y2;
}
+static void intel_psr2_sel_fetch_pipe_alignment(const struct intel_crtc_state *crtc_state,
+ struct drm_rect *pipe_clip)
+{
+ struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+ const u16 y_alignment = crtc_state->su_y_granularity;
+
+ pipe_clip->y1 -= pipe_clip->y1 % y_alignment;
+ if (pipe_clip->y2 % y_alignment)
+ pipe_clip->y2 = ((pipe_clip->y2 / y_alignment) + 1) * y_alignment;
+
+ if (IS_ALDERLAKE_P(dev_priv) && crtc_state->dsc.compression_enable)
+ drm_warn(&dev_priv->drm, "Missing PSR2 sel fetch alignment with DSC\n");
+}
+
int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
struct intel_crtc *crtc)
{
@@ -1540,10 +1705,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
if (full_update)
goto skip_sel_fetch_set_loop;
- /* It must be aligned to 4 lines */
- pipe_clip.y1 -= pipe_clip.y1 % 4;
- if (pipe_clip.y2 % 4)
- pipe_clip.y2 = ((pipe_clip.y2 / 4) + 1) * 4;
+ intel_psr2_sel_fetch_pipe_alignment(crtc_state, &pipe_clip);
/*
* Now that we have the pipe damaged area check if it intersect with
@@ -1564,6 +1726,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
sel_fetch_area = &new_plane_state->psr2_sel_fetch_area;
sel_fetch_area->y1 = inter.y1 - new_plane_state->uapi.dst.y1;
sel_fetch_area->y2 = inter.y2 - new_plane_state->uapi.dst.y1;
+ crtc_state->update_planes |= BIT(plane->id);
}
skip_sel_fetch_set_loop:
diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c
index 98dd787b00e3..8a52b7a16774 100644
--- a/drivers/gpu/drm/i915/display/intel_quirks.c
+++ b/drivers/gpu/drm/i915/display/intel_quirks.c
@@ -53,6 +53,12 @@ static void quirk_increase_ddi_disabled_time(struct drm_i915_private *i915)
drm_info(&i915->drm, "Applying Increase DDI Disabled quirk\n");
}
+static void quirk_no_pps_backlight_power_hook(struct drm_i915_private *i915)
+{
+ i915->quirks |= QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK;
+ drm_info(&i915->drm, "Applying no pps backlight power quirk\n");
+}
+
struct intel_quirk {
int device;
int subsystem_vendor;
@@ -72,6 +78,12 @@ static int intel_dmi_reverse_brightness(const struct dmi_system_id *id)
return 1;
}
+static int intel_dmi_no_pps_backlight(const struct dmi_system_id *id)
+{
+ DRM_INFO("No pps backlight support on %s\n", id->ident);
+ return 1;
+}
+
static const struct intel_dmi_quirk intel_dmi_quirks[] = {
{
.dmi_id_list = &(const struct dmi_system_id[]) {
@@ -96,6 +108,28 @@ static const struct intel_dmi_quirk intel_dmi_quirks[] = {
},
.hook = quirk_invert_brightness,
},
+ {
+ .dmi_id_list = &(const struct dmi_system_id[]) {
+ {
+ .callback = intel_dmi_no_pps_backlight,
+ .ident = "Google Lillipup sku524294",
+ .matches = {DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Google"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "Lindar"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "sku524294"),
+ },
+ },
+ {
+ .callback = intel_dmi_no_pps_backlight,
+ .ident = "Google Lillipup sku524295",
+ .matches = {DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Google"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "Lindar"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "sku524295"),
+ },
+ },
+ { }
+ },
+ .hook = quirk_no_pps_backlight_power_hook,
+ },
};
static struct intel_quirk intel_quirks[] = {
diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
index e4f91d7a5c60..6cb27599ea03 100644
--- a/drivers/gpu/drm/i915/display/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
@@ -1824,7 +1824,7 @@ static void intel_enable_sdvo(struct intel_atomic_state *state,
struct drm_device *dev = encoder->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
- struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
+ struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
u32 temp;
bool input1, input2;
int i;
@@ -1835,7 +1835,7 @@ static void intel_enable_sdvo(struct intel_atomic_state *state,
intel_sdvo_write_sdvox(intel_sdvo, temp);
for (i = 0; i < 2; i++)
- intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
+ intel_wait_for_vblank(dev_priv, crtc->pipe);
success = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2);
/*
diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c
new file mode 100644
index 000000000000..18b52b64af95
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c
@@ -0,0 +1,862 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2019 Intel Corporation
+ */
+
+#include <linux/util_macros.h>
+
+#include "intel_de.h"
+#include "intel_display_types.h"
+#include "intel_snps_phy.h"
+
+/**
+ * DOC: Synopsis PHY support
+ *
+ * Synopsis PHYs are primarily programmed by looking up magic register values
+ * in tables rather than calculating the necessary values at runtime.
+ *
+ * Of special note is that the SNPS PHYs include a dedicated port PLL, known as
+ * an "MPLLB." The MPLLB replaces the shared DPLL functionality used on other
+ * platforms and must be programming directly during the modeset sequence
+ * since it is not handled by the shared DPLL framework as on other platforms.
+ */
+
+void intel_snps_phy_wait_for_calibration(struct drm_i915_private *dev_priv)
+{
+ enum phy phy;
+
+ for_each_phy_masked(phy, ~0) {
+ if (!intel_phy_is_snps(dev_priv, phy))
+ continue;
+
+ if (intel_de_wait_for_clear(dev_priv, ICL_PHY_MISC(phy),
+ DG2_PHY_DP_TX_ACK_MASK, 25))
+ DRM_ERROR("SNPS PHY %c failed to calibrate after 25ms.\n",
+ phy);
+ }
+}
+
+void intel_snps_phy_update_psr_power_state(struct drm_i915_private *dev_priv,
+ enum phy phy, bool enable)
+{
+ u32 val;
+
+ if (!intel_phy_is_snps(dev_priv, phy))
+ return;
+
+ val = REG_FIELD_PREP(SNPS_PHY_TX_REQ_LN_DIS_PWR_STATE_PSR,
+ enable ? 2 : 3);
+ intel_uncore_rmw(&dev_priv->uncore, SNPS_PHY_TX_REQ(phy),
+ SNPS_PHY_TX_REQ_LN_DIS_PWR_STATE_PSR, val);
+}
+
+static const u32 dg2_ddi_translations[] = {
+ /* VS 0, pre-emph 0 */
+ REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 26),
+
+ /* VS 0, pre-emph 1 */
+ REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 33) |
+ REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 6),
+
+ /* VS 0, pre-emph 2 */
+ REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 38) |
+ REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 12),
+
+ /* VS 0, pre-emph 3 */
+ REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 43) |
+ REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 19),
+
+ /* VS 1, pre-emph 0 */
+ REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 39),
+
+ /* VS 1, pre-emph 1 */
+ REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 44) |
+ REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 8),
+
+ /* VS 1, pre-emph 2 */
+ REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 47) |
+ REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 15),
+
+ /* VS 2, pre-emph 0 */
+ REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 52),
+
+ /* VS 2, pre-emph 1 */
+ REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 51) |
+ REG_FIELD_PREP(SNPS_PHY_TX_EQ_POST, 10),
+
+ /* VS 3, pre-emph 0 */
+ REG_FIELD_PREP(SNPS_PHY_TX_EQ_MAIN, 62),
+};
+
+void intel_snps_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
+ u32 level)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
+ int n_entries, ln;
+
+ n_entries = ARRAY_SIZE(dg2_ddi_translations);
+ if (level >= n_entries)
+ level = n_entries - 1;
+
+ for (ln = 0; ln < 4; ln++)
+ intel_de_write(dev_priv, SNPS_PHY_TX_EQ(ln, phy),
+ dg2_ddi_translations[level]);
+}
+
+/*
+ * Basic DP link rates with 100 MHz reference clock.
+ */
+
+static const struct intel_mpllb_state dg2_dp_rbr_100 = {
+ .clock = 162000,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 20) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 2),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 226),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
+ .mpllb_fracn2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 39321) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 3),
+};
+
+static const struct intel_mpllb_state dg2_dp_hbr1_100 = {
+ .clock = 270000,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 20) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 184),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
+};
+
+static const struct intel_mpllb_state dg2_dp_hbr2_100 = {
+ .clock = 540000,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 20) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 184),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
+};
+
+static const struct intel_mpllb_state dg2_dp_hbr3_100 = {
+ .clock = 810000,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 19) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 292),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
+};
+
+static const struct intel_mpllb_state *dg2_dp_100_tables[] = {
+ &dg2_dp_rbr_100,
+ &dg2_dp_hbr1_100,
+ &dg2_dp_hbr2_100,
+ &dg2_dp_hbr3_100,
+ NULL,
+};
+
+/*
+ * Basic DP link rates with 38.4 MHz reference clock.
+ */
+
+static const struct intel_mpllb_state dg2_dp_rbr_38_4 = {
+ .clock = 162000,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 1),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 25) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 2),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 304),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
+ .mpllb_fracn2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 49152),
+};
+
+static const struct intel_mpllb_state dg2_dp_hbr1_38_4 = {
+ .clock = 270000,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 1),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 25) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 248),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
+ .mpllb_fracn2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 40960),
+};
+
+static const struct intel_mpllb_state dg2_dp_hbr2_38_4 = {
+ .clock = 540000,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 1),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 25) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 248),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
+ .mpllb_fracn2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 40960),
+};
+
+static const struct intel_mpllb_state dg2_dp_hbr3_38_4 = {
+ .clock = 810000,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 1),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 26) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 388),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
+ .mpllb_fracn2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 61440),
+};
+
+static const struct intel_mpllb_state *dg2_dp_38_4_tables[] = {
+ &dg2_dp_rbr_38_4,
+ &dg2_dp_hbr1_38_4,
+ &dg2_dp_hbr2_38_4,
+ &dg2_dp_hbr3_38_4,
+ NULL,
+};
+
+/*
+ * eDP link rates with 100 MHz reference clock.
+ */
+
+static const struct intel_mpllb_state dg2_edp_r216 = {
+ .clock = 216000,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 19) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 312),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
+ .mpllb_fracn2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 52428) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 4),
+ .mpllb_sscen =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_PEAK, 50961),
+ .mpllb_sscstep =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 65752),
+};
+
+static const struct intel_mpllb_state dg2_edp_r243 = {
+ .clock = 243000,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 20) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 356),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
+ .mpllb_fracn2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 2),
+ .mpllb_sscen =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_PEAK, 57331),
+ .mpllb_sscstep =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 73971),
+};
+
+static const struct intel_mpllb_state dg2_edp_r324 = {
+ .clock = 324000,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 20) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 2),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 226),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
+ .mpllb_fracn2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 39321) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 3),
+ .mpllb_sscen =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_PEAK, 38221),
+ .mpllb_sscstep =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 49314),
+};
+
+static const struct intel_mpllb_state dg2_edp_r432 = {
+ .clock = 432000,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 19) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 312),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
+ .mpllb_fracn2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 52428) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 4),
+ .mpllb_sscen =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_PEAK, 50961),
+ .mpllb_sscstep =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_STEPSIZE, 65752),
+};
+
+static const struct intel_mpllb_state *dg2_edp_tables[] = {
+ &dg2_dp_rbr_100,
+ &dg2_edp_r216,
+ &dg2_edp_r243,
+ &dg2_dp_hbr1_100,
+ &dg2_edp_r324,
+ &dg2_edp_r432,
+ &dg2_dp_hbr2_100,
+ &dg2_dp_hbr3_100,
+ NULL,
+};
+
+/*
+ * HDMI link rates with 100 MHz reference clock.
+ */
+
+static const struct intel_mpllb_state dg2_hdmi_25_175 = {
+ .clock = 25175,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 15) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 5) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 128) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 143),
+ .mpllb_fracn2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 36663) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 71),
+ .mpllb_sscen =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
+};
+
+static const struct intel_mpllb_state dg2_hdmi_27_0 = {
+ .clock = 27000,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 15) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 5) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 140) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
+ .mpllb_fracn2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 2),
+ .mpllb_sscen =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
+};
+
+static const struct intel_mpllb_state dg2_hdmi_74_25 = {
+ .clock = 74250,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 15) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 3) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 86) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
+ .mpllb_fracn2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 2),
+ .mpllb_sscen =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
+};
+
+static const struct intel_mpllb_state dg2_hdmi_148_5 = {
+ .clock = 148500,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 15) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 86) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
+ .mpllb_fracn2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 2),
+ .mpllb_sscen =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
+};
+
+static const struct intel_mpllb_state dg2_hdmi_594 = {
+ .clock = 594000,
+ .ref_control =
+ REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 3),
+ .mpllb_cp =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 4) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 15) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 64) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 124),
+ .mpllb_div =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
+ .mpllb_div2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 86) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_HDMI_DIV, 1),
+ .mpllb_fracn1 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 5),
+ .mpllb_fracn2 =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 26214) |
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_REM, 2),
+ .mpllb_sscen =
+ REG_FIELD_PREP(SNPS_PHY_MPLLB_SSC_UP_SPREAD, 1),
+};
+
+static const struct intel_mpllb_state *dg2_hdmi_tables[] = {
+ &dg2_hdmi_25_175,
+ &dg2_hdmi_27_0,
+ &dg2_hdmi_74_25,
+ &dg2_hdmi_148_5,
+ &dg2_hdmi_594,
+ NULL,
+};
+
+static const struct intel_mpllb_state **
+intel_mpllb_tables_get(struct intel_crtc_state *crtc_state,
+ struct intel_encoder *encoder)
+{
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP)) {
+ return dg2_edp_tables;
+ } else if (intel_crtc_has_dp_encoder(crtc_state)) {
+ /*
+ * FIXME: Initially we're just enabling the "combo" outputs on
+ * port A-D. The MPLLB for those ports takes an input from the
+ * "Display Filter PLL" which always has an output frequency
+ * of 100 MHz, hence the use of the _100 tables below.
+ *
+ * Once we enable port TC1 it will either use the same 100 MHz
+ * "Display Filter PLL" (when strapped to support a native
+ * display connection) or different 38.4 MHz "Filter PLL" when
+ * strapped to support a USB connection, so we'll need to check
+ * that to determine which table to use.
+ */
+ if (0)
+ return dg2_dp_38_4_tables;
+ else
+ return dg2_dp_100_tables;
+ } else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
+ return dg2_hdmi_tables;
+ }
+
+ MISSING_CASE(encoder->type);
+ return NULL;
+}
+
+int intel_mpllb_calc_state(struct intel_crtc_state *crtc_state,
+ struct intel_encoder *encoder)
+{
+ const struct intel_mpllb_state **tables;
+ int i;
+
+ if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
+ if (intel_snps_phy_check_hdmi_link_rate(crtc_state->port_clock)
+ != MODE_OK) {
+ /*
+ * FIXME: Can only support fixed HDMI frequencies
+ * until we have a proper algorithm under a valid
+ * license.
+ */
+ DRM_DEBUG_KMS("Can't support HDMI link rate %d\n",
+ crtc_state->port_clock);
+ return -EINVAL;
+ }
+ }
+
+ tables = intel_mpllb_tables_get(crtc_state, encoder);
+ if (!tables)
+ return -EINVAL;
+
+ for (i = 0; tables[i]; i++) {
+ if (crtc_state->port_clock <= tables[i]->clock) {
+ crtc_state->mpllb_state = *tables[i];
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+void intel_mpllb_enable(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ const struct intel_mpllb_state *pll_state = &crtc_state->mpllb_state;
+ enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
+ i915_reg_t enable_reg = (phy <= PHY_D ?
+ DG2_PLL_ENABLE(phy) : MG_PLL_ENABLE(0));
+
+ /*
+ * 3. Software programs the following PLL registers for the desired
+ * frequency.
+ */
+ intel_de_write(dev_priv, SNPS_PHY_MPLLB_CP(phy), pll_state->mpllb_cp);
+ intel_de_write(dev_priv, SNPS_PHY_MPLLB_DIV(phy), pll_state->mpllb_div);
+ intel_de_write(dev_priv, SNPS_PHY_MPLLB_DIV2(phy), pll_state->mpllb_div2);
+ intel_de_write(dev_priv, SNPS_PHY_MPLLB_SSCEN(phy), pll_state->mpllb_sscen);
+ intel_de_write(dev_priv, SNPS_PHY_MPLLB_SSCSTEP(phy), pll_state->mpllb_sscstep);
+ intel_de_write(dev_priv, SNPS_PHY_MPLLB_FRACN1(phy), pll_state->mpllb_fracn1);
+ intel_de_write(dev_priv, SNPS_PHY_MPLLB_FRACN2(phy), pll_state->mpllb_fracn2);
+
+ /*
+ * 4. If the frequency will result in a change to the voltage
+ * requirement, follow the Display Voltage Frequency Switching -
+ * Sequence Before Frequency Change.
+ *
+ * We handle this step in bxt_set_cdclk().
+ */
+
+ /* 5. Software sets DPLL_ENABLE [PLL Enable] to "1". */
+ intel_uncore_rmw(&dev_priv->uncore, enable_reg, 0, PLL_ENABLE);
+
+ /*
+ * 9. Software sets SNPS_PHY_MPLLB_DIV dp_mpllb_force_en to "1". This
+ * will keep the PLL running during the DDI lane programming and any
+ * typeC DP cable disconnect. Do not set the force before enabling the
+ * PLL because that will start the PLL before it has sampled the
+ * divider values.
+ */
+ intel_de_write(dev_priv, SNPS_PHY_MPLLB_DIV(phy),
+ pll_state->mpllb_div | SNPS_PHY_MPLLB_FORCE_EN);
+
+ /*
+ * 10. Software polls on register DPLL_ENABLE [PLL Lock] to confirm PLL
+ * is locked at new settings. This register bit is sampling PHY
+ * dp_mpllb_state interface signal.
+ */
+ if (intel_de_wait_for_set(dev_priv, enable_reg, PLL_LOCK, 5))
+ DRM_ERROR("Port %c PLL not locked\n", phy_name(phy));
+
+ /*
+ * 11. If the frequency will result in a change to the voltage
+ * requirement, follow the Display Voltage Frequency Switching -
+ * Sequence After Frequency Change.
+ *
+ * We handle this step in bxt_set_cdclk().
+ */
+}
+
+void intel_mpllb_disable(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);
+ i915_reg_t enable_reg = (phy <= PHY_D ?
+ DG2_PLL_ENABLE(phy) : MG_PLL_ENABLE(0));
+
+ /*
+ * 1. If the frequency will result in a change to the voltage
+ * requirement, follow the Display Voltage Frequency Switching -
+ * Sequence Before Frequency Change.
+ *
+ * We handle this step in bxt_set_cdclk().
+ */
+
+ /* 2. Software programs DPLL_ENABLE [PLL Enable] to "0" */
+ intel_uncore_rmw(&dev_priv->uncore, enable_reg, PLL_ENABLE, 0);
+
+ /*
+ * 4. Software programs SNPS_PHY_MPLLB_DIV dp_mpllb_force_en to "0".
+ * This will allow the PLL to stop running.
+ */
+ intel_uncore_rmw(&dev_priv->uncore, SNPS_PHY_MPLLB_DIV(phy),
+ SNPS_PHY_MPLLB_FORCE_EN, 0);
+
+ /*
+ * 5. Software polls DPLL_ENABLE [PLL Lock] for PHY acknowledgment
+ * (dp_txX_ack) that the new transmitter setting request is completed.
+ */
+ if (intel_de_wait_for_clear(dev_priv, enable_reg, PLL_LOCK, 5))
+ DRM_ERROR("Port %c PLL not locked\n", phy_name(phy));
+
+ /*
+ * 6. If the frequency will result in a change to the voltage
+ * requirement, follow the Display Voltage Frequency Switching -
+ * Sequence After Frequency Change.
+ *
+ * We handle this step in bxt_set_cdclk().
+ */
+}
+
+int intel_mpllb_calc_port_clock(struct intel_encoder *encoder,
+ const struct intel_mpllb_state *pll_state)
+{
+ unsigned int frac_quot = 0, frac_rem = 0, frac_den = 1;
+ unsigned int multiplier, tx_clk_div, refclk;
+ bool frac_en;
+
+ if (0)
+ refclk = 38400;
+ else
+ refclk = 100000;
+
+ refclk >>= REG_FIELD_GET(SNPS_PHY_MPLLB_REF_CLK_DIV, pll_state->mpllb_div2) - 1;
+
+ frac_en = REG_FIELD_GET(SNPS_PHY_MPLLB_FRACN_EN, pll_state->mpllb_fracn1);
+
+ if (frac_en) {
+ frac_quot = REG_FIELD_GET(SNPS_PHY_MPLLB_FRACN_QUOT, pll_state->mpllb_fracn2);
+ frac_rem = REG_FIELD_GET(SNPS_PHY_MPLLB_FRACN_REM, pll_state->mpllb_fracn2);
+ frac_den = REG_FIELD_GET(SNPS_PHY_MPLLB_FRACN_DEN, pll_state->mpllb_fracn1);
+ }
+
+ multiplier = REG_FIELD_GET(SNPS_PHY_MPLLB_MULTIPLIER, pll_state->mpllb_div2) / 2 + 16;
+
+ tx_clk_div = REG_FIELD_GET(SNPS_PHY_MPLLB_TX_CLK_DIV, pll_state->mpllb_div);
+
+ return DIV_ROUND_CLOSEST_ULL(mul_u32_u32(refclk, (multiplier << 16) + frac_quot) +
+ DIV_ROUND_CLOSEST(refclk * frac_rem, frac_den),
+ 10 << (tx_clk_div + 16));
+}
+
+void intel_mpllb_readout_hw_state(struct intel_encoder *encoder,
+ struct intel_mpllb_state *pll_state)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ enum phy phy = intel_port_to_phy(dev_priv, encoder->port);
+
+ pll_state->mpllb_cp = intel_de_read(dev_priv, SNPS_PHY_MPLLB_CP(phy));
+ pll_state->mpllb_div = intel_de_read(dev_priv, SNPS_PHY_MPLLB_DIV(phy));
+ pll_state->mpllb_div2 = intel_de_read(dev_priv, SNPS_PHY_MPLLB_DIV2(phy));
+ pll_state->mpllb_sscen = intel_de_read(dev_priv, SNPS_PHY_MPLLB_SSCEN(phy));
+ pll_state->mpllb_sscstep = intel_de_read(dev_priv, SNPS_PHY_MPLLB_SSCSTEP(phy));
+ pll_state->mpllb_fracn1 = intel_de_read(dev_priv, SNPS_PHY_MPLLB_FRACN1(phy));
+ pll_state->mpllb_fracn2 = intel_de_read(dev_priv, SNPS_PHY_MPLLB_FRACN2(phy));
+
+ /*
+ * REF_CONTROL is under firmware control and never programmed by the
+ * driver; we read it only for sanity checking purposes. The bspec
+ * only tells us the expected value for one field in this register,
+ * so we'll only read out those specific bits here.
+ */
+ pll_state->ref_control = intel_de_read(dev_priv, SNPS_PHY_REF_CONTROL(phy)) &
+ SNPS_PHY_REF_CONTROL_REF_RANGE;
+
+ /*
+ * MPLLB_DIV is programmed twice, once with the software-computed
+ * state, then again with the MPLLB_FORCE_EN bit added. Drop that
+ * extra bit during readout so that we return the actual expected
+ * software state.
+ */
+ pll_state->mpllb_div &= ~SNPS_PHY_MPLLB_FORCE_EN;
+}
+
+int intel_snps_phy_check_hdmi_link_rate(int clock)
+{
+ const struct intel_mpllb_state **tables = dg2_hdmi_tables;
+ int i;
+
+ for (i = 0; tables[i]; i++) {
+ if (clock == tables[i]->clock)
+ return MODE_OK;
+ }
+
+ return MODE_CLOCK_RANGE;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.h b/drivers/gpu/drm/i915/display/intel_snps_phy.h
new file mode 100644
index 000000000000..6261ff88ef5c
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_snps_phy.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2019 Intel Corporation
+ */
+
+#ifndef __INTEL_SNPS_PHY_H__
+#define __INTEL_SNPS_PHY_H__
+
+#include <linux/types.h>
+
+struct drm_i915_private;
+struct intel_encoder;
+struct intel_crtc_state;
+struct intel_mpllb_state;
+enum phy;
+
+void intel_snps_phy_wait_for_calibration(struct drm_i915_private *dev_priv);
+void intel_snps_phy_update_psr_power_state(struct drm_i915_private *dev_priv,
+ enum phy phy, bool enable);
+
+int intel_mpllb_calc_state(struct intel_crtc_state *crtc_state,
+ struct intel_encoder *encoder);
+void intel_mpllb_enable(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state);
+void intel_mpllb_disable(struct intel_encoder *encoder);
+void intel_mpllb_readout_hw_state(struct intel_encoder *encoder,
+ struct intel_mpllb_state *pll_state);
+int intel_mpllb_calc_port_clock(struct intel_encoder *encoder,
+ const struct intel_mpllb_state *pll_state);
+
+int intel_snps_phy_check_hdmi_link_rate(int clock);
+void intel_snps_phy_ddi_vswing_sequence(struct intel_encoder *encoder,
+ u32 level);
+
+#endif /* __INTEL_SNPS_PHY_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index 4ae9a7455b23..08116f41da26 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -1856,7 +1856,7 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv,
zpos = sprite + 1;
drm_plane_create_zpos_immutable_property(&plane->base, zpos);
- drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
+ intel_plane_helper_add(plane);
return plane;
diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c
index c23c210a55f5..3ffece568ed9 100644
--- a/drivers/gpu/drm/i915/display/intel_tc.c
+++ b/drivers/gpu/drm/i915/display/intel_tc.c
@@ -556,7 +556,7 @@ intel_tc_port_get_target_mode(struct intel_digital_port *dig_port)
}
static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port,
- int required_lanes)
+ int required_lanes, bool force_disconnect)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
enum tc_port_mode old_tc_mode = dig_port->tc_mode;
@@ -572,7 +572,8 @@ static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port,
}
icl_tc_phy_disconnect(dig_port);
- icl_tc_phy_connect(dig_port, required_lanes);
+ if (!force_disconnect)
+ icl_tc_phy_connect(dig_port, required_lanes);
drm_dbg_kms(&i915->drm, "Port %s: TC port mode reset (%s -> %s)\n",
dig_port->tc_port_name,
@@ -662,7 +663,7 @@ bool intel_tc_port_connected(struct intel_encoder *encoder)
}
static void __intel_tc_port_lock(struct intel_digital_port *dig_port,
- int required_lanes)
+ int required_lanes, bool force_disconnect)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
intel_wakeref_t wakeref;
@@ -676,8 +677,9 @@ static void __intel_tc_port_lock(struct intel_digital_port *dig_port,
tc_cold_wref = tc_cold_block(dig_port);
- if (intel_tc_port_needs_reset(dig_port))
- intel_tc_port_reset_mode(dig_port, required_lanes);
+ if (force_disconnect || intel_tc_port_needs_reset(dig_port))
+ intel_tc_port_reset_mode(dig_port, required_lanes,
+ force_disconnect);
tc_cold_unblock(dig_port, tc_cold_wref);
}
@@ -688,7 +690,7 @@ static void __intel_tc_port_lock(struct intel_digital_port *dig_port,
void intel_tc_port_lock(struct intel_digital_port *dig_port)
{
- __intel_tc_port_lock(dig_port, 1);
+ __intel_tc_port_lock(dig_port, 1, false);
}
void intel_tc_port_unlock(struct intel_digital_port *dig_port)
@@ -702,6 +704,24 @@ void intel_tc_port_unlock(struct intel_digital_port *dig_port)
wakeref);
}
+/**
+ * intel_tc_port_disconnect_phy: disconnect TypeC PHY from display port
+ * @dig_port: digital port
+ *
+ * Disconnect the given digital port from its TypeC PHY (handing back the
+ * control of the PHY to the TypeC subsystem). The only purpose of this
+ * function is to force the disconnect even with a TypeC display output still
+ * plugged to the TypeC connector, which is required by the TypeC firmwares
+ * during system suspend and shutdown. Otherwise - during the unplug event
+ * handling - the PHY ownership is released automatically by
+ * intel_tc_port_reset_mode(), when calling this function is not required.
+ */
+void intel_tc_port_disconnect_phy(struct intel_digital_port *dig_port)
+{
+ __intel_tc_port_lock(dig_port, 1, true);
+ intel_tc_port_unlock(dig_port);
+}
+
bool intel_tc_port_ref_held(struct intel_digital_port *dig_port)
{
return mutex_is_locked(&dig_port->tc_lock) ||
@@ -711,7 +731,7 @@ bool intel_tc_port_ref_held(struct intel_digital_port *dig_port)
void intel_tc_port_get_link(struct intel_digital_port *dig_port,
int required_lanes)
{
- __intel_tc_port_lock(dig_port, required_lanes);
+ __intel_tc_port_lock(dig_port, required_lanes, false);
dig_port->tc_link_refcount++;
intel_tc_port_unlock(dig_port);
}
diff --git a/drivers/gpu/drm/i915/display/intel_tc.h b/drivers/gpu/drm/i915/display/intel_tc.h
index 0eacbd76ec15..0c881f645e27 100644
--- a/drivers/gpu/drm/i915/display/intel_tc.h
+++ b/drivers/gpu/drm/i915/display/intel_tc.h
@@ -13,6 +13,8 @@ struct intel_digital_port;
struct intel_encoder;
bool intel_tc_port_connected(struct intel_encoder *encoder);
+void intel_tc_port_disconnect_phy(struct intel_digital_port *dig_port);
+
u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port);
u32 intel_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_port);
int intel_tc_port_fia_max_lane_count(struct intel_digital_port *dig_port);
diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c
index aa52af7891f0..d02f09f7e750 100644
--- a/drivers/gpu/drm/i915/display/intel_tv.c
+++ b/drivers/gpu/drm/i915/display/intel_tv.c
@@ -1420,7 +1420,7 @@ static void intel_tv_pre_enable(struct intel_atomic_state *state,
const struct drm_connector_state *conn_state)
{
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
+ struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
struct intel_tv *intel_tv = enc_to_tv(encoder);
const struct intel_tv_connector_state *tv_conn_state =
to_intel_tv_connector_state(conn_state);
@@ -1466,7 +1466,7 @@ static void intel_tv_pre_enable(struct intel_atomic_state *state,
break;
}
- tv_ctl |= TV_ENC_PIPE_SEL(intel_crtc->pipe);
+ tv_ctl |= TV_ENC_PIPE_SEL(crtc->pipe);
switch (tv_mode->oversample) {
case 8:
@@ -1571,8 +1571,7 @@ static int
intel_tv_detect_type(struct intel_tv *intel_tv,
struct drm_connector *connector)
{
- struct drm_crtc *crtc = connector->state->crtc;
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_crtc *crtc = to_intel_crtc(connector->state->crtc);
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
u32 tv_ctl, save_tv_ctl;
@@ -1594,7 +1593,7 @@ intel_tv_detect_type(struct intel_tv *intel_tv,
/* Poll for TV detection */
tv_ctl &= ~(TV_ENC_ENABLE | TV_ENC_PIPE_SEL_MASK | TV_TEST_MODE_MASK);
tv_ctl |= TV_TEST_MODE_MONITOR_DETECT;
- tv_ctl |= TV_ENC_PIPE_SEL(intel_crtc->pipe);
+ tv_ctl |= TV_ENC_PIPE_SEL(crtc->pipe);
tv_dac &= ~(TVDAC_SENSE_MASK | DAC_A_MASK | DAC_B_MASK | DAC_C_MASK);
tv_dac |= (TVDAC_STATE_CHG_EN |
@@ -1619,7 +1618,7 @@ intel_tv_detect_type(struct intel_tv *intel_tv,
intel_de_write(dev_priv, TV_DAC, tv_dac);
intel_de_posting_read(dev_priv, TV_DAC);
- intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
+ intel_wait_for_vblank(dev_priv, crtc->pipe);
type = -1;
tv_dac = intel_de_read(dev_priv, TV_DAC);
@@ -1652,7 +1651,7 @@ intel_tv_detect_type(struct intel_tv *intel_tv,
intel_de_posting_read(dev_priv, TV_CTL);
/* For unknown reasons the hw barfs if we don't do this vblank wait. */
- intel_wait_for_vblank(dev_priv, intel_crtc->pipe);
+ intel_wait_for_vblank(dev_priv, crtc->pipe);
/* Restore interrupt config */
if (connector->polled & DRM_CONNECTOR_POLL_HPD) {
diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
index dbe24d7e7375..330077c2e588 100644
--- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
+++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
@@ -456,7 +456,7 @@ struct child_device_config {
u16 dp_gpio_pin_num; /* 195 */
u8 dp_iboost_level:4; /* 196 */
u8 hdmi_iboost_level:4; /* 196 */
- u8 dp_max_link_rate:3; /* 216/230 CNL+ */
+ u8 dp_max_link_rate:3; /* 216/230 GLK+ */
u8 dp_max_link_rate_reserved:5; /* 216/230 */
} __packed;
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
index 85749370508c..df3286aa6999 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -348,7 +348,10 @@ bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state)
if (DISPLAY_VER(i915) >= 12)
return true;
- if ((DISPLAY_VER(i915) >= 11 || IS_CANNONLAKE(i915)) && (pipe != PIPE_A || (cpu_transcoder == TRANSCODER_EDP || cpu_transcoder == TRANSCODER_DSI_0 || cpu_transcoder == TRANSCODER_DSI_1)))
+ if (DISPLAY_VER(i915) >= 11 &&
+ (pipe != PIPE_A || cpu_transcoder == TRANSCODER_EDP ||
+ cpu_transcoder == TRANSCODER_DSI_0 ||
+ cpu_transcoder == TRANSCODER_DSI_1))
return true;
return false;
diff --git a/drivers/gpu/drm/i915/display/intel_vga.c b/drivers/gpu/drm/i915/display/intel_vga.c
index f002b82ba9c0..fa779f7ea415 100644
--- a/drivers/gpu/drm/i915/display/intel_vga.c
+++ b/drivers/gpu/drm/i915/display/intel_vga.c
@@ -29,6 +29,9 @@ void intel_vga_disable(struct drm_i915_private *dev_priv)
i915_reg_t vga_reg = intel_vga_cntrl_reg(dev_priv);
u8 sr1;
+ if (intel_de_read(dev_priv, vga_reg) & VGA_DISP_DISABLE)
+ return;
+
/* WaEnableVGAAccessThroughIOPort:ctg,elk,ilk,snb,ivb,vlv,hsw */
vga_get_uninterruptible(pdev, VGA_RSRC_LEGACY_IO);
outb(SR01, VGA_SR_INDEX);
@@ -121,9 +124,9 @@ intel_vga_set_state(struct drm_i915_private *i915, bool enable_decode)
}
static unsigned int
-intel_vga_set_decode(void *cookie, bool enable_decode)
+intel_vga_set_decode(struct pci_dev *pdev, bool enable_decode)
{
- struct drm_i915_private *i915 = cookie;
+ struct drm_i915_private *i915 = pdev_to_i915(pdev);
intel_vga_set_state(i915, enable_decode);
@@ -136,6 +139,7 @@ intel_vga_set_decode(void *cookie, bool enable_decode)
int intel_vga_register(struct drm_i915_private *i915)
{
+
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
int ret;
@@ -147,7 +151,7 @@ int intel_vga_register(struct drm_i915_private *i915)
* then we do not take part in VGA arbitration and the
* vga_client_register() fails with -ENODEV.
*/
- ret = vga_client_register(pdev, i915, NULL, intel_vga_set_decode);
+ ret = vga_client_register(pdev, intel_vga_set_decode);
if (ret && ret != -ENODEV)
return ret;
@@ -158,5 +162,5 @@ void intel_vga_unregister(struct drm_i915_private *i915)
{
struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
- vga_client_register(pdev, NULL, NULL, NULL);
+ vga_client_unregister(pdev);
}
diff --git a/drivers/gpu/drm/i915/display/skl_scaler.c b/drivers/gpu/drm/i915/display/skl_scaler.c
index 394b7bbf48d8..37eabeff8197 100644
--- a/drivers/gpu/drm/i915/display/skl_scaler.c
+++ b/drivers/gpu/drm/i915/display/skl_scaler.c
@@ -96,9 +96,8 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
{
struct intel_crtc_scaler_state *scaler_state =
&crtc_state->scaler_state;
- struct intel_crtc *intel_crtc =
- to_intel_crtc(crtc_state->uapi.crtc);
- struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
const struct drm_display_mode *adjusted_mode =
&crtc_state->hw.adjusted_mode;
@@ -141,7 +140,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
drm_dbg_kms(&dev_priv->drm,
"scaler_user index %u.%u: "
"Staged freeing scaler id %d scaler_users = 0x%x\n",
- intel_crtc->pipe, scaler_user, *scaler_id,
+ crtc->pipe, scaler_user, *scaler_id,
scaler_state->scaler_users);
*scaler_id = -1;
}
@@ -167,7 +166,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
drm_dbg_kms(&dev_priv->drm,
"scaler_user index %u.%u: src %ux%u dst %ux%u "
"size is out of scaler range\n",
- intel_crtc->pipe, scaler_user, src_w, src_h,
+ crtc->pipe, scaler_user, src_w, src_h,
dst_w, dst_h);
return -EINVAL;
}
@@ -176,7 +175,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
scaler_state->scaler_users |= (1 << scaler_user);
drm_dbg_kms(&dev_priv->drm, "scaler_user index %u.%u: "
"staged scaling request for %ux%u->%ux%u scaler_users = 0x%x\n",
- intel_crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h,
+ crtc->pipe, scaler_user, src_w, src_h, dst_w, dst_h,
scaler_state->scaler_users);
return 0;
@@ -295,12 +294,12 @@ int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
return 0;
}
-static int cnl_coef_tap(int i)
+static int glk_coef_tap(int i)
{
return i % 7;
}
-static u16 cnl_nearest_filter_coef(int t)
+static u16 glk_nearest_filter_coef(int t)
{
return t == 3 ? 0x0800 : 0x3000;
}
@@ -342,29 +341,29 @@ static u16 cnl_nearest_filter_coef(int t)
*
*/
-static void cnl_program_nearest_filter_coefs(struct drm_i915_private *dev_priv,
+static void glk_program_nearest_filter_coefs(struct drm_i915_private *dev_priv,
enum pipe pipe, int id, int set)
{
int i;
- intel_de_write_fw(dev_priv, CNL_PS_COEF_INDEX_SET(pipe, id, set),
+ intel_de_write_fw(dev_priv, GLK_PS_COEF_INDEX_SET(pipe, id, set),
PS_COEE_INDEX_AUTO_INC);
for (i = 0; i < 17 * 7; i += 2) {
u32 tmp;
int t;
- t = cnl_coef_tap(i);
- tmp = cnl_nearest_filter_coef(t);
+ t = glk_coef_tap(i);
+ tmp = glk_nearest_filter_coef(t);
- t = cnl_coef_tap(i + 1);
- tmp |= cnl_nearest_filter_coef(t) << 16;
+ t = glk_coef_tap(i + 1);
+ tmp |= glk_nearest_filter_coef(t) << 16;
- intel_de_write_fw(dev_priv, CNL_PS_COEF_DATA_SET(pipe, id, set),
+ intel_de_write_fw(dev_priv, GLK_PS_COEF_DATA_SET(pipe, id, set),
tmp);
}
- intel_de_write_fw(dev_priv, CNL_PS_COEF_INDEX_SET(pipe, id, set), 0);
+ intel_de_write_fw(dev_priv, GLK_PS_COEF_INDEX_SET(pipe, id, set), 0);
}
static u32 skl_scaler_get_filter_select(enum drm_scaling_filter filter, int set)
@@ -387,7 +386,7 @@ static void skl_scaler_setup_filter(struct drm_i915_private *dev_priv, enum pipe
case DRM_SCALING_FILTER_DEFAULT:
break;
case DRM_SCALING_FILTER_NEAREST_NEIGHBOR:
- cnl_program_nearest_filter_coefs(dev_priv, pipe, id, set);
+ glk_program_nearest_filter_coefs(dev_priv, pipe, id, set);
break;
default:
MISSING_CASE(filter);
@@ -515,17 +514,17 @@ skl_program_plane_scaler(struct intel_plane *plane,
(crtc_w << 16) | crtc_h);
}
-static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
+static void skl_detach_scaler(struct intel_crtc *crtc, int id)
{
- struct drm_device *dev = intel_crtc->base.dev;
+ struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
unsigned long irqflags;
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
- intel_de_write_fw(dev_priv, SKL_PS_CTRL(intel_crtc->pipe, id), 0);
- intel_de_write_fw(dev_priv, SKL_PS_WIN_POS(intel_crtc->pipe, id), 0);
- intel_de_write_fw(dev_priv, SKL_PS_WIN_SZ(intel_crtc->pipe, id), 0);
+ intel_de_write_fw(dev_priv, SKL_PS_CTRL(crtc->pipe, id), 0);
+ intel_de_write_fw(dev_priv, SKL_PS_WIN_POS(crtc->pipe, id), 0);
+ intel_de_write_fw(dev_priv, SKL_PS_WIN_SZ(crtc->pipe, id), 0);
spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
}
@@ -535,15 +534,15 @@ static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
*/
void skl_detach_scalers(const struct intel_crtc_state *crtc_state)
{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
const struct intel_crtc_scaler_state *scaler_state =
&crtc_state->scaler_state;
int i;
/* loop through and disable scalers that aren't in use */
- for (i = 0; i < intel_crtc->num_scalers; i++) {
+ for (i = 0; i < crtc->num_scalers; i++) {
if (!scaler_state->scalers[i].in_use)
- skl_detach_scaler(intel_crtc, i);
+ skl_detach_scaler(crtc, i);
}
}
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 92a4fd508e92..724e7b04f3b6 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -835,7 +835,7 @@ static u32 skl_plane_ctl_rotate(unsigned int rotate)
return 0;
}
-static u32 cnl_plane_ctl_flip(unsigned int reflect)
+static u32 icl_plane_ctl_flip(unsigned int reflect)
{
switch (reflect) {
case 0:
@@ -917,8 +917,8 @@ static u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
plane_ctl |= skl_plane_ctl_tiling(fb->modifier);
plane_ctl |= skl_plane_ctl_rotate(rotation & DRM_MODE_ROTATE_MASK);
- if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv))
- plane_ctl |= cnl_plane_ctl_flip(rotation &
+ if (DISPLAY_VER(dev_priv) >= 11)
+ plane_ctl |= icl_plane_ctl_flip(rotation &
DRM_MODE_REFLECT_MASK);
if (key->flags & I915_SET_COLORKEY_DESTINATION)
@@ -926,7 +926,7 @@ static u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
else if (key->flags & I915_SET_COLORKEY_SOURCE)
plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE;
- /* Wa_22012358565:adlp */
+ /* Wa_22012358565:adl-p */
if (DISPLAY_VER(dev_priv) == 13)
plane_ctl |= adlp_plane_ctl_arb_slots(plane_state);
@@ -1270,7 +1270,7 @@ static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_s
int pipe_src_w = crtc_state->pipe_src_w;
/*
- * Display WA #1175: cnl,glk
+ * Display WA #1175: glk
* Planes other than the cursor may cause FIFO underflow and display
* corruption if starting less than 4 pixels from the right edge of
* the screen.
@@ -1828,7 +1828,7 @@ static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
if (plane_id == PLANE_CURSOR)
return false;
- if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv))
+ if (DISPLAY_VER(dev_priv) >= 11)
return true;
if (IS_GEMINILAKE(dev_priv))
@@ -1910,11 +1910,11 @@ static bool gen12_plane_supports_mc_ccs(struct drm_i915_private *dev_priv,
{
/* Wa_14010477008:tgl[a0..c0],rkl[all],dg1[all] */
if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv) ||
- IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_C0))
+ IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_D0))
return false;
/* Wa_22011186057 */
- if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A0))
+ if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0))
return false;
return plane_id < PLANE_SPRITE4;
@@ -1938,7 +1938,7 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
/* Wa_22011186057 */
- if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A0))
+ if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0))
return false;
break;
default:
@@ -1995,7 +1995,7 @@ static const u64 *gen12_get_plane_modifiers(struct drm_i915_private *dev_priv,
enum plane_id plane_id)
{
/* Wa_22011186057 */
- if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A0))
+ if (IS_ADLP_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0))
return adlp_step_a_plane_format_modifiers;
else if (gen12_plane_supports_mc_ccs(dev_priv, plane_id))
return gen12_plane_format_modifiers_mc_ccs;
@@ -2144,7 +2144,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
- if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv))
+ if (DISPLAY_VER(dev_priv) >= 11)
supported_rotations |= DRM_MODE_REFLECT_X;
drm_plane_create_rotation_property(&plane->base,
@@ -2174,12 +2174,12 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
if (DISPLAY_VER(dev_priv) >= 12)
drm_plane_enable_fb_damage_clips(&plane->base);
- if (DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv))
+ if (DISPLAY_VER(dev_priv) >= 11)
drm_plane_create_scaling_filter_property(&plane->base,
BIT(DRM_SCALING_FILTER_DEFAULT) |
BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR));
- drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
+ intel_plane_helper_add(plane);
return plane;
@@ -2295,7 +2295,7 @@ skl_get_initial_plane_config(struct intel_crtc *crtc,
break;
}
- if ((DISPLAY_VER(dev_priv) >= 11 || IS_CANNONLAKE(dev_priv)) && val & PLANE_CTL_FLIP_HORIZONTAL)
+ if (DISPLAY_VER(dev_priv) >= 11 && val & PLANE_CTL_FLIP_HORIZONTAL)
plane_config->rotation |= DRM_MODE_REFLECT_X;
/* 90/270 degree rotation would require extra work */
diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c
index 084c9c43b2ed..0ee4ff341e25 100644
--- a/drivers/gpu/drm/i915/display/vlv_dsi.c
+++ b/drivers/gpu/drm/i915/display/vlv_dsi.c
@@ -780,10 +780,9 @@ static void intel_dsi_pre_enable(struct intel_atomic_state *state,
const struct drm_connector_state *conn_state)
{
struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
- struct drm_crtc *crtc = pipe_config->uapi.crtc;
- struct drm_i915_private *dev_priv = to_i915(crtc->dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- enum pipe pipe = intel_crtc->pipe;
+ struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+ enum pipe pipe = crtc->pipe;
enum port port;
u32 val;
bool glk_cold_boot = false;
@@ -1389,7 +1388,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
struct drm_encoder *encoder = &intel_encoder->base;
struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = to_i915(dev);
- struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
+ struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
struct intel_dsi *intel_dsi = enc_to_intel_dsi(to_intel_encoder(encoder));
const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
enum port port;
@@ -1397,7 +1396,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
u32 val, tmp;
u16 mode_hdisplay;
- drm_dbg_kms(&dev_priv->drm, "pipe %c\n", pipe_name(intel_crtc->pipe));
+ drm_dbg_kms(&dev_priv->drm, "pipe %c\n", pipe_name(crtc->pipe));
mode_hdisplay = adjusted_mode->crtc_hdisplay;
@@ -1424,7 +1423,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
intel_de_write(dev_priv, MIPI_CTRL(port),
tmp | READ_REQUEST_PRIORITY_HIGH);
} else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
- enum pipe pipe = intel_crtc->pipe;
+ enum pipe pipe = crtc->pipe;
tmp = intel_de_read(dev_priv, MIPI_CTRL(port));
tmp &= ~BXT_PIPE_SELECT_MASK;