aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_pm.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-04-28 03:56:39 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-05-24 11:54:00 -0400
commit7b9e0ae6da0a7eaf2680a1a788f08df123724f3b (patch)
tree34098c8670c181ac16210d7647057cbc22ceb6f1 /drivers/gpu/drm/i915/intel_pm.c
parent59d92bfa5f0cdf57f82f5181b0ad6af75c3fdf41 (diff)
drm/i915: Always update RPS interrupts thresholds along with frequency
In order to avoid missed down-interrupts when coming out of RC6, it is advised that we always reset the down-threshold upon a PM event. This is due to that the PM unit goes through a little dance when coming out of RC6, it first brings the GPU up at the lowest frequency then a short time later it restores the thresholds. During that interval, the down-interval may expire and the interrupt be suppressed. Now aware of the dance taking place within the GPU when coming out of RC6, one wonders what other writes need to be queued in the fifo buffer in order to be properly sequenced; setting the RP state appears to be one. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=44006 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Acked-by: Ben Widawsky <ben@bwidawsk.net> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c57
1 files changed, 40 insertions, 17 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 8e79ff67ec98..bbca4e403b84 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2270,10 +2270,33 @@ void ironlake_disable_drps(struct drm_device *dev)
2270void gen6_set_rps(struct drm_device *dev, u8 val) 2270void gen6_set_rps(struct drm_device *dev, u8 val)
2271{ 2271{
2272 struct drm_i915_private *dev_priv = dev->dev_private; 2272 struct drm_i915_private *dev_priv = dev->dev_private;
2273 u32 swreq; 2273 u32 limits;
2274 2274
2275 swreq = (val & 0x3ff) << 25; 2275 limits = 0;
2276 I915_WRITE(GEN6_RPNSWREQ, swreq); 2276 if (val >= dev_priv->max_delay)
2277 val = dev_priv->max_delay;
2278 else
2279 limits |= dev_priv->max_delay << 24;
2280
2281 if (val <= dev_priv->min_delay)
2282 val = dev_priv->min_delay;
2283 else
2284 limits |= dev_priv->min_delay << 16;
2285
2286 if (val == dev_priv->cur_delay)
2287 return;
2288
2289 I915_WRITE(GEN6_RPNSWREQ,
2290 GEN6_FREQUENCY(val) |
2291 GEN6_OFFSET(0) |
2292 GEN6_AGGRESSIVE_TURBO);
2293
2294 /* Make sure we continue to get interrupts
2295 * until we hit the minimum or maximum frequencies.
2296 */
2297 I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits);
2298
2299 dev_priv->cur_delay = val;
2277} 2300}
2278 2301
2279void gen6_disable_rps(struct drm_device *dev) 2302void gen6_disable_rps(struct drm_device *dev)
@@ -2327,11 +2350,10 @@ int intel_enable_rc6(const struct drm_device *dev)
2327void gen6_enable_rps(struct drm_i915_private *dev_priv) 2350void gen6_enable_rps(struct drm_i915_private *dev_priv)
2328{ 2351{
2329 struct intel_ring_buffer *ring; 2352 struct intel_ring_buffer *ring;
2330 u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); 2353 u32 rp_state_cap;
2331 u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); 2354 u32 gt_perf_status;
2332 u32 pcu_mbox, rc6_mask = 0; 2355 u32 pcu_mbox, rc6_mask = 0;
2333 u32 gtfifodbg; 2356 u32 gtfifodbg;
2334 int cur_freq, min_freq, max_freq;
2335 int rc6_mode; 2357 int rc6_mode;
2336 int i; 2358 int i;
2337 2359
@@ -2352,6 +2374,14 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
2352 2374
2353 gen6_gt_force_wake_get(dev_priv); 2375 gen6_gt_force_wake_get(dev_priv);
2354 2376
2377 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
2378 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
2379
2380 /* In units of 100MHz */
2381 dev_priv->max_delay = rp_state_cap & 0xff;
2382 dev_priv->min_delay = (rp_state_cap & 0xff0000) >> 16;
2383 dev_priv->cur_delay = 0;
2384
2355 /* disable the counters and set deterministic thresholds */ 2385 /* disable the counters and set deterministic thresholds */
2356 I915_WRITE(GEN6_RC_CONTROL, 0); 2386 I915_WRITE(GEN6_RC_CONTROL, 0);
2357 2387
@@ -2399,8 +2429,8 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
2399 2429
2400 I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); 2430 I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000);
2401 I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, 2431 I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
2402 18 << 24 | 2432 dev_priv->max_delay << 24 |
2403 6 << 16); 2433 dev_priv->min_delay << 16);
2404 I915_WRITE(GEN6_RP_UP_THRESHOLD, 10000); 2434 I915_WRITE(GEN6_RP_UP_THRESHOLD, 10000);
2405 I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000); 2435 I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000);
2406 I915_WRITE(GEN6_RP_UP_EI, 100000); 2436 I915_WRITE(GEN6_RP_UP_EI, 100000);
@@ -2426,10 +2456,6 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
2426 500)) 2456 500))
2427 DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); 2457 DRM_ERROR("timeout waiting for pcode mailbox to finish\n");
2428 2458
2429 min_freq = (rp_state_cap & 0xff0000) >> 16;
2430 max_freq = rp_state_cap & 0xff;
2431 cur_freq = (gt_perf_status & 0xff00) >> 8;
2432
2433 /* Check for overclock support */ 2459 /* Check for overclock support */
2434 if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, 2460 if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
2435 500)) 2461 500))
@@ -2440,14 +2466,11 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
2440 500)) 2466 500))
2441 DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); 2467 DRM_ERROR("timeout waiting for pcode mailbox to finish\n");
2442 if (pcu_mbox & (1<<31)) { /* OC supported */ 2468 if (pcu_mbox & (1<<31)) { /* OC supported */
2443 max_freq = pcu_mbox & 0xff; 2469 dev_priv->max_delay = pcu_mbox & 0xff;
2444 DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max to %dMHz\n", pcu_mbox * 50); 2470 DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max to %dMHz\n", pcu_mbox * 50);
2445 } 2471 }
2446 2472
2447 /* In units of 100MHz */ 2473 gen6_set_rps(dev_priv->dev, (gt_perf_status & 0xff00) >> 8);
2448 dev_priv->max_delay = max_freq;
2449 dev_priv->min_delay = min_freq;
2450 dev_priv->cur_delay = cur_freq;
2451 2474
2452 /* requires MSI enabled */ 2475 /* requires MSI enabled */
2453 I915_WRITE(GEN6_PMIER, 2476 I915_WRITE(GEN6_PMIER,