As a complement to the suggestions put forward by Jesse in drm/i915: "Scotty, I need more power!" (1372436290-3297-1-git-send-email-jbarnes@xxxxxxxxxxxxxxxx) and drm/i915: boost GPU and CPU freq when leaving idle (1372438472-3233-1-git-send-email-jbarnes@xxxxxxxxxxxxxxxx) we also have the ability to fine tune how we respond to the GPU's requests for more power. This patch introduces the i915.rps_policy module parameter that adjusts how we respond to the upclock request: 1 - Powersaving (current implementation) Increase the frequency by one bin on every upclock request. 2 - Conservative (new default) When waking from idle, boost the render frequency to the default render frequency (RP1) 3 - Ondemand At every upclock request, increase to halfway between the current frequency and maximum. This should give rapid upclocking similar to tcp window scaling. 4 - Performance Every time the GPU wants more power, give it everything we have. Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_drv.c | 8 +++++++ drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_irq.c | 46 +++++++++++++++++++++++++++++------------ drivers/gpu/drm/i915/intel_pm.c | 1 + 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 1d8cedc..7ad80f4 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -72,6 +72,14 @@ MODULE_PARM_DESC(i915_enable_rc6, "For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. " "default: -1 (use per-chip default)"); +int i915_rps_policy __read_mostly = 1; +module_param_named(rps_policy, i915_rps_policy, int, 0600); +MODULE_PARM_DESC(rps_policy, + "Specify a policy to use to respond to requests to change the render clock. " + "Different levels of uplocking agressiveness can be selected" + "(0 = Powersaving, slowly uplock; 1 = Conservative, when the gpu wakes from idle go straight to RP1/RPe (recommended minimum active GPU frequency); 2 = Ondemand, rapidly increase frequency whilst upclocking; 4 = Performance, always upclock to maximum frequency). " + "default: 1 (Conservative)"); + int i915_enable_fbc __read_mostly = -1; module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600); MODULE_PARM_DESC(i915_enable_fbc, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ec14124..71232bc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -811,6 +811,7 @@ struct intel_gen6_power_mgmt { u8 min_delay; u8 max_delay; u8 rpe_delay; + u8 rp1_delay; u8 hw_max; struct delayed_work delayed_resume_work; @@ -1635,6 +1636,7 @@ extern int i915_lvds_channel_mode __read_mostly; extern int i915_panel_use_ssc __read_mostly; extern int i915_vbt_sdvo_panel_type __read_mostly; extern int i915_enable_rc6 __read_mostly; +extern int i915_rps_policy __read_mostly; extern int i915_enable_fbc __read_mostly; extern bool i915_enable_hangcheck __read_mostly; extern int i915_enable_ppgtt __read_mostly; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index ee3e49c..edd73c0 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -728,14 +728,32 @@ static void gen6_pm_rps_work(struct work_struct *work) mutex_lock(&dev_priv->rps.hw_lock); if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) { - new_delay = dev_priv->rps.cur_delay + 1; + switch (i915_rps_policy) { + case 0: /* Powersave, slow increase in frequency */ + new_delay = dev_priv->rps.cur_delay + 1; + break; + + case 1: /* Conservative, jump directly to RPe */ + new_delay = dev_priv->rps.rp1_delay; + if (dev_priv->rps.cur_delay >= new_delay) + new_delay = dev_priv->rps.cur_delay + 1; + break; + + case 2: /* Ondemand, halfway to maximum */ + new_delay = dev_priv->rps.cur_delay + 1; + if (new_delay < dev_priv->rps.rp1_delay) + new_delay = dev_priv->rps.rp1_delay; + else + new_delay = (dev_priv->rps.max_delay + new_delay) >> 1; + break; + + default: /* Performance, straight to maximum */ + new_delay = dev_priv->rps.max_delay; + break; + } - /* - * For better performance, jump directly - * to RPe if we're below it. - */ if (IS_VALLEYVIEW(dev_priv->dev) && - dev_priv->rps.cur_delay < dev_priv->rps.rpe_delay) + new_delay < dev_priv->rps.rpe_delay) new_delay = dev_priv->rps.rpe_delay; } else new_delay = dev_priv->rps.cur_delay - 1; @@ -743,13 +761,15 @@ static void gen6_pm_rps_work(struct work_struct *work) /* sysfs frequency interfaces may have snuck in while servicing the * interrupt */ - if (new_delay >= dev_priv->rps.min_delay && - new_delay <= dev_priv->rps.max_delay) { - if (IS_VALLEYVIEW(dev_priv->dev)) - valleyview_set_rps(dev_priv->dev, new_delay); - else - gen6_set_rps(dev_priv->dev, new_delay); - } + if (new_delay < dev_priv->rps.min_delay) + new_delay = dev_priv->rps.min_delay; + if (new_delay > dev_priv->rps.max_delay) + new_delay = dev_priv->rps.max_delay; + + if (IS_VALLEYVIEW(dev_priv->dev)) + valleyview_set_rps(dev_priv->dev, new_delay); + else + gen6_set_rps(dev_priv->dev, new_delay); if (IS_VALLEYVIEW(dev_priv->dev)) { /* diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 4e6d618..e9e467c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3242,6 +3242,7 @@ static void gen6_enable_rps(struct drm_device *dev) /* In units of 50MHz */ dev_priv->rps.hw_max = dev_priv->rps.max_delay = rp_state_cap & 0xff; dev_priv->rps.min_delay = (rp_state_cap & 0xff0000) >> 16; + dev_priv->rps.rp1_delay = (rp_state_cap & 0xff00) >> 8; dev_priv->rps.cur_delay = 0; /* disable the counters and set deterministic thresholds */ -- 1.8.3.2 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx