[Intel-gfx] [PATCH 4/5] drm/i915: Idleness detection for DRRS

2014-02-14 Thread Vandana Kannan
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.kan...@intel.com
Signed-off-by: Pradeep Bhat pradeep.b...@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-de...@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);
 

Re: [Intel-gfx] [PATCH 4/5] drm/i915: Idleness detection for DRRS

2014-02-14 Thread Chris Wilson
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
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 4/5] drm/i915: Idleness detection for DRRS

2014-01-29 Thread Vandana Kannan
On Jan-22-2014 7:56 PM, Jani Nikula wrote:
 On Mon, 23 Dec 2013, Vandana Kannan vandana.kan...@intel.com wrote:
 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

 Signed-off-by: Vandana Kannan vandana.kan...@intel.com
 Signed-off-by: Pradeep Bhat pradeep.b...@intel.com
 ---
  drivers/gpu/drm/i915/i915_drv.h  |   16 +
  drivers/gpu/drm/i915/intel_display.c |   14 
  drivers/gpu/drm/i915/intel_dp.c  |   10 +++
  drivers/gpu/drm/i915/intel_drv.h |4 ++
  drivers/gpu/drm/i915/intel_pm.c  |  122 
 ++
  drivers/gpu/drm/i915/intel_sprite.c  |2 +
  6 files changed, 168 insertions(+)

 diff --git a/drivers/gpu/drm/i915/i915_drv.h 
 b/drivers/gpu/drm/i915/i915_drv.h
 index f8fd045..d7308cc 100644
 --- a/drivers/gpu/drm/i915/i915_drv.h
 +++ b/drivers/gpu/drm/i915/i915_drv.h
 @@ -712,6 +712,21 @@ struct i915_fbc {
  } no_fbc_reason;
  };
  
 +/* configure the number of secs the system must be idle
 + * before DRRS is enabled
 +*/
 +#define DRRS_IDLENESS_TIME 2000 /* in millisecs */
 +
 +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;
 
 I'll probably see this more useful as a module parameter than a field
 here, with 0 meaning disable.
 
Ok. I will look into this.
 +} *drrs_work;
 +};
 +
  struct i915_psr {
  bool sink_support;
  bool source_ok;
 @@ -1400,6 +1415,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/intel_display.c 
 b/drivers/gpu/drm/i915/intel_display.c
 index a40651e..995d117 100644
 --- a/drivers/gpu/drm/i915/intel_display.c
 +++ b/drivers/gpu/drm/i915/intel_display.c
 @@ -2395,6 +2395,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);
  
 @@ -3559,6 +3560,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)
 @@ -3600,6 +3602,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);
  }
  
 @@ -3806,6 +3809,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);
  }
  
 @@ -3853,6 +3857,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);
  }
  
 @@ -8226,6 +8231,11 @@ static void intel_unpin_work_fn(struct work_struct 
 *__work)
  drm_gem_object_unreference(work-old_fb_obj-base);
  
  intel_update_fbc(dev);
 +
 +/* disable current DRRS work scheduled and restart
 + * to push work by another x seconds
 + */
 +intel_update_drrs(dev);
  mutex_unlock(dev-struct_mutex);
  
  BUG_ON(atomic_read(to_intel_crtc(work-crtc)-unpin_work_count) == 0);
 @@ -8665,6 +8675,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);
  
 @@ -10880,6 +10891,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
 @@ -11286,6 +11298,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 d1e1d6e..7778808 100644
 --- a/drivers/gpu/drm/i915/intel_dp.c
 +++ b/drivers/gpu/drm/i915/intel_dp.c
 @@ -3289,11 +3289,18 @@ void intel_dp_encoder_destroy(struct drm_encoder 
 *encoder)
  struct intel_digital_port 

Re: [Intel-gfx] [PATCH 4/5] drm/i915: Idleness detection for DRRS

2014-01-22 Thread Jani Nikula
On Mon, 23 Dec 2013, Vandana Kannan vandana.kan...@intel.com wrote:
 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

 Signed-off-by: Vandana Kannan vandana.kan...@intel.com
 Signed-off-by: Pradeep Bhat pradeep.b...@intel.com
 ---
  drivers/gpu/drm/i915/i915_drv.h  |   16 +
  drivers/gpu/drm/i915/intel_display.c |   14 
  drivers/gpu/drm/i915/intel_dp.c  |   10 +++
  drivers/gpu/drm/i915/intel_drv.h |4 ++
  drivers/gpu/drm/i915/intel_pm.c  |  122 
 ++
  drivers/gpu/drm/i915/intel_sprite.c  |2 +
  6 files changed, 168 insertions(+)

 diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
 index f8fd045..d7308cc 100644
 --- a/drivers/gpu/drm/i915/i915_drv.h
 +++ b/drivers/gpu/drm/i915/i915_drv.h
 @@ -712,6 +712,21 @@ struct i915_fbc {
   } no_fbc_reason;
  };
  
 +/* configure the number of secs the system must be idle
 + * before DRRS is enabled
 +*/
 +#define DRRS_IDLENESS_TIME 2000 /* in millisecs */
 +
 +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;

