diff options
author | Ben Skeggs <skeggsb@gmail.com> | 2008-05-02 01:03:51 +1000 |
---|---|---|
committer | Ben Skeggs <skeggsb@gmail.com> | 2008-05-02 01:36:08 +1000 |
commit | 6d8062ac1e048c3643d3a9d2432e497e17f717de (patch) | |
tree | a01d6a4851e9cd98cca6f9f013db408cceea73b5 | |
parent | 77d20928b330acda5b6ceb469f50757b5300702b (diff) |
nouveau: guard against channels potentially not having a context, fix nv50
-rw-r--r-- | shared-core/nouveau_irq.c | 79 | ||||
-rw-r--r-- | shared-core/nv50_graph.c | 2 |
2 files changed, 39 insertions, 42 deletions
diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c index 103fd96b..d002f642 100644 --- a/shared-core/nouveau_irq.c +++ b/shared-core/nouveau_irq.c @@ -191,55 +191,54 @@ nouveau_print_bitfield_names(uint32_t value, } static int -nouveau_graph_trapped_channel(struct drm_device *dev, int *channel_ret) +nouveau_graph_chid_from_grctx(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine = &dev_priv->Engine; - int channel; + uint32_t inst; + int i; - if (dev_priv->card_type < NV_10) { - channel = (NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 24) & 0xf; - } else if (dev_priv->card_type < NV_40) { - channel = (NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f; - } else - if (dev_priv->card_type < NV_50) { - uint32_t cur_grctx = (NV_READ(0x40032C) & 0xfffff) << 4; + if (dev_priv->card_type < NV_40) + return dev_priv->Engine.fifo.channels; + else + if (dev_priv->card_type < NV_50) + inst = (NV_READ(0x40032c) & 0xfffff) << 4; + else + inst = NV_READ(0x40032c) & 0xfffff; - /* 0x400704 *sometimes* contains a sensible channel ID, but - * mostly not.. for now lookup which channel owns the active - * PGRAPH context. Probably a better way, but this'll do - * for now. - */ - for (channel = 0; channel < 32; channel++) { - if (dev_priv->fifos[channel] == NULL) - continue; - if (cur_grctx == - dev_priv->fifos[channel]->ramin_grctx->instance) - break; - } - if (channel == 32) { - DRM_ERROR("AIII, unable to determine active channel " - "from PGRAPH context 0x%08x\n", cur_grctx); - return -EINVAL; - } - } else { - uint32_t cur_grctx = (NV_READ(0x40032C) & 0xfffff) << 12; + for (i = 0; i < dev_priv->Engine.fifo.channels; i++) { + struct nouveau_channel *chan = dev_priv->fifos[i]; + + if (!chan || !chan->ramin_grctx) + continue; - for (channel = 0; channel < 128; channel++) { - if (dev_priv->fifos[channel] == NULL) - continue; - if (cur_grctx == - dev_priv->fifos[channel]->ramin_grctx->instance) + if (dev_priv->card_type < NV_50) { + if (inst == chan->ramin_grctx->instance) + break; + } else { + if (inst == INSTANCE_RD(chan->ramin_grctx->gpuobj, 0)) break; - } - if (channel == 128) { - DRM_ERROR("AIII, unable to determine active channel " - "from PGRAPH context 0x%08x\n", cur_grctx); - return -EINVAL; } } - if (channel > engine->fifo.channels || !dev_priv->fifos[channel]) { + return i; +} + +static int +nouveau_graph_trapped_channel(struct drm_device *dev, int *channel_ret) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->Engine; + int channel; + + if (dev_priv->card_type < NV_10) + channel = (NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 24) & 0xf; + else + if (dev_priv->card_type < NV_40) + channel = (NV_READ(NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f; + else + channel = nouveau_graph_chid_from_grctx(dev); + + if (channel >= engine->fifo.channels || !dev_priv->fifos[channel]) { DRM_ERROR("AIII, invalid/inactive channel id %d\n", channel); return -EINVAL; } diff --git a/shared-core/nv50_graph.c b/shared-core/nv50_graph.c index ebe4b1f6..1300c83a 100644 --- a/shared-core/nv50_graph.c +++ b/shared-core/nv50_graph.c @@ -251,7 +251,6 @@ nv86_graph_init_ctxvals(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_gpuobj *ctx = ref->gpuobj; - INSTANCE_WR(ctx, 0x0/4, 0x1); INSTANCE_WR(ctx, 0x10C/4, 0x30); INSTANCE_WR(ctx, 0x1D4/4, 0x3); INSTANCE_WR(ctx, 0x1D8/4, 0x1000); @@ -937,7 +936,6 @@ nv84_graph_init_ctxvals(struct drm_device *dev, struct nouveau_gpuobj_ref *ref) struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_gpuobj *ctx = ref->gpuobj; - INSTANCE_WR(ctx, 0x00000/4, 0x00000001); INSTANCE_WR(ctx, 0x0010c/4, 0x00000030); INSTANCE_WR(ctx, 0x00130/4, 0x00000002); INSTANCE_WR(ctx, 0x001d4/4, 0x00000003); |