diff options
| author | Maarten Maathuis <madman2003@gmail.com> | 2010-01-20 13:54:34 -0500 |
|---|---|---|
| committer | Ben Skeggs <bskeggs@redhat.com> | 2010-02-09 17:19:39 -0500 |
| commit | b1d37aa0aa43c5bf857364093ab2191acd37f2ec (patch) | |
| tree | f53cce50b3be629ce7f9fab19c7b1633815306cd | |
| parent | a87ff62a80a6a65fc664cd410061910b8c52b896 (diff) | |
drm/nv50: make the pgraph irq handler loop like the pre-nv50 version
Unset the bit that indicates that a ctxprog can continue at the end.
Signed-off-by: Maarten Maathuis <madman2003@gmail.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_irq.c | 141 |
1 files changed, 77 insertions, 64 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index baa9b3e0b66b..447f9f69d6b1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c | |||
| @@ -580,86 +580,99 @@ nouveau_pgraph_irq_handler(struct drm_device *dev) | |||
| 580 | static void | 580 | static void |
| 581 | nv50_pgraph_irq_handler(struct drm_device *dev) | 581 | nv50_pgraph_irq_handler(struct drm_device *dev) |
| 582 | { | 582 | { |
| 583 | uint32_t status, nsource; | 583 | uint32_t status; |
| 584 | 584 | ||
| 585 | status = nv_rd32(dev, NV03_PGRAPH_INTR); | 585 | while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) { |
| 586 | nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); | 586 | uint32_t nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); |
| 587 | 587 | ||
| 588 | if (status & 0x00000001) { | 588 | if (status & 0x00000001) { |
| 589 | nouveau_pgraph_intr_notify(dev, nsource); | 589 | nouveau_pgraph_intr_notify(dev, nsource); |
| 590 | status &= ~0x00000001; | 590 | status &= ~0x00000001; |
| 591 | nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001); | 591 | nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001); |
| 592 | } | 592 | } |
| 593 | 593 | ||
| 594 | if (status & 0x00000010) { | 594 | if (status & 0x00000010) { |
| 595 | nouveau_pgraph_intr_error(dev, nsource | | 595 | nouveau_pgraph_intr_error(dev, nsource | |
| 596 | NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD); | 596 | NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD); |
| 597 | 597 | ||
| 598 | status &= ~0x00000010; | 598 | status &= ~0x00000010; |
| 599 | nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010); | 599 | nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010); |
| 600 | } | 600 | } |
| 601 | 601 | ||
| 602 | if (status & 0x00001000) { | 602 | if (status & 0x00001000) { |
| 603 | nv_wr32(dev, 0x400500, 0x00000000); | 603 | nv_wr32(dev, 0x400500, 0x00000000); |
| 604 | nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH); | 604 | nv_wr32(dev, NV03_PGRAPH_INTR, |
| 605 | nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev, | 605 | NV_PGRAPH_INTR_CONTEXT_SWITCH); |
| 606 | NV40_PGRAPH_INTR_EN) & ~NV_PGRAPH_INTR_CONTEXT_SWITCH); | 606 | nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev, |
| 607 | nv_wr32(dev, 0x400500, 0x00010001); | 607 | NV40_PGRAPH_INTR_EN) & |
| 608 | ~NV_PGRAPH_INTR_CONTEXT_SWITCH); | ||
| 609 | nv_wr32(dev, 0x400500, 0x00010001); | ||
| 608 | 610 | ||
| 609 | nv50_graph_context_switch(dev); | 611 | nv50_graph_context_switch(dev); |
| 610 | 612 | ||
| 611 | status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; | 613 | status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; |
| 612 | } | 614 | } |
| 613 | 615 | ||
| 614 | if (status & 0x00100000) { | 616 | if (status & 0x00100000) { |
| 615 | nouveau_pgraph_intr_error(dev, nsource | | 617 | nouveau_pgraph_intr_error(dev, nsource | |
| 616 | NV03_PGRAPH_NSOURCE_DATA_ERROR); | 618 | NV03_PGRAPH_NSOURCE_DATA_ERROR); |
| 617 | 619 | ||
| 618 | status &= ~0x00100000; | 620 | status &= ~0x00100000; |
| 619 | nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000); | 621 | nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000); |
| 620 | } | 622 | } |
| 621 | 623 | ||
| 622 | if (status & 0x00200000) { | 624 | if (status & 0x00200000) { |
| 623 | int r; | 625 | int r; |
| 624 | 626 | ||
| 625 | nouveau_pgraph_intr_error(dev, nsource | | 627 | nouveau_pgraph_intr_error(dev, nsource | |
| 626 | NV03_PGRAPH_NSOURCE_PROTECTION_ERROR); | 628 | NV03_PGRAPH_NSOURCE_PROTECTION_ERROR); |
| 627 | 629 | ||
| 628 | NV_ERROR(dev, "magic set 1:\n"); | 630 | NV_ERROR(dev, "magic set 1:\n"); |
| 629 | for (r = 0x408900; r <= 0x408910; r += 4) | 631 | for (r = 0x408900; r <= 0x408910; r += 4) |
| 630 | NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r)); | 632 | NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, |
| 631 | nv_wr32(dev, 0x408900, nv_rd32(dev, 0x408904) | 0xc0000000); | 633 | nv_rd32(dev, r)); |
| 632 | for (r = 0x408e08; r <= 0x408e24; r += 4) | 634 | nv_wr32(dev, 0x408900, |
| 633 | NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r)); | 635 | nv_rd32(dev, 0x408904) | 0xc0000000); |
| 634 | nv_wr32(dev, 0x408e08, nv_rd32(dev, 0x408e08) | 0xc0000000); | 636 | for (r = 0x408e08; r <= 0x408e24; r += 4) |
| 635 | 637 | NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, | |
| 636 | NV_ERROR(dev, "magic set 2:\n"); | 638 | nv_rd32(dev, r)); |
| 637 | for (r = 0x409900; r <= 0x409910; r += 4) | 639 | nv_wr32(dev, 0x408e08, |
| 638 | NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r)); | 640 | nv_rd32(dev, 0x408e08) | 0xc0000000); |
| 639 | nv_wr32(dev, 0x409900, nv_rd32(dev, 0x409904) | 0xc0000000); | 641 | |
| 640 | for (r = 0x409e08; r <= 0x409e24; r += 4) | 642 | NV_ERROR(dev, "magic set 2:\n"); |
| 641 | NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, nv_rd32(dev, r)); | 643 | for (r = 0x409900; r <= 0x409910; r += 4) |
| 642 | nv_wr32(dev, 0x409e08, nv_rd32(dev, 0x409e08) | 0xc0000000); | 644 | NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, |
| 643 | 645 | nv_rd32(dev, r)); | |
| 644 | status &= ~0x00200000; | 646 | nv_wr32(dev, 0x409900, |
| 645 | nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource); | 647 | nv_rd32(dev, 0x409904) | 0xc0000000); |
| 646 | nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000); | 648 | for (r = 0x409e08; r <= 0x409e24; r += 4) |
| 647 | } | 649 | NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, |
| 650 | nv_rd32(dev, r)); | ||
| 651 | nv_wr32(dev, 0x409e08, | ||
| 652 | nv_rd32(dev, 0x409e08) | 0xc0000000); | ||
| 653 | |||
| 654 | status &= ~0x00200000; | ||
| 655 | nv_wr32(dev, NV03_PGRAPH_NSOURCE, nsource); | ||
| 656 | nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000); | ||
| 657 | } | ||
| 648 | 658 | ||
| 649 | if (status) { | 659 | if (status) { |
| 650 | NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", status); | 660 | NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", |
| 651 | nv_wr32(dev, NV03_PGRAPH_INTR, status); | 661 | status); |
| 652 | } | 662 | nv_wr32(dev, NV03_PGRAPH_INTR, status); |
| 663 | } | ||
| 653 | 664 | ||
| 654 | { | 665 | { |
| 655 | const int isb = (1 << 16) | (1 << 0); | 666 | const int isb = (1 << 16) | (1 << 0); |
| 656 | 667 | ||
| 657 | if ((nv_rd32(dev, 0x400500) & isb) != isb) | 668 | if ((nv_rd32(dev, 0x400500) & isb) != isb) |
| 658 | nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | isb); | 669 | nv_wr32(dev, 0x400500, |
| 659 | nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31)); | 670 | nv_rd32(dev, 0x400500) | isb); |
| 671 | } | ||
| 660 | } | 672 | } |
| 661 | 673 | ||
| 662 | nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); | 674 | nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); |
| 675 | nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31)); | ||
| 663 | } | 676 | } |
| 664 | 677 | ||
| 665 | static void | 678 | static void |