I'll probably see this more useful as a module parameter than a field
here, with 0 meaning disable.

 + } *drrs_work;
 +};
 +
  struct i915_psr {
   bool sink_support;
   bool source_ok;
 @@ -1400,6 +1415,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/intel_display.c 
 b/drivers/gpu/drm/i915/intel_display.c
 index a40651e..995d117 100644
 --- a/drivers/gpu/drm/i915/intel_display.c
 +++ b/drivers/gpu/drm/i915/intel_display.c
 @@ -2395,6 +2395,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);
  
 @@ -3559,6 +3560,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)
 @@ -3600,6 +3602,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);
  }
  
 @@ -3806,6 +3809,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);
  }
  
 @@ -3853,6 +3857,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);
  }
  
 @@ -8226,6 +8231,11 @@ static void intel_unpin_work_fn(struct work_struct 
 *__work)
   drm_gem_object_unreference(work-old_fb_obj-base);
  
   intel_update_fbc(dev);
 +
 + /* disable current DRRS work scheduled and restart
 +  * to push work by another x seconds
 +  */
 + intel_update_drrs(dev);
   mutex_unlock(dev-struct_mutex);
  
   BUG_ON(atomic_read(to_intel_crtc(work-crtc)-unpin_work_count) == 0);
 @@ -8665,6 +8675,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);
  
 @@ -10880,6 +10891,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
 @@ -11286,6 +11298,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 d1e1d6e..7778808 100644
 --- a/drivers/gpu/drm/i915/intel_dp.c
 +++ b/drivers/gpu/drm/i915/intel_dp.c
 @@ -3289,11 +3289,18 @@ void intel_dp_encoder_destroy(struct drm_encoder 
 *encoder)
   struct intel_digital_port *intel_dig_port = 

[Intel-gfx] [PATCH 4/5] drm/i915: Idleness detection for DRRS

2013-12-22 Thread Vandana Kannan
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

Signed-off-by: Vandana Kannan vandana.kan...@intel.com
Signed-off-by: Pradeep Bhat pradeep.b...@intel.com
---
 drivers/gpu/drm/i915/i915_drv.h  |   16 +
 drivers/gpu/drm/i915/intel_display.c |   14 
 drivers/gpu/drm/i915/intel_dp.c  |   10 +++
 drivers/gpu/drm/i915/intel_drv.h |4 ++
 drivers/gpu/drm/i915/intel_pm.c  |  122 ++
 drivers/gpu/drm/i915/intel_sprite.c  |2 +
 6 files changed, 168 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f8fd045..d7308cc 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -712,6 +712,21 @@ struct i915_fbc {
} no_fbc_reason;
 };
 
+/* configure the number of secs the system must be idle
+ * before DRRS is enabled
+*/
+#define DRRS_IDLENESS_TIME 2000 /* in millisecs */
+
+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 {
bool sink_support;
bool source_ok;
@@ -1400,6 +1415,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/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index a40651e..995d117 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2395,6 +2395,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);
 
@@ -3559,6 +3560,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)
@@ -3600,6 +3602,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);
 }
 
@@ -3806,6 +3809,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);
 }
 
@@ -3853,6 +3857,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);
 }
 
@@ -8226,6 +8231,11 @@ static void intel_unpin_work_fn(struct work_struct 
*__work)
drm_gem_object_unreference(work-old_fb_obj-base);
 
intel_update_fbc(dev);
+
+   /* disable current DRRS work scheduled and restart
+* to push work by another x seconds
+*/
+   intel_update_drrs(dev);
mutex_unlock(dev-struct_mutex);
 
BUG_ON(atomic_read(to_intel_crtc(work-crtc)-unpin_work_count) == 0);
@@ -8665,6 +8675,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);
 
@@ -10880,6 +10891,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
@@ -11286,6 +11298,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 d1e1d6e..7778808 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3289,11 +3289,18 @@ 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;
 

[Intel-gfx] [PATCH 4/5] drm/i915: Idleness detection for DRRS

