summaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
authorPekka Paalanen <pq@iki.fi>2007-07-06 20:33:32 +0300
committerPekka Paalanen <pq@iki.fi>2007-07-18 14:23:41 +0300
commitaf4cfa624a005f7105db89f6f076c41adbe44bd3 (patch)
tree79263329def0fab100d79643e2d86c15377f69f6 /shared-core
parent696bee093f6f75dbb48699ff32bbebe2d3a1e307 (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.c35
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);
+ }
}
}