[Intel-gfx] [PATCH 4/5] drm/i915: Idleness detection for DRRS
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
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
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
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
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
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
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
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
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
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
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