intel-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: "José Roberto de Souza" <jose.souza@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: Jani Nikula <jani.nikula@intel.com>
Subject: [Intel-gfx] [PATCH CI 02/10] drm/i915/bios: Start to support two integrated panels
Date: Thu, 29 Jul 2021 14:55:37 -0700	[thread overview]
Message-ID: <20210729215545.192606-2-jose.souza@intel.com> (raw)
In-Reply-To: <20210729215545.192606-1-jose.souza@intel.com>

VBT has support for up two integrated panels but i915 only supports one.

So here stating to add the basic support for two integrated panels
and moving the DRRS to ddi_vbt_port_info instead of keeping a global
one.
Other VBT blocks will be converted in following patches.

While at is also nucking lvds_dither as it is not used.

Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
 drivers/gpu/drm/i915/display/intel_bios.c     | 185 +++++++++++++-----
 drivers/gpu/drm/i915/display/intel_bios.h     |   2 +
 drivers/gpu/drm/i915/display/intel_dp.c       |   5 +-
 drivers/gpu/drm/i915/display/intel_vbt_defs.h |   3 +
 drivers/gpu/drm/i915/i915_drv.h               |   5 +-
 5 files changed, 150 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c
index a6cb33f847a43..9439bfe32b136 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.c
+++ b/drivers/gpu/drm/i915/display/intel_bios.c
@@ -211,22 +211,20 @@ get_lvds_fp_timing(const struct bdb_header *bdb,
 	return (const struct lvds_fp_timing *)((const u8 *)bdb + ofs);
 }
 
-/* Parse general panel options */
-static void
-parse_panel_options(struct drm_i915_private *i915,
-		    const struct bdb_header *bdb)
+/*
+ * Parse and set vbt.panel_type, it will be used by the VBT blocks that are
+ * not being called from parse_integrated_panel() yet.
+ */
+static void parse_panel_type(struct drm_i915_private *i915,
+			     const struct bdb_header *bdb)
 {
 	const struct bdb_lvds_options *lvds_options;
-	int panel_type;
-	int drrs_mode;
-	int ret;
+	int ret, panel_type;
 
 	lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
 	if (!lvds_options)
 		return;
 
-	i915->vbt.lvds_dither = lvds_options->pixel_dither;
-
 	ret = intel_opregion_get_panel_type(i915);
 	if (ret >= 0) {
 		drm_WARN_ON(&i915->drm, ret > 0xf);
@@ -246,9 +244,25 @@ parse_panel_options(struct drm_i915_private *i915,
 	}
 
 	i915->vbt.panel_type = panel_type;
+}
+
+/* Parse general panel options */
+static void
+parse_panel_options(struct drm_i915_private *i915,
+		    const struct bdb_header *bdb,
+		    struct ddi_vbt_port_info *info,
+		    int panel_index)
+{
+	const struct bdb_lvds_options *lvds_options;
+	int drrs_mode;
+
+	lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);
+	if (!lvds_options)
+		return;
+
+	drrs_mode = lvds_options->dps_panel_type_bits >> (panel_index * 2);
+	drrs_mode &= MODE_MASK;
 
-	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 +270,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;
@@ -710,28 +724,42 @@ parse_driver_features(struct drm_i915_private *i915,
 			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;
-
+	if (bdb->version < 228)
 		i915->vbt.psr.enable = driver->psr_enabled;
-	}
+}
+
+static void
+parse_driver_features_drrs_only(struct drm_i915_private *i915,
+				const struct bdb_header *bdb,
+				struct ddi_vbt_port_info *info)
+{
+	const struct bdb_driver_features *driver;
+
+	if (bdb->version >= 228)
+		return;
+
+	driver = find_section(bdb, BDB_DRIVER_FEATURES);
+	if (!driver)
+		return;
+
+	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)
+		info->drrs_type = DRRS_NOT_SUPPORTED;
 }
 
 static void
 parse_power_conservation_features(struct drm_i915_private *i915,
-				  const struct bdb_header *bdb)
+				  const struct bdb_header *bdb,
+				  struct ddi_vbt_port_info *info,
+				  int panel_index)
 {
 	const struct bdb_lfp_power *power;
-	u8 panel_type = i915->vbt.panel_type;
 
 	if (bdb->version < 228)
 		return;
@@ -740,7 +768,7 @@ parse_power_conservation_features(struct drm_i915_private *i915,
 	if (!power)
 		return;
 
-	i915->vbt.psr.enable = power->psr & BIT(panel_type);
+	i915->vbt.psr.enable = power->psr & BIT(panel_index);
 
 	/*
 	 * If DRRS is not supported, drrs_type has to be set to 0.
@@ -748,11 +776,11 @@ 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);
+		i915->vbt.edp.hobl = power->hobl & BIT(panel_index);
 }
 
 static void
@@ -1887,6 +1915,74 @@ 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 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;
+}
+
+static void parse_integrated_panel(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 = 0, panel_index, opregion_panel_index;
+
+	if (devdata->child.handle == HANDLE_LFP_1)
+		lfp_inst = 1;
+	else if (devdata->child.handle == HANDLE_LFP_2)
+		lfp_inst = 2;
+
+	if (lfp_inst == 0)
+		return;
+
+	bdb = get_bdb_header(vbt);
+	panel_index = get_lfp_panel_index(i915, bdb, lfp_inst);
+
+	opregion_panel_index = intel_opregion_get_panel_type(i915);
+	/*
+	 * TODO: the current implementation always use the panel index from
+	 * opregion if available due to issues with old platforms.
+	 * But this do not supports two panels and in SKL or newer I never saw a
+	 * system were this call returns a valid value.
+	 * So will change this to only use opregion up to BDW in a separated
+	 * commit.
+	 */
+	if (opregion_panel_index >= 0)
+		panel_index = opregion_panel_index;
+
+	if (panel_index == -1)
+		return;
+
+	parse_panel_options(i915, bdb, info, panel_index);
+	parse_power_conservation_features(i915, bdb, info, panel_index);
+	parse_driver_features_drrs_only(i915, bdb, info);
+}
+
 static void parse_ddi_port(struct drm_i915_private *i915,
 			   struct intel_bios_encoder_data *devdata)
 {
@@ -2018,6 +2114,8 @@ static void parse_ddi_port(struct drm_i915_private *i915,
 			    port_name(port), info->dp_max_link_rate);
 	}
 
+	parse_integrated_panel(i915, devdata, info);
+
 	info->devdata = devdata;
 }
 
