[PATCH 1/2] aaa

José Roberto de Souza jose.souza at intel.com
Tue Jul 20 20:42:51 UTC 2021


---
 drivers/gpu/drm/i915/display/g4x_dp.c         |   9 +-
 drivers/gpu/drm/i915/display/icl_dsi.c        |   2 +-
 drivers/gpu/drm/i915/display/intel_bios.c     | 393 ++++++++++--------
 drivers/gpu/drm/i915/display/intel_bios.h     |   8 +
 drivers/gpu/drm/i915/display/intel_ddi.c      |   9 +-
 .../drm/i915/display/intel_ddi_buf_trans.c    |  71 ++--
 .../drm/i915/display/intel_display_types.h    |   2 +
 drivers/gpu/drm/i915/display/intel_dp.c       |  17 +-
 .../drm/i915/display/intel_dp_aux_backlight.c |  14 +-
 .../i915/display/intel_dsi_dcs_backlight.c    |   3 +-
 drivers/gpu/drm/i915/display/intel_dsi_vbt.c  |   2 +-
 drivers/gpu/drm/i915/display/intel_dvo.c      |   2 +-
 drivers/gpu/drm/i915/display/intel_lvds.c     |   4 +-
 drivers/gpu/drm/i915/display/intel_panel.c    |  32 +-
 drivers/gpu/drm/i915/display/intel_panel.h    |   2 +-
 drivers/gpu/drm/i915/display/intel_pps.c      |  11 +-
 drivers/gpu/drm/i915/display/intel_psr.c      |  30 +-
 drivers/gpu/drm/i915/display/intel_sdvo.c     |   3 +-
 drivers/gpu/drm/i915/display/intel_vbt_defs.h |  17 +-
 drivers/gpu/drm/i915/display/vlv_dsi.c        |   2 +-
 drivers/gpu/drm/i915/i915_drv.h               |  78 ++--
 21 files changed, 399 insertions(+), 312 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c
index de0f358184aa3..273bc5295ae33 100644
--- a/drivers/gpu/drm/i915/display/g4x_dp.c
+++ b/drivers/gpu/drm/i915/display/g4x_dp.c
@@ -340,6 +340,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
 	u32 tmp, flags = 0;
 	enum port port = encoder->port;
 	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+	struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 
 	if (encoder->type == INTEL_OUTPUT_EDP)
 		pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP);
@@ -396,8 +397,8 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
 		intel_dotclock_calculate(pipe_config->port_clock,
 					 &pipe_config->dp_m_n);
 
-	if (intel_dp_is_edp(intel_dp) && dev_priv->vbt.edp.bpp &&
-	    pipe_config->pipe_bpp > dev_priv->vbt.edp.bpp) {
+	if (intel_dp_is_edp(intel_dp) && vbt_edp_info->bpp &&
+	    pipe_config->pipe_bpp > vbt_edp_info->bpp) {
 		/*
 		 * This is a big fat ugly hack.
 		 *
@@ -413,8 +414,8 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
 		 */
 		drm_dbg_kms(&dev_priv->drm,
 			    "pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
-			    pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp);
-		dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
+			    pipe_config->pipe_bpp, vbt_edp_info->bpp);
+		vbt_edp_info->bpp = pipe_config->pipe_bpp;
 	}
 }
 
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 43ec7fcd3f5d2..5b385324d8c2a 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -2041,7 +2041,7 @@ void icl_dsi_init(struct drm_i915_private *dev_priv)
 		goto err;
 	}
 
-	intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
+	intel_panel_init(intel_connector, fixed_mode, NULL);
 	intel_panel_setup_backlight(connector, INVALID_PIPE);
 
 	if (dev_priv->vbt.dsi.config->dual_link)
diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index 5b6922e28ef28..45d332b1b6f41 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -211,44 +211,44 @@ get_lvds_fp_timing(const struct bdb_header *bdb,
 	return (const struct lvds_fp_timing *)((const u8 *)bdb + ofs);
 }
 
+static int
+get_lfp_panel_index(struct drm_i915_private *i915,
+		    const struct bdb_header *bdb, int lfp_panel_instance)
+{
+	const struct bdb_lvds_options *lvds_options;
+
+	lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
+	if (!lvds_options)
+		return -1;
+
+	switch(lfp_panel_instance) {
+	case 1:
+		return lvds_options->panel_type;
+	case 2:
+		return lvds_options->panel_type2;
+	default:
+		break;
+	}
+
+	return -1;
+}
+
 /* Parse general panel options */
 static void
 parse_panel_options(struct drm_i915_private *i915,
-		    const struct bdb_header *bdb)
+		    const struct bdb_header *bdb, int panel_index,
+		    struct ddi_vbt_port_info *info)
 {
 	const struct bdb_lvds_options *lvds_options;
-	int panel_type;
 	int drrs_mode;
-	int ret;
 
 	lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
 	if (!lvds_options)
 		return;
 
-	i915->vbt.lvds_dither = lvds_options->pixel_dither;
+	drrs_mode = lvds_options->dps_panel_type_bits >> (panel_index * 2);
+	drrs_mode &= MODE_MASK;
 
-	ret = intel_opregion_get_panel_type(i915);
-	if (ret >= 0) {
-		drm_WARN_ON(&i915->drm, ret > 0xf);
-		panel_type = ret;
-		drm_dbg_kms(&i915->drm, "Panel type: %d (OpRegion)\n",
-			    panel_type);
-	} else {
-		if (lvds_options->panel_type > 0xf) {
-			drm_dbg_kms(&i915->drm,
-				    "Invalid VBT panel type 0x%x\n",
-				    lvds_options->panel_type);
-			return;
-		}
-		panel_type = lvds_options->panel_type;
-		drm_dbg_kms(&i915->drm, "Panel type: %d (VBT)\n",
-			    panel_type);
-	}
-
-	i915->vbt.panel_type = panel_type;
-
-	drrs_mode = (lvds_options->dps_panel_type_bits
-				>> (panel_type * 2)) & MODE_MASK;
 	/*
 	 * VBT has static DRRS = 0 and seamless DRRS = 2.
 	 * The below piece of code is required to adjust vbt.drrs_type
@@ -256,16 +256,16 @@ parse_panel_options(struct drm_i915_private *i915,
 	 */
 	switch (drrs_mode) {
 	case 0:
-		i915->vbt.drrs_type = STATIC_DRRS_SUPPORT;
+		info->drrs_type = STATIC_DRRS_SUPPORT;
 		drm_dbg_kms(&i915->drm, "DRRS supported mode is static\n");
 		break;
 	case 2:
-		i915->vbt.drrs_type = SEAMLESS_DRRS_SUPPORT;
+		info->drrs_type = SEAMLESS_DRRS_SUPPORT;
 		drm_dbg_kms(&i915->drm,
 			    "DRRS supported mode is seamless\n");
 		break;
 	default:
-		i915->vbt.drrs_type = DRRS_NOT_SUPPORTED;
+		info->drrs_type = DRRS_NOT_SUPPORTED;
 		drm_dbg_kms(&i915->drm,
 			    "DRRS not supported (VBT input)\n");
 		break;
@@ -275,14 +275,14 @@ parse_panel_options(struct drm_i915_private *i915,
 /* Try to find integrated panel timing data */
 static void
 parse_lfp_panel_dtd(struct drm_i915_private *i915,
-		    const struct bdb_header *bdb)
+		    const struct bdb_header *bdb, int panel_index,
+		    struct ddi_vbt_port_info *info)
 {
 	const struct bdb_lvds_lfp_data *lvds_lfp_data;
 	const struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs;
 	const struct lvds_dvo_timing *panel_dvo_timing;
 	const struct lvds_fp_timing *fp_timing;
 	struct drm_display_mode *panel_fixed_mode;
-	int panel_type = i915->vbt.panel_type;
 
 	lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
 	if (!lvds_lfp_data)
@@ -294,7 +294,7 @@ parse_lfp_panel_dtd(struct drm_i915_private *i915,
 
 	panel_dvo_timing = get_lvds_dvo_timing(lvds_lfp_data,
 					       lvds_lfp_data_ptrs,
-					       panel_type);
+					       panel_index);
 
 	panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
 	if (!panel_fixed_mode)
@@ -302,7 +302,7 @@ parse_lfp_panel_dtd(struct drm_i915_private *i915,
 
 	fill_detail_timing_data(panel_fixed_mode, panel_dvo_timing);
 
-	i915->vbt.lfp_lvds_vbt_mode = panel_fixed_mode;
+	info->lfp_lvds_vbt_mode = panel_fixed_mode;
 
 	drm_dbg_kms(&i915->drm,
 		    "Found panel mode in BIOS VBT legacy lfp table:\n");
@@ -310,22 +310,23 @@ parse_lfp_panel_dtd(struct drm_i915_private *i915,
 
 	fp_timing = get_lvds_fp_timing(bdb, lvds_lfp_data,
 				       lvds_lfp_data_ptrs,
-				       panel_type);
+				       panel_index);
 	if (fp_timing) {
 		/* check the resolution, just to be sure */
 		if (fp_timing->x_res == panel_fixed_mode->hdisplay &&
 		    fp_timing->y_res == panel_fixed_mode->vdisplay) {
-			i915->vbt.bios_lvds_val = fp_timing->lvds_reg_val;
+			info->bios_lvds_val = fp_timing->lvds_reg_val;
 			drm_dbg_kms(&i915->drm,
 				    "VBT initial LVDS value %x\n",
-				    i915->vbt.bios_lvds_val);
+				    info->bios_lvds_val);
 		}
 	}
 }
 
 static void
 parse_generic_dtd(struct drm_i915_private *i915,
-		  const struct bdb_header *bdb)
+		  const struct bdb_header *bdb, int panel_index,
+		  struct ddi_vbt_port_info *info)
 {
 	const struct bdb_generic_dtd *generic_dtd;
 	const struct generic_dtd_entry *dtd;
@@ -349,14 +350,14 @@ parse_generic_dtd(struct drm_i915_private *i915,
 
 	num_dtd = (get_blocksize(generic_dtd) -
 		   sizeof(struct bdb_generic_dtd)) / generic_dtd->gdtd_size;
-	if (i915->vbt.panel_type >= num_dtd) {
+	if (panel_index >= num_dtd) {
 		drm_err(&i915->drm,
-			"Panel type %d not found in table of %d DTD's\n",
-			i915->vbt.panel_type, num_dtd);
+			"Panel index %d not found in table of %d DTD's\n",
+			panel_index, num_dtd);
 		return;
 	}
 
-	dtd = &generic_dtd->dtd[i915->vbt.panel_type];
+	dtd = &generic_dtd->dtd[panel_index];
 
 	panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);
 	if (!panel_fixed_mode)
@@ -399,12 +400,13 @@ parse_generic_dtd(struct drm_i915_private *i915,
 		    "Found panel mode in BIOS VBT generic dtd table:\n");
 	drm_mode_debug_printmodeline(panel_fixed_mode);
 
-	i915->vbt.lfp_lvds_vbt_mode = panel_fixed_mode;
+	info->lfp_lvds_vbt_mode = panel_fixed_mode;
 }
 
 static void
 parse_panel_dtd(struct drm_i915_private *i915,
-		const struct bdb_header *bdb)
+		const struct bdb_header *bdb, int panel_index,
+		struct ddi_vbt_port_info *info)
 {
 	/*
 	 * Older VBTs provided provided DTD information for internal displays
@@ -415,18 +417,18 @@ parse_panel_dtd(struct drm_i915_private *i915,
 	 * back to trying the old LFP block if that fails.
 	 */
 	if (bdb->version >= 229)
-		parse_generic_dtd(i915, bdb);
-	if (!i915->vbt.lfp_lvds_vbt_mode)
-		parse_lfp_panel_dtd(i915, bdb);
+		parse_generic_dtd(i915, bdb, panel_index, info);
+	if (!info->lfp_lvds_vbt_mode)
+		parse_lfp_panel_dtd(i915, bdb, panel_index, info);
 }
 
 static void
 parse_lfp_backlight(struct drm_i915_private *i915,
-		    const struct bdb_header *bdb)
+		    const struct bdb_header *bdb, int panel_index,
+		    struct ddi_vbt_port_info *info)
 {
 	const struct bdb_lfp_backlight_data *backlight_data;
 	const struct lfp_backlight_data_entry *entry;
-	int panel_type = i915->vbt.panel_type;
 	u16 level;
 
 	backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT);