2013-12-19 Thread Vandana Kannan
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's review comments
Modify idleness detection implementation to make it similar to the
implementation of intel_update_fbc/intel_disable_fbc

Change-Id: I17b011b3867a39588375f2b97b992444972f7760
Signed-off-by: Vandana Kannan vandana.kan...@intel.com
Signed-off-by: Pradeep Bhat pradeep.b...@intel.com
Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk
---
 drivers/gpu/drm/i915/i915_drv.h  |   16 +
 drivers/gpu/drm/i915/intel_display.c |   14 
 drivers/gpu/drm/i915/intel_dp.c  |9 +++
 drivers/gpu/drm/i915/intel_drv.h |5 +-
 drivers/gpu/drm/i915/intel_pm.c  |  122 ++
 drivers/gpu/drm/i915/intel_sprite.c  |3 +
 6 files changed, 168 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 4d6665b..7ed20cf 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -713,6 +713,21 @@ struct i915_fbc {
} no_fbc_reason;
 };
 
+/* configure the number of secs the system must be idle
+ * before DRRS is enabled
+*/
+#define DRRS_IDLENESS_TIME 2000 /* in millisecs */
+
+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 {
bool sink_support;
bool source_ok;
@@ -1397,6 +1412,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/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 0332d7c..a25c5da 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2385,6 +2385,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);
 
@@ -3549,6 +3550,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)
@@ -3590,6 +3592,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);
 }
 
@@ -3796,6 +3799,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);
 }
 
@@ -3843,6 +3847,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);
 }
 
@@ -8184,6 +8189,11 @@ static void intel_unpin_work_fn(struct work_struct 
*__work)
drm_gem_object_unreference(work-old_fb_obj-base);
 
intel_update_fbc(dev);
+
+   /* disable current DRRS work scheduled and restart
+* to push work by another x seconds
+*/
+   intel_update_drrs(dev);
mutex_unlock(dev-struct_mutex);
 
BUG_ON(atomic_read(to_intel_crtc(work-crtc)-unpin_work_count) == 0);
@@ -8623,6 +8633,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);
 
@@ -10843,6 +10854,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
@@ -11250,6 +11262,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 e110f26..c96ed34 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3292,11 +3292,18 @@ 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 = 

Re: [Intel-gfx] [PATCH 4/5] drm/i915: Idleness detection for DRRS

2013-12-18 Thread Vandana Kannan
On Dec-17-2013 5:59 PM, Chris Wilson wrote:
 On Tue, Dec 17, 2013 at 10:58:26AM +0530, Vandana Kannan wrote:
 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.
 
 Looks very inconsistent next to intel_fbc_disable/intel_fbc_update.
 -Chris
 
We have implemented this in a way that it is similar to fbc
implementation. Could you explain some more about your review comment?
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 4/5] drm/i915: Idleness detection for DRRS

2013-12-18 Thread Chris Wilson
On Wed, Dec 18, 2013 at 01:48:12PM +0530, Vandana Kannan wrote:
 On Dec-17-2013 5:59 PM, Chris Wilson wrote:
  On Tue, Dec 17, 2013 at 10:58:26AM +0530, Vandana Kannan wrote:
  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.
  
  Looks very inconsistent next to intel_fbc_disable/intel_fbc_update.
  -Chris
  
 We have implemented this in a way that it is similar to fbc
 implementation. Could you explain some more about your review comment?

See the split between intel_fbc_disable and intel_fbc_update and how it
would make your code more tidy, your API harder to get wrong and make it
easier to integrate all of these triggers into a single routine. Also
note that you miss out on frontbuffer rendering detection.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 4/5] drm/i915: Idleness detection for DRRS

2013-12-18 Thread Vandana Kannan
On Dec-18-2013 2:34 PM, Chris Wilson wrote:
 On Wed, Dec 18, 2013 at 01:48:12PM +0530, Vandana Kannan wrote:
 On Dec-17-2013 5:59 PM, Chris Wilson wrote:
 On Tue, Dec 17, 2013 at 10:58:26AM +0530, Vandana Kannan wrote:
 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.

 Looks very inconsistent next to intel_fbc_disable/intel_fbc_update.
 -Chris

 We have implemented this in a way that it is similar to fbc
 implementation. Could you explain some more about your review comment?
 
 See the split between intel_fbc_disable and intel_fbc_update and how it
 would make your code more tidy, your API harder to get wrong and make it
 easier to integrate all of these triggers into a single routine. Also
 note that you miss out on frontbuffer rendering detection.
 -Chris
 
The current implementation makes use of bool update to differentiate
between an update/disable. I will make changes so that the
implementation is similar to intel_fbc_disable/intel_fbc_update.
Could you give more information on the miss on frontbuffer rendering
detection?
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