@@ -2144,9 +2242,6 @@ init_vbt_defaults(struct drm_i915_private *i915)
 	/* 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;
 
@@ -2227,13 +2322,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
@@ -2387,12 +2475,11 @@ 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_type(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);
@@ -3012,3 +3099,11 @@ intel_bios_encoder_data_lookup(struct drm_i915_private *i915, enum port port)
 {
 	return i915->vbt.ddi_port_info[port].devdata;
 }
+
+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;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_bios.h b/drivers/gpu/drm/i915/display/intel_bios.h
index 4709c4d298059..bad282b64c5e6 100644
--- a/drivers/gpu/drm/i915/display/intel_bios.h
+++ b/drivers/gpu/drm/i915/display/intel_bios.h
@@ -266,4 +266,6 @@ 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);
 
+enum drrs_support_type intel_bios_drrs_type(struct intel_encoder *encoder);
+
 #endif /* _INTEL_BIOS_H_ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index a54e339947c65..80a2caf4b8053 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5136,6 +5136,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);
@@ -5146,7 +5147,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;
 	}
@@ -5158,7 +5159,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,
diff --git a/drivers/gpu/drm/i915/display/intel_vbt_defs.h b/drivers/gpu/drm/i915/display/intel_vbt_defs.h
index dbe24d7e73759..cd927d13250f1 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.
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8bb3661d3b2db..df096a283d52a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -650,6 +650,8 @@ struct ddi_vbt_port_info {
 	u8 alternate_ddc_pin;
 
 	int dp_max_link_rate;		/* 0 for not limited by VBT */
+
+	enum drrs_support_type drrs_type;
 };
 
 enum psr_lines_to_wait {
@@ -668,7 +670,6 @@ struct intel_vbt_data {
 
 	/* 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;
@@ -679,8 +680,6 @@ struct intel_vbt_data {
 	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;
-- 
2.32.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2021-07-29 21:51 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-29 21:55 [Intel-gfx] [PATCH CI 01/10] drm/i915/bios: Allow DSI ports to be parsed by parse_ddi_port() José Roberto de Souza
2021-07-29 21:55 ` José Roberto de Souza [this message]
2021-07-29 21:55 ` [Intel-gfx] [PATCH CI 03/10] drm/i915/bios: Enable parse of two integrated panels timing data José Roberto de Souza
2021-07-29 21:55 ` [Intel-gfx] [PATCH CI 04/10] drm/i915/bios: Enable parse of two integrated panels backlight data José Roberto de Souza
2021-07-29 21:55 ` [Intel-gfx] [PATCH CI 05/10] drm/i915/bios: Enable parse of two integrated panels eDP data José Roberto de Souza
2021-07-29 21:55 ` [Intel-gfx] [PATCH CI 06/10] drm/i915/bios: Enable parse of two integrated panels PSR data José Roberto de Souza
2021-07-29 21:55 ` [Intel-gfx] [PATCH CI 07/10] drm/i915/bios: Enable parse of two DSI panels data José Roberto de Souza
2021-07-29 21:55 ` [Intel-gfx] [PATCH CI 08/10] drm/i915/bios: Nuke panel_type José Roberto de Souza
2021-07-29 21:55 ` [Intel-gfx] [PATCH CI 09/10] drm/i915/bios: Only use opregion panel index for display ver 8 and older José Roberto de Souza
2021-07-29 21:55 ` [Intel-gfx] [PATCH CI 10/10] drm/i915/display/tgl+: Use PPS index from vbt José Roberto de Souza
2021-07-29 22:00 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [CI,01/10] drm/i915/bios: Allow DSI ports to be parsed by parse_ddi_port() Patchwork
2021-07-29 22:01 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2021-07-29 22:26 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2021-07-30  9:19 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210729215545.192606-2-jose.souza@intel.com \
    --to=jose.souza@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=jani.nikula@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).