@@ -440,38 +442,38 @@ parse_lfp_backlight(struct drm_i915_private *i915,
 		return;
 	}
 
-	entry = &backlight_data->data[panel_type];
+	entry = &backlight_data->data[panel_index];
 
-	i915->vbt.backlight.present = entry->type == BDB_BACKLIGHT_TYPE_PWM;
-	if (!i915->vbt.backlight.present) {
+	info->backlight.present = entry->type == BDB_BACKLIGHT_TYPE_PWM;
+	if (!info->backlight.present) {
 		drm_dbg_kms(&i915->drm,
 			    "PWM backlight not present in VBT (type %u)\n",
 			    entry->type);
 		return;
 	}
 
-	i915->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI;
+	info->backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI;
 	if (bdb->version >= 191 &&
 	    get_blocksize(backlight_data) >= sizeof(*backlight_data)) {
 		const struct lfp_backlight_control_method *method;
 
-		method = &backlight_data->backlight_control[panel_type];
-		i915->vbt.backlight.type = method->type;
-		i915->vbt.backlight.controller = method->controller;
+		method = &backlight_data->backlight_control[panel_index];
+		info->backlight.type = method->type;
+		info->backlight.controller = method->controller;
 	}
 
-	i915->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
-	i915->vbt.backlight.active_low_pwm = entry->active_low_pwm;
+	info->backlight.pwm_freq_hz = entry->pwm_freq_hz;
+	info->backlight.active_low_pwm = entry->active_low_pwm;
 
 	if (bdb->version >= 234) {
 		u16 min_level;
 		bool scale;
 
-		level = backlight_data->brightness_level[panel_type].level;
-		min_level = backlight_data->brightness_min_level[panel_type].level;
+		level = backlight_data->brightness_level[panel_index].level;
+		min_level = backlight_data->brightness_min_level[panel_index].level;
 
 		if (bdb->version >= 236)
-			scale = backlight_data->brightness_precision_bits[panel_type] == 16;
+			scale = backlight_data->brightness_precision_bits[panel_index] == 16;
 		else
 			scale = level > 255;
 
@@ -482,20 +484,20 @@ parse_lfp_backlight(struct drm_i915_private *i915,
 			drm_warn(&i915->drm, "Brightness min level > 255\n");
 			level = 255;
 		}
-		i915->vbt.backlight.min_brightness = min_level;
+		info->backlight.min_brightness = min_level;
 	} else {
-		level = backlight_data->level[panel_type];
-		i915->vbt.backlight.min_brightness = entry->min_brightness;
+		level = backlight_data->level[panel_index];
+		info->backlight.min_brightness = entry->min_brightness;
 	}
 
 	drm_dbg_kms(&i915->drm,
 		    "VBT backlight PWM modulation frequency %u Hz, "
 		    "active %s, min brightness %u, level %u, controller %u\n",
-		    i915->vbt.backlight.pwm_freq_hz,
-		    i915->vbt.backlight.active_low_pwm ? "low" : "high",
-		    i915->vbt.backlight.min_brightness,
+		    info->backlight.pwm_freq_hz,
+		    info->backlight.active_low_pwm ? "low" : "high",
+		    info->backlight.min_brightness,
 		    level,
-		    i915->vbt.backlight.controller);
+		    info->backlight.controller);
 }
 
 /* Try to find sdvo panel data */
@@ -709,29 +711,14 @@ parse_driver_features(struct drm_i915_private *i915,
 		    driver->lvds_config != BDB_DRIVER_FEATURE_INT_SDVO_LVDS)
 			i915->vbt.int_lvds_support = 0;
 	}
