aboutsummaryrefslogtreecommitdiff
path: root/shared-core/nouveau_irq.c
diff options
context:
space:
mode:
authorArthur Huillet <arthur.huillet@free.fr>2007-10-12 22:39:58 +0200
committerArthur Huillet <arthur.huillet@free.fr>2007-10-12 22:40:08 +0200
commit9d779e2c88a02f5f9d57618145654610f0f10e28 (patch)
tree71edc278babecb3d9a7d37c449925a03d83f3fc3 /shared-core/nouveau_irq.c
parent74ea019863c1d08d31eac81d3bfc73e97479b2c5 (diff)
nouveau: mandatory "oops I forgot half of the files" commit
Diffstat (limited to 'shared-core/nouveau_irq.c')
-rw-r--r--shared-core/nouveau_irq.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c
index dfef718b..7ba45700 100644
--- a/shared-core/nouveau_irq.c
+++ b/shared-core/nouveau_irq.c
@@ -35,6 +35,7 @@
#include "nouveau_drm.h"
#include "nouveau_drv.h"
#include "nouveau_reg.h"
+#include "nouveau_swmthd.h"
void nouveau_irq_preinstall(struct drm_device *dev)
{
@@ -340,20 +341,27 @@ nouveau_graph_dump_trap_info(struct drm_device *dev)
static void nouveau_pgraph_irq_handler(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- uint32_t status, nsource;
+ uint32_t status, nsource, method;
+ uint32_t obj_class;
- status = NV_READ(NV03_PGRAPH_INTR);
- if (!status)
- return;
+ while ( (status = NV_READ(NV03_PGRAPH_INTR)) ) {
nsource = NV_READ(NV03_PGRAPH_NSOURCE);
if (status & NV_PGRAPH_INTR_NOTIFY) {
DRM_DEBUG("PGRAPH notify interrupt\n");
- nouveau_graph_dump_trap_info(dev);
+ if ( dev_priv->card_type == NV_04 && (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD ) ) {
+ /* NV4 (nvidia TNT 1) reports software methods with PGRAPH NOTIFY ILLEGAL_MTHD*/
+ method = NV_READ(NV04_PGRAPH_TRAPPED_ADDR) & 0x1FFC;
+ obj_class = NV_READ(NV04_PGRAPH_CTX_SWITCH1) & 0xFFF;
+ DRM_DEBUG("Got NV04 software method method %x for class %#x\n", method, obj_class);
+ if ( nouveau_sw_method_execute(dev, obj_class, method) )
+ DRM_ERROR("Unable to execute NV04 software method %x for object class %x. Please report.\n", method, obj_class);
+ }
status &= ~NV_PGRAPH_INTR_NOTIFY;
NV_WRITE(NV03_PGRAPH_INTR, NV_PGRAPH_INTR_NOTIFY);
+ NV_WRITE(NV04_PGRAPH_FIFO, 1);
}
if (status & NV_PGRAPH_INTR_ERROR) {
@@ -392,8 +400,9 @@ static void nouveau_pgraph_irq_handler(struct drm_device *dev)
DRM_ERROR("Unhandled PGRAPH interrupt: STAT=0x%08x\n", status);
NV_WRITE(NV03_PGRAPH_INTR, status);
}
+NV_WRITE(NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING);
+ }
- NV_WRITE(NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING);
}
static void nouveau_crtc_irq_handler(struct drm_device *dev, int crtc)