@@ -1175,6 +1175,15 @@ struct intel_vbt_data {
int lvds_ssc_freq;
unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
+ /**
+ * DRRS mode type (Seamless OR Static DRRS)
+ * drrs_mode Val 0x2 is Seamless DRRS and 0 is Static DRRS.
+ * These values correspond to the VBT values for drrs mode.
+ */
+ int drrs_mode;
+ /* DRRS enabled or disabled in VBT */
+ bool drrs_enabled;
+
/* eDP */
int edp_rate;
int edp_lanes;
@@ -195,6 +195,21 @@ get_lvds_fp_timing(const struct bdb_header *bdb,
return (const struct lvds_fp_timing *)((const u8 *)bdb + ofs);
}
+/**
+ * This function returns the 2 bit information pertaining to a panel type
+ * present in a 32 bit field in VBT blocks. There are 16 panel types in VBT
+ * each occupying 2 bits of information in some 32 bit fields of VBT blocks.
+ */
+static int
+get_mode_by_paneltype(unsigned int word)
+{
+ /**
+ * The caller of this API should interpret the 2 bits
+ * based on VBT description for that field.
+ */
+ return (word >> ((panel_type - 1) * 2)) & MODE_MASK;
+}
+
/* Try to find integrated panel data */
static void
parse_lfp_panel_data(struct drm_i915_private *dev_priv,
@@ -218,6 +233,11 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
panel_type = lvds_options->panel_type;
+ dev_priv->vbt.drrs_mode =
+ get_mode_by_paneltype(lvds_options->dps_panel_type_bits);
+ DRM_DEBUG_KMS("DRRS supported mode is : %s\n",
+ (dev_priv->vbt.drrs_mode == 0) ? "STATIC" : "SEAMLESS");
+
lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
if (!lvds_lfp_data)
return;
@@ -488,6 +508,9 @@ parse_driver_features(struct drm_i915_private *dev_priv,
if (driver->dual_frequency)
dev_priv->render_reclock_avail = true;
+
+ dev_priv->vbt.drrs_enabled = driver->drrs_state;
+ DRM_DEBUG_KMS("DRRS State Enabled : %d\n", driver->drrs_state);
}
static void
@@ -202,6 +202,9 @@ struct bdb_general_features {
#define DEVICE_PORT_DVOB 0x01
#define DEVICE_PORT_DVOC 0x02
+/* Mask for DRRS / Panel Channel / SSC / BLT control bits extraction */
+#define MODE_MASK 0x3
+
/* We used to keep this struct but without any version control. We should avoid
* using it in the future, but it should be safe to keep using it in the old
* code. */
@@ -293,6 +296,18 @@ struct bdb_lvds_options {
u8 lvds_edid:1;
u8 rsvd2:1;
u8 rsvd4;
+ /* LVDS Panel channel bits stored here */
+ u32 lvds_panel_channel_bits;
+ /* LVDS SSC (Spread Spectrum Clock) bits stored here. */
+ u16 ssc_bits;
+ u16 ssc_freq;
+ u16 ssc_ddt;
+ /* Panel color depth defined here */
+ u16 panel_color_depth;
+ /* LVDS panel type bits stored here */
+ u32 dps_panel_type_bits;
+ /* LVDS backlight control type bits stored here */
+ u32 blt_control_type_bits;
} __attribute__((packed));
/* LFP pointer table contains entries to the struct below */
@@ -462,6 +477,20 @@ struct bdb_driver_features {
u8 hdmi_termination;
u8 custom_vbt_version;
+ /* Driver features data block */
+ u16 rmpm_state:1;
+ u16 s2ddt_state:1;
+ u16 dpst_state:1;
+ u16 bltclt_state:1;
+ u16 adb_state:1;
+ u16 drrs_state:1;
+ u16 grs_state:1;
+ u16 gpmt_state:1;
+ u16 tbt_state:1;
+ u16 psr_state:1;
+ u16 ips_state:1;
+ u16 reserved3:4;
+ u16 pc_feature_validity:1;
} __attribute__((packed));
#define EDP_18BPP 0