-
-	if (bdb->version < 228) {
-		drm_dbg_kms(&i915->drm, "DRRS State Enabled:%d\n",
-			    driver->drrs_enabled);
-		/*
-		 * If DRRS is not supported, drrs_type has to be set to 0.
-		 * This is because, VBT is configured in such a way that
-		 * static DRRS is 0 and DRRS not supported is represented by
-		 * driver->drrs_enabled=false
-		 */
-		if (!driver->drrs_enabled)
-			i915->vbt.drrs_type = DRRS_NOT_SUPPORTED;
-
-		i915->vbt.psr.enable = driver->psr_enabled;
-	}
 }
 
 static void
 parse_power_conservation_features(struct drm_i915_private *i915,
-				  const struct bdb_header *bdb)
+				  const struct bdb_header *bdb, int panel_index,
+				  struct ddi_vbt_port_info *info)
 {
 	const struct bdb_lfp_power *power;
-	u8 panel_type = i915->vbt.panel_type;
 
 	if (bdb->version < 228)
 		return;
@@ -740,7 +727,7 @@ parse_power_conservation_features(struct drm_i915_private *i915,
 	if (!power)
 		return;
 
-	i915->vbt.psr.enable = power->psr & BIT(panel_type);
+	info->psr.enable = power->psr & BIT(panel_index);
 
 	/*
 	 * If DRRS is not supported, drrs_type has to be set to 0.
@@ -748,49 +735,49 @@ parse_power_conservation_features(struct drm_i915_private *i915,
 	 * static DRRS is 0 and DRRS not supported is represented by
 	 * power->drrs & BIT(panel_type)=false
 	 */
-	if (!(power->drrs & BIT(panel_type)))
-		i915->vbt.drrs_type = DRRS_NOT_SUPPORTED;
+	if (!(power->drrs & BIT(panel_index)))
+		info->drrs_type = DRRS_NOT_SUPPORTED;
 
 	if (bdb->version >= 232)
-		i915->vbt.edp.hobl = power->hobl & BIT(panel_type);
+		info->edp.hobl = power->hobl & BIT(panel_index);
 }
 
 static void
-parse_edp(struct drm_i915_private *i915, const struct bdb_header *bdb)
+parse_edp(struct drm_i915_private *i915, const struct bdb_header *bdb,
+	  int panel_index, struct ddi_vbt_port_info *info)
 {
 	const struct bdb_edp *edp;
 	const struct edp_power_seq *edp_pps;
 	const struct edp_fast_link_params *edp_link_params;
-	int panel_type = i915->vbt.panel_type;
 
 	edp = find_section(bdb, BDB_EDP);
 	if (!edp)
 		return;
 
-	switch ((edp->color_depth >> (panel_type * 2)) & 3) {
+	switch ((edp->color_depth >> (panel_index * 2)) & 3) {
 	case EDP_18BPP:
-		i915->vbt.edp.bpp = 18;
+		info->edp.bpp = 18;
 		break;
 	case EDP_24BPP:
-		i915->vbt.edp.bpp = 24;
+		info->edp.bpp = 24;
 		break;
 	case EDP_30BPP:
-		i915->vbt.edp.bpp = 30;
+		info->edp.bpp = 30;
 		break;
 	}
 
 	/* Get the eDP sequencing and link info */
-	edp_pps = &edp->power_seqs[panel_type];
-	edp_link_params = &edp->fast_link_params[panel_type];
+	edp_pps = &edp->power_seqs[panel_index];
+	edp_link_params = &edp->fast_link_params[panel_index];
 
-	i915->vbt.edp.pps = *edp_pps;
+	info->edp.pps = *edp_pps;
 
 	switch (edp_link_params->rate) {
 	case EDP_RATE_1_62:
-		i915->vbt.edp.rate = DP_LINK_BW_1_62;
+		info->edp.rate = DP_LINK_BW_1_62;
 		break;
 	case EDP_RATE_2_7:
-		i915->vbt.edp.rate = DP_LINK_BW_2_7;
+		info->edp.rate = DP_LINK_BW_2_7;
 		break;
 	default:
 		drm_dbg_kms(&i915->drm,
@@ -801,13 +788,13 @@ parse_edp(struct drm_i915_private *i915, const struct bdb_header *bdb)
 
 	switch (edp_link_params->lanes) {
 	case EDP_LANE_1:
-		i915->vbt.edp.lanes = 1;
+		info->edp.lanes = 1;
 		break;
 	case EDP_LANE_2:
-		i915->vbt.edp.lanes = 2;
+		info->edp.lanes = 2;
 		break;
 	case EDP_LANE_4:
-		i915->vbt.edp.lanes = 4;
+		info->edp.lanes = 4;
 		break;
 	default:
 		drm_dbg_kms(&i915->drm,
@@ -818,16 +805,16 @@ parse_edp(struct drm_i915_private *i915, const struct bdb_header *bdb)
 
 	switch (edp_link_params->preemphasis) {
 	case EDP_PREEMPHASIS_NONE:
-		i915->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_0;
+		info->edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_0;
 		break;
 	case EDP_PREEMPHASIS_3_5dB:
-		i915->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_1;
+		info->edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_1;
 		break;
 	case EDP_PREEMPHASIS_6dB:
-		i915->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_2;
+		info->edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_2;
 		break;
 	case EDP_PREEMPHASIS_9_5dB:
-		i915->vbt.edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_3;
+		info->edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_3;
 		break;
 	default:
 		drm_dbg_kms(&i915->drm,
@@ -838,16 +825,16 @@ parse_edp(struct drm_i915_private *i915, const struct bdb_header *bdb)
 
 	switch (edp_link_params->vswing) {
 	case EDP_VSWING_0_4V:
-		i915->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
+		info->edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
 		break;
 	case EDP_VSWING_0_6V:
-		i915->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_1;
+		info->edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_1;
 		break;
 	case EDP_VSWING_0_8V:
-		i915->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
+		info->edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
 		break;
 	case EDP_VSWING_1_2V:
-		i915->vbt.edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
+		info->edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
 		break;
 	default:
 		drm_dbg_kms(&i915->drm,
@@ -861,21 +848,21 @@ parse_edp(struct drm_i915_private *i915, const struct bdb_header *bdb)
 
 		/* Don't read from VBT if module parameter has valid value*/
 		if (i915->params.edp_vswing) {
-			i915->vbt.edp.low_vswing =
+			info->edp.low_vswing =
 				i915->params.edp_vswing == 1;
 		} else {
-			vswing = (edp->edp_vswing_preemph >> (panel_type * 4)) & 0xF;
-			i915->vbt.edp.low_vswing = vswing == 0;
+			vswing = (edp->edp_vswing_preemph >> (panel_index * 4)) & 0xF;
+			info->edp.low_vswing = vswing == 0;
 		}
 	}
 }
 
 static void
-parse_psr(struct drm_i915_private *i915, const struct bdb_header *bdb)
+parse_psr(struct drm_i915_private *i915, const struct bdb_header *bdb,
+	  int panel_index, struct ddi_vbt_port_info *info)
 {
 	const struct bdb_psr *psr;
 	const struct psr_table *psr_table;
-	int panel_type = i915->vbt.panel_type;
 
 	psr = find_section(bdb, BDB_PSR);
 	if (!psr) {
@@ -883,27 +870,27 @@ parse_psr(struct drm_i915_private *i915, const struct bdb_header *bdb)
 		return;
 	}
 
-	psr_table = &psr->psr_table[panel_type];
+	psr_table = &psr->psr_table[panel_index];
 
-	i915->vbt.psr.full_link = psr_table->full_link;
-	i915->vbt.psr.require_aux_wakeup = psr_table->require_aux_to_wakeup;
+	info->psr.full_link = psr_table->full_link;
+	info->psr.require_aux_wakeup = psr_table->require_aux_to_wakeup;
 
 	/* Allowed VBT values goes from 0 to 15 */
-	i915->vbt.psr.idle_frames = psr_table->idle_frames < 0 ? 0 :
+	info->psr.idle_frames = psr_table->idle_frames < 0 ? 0 :
 		psr_table->idle_frames > 15 ? 15 : psr_table->idle_frames;
 
 	switch (psr_table->lines_to_wait) {
 	case 0:
-		i915->vbt.psr.lines_to_wait = PSR_0_LINES_TO_WAIT;
+		info->psr.lines_to_wait = PSR_0_LINES_TO_WAIT;
 		break;
 	case 1:
-		i915->vbt.psr.lines_to_wait = PSR_1_LINE_TO_WAIT;
+		info->psr.lines_to_wait = PSR_1_LINE_TO_WAIT;
 		break;
 	case 2:
-		i915->vbt.psr.lines_to_wait = PSR_4_LINES_TO_WAIT;
+		info->psr.lines_to_wait = PSR_4_LINES_TO_WAIT;
 		break;
 	case 3:
-		i915->vbt.psr.lines_to_wait = PSR_8_LINES_TO_WAIT;
+		info->psr.lines_to_wait = PSR_8_LINES_TO_WAIT;
 		break;
 	default:
 		drm_dbg_kms(&i915->drm,
@@ -920,13 +907,13 @@ parse_psr(struct drm_i915_private *i915, const struct bdb_header *bdb)
 	    (DISPLAY_VER(i915) >= 9 && !IS_BROXTON(i915))) {
 		switch (psr_table->tp1_wakeup_time) {
 		case 0:
-			i915->vbt.psr.tp1_wakeup_time_us = 500;
+			info->psr.tp1_wakeup_time_us = 500;
 			break;
 		case 1:
-			i915->vbt.psr.tp1_wakeup_time_us = 100;
+			info->psr.tp1_wakeup_time_us = 100;
 			break;
 		case 3:
-			i915->vbt.psr.tp1_wakeup_time_us = 0;
+			info->psr.tp1_wakeup_time_us = 0;
 			break;
 		default:
 			drm_dbg_kms(&i915->drm,
@@ -934,19 +921,19 @@ parse_psr(struct drm_i915_private *i915, const struct bdb_header *bdb)
 				    psr_table->tp1_wakeup_time);
 			fallthrough;
 		case 2:
-			i915->vbt.psr.tp1_wakeup_time_us = 2500;
+			info->psr.tp1_wakeup_time_us = 2500;
 			break;
 		}
 
 		switch (psr_table->tp2_tp3_wakeup_time) {
 		case 0:
-			i915->vbt.psr.tp2_tp3_wakeup_time_us = 500;
+			info->psr.tp2_tp3_wakeup_time_us = 500;
 			break;
 		case 1:
-			i915->vbt.psr.tp2_tp3_wakeup_time_us = 100;
+			info->psr.tp2_tp3_wakeup_time_us = 100;
 			break;
 		case 3:
-			i915->vbt.psr.tp2_tp3_wakeup_time_us = 0;
+			info->psr.tp2_tp3_wakeup_time_us = 0;
 			break;
 		default:
 			drm_dbg_kms(&i915->drm,
@@ -954,18 +941,18 @@ parse_psr(struct drm_i915_private *i915, const struct bdb_header *bdb)
 				    psr_table->tp2_tp3_wakeup_time);
 			fallthrough;
 		case 2:
-			i915->vbt.psr.tp2_tp3_wakeup_time_us = 2500;
+			info->psr.tp2_tp3_wakeup_time_us = 2500;
 		break;
 		}
 	} else {
-		i915->vbt.psr.tp1_wakeup_time_us = psr_table->tp1_wakeup_time * 100;
-		i915->vbt.psr.tp2_tp3_wakeup_time_us = psr_table->tp2_tp3_wakeup_time * 100;
+		info->psr.tp1_wakeup_time_us = psr_table->tp1_wakeup_time * 100;
+		info->psr.tp2_tp3_wakeup_time_us = psr_table->tp2_tp3_wakeup_time * 100;
 	}
 
 	if (bdb->version >= 226) {
 		u32 wakeup_time = psr->psr2_tp2_tp3_wakeup_time;
 
-		wakeup_time = (wakeup_time >> (2 * panel_type)) & 0x3;
+		wakeup_time = (wakeup_time >> (2 * panel_index)) & 0x3;
 		switch (wakeup_time) {
 		case 0:
 			wakeup_time = 500;
@@ -981,10 +968,10 @@ parse_psr(struct drm_i915_private *i915, const struct bdb_header *bdb)
 			wakeup_time = 2500;
 			break;
 		}
-		i915->vbt.psr.psr2_tp2_tp3_wakeup_time_us = wakeup_time;
+		info->psr.psr2_tp2_tp3_wakeup_time_us = wakeup_time;
 	} else {
 		/* Reusing PSR1 wakeup time for PSR2 in older VBTs */
-		i915->vbt.psr.psr2_tp2_tp3_wakeup_time_us = i915->vbt.psr.tp2_tp3_wakeup_time_us;
+		info->psr.psr2_tp2_tp3_wakeup_time_us = info->psr.tp2_tp3_wakeup_time_us;
 	}
 }
 
@@ -1032,12 +1019,11 @@ static void parse_dsi_backlight_ports(struct drm_i915_private *i915,
 
 static void
 parse_mipi_config(struct drm_i915_private *i915,
-		  const struct bdb_header *bdb)
+		  const struct bdb_header *bdb, int panel_index)
 {
 	const struct bdb_mipi_config *start;
 	const struct mipi_config *config;
 	const struct mipi_pps_data *pps;
-	int panel_type = i915->vbt.panel_type;
 	enum port port;
 
 	/* parse MIPI blocks only if LFP type is MIPI */
@@ -1062,14 +1048,14 @@ parse_mipi_config(struct drm_i915_private *i915,
 	}
 
 	drm_dbg(&i915->drm, "Found MIPI Config block, panel index = %d\n",
-		panel_type);
+		panel_index);
 
 	/*
 	 * get hold of the correct configuration block and pps data as per
 	 * the panel_type as index
 	 */
-	config = &start->config[panel_type];
-	pps = &start->pps[panel_type];
+	config = &start->config[panel_index];
+	pps = &start->pps[panel_index];
 
 	/* store as of now full data. Trim when we realise all is not needed */
 	i915->vbt.dsi.config = kmemdup(config, sizeof(struct mipi_config), GFP_KERNEL);
@@ -1352,9 +1338,8 @@ static void fixup_mipi_sequences(struct drm_i915_private *i915)
 
 static void
 parse_mipi_sequence(struct drm_i915_private *i915,
-		    const struct bdb_header *bdb)
+		    const struct bdb_header *bdb, int panel_index)
 {
-	int panel_type = i915->vbt.panel_type;
 	const struct bdb_mipi_sequence *sequence;
 	const u8 *seq_data;
 	u32 seq_size;
@@ -1383,7 +1368,7 @@ parse_mipi_sequence(struct drm_i915_private *i915,
 	drm_dbg(&i915->drm, "Found MIPI sequence block v%u\n",
 		sequence->version);
 
-	seq_data = find_panel_sequence_block(sequence, panel_type, &seq_size);
+	seq_data = find_panel_sequence_block(sequence, panel_index, &seq_size);
 	if (!seq_data)
 		return;
 
@@ -1881,6 +1866,45 @@ static bool is_port_valid(struct drm_i915_private *i915, enum port port)
 	return true;
 }
 
+static const struct bdb_header *get_bdb_header(const struct vbt_header *vbt)
+{
+	const void *_vbt = vbt;
+
+	return _vbt + vbt->bdb_offset;
+}
+
+static void parse_lfp(struct drm_i915_private *i915,
+		      struct intel_bios_encoder_data *devdata,
+		      struct ddi_vbt_port_info *info)
+{
+	const struct vbt_header *vbt = i915->opregion.vbt;
+	const struct bdb_header *bdb;
+	int lfp_inst, panel_index;
+
+	if (devdata->child.handle == HANDLE_LFP_1)
+		lfp_inst = 1;
+	else if (devdata->child.handle == HANDLE_LFP_2)
+		lfp_inst = 2;
+	else
+		return;
+
+	bdb = get_bdb_header(vbt);
+	panel_index = get_lfp_panel_index(i915, bdb, lfp_inst);
+	if (panel_index == -1)
+		return;
+
+	parse_panel_options(i915, bdb, panel_index, info);
+	parse_panel_dtd(i915, bdb, panel_index, info);	
+	parse_lfp_backlight(i915, bdb, panel_index, info);
+	parse_power_conservation_features(i915, bdb, panel_index, info);
+	parse_edp(i915, bdb, panel_index, info);
+	parse_psr(i915, bdb, panel_index, info);
+
+	/* TODO: only handling one instance of mipi */
+	parse_mipi_config(i915, bdb, panel_index);
+	parse_mipi_sequence(i915, bdb, panel_index);
+}
+
 static void parse_ddi_port(struct drm_i915_private *i915,
 			   struct intel_bios_encoder_data *devdata)
 {
@@ -2010,6 +2034,8 @@ static void parse_ddi_port(struct drm_i915_private *i915,
 			    port_name(port), info->dp_max_link_rate);
 	}
 
+	parse_lfp(i915, devdata, info);
+
 	info->devdata = devdata;
 }
 
@@ -2133,12 +2159,6 @@ init_vbt_defaults(struct drm_i915_private *i915)
 {
 	i915->vbt.crt_ddc_pin = GMBUS_PIN_VGADDC;
 
-	/* Default to having backlight */
-	i915->vbt.backlight.present = true;
-
-	/* LFP panel data */
-	i915->vbt.lvds_dither = 1;
-
 	/* SDVO panel data */
 	i915->vbt.sdvo_lvds_vbt_mode = NULL;
 
@@ -2218,13 +2238,6 @@ init_vbt_missing_defaults(struct drm_i915_private *i915)
 	i915->vbt.version = 155;
 }
 
-static const struct bdb_header *get_bdb_header(const struct vbt_header *vbt)
-{
-	const void *_vbt = vbt;
-
-	return _vbt + vbt->bdb_offset;
-}
-
 /**
  * intel_bios_is_valid_vbt - does the given buffer contain a valid VBT
  * @buf:	pointer to a buffer to validate
@@ -2378,16 +2391,8 @@ void intel_bios_init(struct drm_i915_private *i915)
 	/* Grab useful general definitions */
 	parse_general_features(i915, bdb);
 	parse_general_definitions(i915, bdb);
-	parse_panel_options(i915, bdb);
-	parse_panel_dtd(i915, bdb);
-	parse_lfp_backlight(i915, bdb);
 	parse_sdvo_panel_data(i915, bdb);
 	parse_driver_features(i915, bdb);
-	parse_power_conservation_features(i915, bdb);
-	parse_edp(i915, bdb);
-	parse_psr(i915, bdb);
-	parse_mipi_config(i915, bdb);
-	parse_mipi_sequence(i915, bdb);
 
 	/* Depends on child device list */
 	parse_compression_parameters(i915, bdb);
@@ -2413,6 +2418,7 @@ void intel_bios_init(struct drm_i915_private *i915)
 void intel_bios_driver_remove(struct drm_i915_private *i915)
 {
 	struct intel_bios_encoder_data *devdata, *n;
+	int i;
 
 	list_for_each_entry_safe(devdata, n, &i915->vbt.display_devices, node) {
 		list_del(&devdata->node);
@@ -2420,10 +2426,13 @@ void intel_bios_driver_remove(struct drm_i915_private *i915)
 		kfree(devdata);
 	}
 
+	for (i = 0; i < I915_MAX_PORTS; i++) {
+		kfree(i915->vbt.ddi_port_info[i].lfp_lvds_vbt_mode);
+		i915->vbt.ddi_port_info[i].lfp_lvds_vbt_mode = NULL;
+	}
+
 	kfree(i915->vbt.sdvo_lvds_vbt_mode);
 	i915->vbt.sdvo_lvds_vbt_mode = NULL;
-	kfree(i915->vbt.lfp_lvds_vbt_mode);
-	i915->vbt.lfp_lvds_vbt_mode = NULL;
 	kfree(i915->vbt.dsi.data);
 	i915->vbt.dsi.data = NULL;
 	kfree(i915->vbt.dsi.pps);
@@ -3003,3 +3012,53 @@ intel_bios_encoder_data_lookup(struct drm_i915_private *i915, enum port port)
 {
 	return i915->vbt.ddi_port_info[port].devdata;
 }
+
+const struct vbt_psr_info *
+intel_bios_psr_info(struct intel_dp *intel_dp)
+{
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *encoder = &dig_port->base;
+
+	return &i915->vbt.ddi_port_info[encoder->port].psr;
+}
+
+struct vbt_edp_info *
+intel_bios_edp_info(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+	return &i915->vbt.ddi_port_info[encoder->port].edp;
+}
+
+const struct vbt_backlight_info *
+intel_bios_backlight_info(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+	return &i915->vbt.ddi_port_info[encoder->port].backlight;
+}
+
+enum drrs_support_type
+intel_bios_drrs_type(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+	return i915->vbt.ddi_port_info[encoder->port].drrs_type;
+}
+
+const struct drm_display_mode *
+intel_bios_lfp_lvds_info(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+	return i915->vbt.ddi_port_info[encoder->port].lfp_lvds_vbt_mode;
+}
+
+unsigned int
+intel_bios_lvds_val(struct intel_encoder *encoder)
+{
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+	return i915->vbt.ddi_port_info[encoder->port].bios_lvds_val;
+}
\ No newline at end of file
diff --git a/drivers/gpu/drm/i915/display/intel_bios.h b/drivers/gpu/drm/i915/display/intel_bios.h
index 4709c4d298059..07fb5292b98cd 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.h
+++ b/drivers/gpu/drm/i915/display/intel_bios.h
@@ -36,6 +36,7 @@ struct drm_i915_private;
 struct intel_bios_encoder_data;
 struct intel_crtc_state;
 struct intel_encoder;
+struct intel_dp;
 enum port;
 
 enum intel_backlight_type {
@@ -266,4 +267,11 @@ bool intel_bios_encoder_supports_tbt(const struct intel_bios_encoder_data *devda
 int intel_bios_encoder_dp_boost_level(const struct intel_bios_encoder_data *devdata);
 int intel_bios_encoder_hdmi_boost_level(const struct intel_bios_encoder_data *devdata);
 
+const struct vbt_psr_info *intel_bios_psr_info(struct intel_dp *intel_dp);
+struct vbt_edp_info *intel_bios_edp_info(struct intel_encoder *encoder);
+const struct vbt_backlight_info *intel_bios_backlight_info(struct intel_encoder *encoder);
+enum drrs_support_type intel_bios_drrs_type(struct intel_encoder *encoder);
+const struct drm_display_mode *intel_bios_lfp_lvds_info(struct intel_encoder *encoder);
+unsigned int intel_bios_lvds_val(struct intel_encoder *encoder);
+
 #endif /* _INTEL_BIOS_H_ */
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 26a3aa73fcc43..87da9b2dca94f 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3644,6 +3644,7 @@ static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
 static void intel_ddi_get_config(struct intel_encoder *encoder,
 				 struct intel_crtc_state *pipe_config)
 {
+	struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
 
@@ -3669,8 +3670,8 @@ static void intel_ddi_get_config(struct intel_encoder *encoder,
 	pipe_config->has_audio =
 		intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
 
-	if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.bpp &&
-	    pipe_config->pipe_bpp > dev_priv->vbt.edp.bpp) {
+	if (encoder->type == INTEL_OUTPUT_EDP && vbt_edp_info->bpp &&
+	    pipe_config->pipe_bpp > vbt_edp_info->bpp) {
 		/*
 		 * This is a big fat ugly hack.
 		 *
@@ -3686,8 +3687,8 @@ static void intel_ddi_get_config(struct intel_encoder *encoder,
 		 */
 		drm_dbg_kms(&dev_priv->drm,
 			    "pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
-			    pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp);
-		dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
+			    pipe_config->pipe_bpp, vbt_edp_info->bpp);
+		vbt_edp_info->bpp = pipe_config->pipe_bpp;
 	}
 
 	if (!pipe_config->bigjoiner_slave)
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 63b1ae830d9a0..8ac04cd7ceeee 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c
@@ -1125,14 +1125,14 @@ 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);
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 
 	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)
+		 vbt_edp_info->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);
@@ -1162,12 +1162,12 @@ 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);
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 
 	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)
+		 vbt_edp_info->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);
@@ -1178,12 +1178,12 @@ skl_u_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);
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 
 	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)
+		 vbt_edp_info->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);
@@ -1194,12 +1194,12 @@ 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);
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 
 	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)
+		 vbt_edp_info->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);
@@ -1210,12 +1210,12 @@ kbl_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);
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 
 	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)
