aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pm.c')
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c64
1 files changed, 44 insertions, 20 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 8e79ff67ec98..d0ce2a5b1d3f 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);
@@ -2408,7 +2438,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
2408 I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); 2438 I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
2409 I915_WRITE(GEN6_RP_CONTROL, 2439 I915_WRITE(GEN6_RP_CONTROL,
2410 GEN6_RP_MEDIA_TURBO | 2440 GEN6_RP_MEDIA_TURBO |
2411 GEN6_RP_MEDIA_HW_MODE | 2441 GEN6_RP_MEDIA_HW_NORMAL_MODE |
2412 GEN6_RP_MEDIA_IS_GFX | 2442 GEN6_RP_MEDIA_IS_GFX |
2413 GEN6_RP_ENABLE | 2443 GEN6_RP_ENABLE |
2414 GEN6_RP_UP_BUSY_AVG | 2444 GEN6_RP_UP_BUSY_AVG |
@@ -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,
@@ -3580,8 +3603,9 @@ static void gen6_sanitize_pm(struct drm_device *dev)
3580 limits |= (dev_priv->min_delay & 0x3f) << 16; 3603 limits |= (dev_priv->min_delay & 0x3f) << 16;
3581 3604
3582 if (old != limits) { 3605 if (old != limits) {
3583 DRM_ERROR("Power management discrepancy: GEN6_RP_INTERRUPT_LIMITS expected %08x, was %08x\n", 3606 /* Note that the known failure case is to read back 0. */
3584 limits, old); 3607 DRM_DEBUG_DRIVER("Power management discrepancy: GEN6_RP_INTERRUPT_LIMITS "
3608 "expected %08x, was %08x\n", limits, old);
3585 I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits); 3609 I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits);
3586 } 3610 }
3587 3611