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 /drivers | |
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>
Diffstat (limited to 'drivers')
-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 |