All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] v5: Enabling DRRS in the kernel
@ 2014-02-14 10:02 Vandana Kannan
  2014-02-14 10:02 ` [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature Vandana Kannan
                   ` (4 more replies)
  0 siblings, 5 replies; 21+ messages in thread
From: Vandana Kannan @ 2014-02-14 10:02 UTC (permalink / raw)
  To: intel-gfx

Dynamic Refresh Rate Switching (DRRS) is a power conservation feature which     
enables swtiching between low and high refresh rates based on the usage         
scenario. This feature is applciable for internal eDP panel. Indication that    
the panel supports DRRS is given by the panel EDID, which would list multiple   
refresh rates for one resolution.                                               
The patch series supports idleness detection in display i915 driver and         
switch to low refresh rate.                                                     
                                                                                
Based on review comments, the functions for idleness detection have been        
restructured. DRRS idleness time has been modified to be a kernel module param. 

Pradeep Bhat (3):
  [Intel-gfx] drm/i915: Adding VBT fields to support eDP DRRS feature
  [Intel-gfx] drm/i915: Parse EDID probed modes for DRRS support
  [Intel-gfx] drm/i915: Add support for DRRS to switch RR

Vandana Kannan (2):
  [Intel-gfx] drm/i915: Idleness detection for DRRS
  [Intel-gfx] drm/i915/bdw: Add support for DRRS to switch RR

 drivers/gpu/drm/i915/i915_drv.h      |   25 +++++
 drivers/gpu/drm/i915/i915_params.c   |    8 ++
 drivers/gpu/drm/i915/i915_reg.h      |    1 +
 drivers/gpu/drm/i915/intel_bios.c    |   29 ++++++
 drivers/gpu/drm/i915/intel_bios.h    |   29 ++++++
 drivers/gpu/drm/i915/intel_display.c |   18 +++-
 drivers/gpu/drm/i915/intel_dp.c      |  176 +++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_drv.h     |   33 ++++++-
 drivers/gpu/drm/i915/intel_pm.c      |  134 ++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_sprite.c  |    2 +
 10 files changed, 451 insertions(+), 4 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature
  2014-02-14 10:02 [PATCH 0/5] v5: Enabling DRRS in the kernel Vandana Kannan
@ 2014-02-14 10:02 ` Vandana Kannan
  2014-02-14 16:39   ` Jesse Barnes
  2014-02-14 10:02 ` [PATCH 2/5] drm/i915: Parse EDID probed modes for DRRS support Vandana Kannan
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 21+ messages in thread
From: Vandana Kannan @ 2014-02-14 10:02 UTC (permalink / raw)
  To: intel-gfx

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch reads the DRRS support and Mode type from VBT fields.
The read information will be stored in VBT struct during BIOS
parsing. The above functionality is needed for decision making
whether DRRS feature is supported in i915 driver for eDP panels.
This information helps us decide if seamless DRRS can be done
at runtime to support certain power saving features. This patch
was tested by setting necessary bit in VBT struct and merging
the new VBT with system BIOS so that we can read the value.

v2: Incorporated review comments from Chris Wilson
Removed "intel_" as a prefix for DRRS specific declarations.

v3: Incorporated Jani's review comments
Removed function which deducts drrs mode from panel_type. Modified some
print statements. Made changes to use DRRS_NOT_SUPPORTED as 0 instead of -1.

Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h   |   13 +++++++++++++
 drivers/gpu/drm/i915/intel_bios.c |   29 +++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_bios.h |   29 +++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 728b9c3..6b4d0b20 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1218,6 +1218,12 @@ struct ddi_vbt_port_info {
 	uint8_t supports_dp:1;
 };
 
+enum drrs_support_type {
+	DRRS_NOT_SUPPORTED = 0,
+	STATIC_DRRS_SUPPORT = 1,
+	SEAMLESS_DRRS_SUPPORT = 2
+};
+
 struct intel_vbt_data {
 	struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
 	struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
@@ -1233,6 +1239,13 @@ struct intel_vbt_data {
 	int lvds_ssc_freq;
 	unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
 
+	/*
+	 * DRRS support type (Seamless OR Static DRRS OR not supported)
+	 * drrs_support type Val 0x2 is Seamless DRRS and 0 is Static DRRS.
+	 * These values correspond to the VBT values for drrs mode.
+	 */
+	enum drrs_support_type drrs_type;
+
 	/* eDP */
 	int edp_rate;
 	int edp_lanes;
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 86b95ca..2414eca 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -218,6 +218,25 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
 
 	panel_type = lvds_options->panel_type;
 
+	dev_priv->vbt.drrs_type = (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
+	 * to match the enum drrs_support_type.
+	 */
+	switch (dev_priv->vbt.drrs_type) {
+	case 0:
+		dev_priv->vbt.drrs_type = STATIC_DRRS_SUPPORT;
+		DRM_DEBUG_KMS("DRRS supported mode is static\n");
+		break;
+	case 2:
+		DRM_DEBUG_KMS("DRRS supported mode is seamless\n");
+		break;
+	default:
+		break;
+	}
+
 	lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
 	if (!lvds_lfp_data)
 		return;
@@ -516,6 +535,16 @@ parse_driver_features(struct drm_i915_private *dev_priv,
 
 	if (driver->dual_frequency)
 		dev_priv->render_reclock_avail = true;
+
+	DRM_DEBUG_KMS("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)
+		dev_priv->vbt.drrs_type = driver->drrs_enabled;
 }
 
 static void
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 282de5e..5505d6c 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -281,6 +281,9 @@ struct bdb_general_definitions {
 	union child_device_config devices[0];
 } __packed;
 
+/* Mask for DRRS / Panel Channel / SSC / BLT control bits extraction */
+#define MODE_MASK		0x3
+
 struct bdb_lvds_options {
 	u8 panel_type;
 	u8 rsvd1;
@@ -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;
 } __packed;
 
 /* LFP pointer table contains entries to the struct below */
@@ -478,6 +493,20 @@ struct bdb_driver_features {
 
 	u8 hdmi_termination;
 	u8 custom_vbt_version;
+	/* Driver features data block */
+	u16 rmpm_enabled:1;
+	u16 s2ddt_enabled:1;
+	u16 dpst_enabled:1;
+	u16 bltclt_enabled:1;
+	u16 adb_enabled:1;
+	u16 drrs_enabled:1;
+	u16 grs_enabled:1;
+	u16 gpmt_enabled:1;
+	u16 tbt_enabled:1;
+	u16 psr_enabled:1;
+	u16 ips_enabled:1;
+	u16 reserved3:4;
+	u16 pc_feature_valid:1;
 } __packed;
 
 #define EDP_18BPP	0
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 2/5] drm/i915: Parse EDID probed modes for DRRS support
  2014-02-14 10:02 [PATCH 0/5] v5: Enabling DRRS in the kernel Vandana Kannan
  2014-02-14 10:02 ` [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature Vandana Kannan
@ 2014-02-14 10:02 ` Vandana Kannan
  2014-02-14 10:02 ` [PATCH 3/5] drm/i915: Add support for DRRS to switch RR Vandana Kannan
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 21+ messages in thread
From: Vandana Kannan @ 2014-02-14 10:02 UTC (permalink / raw)
  To: intel-gfx

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch and finds out the lowest refresh rate supported for the resolution
same as the fixed_mode, based on the implementaion find_panel_downclock.
It also checks the VBT fields to see if panel supports seamless DRRS or not.
Based on above data it marks whether eDP panel supports seamless DRRS or not.
This information is needed for supporting seamless DRRS switch for certain
power saving usecases. This patch is tested by enabling the DRM logs and
user should see whether Seamless DRRS is supported or not.

v2: Daniel's review comments
Modified downclock deduction based on intel_find_panel_downclock

v3: Chris's review comments
Moved edp_downclock_avail and edp_downclock to intel_panel

v4: Jani's review comments.
Changed name of the enum edp_panel_type to drrs_support type.
Change is_drrs_supported to drrs_support of type enum drrs_support_type.

v5: Incorporated Jani's review comments
Modify intel_dp_drrs_initialize to return downclock mode. Support for Gen7
and above.

Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
---
 drivers/gpu/drm/i915/intel_dp.c  |   53 +++++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_drv.h |   20 ++++++++++++++
 2 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 88cc9d3..f7dba83 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3666,6 +3666,49 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
 		      I915_READ(pp_div_reg));
 }
 
+static struct drm_display_mode *
+intel_dp_drrs_initialize(struct intel_digital_port *intel_dig_port,
+			struct intel_connector *intel_connector,
+			struct drm_display_mode *fixed_mode)
+{
+	struct drm_connector *connector = &intel_connector->base;
+	struct intel_dp *intel_dp = &intel_dig_port->dp;
+	struct drm_device *dev = intel_dig_port->base.base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_display_mode *downclock_mode = NULL;
+
+	/**
+	 * Check if PSR is supported by panel and enabled
+	 * if so then DRRS is reported as not supported for Haswell.
+	 */
+	if (INTEL_INFO(dev)->gen < 8 &&	intel_edp_is_psr_enabled(dev)) {
+		DRM_INFO("eDP panel has PSR enabled. Cannot support DRRS\n");
+		return downclock_mode;
+	}
+
+	/* First check if DRRS is enabled from VBT struct */
+	if (dev_priv->vbt.drrs_type == DRRS_NOT_SUPPORTED) {
+		DRM_INFO("VBT doesn't support DRRS\n");
+		return downclock_mode;
+	}
+
+	downclock_mode = intel_find_panel_downclock(dev,fixed_mode, connector);
+
+	if (downclock_mode != NULL &&
+		dev_priv->vbt.drrs_type == SEAMLESS_DRRS_SUPPORT) {
+		intel_connector->panel.edp_downclock_avail = true;
+		intel_connector->panel.edp_downclock =
+			downclock_mode->clock;
+
+		intel_dp->drrs_state.type = dev_priv->vbt.drrs_type;
+
+		intel_dp->drrs_state.refresh_rate_type = DRRS_HIGH_RR;
+		DRM_INFO("seamless DRRS supported for eDP panel.\n");
+	}
+
+	return downclock_mode;
+}
+
 static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 				     struct intel_connector *intel_connector,
 				     struct edp_power_seq *power_seq)
@@ -3675,10 +3718,13 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 	struct drm_device *dev = intel_dig_port->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_display_mode *fixed_mode = NULL;
+	struct drm_display_mode *downclock_mode = NULL;
 	bool has_dpcd;
 	struct drm_display_mode *scan;
 	struct edid *edid;
 
+	intel_dp->drrs_state.type = DRRS_NOT_SUPPORTED;
+
 	if (!is_edp(intel_dp))
 		return true;
 
