* [PATCH v2 0/3] VLV Turbo/rps + RC6 workaround
@ 2014-01-09 14:01 deepak.s
2014-01-09 14:01 ` [PATCH v3 1/3] drm/i915: Disable/Enable PM Intrrupts based on the current freq deepak.s
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: deepak.s @ 2014-01-09 14:01 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak S
From: Deepak S <deepak.s@intel.com>
Below patches addes WA to set Gfx freq while clock are down. Also, added a WA to enables both RC6 and Turbo work together.
Deepak S (3):
drm/i915: Disable/Enable PM Intrrupts based on the current freq.
drm/i915/vlv: WA to fix Voltage not getting dropped to Vmin when Gfx
is power gated.
drm/i915/vlv: WA for Turbo and RC6 to work together.
drivers/gpu/drm/i915/i915_drv.h | 16 ++++
drivers/gpu/drm/i915/i915_irq.c | 182 ++++++++++++++++++++++++++++++++++++++--
drivers/gpu/drm/i915/i915_reg.h | 23 +++++
drivers/gpu/drm/i915/intel_pm.c | 102 +++++++++++++++++++---
4 files changed, 304 insertions(+), 19 deletions(-)
--
1.8.4.2
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 1/3] drm/i915: Disable/Enable PM Intrrupts based on the current freq.
2014-01-09 14:01 [PATCH v2 0/3] VLV Turbo/rps + RC6 workaround deepak.s
@ 2014-01-09 14:01 ` deepak.s
2014-01-13 23:01 ` Jesse Barnes
2014-01-14 9:21 ` Daniel Vetter
2014-01-09 14:01 ` [PATCH v2 2/3] drm/i915/vlv: WA to fix Voltage not getting dropped to Vmin when Gfx is power gated deepak.s
2014-01-09 14:01 ` [PATCH 3/3] drm/i915/vlv: WA for Turbo and RC6 to work together deepak.s
2 siblings, 2 replies; 10+ messages in thread
From: deepak.s @ 2014-01-09 14:01 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak S
From: Deepak S <deepak.s@intel.com>
When current delay is already at max delay, Let's disable the PM UP
THRESHOLD INTRRUPTS, so that we will not get further interrupts until
current delay is less than max delay, Also request for the PM DOWN
THRESHOLD INTRRUPTS to indicate the decrease in clock freq. and
viceversa for PM DOWN THRESHOLD INTRRUPTS.
v2: Use bool variables (Daniel)
v3: Fix Interrupt masking bit (Deepak)
Signed-off-by: Deepak S <deepak.s@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 3 +++
drivers/gpu/drm/i915/i915_irq.c | 31 +++++++++++++++++++++++++++++--
drivers/gpu/drm/i915/intel_pm.c | 3 +++
3 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index cc8afff..d49e674 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -943,6 +943,9 @@ struct intel_gen6_power_mgmt {
u8 rp0_delay;
u8 hw_max;
+ bool rp_up_masked;
+ bool rp_down_masked;
+
int last_adj;
enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 1d44c79..e87d47a 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -988,7 +988,20 @@ static void gen6_pm_rps_work(struct work_struct *work)
adj *= 2;
else
adj = 1;
- new_delay = dev_priv->rps.cur_delay + adj;
+
+ if (dev_priv->rps.cur_delay >= dev_priv->rps.max_delay) {
+ I915_WRITE(GEN6_PMINTRMSK,
+ I915_READ(GEN6_PMINTRMSK) | 1 << 5);
+ dev_priv->rps.rp_up_masked = true;
+ new_delay = dev_priv->rps.cur_delay;
+ } else
+ new_delay = dev_priv->rps.cur_delay + adj;
+
+ if (dev_priv->rps.rp_down_masked) {
+ I915_WRITE(GEN6_PMINTRMSK,
+ I915_READ(GEN6_PMINTRMSK) & ~(1 << 4));
+ dev_priv->rps.rp_down_masked = false;
+ }
/*
* For better performance, jump directly
@@ -1007,7 +1020,21 @@ static void gen6_pm_rps_work(struct work_struct *work)
adj *= 2;
else
adj = -1;
- new_delay = dev_priv->rps.cur_delay + adj;
+
+ if (dev_priv->rps.cur_delay <= dev_priv->rps.min_delay) {
+ I915_WRITE(GEN6_PMINTRMSK,
+ I915_READ(GEN6_PMINTRMSK) | 1 << 4);
+ dev_priv->rps.rp_down_masked = true;
+ new_delay = dev_priv->rps.cur_delay;
+ } else
+ new_delay = dev_priv->rps.cur_delay + adj;
+
+ if (dev_priv->rps.rp_up_masked) {
+ I915_WRITE(GEN6_PMINTRMSK,
+ I915_READ(GEN6_PMINTRMSK) & ~(1 << 5));
+ dev_priv->rps.rp_up_masked = false;
+ }
+
} else { /* unknown event */
new_delay = dev_priv->rps.cur_delay;
}
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 469170c..9c950e4 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3628,6 +3628,9 @@ static void valleyview_enable_rps(struct drm_device *dev)
vlv_gpu_freq(dev_priv, dev_priv->rps.rpe_delay),
dev_priv->rps.rpe_delay);
+ dev_priv->rps.rp_up_masked = false;
+ dev_priv->rps.rp_down_masked = false;
+
valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay);
gen6_enable_rps_interrupts(dev);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 2/3] drm/i915/vlv: WA to fix Voltage not getting dropped to Vmin when Gfx is power gated.
2014-01-09 14:01 [PATCH v2 0/3] VLV Turbo/rps + RC6 workaround deepak.s
2014-01-09 14:01 ` [PATCH v3 1/3] drm/i915: Disable/Enable PM Intrrupts based on the current freq deepak.s
@ 2014-01-09 14:01 ` deepak.s
2014-01-13 22:53 ` Jesse Barnes
2014-01-09 14:01 ` [PATCH 3/3] drm/i915/vlv: WA for Turbo and RC6 to work together deepak.s
2 siblings, 1 reply; 10+ messages in thread
From: deepak.s @ 2014-01-09 14:01 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak S
From: Deepak S <deepak.s@intel.com>
When we enter RC6 and GFX Clocks are off, the voltage remains higher
than Vmin. When we try to set the freq to RPe, it might fail since the
Gfx clocks are down. So to fix this in Gfx idle, Bring the GFX clock up
and set the freq to RPe then move GFx down.
v2: remove vlv_update_rps_cur_delay function. Update commit message (Daniel)
Signed-off-by: Deepak S <deepak.s@intel.com>
---
drivers/gpu/drm/i915/i915_reg.h | 4 ++++
drivers/gpu/drm/i915/intel_pm.c | 48 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index a699efd..e37831f 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4940,6 +4940,10 @@
GEN6_PM_RP_DOWN_THRESHOLD | \
GEN6_PM_RP_DOWN_TIMEOUT)
+#define VLV_GTLC_SURVIVABILITY_REG 0x130098
+#define VLV_GFX_CLK_STATUS_BIT (1<<3)
+#define VLV_GFX_CLK_FORCE_ON_BIT (1<<2)
+
#define GEN6_GT_GFX_RC6_LOCKED 0x138104
#define VLV_COUNTER_CONTROL 0x138104
#define VLV_COUNT_RANGE_HIGH (1<<15)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 9c950e4..a8e05fe 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3050,6 +3050,51 @@ void gen6_set_rps(struct drm_device *dev, u8 val)
trace_intel_gpu_freq_change(val * 50);
}
+/* vlv_set_rps_idle: Set the frequency to Rpe if Gfx clocks are down
+ *
+ * * If Gfx is Idle, then
+ * 1. Mask Turbo interrupts
+ * 2. Bring up Gfx clock
+ * 3. Change the freq to Rpe and wait till P-Unit updates freq
+ * 4. Clear the Force GFX CLK ON bit so that Gfx can down
+ * 5. Unmask Turbo interrupts
+*/
+static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
+{
+ /*
+ * When we are idle. Drop to min voltage state.
+ */
+
+ if (dev_priv->rps.cur_delay == dev_priv->rps.rpe_delay)
+ return;
+
+ /* Mask turbo interrupt so that they will not come in between */
+ I915_WRITE(GEN6_PMINTRMSK, 0xffffffff);
+
+ /* Bring up the Gfx clock */
+ I915_WRITE(VLV_GTLC_SURVIVABILITY_REG,
+ I915_READ(VLV_GTLC_SURVIVABILITY_REG) |
+ VLV_GFX_CLK_FORCE_ON_BIT);
+
+ if (wait_for_atomic(((VLV_GFX_CLK_STATUS_BIT &
+ I915_READ(VLV_GTLC_SURVIVABILITY_REG)) != 0), 500)) {
+ DRM_ERROR("GFX_CLK_ON request timed out\n");
+ return;
+ }
+
+ valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay);
+
+ /* Release the Gfx clock */
+ I915_WRITE(VLV_GTLC_SURVIVABILITY_REG,
+ I915_READ(VLV_GTLC_SURVIVABILITY_REG) &
+ ~VLV_GFX_CLK_FORCE_ON_BIT);
+
+ /* Unmask Turbo interrupts */
+ I915_WRITE(GEN6_PMINTRMSK, ~GEN6_PM_RPS_EVENTS);
+}
+
+
+
void gen6_rps_idle(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = dev_priv->dev;
@@ -3057,7 +3102,7 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
mutex_lock(&dev_priv->rps.hw_lock);
if (dev_priv->rps.enabled) {
if (IS_VALLEYVIEW(dev))
- valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_delay);
+ vlv_set_rps_idle(dev_priv);
else
gen6_set_rps(dev_priv->dev, dev_priv->rps.min_delay);
dev_priv->rps.last_adj = 0;
@@ -4288,6 +4333,7 @@ void intel_gpu_ips_teardown(void)
i915_mch_dev = NULL;
spin_unlock_irq(&mchdev_lock);
}
+
static void intel_init_emon(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
--
1.8.4.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3] drm/i915/vlv: WA for Turbo and RC6 to work together.
2014-01-09 14:01 [PATCH v2 0/3] VLV Turbo/rps + RC6 workaround deepak.s
2014-01-09 14:01 ` [PATCH v3 1/3] drm/i915: Disable/Enable PM Intrrupts based on the current freq deepak.s
2014-01-09 14:01 ` [PATCH v2 2/3] drm/i915/vlv: WA to fix Voltage not getting dropped to Vmin when Gfx is power gated deepak.s
@ 2014-01-09 14:01 ` deepak.s
2 siblings, 0 replies; 10+ messages in thread
From: deepak.s @ 2014-01-09 14:01 UTC (permalink / raw)
To: intel-gfx; +Cc: Deepak S
From: Deepak S <deepak.s@intel.com>
With RC6 enabled, BYT has an HW issue in determining the right
Gfx busyness.
WA for Turbo + RC6: Use SW based Gfx busy-ness detection to decide
on increasing/decreasing the freq. This logic will monitor C0
counters of render/media power-wells over EI period and takes
necessary action based on these values
Signed-off-by: Deepak S <deepak.s@intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 13 ++++
drivers/gpu/drm/i915/i915_irq.c | 151 ++++++++++++++++++++++++++++++++++++++--
drivers/gpu/drm/i915/i915_reg.h | 19 +++++
drivers/gpu/drm/i915/intel_pm.c | 53 ++++++++++----
4 files changed, 219 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d49e674..0bb4aa6 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -942,10 +942,23 @@ struct intel_gen6_power_mgmt {
u8 rp1_delay;
u8 rp0_delay;
u8 hw_max;
+ u8 hw_min;
bool rp_up_masked;
bool rp_down_masked;
+ u32 cz_freq;
+ u32 ei_interrupt_count;
+
+ u32 cz_ts_up_ei;
+ u32 render_up_EI_C0;
+ u32 media_up_EI_C0;
+ u32 cz_ts_down_ei;
+ u32 render_down_EI_C0;
+ u32 media_down_EI_C0;
+
+ bool use_RC0_residency_for_turbo;
+
int last_adj;
enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index e87d47a..f6adc0b3 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -960,6 +960,123 @@ static void notify_ring(struct drm_device *dev,
i915_queue_hangcheck(dev);
}
+/**
+ * vlv_calc_delay_from_C0_counters - Increase/Decrease freq based on GPU
+ * busy-ness calculated from C0 counters of render & media power wells
+ * @dev_priv: DRM device private
+ *
+ */
+static u32 vlv_calc_delay_from_C0_counters(struct drm_i915_private *dev_priv)
+{
+ u32 cz_ts = 0;
+ u32 render_count = 0, media_count = 0;
+ u32 elapsed_render = 0, elapsed_media = 0;
+ u32 elapsed_time = 0;
+ u32 residency_C0_up = 0, residency_C0_down = 0;
+ u8 new_delay;
+
+ dev_priv->rps.ei_interrupt_count++;
+
+ WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+ cz_ts = vlv_punit_read(dev_priv, PUNIT_REG_CZ_TIMESTAMP);
+
+ render_count = I915_READ(VLV_RENDER_C0_COUNT_REG);
+ media_count = I915_READ(VLV_MEDIA_C0_COUNT_REG);
+
+ if (0 == dev_priv->rps.cz_ts_up_ei) {
+
+ dev_priv->rps.cz_ts_up_ei = dev_priv->rps.cz_ts_down_ei = cz_ts;
+ dev_priv->rps.render_up_EI_C0 = dev_priv->rps.render_down_EI_C0
+ = render_count;
+ dev_priv->rps.media_up_EI_C0 = dev_priv->rps.media_down_EI_C0
+ = media_count;
+
+ return dev_priv->rps.cur_delay;
+ }
+
+ elapsed_time = cz_ts - dev_priv->rps.cz_ts_up_ei;
+ dev_priv->rps.cz_ts_up_ei = cz_ts;
+
+ elapsed_render = render_count - dev_priv->rps.render_up_EI_C0;
+ dev_priv->rps.render_up_EI_C0 = render_count;
+
+ elapsed_media = media_count - dev_priv->rps.media_up_EI_C0;
+ dev_priv->rps.media_up_EI_C0 = media_count;
+
+ /* Convert all the counters into common unit of milli sec */
+ elapsed_time /= VLV_CZ_CLOCK_TO_MILLI_SEC;
+ elapsed_render /= (dev_priv->rps.cz_freq / 1000);
+ elapsed_media /= (dev_priv->rps.cz_freq / 1000);
+
+ /* Calculate overall C0 residency percentage only
+ * if elapsed time is non zero
+ */
+ if (elapsed_time) {
+ residency_C0_up = ((max(elapsed_render, elapsed_media)
+ * 100) / elapsed_time);
+ }
+
+ /* To down throttle, C0 residency should be less than down threshold
+ * for continous EI intervals. So calculate down EI counters
+ * once in VLV_INT_COUNT_FOR_DOWN_EI
+ */
+ if (VLV_INT_COUNT_FOR_DOWN_EI == dev_priv->rps.ei_interrupt_count) {
+
+ dev_priv->rps.ei_interrupt_count = 0;
+
+ elapsed_time = cz_ts - dev_priv->rps.cz_ts_down_ei;
+ dev_priv->rps.cz_ts_down_ei = cz_ts;
+
+ elapsed_render = render_count - dev_priv->rps.render_down_EI_C0;
+ dev_priv->rps.render_down_EI_C0 = render_count;
+
+ elapsed_media = media_count - dev_priv->rps.media_down_EI_C0;
+ dev_priv->rps.media_down_EI_C0 = media_count;
+
+ /* Convert all the counters into common unit of milli sec */
+ elapsed_time /= 100000;
+ elapsed_render /= (dev_priv->rps.cz_freq / 1000);
+ elapsed_media /= (dev_priv->rps.cz_freq / 1000);
+
+ /* Calculate overall C0 residency percentage only
+ * if elapsed time is non zero
+ */
+ if (elapsed_time) {
+ residency_C0_down =
+ ((max(elapsed_render, elapsed_media) * 100)
+ / elapsed_time);
+ }
+
+ }
+
+ new_delay = dev_priv->rps.cur_delay;
+
+ /* C0 residency is greater than UP threshold. Increase Frequency */
+ if (residency_C0_up >= VLV_RP_UP_EI_THRESHOLD) {
+
+ if (dev_priv->rps.cur_delay < dev_priv->rps.max_delay)
+ new_delay = dev_priv->rps.cur_delay + 1;
+
+ /*
+ * For better performance, jump directly
+ * to RPe if we're below it.
+ */
+ if (new_delay < dev_priv->rps.rpe_delay)
+ new_delay = dev_priv->rps.rpe_delay;
+
+ } else if (!dev_priv->rps.ei_interrupt_count &&
+ (residency_C0_down < VLV_RP_DOWN_EI_THRESHOLD)) {
+ /* This means, C0 residency is less than down threshold over
+ * a period of VLV_INT_COUNT_FOR_DOWN_EI. So, reduce the freq
+ */
+ if (dev_priv->rps.cur_delay > dev_priv->rps.min_delay)
+ new_delay = dev_priv->rps.cur_delay - 1;
+ }
+
+ return new_delay;
+}
+
static void gen6_pm_rps_work(struct work_struct *work)
{
drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
@@ -971,15 +1088,18 @@ static void gen6_pm_rps_work(struct work_struct *work)
pm_iir = dev_priv->rps.pm_iir;
dev_priv->rps.pm_iir = 0;
/* Make sure not to corrupt PMIMR state used by ringbuffer code */
- snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS);
+ if (dev_priv->rps.use_RC0_residency_for_turbo)
+ snb_enable_pm_irq(dev_priv, GEN6_PM_RP_UP_EI_EXPIRED);
+ else
+ snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS);
+
spin_unlock_irq(&dev_priv->irq_lock);
/* Make sure we didn't queue anything we're not going to process. */
- WARN_ON(pm_iir & ~GEN6_PM_RPS_EVENTS);
+ WARN_ON(pm_iir & ~(GEN6_PM_RPS_EVENTS | GEN6_PM_RP_UP_EI_EXPIRED));
- if ((pm_iir & GEN6_PM_RPS_EVENTS) == 0)
+ if ((pm_iir & (GEN6_PM_RPS_EVENTS | GEN6_PM_RP_UP_EI_EXPIRED)) == 0)
return;
-
mutex_lock(&dev_priv->rps.hw_lock);
adj = dev_priv->rps.last_adj;
@@ -1015,6 +1135,8 @@ static void gen6_pm_rps_work(struct work_struct *work)
else
new_delay = dev_priv->rps.min_delay;
adj = 0;
+ } else if (pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) {
+ new_delay = vlv_calc_delay_from_C0_counters(dev_priv);
} else if (pm_iir & GEN6_PM_RP_DOWN_THRESHOLD) {
if (adj < 0)
adj *= 2;
@@ -1424,6 +1546,16 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir)
queue_work(dev_priv->wq, &dev_priv->rps.work);
}
+ if (pm_iir & GEN6_PM_RP_UP_EI_EXPIRED) {
+ spin_lock(&dev_priv->irq_lock);
+ dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RP_UP_EI_EXPIRED;
+ snb_disable_pm_irq(dev_priv, pm_iir & GEN6_PM_RP_UP_EI_EXPIRED);
+ spin_unlock(&dev_priv->irq_lock);
+ DRM_DEBUG_DRIVER("\nQueueing RPS Work - RC6 WA Turbo");
+
+ queue_work(dev_priv->wq, &dev_priv->rps.work);
+ }
+
if (HAS_VEBOX(dev_priv->dev)) {
if (pm_iir & PM_VEBOX_USER_INTERRUPT)
notify_ring(dev_priv->dev, &dev_priv->ring[VECS]);
@@ -1509,7 +1641,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS)
gmbus_irq_handler(dev);
- if (pm_iir)
+ if (pm_iir & (GEN6_PM_RPS_EVENTS | GEN6_PM_RP_UP_EI_EXPIRED))
gen6_rps_irq_handler(dev_priv, pm_iir);
I915_WRITE(GTIIR, gt_iir);
@@ -2833,6 +2965,15 @@ static void gen5_gt_irq_postinstall(struct drm_device *dev)
pm_irqs |= PM_VEBOX_USER_INTERRUPT;
dev_priv->pm_irq_mask = 0xffffffff;
+
+ if (dev_priv->rps.use_RC0_residency_for_turbo) {
+ dev_priv->pm_irq_mask &= ~GEN6_PM_RP_UP_EI_EXPIRED;
+ pm_irqs |= GEN6_PM_RP_UP_EI_EXPIRED;
+ } else {
+ dev_priv->pm_irq_mask &= ~GEN6_PM_RPS_EVENTS;
+ pm_irqs |= GEN6_PM_RPS_EVENTS;
+ }
+
I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR));
I915_WRITE(GEN6_PMIMR, dev_priv->pm_irq_mask);
I915_WRITE(GEN6_PMIER, pm_irqs);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index e37831f..370e8d6 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -391,6 +391,7 @@
#define PUNIT_REG_GPU_FREQ_STS 0xd8
#define GENFREQSTATUS (1<<0)
#define PUNIT_REG_MEDIA_TURBO_FREQ_REQ 0xdc
+#define PUNIT_REG_CZ_TIMESTAMP 0xce
#define PUNIT_FUSE_BUS2 0xf6 /* bits 47:40 */
#define PUNIT_FUSE_BUS1 0xf5 /* bits 55:48 */
@@ -406,6 +407,15 @@
#define FB_FMAX_VMIN_FREQ_LO_SHIFT 27
#define FB_FMAX_VMIN_FREQ_LO_MASK 0xf8000000
+#define VLV_CZ_CLOCK_FREQ_DDR_MODE_800 200000000
+#define VLV_CZ_CLOCK_FREQ_DDR_MODE_1066 266666666
+#define VLV_CZ_CLOCK_FREQ_DDR_MODE_1333 333333333
+
+#define VLV_CZ_CLOCK_TO_MILLI_SEC 100000
+#define VLV_RP_UP_EI_THRESHOLD 90
+#define VLV_RP_DOWN_EI_THRESHOLD 70
+#define VLV_INT_COUNT_FOR_DOWN_EI 5
+
/* vlv2 north clock has */
#define CCK_FUSE_REG 0x8
#define CCK_FUSE_HPLL_FREQ_MASK 0x3
@@ -4822,6 +4832,7 @@
#define FORCEWAKE_ACK 0x130090
#define VLV_GTLC_WAKE_CTRL 0x130090
#define VLV_GTLC_PW_STATUS 0x130094
+#define VLV_GTLC_SURVIVABILITY_REG 0x130098
#define FORCEWAKE_MT 0xa188 /* multi-threaded */
#define FORCEWAKE_KERNEL 0x1
#define FORCEWAKE_USER 0x2
@@ -4829,6 +4840,11 @@
#define ECOBUS 0xa180
#define FORCEWAKE_MT_ENABLE (1<<5)
+#define VLV_GFX_CLK_FORCE_ON_BIT (1<<2)
+#define VLV_GFX_CLK_STATUS_BIT (1<<3)
+
+#define VLV_RC_COUNTER_CONTROL 0xFFFF00FF
+
#define GTFIFODBG 0x120000
#define GT_FIFO_SBDROPERR (1<<6)
#define GT_FIFO_BLOBDROPERR (1<<5)
@@ -4944,6 +4960,9 @@
#define VLV_GFX_CLK_STATUS_BIT (1<<3)
#define VLV_GFX_CLK_FORCE_ON_BIT (1<<2)
+#define VLV_RENDER_C0_COUNT_REG 0x138118
+#define VLV_MEDIA_C0_COUNT_REG 0x13811C
+
#define GEN6_GT_GFX_RC6_LOCKED 0x138104
#define VLV_COUNTER_CONTROL 0x138104
#define VLV_COUNT_RANGE_HIGH (1<<15)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index a8e05fe..7706552 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3090,7 +3090,11 @@ static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
~VLV_GFX_CLK_FORCE_ON_BIT);
/* Unmask Turbo interrupts */
- I915_WRITE(GEN6_PMINTRMSK, ~GEN6_PM_RPS_EVENTS);
+ if (dev_priv->rps.use_RC0_residency_for_turbo)
+ I915_WRITE(GEN6_PMINTRMSK, ~GEN6_PM_RP_UP_EI_EXPIRED);
+ else
+ I915_WRITE(GEN6_PMINTRMSK, ~GEN6_PM_RPS_EVENTS);
+
}
@@ -3153,7 +3157,13 @@ static void gen6_disable_rps_interrupts(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
I915_WRITE(GEN6_PMINTRMSK, 0xffffffff);
- I915_WRITE(GEN6_PMIER, I915_READ(GEN6_PMIER) & ~GEN6_PM_RPS_EVENTS);
+ if (dev_priv->rps.use_RC0_residency_for_turbo) {
+ I915_WRITE(GEN6_PMIER, I915_READ(GEN6_PMIER) &
+ ~GEN6_PM_RP_UP_EI_EXPIRED);
+ } else {
+ I915_WRITE(GEN6_PMIER, I915_READ(GEN6_PMIER) &
+ ~GEN6_PM_RPS_EVENTS);
+ }
/* Complete PM interrupt masking here doesn't race with the rps work
* item again unmasking PM interrupts because that is using a different
* register (PMIMR) to mask PM interrupts. The only risk is in leaving
@@ -3163,7 +3173,10 @@ static void gen6_disable_rps_interrupts(struct drm_device *dev)
dev_priv->rps.pm_iir = 0;
spin_unlock_irq(&dev_priv->irq_lock);
- I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS);
+ if (dev_priv->rps.use_RC0_residency_for_turbo)
+ I915_WRITE(GEN6_PMIIR, GEN6_PM_RP_UP_EI_EXPIRED);
+ else
+ I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS);
}
static void gen6_disable_rps(struct drm_device *dev)
@@ -3233,19 +3246,29 @@ static void gen6_enable_rps_interrupts(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
u32 enabled_intrs;
+ /* Clear out any stale interrupts first */
spin_lock_irq(&dev_priv->irq_lock);
WARN_ON(dev_priv->rps.pm_iir);
- snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS);
- I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS);
+ if (dev_priv->rps.use_RC0_residency_for_turbo) {
+ snb_enable_pm_irq(dev_priv, GEN6_PM_RP_UP_EI_EXPIRED);
+ I915_WRITE(GEN6_PMIIR, GEN6_PM_RP_UP_EI_EXPIRED);
+ } else {
+ snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS);
+ I915_WRITE(GEN6_PMIIR, GEN6_PM_RPS_EVENTS);
+ }
spin_unlock_irq(&dev_priv->irq_lock);
/* only unmask PM interrupts we need. Mask all others. */
- enabled_intrs = GEN6_PM_RPS_EVENTS;
+ if (dev_priv->rps.use_RC0_residency_for_turbo)
+ enabled_intrs = GEN6_PM_RP_UP_EI_EXPIRED;
+ else
+ enabled_intrs = GEN6_PM_RPS_EVENTS;
/* IVB and SNB hard hangs on looping batchbuffer
* if GEN6_PM_UP_EI_EXPIRED is masked.
*/
- if (INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev))
+ if (INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev) &&
+ !dev_priv->rps.use_RC0_residency_for_turbo)
enabled_intrs |= GEN6_PM_RP_UP_EI_EXPIRED;
I915_WRITE(GEN6_PMINTRMSK, ~enabled_intrs);
@@ -3632,10 +3655,7 @@ static void valleyview_enable_rps(struct drm_device *dev)
I915_WRITE(GEN6_RC6_THRESHOLD, 0x557);
/* allows RC6 residency counter to work */
- I915_WRITE(VLV_COUNTER_CONTROL,
- _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH |
- VLV_MEDIA_RC6_COUNT_EN |
- VLV_RENDER_RC6_COUNT_EN));
+ I915_WRITE(VLV_COUNTER_CONTROL, VLV_RC_COUNTER_CONTROL);
if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
rc6_mode = GEN7_RC_CTL_TO_MODE | VLV_RC_CTL_CTX_RST_PARALLEL;
@@ -3664,7 +3684,9 @@ static void valleyview_enable_rps(struct drm_device *dev)
vlv_gpu_freq(dev_priv, dev_priv->rps.rpe_delay),
dev_priv->rps.rpe_delay);
- dev_priv->rps.min_delay = valleyview_rps_min_freq(dev_priv);
+ dev_priv->rps.hw_min = valleyview_rps_min_freq(dev_priv);
+
+ dev_priv->rps.min_delay = dev_priv->rps.hw_min;
DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
vlv_gpu_freq(dev_priv, dev_priv->rps.min_delay),
dev_priv->rps.min_delay);
@@ -3678,6 +3700,9 @@ static void valleyview_enable_rps(struct drm_device *dev)
valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay);
+ /* enable WA for RC6+turbo to work together */
+ dev_priv->rps.use_RC0_residency_for_turbo = true;
+
gen6_enable_rps_interrupts(dev);
gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
@@ -4967,15 +4992,19 @@ static void valleyview_init_clock_gating(struct drm_device *dev)
switch ((val >> 6) & 3) {
case 0:
dev_priv->mem_freq = 800;
+ dev_priv->rps.cz_freq = VLV_CZ_CLOCK_FREQ_DDR_MODE_800;
break;
case 1:
dev_priv->mem_freq = 1066;
+ dev_priv->rps.cz_freq = VLV_CZ_CLOCK_FREQ_DDR_MODE_1066;
break;
case 2:
dev_priv->mem_freq = 1333;
+ dev_priv->rps.cz_freq = VLV_CZ_CLOCK_FREQ_DDR_MODE_1333;
break;
case 3:
dev_priv->mem_freq = 1333;
+ dev_priv->rps.cz_freq = VLV_CZ_CLOCK_FREQ_DDR_MODE_1333;
break;
}
DRM_DEBUG_DRIVER("DDR speed: %d MHz", dev_priv->mem_freq);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2 2/3] drm/i915/vlv: WA to fix Voltage not getting dropped to Vmin when Gfx is power gated.
2014-01-09 14:01 ` [PATCH v2 2/3] drm/i915/vlv: WA to fix Voltage not getting dropped to Vmin when Gfx is power gated deepak.s
@ 2014-01-13 22:53 ` Jesse Barnes
2014-01-14 9:12 ` S, Deepak
0 siblings, 1 reply; 10+ messages in thread
From: Jesse Barnes @ 2014-01-13 22:53 UTC (permalink / raw)
To: deepak.s; +Cc: intel-gfx
On Thu, 9 Jan 2014 19:31:09 +0530
deepak.s@intel.com wrote:
> From: Deepak S <deepak.s@intel.com>
>
> When we enter RC6 and GFX Clocks are off, the voltage remains higher
> than Vmin. When we try to set the freq to RPe, it might fail since the
> Gfx clocks are down. So to fix this in Gfx idle, Bring the GFX clock up
> and set the freq to RPe then move GFx down.
>
> v2: remove vlv_update_rps_cur_delay function. Update commit message (Daniel)
>
> Signed-off-by: Deepak S <deepak.s@intel.com>
> ---
> drivers/gpu/drm/i915/i915_reg.h | 4 ++++
> drivers/gpu/drm/i915/intel_pm.c | 48 ++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index a699efd..e37831f 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4940,6 +4940,10 @@
> GEN6_PM_RP_DOWN_THRESHOLD | \
> GEN6_PM_RP_DOWN_TIMEOUT)
>
> +#define VLV_GTLC_SURVIVABILITY_REG 0x130098
> +#define VLV_GFX_CLK_STATUS_BIT (1<<3)
> +#define VLV_GFX_CLK_FORCE_ON_BIT (1<<2)
> +
> #define GEN6_GT_GFX_RC6_LOCKED 0x138104
> #define VLV_COUNTER_CONTROL 0x138104
> #define VLV_COUNT_RANGE_HIGH (1<<15)
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 9c950e4..a8e05fe 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3050,6 +3050,51 @@ void gen6_set_rps(struct drm_device *dev, u8 val)
> trace_intel_gpu_freq_change(val * 50);
> }
>
> +/* vlv_set_rps_idle: Set the frequency to Rpe if Gfx clocks are down
> + *
> + * * If Gfx is Idle, then
> + * 1. Mask Turbo interrupts
> + * 2. Bring up Gfx clock
> + * 3. Change the freq to Rpe and wait till P-Unit updates freq
> + * 4. Clear the Force GFX CLK ON bit so that Gfx can down
> + * 5. Unmask Turbo interrupts
> +*/
> +static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
> +{
> + /*
> + * When we are idle. Drop to min voltage state.
> + */
> +
> + if (dev_priv->rps.cur_delay == dev_priv->rps.rpe_delay)
> + return;
> +
> + /* Mask turbo interrupt so that they will not come in between */
> + I915_WRITE(GEN6_PMINTRMSK, 0xffffffff);
> +
> + /* Bring up the Gfx clock */
> + I915_WRITE(VLV_GTLC_SURVIVABILITY_REG,
> + I915_READ(VLV_GTLC_SURVIVABILITY_REG) |
> + VLV_GFX_CLK_FORCE_ON_BIT);
> +
> + if (wait_for_atomic(((VLV_GFX_CLK_STATUS_BIT &
> + I915_READ(VLV_GTLC_SURVIVABILITY_REG)) != 0), 500)) {
> + DRM_ERROR("GFX_CLK_ON request timed out\n");
> + return;
> + }
> +
> + valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay);
> +
> + /* Release the Gfx clock */
> + I915_WRITE(VLV_GTLC_SURVIVABILITY_REG,
> + I915_READ(VLV_GTLC_SURVIVABILITY_REG) &
> + ~VLV_GFX_CLK_FORCE_ON_BIT);
> +
> + /* Unmask Turbo interrupts */
> + I915_WRITE(GEN6_PMINTRMSK, ~GEN6_PM_RPS_EVENTS);
> +}
> +
> +
> +
> void gen6_rps_idle(struct drm_i915_private *dev_priv)
> {
> struct drm_device *dev = dev_priv->dev;
> @@ -3057,7 +3102,7 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
> mutex_lock(&dev_priv->rps.hw_lock);
> if (dev_priv->rps.enabled) {
> if (IS_VALLEYVIEW(dev))
> - valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_delay);
> + vlv_set_rps_idle(dev_priv);
> else
> gen6_set_rps(dev_priv->dev, dev_priv->rps.min_delay);
> dev_priv->rps.last_adj = 0;
> @@ -4288,6 +4333,7 @@ void intel_gpu_ips_teardown(void)
> i915_mch_dev = NULL;
> spin_unlock_irq(&mchdev_lock);
> }
> +
> static void intel_init_emon(struct drm_device *dev)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
Yeah if we need to bring the gfx clocks up (which makes sense) then I
guess we need this. I'm not sure about the wait on the punit though;
that could end up penalizing us in bursty workloads, since the punit
can take quite some time to update the freq, but I don't actually see a
wait here?
Also, is the 500ms timeout really required for the gfx clock? That's a
long time to potentially hold the mutex and delay any clock boosting or
other activity...
--
Jesse Barnes, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/3] drm/i915: Disable/Enable PM Intrrupts based on the current freq.
2014-01-09 14:01 ` [PATCH v3 1/3] drm/i915: Disable/Enable PM Intrrupts based on the current freq deepak.s
@ 2014-01-13 23:01 ` Jesse Barnes
2014-01-14 9:21 ` Daniel Vetter
1 sibling, 0 replies; 10+ messages in thread
From: Jesse Barnes @ 2014-01-13 23:01 UTC (permalink / raw)
To: deepak.s; +Cc: intel-gfx
On Thu, 9 Jan 2014 19:31:08 +0530
deepak.s@intel.com wrote:
> From: Deepak S <deepak.s@intel.com>
>
> When current delay is already at max delay, Let's disable the PM UP
> THRESHOLD INTRRUPTS, so that we will not get further interrupts until
> current delay is less than max delay, Also request for the PM DOWN
> THRESHOLD INTRRUPTS to indicate the decrease in clock freq. and
> viceversa for PM DOWN THRESHOLD INTRRUPTS.
>
> v2: Use bool variables (Daniel)
>
> v3: Fix Interrupt masking bit (Deepak)
>
> Signed-off-by: Deepak S <deepak.s@intel.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 3 +++
> drivers/gpu/drm/i915/i915_irq.c | 31 +++++++++++++++++++++++++++++--
> drivers/gpu/drm/i915/intel_pm.c | 3 +++
> 3 files changed, 35 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index cc8afff..d49e674 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -943,6 +943,9 @@ struct intel_gen6_power_mgmt {
> u8 rp0_delay;
> u8 hw_max;
>
> + bool rp_up_masked;
> + bool rp_down_masked;
> +
> int last_adj;
> enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 1d44c79..e87d47a 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -988,7 +988,20 @@ static void gen6_pm_rps_work(struct work_struct *work)
> adj *= 2;
> else
> adj = 1;
> - new_delay = dev_priv->rps.cur_delay + adj;
> +
> + if (dev_priv->rps.cur_delay >= dev_priv->rps.max_delay) {
> + I915_WRITE(GEN6_PMINTRMSK,
> + I915_READ(GEN6_PMINTRMSK) | 1 << 5);
> + dev_priv->rps.rp_up_masked = true;
> + new_delay = dev_priv->rps.cur_delay;
> + } else
> + new_delay = dev_priv->rps.cur_delay + adj;
> +
> + if (dev_priv->rps.rp_down_masked) {
> + I915_WRITE(GEN6_PMINTRMSK,
> + I915_READ(GEN6_PMINTRMSK) & ~(1 << 4));
> + dev_priv->rps.rp_down_masked = false;
> + }
I've looked at this too much and confused myself. It looks like the
old logic of the delay numbers being in reverse order has changed
(or maybe that was just ILK?)... so I guess the above
is ok (I was afraid we'd end up masking on the first interrupt
everytime).
So:
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Thanks,
Jesse
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 2/3] drm/i915/vlv: WA to fix Voltage not getting dropped to Vmin when Gfx is power gated.
2014-01-13 22:53 ` Jesse Barnes
@ 2014-01-14 9:12 ` S, Deepak
0 siblings, 0 replies; 10+ messages in thread
From: S, Deepak @ 2014-01-14 9:12 UTC (permalink / raw)
To: Jesse Barnes; +Cc: intel-gfx@lists.freedesktop.org
[-- Attachment #1: Type: text/plain, Size: 5335 bytes --]
>Yeah if we need to bring the gfx clocks up (which makes sense) then I guess we need this. I'm not sure about the wait on the punit though; that could end up penalizing us in bursty workloads, since the punit can take quite some time to update the freq, but I don't actually see a wait here?
Ville suggested we don't need wait after requesting the freq. " AFAIK the punit will recheck the situation periodically, and it will try to use PUNIT_REG_GPU_FREQ_REQ."
>Also, is the 500ms timeout really required for the gfx clock? That's a long time to potentially hold the mutex and delay any clock boosting or other activity...
Yes agree, we don't need 500ms. I will change the delay to 5ms and submit a new command.
Thanks
Deepak
-----Original Message-----
From: Jesse Barnes [mailto:jbarnes@virtuousgeek.org]
Sent: Tuesday, January 14, 2014 4:23 AM
To: S, Deepak
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH v2 2/3] drm/i915/vlv: WA to fix Voltage not getting dropped to Vmin when Gfx is power gated.
On Thu, 9 Jan 2014 19:31:09 +0530
deepak.s@intel.com wrote:
> From: Deepak S <deepak.s@intel.com>
>
> When we enter RC6 and GFX Clocks are off, the voltage remains higher
> than Vmin. When we try to set the freq to RPe, it might fail since the
> Gfx clocks are down. So to fix this in Gfx idle, Bring the GFX clock
> up and set the freq to RPe then move GFx down.
>
> v2: remove vlv_update_rps_cur_delay function. Update commit message
> (Daniel)
>
> Signed-off-by: Deepak S <deepak.s@intel.com>
> ---
> drivers/gpu/drm/i915/i915_reg.h | 4 ++++
> drivers/gpu/drm/i915/intel_pm.c | 48
> ++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 51 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h index a699efd..e37831f 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4940,6 +4940,10 @@
> GEN6_PM_RP_DOWN_THRESHOLD | \
> GEN6_PM_RP_DOWN_TIMEOUT)
>
> +#define VLV_GTLC_SURVIVABILITY_REG 0x130098
> +#define VLV_GFX_CLK_STATUS_BIT (1<<3)
> +#define VLV_GFX_CLK_FORCE_ON_BIT (1<<2)
> +
> #define GEN6_GT_GFX_RC6_LOCKED 0x138104
> #define VLV_COUNTER_CONTROL 0x138104
> #define VLV_COUNT_RANGE_HIGH (1<<15)
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c index 9c950e4..a8e05fe 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3050,6 +3050,51 @@ void gen6_set_rps(struct drm_device *dev, u8 val)
> trace_intel_gpu_freq_change(val * 50); }
>
> +/* vlv_set_rps_idle: Set the frequency to Rpe if Gfx clocks are down
> + *
> + * * If Gfx is Idle, then
> + * 1. Mask Turbo interrupts
> + * 2. Bring up Gfx clock
> + * 3. Change the freq to Rpe and wait till P-Unit updates freq
> + * 4. Clear the Force GFX CLK ON bit so that Gfx can down
> + * 5. Unmask Turbo interrupts
> +*/
> +static void vlv_set_rps_idle(struct drm_i915_private *dev_priv) {
> + /*
> + * When we are idle. Drop to min voltage state.
> + */
> +
> + if (dev_priv->rps.cur_delay == dev_priv->rps.rpe_delay)
> + return;
> +
> + /* Mask turbo interrupt so that they will not come in between */
> + I915_WRITE(GEN6_PMINTRMSK, 0xffffffff);
> +
> + /* Bring up the Gfx clock */
> + I915_WRITE(VLV_GTLC_SURVIVABILITY_REG,
> + I915_READ(VLV_GTLC_SURVIVABILITY_REG) |
> + VLV_GFX_CLK_FORCE_ON_BIT);
> +
> + if (wait_for_atomic(((VLV_GFX_CLK_STATUS_BIT &
> + I915_READ(VLV_GTLC_SURVIVABILITY_REG)) != 0), 500)) {
> + DRM_ERROR("GFX_CLK_ON request timed out\n");
> + return;
> + }
> +
> + valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay);
> +
> + /* Release the Gfx clock */
> + I915_WRITE(VLV_GTLC_SURVIVABILITY_REG,
> + I915_READ(VLV_GTLC_SURVIVABILITY_REG) &
> + ~VLV_GFX_CLK_FORCE_ON_BIT);
> +
> + /* Unmask Turbo interrupts */
> + I915_WRITE(GEN6_PMINTRMSK, ~GEN6_PM_RPS_EVENTS); }
> +
> +
> +
> void gen6_rps_idle(struct drm_i915_private *dev_priv) {
> struct drm_device *dev = dev_priv->dev; @@ -3057,7 +3102,7 @@ void
> gen6_rps_idle(struct drm_i915_private *dev_priv)
> mutex_lock(&dev_priv->rps.hw_lock);
> if (dev_priv->rps.enabled) {
> if (IS_VALLEYVIEW(dev))
> - valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_delay);
> + vlv_set_rps_idle(dev_priv);
> else
> gen6_set_rps(dev_priv->dev, dev_priv->rps.min_delay);
> dev_priv->rps.last_adj = 0;
> @@ -4288,6 +4333,7 @@ void intel_gpu_ips_teardown(void)
> i915_mch_dev = NULL;
> spin_unlock_irq(&mchdev_lock);
> }
> +
> static void intel_init_emon(struct drm_device *dev) {
> struct drm_i915_private *dev_priv = dev->dev_private;
Yeah if we need to bring the gfx clocks up (which makes sense) then I guess we need this. I'm not sure about the wait on the punit though; that could end up penalizing us in bursty workloads, since the punit can take quite some time to update the freq, but I don't actually see a wait here?
Also, is the 500ms timeout really required for the gfx clock? That's a long time to potentially hold the mutex and delay any clock boosting or other activity...
--
Jesse Barnes, Intel Open Source Technology Center
[-- Attachment #2: Type: message/rfc822, Size: 7053 bytes --]
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: "S, Deepak" <deepak.s@intel.com>
Cc: "intel-gfx@lists.freedesktop.org" <intel-gfx@lists.freedesktop.org>
Subject: Re: [Intel-gfx] [PATCH 1/4] drm/i915: update current freq properly before requesting new freq.
Date: Mon, 9 Dec 2013 10:03:45 +0000
Message-ID: <20131209100345.GG10036@intel.com>
On Sun, Dec 08, 2013 at 02:16:43PM +0530, deepak.s@intel.com wrote:
> From: Deepak S <deepak.s@intel.com>
>
> on VLV, P-Unit doesn't garauntee that last requested freq by driver
> is actually the current running frequency. We need to make sure we update
> the cur freq. before requesitng new freq.
>
> Signed-off-by: Deepak S <deepak.s@intel.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 1 +
> drivers/gpu/drm/i915/i915_irq.c | 8 ++++++++
> drivers/gpu/drm/i915/intel_pm.c | 31 +++++++++++++++++++++++++++++++
> 3 files changed, 40 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 780f815..a62ac0c 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -2416,6 +2416,7 @@ 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);
> extern void valleyview_set_rps(struct drm_device *dev, u8 val);
> +extern bool vlv_update_rps_cur_delay(struct drm_i915_private *dev_priv);
> extern int valleyview_rps_max_freq(struct drm_i915_private *dev_priv);
> extern int valleyview_rps_min_freq(struct drm_i915_private *dev_priv);
> extern void intel_detect_pch(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 2715600..4bde03a 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -982,6 +982,14 @@ static void gen6_pm_rps_work(struct work_struct *work)
>
> mutex_lock(&dev_priv->rps.hw_lock);
>
> + /* Make sure we have current freq updated properly. Doing this
> + * here becuase, on VLV, P-Unit doesnt garauntee that last requested
> + * freq by driver is actually the current running frequency
> + */
> +
> + if (IS_VALLEYVIEW(dev_priv->dev))
> + vlv_update_rps_cur_delay(dev_priv);
> +
> adj = dev_priv->rps.last_adj;
> if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
> if (adj > 0)
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index e6d98fe..7f6c747 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3607,6 +3607,35 @@ void gen6_rps_boost(struct drm_i915_private *dev_priv)
> mutex_unlock(&dev_priv->rps.hw_lock);
> }
>
> +/*
> + * Wait until the previous freq change has completed,
> + * or the timeout elapsed, and then update our notion
> + * of the current GPU frequency.
> + */
> +bool vlv_update_rps_cur_delay(struct drm_i915_private *dev_priv)
> +{
> + u32 pval;
> +
> + WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
> +
> + if (wait_for(((pval = vlv_punit_read(dev_priv,
> + PUNIT_REG_GPU_FREQ_STS)) &
> + GENFREQSTATUS) == 0, 10))
> + DRM_DEBUG_DRIVER("timed out waiting for Punit\n");
> +
> + pval >>= 8;
> +
> + if (pval != dev_priv->rps.cur_delay)
> + DRM_DEBUG_DRIVER("Punit overrode GPU freq: %d MHz (%u) requested, but got %d Mhz (%u)\n",
> + vlv_gpu_freq(dev_priv, dev_priv->rps.cur_delay),
> + dev_priv->rps.cur_delay,
> + vlv_gpu_freq(dev_priv, pval), pval);
> +
> + dev_priv->rps.cur_delay = pval;
> + return true;
> +}
I just killed this guys a while ago. If you think we need to resurrect
it, you should do it w/ git revert to make it clear where it came from.
But I'd want more justification than what you have provided. My
understanding is that PUNIT_REG_GPU_FREQ_STS alwasy reflects the
current operating frequency of the GPU, and that can be affected by
thermal conditions (and media turbo, which I'll ignore for simplicity)
in addition to the frequency requested by the driver. AFAIK the punit
will recheck the situation periodically, and it will try to use
PUNIT_REG_GPU_FREQ_REQ. It will check the thermal conditions to
figure out if it needs to further limit the frequency. Once the
thermal conditions permit it, the frequency should return back to the
last requested turbo frequency, without the driver having to rewrite
PUNIT_REG_GPU_FREQ_REQ.
If I'm right updating cur_delay based on PUNIT_REG_GPU_FREQ_STS is
clearly the wrong thing to do. So I think we need more details on
what the punit does in order to figure out what's the right thing
to do here.
> +
> +
> void valleyview_set_rps(struct drm_device *dev, u8 val)
> {
> struct drm_i915_private *dev_priv = dev->dev_private;
> @@ -3615,6 +3644,8 @@ void valleyview_set_rps(struct drm_device *dev, u8 val)
> WARN_ON(val > dev_priv->rps.max_delay);
> WARN_ON(val < dev_priv->rps.min_delay);
>
> + vlv_update_rps_cur_delay(dev_priv);
> +
> DRM_DEBUG_DRIVER("GPU freq request from %d MHz (%u) to %d MHz (%u)\n",
> vlv_gpu_freq(dev_priv, dev_priv->rps.cur_delay),
> dev_priv->rps.cur_delay,
> --
> 1.8.4.2
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Ville Syrjälä
Intel OTC
[-- Attachment #3: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/3] drm/i915: Disable/Enable PM Intrrupts based on the current freq.
2014-01-09 14:01 ` [PATCH v3 1/3] drm/i915: Disable/Enable PM Intrrupts based on the current freq deepak.s
2014-01-13 23:01 ` Jesse Barnes
@ 2014-01-14 9:21 ` Daniel Vetter
2014-01-14 9:23 ` S, Deepak
2014-01-16 5:47 ` S, Deepak
1 sibling, 2 replies; 10+ messages in thread
From: Daniel Vetter @ 2014-01-14 9:21 UTC (permalink / raw)
To: deepak.s; +Cc: intel-gfx
On Thu, Jan 09, 2014 at 07:31:08PM +0530, deepak.s@intel.com wrote:
> From: Deepak S <deepak.s@intel.com>
>
> When current delay is already at max delay, Let's disable the PM UP
> THRESHOLD INTRRUPTS, so that we will not get further interrupts until
> current delay is less than max delay, Also request for the PM DOWN
> THRESHOLD INTRRUPTS to indicate the decrease in clock freq. and
> viceversa for PM DOWN THRESHOLD INTRRUPTS.
>
> v2: Use bool variables (Daniel)
>
> v3: Fix Interrupt masking bit (Deepak)
>
> Signed-off-by: Deepak S <deepak.s@intel.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 3 +++
> drivers/gpu/drm/i915/i915_irq.c | 31 +++++++++++++++++++++++++++++--
> drivers/gpu/drm/i915/intel_pm.c | 3 +++
> 3 files changed, 35 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index cc8afff..d49e674 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -943,6 +943,9 @@ struct intel_gen6_power_mgmt {
> u8 rp0_delay;
> u8 hw_max;
>
> + bool rp_up_masked;
> + bool rp_down_masked;
> +
> int last_adj;
> enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
> index 1d44c79..e87d47a 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -988,7 +988,20 @@ static void gen6_pm_rps_work(struct work_struct *work)
> adj *= 2;
> else
> adj = 1;
> - new_delay = dev_priv->rps.cur_delay + adj;
> +
> + if (dev_priv->rps.cur_delay >= dev_priv->rps.max_delay) {
> + I915_WRITE(GEN6_PMINTRMSK,
> + I915_READ(GEN6_PMINTRMSK) | 1 << 5);
Please use the symbolic constants in i915_reg.h, we can reuse the ones
below GEN6_PMIER. Also Chris had some comment to move this code around,
but I didn't really understand what he wants. Chris, can you please
clarify?
Thanks, Daniel
> + dev_priv->rps.rp_up_masked = true;
> + new_delay = dev_priv->rps.cur_delay;
> + } else
> + new_delay = dev_priv->rps.cur_delay + adj;
> +
> + if (dev_priv->rps.rp_down_masked) {
> + I915_WRITE(GEN6_PMINTRMSK,
> + I915_READ(GEN6_PMINTRMSK) & ~(1 << 4));
> + dev_priv->rps.rp_down_masked = false;
> + }
>
> /*
> * For better performance, jump directly
> @@ -1007,7 +1020,21 @@ static void gen6_pm_rps_work(struct work_struct *work)
> adj *= 2;
> else
> adj = -1;
> - new_delay = dev_priv->rps.cur_delay + adj;
> +
> + if (dev_priv->rps.cur_delay <= dev_priv->rps.min_delay) {
> + I915_WRITE(GEN6_PMINTRMSK,
> + I915_READ(GEN6_PMINTRMSK) | 1 << 4);
> + dev_priv->rps.rp_down_masked = true;
> + new_delay = dev_priv->rps.cur_delay;
> + } else
> + new_delay = dev_priv->rps.cur_delay + adj;
> +
> + if (dev_priv->rps.rp_up_masked) {
> + I915_WRITE(GEN6_PMINTRMSK,
> + I915_READ(GEN6_PMINTRMSK) & ~(1 << 5));
> + dev_priv->rps.rp_up_masked = false;
> + }
> +
> } else { /* unknown event */
> new_delay = dev_priv->rps.cur_delay;
> }
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 469170c..9c950e4 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3628,6 +3628,9 @@ static void valleyview_enable_rps(struct drm_device *dev)
> vlv_gpu_freq(dev_priv, dev_priv->rps.rpe_delay),
> dev_priv->rps.rpe_delay);
>
> + dev_priv->rps.rp_up_masked = false;
> + dev_priv->rps.rp_down_masked = false;
> +
> valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay);
>
> gen6_enable_rps_interrupts(dev);
> --
> 1.8.4.2
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/3] drm/i915: Disable/Enable PM Intrrupts based on the current freq.
2014-01-14 9:21 ` Daniel Vetter
@ 2014-01-14 9:23 ` S, Deepak
2014-01-16 5:47 ` S, Deepak
1 sibling, 0 replies; 10+ messages in thread
From: S, Deepak @ 2014-01-14 9:23 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx@lists.freedesktop.org
Thanks Daniel. I will wait for Chris feedback and then address the comments.
-----Original Message-----
From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
Sent: Tuesday, January 14, 2014 2:52 PM
To: S, Deepak
Cc: intel-gfx@lists.freedesktop.org; Chris Wilson
Subject: Re: [Intel-gfx] [PATCH v3 1/3] drm/i915: Disable/Enable PM Intrrupts based on the current freq.
On Thu, Jan 09, 2014 at 07:31:08PM +0530, deepak.s@intel.com wrote:
> From: Deepak S <deepak.s@intel.com>
>
> When current delay is already at max delay, Let's disable the PM UP
> THRESHOLD INTRRUPTS, so that we will not get further interrupts until
> current delay is less than max delay, Also request for the PM DOWN
> THRESHOLD INTRRUPTS to indicate the decrease in clock freq. and
> viceversa for PM DOWN THRESHOLD INTRRUPTS.
>
> v2: Use bool variables (Daniel)
>
> v3: Fix Interrupt masking bit (Deepak)
>
> Signed-off-by: Deepak S <deepak.s@intel.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 3 +++
> drivers/gpu/drm/i915/i915_irq.c | 31 +++++++++++++++++++++++++++++--
> drivers/gpu/drm/i915/intel_pm.c | 3 +++
> 3 files changed, 35 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h index cc8afff..d49e674 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -943,6 +943,9 @@ struct intel_gen6_power_mgmt {
> u8 rp0_delay;
> u8 hw_max;
>
> + bool rp_up_masked;
> + bool rp_down_masked;
> +
> int last_adj;
> enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c
> b/drivers/gpu/drm/i915/i915_irq.c index 1d44c79..e87d47a 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -988,7 +988,20 @@ static void gen6_pm_rps_work(struct work_struct *work)
> adj *= 2;
> else
> adj = 1;
> - new_delay = dev_priv->rps.cur_delay + adj;
> +
> + if (dev_priv->rps.cur_delay >= dev_priv->rps.max_delay) {
> + I915_WRITE(GEN6_PMINTRMSK,
> + I915_READ(GEN6_PMINTRMSK) | 1 << 5);
Please use the symbolic constants in i915_reg.h, we can reuse the ones below GEN6_PMIER. Also Chris had some comment to move this code around, but I didn't really understand what he wants. Chris, can you please clarify?
Thanks, Daniel
> + dev_priv->rps.rp_up_masked = true;
> + new_delay = dev_priv->rps.cur_delay;
> + } else
> + new_delay = dev_priv->rps.cur_delay + adj;
> +
> + if (dev_priv->rps.rp_down_masked) {
> + I915_WRITE(GEN6_PMINTRMSK,
> + I915_READ(GEN6_PMINTRMSK) & ~(1 << 4));
> + dev_priv->rps.rp_down_masked = false;
> + }
>
> /*
> * For better performance, jump directly @@ -1007,7 +1020,21 @@
> static void gen6_pm_rps_work(struct work_struct *work)
> adj *= 2;
> else
> adj = -1;
> - new_delay = dev_priv->rps.cur_delay + adj;
> +
> + if (dev_priv->rps.cur_delay <= dev_priv->rps.min_delay) {
> + I915_WRITE(GEN6_PMINTRMSK,
> + I915_READ(GEN6_PMINTRMSK) | 1 << 4);
> + dev_priv->rps.rp_down_masked = true;
> + new_delay = dev_priv->rps.cur_delay;
> + } else
> + new_delay = dev_priv->rps.cur_delay + adj;
> +
> + if (dev_priv->rps.rp_up_masked) {
> + I915_WRITE(GEN6_PMINTRMSK,
> + I915_READ(GEN6_PMINTRMSK) & ~(1 << 5));
> + dev_priv->rps.rp_up_masked = false;
> + }
> +
> } else { /* unknown event */
> new_delay = dev_priv->rps.cur_delay;
> }
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c index 469170c..9c950e4 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3628,6 +3628,9 @@ static void valleyview_enable_rps(struct drm_device *dev)
> vlv_gpu_freq(dev_priv, dev_priv->rps.rpe_delay),
> dev_priv->rps.rpe_delay);
>
> + dev_priv->rps.rp_up_masked = false;
> + dev_priv->rps.rp_down_masked = false;
> +
> valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay);
>
> gen6_enable_rps_interrupts(dev);
> --
> 1.8.4.2
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/3] drm/i915: Disable/Enable PM Intrrupts based on the current freq.
2014-01-14 9:21 ` Daniel Vetter
2014-01-14 9:23 ` S, Deepak
@ 2014-01-16 5:47 ` S, Deepak
1 sibling, 0 replies; 10+ messages in thread
From: S, Deepak @ 2014-01-16 5:47 UTC (permalink / raw)
To: Daniel Vetter; +Cc: intel-gfx@lists.freedesktop.org
>Please use the symbolic constants in i915_reg.h, we can reuse the ones below GEN6_PMIER. Also Chris had some comment to move this code around, but I didn't really understand what he wants. Chris, can you please clarify?
Hi Chris,
Can you please clarify on this?
Thanks
Deepak
-----Original Message-----
From: Daniel Vetter [mailto:daniel.vetter@ffwll.ch] On Behalf Of Daniel Vetter
Sent: Tuesday, January 14, 2014 2:52 PM
To: S, Deepak
Cc: intel-gfx@lists.freedesktop.org; Chris Wilson
Subject: Re: [Intel-gfx] [PATCH v3 1/3] drm/i915: Disable/Enable PM Intrrupts based on the current freq.
On Thu, Jan 09, 2014 at 07:31:08PM +0530, deepak.s@intel.com wrote:
> From: Deepak S <deepak.s@intel.com>
>
> When current delay is already at max delay, Let's disable the PM UP
> THRESHOLD INTRRUPTS, so that we will not get further interrupts until
> current delay is less than max delay, Also request for the PM DOWN
> THRESHOLD INTRRUPTS to indicate the decrease in clock freq. and
> viceversa for PM DOWN THRESHOLD INTRRUPTS.
>
> v2: Use bool variables (Daniel)
>
> v3: Fix Interrupt masking bit (Deepak)
>
> Signed-off-by: Deepak S <deepak.s@intel.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 3 +++
> drivers/gpu/drm/i915/i915_irq.c | 31 +++++++++++++++++++++++++++++--
> drivers/gpu/drm/i915/intel_pm.c | 3 +++
> 3 files changed, 35 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h index cc8afff..d49e674 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -943,6 +943,9 @@ struct intel_gen6_power_mgmt {
> u8 rp0_delay;
> u8 hw_max;
>
> + bool rp_up_masked;
> + bool rp_down_masked;
> +
> int last_adj;
> enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
>
> diff --git a/drivers/gpu/drm/i915/i915_irq.c
> b/drivers/gpu/drm/i915/i915_irq.c index 1d44c79..e87d47a 100644
> --- a/drivers/gpu/drm/i915/i915_irq.c
> +++ b/drivers/gpu/drm/i915/i915_irq.c
> @@ -988,7 +988,20 @@ static void gen6_pm_rps_work(struct work_struct *work)
> adj *= 2;
> else
> adj = 1;
> - new_delay = dev_priv->rps.cur_delay + adj;
> +
> + if (dev_priv->rps.cur_delay >= dev_priv->rps.max_delay) {
> + I915_WRITE(GEN6_PMINTRMSK,
> + I915_READ(GEN6_PMINTRMSK) | 1 << 5);
Please use the symbolic constants in i915_reg.h, we can reuse the ones below GEN6_PMIER. Also Chris had some comment to move this code around, but I didn't really understand what he wants. Chris, can you please clarify?
Thanks, Daniel
> + dev_priv->rps.rp_up_masked = true;
> + new_delay = dev_priv->rps.cur_delay;
> + } else
> + new_delay = dev_priv->rps.cur_delay + adj;
> +
> + if (dev_priv->rps.rp_down_masked) {
> + I915_WRITE(GEN6_PMINTRMSK,
> + I915_READ(GEN6_PMINTRMSK) & ~(1 << 4));
> + dev_priv->rps.rp_down_masked = false;
> + }
>
> /*
> * For better performance, jump directly @@ -1007,7 +1020,21 @@
> static void gen6_pm_rps_work(struct work_struct *work)
> adj *= 2;
> else
> adj = -1;
> - new_delay = dev_priv->rps.cur_delay + adj;
> +
> + if (dev_priv->rps.cur_delay <= dev_priv->rps.min_delay) {
> + I915_WRITE(GEN6_PMINTRMSK,
> + I915_READ(GEN6_PMINTRMSK) | 1 << 4);
> + dev_priv->rps.rp_down_masked = true;
> + new_delay = dev_priv->rps.cur_delay;
> + } else
> + new_delay = dev_priv->rps.cur_delay + adj;
> +
> + if (dev_priv->rps.rp_up_masked) {
> + I915_WRITE(GEN6_PMINTRMSK,
> + I915_READ(GEN6_PMINTRMSK) & ~(1 << 5));
> + dev_priv->rps.rp_up_masked = false;
> + }
> +
> } else { /* unknown event */
> new_delay = dev_priv->rps.cur_delay;
> }
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c index 469170c..9c950e4 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3628,6 +3628,9 @@ static void valleyview_enable_rps(struct drm_device *dev)
> vlv_gpu_freq(dev_priv, dev_priv->rps.rpe_delay),
> dev_priv->rps.rpe_delay);
>
> + dev_priv->rps.rp_up_masked = false;
> + dev_priv->rps.rp_down_masked = false;
> +
> valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay);
>
> gen6_enable_rps_interrupts(dev);
> --
> 1.8.4.2
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2014-01-16 5:48 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-09 14:01 [PATCH v2 0/3] VLV Turbo/rps + RC6 workaround deepak.s
2014-01-09 14:01 ` [PATCH v3 1/3] drm/i915: Disable/Enable PM Intrrupts based on the current freq deepak.s
2014-01-13 23:01 ` Jesse Barnes
2014-01-14 9:21 ` Daniel Vetter
2014-01-14 9:23 ` S, Deepak
2014-01-16 5:47 ` S, Deepak
2014-01-09 14:01 ` [PATCH v2 2/3] drm/i915/vlv: WA to fix Voltage not getting dropped to Vmin when Gfx is power gated deepak.s
2014-01-13 22:53 ` Jesse Barnes
2014-01-14 9:12 ` S, Deepak
2014-01-09 14:01 ` [PATCH 3/3] drm/i915/vlv: WA for Turbo and RC6 to work together deepak.s
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox