diff options
author | Pekka Paalanen <pq@iki.fi> | 2007-07-06 20:33:32 +0300 |
---|---|---|
committer | Pekka Paalanen <pq@iki.fi> | 2007-07-18 14:23:41 +0300 |
commit | af4cfa624a005f7105db89f6f076c41adbe44bd3 (patch) | |
tree | 79263329def0fab100d79643e2d86c15377f69f6 /shared-core | |
parent | 696bee093f6f75dbb48699ff32bbebe2d3a1e307 (diff) |
nouveau: Make nouveau_wait_for_idle() read PTIMER.
Following my nv28 kmmio dumps, nouveau_wait_for_idle() is modified to
read PTIMER and NV03_PMC_ENABLE. Also a timeout based on PTIMER value is
added, so wait_for_idle() cannot stall indefinitely (unless PTIMER is
halted). The timeout was selected as 1 giga-ticks, which for me is 1s.
Diffstat (limited to 'shared-core')
-rw-r--r-- | shared-core/nouveau_state.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c index 5b67aea1..a26ecea3 100644 --- a/shared-core/nouveau_state.c +++ b/shared-core/nouveau_state.c @@ -522,16 +522,31 @@ int nouveau_ioctl_setparam(DRM_IOCTL_ARGS) void nouveau_wait_for_idle(struct drm_device *dev) { struct drm_nouveau_private *dev_priv=dev->dev_private; - switch(dev_priv->card_type) - { - case NV_03: - while(NV_READ(NV03_PGRAPH_STATUS)); - break; - case NV_50: - break; - default: - while(NV_READ(NV04_PGRAPH_STATUS)); - break; + switch(dev_priv->card_type) { + case NV_03: + while (NV_READ(NV03_PGRAPH_STATUS)); + break; + case NV_50: + break; + default: { + /* This stuff is more or less a copy of what is seen + * in nv28 kmmio dump. + */ + uint64_t started = dev_priv->Engine.timer.read(dev); + uint64_t stopped = started; + uint32_t status; + do { + uint32_t pmc_e = NV_READ(NV03_PMC_ENABLE); + status = NV_READ(NV04_PGRAPH_STATUS); + if (!status) + break; + stopped = dev_priv->Engine.timer.read(dev); + /* It'll never wrap anyway... */ + } while (stopped - started < 1000000000ULL); + if (status) + DRM_ERROR("timed out with status 0x%08x\n", + status); + } } } |