@@ -3720,6 +3766,11 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 	list_for_each_entry(scan, &connector->probed_modes, head) {
 		if ((scan->type & DRM_MODE_TYPE_PREFERRED)) {
 			fixed_mode = drm_mode_duplicate(dev, scan);
+			if (INTEL_INFO(dev)->gen > 6)
+				downclock_mode =
+					intel_dp_drrs_initialize(
+						intel_dig_port,
+						intel_connector, fixed_mode);
 			break;
 		}
 	}
@@ -3732,7 +3783,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
 			fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
 	}
 
-	intel_panel_init(&intel_connector->panel, fixed_mode, NULL);
+	intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
 	intel_panel_setup_backlight(connector);
 
 	return true;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 6aa549a..c41c735 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -168,6 +168,9 @@ struct intel_panel {
 		bool active_low_pwm;
 		struct backlight_device *device;
 	} backlight;
+
+	bool edp_downclock_avail;
+	int edp_downclock;
 };
 
 struct intel_connector {
@@ -464,6 +467,22 @@ struct intel_hdmi {
 
 #define DP_MAX_DOWNSTREAM_PORTS		0x10
 
+/**
+ * HIGH_RR is the highest eDP panel refresh rate read from EDID
+ * LOW_RR is the lowest eDP panel refresh rate found from EDID
+ * parsing for same resolution.
+ */
+enum edp_drrs_refresh_rate_type {
+	DRRS_HIGH_RR,
+	DRRS_LOW_RR,
+	DRRS_MAX_RR, /* RR count */
+};
+
+struct drrs_info {
+	enum drrs_support_type type;
+	enum edp_drrs_refresh_rate_type refresh_rate_type;
+};
+
 struct intel_dp {
 	uint32_t output_reg;
 	uint32_t aux_ch_ctl_reg;
@@ -503,6 +522,7 @@ struct intel_dp {
 				     bool has_aux_irq,
 				     int send_bytes,
 				     uint32_t aux_clock_divider);
+	struct drrs_info drrs_state;
 };
 
 struct intel_digital_port {
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 3/5] drm/i915: Add support for DRRS to switch RR
  2014-02-14 10:02 [PATCH 0/5] v5: Enabling DRRS in the kernel Vandana Kannan
  2014-02-14 10:02 ` [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature Vandana Kannan
  2014-02-14 10:02 ` [PATCH 2/5] drm/i915: Parse EDID probed modes for DRRS support Vandana Kannan
@ 2014-02-14 10:02 ` Vandana Kannan
  2014-02-14 10:02 ` [PATCH 4/5] drm/i915: Idleness detection for DRRS Vandana Kannan
  2014-02-14 10:02 ` [PATCH 5/5] drm/i915/bdw: Add support for DRRS to switch RR Vandana Kannan
  4 siblings, 0 replies; 21+ messages in thread
From: Vandana Kannan @ 2014-02-14 10:02 UTC (permalink / raw)
  To: intel-gfx

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch computes and stored 2nd M/N/TU for switching to different
refresh rate dynamically. PIPECONF_EDP_RR_MODE_SWITCH bit helps toggle
between alternate refresh rates programmed in 2nd M/N/TU registers.

v2: Daniel's review comments
Computing M2/N2 in compute_config and storing it in crtc_config

v3: Modified reference to edp_downclock and edp_downclock_avail based on the
changes made to move them from dev_private to intel_panel.

v4: Modified references to is_drrs_supported based on the changes made to
rename it to drrs_support.

v5: Jani's review comments
Removed superfluous return statements. Changed support for Gen 7 and above.
Corrected indentation. Re-structured the code which finds crtc and connector
from encoder. Changed some logs to be less verbose.

Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h  |    6 +++
 drivers/gpu/drm/i915/i915_reg.h  |    1 +
 drivers/gpu/drm/i915/intel_dp.c  |  101 ++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h |    6 ++-
 4 files changed, 113 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6b4d0b20..3dd1d7e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -774,6 +774,11 @@ struct i915_fbc {
 	} no_fbc_reason;
 };
 
+struct i915_drrs {
+	struct intel_connector *connector;
+	struct intel_dp *dp;
+};
+
 struct i915_psr {
 	bool sink_support;
 	bool source_ok;
@@ -1466,6 +1471,7 @@ typedef struct drm_i915_private {
 	int num_plane;
 
 	struct i915_fbc fbc;
+	struct i915_drrs drrs;
 	struct intel_opregion opregion;
 	struct intel_vbt_data vbt;
 
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index f73a49d..bfd7703 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3225,6 +3225,7 @@
 #define   PIPECONF_INTERLACED_DBL_ILK		(4 << 21) /* ilk/snb only */
 #define   PIPECONF_PFIT_PF_INTERLACED_DBL_ILK	(5 << 21) /* ilk/snb only */
 #define   PIPECONF_INTERLACE_MODE_MASK		(7 << 21)
+#define   PIPECONF_EDP_RR_MODE_SWITCH		(1 << 20)
 #define   PIPECONF_CXSR_DOWNCLOCK	(1<<16)
 #define   PIPECONF_COLOR_RANGE_SELECT	(1 << 13)
 #define   PIPECONF_BPC_MASK	(0x7 << 5)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index f7dba83..1933675 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -832,6 +832,20 @@ intel_dp_set_clock(struct intel_encoder *encoder,
 	}
 }
 
+static void
+intel_dp_set_m2_n2(struct intel_crtc *crtc, struct intel_link_m_n *m_n)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	enum transcoder transcoder = crtc->config.cpu_transcoder;
+
+	I915_WRITE(PIPE_DATA_M2(transcoder),
+		TU_SIZE(m_n->tu) | m_n->gmch_m);
+	I915_WRITE(PIPE_DATA_N2(transcoder), m_n->gmch_n);
+	I915_WRITE(PIPE_LINK_M2(transcoder), m_n->link_m);
+	I915_WRITE(PIPE_LINK_N2(transcoder), m_n->link_n);
+}
+
 bool
 intel_dp_compute_config(struct intel_encoder *encoder,
 			struct intel_crtc_config *pipe_config)
@@ -936,6 +950,15 @@ found:
 			       pipe_config->port_clock,
 			       &pipe_config->dp_m_n);
 
+	if (intel_connector->panel.edp_downclock_avail &&
+		intel_dp->drrs_state.type == SEAMLESS_DRRS_SUPPORT) {
+			intel_link_compute_m_n(bpp, lane_count,
+				intel_connector->panel.edp_downclock,
+				pipe_config->port_clock,
+				&pipe_config->dp_m2_n2);
+	}
+
+
 	intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
 
 	return true;
@@ -3666,6 +3689,79 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
 		      I915_READ(pp_div_reg));
 }
 
+void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_encoder *encoder;
+	struct intel_dp *intel_dp = dev_priv->drrs.dp;
+	struct intel_crtc_config *config = NULL;
+	struct intel_crtc *intel_crtc = NULL;
+	struct intel_connector *intel_connector = dev_priv->drrs.connector;
+	u32 reg, val;
+	int index = 0;
+
+	if (refresh_rate <= 0) {
+		DRM_DEBUG_KMS("Refresh rate should be positive non-zero.\n");
+		return;
+	}
+
+	if (intel_dp == NULL) {
+		DRM_DEBUG_KMS("DRRS supported for eDP only.\n");
+		return;
+	}
+
+	encoder = intel_attached_encoder(&intel_connector->base);
+	intel_crtc = encoder->new_crtc;
+
+	if (!intel_crtc) {
+		DRM_DEBUG_KMS("DRRS: intel_crtc not initialized\n");
+		return;
+	}
+
+	config = &intel_crtc->config;
+
+	if (intel_dp->drrs_state.type < SEAMLESS_DRRS_SUPPORT) {
+		DRM_DEBUG_KMS("Seamless DRRS not supported.\n");
+		return;
+	}
+
+	if (intel_connector->panel.fixed_mode->vrefresh == refresh_rate)
+		index = DRRS_HIGH_RR;
+	else
+		index = DRRS_LOW_RR;
+
+	if (index == intel_dp->drrs_state.refresh_rate_type) {
+		DRM_DEBUG_KMS(
+			"DRRS requested for previously set RR...ignoring\n");
+		return;
+	}
+
+	if (!intel_crtc->active) {
+		DRM_DEBUG_KMS("eDP encoder has been disabled. CRTC not Active\n");
+		return;
+	}
+
+	mutex_lock(&intel_dp->drrs_state.mutex);
+
+	if (INTEL_INFO(dev)->gen > 6 && INTEL_INFO(dev)->gen < 8) {
+		reg = PIPECONF(intel_crtc->config.cpu_transcoder);
+		val = I915_READ(reg);
+		if (index > DRRS_HIGH_RR) {
+			val |= PIPECONF_EDP_RR_MODE_SWITCH;
+			intel_dp_set_m2_n2(intel_crtc, &config->dp_m2_n2);
+		} else {
+			val &= ~PIPECONF_EDP_RR_MODE_SWITCH;
+		}
+		I915_WRITE(reg, val);
+	}
+
+	intel_dp->drrs_state.refresh_rate_type = index;
+	DRM_DEBUG_KMS("eDP Refresh Rate set to : %dHz\n", refresh_rate);
+
+	mutex_unlock(&intel_dp->drrs_state.mutex);
+
+}
+
 static struct drm_display_mode *
 intel_dp_drrs_initialize(struct intel_digital_port *intel_dig_port,
 			struct intel_connector *intel_connector,
@@ -3700,6 +3796,11 @@ intel_dp_drrs_initialize(struct intel_digital_port *intel_dig_port,
 		intel_connector->panel.edp_downclock =
 			downclock_mode->clock;
 
+		dev_priv->drrs.connector = intel_connector;
+		dev_priv->drrs.dp = intel_dp;
+
+		mutex_init(&intel_dp->drrs_state.mutex);
+
 		intel_dp->drrs_state.type = dev_priv->vbt.drrs_type;
 
 		intel_dp->drrs_state.refresh_rate_type = DRRS_HIGH_RR;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c41c735..4f7c816 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -291,6 +291,9 @@ struct intel_crtc_config {
 	int pipe_bpp;
 	struct intel_link_m_n dp_m_n;
 
+	/* m2_n2 for eDP downclock */
+	struct intel_link_m_n dp_m2_n2;
+
 	/*
 	 * Frequence the dpll for the port should run at. Differs from the
 	 * adjusted dotclock e.g. for DP or 12bpc hdmi mode. This is also
@@ -481,6 +484,7 @@ enum edp_drrs_refresh_rate_type {
 struct drrs_info {
 	enum drrs_support_type type;
 	enum edp_drrs_refresh_rate_type refresh_rate_type;
+	struct mutex mutex;
 };
 
 struct intel_dp {
@@ -769,7 +773,7 @@ void intel_edp_panel_off(struct intel_dp *intel_dp);
 void intel_edp_psr_enable(struct intel_dp *intel_dp);
 void intel_edp_psr_disable(struct intel_dp *intel_dp);
 void intel_edp_psr_update(struct drm_device *dev);
-
+void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate);
 
 /* intel_dsi.c */
 bool intel_dsi_init(struct drm_device *dev);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 4/5]  drm/i915: Idleness detection for DRRS
  2014-02-14 10:02 [PATCH 0/5] v5: Enabling DRRS in the kernel Vandana Kannan
                   ` (2 preceding siblings ...)
  2014-02-14 10:02 ` [PATCH 3/5] drm/i915: Add support for DRRS to switch RR Vandana Kannan
@ 2014-02-14 10:02 ` Vandana Kannan
  2014-02-14 10:30   ` Chris Wilson
  2014-02-14 10:02 ` [PATCH 5/5] drm/i915/bdw: Add support for DRRS to switch RR Vandana Kannan
  4 siblings, 1 reply; 21+ messages in thread
From: Vandana Kannan @ 2014-02-14 10:02 UTC (permalink / raw)
  To: intel-gfx

Adding support to detect display idleness by tracking page flip from
user space. Switch to low refresh rate is triggered after 2 seconds of
idleness. The delay is configurable. If there is a page flip or call to
update the plane, then high refresh rate is applied.
The feature is not used in dual-display mode.

v2: Chris Wilson's review comments incorporated.
Modify idleness detection implementation to make it similar to the
implementation of intel_update_fbc/intel_disable_fbc

v3: Internal review comments incorporated
Add NULL pointer check in intel_disable_drrs.
Add drrs calls in i9xx_crtc_enable/disable and valleyview_crtc_enable.

v4: Jani's review comments incorporated.
Change in sequence in intel_update_drrs. Comment modified to remove details
of update param. Modified DRRS idleness interval to a module parameter.

Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |    6 ++
 drivers/gpu/drm/i915/i915_params.c   |    8 ++
 drivers/gpu/drm/i915/intel_display.c |   16 ++++
 drivers/gpu/drm/i915/intel_dp.c      |    9 +++
 drivers/gpu/drm/i915/intel_drv.h     |    5 +-
 drivers/gpu/drm/i915/intel_pm.c      |  134 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_sprite.c  |    2 +
 7 files changed, 179 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 3dd1d7e..8cb91d1 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -777,6 +777,11 @@ struct i915_fbc {
 struct i915_drrs {
 	struct intel_connector *connector;
 	struct intel_dp *dp;
+	struct intel_drrs_work {
+		struct delayed_work work;
+		struct drm_crtc *crtc;
+		int interval;
+	} *drrs_work;
 };
 
 struct i915_psr {
@@ -1976,6 +1981,7 @@ struct i915_params {
 	bool prefault_disable;
 	bool reset;
 	int invert_brightness;
+	int drrs_interval;
 };
 extern struct i915_params i915 __read_mostly;
 
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index c743057..69f8b83 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -47,6 +47,7 @@ struct i915_params i915 __read_mostly = {
 	.prefault_disable = 0,
 	.reset = true,
 	.invert_brightness = 0,
+	.drrs_interval = 2000,
 };
 
 module_param_named(modeset, i915.modeset, int, 0400);
@@ -153,3 +154,10 @@ MODULE_PARM_DESC(invert_brightness,
 	"report PCI device ID, subsystem vendor and subsystem device ID "
 	"to dri-devel@lists.freedesktop.org, if your machine needs it. "
 	"It will then be included in an upcoming module version.");
+
+module_param_named(drrs_interval, i915.drrs_interval, int, 0600);
+MODULE_PARM_DESC(drrs_interval,
+	"DRRS idleness detection interval  (default: 2000 ms)."
+	"If this field is set to 0, then seamless DRRS feature "
+	"based on idleness detection is disabled."
+	"The interval is to be set in milliseconds.");
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4d4a0d9..86cd603 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2410,6 +2410,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 	}
 
 	intel_update_fbc(dev);
+	intel_update_drrs(dev);
 	intel_edp_psr_update(dev);
 	mutex_unlock(&dev->struct_mutex);
 
@@ -3598,6 +3599,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 
 	mutex_lock(&dev->struct_mutex);
 	intel_update_fbc(dev);
+	intel_update_drrs(dev);
 	mutex_unlock(&dev->struct_mutex);
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
@@ -3639,6 +3641,7 @@ static void haswell_crtc_enable_planes(struct drm_crtc *crtc)
 
 	mutex_lock(&dev->struct_mutex);
 	intel_update_fbc(dev);
+	intel_update_drrs(dev);
 	mutex_unlock(&dev->struct_mutex);
 }
 
@@ -3845,6 +3848,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
 
 	mutex_lock(&dev->struct_mutex);
 	intel_update_fbc(dev);
+	intel_update_drrs(dev);
 	mutex_unlock(&dev->struct_mutex);
 }
 
@@ -3892,6 +3896,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
 
 	mutex_lock(&dev->struct_mutex);
 	intel_update_fbc(dev);
+	intel_update_drrs(dev);
 	mutex_unlock(&dev->struct_mutex);
 }
 