+		 vbt_edp_info->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);
@@ -1226,12 +1226,12 @@ kbl_u_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);
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 
 	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)
+		 vbt_edp_info->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);
@@ -1242,12 +1242,12 @@ 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);
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 
 	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)
+		 vbt_edp_info->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);
@@ -1258,12 +1258,12 @@ bxt_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);
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 
 	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)
+		 vbt_edp_info->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);
@@ -1316,10 +1316,11 @@ cnl_get_buf_trans_dp(struct intel_encoder *encoder, int *n_entries)
 static const struct intel_ddi_buf_trans *
 cnl_get_buf_trans_edp(struct intel_encoder *encoder, int *n_entries)
 {
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 	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 (vbt_edp_info->low_vswing) {
 		if (voltage == VOLTAGE_INFO_0_85V) {
 			return intel_get_buf_trans(&cnl_ddi_translations_edp_0_85V,
 						   n_entries);
@@ -1365,12 +1366,12 @@ icl_get_combo_buf_trans_edp(struct intel_encoder *encoder,
 			    const struct intel_crtc_state *crtc_state,
 			    int *n_entries)
 {
-	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(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.low_vswing) {
+	} else if (vbt_edp_info->low_vswing) {
 		return intel_get_buf_trans(&icl_combo_phy_ddi_translations_edp_hbr2,
 					   n_entries);
 	}
@@ -1432,12 +1433,12 @@ 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);
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 
 	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)
+		 vbt_edp_info->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);
@@ -1459,12 +1460,12 @@ 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);
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 
 	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)
