diff options
author | Ben Widawsky <ben@bwidawsk.net> | 2011-04-25 14:23:07 -0400 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2011-05-10 16:56:46 -0400 |
commit | fcca7926299944841569515da321bef9655b7703 (patch) | |
tree | 3d3961db5e3d1821bd68c3c09365f9e557e61d55 /drivers/gpu/drm/i915/i915_drv.h | |
parent | b7287d8054d219b3009f7ca82edf24f89fd363e5 (diff) |
drm/i915: reference counted forcewake
Provide a reference count to track the forcewake state of the GPU and
give a safe mechanism for userspace to wake the GT. This also potentially
saves a UC read if the GT is known to be awake already.
The reference count is atomic, but the register access and hardware wake
sequence is protected by struct_mutex.
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_drv.h')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 083644ef8f31..bafb387dd416 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -709,6 +709,8 @@ typedef struct drm_i915_private { | |||
709 | struct intel_fbdev *fbdev; | 709 | struct intel_fbdev *fbdev; |
710 | 710 | ||
711 | struct drm_property *broadcast_rgb_property; | 711 | struct drm_property *broadcast_rgb_property; |
712 | |||
713 | atomic_t forcewake_count; | ||
712 | } drm_i915_private_t; | 714 | } drm_i915_private_t; |
713 | 715 | ||
714 | enum i915_cache_level { | 716 | enum i915_cache_level { |
@@ -1329,8 +1331,8 @@ extern void intel_display_print_error_state(struct seq_file *m, | |||
1329 | * must be set to prevent GT core from power down and stale values being | 1331 | * must be set to prevent GT core from power down and stale values being |
1330 | * returned. | 1332 | * returned. |
1331 | */ | 1333 | */ |
1332 | void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); | 1334 | void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); |
1333 | void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); | 1335 | void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); |
1334 | void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); | 1336 | void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); |
1335 | 1337 | ||
1336 | /* We give fast paths for the really cool registers */ | 1338 | /* We give fast paths for the really cool registers */ |
@@ -1343,15 +1345,16 @@ void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); | |||
1343 | static inline u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ | 1345 | static inline u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ |
1344 | u##x val = 0; \ | 1346 | u##x val = 0; \ |
1345 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ | 1347 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ |
1346 | __gen6_gt_force_wake_get(dev_priv); \ | 1348 | gen6_gt_force_wake_get(dev_priv); \ |
1347 | val = read##y(dev_priv->regs + reg); \ | 1349 | val = read##y(dev_priv->regs + reg); \ |
1348 | __gen6_gt_force_wake_put(dev_priv); \ | 1350 | gen6_gt_force_wake_put(dev_priv); \ |
1349 | } else { \ | 1351 | } else { \ |
1350 | val = read##y(dev_priv->regs + reg); \ | 1352 | val = read##y(dev_priv->regs + reg); \ |
1351 | } \ | 1353 | } \ |
1352 | trace_i915_reg_rw(false, reg, val, sizeof(val)); \ | 1354 | trace_i915_reg_rw(false, reg, val, sizeof(val)); \ |
1353 | return val; \ | 1355 | return val; \ |
1354 | } | 1356 | } |
1357 | |||
1355 | __i915_read(8, b) | 1358 | __i915_read(8, b) |
1356 | __i915_read(16, w) | 1359 | __i915_read(16, w) |
1357 | __i915_read(32, l) | 1360 | __i915_read(32, l) |