@@ -4176,6 +4181,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
 	intel_crtc_update_cursor(crtc, true);
 
 	intel_update_fbc(dev);
+	intel_update_drrs(dev);
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
 		encoder->enable(encoder);
@@ -4221,6 +4227,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
 	intel_crtc_dpms_overlay(intel_crtc, true);
 
 	intel_update_fbc(dev);
+	intel_update_drrs(dev);
 
 	for_each_encoder_on_crtc(dev, crtc, encoder)
 		encoder->enable(encoder);
@@ -4286,6 +4293,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
 	intel_update_watermarks(crtc);
 
 	intel_update_fbc(dev);
+	intel_update_drrs(dev);
 }
 
 static void i9xx_crtc_off(struct drm_crtc *crtc)
@@ -8281,6 +8289,10 @@ static void intel_unpin_work_fn(struct work_struct *__work)
 	drm_gem_object_unreference(&work->pending_flip_obj->base);
 	drm_gem_object_unreference(&work->old_fb_obj->base);
 
+	/* disable current DRRS work scheduled and restart
+	 * to push work by another x seconds
+	 */
+	intel_update_drrs(dev);
 	intel_update_fbc(dev);
 	mutex_unlock(&dev->struct_mutex);
 
@@ -8722,6 +8734,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 		goto cleanup_pending;
 
 	intel_disable_fbc(dev);
+	intel_disable_drrs(dev);
 	intel_mark_fb_busy(obj, NULL);
 	mutex_unlock(&dev->struct_mutex);
 
@@ -11055,6 +11068,7 @@ void intel_modeset_init(struct drm_device *dev)
 
 	/* Just in case the BIOS is doing something questionable. */
 	intel_disable_fbc(dev);
+	intel_disable_drrs(dev);
 }
 
 static void
@@ -11461,6 +11475,8 @@ void intel_modeset_cleanup(struct drm_device *dev)
 
 	intel_disable_fbc(dev);
 
+	intel_disable_drrs(dev);
+
 	intel_disable_gt_powersave(dev);
 
 	ironlake_teardown_rc6(dev);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 1933675..3407af6 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3411,11 +3411,17 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
 	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
 	struct intel_dp *intel_dp = &intel_dig_port->dp;
 	struct drm_device *dev = intel_dp_to_dev(intel_dp);
+	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	i2c_del_adapter(&intel_dp->adapter);
 	drm_encoder_cleanup(encoder);
 	if (is_edp(intel_dp)) {
 		cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
+		/* DRRS cleanup */
+		if (intel_dp->drrs_state.type == SEAMLESS_DRRS_SUPPORT) {
+			kfree(dev_priv->drrs.drrs_work);
+			dev_priv->drrs.drrs_work = NULL;
+		}
 		mutex_lock(&dev->mode_config.mutex);
 		edp_panel_vdd_off_sync(intel_dp);
 		mutex_unlock(&dev->mode_config.mutex);
@@ -3799,6 +3805,9 @@ intel_dp_drrs_initialize(struct intel_digital_port *intel_dig_port,
 		dev_priv->drrs.connector = intel_connector;
 		dev_priv->drrs.dp = intel_dp;
 
+		intel_init_drrs_idleness_detection(dev,
+			intel_connector, intel_dp);
+
 		mutex_init(&intel_dp->drrs_state.mutex);
 
 		intel_dp->drrs_state.type = dev_priv->vbt.drrs_type;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 4f7c816..c8d6aa2 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -911,7 +911,10 @@ void intel_runtime_pm_put(struct drm_i915_private *dev_priv);
 void intel_init_runtime_pm(struct drm_i915_private *dev_priv);
 void intel_fini_runtime_pm(struct drm_i915_private *dev_priv);
 void ilk_wm_get_hw_state(struct drm_device *dev);
-
+void intel_init_drrs_idleness_detection(struct drm_device *dev,
+		struct intel_connector *connector, struct intel_dp *dp);
+void intel_update_drrs(struct drm_device *dev);
+void intel_disable_drrs(struct drm_device *dev);
 
 /* intel_sdvo.c */
 bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 9ab3883..2b84864 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -618,6 +618,140 @@ out_disable:
 	i915_gem_stolen_cleanup_compression(dev);
 }
 
+static void intel_drrs_work_fn(struct work_struct *__work)
+{
+	struct intel_drrs_work *work =
+		container_of(to_delayed_work(__work),
+			     struct intel_drrs_work, work);
+	struct drm_device *dev = work->crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	intel_dp_set_drrs_state(work->crtc->dev,
+		dev_priv->drrs.connector->panel.downclock_mode->vrefresh);
+}
+
+static void intel_cancel_drrs_work(struct drm_i915_private *dev_priv)
+{
+	if (dev_priv->drrs.drrs_work == NULL)
+		return;
+
+	DRM_DEBUG_KMS("cancelling pending DRRS enable\n");
+
+	cancel_delayed_work_sync(&dev_priv->drrs.drrs_work->work);
+}
+
+static void intel_enable_drrs(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	intel_cancel_drrs_work(dev_priv);
+
+	if (dev_priv->drrs.dp->drrs_state.refresh_rate_type
+							!= DRRS_LOW_RR) {
+		dev_priv->drrs.drrs_work->crtc = crtc;
+
+		/* Delay the actual enabling to let pageflipping cease and the
+		 * display to settle before starting DRRS
+		 */
+		schedule_delayed_work(&dev_priv->drrs.drrs_work->work,
+			msecs_to_jiffies(dev_priv->drrs.drrs_work->interval));
+	}
+}
+
+void intel_disable_drrs(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->drrs.dp == NULL) {
+		DRM_DEBUG_KMS("DRRS is not supported.\n");
+		return;
+	}
+
+	/* as part of disable DRRS, reset refresh rate to HIGH_RR */
+	if (dev_priv->drrs.dp->drrs_state.refresh_rate_type
+							== DRRS_LOW_RR) {
+		intel_cancel_drrs_work(dev_priv);
+		intel_dp_set_drrs_state(dev,
+			dev_priv->drrs.connector->panel.fixed_mode->vrefresh);
+	}
+}
+
+/**
+ * intel_update_drrs - enable/disable DRRS as needed
+ * @dev: the drm_device
+*/
+void intel_update_drrs(struct drm_device *dev)
+{
+	struct drm_crtc *crtc = NULL, *tmp_crtc;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* if drrs.connector is NULL, then drrs_init did not get called.
+	 * which means DRRS is not supported.
+	 */
+	if (dev_priv->drrs.connector == NULL) {
+		DRM_DEBUG_KMS("DRRS is not supported.\n");
+		return;
+	}
+
+	if (dev_priv->drrs.connector->panel.downclock_mode == NULL) {
+		DRM_DEBUG_KMS(
+			"No downclock mode found. DRRS not supported\n");
+		return;
+	}
+
+	list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) {
+		if (tmp_crtc != NULL && intel_crtc_active(tmp_crtc) &&
+		    to_intel_crtc(tmp_crtc)->primary_enabled) {
+			if (crtc) {
+				DRM_DEBUG_KMS(
+				"more than one pipe active, disabling DRRS\n");
+				intel_disable_drrs(dev);
+				return;
+			}
+			crtc = tmp_crtc;
+		}
+	}
+
+	if (crtc == NULL) {
+		DRM_DEBUG_KMS("DRRS: crtc not initialized\n");
+		return;
+	}
+
+	intel_disable_drrs(dev);
+
+	/* re-enable idleness detection */
+	intel_enable_drrs(crtc);
+}
+
+void intel_init_drrs_idleness_detection(struct drm_device *dev,
+					struct intel_connector *connector,
+					struct intel_dp *dp)
+{
+	struct intel_drrs_work *work;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (i915.drrs_interval == 0) {
+		DRM_INFO("DRRS disable by flag\n");
+		dev_priv->drrs.connector = NULL;
+		dev_priv->drrs.dp = NULL;
+		return;
+	}
+
+	work = kzalloc(sizeof(struct intel_drrs_work), GFP_KERNEL);
+	if (!work) {
+		DRM_ERROR("Failed to allocate DRRS work structure\n");
+		dev_priv->drrs.connector = NULL;
+		dev_priv->drrs.dp = NULL;
+		return;
+	}
+
+	work->interval = i915.drrs_interval;
+	INIT_DELAYED_WORK(&work->work, intel_drrs_work_fn);
+
+	dev_priv->drrs.drrs_work = work;
+}
+
 static void i915_pineview_get_mem_freq(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 336ae6c..6c465cd 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -547,6 +547,7 @@ intel_enable_primary(struct drm_crtc *crtc)
 
 	mutex_lock(&dev->struct_mutex);
 	intel_update_fbc(dev);
+	intel_update_drrs(dev);
 	mutex_unlock(&dev->struct_mutex);
 }
 