+		 vbt_edp_info->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);
@@ -1496,16 +1497,16 @@ 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);
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 	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) {
+	} else if (vbt_edp_info->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) {
+	} else if (vbt_edp_info->low_vswing) {
 		return intel_get_buf_trans(&icl_combo_phy_ddi_translations_edp_hbr2,
 					   n_entries);
 	}
@@ -1544,16 +1545,16 @@ 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);
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 	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)
+	else if (vbt_edp_info->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)
+	else if (vbt_edp_info->low_vswing)
 		return intel_get_buf_trans(&icl_combo_phy_ddi_translations_edp_hbr2,
 					   n_entries);
 	else
@@ -1589,16 +1590,16 @@ 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);
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 	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) {
+	} else if (vbt_edp_info->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) {
+	} else if (vbt_edp_info->low_vswing) {
 		return intel_get_buf_trans(&icl_combo_phy_ddi_translations_edp_hbr2,
 					   n_entries);
 	}
@@ -1635,14 +1636,14 @@ adls_get_combo_buf_trans_edp(struct intel_encoder *encoder,
 			     const struct intel_crtc_state *crtc_state,
 			     int *n_entries)
 {
-	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 	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)
+	else if (vbt_edp_info->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)
+	else if (vbt_edp_info->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);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 19d8d3eefbc27..a5154d2594430 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -327,6 +327,8 @@ struct intel_panel {
 		const struct intel_panel_bl_funcs *pwm_funcs;
 		void (*power)(struct intel_connector *, bool enable);
 	} backlight;
