diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-06-18 02:27:24 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-09-20 02:02:50 -0400 |
commit | 78e2933d07124ea28593a1bdadc546294f77a504 (patch) | |
tree | a77de03892418f501fe5222dacce8ddb81a39b18 /drivers/gpu | |
parent | 95f0de3a0ae52bbe11f285ae46b5319bb2a2360d (diff) |
drm/nouveau: add function to wait until a callback returns true
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 17 |
2 files changed, 21 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 06867055181e..0f0c5e59535f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -833,6 +833,8 @@ extern bool nouveau_wait_eq(struct drm_device *, uint64_t timeout, | |||
833 | uint32_t reg, uint32_t mask, uint32_t val); | 833 | uint32_t reg, uint32_t mask, uint32_t val); |
834 | extern bool nouveau_wait_ne(struct drm_device *, uint64_t timeout, | 834 | extern bool nouveau_wait_ne(struct drm_device *, uint64_t timeout, |
835 | uint32_t reg, uint32_t mask, uint32_t val); | 835 | uint32_t reg, uint32_t mask, uint32_t val); |
836 | extern bool nouveau_wait_cb(struct drm_device *, u64 timeout, | ||
837 | bool (*cond)(void *), void *); | ||
836 | extern bool nouveau_wait_for_idle(struct drm_device *); | 838 | extern bool nouveau_wait_for_idle(struct drm_device *); |
837 | extern int nouveau_card_init(struct drm_device *); | 839 | extern int nouveau_card_init(struct drm_device *); |
838 | 840 | ||
@@ -1457,6 +1459,8 @@ static inline void nv_wr08(struct drm_device *dev, unsigned reg, u8 val) | |||
1457 | nouveau_wait_eq(dev, 2000000000ULL, (reg), (mask), (val)) | 1459 | nouveau_wait_eq(dev, 2000000000ULL, (reg), (mask), (val)) |
1458 | #define nv_wait_ne(dev, reg, mask, val) \ | 1460 | #define nv_wait_ne(dev, reg, mask, val) \ |
1459 | nouveau_wait_ne(dev, 2000000000ULL, (reg), (mask), (val)) | 1461 | nouveau_wait_ne(dev, 2000000000ULL, (reg), (mask), (val)) |
1462 | #define nv_wait_cb(dev, func, data) \ | ||
1463 | nouveau_wait_cb(dev, 2000000000ULL, (func), (data)) | ||
1460 | 1464 | ||
1461 | /* PRAMIN access */ | 1465 | /* PRAMIN access */ |
1462 | static inline u32 nv_ri32(struct drm_device *dev, unsigned offset) | 1466 | static inline u32 nv_ri32(struct drm_device *dev, unsigned offset) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 3e7f3812bfcd..8dc73b6b8138 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -1200,6 +1200,23 @@ nouveau_wait_ne(struct drm_device *dev, uint64_t timeout, | |||
1200 | return false; | 1200 | return false; |
1201 | } | 1201 | } |
1202 | 1202 | ||
1203 | /* Wait until cond(data) == true, up until timeout has hit */ | ||
1204 | bool | ||
1205 | nouveau_wait_cb(struct drm_device *dev, u64 timeout, | ||
1206 | bool (*cond)(void *), void *data) | ||
1207 | { | ||
1208 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
1209 | struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; | ||
1210 | u64 start = ptimer->read(dev); | ||
1211 | |||
1212 | do { | ||
1213 | if (cond(data) == true) | ||
1214 | return true; | ||
1215 | } while (ptimer->read(dev) - start < timeout); | ||
1216 | |||
1217 | return false; | ||
1218 | } | ||
1219 | |||
1203 | /* Waits for PGRAPH to go completely idle */ | 1220 | /* Waits for PGRAPH to go completely idle */ |
1204 | bool nouveau_wait_for_idle(struct drm_device *dev) | 1221 | bool nouveau_wait_for_idle(struct drm_device *dev) |
1205 | { | 1222 | { |