aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-11-01 21:33:27 -0400
committerBen Skeggs <bskeggs@redhat.com>2012-11-28 18:57:44 -0500
commit14464b8cd643467cb97335eb75ea676260dd0ad8 (patch)
tree0e3afde552b1aad18941047bd2b8c77c084f8e2c
parent206c38a9f1905d3054778f26289591376829d5ad (diff)
drm/nvd0/disp: move remaining interrupt handling to core
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c266
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_irq.c14
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvd0_display.c252
4 files changed, 270 insertions, 263 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
index fa1b9709f1cf..17d452cd6d39 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
@@ -33,6 +33,13 @@
33#include <subdev/timer.h> 33#include <subdev/timer.h>
34#include <subdev/fb.h> 34#include <subdev/fb.h>
35#include <subdev/bar.h> 35#include <subdev/bar.h>
36#include <subdev/clock.h>
37
38#include <subdev/bios.h>
39#include <subdev/bios/dcb.h>
40#include <subdev/bios/disp.h>
41#include <subdev/bios/init.h>
42#include <subdev/bios/pll.h>
36 43
37#include "nv50.h" 44#include "nv50.h"
38 45
@@ -563,6 +570,206 @@ nvd0_disp_sclass[] = {
563 * Display engine implementation 570 * Display engine implementation
564 ******************************************************************************/ 571 ******************************************************************************/
565 572
573static u16
574exec_lookup(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl,
575 struct dcb_output *dcb, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
576 struct nvbios_outp *info)
577{
578 struct nouveau_bios *bios = nouveau_bios(priv);
579 u16 data, idx = 0;
580 u16 mask, type;
581
582 if (outp < 4) {
583 type = DCB_OUTPUT_ANALOG;
584 mask = 0;
585 } else {
586 outp -= 4;
587 switch (ctrl & 0x00000f00) {
588 case 0x00000000: type = DCB_OUTPUT_LVDS; mask = 1; break;
589 case 0x00000100: type = DCB_OUTPUT_TMDS; mask = 1; break;
590 case 0x00000200: type = DCB_OUTPUT_TMDS; mask = 2; break;
591 case 0x00000500: type = DCB_OUTPUT_TMDS; mask = 3; break;
592 case 0x00000800: type = DCB_OUTPUT_DP; mask = 1; break;
593 case 0x00000900: type = DCB_OUTPUT_DP; mask = 2; break;
594 default:
595 nv_error(priv, "unknown SOR mc 0x%08x\n", ctrl);
596 return 0x0000;
597 }
598 dcb->sorconf.link = mask;
599 }
600
601 mask = 0x00c0 & (mask << 6);
602 mask |= 0x0001 << outp;
603 mask |= 0x0100 << head;
604
605 /* this is a tad special, but for the moment its needed to get
606 * all the dcb data required by the vbios scripts.. will be cleaned
607 * up later as more bits are moved to the core..
608 */
609 while ((data = dcb_outp(bios, idx++, ver, hdr))) {
610 u32 conn = nv_ro32(bios, data + 0);
611 u32 conf = nv_ro32(bios, data + 4);
612 if ((conn & 0x00300000) ||
613 (conn & 0x0000000f) != type ||
614 (conn & 0x0f000000) != (0x01000000 << outp))
615 continue;
616
617 if ( (mask & 0x00c0) && (mask & 0x00c0) !=
618 ((mask & 0x00c0) & ((conf & 0x00000030) << 2)))
619 continue;
620
621 dcb->type = type;
622 dcb->or = 1 << outp;
623 dcb->connector = (conn & 0x0000f000) >> 12;
624
625 return nvbios_outp_match(bios, type, mask, ver, hdr, cnt, len, info);
626 }
627
628 return 0x0000;
629}
630
631static bool
632exec_script(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl, int id)
633{
634 struct nouveau_bios *bios = nouveau_bios(priv);
635 struct nvbios_outp info;
636 struct dcb_output dcb;
637 u8 ver, hdr, cnt, len;
638 u16 data;
639
640 data = exec_lookup(priv, head, outp, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info);
641 if (data) {
642 struct nvbios_init init = {
643 .subdev = nv_subdev(priv),
644 .bios = bios,
645 .offset = info.script[id],
646 .outp = &dcb,
647 .crtc = head,
648 .execute = 1,
649 };
650
651 return nvbios_exec(&init) == 0;
652 }
653
654 return false;
655}
656
657static bool
658exec_clkcmp(struct nv50_disp_priv *priv, int head, int outp,
659 u32 ctrl, u32 conf, int id, u32 pclk)
660{
661 struct nouveau_bios *bios = nouveau_bios(priv);
662 struct nvbios_outp info1;
663 struct nvbios_ocfg info2;
664 struct dcb_output dcb;
665 u8 ver, hdr, cnt, len;
666 u16 data;
667
668 data = exec_lookup(priv, head, outp, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info1);
669 if (data) {
670 data = nvbios_ocfg_match(bios, data, conf, &ver, &hdr, &cnt, &len, &info2);
671 if (data) {
672 data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk);
673 if (data) {
674 struct nvbios_init init = {
675 .subdev = nv_subdev(priv),
676 .bios = bios,
677 .offset = data,
678 .outp = &dcb,
679 .crtc = head,
680 .execute = 1,
681 };
682
683 return nvbios_exec(&init) == 0;
684 }
685 }
686 }
687
688 return false;
689}
690
691static void
692nvd0_display_unk1_handler(struct nv50_disp_priv *priv, u32 head, u32 mask)
693{
694 int i;
695
696 for (i = 0; mask && i < 8; i++) {
697 u32 mcc = nv_rd32(priv, 0x640180 + (i * 0x20));
698 if (mcc & (1 << head))
699 exec_script(priv, head, i, mcc, 1);
700 }
701
702 nv_wr32(priv, 0x6101d4, 0x00000000);
703 nv_wr32(priv, 0x6109d4, 0x00000000);
704 nv_wr32(priv, 0x6101d0, 0x80000000);
705}
706
707static void
708nvd0_display_unk2_handler(struct nv50_disp_priv *priv, u32 head, u32 mask)
709{
710 u32 pclk;
711 int i;
712
713 for (i = 0; mask && i < 8; i++) {
714 u32 mcc = nv_rd32(priv, 0x640180 + (i * 0x20));
715 if (mcc & (1 << head))
716 exec_script(priv, head, i, mcc, 2);
717 }
718
719 pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000;
720 nv_debug(priv, "head %d pclk %d mask 0x%08x\n", head, pclk, mask);
721 if (pclk && (mask & 0x00010000)) {
722 struct nouveau_clock *clk = nouveau_clock(priv);
723 clk->pll_set(clk, PLL_VPLL0 + head, pclk);
724 }
725
726 nv_wr32(priv, 0x612200 + (head * 0x800), 0x00000000);
727
728 for (i = 0; mask && i < 8; i++) {
729 u32 mcp = nv_rd32(priv, 0x660180 + (i * 0x20));
730 u32 cfg = nv_rd32(priv, 0x660184 + (i * 0x20));
731 if (mcp & (1 << head)) {
732 if (exec_clkcmp(priv, head, i, mcp, cfg, 0, pclk)) {
733 u32 addr, mask, data = 0x00000000;
734 if (i < 4) {
735 addr = 0x612280 + ((i - 0) * 0x800);
736 mask = 0xffffffff;
737 } else {
738 addr = 0x612300 + ((i - 4) * 0x800);
739 mask = 0x00000707;
740 if (cfg & 0x00000100)
741 data = 0x00000101;
742 }
743 nv_mask(priv, addr, mask, data);
744 }
745 break;
746 }
747 }
748
749 nv_wr32(priv, 0x6101d4, 0x00000000);
750 nv_wr32(priv, 0x6109d4, 0x00000000);
751 nv_wr32(priv, 0x6101d0, 0x80000000);
752}
753
754static void
755nvd0_display_unk4_handler(struct nv50_disp_priv *priv, u32 head, u32 mask)
756{
757 int pclk, i;
758
759 pclk = nv_rd32(priv, 0x660450 + (head * 0x300)) / 1000;
760
761 for (i = 0; mask && i < 8; i++) {
762 u32 mcp = nv_rd32(priv, 0x660180 + (i * 0x20));
763 u32 cfg = nv_rd32(priv, 0x660184 + (i * 0x20));
764 if (mcp & (1 << head))
765 exec_clkcmp(priv, head, i, mcp, cfg, 1, pclk);
766 }
767
768 nv_wr32(priv, 0x6101d4, 0x00000000);
769 nv_wr32(priv, 0x6109d4, 0x00000000);
770 nv_wr32(priv, 0x6101d0, 0x80000000);
771}
772
566static void 773static void
567nvd0_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc) 774nvd0_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
568{ 775{
@@ -599,7 +806,64 @@ nvd0_disp_intr(struct nouveau_subdev *subdev)
599 u32 intr = nv_rd32(priv, 0x610088); 806 u32 intr = nv_rd32(priv, 0x610088);
600 int i; 807 int i;
601 808
602 for (i = 0; i < 4; i++) { 809 if (intr & 0x00000001) {
810 u32 stat = nv_rd32(priv, 0x61008c);
811 nv_wr32(priv, 0x61008c, stat);
812 intr &= ~0x00000001;
813 }
814
815 if (intr & 0x00000002) {
816 u32 stat = nv_rd32(priv, 0x61009c);
817 int chid = ffs(stat) - 1;
818 if (chid >= 0) {
819 u32 mthd = nv_rd32(priv, 0x6101f0 + (chid * 12));
820 u32 data = nv_rd32(priv, 0x6101f4 + (chid * 12));
821 u32 unkn = nv_rd32(priv, 0x6101f8 + (chid * 12));
822
823 nv_error(priv, "chid %d mthd 0x%04x data 0x%08x "
824 "0x%08x 0x%08x\n",
825 chid, (mthd & 0x0000ffc), data, mthd, unkn);
826 nv_wr32(priv, 0x61009c, (1 << chid));
827 nv_wr32(priv, 0x6101f0 + (chid * 12), 0x90000000);
828 }
829
830 intr &= ~0x00000002;
831 }
832
833 if (intr & 0x00100000) {
834 u32 stat = nv_rd32(priv, 0x6100ac);
835 u32 mask = 0, crtc = ~0;
836
837 while (!mask && ++crtc < priv->head.nr)
838 mask = nv_rd32(priv, 0x6101d4 + (crtc * 0x800));
839
840 if (stat & 0x00000001) {
841 nv_wr32(priv, 0x6100ac, 0x00000001);
842 nvd0_display_unk1_handler(priv, crtc, mask);
843 stat &= ~0x00000001;
844 }
845
846 if (stat & 0x00000002) {
847 nv_wr32(priv, 0x6100ac, 0x00000002);
848 nvd0_display_unk2_handler(priv, crtc, mask);
849 stat &= ~0x00000002;
850 }
851
852 if (stat & 0x00000004) {
853 nv_wr32(priv, 0x6100ac, 0x00000004);
854 nvd0_display_unk4_handler(priv, crtc, mask);
855 stat &= ~0x00000004;
856 }
857
858 if (stat) {
859 nv_info(priv, "unknown intr24 0x%08x\n", stat);
860 nv_wr32(priv, 0x6100ac, stat);
861 }
862
863 intr &= ~0x00100000;
864 }
865
866 for (i = 0; i < priv->head.nr; i++) {
603 u32 mask = 0x01000000 << i; 867 u32 mask = 0x01000000 << i;
604 if (mask & intr) { 868 if (mask & intr) {
605 u32 stat = nv_rd32(priv, 0x6100bc + (i * 0x800)); 869 u32 stat = nv_rd32(priv, 0x6100bc + (i * 0x800));
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c
index 1d8cb506a28a..03cdc077c4bc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_irq.c
+++ b/drivers/gpu/drm/nouveau/nouveau_irq.c
@@ -61,15 +61,11 @@ nouveau_irq_handler(DRM_IRQ_ARGS)
61 61
62 nv_subdev(pmc)->intr(nv_subdev(pmc)); 62 nv_subdev(pmc)->intr(nv_subdev(pmc));
63 63
64 if (dev->mode_config.num_crtc) { 64 if (dev->mode_config.num_crtc &&
65 if (device->card_type >= NV_D0) { 65 device->card_type <= NV_C0 &&
66 if (nv_rd32(device, 0x000100) & 0x04000000) 66 device->card_type >= NV_50) {
67 nvd0_display_intr(dev); 67 if (nv_rd32(device, 0x000100) & 0x04000000)
68 } else 68 nv50_display_intr(dev);
69 if (device->card_type >= NV_50) {
70 if (nv_rd32(device, 0x000100) & 0x04000000)
71 nv50_display_intr(dev);
72 }
73 } 69 }
74 70
75 return IRQ_HANDLED; 71 return IRQ_HANDLED;
diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h
index 973554d8a7a6..40aa6737adeb 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.h
+++ b/drivers/gpu/drm/nouveau/nv50_display.h
@@ -94,7 +94,6 @@ int nvd0_display_create(struct drm_device *);
94void nvd0_display_destroy(struct drm_device *); 94void nvd0_display_destroy(struct drm_device *);
95int nvd0_display_init(struct drm_device *); 95int nvd0_display_init(struct drm_device *);
96void nvd0_display_fini(struct drm_device *); 96void nvd0_display_fini(struct drm_device *);
97void nvd0_display_intr(struct drm_device *);
98 97
99void nvd0_display_flip_stop(struct drm_crtc *); 98void nvd0_display_flip_stop(struct drm_crtc *);
100int nvd0_display_flip_next(struct drm_crtc *, struct drm_framebuffer *, 99int nvd0_display_flip_next(struct drm_crtc *, struct drm_framebuffer *,
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c
index edc79c3572c0..fa0ca63e333d 100644
--- a/drivers/gpu/drm/nouveau/nvd0_display.c
+++ b/drivers/gpu/drm/nouveau/nvd0_display.c
@@ -271,7 +271,6 @@ struct nvd0_disp {
271 struct nouveau_object *core; 271 struct nouveau_object *core;
272 struct nvd0_mast mast; 272 struct nvd0_mast mast;
273 273
274 struct tasklet_struct tasklet;
275 u32 modeset; 274 u32 modeset;
276 275
277 struct nouveau_bo *sync; 276 struct nouveau_bo *sync;
@@ -1763,254 +1762,6 @@ nvd0_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
1763} 1762}
1764 1763
1765/****************************************************************************** 1764/******************************************************************************
1766 * IRQ
1767 *****************************************************************************/
1768static struct dcb_output *
1769lookup_dcb(struct drm_device *dev, int id, u32 mc)
1770{
1771 struct nouveau_drm *drm = nouveau_drm(dev);
1772 int type, or, i, link = -1;
1773
1774 if (id < 4) {
1775 type = DCB_OUTPUT_ANALOG;
1776 or = id;
1777 } else {
1778 switch (mc & 0x00000f00) {
1779 case 0x00000000: link = 0; type = DCB_OUTPUT_LVDS; break;
1780 case 0x00000100: link = 0; type = DCB_OUTPUT_TMDS; break;
1781 case 0x00000200: link = 1; type = DCB_OUTPUT_TMDS; break;
1782 case 0x00000500: link = 0; type = DCB_OUTPUT_TMDS; break;
1783 case 0x00000800: link = 0; type = DCB_OUTPUT_DP; break;
1784 case 0x00000900: link = 1; type = DCB_OUTPUT_DP; break;
1785 default:
1786 NV_ERROR(drm, "PDISP: unknown SOR mc 0x%08x\n", mc);
1787 return NULL;
1788 }
1789
1790 or = id - 4;
1791 }
1792
1793 for (i = 0; i < drm->vbios.dcb.entries; i++) {
1794 struct dcb_output *dcb = &drm->vbios.dcb.entry[i];
1795 if (dcb->type == type && (dcb->or & (1 << or)) &&
1796 (link < 0 || link == !(dcb->sorconf.link & 1)))
1797 return dcb;
1798 }
1799
1800 NV_ERROR(drm, "PDISP: DCB for %d/0x%08x not found\n", id, mc);
1801 return NULL;
1802}
1803
1804static void
1805nvd0_display_unk1_handler(struct drm_device *dev, u32 crtc, u32 mask)
1806{
1807 struct nouveau_device *device = nouveau_dev(dev);
1808 struct dcb_output *dcb;
1809 int i;
1810
1811 for (i = 0; mask && i < 8; i++) {
1812 u32 mcc = nv_rd32(device, 0x640180 + (i * 0x20));
1813 if (!(mcc & (1 << crtc)))
1814 continue;
1815
1816 dcb = lookup_dcb(dev, i, mcc);
1817 if (!dcb)
1818 continue;
1819
1820 nouveau_bios_run_display_table(dev, 0x0000, -1, dcb, crtc);
1821 }
1822
1823 nv_wr32(device, 0x6101d4, 0x00000000);
1824 nv_wr32(device, 0x6109d4, 0x00000000);
1825 nv_wr32(device, 0x6101d0, 0x80000000);
1826}
1827
1828static void
1829nvd0_display_unk2_handler(struct drm_device *dev, u32 crtc, u32 mask)
1830{
1831 struct nouveau_device *device = nouveau_dev(dev);
1832 struct nouveau_drm *drm = nouveau_drm(dev);
1833 struct dcb_output *dcb;
1834 u32 or, tmp, pclk;
1835 int i;
1836
1837 for (i = 0; mask && i < 8; i++) {
1838 u32 mcc = nv_rd32(device, 0x640180 + (i * 0x20));
1839 if (!(mcc & (1 << crtc)))
1840 continue;
1841
1842 dcb = lookup_dcb(dev, i, mcc);
1843 if (!dcb)
1844 continue;
1845
1846 nouveau_bios_run_display_table(dev, 0x0000, -2, dcb, crtc);
1847 }
1848
1849 pclk = nv_rd32(device, 0x660450 + (crtc * 0x300)) / 1000;
1850 NV_DEBUG(drm, "PDISP: crtc %d pclk %d mask 0x%08x\n",
1851 crtc, pclk, mask);
1852 if (pclk && (mask & 0x00010000)) {
1853 nv50_crtc_set_clock(dev, crtc, pclk);
1854 }
1855
1856 for (i = 0; mask && i < 8; i++) {
1857 u32 mcp = nv_rd32(device, 0x660180 + (i * 0x20));
1858 u32 cfg = nv_rd32(device, 0x660184 + (i * 0x20));
1859 if (!(mcp & (1 << crtc)))
1860 continue;
1861
1862 dcb = lookup_dcb(dev, i, mcp);
1863 if (!dcb)
1864 continue;
1865 or = ffs(dcb->or) - 1;
1866
1867 nouveau_bios_run_display_table(dev, cfg, pclk, dcb, crtc);
1868
1869 nv_wr32(device, 0x612200 + (crtc * 0x800), 0x00000000);
1870 switch (dcb->type) {
1871 case DCB_OUTPUT_ANALOG:
1872 nv_wr32(device, 0x612280 + (or * 0x800), 0x00000000);
1873 break;
1874 case DCB_OUTPUT_TMDS:
1875 case DCB_OUTPUT_LVDS:
1876 case DCB_OUTPUT_DP:
1877 if (cfg & 0x00000100)
1878 tmp = 0x00000101;
1879 else
1880 tmp = 0x00000000;
1881
1882 nv_mask(device, 0x612300 + (or * 0x800), 0x00000707, tmp);
1883 break;
1884 default:
1885 break;
1886 }
1887
1888 break;
1889 }
1890
1891 nv_wr32(device, 0x6101d4, 0x00000000);
1892 nv_wr32(device, 0x6109d4, 0x00000000);
1893 nv_wr32(device, 0x6101d0, 0x80000000);
1894}
1895
1896static void
1897nvd0_display_unk4_handler(struct drm_device *dev, u32 crtc, u32 mask)
1898{
1899 struct nouveau_device *device = nouveau_dev(dev);
1900 struct dcb_output *dcb;
1901 int pclk, i;
1902
1903 pclk = nv_rd32(device, 0x660450 + (crtc * 0x300)) / 1000;
1904
1905 for (i = 0; mask && i < 8; i++) {
1906 u32 mcp = nv_rd32(device, 0x660180 + (i * 0x20));
1907 u32 cfg = nv_rd32(device, 0x660184 + (i * 0x20));
1908 if (!(mcp & (1 << crtc)))
1909 continue;
1910
1911 dcb = lookup_dcb(dev, i, mcp);
1912 if (!dcb)
1913 continue;
1914
1915 nouveau_bios_run_display_table(dev, cfg, -pclk, dcb, crtc);
1916 }
1917
1918 nv_wr32(device, 0x6101d4, 0x00000000);
1919 nv_wr32(device, 0x6109d4, 0x00000000);
1920 nv_wr32(device, 0x6101d0, 0x80000000);
1921}
1922
1923static void
1924nvd0_display_bh(unsigned long data)
1925{
1926 struct drm_device *dev = (struct drm_device *)data;
1927 struct nouveau_device *device = nouveau_dev(dev);
1928 struct nouveau_drm *drm = nouveau_drm(dev);
1929 struct nvd0_disp *disp = nvd0_disp(dev);
1930 u32 mask = 0, crtc = ~0;
1931 int i;
1932
1933 if (drm_debug & (DRM_UT_DRIVER | DRM_UT_KMS)) {
1934 NV_INFO(drm, "PDISP: modeset req %d\n", disp->modeset);
1935 NV_INFO(drm, " STAT: 0x%08x 0x%08x 0x%08x\n",
1936 nv_rd32(device, 0x6101d0),
1937 nv_rd32(device, 0x6101d4), nv_rd32(device, 0x6109d4));
1938 for (i = 0; i < 8; i++) {
1939 NV_INFO(drm, " %s%d: 0x%08x 0x%08x\n",
1940 i < 4 ? "DAC" : "SOR", i,
1941 nv_rd32(device, 0x640180 + (i * 0x20)),
1942 nv_rd32(device, 0x660180 + (i * 0x20)));
1943 }
1944 }
1945
1946 while (!mask && ++crtc < dev->mode_config.num_crtc)
1947 mask = nv_rd32(device, 0x6101d4 + (crtc * 0x800));
1948
1949 if (disp->modeset & 0x00000001)
1950 nvd0_display_unk1_handler(dev, crtc, mask);
1951 if (disp->modeset & 0x00000002)
1952 nvd0_display_unk2_handler(dev, crtc, mask);
1953 if (disp->modeset & 0x00000004)
1954 nvd0_display_unk4_handler(dev, crtc, mask);
1955}
1956
1957void
1958nvd0_display_intr(struct drm_device *dev)
1959{
1960 struct nvd0_disp *disp = nvd0_disp(dev);
1961 struct nouveau_device *device = nouveau_dev(dev);
1962 struct nouveau_drm *drm = nouveau_drm(dev);
1963 u32 intr = nv_rd32(device, 0x610088);
1964
1965 if (intr & 0x00000001) {
1966 u32 stat = nv_rd32(device, 0x61008c);
1967 nv_wr32(device, 0x61008c, stat);
1968 intr &= ~0x00000001;
1969 }
1970
1971 if (intr & 0x00000002) {
1972 u32 stat = nv_rd32(device, 0x61009c);
1973 int chid = ffs(stat) - 1;
1974 if (chid >= 0) {
1975 u32 mthd = nv_rd32(device, 0x6101f0 + (chid * 12));
1976 u32 data = nv_rd32(device, 0x6101f4 + (chid * 12));
1977 u32 unkn = nv_rd32(device, 0x6101f8 + (chid * 12));
1978
1979 NV_INFO(drm, "EvoCh: chid %d mthd 0x%04x data 0x%08x "
1980 "0x%08x 0x%08x\n",
1981 chid, (mthd & 0x0000ffc), data, mthd, unkn);
1982 nv_wr32(device, 0x61009c, (1 << chid));
1983 nv_wr32(device, 0x6101f0 + (chid * 12), 0x90000000);
1984 }
1985
1986 intr &= ~0x00000002;
1987 }
1988
1989 if (intr & 0x00100000) {
1990 u32 stat = nv_rd32(device, 0x6100ac);
1991
1992 if (stat & 0x00000007) {
1993 disp->modeset = stat;
1994 tasklet_schedule(&disp->tasklet);
1995
1996 nv_wr32(device, 0x6100ac, (stat & 0x00000007));
1997 stat &= ~0x00000007;
1998 }
1999
2000 if (stat) {
2001 NV_INFO(drm, "PDISP: unknown intr24 0x%08x\n", stat);
2002 nv_wr32(device, 0x6100ac, stat);
2003 }
2004
2005 intr &= ~0x00100000;
2006 }
2007
2008 intr &= ~0x0f000000; /* vblank, handled in core */
2009 if (intr)
2010 NV_INFO(drm, "PDISP: unknown intr 0x%08x\n", intr);
2011}
2012
2013/******************************************************************************
2014 * Init 1765 * Init
2015 *****************************************************************************/ 1766 *****************************************************************************/
2016void 1767void
@@ -2156,9 +1907,6 @@ nvd0_display_create(struct drm_device *dev)
2156 connector->funcs->destroy(connector); 1907 connector->funcs->destroy(connector);
2157 } 1908 }
2158 1909
2159 /* setup interrupt handling */
2160 tasklet_init(&disp->tasklet, nvd0_display_bh, (unsigned long)dev);
2161
2162out: 1910out:
2163 if (ret) 1911 if (ret)
2164 nvd0_display_destroy(dev); 1912 nvd0_display_destroy(dev);