+
+	const struct vbt_backlight_info *vbt_backlight_info;
 };
 
 struct intel_digital_port;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index c386ef8eb2006..0e60be9443749 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1025,13 +1025,17 @@ static int intel_dp_max_bpp(struct intel_dp *intel_dp,
 
 	bpp = bpc * 3;
 	if (intel_dp_is_edp(intel_dp)) {
+		struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+		struct intel_encoder *encoder = &dig_port->base;
+		const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
+
 		/* Get bpp from vbt only for panels that dont have bpp in edid */
 		if (intel_connector->base.display_info.bpc == 0 &&
-		    dev_priv->vbt.edp.bpp && dev_priv->vbt.edp.bpp < bpp) {
+		    vbt_edp_info->bpp && vbt_edp_info->bpp < bpp) {
 			drm_dbg_kms(&dev_priv->drm,
 				    "clamping bpp for eDP panel to BIOS-provided %i\n",
-				    dev_priv->vbt.edp.bpp);
-			bpp = dev_priv->vbt.edp.bpp;
+				    vbt_edp_info->bpp);
+			bpp = vbt_edp_info->bpp;
 		}
 	}
 
@@ -5133,6 +5137,7 @@ intel_dp_drrs_init(struct intel_connector *connector,
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	struct drm_display_mode *downclock_mode = NULL;
+	enum drrs_support_type drrs_type = intel_bios_drrs_type(connector->encoder);
 
 	INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);
 	mutex_init(&dev_priv->drrs.mutex);
@@ -5143,7 +5148,7 @@ intel_dp_drrs_init(struct intel_connector *connector,
 		return NULL;
 	}
 
-	if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) {
+	if (drrs_type != SEAMLESS_DRRS_SUPPORT) {
 		drm_dbg_kms(&dev_priv->drm, "VBT doesn't support DRRS\n");
 		return NULL;
 	}
@@ -5155,7 +5160,7 @@ intel_dp_drrs_init(struct intel_connector *connector,
 		return NULL;
 	}
 
-	dev_priv->drrs.type = dev_priv->vbt.drrs_type;
+	dev_priv->drrs.type = drrs_type;
 
 	dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR;
 	drm_dbg_kms(&dev_priv->drm,
@@ -5251,7 +5256,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 			    pipe_name(pipe));
 	}
 