Re: [Intel-gfx] [PATCH 4/5] drm/i915: Idleness detection for DRRS

2013-12-17 Thread Chris Wilson
On Tue, Dec 17, 2013 at 10:58:26AM +0530, Vandana Kannan wrote:
 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.

Looks very inconsistent next to intel_fbc_disable/intel_fbc_update.
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx


[Intel-gfx] [PATCH 4/5] drm/i915: Idleness detection for DRRS

2013-12-16 Thread Vandana Kannan
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.

Change-Id: I17b011b3867a39588375f2b97b992444972f7760
Signed-off-by: Vandana Kannan vandana.kan...@intel.com
Signed-off-by: Pradeep Bhat pradeep.b...@intel.com
---
 drivers/gpu/drm/i915/i915_drv.h  |   19 ++
 drivers/gpu/drm/i915/intel_display.c |   13 
 drivers/gpu/drm/i915/intel_dp.c  |9 +++
 drivers/gpu/drm/i915/intel_pm.c  |  112 ++
 drivers/gpu/drm/i915/intel_sprite.c  |3 +
 5 files changed, 156 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c9bca16..ec29603 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -713,6 +713,21 @@ struct i915_fbc {
} no_fbc_reason;
 };
 
+/* configure the number of secs the system must be idle
+ * before DRRS is enabled
+*/
+#define DRRS_IDLENESS_TIME 2000 /* in millisecs */
+
+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 {
bool sink_support;
bool source_ok;
@@ -1397,6 +1412,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;
 
@@ -2422,6 +2438,9 @@ extern void intel_modeset_setup_hw_state(struct 
drm_device *dev,
 extern void i915_redisable_vga(struct drm_device *dev);
 extern bool intel_fbc_enabled(struct drm_device *dev);
 extern void intel_disable_fbc(struct drm_device *dev);
+extern void intel_init_drrs_idleness_detection(struct drm_device *dev,
+   struct intel_connector *connector, struct intel_dp *dp);
+extern void intel_update_drrs(struct drm_device *dev, bool update);
 extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
 extern void intel_init_pch_refclk(struct drm_device *dev);
 extern void gen6_set_rps(struct drm_device *dev, u8 val);
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 0332d7c..9a699cf 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2385,6 +2385,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
}
 
intel_update_fbc(dev);
+   intel_update_drrs(dev, true);
intel_edp_psr_update(dev);
mutex_unlock(dev-struct_mutex);
 
@@ -3549,6 +3550,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 
mutex_lock(dev-struct_mutex);
intel_update_fbc(dev);
+   intel_update_drrs(dev, true);
mutex_unlock(dev-struct_mutex);
 
for_each_encoder_on_crtc(dev, crtc, encoder)
@@ -3590,6 +3592,7 @@ static void haswell_crtc_enable_planes(struct drm_crtc 
*crtc)
 
mutex_lock(dev-struct_mutex);
intel_update_fbc(dev);
+   intel_update_drrs(dev, true);
mutex_unlock(dev-struct_mutex);
 }
 
@@ -3796,6 +3799,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
 
mutex_lock(dev-struct_mutex);
intel_update_fbc(dev);
+   intel_update_drrs(dev, true);
mutex_unlock(dev-struct_mutex);
 }
 
@@ -3843,6 +3847,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
 
mutex_lock(dev-struct_mutex);
intel_update_fbc(dev);
+   intel_update_drrs(dev, true);
mutex_unlock(dev-struct_mutex);
 }
 
@@ -8184,6 +8189,11 @@ static void intel_unpin_work_fn(struct work_struct 
*__work)
drm_gem_object_unreference(work-old_fb_obj-base);
 
intel_update_fbc(dev);
+
+   /* disable current DRRS work scheduled and restart
+* to push work by another x seconds
+*/
+   intel_update_drrs(dev, true);
mutex_unlock(dev-struct_mutex);
 
BUG_ON(atomic_read(to_intel_crtc(work-crtc)-unpin_work_count) == 0);
@@ -8623,6 +8633,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
goto cleanup_pending;
 
intel_disable_fbc(dev);
+   intel_update_drrs(dev, false);
intel_mark_fb_busy(obj, NULL);
mutex_unlock(dev-struct_mutex);
 
@@ -11250,6 +11261,8 @@ void intel_modeset_cleanup(struct drm_device *dev)
 
intel_disable_fbc(dev);
 
+   intel_update_drrs(dev, false);
+
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 fbf71ed..209be3c 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3293,11 +3293,18 @@ void