@@ -566,6 +567,7 @@ intel_disable_primary(struct drm_crtc *crtc)
 	mutex_lock(&dev->struct_mutex);
 	if (dev_priv->fbc.plane == intel_crtc->plane)
 		intel_disable_fbc(dev);
+	intel_disable_drrs(dev);
 	mutex_unlock(&dev->struct_mutex);
 
 	/*
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 5/5] drm/i915/bdw: Add support for DRRS to switch RR
  2014-02-14 10:02 [PATCH 0/5] v5: Enabling DRRS in the kernel Vandana Kannan
                   ` (3 preceding siblings ...)
  2014-02-14 10:02 ` [PATCH 4/5] drm/i915: Idleness detection for DRRS Vandana Kannan
@ 2014-02-14 10:02 ` Vandana Kannan
  4 siblings, 0 replies; 21+ messages in thread
From: Vandana Kannan @ 2014-02-14 10:02 UTC (permalink / raw)
  To: intel-gfx

For Broadwell, there is one instance of Transcoder MN values per transcoder.
For dynamic switching between multiple refreshr rates, M/N values may be
reprogrammed on the fly. Link N programming triggers update of all data and
link M & N registers and the new M/N values will be used in the next frame
that is output.

v2: Incorporated Chris's review comments
Changed to check for gen >=8 or gen > 5 before setting M/N registers

v3: Incorporated Jani's review comments
Re-use cpu_transcoder_set_m_n for BDW.

Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |    2 +-
 drivers/gpu/drm/i915/intel_dp.c      |   25 +++++++++++++++++++------
 drivers/gpu/drm/i915/intel_drv.h     |    2 ++
 3 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 86cd603..64ed4e3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4901,7 +4901,7 @@ static void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc,
 	I915_WRITE(PCH_TRANS_LINK_N1(pipe), m_n->link_n);
 }
 
-static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
+void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
 					 struct intel_link_m_n *m_n)
 {
 	struct drm_device *dev = crtc->base.dev;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 3407af6..0cfba6b 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -839,11 +839,15 @@ intel_dp_set_m2_n2(struct intel_crtc *crtc, struct intel_link_m_n *m_n)
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	enum transcoder transcoder = crtc->config.cpu_transcoder;
 
-	I915_WRITE(PIPE_DATA_M2(transcoder),
-		TU_SIZE(m_n->tu) | m_n->gmch_m);
-	I915_WRITE(PIPE_DATA_N2(transcoder), m_n->gmch_n);
-	I915_WRITE(PIPE_LINK_M2(transcoder), m_n->link_m);
-	I915_WRITE(PIPE_LINK_N2(transcoder), m_n->link_n);
+	if (INTEL_INFO(dev)->gen >= 8) {
+		intel_cpu_transcoder_set_m_n(crtc, m_n);
+	} else if (INTEL_INFO(dev)->gen > 6) {
+		I915_WRITE(PIPE_DATA_M2(transcoder),
+			TU_SIZE(m_n->tu) | m_n->gmch_m);
+		I915_WRITE(PIPE_DATA_N2(transcoder), m_n->gmch_n);
+		I915_WRITE(PIPE_LINK_M2(transcoder), m_n->link_m);
+		I915_WRITE(PIPE_LINK_N2(transcoder), m_n->link_n);
+	}
 }
 
 bool
@@ -3749,7 +3753,16 @@ void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
 
 	mutex_lock(&intel_dp->drrs_state.mutex);
 
-	if (INTEL_INFO(dev)->gen > 6 && INTEL_INFO(dev)->gen < 8) {
+	if (INTEL_INFO(dev)->gen >= 8) {
+		switch (index) {
+		case DRRS_HIGH_RR:
+			intel_dp_set_m2_n2(intel_crtc, &config->dp_m_n);
+			break;
+		case DRRS_LOW_RR:
+			intel_dp_set_m2_n2(intel_crtc, &config->dp_m2_n2);
+			break;
+		};
+	} else if (INTEL_INFO(dev)->gen > 6) {
 		reg = PIPECONF(intel_crtc->config.cpu_transcoder);
 		val = I915_READ(reg);
 		if (index > DRRS_HIGH_RR) {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c8d6aa2..4da5abc 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -751,6 +751,8 @@ void hsw_enable_ips(struct intel_crtc *crtc);
 void hsw_disable_ips(struct intel_crtc *crtc);
 void intel_display_set_init_power(struct drm_device *dev, bool enable);
 int valleyview_get_vco(struct drm_i915_private *dev_priv);
+void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc,
+				struct intel_link_m_n *m_n);
 
 /* intel_dp.c */
 void intel_dp_init(struct drm_device *dev, int output_reg, enum port port);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 4/5]  drm/i915: Idleness detection for DRRS
  2014-02-14 10:02 ` [PATCH 4/5] drm/i915: Idleness detection for DRRS Vandana Kannan
@ 2014-02-14 10:30   ` Chris Wilson
  0 siblings, 0 replies; 21+ messages in thread
From: Chris Wilson @ 2014-02-14 10:30 UTC (permalink / raw)
  To: Vandana Kannan; +Cc: intel-gfx