-	intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
+	intel_panel_init(intel_connector, fixed_mode, downclock_mode);
 	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);
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 6ac568617ef37..996d24872ae8c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
@@ -310,14 +310,15 @@ static int intel_dp_aux_vesa_setup_backlight(struct intel_connector *connector,
 {
 	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;
 
-	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);
+	ret = drm_edp_backlight_init(&intel_dp->aux,
+				     &panel->backlight.edp.vesa.info,
+				     panel->vbt_backlight_info->pwm_freq_hz,
+				     intel_dp->edp_dpcd, &current_level,
+				     &current_mode);
 	if (ret < 0)
 		return ret;
 
@@ -391,7 +392,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
 	case INTEL_DP_AUX_BACKLIGHT_OFF:
 		return -ENODEV;
 	case INTEL_DP_AUX_BACKLIGHT_AUTO:
-		switch (i915->vbt.backlight.type) {
+		switch (panel->vbt_backlight_info->type) {
 		case INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE:
 			try_vesa_interface = true;
 			break;
@@ -403,7 +404,8 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
 		}
 		break;
 	case INTEL_DP_AUX_BACKLIGHT_ON:
-		if (i915->vbt.backlight.type != INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE)
+		if (panel->vbt_backlight_info->type !=
+		    INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE)
 			try_intel_interface = true;
 
 		try_vesa_interface = true;
diff --git a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
index 584c14c4cbd0e..018900255fef3 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_dcs_backlight.c
@@ -166,11 +166,10 @@ static const struct intel_panel_bl_funcs dcs_bl_funcs = {
 int intel_dsi_dcs_init_backlight_funcs(struct intel_connector *intel_connector)
 {
 	struct drm_device *dev = intel_connector->base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_encoder *encoder = intel_attached_encoder(intel_connector);
 	struct intel_panel *panel = &intel_connector->panel;
 
-	if (dev_priv->vbt.backlight.type != INTEL_BACKLIGHT_DSI_DCS)
+	if (panel->vbt_backlight_info->type != INTEL_BACKLIGHT_DSI_DCS)
 		return -ENODEV;
 
 	if (drm_WARN_ON(dev, encoder->type != INTEL_OUTPUT_DSI))
diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
index c2a2cd1f84dc5..a2110361889c8 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c
@@ -729,7 +729,7 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct mipi_config *mipi_config = dev_priv->vbt.dsi.config;
 	struct mipi_pps_data *pps = dev_priv->vbt.dsi.pps;
-	struct drm_display_mode *mode = dev_priv->vbt.lfp_lvds_vbt_mode;
+	const struct drm_display_mode *mode = intel_bios_lfp_lvds_info(&intel_dsi->base);
 	u16 burst_mode_ratio;
 	enum port port;
 
diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c
index 77419f8c05e9f..7aeb68695530b 100644
--- a/drivers/gpu/drm/i915/display/intel_dvo.c
+++ b/drivers/gpu/drm/i915/display/intel_dvo.c
@@ -553,7 +553,7 @@ void intel_dvo_init(struct drm_i915_private *dev_priv)
 			 * headers, likely), so for now, just get the current
 			 * mode being output through DVO.
 			 */
-			intel_panel_init(&intel_connector->panel,
+			intel_panel_init(intel_connector,
 					 intel_dvo_get_current_mode(intel_encoder),
 					 NULL);
 			intel_dvo->panel_wants_dither = true;
diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
index e0381b0fce914..bd61280014f87 100644
--- a/drivers/gpu/drm/i915/display/intel_lvds.c
+++ b/drivers/gpu/drm/i915/display/intel_lvds.c
@@ -810,7 +810,7 @@ static bool compute_is_dual_link_lvds(struct intel_lvds_encoder *lvds_encoder)
 	else
 		val &= ~(LVDS_DETECTED | LVDS_PIPE_SEL_MASK);
 	if (val == 0)
-		val = dev_priv->vbt.bios_lvds_val;
+		val = intel_bios_lvds_val(&lvds_encoder->base);
 
 	return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP;
 }
@@ -998,7 +998,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv)
 out:
 	mutex_unlock(&dev->mode_config.mutex);
 
-	intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
+	intel_panel_init(intel_connector, fixed_mode, downclock_mode);
 	intel_panel_setup_backlight(connector, INVALID_PIPE);
 
 	lvds_encoder->is_dual_link = compute_is_dual_link_lvds(lvds_encoder);
diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
index 7d7a60b4d2de7..466a6adc594f3 100644
--- a/drivers/gpu/drm/i915/display/intel_panel.c
+++ b/drivers/gpu/drm/i915/display/intel_panel.c
@@ -153,12 +153,12 @@ intel_panel_vbt_fixed_mode(struct intel_connector *connector)
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	struct drm_display_info *info = &connector->base.display_info;
 	struct drm_display_mode *fixed_mode;
+	const struct drm_display_mode *lfp_lvds_vbt_mode = intel_bios_lfp_lvds_info(connector->encoder);
 
-	if (!dev_priv->vbt.lfp_lvds_vbt_mode)
+	if (!lfp_lvds_vbt_mode)
 		return NULL;
 
-	fixed_mode = drm_mode_duplicate(&dev_priv->drm,
-					dev_priv->vbt.lfp_lvds_vbt_mode);
+	fixed_mode = drm_mode_duplicate(&dev_priv->drm, lfp_lvds_vbt_mode);
 	if (!fixed_mode)
 		return NULL;
 
@@ -1595,9 +1595,10 @@ static u32 vlv_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
 	return DIV_ROUND_CLOSEST(clock, pwm_freq_hz * mul);
 }
 
-static u16 get_vbt_pwm_freq(struct drm_i915_private *dev_priv)
+static u16 get_vbt_pwm_freq(struct drm_i915_private *dev_priv,
+			    struct intel_panel *panel)
 {
-	u16 pwm_freq_hz = dev_priv->vbt.backlight.pwm_freq_hz;
+	u16 pwm_freq_hz = panel->vbt_backlight_info->pwm_freq_hz;
 
 	if (pwm_freq_hz) {
 		drm_dbg_kms(&dev_priv->drm,
@@ -1617,7 +1618,7 @@ static u32 get_backlight_max_vbt(struct intel_connector *connector)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	struct intel_panel *panel = &connector->panel;
-	u16 pwm_freq_hz = get_vbt_pwm_freq(dev_priv);
+	u16 pwm_freq_hz = get_vbt_pwm_freq(dev_priv, panel);
 	u32 pwm;
 
 	if (!panel->backlight.pwm_funcs->hz_to_pwm) {
@@ -1654,11 +1655,11 @@ static u32 get_backlight_min_vbt(struct intel_connector *connector)
 	 * against this by letting the minimum be at most (arbitrarily chosen)
 	 * 25% of the max.
 	 */
-	min = clamp_t(int, dev_priv->vbt.backlight.min_brightness, 0, 64);
-	if (min != dev_priv->vbt.backlight.min_brightness) {
+	min = clamp_t(int, panel->vbt_backlight_info->min_brightness, 0, 64);
+	if (min != panel->vbt_backlight_info->min_brightness) {
 		drm_dbg_kms(&dev_priv->drm,
 			    "clamping VBT min backlight %d/255 to %d/255\n",
-			    dev_priv->vbt.backlight.min_brightness, min);
+			    panel->vbt_backlight_info->min_brightness, min);
 	}
 
 	/* vbt value is a coefficient in range [0..255] */
@@ -1847,7 +1848,7 @@ bxt_setup_backlight(struct intel_connector *connector, enum pipe unused)
 	struct intel_panel *panel = &connector->panel;
 	u32 pwm_ctl, val;
 
-	panel->backlight.controller = dev_priv->vbt.backlight.controller;
+	panel->backlight.controller = panel->vbt_backlight_info->controller;
 
 	pwm_ctl = intel_de_read(dev_priv,
 				BXT_BLC_PWM_CTL(panel->backlight.controller));
@@ -1949,11 +1950,11 @@ static int ext_pwm_setup_backlight(struct intel_connector *connector,
 
 		drm_dbg_kms(&dev_priv->drm, "PWM already enabled at freq %ld, VBT freq %d, level %d\n",
 			    NSEC_PER_SEC / (unsigned long)panel->backlight.pwm_state.period,
-			    get_vbt_pwm_freq(dev_priv), level);
+			    get_vbt_pwm_freq(dev_priv, panel), level);
 	} else {
 		/* Set period from VBT frequency, leave other settings at 0. */
 		panel->backlight.pwm_state.period =
-			NSEC_PER_SEC / get_vbt_pwm_freq(dev_priv);
+			NSEC_PER_SEC / get_vbt_pwm_freq(dev_priv, panel);
 	}
 
 	drm_info(&dev_priv->drm, "Using %s PWM for LCD backlight control\n",
@@ -2039,7 +2040,7 @@ int intel_panel_setup_backlight(struct drm_connector *connector, enum pipe pipe)
 	struct intel_panel *panel = &intel_connector->panel;
 	int ret;
 
-	if (!dev_priv->vbt.backlight.present) {
+	if (!panel->vbt_backlight_info->present) {
 		if (dev_priv->quirks & QUIRK_BACKLIGHT_PRESENT) {
 			drm_dbg_kms(&dev_priv->drm,
 				    "no backlight present per VBT, but present per quirk\n");
@@ -2228,10 +2229,13 @@ intel_panel_detect(struct drm_connector *connector, bool force)
 	return connector_status_connected;
 }
 
-int intel_panel_init(struct intel_panel *panel,
+int intel_panel_init(struct intel_connector *intel_connector,
 		     struct drm_display_mode *fixed_mode,
 		     struct drm_display_mode *downclock_mode)
 {
+	struct intel_panel *panel = &intel_connector->panel;
+
+	panel->vbt_backlight_info = intel_bios_backlight_info(intel_connector->encoder);
 	intel_panel_init_backlight_funcs(panel);
 
 	panel->fixed_mode = fixed_mode;
diff --git a/drivers/gpu/drm/i915/display/intel_panel.h b/drivers/gpu/drm/i915/display/intel_panel.h
index 1d340f77bffc7..fa57679c2c8c5 100644
--- a/drivers/gpu/drm/i915/display/intel_panel.h
+++ b/drivers/gpu/drm/i915/display/intel_panel.h
@@ -19,7 +19,7 @@ struct intel_crtc_state;
 struct intel_encoder;
 struct intel_panel;
 
-int intel_panel_init(struct intel_panel *panel,
+int intel_panel_init(struct intel_connector *intel_connector,
 		     struct drm_display_mode *fixed_mode,
 		     struct drm_display_mode *downclock_mode);
 void intel_panel_fini(struct intel_panel *panel);
diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c
index a36ec4a818ff5..6289d925bf338 100644
--- a/drivers/gpu/drm/i915/display/intel_pps.c
+++ b/drivers/gpu/drm/i915/display/intel_pps.c
@@ -207,7 +207,10 @@ static int
 bxt_power_sequencer_idx(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-	int backlight_controller = dev_priv->vbt.backlight.controller;
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *encoder = &dig_port->base;
+	const struct vbt_backlight_info *vbt_backlight_info = intel_bios_backlight_info(encoder);
+	int backlight_controller = vbt_backlight_info->controller;
 
 	lockdep_assert_held(&dev_priv->pps_mutex);
 
@@ -362,6 +365,7 @@ static void intel_pps_get_registers(struct intel_dp *intel_dp,
 
 	memset(regs, 0, sizeof(*regs));
 
+	// TODO bxt_power_sequencer_idx for newer platforms?
 	if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
 		pps_idx = bxt_power_sequencer_idx(intel_dp);
 	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
@@ -1158,6 +1162,9 @@ static void pps_init_delays(struct intel_dp *intel_dp)
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	struct edp_power_seq cur, vbt, spec,
 		*final = &intel_dp->pps.pps_delays;
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *encoder = &dig_port->base;
+	const struct vbt_edp_info *vbt_edp_info = intel_bios_edp_info(encoder);
 
 	lockdep_assert_held(&dev_priv->pps_mutex);
 
@@ -1169,7 +1176,7 @@ static void pps_init_delays(struct intel_dp *intel_dp)
 
 	intel_pps_dump_state("cur", &cur);
 
-	vbt = dev_priv->vbt.edp.pps;
+	vbt = vbt_edp_info->pps;
 	/* On Toshiba Satellite P50-C-18C system the VBT T12 delay
 	 * of 500ms appears to be too short. Ocassionally the panel
 	 * just fails to power back on. Increasing the delay to 800ms
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index d436490ab28c6..9425e33461e23 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -428,6 +428,7 @@ static void intel_psr_enable_sink(struct intel_dp *intel_dp)
 
 static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp)
 {
+	const struct vbt_psr_info *vbt_psr_info = intel_bios_psr_info(intel_dp);
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	u32 val = 0;
 
@@ -440,20 +441,20 @@ static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp)
 		goto check_tp3_sel;
 	}
 
-	if (dev_priv->vbt.psr.tp1_wakeup_time_us == 0)
+	if (vbt_psr_info->tp1_wakeup_time_us == 0)
 		val |= EDP_PSR_TP1_TIME_0us;
-	else if (dev_priv->vbt.psr.tp1_wakeup_time_us <= 100)
+	else if (vbt_psr_info->tp1_wakeup_time_us <= 100)
 		val |= EDP_PSR_TP1_TIME_100us;
-	else if (dev_priv->vbt.psr.tp1_wakeup_time_us <= 500)
+	else if (vbt_psr_info->tp1_wakeup_time_us <= 500)
 		val |= EDP_PSR_TP1_TIME_500us;
 	else
 		val |= EDP_PSR_TP1_TIME_2500us;
 
-	if (dev_priv->vbt.psr.tp2_tp3_wakeup_time_us == 0)
+	if (vbt_psr_info->tp2_tp3_wakeup_time_us == 0)
 		val |= EDP_PSR_TP2_TP3_TIME_0us;
-	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time_us <= 100)
+	else if (vbt_psr_info->tp2_tp3_wakeup_time_us <= 100)
 		val |= EDP_PSR_TP2_TP3_TIME_100us;
-	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time_us <= 500)
+	else if (vbt_psr_info->tp2_tp3_wakeup_time_us <= 500)
 		val |= EDP_PSR_TP2_TP3_TIME_500us;
 	else
 		val |= EDP_PSR_TP2_TP3_TIME_2500us;
@@ -470,13 +471,14 @@ static u32 intel_psr1_get_tp_time(struct intel_dp *intel_dp)
 
 static u8 psr_compute_idle_frames(struct intel_dp *intel_dp)
 {
+	const struct vbt_psr_info *vbt_psr_info = intel_bios_psr_info(intel_dp);
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	int idle_frames;
 
 	/* Let's use 6 as the minimum to cover all known cases including the
 	 * off-by-one issue that HW has in some cases.
 	 */
-	idle_frames = max(6, dev_priv->vbt.psr.idle_frames);
+	idle_frames = max(6, vbt_psr_info->idle_frames);
 	idle_frames = max(idle_frames, intel_dp->psr.sink_sync_latency + 1);
 
 	if (drm_WARN_ON(&dev_priv->drm, idle_frames > 0xf))
@@ -512,18 +514,19 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp)
 
 static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp)
 {
+	const struct vbt_psr_info *vbt_psr_info = intel_bios_psr_info(intel_dp);
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	u32 val = 0;
 
 	if (dev_priv->params.psr_safest_params)
 		return EDP_PSR2_TP2_TIME_2500us;
 
-	if (dev_priv->vbt.psr.psr2_tp2_tp3_wakeup_time_us >= 0 &&
-	    dev_priv->vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 50)
+	if (vbt_psr_info->psr2_tp2_tp3_wakeup_time_us >= 0 &&
+	    vbt_psr_info->psr2_tp2_tp3_wakeup_time_us <= 50)
 		val |= EDP_PSR2_TP2_TIME_50us;
-	else if (dev_priv->vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 100)
+	else if (vbt_psr_info->psr2_tp2_tp3_wakeup_time_us <= 100)
 		val |= EDP_PSR2_TP2_TIME_100us;
-	else if (dev_priv->vbt.psr.psr2_tp2_tp3_wakeup_time_us <= 500)
+	else if (vbt_psr_info->psr2_tp2_tp3_wakeup_time_us <= 500)
 		val |= EDP_PSR2_TP2_TIME_500us;
 	else
 		val |= EDP_PSR2_TP2_TIME_2500us;
@@ -2135,6 +2138,7 @@ void intel_psr_flush(struct drm_i915_private *dev_priv,
  */
 void intel_psr_init(struct intel_dp *intel_dp)
 {
+	const struct vbt_psr_info *vbt_psr_info = intel_bios_psr_info(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);
 
@@ -2167,7 +2171,7 @@ void intel_psr_init(struct intel_dp *intel_dp)
 		dev_priv->hsw_psr_mmio_adjust = _SRD_CTL_EDP - _HSW_EDP_PSR_BASE;
 
 	if (dev_priv->params.enable_psr == -1)
-		if (DISPLAY_VER(dev_priv) < 9 || !dev_priv->vbt.psr.enable)
+		if (DISPLAY_VER(dev_priv) < 9 || !vbt_psr_info->enable)
 			dev_priv->params.enable_psr = 0;
 
 	/* Set link_standby x link_off defaults */
@@ -2176,7 +2180,7 @@ void intel_psr_init(struct intel_dp *intel_dp)
 		intel_dp->psr.link_standby = false;
 	else if (DISPLAY_VER(dev_priv) < 12)
 		/* For new platforms up to TGL let's respect VBT back again */
-		intel_dp->psr.link_standby = dev_priv->vbt.psr.full_link;
+		intel_dp->psr.link_standby = vbt_psr_info->full_link;
 
 	INIT_WORK(&intel_dp->psr.work, intel_psr_work);
 	INIT_DELAYED_WORK(&intel_dp->psr.dc3co_work, tgl_dc3co_disable_work);
diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
index 6cb27599ea030..6f90779e53d77 100644
--- a/drivers/gpu/drm/i915/display/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
@@ -2923,8 +2923,7 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
 			struct drm_display_mode *fixed_mode =
 				drm_mode_duplicate(connector->dev, mode);
 
-			intel_panel_init(&intel_connector->panel,
-					 fixed_mode, NULL);
+			intel_panel_init(intel_connector, fixed_mode, NULL);
 			break;
 		}
 	}
diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
index dbe24d7e73759..bed5b308641eb 100644
--- a/drivers/gpu/drm/i915/display/intel_vbt_defs.h
+++ b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
@@ -359,6 +359,9 @@ enum vbt_gmbus_ddi {
 #define BDB_230_VBT_DP_MAX_LINK_RATE_UHBR13P5	6
 #define BDB_230_VBT_DP_MAX_LINK_RATE_UHBR20	7
 
+#define HANDLE_LFP_1 0x0008
+#define HANDLE_LFP_2 0x0080
+
 /*
  * The child device config, aka the display device data structure, provides a
  * description of a port and its configuration on the platform.
@@ -701,17 +704,9 @@ struct bdb_edp {
 #define MODE_MASK		0x3
 
 struct bdb_lvds_options {
-	u8 panel_type;
-	u8 panel_type2;						/* 212 */
-	/* LVDS capabilities, stored in a dword */
-	u8 pfit_mode:2;
-	u8 pfit_text_mode_enhanced:1;
-	u8 pfit_gfx_mode_enhanced:1;
-	u8 pfit_ratio_auto:1;
-	u8 pixel_dither:1;
-	u8 lvds_edid:1;
-	u8 rsvd2:1;
-	u8 rsvd4;
+	u8 panel_type;/* first panel index */
+	u8 panel_type2;/* second panel index 212+ */						/* 212 */
+	u16 lfp_capabilities;/* Do no handle multi lfps */
 	/* LVDS Panel channel bits stored here */
 	u32 lvds_panel_channel_bits;
 	/* LVDS SSC (Spread Spectrum Clock) bits stored here. */
diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c
index 0ee4ff341e25d..ec61d09352718 100644
--- a/drivers/gpu/drm/i915/display/vlv_dsi.c
+++ b/drivers/gpu/drm/i915/display/vlv_dsi.c
@@ -1963,7 +1963,7 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
 		goto err_cleanup_connector;
 	}
 
-	intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
+	intel_panel_init(intel_connector, fixed_mode, NULL);
 	intel_panel_setup_backlight(connector, INVALID_PIPE);
 
 	vlv_dsi_add_properties(intel_connector);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f99b6c0dd068d..4dda832f9fe08 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -642,6 +642,13 @@ i915_fence_timeout(const struct drm_i915_private *i915)
 
 #define HAS_HW_SAGV_WM(i915) (DISPLAY_VER(i915) >= 13 && !IS_DGFX(i915))
 
+enum psr_lines_to_wait {
+	PSR_0_LINES_TO_WAIT = 0,
+	PSR_1_LINE_TO_WAIT,
+	PSR_4_LINES_TO_WAIT,
+	PSR_8_LINES_TO_WAIT
+};
+
 struct ddi_vbt_port_info {
 	/* Non-NULL if port present. */
 	struct intel_bios_encoder_data *devdata;
@@ -656,50 +663,13 @@ struct ddi_vbt_port_info {
 	u8 alternate_ddc_pin;
 
 	int dp_max_link_rate;		/* 0 for not limited by VBT */
-};
-
-enum psr_lines_to_wait {
-	PSR_0_LINES_TO_WAIT = 0,
-	PSR_1_LINE_TO_WAIT,
-	PSR_4_LINES_TO_WAIT,
-	PSR_8_LINES_TO_WAIT
-};
-
-struct intel_vbt_data {
-	/* bdb version */
-	u16 version;
 
 	struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
-	struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
-
-	/* Feature bits */
-	unsigned int int_tv_support:1;
-	unsigned int lvds_dither:1;
-	unsigned int int_crt_support:1;
-	unsigned int lvds_use_ssc:1;
-	unsigned int int_lvds_support:1;
-	unsigned int display_clock_mode:1;
-	unsigned int fdi_rx_polarity_inverted:1;
-	unsigned int panel_type:4;
-	int lvds_ssc_freq;
 	unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
-	enum drm_panel_orientation orientation;
 
 	enum drrs_support_type drrs_type;
 
-	struct {
-		int rate;
-		int lanes;
-		int preemphasis;
-		int vswing;
-		bool low_vswing;
-		bool initialized;
-		int bpp;
-		struct edp_power_seq pps;
-		bool hobl;
-	} edp;
-
-	struct {
+	struct vbt_psr_info {
 		bool enable;
 		bool full_link;
 		bool require_aux_wakeup;
@@ -710,7 +680,7 @@ struct intel_vbt_data {
 		int psr2_tp2_tp3_wakeup_time_us;
 	} psr;
 
-	struct {
+	struct vbt_backlight_info {
 		u16 pwm_freq_hz;
 		bool present;
 		bool active_low_pwm;
@@ -719,6 +689,36 @@ struct intel_vbt_data {
 		enum intel_backlight_type type;
 	} backlight;
 
+	struct vbt_edp_info {
+		int rate;
+		int lanes;
+		int preemphasis;
+		int vswing;
+		bool low_vswing;
+		bool initialized;
+		int bpp;
+		struct edp_power_seq pps;
+		bool hobl;
+	} edp;
+};
+
+struct intel_vbt_data {
+	/* bdb version */
+	u16 version;
+
+	struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
+
+	/* Feature bits */
+	unsigned int int_tv_support:1;
+	unsigned int int_crt_support:1;
+	unsigned int lvds_use_ssc:1;
+	unsigned int int_lvds_support:1;
+	unsigned int display_clock_mode:1;
+	unsigned int fdi_rx_polarity_inverted:1;
+	//unsigned int panel_type:4;//drop
+	int lvds_ssc_freq;
+	enum drm_panel_orientation orientation;
+
 	/* MIPI DSI */
 	struct {
 		u16 panel_id;
-- 
2.32.0



More information about the Intel-gfx-trybot mailing list