On Fri, Feb 14, 2014 at 03:32:21PM +0530, Vandana Kannan wrote:
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 1933675..3407af6 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3411,11 +3411,17 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder)
>  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
>  	struct intel_dp *intel_dp = &intel_dig_port->dp;
>  	struct drm_device *dev = intel_dp_to_dev(intel_dp);
> +	struct drm_i915_private *dev_priv = dev->dev_private;
>  
>  	i2c_del_adapter(&intel_dp->adapter);
>  	drm_encoder_cleanup(encoder);
>  	if (is_edp(intel_dp)) {
>  		cancel_delayed_work_sync(&intel_dp->panel_vdd_work);
> +		/* DRRS cleanup */
> +		if (intel_dp->drrs_state.type == SEAMLESS_DRRS_SUPPORT) {
> +			kfree(dev_priv->drrs.drrs_work);
> +			dev_priv->drrs.drrs_work = NULL;
> +		}

This is dangerous.

 if (dp == dev_priv->drrs.dp) {
   intel_drrs_disable();
   cancel_delayed_work_sync(&dev_priv->drrs.work);
   dev_priv->drrs.dp = NULL;
 }
(call this intel_dp_drrs_fini(dev_priv, dp) rather than touching
dev_priv here - lets try to keep the layering violations to a minimum)

and just embed the drrs work into dev_priv.

Also try to spot the bug in the above logic I just wrote. Caveat lector.

>  		mutex_lock(&dev->mode_config.mutex);
>  		edp_panel_vdd_off_sync(intel_dp);
>  		mutex_unlock(&dev->mode_config.mutex);
> @@ -3799,6 +3805,9 @@ intel_dp_drrs_initialize(struct intel_digital_port *intel_dig_port,
>  		dev_priv->drrs.connector = intel_connector;
>  		dev_priv->drrs.dp = intel_dp;
>  
> +		intel_init_drrs_idleness_detection(dev,
> +			intel_connector, intel_dp);
> +

And this is just plain ugly.

intel_dp is a synoym for intel_connector, so we only need one of them.
You are setting dev_priv state outside of the init() routine only to
clear it inside, and pass all the state you set into the init() routine.

initialize()! Just use init() like everywhere else.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature
  2014-02-14 10:02 ` [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature Vandana Kannan
@ 2014-02-14 16:39   ` Jesse Barnes
  0 siblings, 0 replies; 21+ messages in thread
From: Jesse Barnes @ 2014-02-14 16:39 UTC (permalink / raw)
  To: Vandana Kannan; +Cc: intel-gfx

On Fri, 14 Feb 2014 15:32:18 +0530
Vandana Kannan <vandana.kannan@intel.com> wrote:

> From: Pradeep Bhat <pradeep.bhat@intel.com>
> 
> This patch reads the DRRS support and Mode type from VBT fields.
> The read information will be stored in VBT struct during BIOS
> parsing. The above functionality is needed for decision making
> whether DRRS feature is supported in i915 driver for eDP panels.
> This information helps us decide if seamless DRRS can be done
> at runtime to support certain power saving features. This patch
> was tested by setting necessary bit in VBT struct and merging
> the new VBT with system BIOS so that we can read the value.
> 
> v2: Incorporated review comments from Chris Wilson
> Removed "intel_" as a prefix for DRRS specific declarations.
> 
> v3: Incorporated Jani's review comments
> Removed function which deducts drrs mode from panel_type. Modified some
> print statements. Made changes to use DRRS_NOT_SUPPORTED as 0 instead of -1.
> 
> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
> Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h   |   13 +++++++++++++
>  drivers/gpu/drm/i915/intel_bios.c |   29 +++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_bios.h |   29 +++++++++++++++++++++++++++++
>  3 files changed, 71 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 728b9c3..6b4d0b20 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1218,6 +1218,12 @@ struct ddi_vbt_port_info {
>  	uint8_t supports_dp:1;
>  };
>  
> +enum drrs_support_type {
> +	DRRS_NOT_SUPPORTED = 0,
> +	STATIC_DRRS_SUPPORT = 1,
> +	SEAMLESS_DRRS_SUPPORT = 2
> +};
> +
>  struct intel_vbt_data {
>  	struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
>  	struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
> @@ -1233,6 +1239,13 @@ struct intel_vbt_data {
>  	int lvds_ssc_freq;
>  	unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
>  
> +	/*
> +	 * DRRS support type (Seamless OR Static DRRS OR not supported)
> +	 * drrs_support type Val 0x2 is Seamless DRRS and 0 is Static DRRS.
> +	 * These values correspond to the VBT values for drrs mode.
> +	 */
> +	enum drrs_support_type drrs_type;
> +
>  	/* eDP */
>  	int edp_rate;
>  	int edp_lanes;
> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
> index 86b95ca..2414eca 100644
> --- a/drivers/gpu/drm/i915/intel_bios.c
> +++ b/drivers/gpu/drm/i915/intel_bios.c
> @@ -218,6 +218,25 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv,
>  
>  	panel_type = lvds_options->panel_type;
>  
> +	dev_priv->vbt.drrs_type = (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
> +	 * to match the enum drrs_support_type.
> +	 */
> +	switch (dev_priv->vbt.drrs_type) {
> +	case 0:
> +		dev_priv->vbt.drrs_type = STATIC_DRRS_SUPPORT;
> +		DRM_DEBUG_KMS("DRRS supported mode is static\n");
> +		break;
> +	case 2:
> +		DRM_DEBUG_KMS("DRRS supported mode is seamless\n");
> +		break;
> +	default:
> +		break;
> +	}
> +
>  	lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
>  	if (!lvds_lfp_data)
>  		return;
> @@ -516,6 +535,16 @@ parse_driver_features(struct drm_i915_private *dev_priv,
>  
>  	if (driver->dual_frequency)
>  		dev_priv->render_reclock_avail = true;
> +
> +	DRM_DEBUG_KMS("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)
> +		dev_priv->vbt.drrs_type = driver->drrs_enabled;
>  }
>  
>  static void
> diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
> index 282de5e..5505d6c 100644
> --- a/drivers/gpu/drm/i915/intel_bios.h
> +++ b/drivers/gpu/drm/i915/intel_bios.h
> @@ -281,6 +281,9 @@ struct bdb_general_definitions {
>  	union child_device_config devices[0];
>  } __packed;
>  
> +/* Mask for DRRS / Panel Channel / SSC / BLT control bits extraction */
> +#define MODE_MASK		0x3
> +
>  struct bdb_lvds_options {
>  	u8 panel_type;
>  	u8 rsvd1;
> @@ -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;
>  } __packed;
>  
>  /* LFP pointer table contains entries to the struct below */
> @@ -478,6 +493,20 @@ struct bdb_driver_features {
>  
>  	u8 hdmi_termination;
>  	u8 custom_vbt_version;
> +	/* Driver features data block */
> +	u16 rmpm_enabled:1;
> +	u16 s2ddt_enabled:1;
> +	u16 dpst_enabled:1;
> +	u16 bltclt_enabled:1;
> +	u16 adb_enabled:1;
> +	u16 drrs_enabled:1;
> +	u16 grs_enabled:1;
> +	u16 gpmt_enabled:1;
> +	u16 tbt_enabled:1;
> +	u16 psr_enabled:1;
> +	u16 ips_enabled:1;
> +	u16 reserved3:4;
> +	u16 pc_feature_valid:1;
>  } __packed;
>  
>  #define EDP_18BPP	0

Since I can't trust the VBT doc I have, I assume this has been tested
on real machines and works.

So:
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>

The VBT choosing 0 for static and 2 for seamless is a bit annoying, but
I guess there's not much we can do about that now...

-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature
  2014-02-03  3:43         ` Vandana Kannan
@ 2014-02-04 10:34           ` Daniel Vetter
  0 siblings, 0 replies; 21+ messages in thread
From: Daniel Vetter @ 2014-02-04 10:34 UTC (permalink / raw)
  To: Vandana Kannan; +Cc: intel-gfx

On Mon, Feb 03, 2014 at 09:13:17AM +0530, Vandana Kannan wrote:
> > Again, everywhere else in intel_bios.c we use panel_type, directly as it
> > is in VBT, 0-based. Are you saying it's all wrong? panel_type can't be
> > 1-based in this one instance, and 0-based in all other instances, right?
> > 
> > This is actually the first priority to check.
> > 
> I have discussed with the author of the patch and i will modify this to
> make panel_type 0-based.

Can we drag the author of the patch itself into this discussion, here on
intel-gfx? Generally round-trip is much faster if we cut out as many
middlemen as possible ...

This is just a general upstreaming bkm.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature
  2014-01-30  6:20       ` Jani Nikula
@ 2014-02-03  3:43         ` Vandana Kannan
  2014-02-04 10:34           ` Daniel Vetter
  0 siblings, 1 reply; 21+ messages in thread
From: Vandana Kannan @ 2014-02-03  3:43 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Jan-30-2014 11:50 AM, Jani Nikula wrote:
> On Thu, 30 Jan 2014, Vandana Kannan <vandana.kannan@intel.com> wrote:
>> On Jan-22-2014 6:39 PM, Jani Nikula wrote:
>>> On Mon, 23 Dec 2013, Vandana Kannan <vandana.kannan@intel.com> wrote:
>>>> From: Pradeep Bhat <pradeep.bhat@intel.com>
>>>>
>>>> This patch reads the DRRS support and Mode type from VBT fields.
>>>> The read information will be stored in VBT struct during BIOS
>>>> parsing. The above functionality is needed for decision making
>>>> whether DRRS feature is supported in i915 driver for eDP panels.
>>>> This information helps us decide if seamless DRRS can be done
>>>> at runtime to support certain power saving features. This patch
>>>> was tested by setting necessary bit in VBT struct and merging
>>>> the new VBT with system BIOS so that we can read the value.
>>>>
>>>> v2: Incorporated review comments from Chris Wilson
>>>> Removed "intel_" as a prefix for DRRS specific declarations.
>>>>
>>>> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
>>>> Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
>>>> ---
>>>>  drivers/gpu/drm/i915/i915_drv.h   |    9 +++++++++
>>>>  drivers/gpu/drm/i915/intel_bios.c |   23 +++++++++++++++++++++++
>>>>  drivers/gpu/drm/i915/intel_bios.h |   29 +++++++++++++++++++++++++++++
>>>>  3 files changed, 61 insertions(+)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>>>> index ae2c80c..f8fd045 100644
>>>> --- a/drivers/gpu/drm/i915/i915_drv.h
>>>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>>>> @@ -1174,6 +1174,15 @@ struct intel_vbt_data {
>>>>  	int lvds_ssc_freq;
>>>>  	unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
>>>>  
>>>> +	/**
>>>
>>> This is not a kerneldoc comment, so drop the extra *.
>>>
>> Ok.
>>>> +	 * 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;
>>>
>>> Both the drrs_mode and drrs_enabled should be replaced by one enum
>>> drrs_support_type which you introduce later. It's all self-explanatory
>>> that way, and you don't need to explain so much.
>>>
>> There are 2 options in the VBT. drrs_enabled to check if DRRS is
>> supported, drrs_mode to show which type. It has been added here as it is
>> for readability.
> 
> I can understand the argument for anything defined in intel_bios.[ch],
> but for the rest, including struct intel_vbt_data, readability comes
> from other reasons than being equivalent with the VBT specs.
> 
>>>> +
>>>>  	/* eDP */
>>>>  	int edp_rate;
>>>>  	int edp_lanes;
>>>> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
>>>> index f88e507..5b04a69 100644
>>>> --- a/drivers/gpu/drm/i915/intel_bios.c
>>>> +++ b/drivers/gpu/drm/i915/intel_bios.c
>>>> @@ -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;
>>>
>>> Everywhere else in intel_bios.c panel_type is used 0-based.
>>>
>> VBT indexes panel type as 1,2,3. Therefore, we have to make the change
>> to match kernel's 0-based usage.
> 
> Again, everywhere else in intel_bios.c we use panel_type, directly as it
> is in VBT, 0-based. Are you saying it's all wrong? panel_type can't be
> 1-based in this one instance, and 0-based in all other instances, right?
> 
> This is actually the first priority to check.
> 
I have discussed with the author of the patch and i will modify this to
make panel_type 0-based.
>>>> +}
>>>
>>> You use the above function only once. IMHO with all the explaining above
>>> it's just too much of a burden to the reader. Just do this in the code.
>>>
>> Ok.
>>>> +
>>>>  /* 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",
>>>                                              ^ drop the space here
>>>
>> Ok
>>>> +			(dev_priv->vbt.drrs_mode == 0) ? "STATIC" : "SEAMLESS");
>>>
>>> Why shouting?
>>>
>>>> +
>>>>  	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);
>>>                                          ^ and here and everywhere
>>>
>> Ok
>>>>  }
>>>>  
>>>>  static void
>>>> diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
>>>> index 81ed58c..0a3a751 100644
>>>> --- a/drivers/gpu/drm/i915/intel_bios.h
>>>> +++ b/drivers/gpu/drm/i915/intel_bios.h
>>>> @@ -281,6 +281,9 @@ struct bdb_general_definitions {
>>>>  	union child_device_config devices[0];
>>>>  } __packed;
>>>>  
>>>> +/* Mask for DRRS / Panel Channel / SSC / BLT control bits extraction */
>>>> +#define MODE_MASK		0x3
>>>> +
>>>>  struct bdb_lvds_options {
>>>>  	u8 panel_type;
>>>>  	u8 rsvd1;
>>>> @@ -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;
>>>
>>> Why does this have "lvds" but the rest not? Why do some fields end in
>>> "bits" but some others not? Some consistency please.
>>>
>> This is how the vbt block definition doc mentions each of these fields.
>> This is the reason why it has been added in this manner.
> 
> I don't have my vbt spec handy right now, but when I was last checking
> these it didn't look consistent with the spec.
> 
> Same for the ones below.
> 
VBT-driver interface document has been referred for this.
>>
>>>> +	/* 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;
>>>
>>> I really *really* wish I knew why some stuff is specified in the lvds
>>> bios blob and some other in edp blob and some stuff specified here is
>>> used in the edp side. Ugh. I wonder if we should check this
>>> panel_color_depth for edp too.
>>>
>> This is how the vbt block definition doc mentions each of these fields.
>> This is the reason why it has been added in this manner.
>>
>>>> +	/* LVDS panel type bits stored here */
>>>> +	u32 dps_panel_type_bits;
>>>> +	/* LVDS backlight control type bits stored here */
>>>> +	u32 blt_control_type_bits;
>>>>  } __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;
>>>
>>> All of the above should be foo_enabled to make them self-explanatory.
>>>
>>>> +	u16 reserved3:4;
>>>> +	u16 pc_feature_validity:1;
>>>
>>> Similarly for this one, should be pc_feature_valid.
>>>
>> This is how the vbt block definition doc mentions this field.
>> This is the reason why it has been added in this manner.
>>>>  } __packed;
>>>>  
>>>>  #define EDP_18BPP	0
>>>> -- 
>>>> 1.7.9.5
>>>>
>>>> _______________________________________________
>>>> Intel-gfx mailing list
>>>> Intel-gfx@lists.freedesktop.org
>>>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>>
>>
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature
  2014-01-30  3:29     ` Vandana Kannan
@ 2014-01-30  6:20       ` Jani Nikula
  2014-02-03  3:43         ` Vandana Kannan
  0 siblings, 1 reply; 21+ messages in thread
From: Jani Nikula @ 2014-01-30  6:20 UTC (permalink / raw)
  To: Vandana Kannan; +Cc: intel-gfx

On Thu, 30 Jan 2014, Vandana Kannan <vandana.kannan@intel.com> wrote:
> On Jan-22-2014 6:39 PM, Jani Nikula wrote:
>> On Mon, 23 Dec 2013, Vandana Kannan <vandana.kannan@intel.com> wrote:
>>> From: Pradeep Bhat <pradeep.bhat@intel.com>
>>>
>>> This patch reads the DRRS support and Mode type from VBT fields.
>>> The read information will be stored in VBT struct during BIOS
>>> parsing. The above functionality is needed for decision making
>>> whether DRRS feature is supported in i915 driver for eDP panels.
>>> This information helps us decide if seamless DRRS can be done
>>> at runtime to support certain power saving features. This patch
>>> was tested by setting necessary bit in VBT struct and merging
>>> the new VBT with system BIOS so that we can read the value.
>>>
>>> v2: Incorporated review comments from Chris Wilson
>>> Removed "intel_" as a prefix for DRRS specific declarations.
>>>
>>> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
>>> Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
>>> ---
>>>  drivers/gpu/drm/i915/i915_drv.h   |    9 +++++++++
>>>  drivers/gpu/drm/i915/intel_bios.c |   23 +++++++++++++++++++++++
>>>  drivers/gpu/drm/i915/intel_bios.h |   29 +++++++++++++++++++++++++++++
>>>  3 files changed, 61 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>>> index ae2c80c..f8fd045 100644
>>> --- a/drivers/gpu/drm/i915/i915_drv.h
>>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>>> @@ -1174,6 +1174,15 @@ struct intel_vbt_data {
>>>  	int lvds_ssc_freq;
>>>  	unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
>>>  
>>> +	/**
>> 
>> This is not a kerneldoc comment, so drop the extra *.
>> 
> Ok.
>>> +	 * 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;
>> 
>> Both the drrs_mode and drrs_enabled should be replaced by one enum
>> drrs_support_type which you introduce later. It's all self-explanatory
>> that way, and you don't need to explain so much.
>> 
> There are 2 options in the VBT. drrs_enabled to check if DRRS is
> supported, drrs_mode to show which type. It has been added here as it is
> for readability.

I can understand the argument for anything defined in intel_bios.[ch],
but for the rest, including struct intel_vbt_data, readability comes
from other reasons than being equivalent with the VBT specs.

>>> +
>>>  	/* eDP */
>>>  	int edp_rate;
>>>  	int edp_lanes;
>>> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
>>> index f88e507..5b04a69 100644
>>> --- a/drivers/gpu/drm/i915/intel_bios.c
>>> +++ b/drivers/gpu/drm/i915/intel_bios.c
>>> @@ -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;
>> 
>> Everywhere else in intel_bios.c panel_type is used 0-based.
>> 
> VBT indexes panel type as 1,2,3. Therefore, we have to make the change
> to match kernel's 0-based usage.

Again, everywhere else in intel_bios.c we use panel_type, directly as it
is in VBT, 0-based. Are you saying it's all wrong? panel_type can't be
1-based in this one instance, and 0-based in all other instances, right?

This is actually the first priority to check.

>>> +}
>> 
>> You use the above function only once. IMHO with all the explaining above
>> it's just too much of a burden to the reader. Just do this in the code.
>> 
> Ok.
>>> +
>>>  /* 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",
>>                                              ^ drop the space here
>> 
> Ok
>>> +			(dev_priv->vbt.drrs_mode == 0) ? "STATIC" : "SEAMLESS");
>> 
>> Why shouting?
>> 
>>> +
>>>  	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);
>>                                          ^ and here and everywhere
>> 
> Ok
>>>  }
>>>  
>>>  static void
>>> diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
>>> index 81ed58c..0a3a751 100644
>>> --- a/drivers/gpu/drm/i915/intel_bios.h
>>> +++ b/drivers/gpu/drm/i915/intel_bios.h
>>> @@ -281,6 +281,9 @@ struct bdb_general_definitions {
>>>  	union child_device_config devices[0];
>>>  } __packed;
>>>  
>>> +/* Mask for DRRS / Panel Channel / SSC / BLT control bits extraction */
>>> +#define MODE_MASK		0x3
>>> +
>>>  struct bdb_lvds_options {
>>>  	u8 panel_type;
>>>  	u8 rsvd1;
>>> @@ -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;
>> 
>> Why does this have "lvds" but the rest not? Why do some fields end in
>> "bits" but some others not? Some consistency please.
>> 
> This is how the vbt block definition doc mentions each of these fields.
> This is the reason why it has been added in this manner.

I don't have my vbt spec handy right now, but when I was last checking
these it didn't look consistent with the spec.

Same for the ones below.

>
>>> +	/* 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;
>> 
>> I really *really* wish I knew why some stuff is specified in the lvds
>> bios blob and some other in edp blob and some stuff specified here is
>> used in the edp side. Ugh. I wonder if we should check this
>> panel_color_depth for edp too.
>>
> This is how the vbt block definition doc mentions each of these fields.
> This is the reason why it has been added in this manner.
>
>>> +	/* LVDS panel type bits stored here */
>>> +	u32 dps_panel_type_bits;
>>> +	/* LVDS backlight control type bits stored here */
>>> +	u32 blt_control_type_bits;
>>>  } __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;
>> 
>> All of the above should be foo_enabled to make them self-explanatory.
>> 
>>> +	u16 reserved3:4;
>>> +	u16 pc_feature_validity:1;
>> 
>> Similarly for this one, should be pc_feature_valid.
>> 
> This is how the vbt block definition doc mentions this field.
> This is the reason why it has been added in this manner.
>>>  } __packed;
>>>  
>>>  #define EDP_18BPP	0
>>> -- 
>>> 1.7.9.5
>>>
>>> _______________________________________________
>>> Intel-gfx mailing list
>>> Intel-gfx@lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>> 
>

-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature
  2014-01-22 13:09   ` Jani Nikula
@ 2014-01-30  3:29     ` Vandana Kannan
  2014-01-30  6:20       ` Jani Nikula
  0 siblings, 1 reply; 21+ messages in thread
From: Vandana Kannan @ 2014-01-30  3:29 UTC (permalink / raw)
  To: Jani Nikula; +Cc: intel-gfx

On Jan-22-2014 6:39 PM, Jani Nikula wrote:
> On Mon, 23 Dec 2013, Vandana Kannan <vandana.kannan@intel.com> wrote:
>> From: Pradeep Bhat <pradeep.bhat@intel.com>
>>
>> This patch reads the DRRS support and Mode type from VBT fields.
>> The read information will be stored in VBT struct during BIOS
>> parsing. The above functionality is needed for decision making
>> whether DRRS feature is supported in i915 driver for eDP panels.
>> This information helps us decide if seamless DRRS can be done
>> at runtime to support certain power saving features. This patch
>> was tested by setting necessary bit in VBT struct and merging
>> the new VBT with system BIOS so that we can read the value.
>>
>> v2: Incorporated review comments from Chris Wilson
>> Removed "intel_" as a prefix for DRRS specific declarations.
>>
>> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
>> Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
>> ---
>>  drivers/gpu/drm/i915/i915_drv.h   |    9 +++++++++
>>  drivers/gpu/drm/i915/intel_bios.c |   23 +++++++++++++++++++++++
>>  drivers/gpu/drm/i915/intel_bios.h |   29 +++++++++++++++++++++++++++++
>>  3 files changed, 61 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>> index ae2c80c..f8fd045 100644
>> --- a/drivers/gpu/drm/i915/i915_drv.h
>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>> @@ -1174,6 +1174,15 @@ struct intel_vbt_data {
>>  	int lvds_ssc_freq;
>>  	unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
>>  
>> +	/**
> 
> This is not a kerneldoc comment, so drop the extra *.
> 
Ok.
>> +	 * 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;
> 
> Both the drrs_mode and drrs_enabled should be replaced by one enum
> drrs_support_type which you introduce later. It's all self-explanatory
> that way, and you don't need to explain so much.
> 
There are 2 options in the VBT. drrs_enabled to check if DRRS is
supported, drrs_mode to show which type. It has been added here as it is
for readability.
>> +
>>  	/* eDP */
>>  	int edp_rate;
>>  	int edp_lanes;
>> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
>> index f88e507..5b04a69 100644
>> --- a/drivers/gpu/drm/i915/intel_bios.c
>> +++ b/drivers/gpu/drm/i915/intel_bios.c
>> @@ -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;
> 
> Everywhere else in intel_bios.c panel_type is used 0-based.
> 
VBT indexes panel type as 1,2,3. Therefore, we have to make the change
to match kernel's 0-based usage.
>> +}
> 
> You use the above function only once. IMHO with all the explaining above
> it's just too much of a burden to the reader. Just do this in the code.
> 
Ok.
>> +
>>  /* 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",
>                                              ^ drop the space here
> 
Ok
>> +			(dev_priv->vbt.drrs_mode == 0) ? "STATIC" : "SEAMLESS");
> 
> Why shouting?
> 
>> +
>>  	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);
>                                          ^ and here and everywhere
> 
Ok
>>  }
>>  
>>  static void
>> diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
>> index 81ed58c..0a3a751 100644
>> --- a/drivers/gpu/drm/i915/intel_bios.h
>> +++ b/drivers/gpu/drm/i915/intel_bios.h
>> @@ -281,6 +281,9 @@ struct bdb_general_definitions {
>>  	union child_device_config devices[0];
>>  } __packed;
>>  
>> +/* Mask for DRRS / Panel Channel / SSC / BLT control bits extraction */
>> +#define MODE_MASK		0x3
>> +
>>  struct bdb_lvds_options {
>>  	u8 panel_type;
>>  	u8 rsvd1;
>> @@ -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;
> 
> Why does this have "lvds" but the rest not? Why do some fields end in
> "bits" but some others not? Some consistency please.
> 
This is how the vbt block definition doc mentions each of these fields.
This is the reason why it has been added in this manner.

>> +	/* 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;
> 
> I really *really* wish I knew why some stuff is specified in the lvds
> bios blob and some other in edp blob and some stuff specified here is
> used in the edp side. Ugh. I wonder if we should check this
> panel_color_depth for edp too.
>
This is how the vbt block definition doc mentions each of these fields.
This is the reason why it has been added in this manner.

>> +	/* LVDS panel type bits stored here */
>> +	u32 dps_panel_type_bits;
>> +	/* LVDS backlight control type bits stored here */
>> +	u32 blt_control_type_bits;
>>  } __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;
> 
> All of the above should be foo_enabled to make them self-explanatory.
> 
>> +	u16 reserved3:4;
>> +	u16 pc_feature_validity:1;
> 
> Similarly for this one, should be pc_feature_valid.
> 
This is how the vbt block definition doc mentions this field.
This is the reason why it has been added in this manner.
>>  } __packed;
>>  
>>  #define EDP_18BPP	0
>> -- 
>> 1.7.9.5
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature
  2013-12-23  7:52 ` [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature Vandana Kannan
@ 2014-01-22 13:09   ` Jani Nikula
  2014-01-30  3:29     ` Vandana Kannan
  0 siblings, 1 reply; 21+ messages in thread
From: Jani Nikula @ 2014-01-22 13:09 UTC (permalink / raw)
  To: Vandana Kannan, intel-gfx

On Mon, 23 Dec 2013, Vandana Kannan <vandana.kannan@intel.com> wrote:
> From: Pradeep Bhat <pradeep.bhat@intel.com>
>
> This patch reads the DRRS support and Mode type from VBT fields.
> The read information will be stored in VBT struct during BIOS
> parsing. The above functionality is needed for decision making
> whether DRRS feature is supported in i915 driver for eDP panels.
> This information helps us decide if seamless DRRS can be done
> at runtime to support certain power saving features. This patch
> was tested by setting necessary bit in VBT struct and merging
> the new VBT with system BIOS so that we can read the value.
>
> v2: Incorporated review comments from Chris Wilson
> Removed "intel_" as a prefix for DRRS specific declarations.
>
> Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
> Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h   |    9 +++++++++
>  drivers/gpu/drm/i915/intel_bios.c |   23 +++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_bios.h |   29 +++++++++++++++++++++++++++++
>  3 files changed, 61 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index ae2c80c..f8fd045 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1174,6 +1174,15 @@ struct intel_vbt_data {
>  	int lvds_ssc_freq;
>  	unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */
>  
> +	/**

This is not a kerneldoc comment, so drop the extra *.

> +	 * 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;

Both the drrs_mode and drrs_enabled should be replaced by one enum
drrs_support_type which you introduce later. It's all self-explanatory
that way, and you don't need to explain so much.

> +
>  	/* eDP */
>  	int edp_rate;
>  	int edp_lanes;
> diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
> index f88e507..5b04a69 100644
> --- a/drivers/gpu/drm/i915/intel_bios.c
> +++ b/drivers/gpu/drm/i915/intel_bios.c
> @@ -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;

Everywhere else in intel_bios.c panel_type is used 0-based.

> +}

You use the above function only once. IMHO with all the explaining above
it's just too much of a burden to the reader. Just do this in the code.

> +
>  /* 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",
                                             ^ drop the space here

> +			(dev_priv->vbt.drrs_mode == 0) ? "STATIC" : "SEAMLESS");

Why shouting?

> +
>  	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);
                                         ^ and here and everywhere

>  }
>  
>  static void
> diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
> index 81ed58c..0a3a751 100644
> --- a/drivers/gpu/drm/i915/intel_bios.h
> +++ b/drivers/gpu/drm/i915/intel_bios.h
> @@ -281,6 +281,9 @@ struct bdb_general_definitions {
>  	union child_device_config devices[0];
>  } __packed;
>  
> +/* Mask for DRRS / Panel Channel / SSC / BLT control bits extraction */
> +#define MODE_MASK		0x3
> +
>  struct bdb_lvds_options {
>  	u8 panel_type;
>  	u8 rsvd1;
> @@ -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;

Why does this have "lvds" but the rest not? Why do some fields end in
"bits" but some others not? Some consistency please.

> +	/* 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;

I really *really* wish I knew why some stuff is specified in the lvds
bios blob and some other in edp blob and some stuff specified here is
used in the edp side. Ugh. I wonder if we should check this
panel_color_depth for edp too.

> +	/* LVDS panel type bits stored here */
> +	u32 dps_panel_type_bits;
> +	/* LVDS backlight control type bits stored here */
> +	u32 blt_control_type_bits;
>  } __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;

All of the above should be foo_enabled to make them self-explanatory.

> +	u16 reserved3:4;
> +	u16 pc_feature_validity:1;

Similarly for this one, should be pc_feature_valid.

>  } __packed;
>  
>  #define EDP_18BPP	0
> -- 
> 1.7.9.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature
  2013-12-23  7:52 [PATCH 0/5] Enabling DRRS in the kernel Vandana Kannan
@ 2013-12-23  7:52 ` Vandana Kannan
  2014-01-22 13:09   ` Jani Nikula
  0 siblings, 1 reply; 21+ messages in thread
From: Vandana Kannan @ 2013-12-23  7:52 UTC (permalink / raw)
  To: intel-gfx

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch reads the DRRS support and Mode type from VBT fields.
The read information will be stored in VBT struct during BIOS
parsing. The above functionality is needed for decision making
whether DRRS feature is supported in i915 driver for eDP panels.
This information helps us decide if seamless DRRS can be done
at runtime to support certain power saving features. This patch
was tested by setting necessary bit in VBT struct and merging
the new VBT with system BIOS so that we can read the value.

v2: Incorporated review comments from Chris Wilson
Removed "intel_" as a prefix for DRRS specific declarations.

Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h   |    9 +++++++++
 drivers/gpu/drm/i915/intel_bios.c |   23 +++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_bios.h |   29 +++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ae2c80c..f8fd045 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1174,6 +1174,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;
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index f88e507..5b04a69 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -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
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 81ed58c..0a3a751 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -281,6 +281,9 @@ struct bdb_general_definitions {
 	union child_device_config devices[0];
 } __packed;
 
+/* Mask for DRRS / Panel Channel / SSC / BLT control bits extraction */
+#define MODE_MASK		0x3
+
 struct bdb_lvds_options {
 	u8 panel_type;
 	u8 rsvd1;
@@ -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;
 } __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;
 } __packed;
 
 #define EDP_18BPP	0
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature
  2013-12-20 10:10 [PATCH 0/5] Enabling DRRS in the kernel Vandana Kannan
@ 2013-12-20 10:10 ` Vandana Kannan
  0 siblings, 0 replies; 21+ messages in thread
From: Vandana Kannan @ 2013-12-20 10:10 UTC (permalink / raw)
  To: intel-gfx

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch reads the DRRS support and Mode type from VBT fields.
The read information will be stored in VBT struct during BIOS
parsing. The above functionality is needed for decision making
whether DRRS feature is supported in i915 driver for eDP panels.
This information helps us decide if seamless DRRS can be done
at runtime to support certain power saving features. This patch
was tested by setting necessary bit in VBT struct and merging
the new VBT with system BIOS so that we can read the value.

v2: Incorporated review comments from Chris Wilson
Removed "intel_" as a prefix for DRRS specific declarations.

Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_drv.h   |    9 +++++++++
 drivers/gpu/drm/i915/intel_bios.c |   23 +++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_bios.h |   29 +++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ae2c80c..f8fd045 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1174,6 +1174,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;
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index f88e507..5b04a69 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -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
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 81ed58c..0a3a751 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -281,6 +281,9 @@ struct bdb_general_definitions {
 	union child_device_config devices[0];
 } __packed;
 
+/* Mask for DRRS / Panel Channel / SSC / BLT control bits extraction */
+#define MODE_MASK		0x3
+
 struct bdb_lvds_options {
 	u8 panel_type;
 	u8 rsvd1;
@@ -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;
 } __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;
 } __packed;
 
 #define EDP_18BPP	0
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature
  2013-12-19  8:30 [PATCH 0/5] Enabling DRRS in the kernel Vandana Kannan
@ 2013-12-19  8:30 ` Vandana Kannan
  0 siblings, 0 replies; 21+ messages in thread
From: Vandana Kannan @ 2013-12-19  8:30 UTC (permalink / raw)
  To: intel-gfx

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch reads the DRRS support and Mode type from VBT fields.
The read information will be stored in VBT struct during BIOS
parsing. The above functionality is needed for decision making
whether DRRS feature is supported in i915 driver for eDP panels.
This information helps us decide if seamless DRRS can be done
at runtime to support certain power saving features. This patch
was tested by setting necessary bit in VBT struct and merging
the new VBT with system BIOS so that we can read the value.

v2: Incorporated review comments from Chris Wilson
Removed "intel_" as a prefix for DRRS specific declarations.

Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/i915_drv.h   |    9 +++++++++
 drivers/gpu/drm/i915/intel_bios.c |   23 +++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_bios.h |   29 +++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 64ed8f4..4d6665b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -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;
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 6dd622d..30ab5a3 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -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
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index f580a2b..8e594f6 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -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
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature
  2013-12-18  9:11       ` Chris Wilson
@ 2013-12-18 10:13         ` Vandana Kannan
  0 siblings, 0 replies; 21+ messages in thread
From: Vandana Kannan @ 2013-12-18 10:13 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Dec-18-2013 2:41 PM, Chris Wilson wrote:
> On Wed, Dec 18, 2013 at 01:38:44PM +0530, Vandana Kannan wrote:
>> On Dec-17-2013 5:56 PM, Chris Wilson wrote:
>>> On Tue, Dec 17, 2013 at 10:58:23AM +0530, Vandana Kannan wrote:
>>>> From: Pradeep Bhat <pradeep.bhat@intel.com>
>>>>
>>>> This patch reads the DRRS support and Mode type from VBT fields.
>>>> The read information will be stored in VBT struct during BIOS
>>>> parsing. The above functionality is needed for decision making
>>>> whether DRRS feature is supported in i915 driver for eDP panels.
>>>> This information helps us decide if seamless DRRS can be done
>>>> at runtime to support certain power saving features. This patch
>>>> was tested by setting necessary bit in VBT struct and merging
>>>> the new VBT with system BIOS so that we can read the value.
>>>
>>> What's the reason for the inconsistent intel_ tautology?
>>>
>> If you are referring to the names of members under bdb_driver_features,
>> which start with intel_, then this is something which can be modified to
>> remove the "intel_". Is it ok?
> 
> Yes, we use intel_ as a function prefix for generic routines that apply
> to almost all display engines. We expect that all of our hardware specific
> structure are used for Intel and so don't need reminding, least
> of all, inconsistently.
> 
> And s/drrs_state/drrs/.
>  
I will make these changes.
- Vandana
>>>> @@ -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.intel_drrs_enabled = driver->intel_drrs_state;
>>>> +	DRM_DEBUG_KMS("DRRS State Enabled : %d\n", driver->intel_drrs_state);
>>>
>>> Now this oddity needs a big explanation. Writing that will hopefully
>>> reveal a better strategy.
>>> -Chris
>>>
>> Panel vendors specify panel capabilities via the VBT. Following this,
>> the panel's capability to support seamless DRRS has to be read from the
>> VBT. The same is being done in the piece of code above. Without this we
>> cannot assume that the panel supports seamless DRRS.
> 
> Nevermind, I misread driver-> as dev_priv->.
> -Chris
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature
  2013-12-18  8:08     ` Vandana Kannan
@ 2013-12-18  9:11       ` Chris Wilson
  2013-12-18 10:13         ` Vandana Kannan
  0 siblings, 1 reply; 21+ messages in thread
From: Chris Wilson @ 2013-12-18  9:11 UTC (permalink / raw)
  To: Vandana Kannan; +Cc: intel-gfx

On Wed, Dec 18, 2013 at 01:38:44PM +0530, Vandana Kannan wrote:
> On Dec-17-2013 5:56 PM, Chris Wilson wrote:
> > On Tue, Dec 17, 2013 at 10:58:23AM +0530, Vandana Kannan wrote:
> >> From: Pradeep Bhat <pradeep.bhat@intel.com>
> >>
> >> This patch reads the DRRS support and Mode type from VBT fields.
> >> The read information will be stored in VBT struct during BIOS
> >> parsing. The above functionality is needed for decision making
> >> whether DRRS feature is supported in i915 driver for eDP panels.
> >> This information helps us decide if seamless DRRS can be done
> >> at runtime to support certain power saving features. This patch
> >> was tested by setting necessary bit in VBT struct and merging
> >> the new VBT with system BIOS so that we can read the value.
> > 
> > What's the reason for the inconsistent intel_ tautology?
> > 
> If you are referring to the names of members under bdb_driver_features,
> which start with intel_, then this is something which can be modified to
> remove the "intel_". Is it ok?

Yes, we use intel_ as a function prefix for generic routines that apply
to almost all display engines. We expect that all of our hardware specific
structure are used for Intel and so don't need reminding, least
of all, inconsistently.

And s/drrs_state/drrs/.
 
> >> @@ -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.intel_drrs_enabled = driver->intel_drrs_state;
> >> +	DRM_DEBUG_KMS("DRRS State Enabled : %d\n", driver->intel_drrs_state);
> > 
> > Now this oddity needs a big explanation. Writing that will hopefully
> > reveal a better strategy.
> > -Chris
> > 
> Panel vendors specify panel capabilities via the VBT. Following this,
> the panel's capability to support seamless DRRS has to be read from the
> VBT. The same is being done in the piece of code above. Without this we
> cannot assume that the panel supports seamless DRRS.

Nevermind, I misread driver-> as dev_priv->.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature
  2013-12-17 12:26   ` Chris Wilson
@ 2013-12-18  8:08     ` Vandana Kannan
  2013-12-18  9:11       ` Chris Wilson
  0 siblings, 1 reply; 21+ messages in thread
From: Vandana Kannan @ 2013-12-18  8:08 UTC (permalink / raw)
  To: Chris Wilson; +Cc: intel-gfx

On Dec-17-2013 5:56 PM, Chris Wilson wrote:
> On Tue, Dec 17, 2013 at 10:58:23AM +0530, Vandana Kannan wrote:
>> From: Pradeep Bhat <pradeep.bhat@intel.com>
>>
>> This patch reads the DRRS support and Mode type from VBT fields.
>> The read information will be stored in VBT struct during BIOS
>> parsing. The above functionality is needed for decision making
>> whether DRRS feature is supported in i915 driver for eDP panels.
>> This information helps us decide if seamless DRRS can be done
>> at runtime to support certain power saving features. This patch
>> was tested by setting necessary bit in VBT struct and merging
>> the new VBT with system BIOS so that we can read the value.
> 
> What's the reason for the inconsistent intel_ tautology?
> 
If you are referring to the names of members under bdb_driver_features,
which start with intel_, then this is something which can be modified to
remove the "intel_". Is it ok?

>> @@ -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.intel_drrs_enabled = driver->intel_drrs_state;
>> +	DRM_DEBUG_KMS("DRRS State Enabled : %d\n", driver->intel_drrs_state);
> 
> Now this oddity needs a big explanation. Writing that will hopefully
> reveal a better strategy.
> -Chris
> 
Panel vendors specify panel capabilities via the VBT. Following this,
the panel's capability to support seamless DRRS has to be read from the
VBT. The same is being done in the piece of code above. Without this we
cannot assume that the panel supports seamless DRRS.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature
  2013-12-17  5:28 ` [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature Vandana Kannan
@ 2013-12-17 12:26   ` Chris Wilson
  2013-12-18  8:08     ` Vandana Kannan
  0 siblings, 1 reply; 21+ messages in thread
From: Chris Wilson @ 2013-12-17 12:26 UTC (permalink / raw)
  To: Vandana Kannan; +Cc: intel-gfx

On Tue, Dec 17, 2013 at 10:58:23AM +0530, Vandana Kannan wrote:
> From: Pradeep Bhat <pradeep.bhat@intel.com>
> 
> This patch reads the DRRS support and Mode type from VBT fields.
> The read information will be stored in VBT struct during BIOS
> parsing. The above functionality is needed for decision making
> whether DRRS feature is supported in i915 driver for eDP panels.
> This information helps us decide if seamless DRRS can be done
> at runtime to support certain power saving features. This patch
> was tested by setting necessary bit in VBT struct and merging
> the new VBT with system BIOS so that we can read the value.

What's the reason for the inconsistent intel_ tautology?

> @@ -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.intel_drrs_enabled = driver->intel_drrs_state;
> +	DRM_DEBUG_KMS("DRRS State Enabled : %d\n", driver->intel_drrs_state);

Now this oddity needs a big explanation. Writing that will hopefully
reveal a better strategy.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature
  2013-12-17  5:28 [PATCH 0/5] Enabling DRRS support in the kernel Vandana Kannan
@ 2013-12-17  5:28 ` Vandana Kannan
  2013-12-17 12:26   ` Chris Wilson
  0 siblings, 1 reply; 21+ messages in thread
From: Vandana Kannan @ 2013-12-17  5:28 UTC (permalink / raw)
  To: intel-gfx

From: Pradeep Bhat <pradeep.bhat@intel.com>

This patch reads the DRRS support and Mode type from VBT fields.
The read information will be stored in VBT struct during BIOS
parsing. The above functionality is needed for decision making
whether DRRS feature is supported in i915 driver for eDP panels.
This information helps us decide if seamless DRRS can be done
at runtime to support certain power saving features. This patch
was tested by setting necessary bit in VBT struct and merging
the new VBT with system BIOS so that we can read the value.

Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com>
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h   |    9 +++++++++
 drivers/gpu/drm/i915/intel_bios.c |   23 +++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_bios.h |   29 +++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 64ed8f4..02e11dc 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -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 intel_drrs_enabled;
+
 	/* eDP */
 	int edp_rate;
 	int edp_lanes;
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 6dd622d..15ee0b8 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -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.intel_drrs_enabled = driver->intel_drrs_state;
+	DRM_DEBUG_KMS("DRRS State Enabled : %d\n", driver->intel_drrs_state);
 }
 
 static void
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index f580a2b..da6685b 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -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 intel_rmpm_state:1;
+	u16 intel_s2ddt_state:1;
+	u16 intel_dpst_state:1;
+	u16 intel_bltclt_state:1;
+	u16 intel_adb_state:1;
+	u16 intel_drrs_state:1;
+	u16 intel_grs_state:1;
+	u16 intel_gpmt_state:1;
+	u16 intel_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
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2014-02-14 16:39 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-14 10:02 [PATCH 0/5] v5: Enabling DRRS in the kernel Vandana Kannan
2014-02-14 10:02 ` [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature Vandana Kannan
2014-02-14 16:39   ` Jesse Barnes
2014-02-14 10:02 ` [PATCH 2/5] drm/i915: Parse EDID probed modes for DRRS support Vandana Kannan
2014-02-14 10:02 ` [PATCH 3/5] drm/i915: Add support for DRRS to switch RR Vandana Kannan
2014-02-14 10:02 ` [PATCH 4/5] drm/i915: Idleness detection for DRRS Vandana Kannan
2014-02-14 10:30   ` Chris Wilson
2014-02-14 10:02 ` [PATCH 5/5] drm/i915/bdw: Add support for DRRS to switch RR Vandana Kannan
  -- strict thread matches above, loose matches on Subject: below --
2013-12-23  7:52 [PATCH 0/5] Enabling DRRS in the kernel Vandana Kannan
2013-12-23  7:52 ` [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature Vandana Kannan
2014-01-22 13:09   ` Jani Nikula
2014-01-30  3:29     ` Vandana Kannan
2014-01-30  6:20       ` Jani Nikula
2014-02-03  3:43         ` Vandana Kannan
2014-02-04 10:34           ` Daniel Vetter
2013-12-20 10:10 [PATCH 0/5] Enabling DRRS in the kernel Vandana Kannan
2013-12-20 10:10 ` [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature Vandana Kannan
2013-12-19  8:30 [PATCH 0/5] Enabling DRRS in the kernel Vandana Kannan
2013-12-19  8:30 ` [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature Vandana Kannan
2013-12-17  5:28 [PATCH 0/5] Enabling DRRS support in the kernel Vandana Kannan
2013-12-17  5:28 ` [PATCH 1/5] drm/i915: Adding VBT fields to support eDP DRRS feature Vandana Kannan
2013-12-17 12:26   ` Chris Wilson
2013-12-18  8:08     ` Vandana Kannan
2013-12-18  9:11       ` Chris Wilson
2013-12-18 10:13         ` Vandana Kannan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.