aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2015-08-20 00:54:22 -0400
committerBen Skeggs <bskeggs@redhat.com>2015-08-27 22:40:48 -0400
commit2b700825e7a7702fb862edba1262c98040dc1bf6 (patch)
tree9887b21c63adad8d7aba0a283010c66791d5a1d9
parentae0a5b2dd2f54584d677701d989732b464b6d8c9 (diff)
drm/nouveau/mc: move device irq handling to platform-specific code
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/device.h4
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h9
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/base.c72
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c46
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c99
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/g94.c40
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf106.c41
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv40.c46
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv4c.c39
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c8
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c80
19 files changed, 182 insertions, 324 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
index bc151c64bbad..b4974505af05 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
@@ -146,6 +146,7 @@ struct nvkm_device_func {
146 struct nvkm_device_tegra *(*tegra)(struct nvkm_device *); 146 struct nvkm_device_tegra *(*tegra)(struct nvkm_device *);
147 void *(*dtor)(struct nvkm_device *); 147 void *(*dtor)(struct nvkm_device *);
148 int (*preinit)(struct nvkm_device *); 148 int (*preinit)(struct nvkm_device *);
149 int (*init)(struct nvkm_device *);
149 void (*fini)(struct nvkm_device *, bool suspend); 150 void (*fini)(struct nvkm_device *, bool suspend);
150}; 151};
151 152
@@ -247,9 +248,6 @@ nv_device_resource_start(struct nvkm_device *device, unsigned int bar);
247resource_size_t 248resource_size_t
248nv_device_resource_len(struct nvkm_device *device, unsigned int bar); 249nv_device_resource_len(struct nvkm_device *device, unsigned int bar);
249 250
250int
251nv_device_get_irq(struct nvkm_device *device, bool stall);
252
253struct platform_device; 251struct platform_device;
254 252
255enum nv_bus_type { 253enum nv_bus_type {
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h b/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h
index 162986e7f8c4..1755c2d30fcd 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h
@@ -5,6 +5,7 @@
5struct nvkm_device_tegra { 5struct nvkm_device_tegra {
6 struct nvkm_device device; 6 struct nvkm_device device;
7 struct platform_device *pdev; 7 struct platform_device *pdev;
8 int irq;
8}; 9};
9 10
10int nvkm_device_tegra_new(struct platform_device *, 11int nvkm_device_tegra_new(struct platform_device *,
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h
index 1fbbdaad7fcd..4de05e718f83 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/mc.h
@@ -5,24 +5,17 @@
5struct nvkm_mc { 5struct nvkm_mc {
6 const struct nvkm_mc_func *func; 6 const struct nvkm_mc_func *func;
7 struct nvkm_subdev subdev; 7 struct nvkm_subdev subdev;
8
9 unsigned int irq;
10 bool use_msi;
11}; 8};
12 9
10void nvkm_mc_intr(struct nvkm_mc *, bool *handled);
13void nvkm_mc_intr_unarm(struct nvkm_mc *); 11void nvkm_mc_intr_unarm(struct nvkm_mc *);
14void nvkm_mc_intr_rearm(struct nvkm_mc *); 12void nvkm_mc_intr_rearm(struct nvkm_mc *);
15u32 nvkm_mc_intr_mask(struct nvkm_mc *);
16void nvkm_mc_unk260(struct nvkm_mc *, u32 data); 13void nvkm_mc_unk260(struct nvkm_mc *, u32 data);
17 14
18int nv04_mc_new(struct nvkm_device *, int, struct nvkm_mc **); 15int nv04_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
19int nv40_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
20int nv44_mc_new(struct nvkm_device *, int, struct nvkm_mc **); 16int nv44_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
21int nv4c_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
22int nv50_mc_new(struct nvkm_device *, int, struct nvkm_mc **); 17int nv50_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
23int g94_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
24int g98_mc_new(struct nvkm_device *, int, struct nvkm_mc **); 18int g98_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
25int gf100_mc_new(struct nvkm_device *, int, struct nvkm_mc **); 19int gf100_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
26int gf106_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
27int gk20a_mc_new(struct nvkm_device *, int, struct nvkm_mc **); 20int gk20a_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
28#endif 21#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h
index ea4b0cce6159..ac14fdf2f967 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/pci.h
@@ -5,13 +5,15 @@
5struct nvkm_pci { 5struct nvkm_pci {
6 const struct nvkm_pci_func *func; 6 const struct nvkm_pci_func *func;
7 struct nvkm_subdev subdev; 7 struct nvkm_subdev subdev;
8 struct pci_dev *pdev;
9 int irq;
10 bool msi;
8}; 11};
9 12
10u32 nvkm_pci_rd32(struct nvkm_pci *, u16 addr); 13u32 nvkm_pci_rd32(struct nvkm_pci *, u16 addr);
11void nvkm_pci_wr08(struct nvkm_pci *, u16 addr, u8 data); 14void nvkm_pci_wr08(struct nvkm_pci *, u16 addr, u8 data);
12void nvkm_pci_wr32(struct nvkm_pci *, u16 addr, u32 data); 15void nvkm_pci_wr32(struct nvkm_pci *, u16 addr, u32 data);
13void nvkm_pci_rom_shadow(struct nvkm_pci *, bool shadow); 16void nvkm_pci_rom_shadow(struct nvkm_pci *, bool shadow);
14void nvkm_pci_msi_rearm(struct nvkm_pci *);
15 17
16int nv04_pci_new(struct nvkm_device *, int, struct nvkm_pci **); 18int nv04_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
17int nv40_pci_new(struct nvkm_device *, int, struct nvkm_pci **); 19int nv40_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
index 743a3e9796dd..5fab8384d1f4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
@@ -479,7 +479,7 @@ nv40_chipset = {
479 .gpio = nv10_gpio_new, 479 .gpio = nv10_gpio_new,
480 .i2c = nv04_i2c_new, 480 .i2c = nv04_i2c_new,
481 .imem = nv40_instmem_new, 481 .imem = nv40_instmem_new,
482 .mc = nv40_mc_new, 482 .mc = nv04_mc_new,
483 .mmu = nv04_mmu_new, 483 .mmu = nv04_mmu_new,
484 .pci = nv40_pci_new, 484 .pci = nv40_pci_new,
485 .therm = nv40_therm_new, 485 .therm = nv40_therm_new,
@@ -505,7 +505,7 @@ nv41_chipset = {
505 .gpio = nv10_gpio_new, 505 .gpio = nv10_gpio_new,
506 .i2c = nv04_i2c_new, 506 .i2c = nv04_i2c_new,
507 .imem = nv40_instmem_new, 507 .imem = nv40_instmem_new,
508 .mc = nv40_mc_new, 508 .mc = nv04_mc_new,
509 .mmu = nv41_mmu_new, 509 .mmu = nv41_mmu_new,
510 .pci = nv40_pci_new, 510 .pci = nv40_pci_new,
511 .therm = nv40_therm_new, 511 .therm = nv40_therm_new,
@@ -531,7 +531,7 @@ nv42_chipset = {
531 .gpio = nv10_gpio_new, 531 .gpio = nv10_gpio_new,
532 .i2c = nv04_i2c_new, 532 .i2c = nv04_i2c_new,
533 .imem = nv40_instmem_new, 533 .imem = nv40_instmem_new,
534 .mc = nv40_mc_new, 534 .mc = nv04_mc_new,
535 .mmu = nv41_mmu_new, 535 .mmu = nv41_mmu_new,
536 .pci = nv40_pci_new, 536 .pci = nv40_pci_new,
537 .therm = nv40_therm_new, 537 .therm = nv40_therm_new,
@@ -557,7 +557,7 @@ nv43_chipset = {
557 .gpio = nv10_gpio_new, 557 .gpio = nv10_gpio_new,
558 .i2c = nv04_i2c_new, 558 .i2c = nv04_i2c_new,
559 .imem = nv40_instmem_new, 559 .imem = nv40_instmem_new,
560 .mc = nv40_mc_new, 560 .mc = nv04_mc_new,
561 .mmu = nv41_mmu_new, 561 .mmu = nv41_mmu_new,
562 .pci = nv40_pci_new, 562 .pci = nv40_pci_new,
563 .therm = nv40_therm_new, 563 .therm = nv40_therm_new,
@@ -609,7 +609,7 @@ nv45_chipset = {
609 .gpio = nv10_gpio_new, 609 .gpio = nv10_gpio_new,
610 .i2c = nv04_i2c_new, 610 .i2c = nv04_i2c_new,
611 .imem = nv40_instmem_new, 611 .imem = nv40_instmem_new,
612 .mc = nv40_mc_new, 612 .mc = nv04_mc_new,
613 .mmu = nv04_mmu_new, 613 .mmu = nv04_mmu_new,
614 .pci = nv40_pci_new, 614 .pci = nv40_pci_new,
615 .therm = nv40_therm_new, 615 .therm = nv40_therm_new,
@@ -661,7 +661,7 @@ nv47_chipset = {
661 .gpio = nv10_gpio_new, 661 .gpio = nv10_gpio_new,
662 .i2c = nv04_i2c_new, 662 .i2c = nv04_i2c_new,
663 .imem = nv40_instmem_new, 663 .imem = nv40_instmem_new,
664 .mc = nv40_mc_new, 664 .mc = nv04_mc_new,
665 .mmu = nv41_mmu_new, 665 .mmu = nv41_mmu_new,
666 .pci = nv40_pci_new, 666 .pci = nv40_pci_new,
667 .therm = nv40_therm_new, 667 .therm = nv40_therm_new,
@@ -687,7 +687,7 @@ nv49_chipset = {
687 .gpio = nv10_gpio_new, 687 .gpio = nv10_gpio_new,
688 .i2c = nv04_i2c_new, 688 .i2c = nv04_i2c_new,
689 .imem = nv40_instmem_new, 689 .imem = nv40_instmem_new,
690 .mc = nv40_mc_new, 690 .mc = nv04_mc_new,
691 .mmu = nv41_mmu_new, 691 .mmu = nv41_mmu_new,
692 .pci = nv40_pci_new, 692 .pci = nv40_pci_new,
693 .therm = nv40_therm_new, 693 .therm = nv40_therm_new,
@@ -739,7 +739,7 @@ nv4b_chipset = {
739 .gpio = nv10_gpio_new, 739 .gpio = nv10_gpio_new,
740 .i2c = nv04_i2c_new, 740 .i2c = nv04_i2c_new,
741 .imem = nv40_instmem_new, 741 .imem = nv40_instmem_new,
742 .mc = nv40_mc_new, 742 .mc = nv04_mc_new,
743 .mmu = nv41_mmu_new, 743 .mmu = nv41_mmu_new,
744 .pci = nv40_pci_new, 744 .pci = nv40_pci_new,
745 .therm = nv40_therm_new, 745 .therm = nv40_therm_new,
@@ -765,7 +765,7 @@ nv4c_chipset = {
765 .gpio = nv10_gpio_new, 765 .gpio = nv10_gpio_new,
766 .i2c = nv04_i2c_new, 766 .i2c = nv04_i2c_new,
767 .imem = nv40_instmem_new, 767 .imem = nv40_instmem_new,
768 .mc = nv4c_mc_new, 768 .mc = nv44_mc_new,
769 .mmu = nv44_mmu_new, 769 .mmu = nv44_mmu_new,
770 .pci = nv4c_pci_new, 770 .pci = nv4c_pci_new,
771 .therm = nv40_therm_new, 771 .therm = nv40_therm_new,
@@ -791,7 +791,7 @@ nv4e_chipset = {
791 .gpio = nv10_gpio_new, 791 .gpio = nv10_gpio_new,
792 .i2c = nv4e_i2c_new, 792 .i2c = nv4e_i2c_new,
793 .imem = nv40_instmem_new, 793 .imem = nv40_instmem_new,
794 .mc = nv4c_mc_new, 794 .mc = nv44_mc_new,
795 .mmu = nv44_mmu_new, 795 .mmu = nv44_mmu_new,
796 .pci = nv4c_pci_new, 796 .pci = nv4c_pci_new,
797 .therm = nv40_therm_new, 797 .therm = nv40_therm_new,
@@ -846,7 +846,7 @@ nv63_chipset = {
846 .gpio = nv10_gpio_new, 846 .gpio = nv10_gpio_new,
847 .i2c = nv04_i2c_new, 847 .i2c = nv04_i2c_new,
848 .imem = nv40_instmem_new, 848 .imem = nv40_instmem_new,
849 .mc = nv4c_mc_new, 849 .mc = nv44_mc_new,
850 .mmu = nv44_mmu_new, 850 .mmu = nv44_mmu_new,
851 .pci = nv4c_pci_new, 851 .pci = nv4c_pci_new,
852 .therm = nv40_therm_new, 852 .therm = nv40_therm_new,
@@ -872,7 +872,7 @@ nv67_chipset = {
872 .gpio = nv10_gpio_new, 872 .gpio = nv10_gpio_new,
873 .i2c = nv04_i2c_new, 873 .i2c = nv04_i2c_new,
874 .imem = nv40_instmem_new, 874 .imem = nv40_instmem_new,
875 .mc = nv4c_mc_new, 875 .mc = nv44_mc_new,
876 .mmu = nv44_mmu_new, 876 .mmu = nv44_mmu_new,
877 .pci = nv4c_pci_new, 877 .pci = nv4c_pci_new,
878 .therm = nv40_therm_new, 878 .therm = nv40_therm_new,
@@ -898,7 +898,7 @@ nv68_chipset = {
898 .gpio = nv10_gpio_new, 898 .gpio = nv10_gpio_new,
899 .i2c = nv04_i2c_new, 899 .i2c = nv04_i2c_new,
900 .imem = nv40_instmem_new, 900 .imem = nv40_instmem_new,
901 .mc = nv4c_mc_new, 901 .mc = nv44_mc_new,
902 .mmu = nv44_mmu_new, 902 .mmu = nv44_mmu_new,
903 .pci = nv4c_pci_new, 903 .pci = nv4c_pci_new,
904 .therm = nv40_therm_new, 904 .therm = nv40_therm_new,
@@ -1022,7 +1022,7 @@ nv94_chipset = {
1022 .gpio = g94_gpio_new, 1022 .gpio = g94_gpio_new,
1023 .i2c = g94_i2c_new, 1023 .i2c = g94_i2c_new,
1024 .imem = nv50_instmem_new, 1024 .imem = nv50_instmem_new,
1025 .mc = g94_mc_new, 1025 .mc = nv50_mc_new,
1026 .mmu = nv50_mmu_new, 1026 .mmu = nv50_mmu_new,
1027 .mxm = nv50_mxm_new, 1027 .mxm = nv50_mxm_new,
1028 .pci = nv40_pci_new, 1028 .pci = nv40_pci_new,
@@ -1054,7 +1054,7 @@ nv96_chipset = {
1054 .gpio = g94_gpio_new, 1054 .gpio = g94_gpio_new,
1055 .i2c = g94_i2c_new, 1055 .i2c = g94_i2c_new,
1056 .imem = nv50_instmem_new, 1056 .imem = nv50_instmem_new,
1057 .mc = g94_mc_new, 1057 .mc = nv50_mc_new,
1058 .mmu = nv50_mmu_new, 1058 .mmu = nv50_mmu_new,
1059 .mxm = nv50_mxm_new, 1059 .mxm = nv50_mxm_new,
1060 .pci = nv40_pci_new, 1060 .pci = nv40_pci_new,
@@ -1385,7 +1385,7 @@ nvc1_chipset = {
1385 .ibus = gf100_ibus_new, 1385 .ibus = gf100_ibus_new,
1386 .imem = nv50_instmem_new, 1386 .imem = nv50_instmem_new,
1387 .ltc = gf100_ltc_new, 1387 .ltc = gf100_ltc_new,
1388 .mc = gf106_mc_new, 1388 .mc = gf100_mc_new,
1389 .mmu = gf100_mmu_new, 1389 .mmu = gf100_mmu_new,
1390 .mxm = nv50_mxm_new, 1390 .mxm = nv50_mxm_new,
1391 .pci = nv40_pci_new, 1391 .pci = nv40_pci_new,
@@ -1420,7 +1420,7 @@ nvc3_chipset = {
1420 .ibus = gf100_ibus_new, 1420 .ibus = gf100_ibus_new,
1421 .imem = nv50_instmem_new, 1421 .imem = nv50_instmem_new,
1422 .ltc = gf100_ltc_new, 1422 .ltc = gf100_ltc_new,
1423 .mc = gf106_mc_new, 1423 .mc = gf100_mc_new,
1424 .mmu = gf100_mmu_new, 1424 .mmu = gf100_mmu_new,
1425 .mxm = nv50_mxm_new, 1425 .mxm = nv50_mxm_new,
1426 .pci = nv40_pci_new, 1426 .pci = nv40_pci_new,
@@ -1563,7 +1563,7 @@ nvcf_chipset = {
1563 .ibus = gf100_ibus_new, 1563 .ibus = gf100_ibus_new,
1564 .imem = nv50_instmem_new, 1564 .imem = nv50_instmem_new,
1565 .ltc = gf100_ltc_new, 1565 .ltc = gf100_ltc_new,
1566 .mc = gf106_mc_new, 1566 .mc = gf100_mc_new,
1567 .mmu = gf100_mmu_new, 1567 .mmu = gf100_mmu_new,
1568 .mxm = nv50_mxm_new, 1568 .mxm = nv50_mxm_new,
1569 .pci = nv40_pci_new, 1569 .pci = nv40_pci_new,
@@ -1598,7 +1598,7 @@ nvd7_chipset = {
1598 .ibus = gf100_ibus_new, 1598 .ibus = gf100_ibus_new,
1599 .imem = nv50_instmem_new, 1599 .imem = nv50_instmem_new,
1600 .ltc = gf100_ltc_new, 1600 .ltc = gf100_ltc_new,
1601 .mc = gf106_mc_new, 1601 .mc = gf100_mc_new,
1602 .mmu = gf100_mmu_new, 1602 .mmu = gf100_mmu_new,
1603 .mxm = nv50_mxm_new, 1603 .mxm = nv50_mxm_new,
1604 .pci = nv40_pci_new, 1604 .pci = nv40_pci_new,
@@ -1631,7 +1631,7 @@ nvd9_chipset = {
1631 .ibus = gf100_ibus_new, 1631 .ibus = gf100_ibus_new,
1632 .imem = nv50_instmem_new, 1632 .imem = nv50_instmem_new,
1633 .ltc = gf100_ltc_new, 1633 .ltc = gf100_ltc_new,
1634 .mc = gf106_mc_new, 1634 .mc = gf100_mc_new,
1635 .mmu = gf100_mmu_new, 1635 .mmu = gf100_mmu_new,
1636 .mxm = nv50_mxm_new, 1636 .mxm = nv50_mxm_new,
1637 .pci = nv40_pci_new, 1637 .pci = nv40_pci_new,
@@ -1666,7 +1666,7 @@ nve4_chipset = {
1666 .ibus = gk104_ibus_new, 1666 .ibus = gk104_ibus_new,
1667 .imem = nv50_instmem_new, 1667 .imem = nv50_instmem_new,
1668 .ltc = gk104_ltc_new, 1668 .ltc = gk104_ltc_new,
1669 .mc = gf106_mc_new, 1669 .mc = gf100_mc_new,
1670 .mmu = gf100_mmu_new, 1670 .mmu = gf100_mmu_new,
1671 .mxm = nv50_mxm_new, 1671 .mxm = nv50_mxm_new,
1672 .pci = nv40_pci_new, 1672 .pci = nv40_pci_new,
@@ -1703,7 +1703,7 @@ nve6_chipset = {
1703 .ibus = gk104_ibus_new, 1703 .ibus = gk104_ibus_new,
1704 .imem = nv50_instmem_new, 1704 .imem = nv50_instmem_new,
1705 .ltc = gk104_ltc_new, 1705 .ltc = gk104_ltc_new,
1706 .mc = gf106_mc_new, 1706 .mc = gf100_mc_new,
1707 .mmu = gf100_mmu_new, 1707 .mmu = gf100_mmu_new,
1708 .mxm = nv50_mxm_new, 1708 .mxm = nv50_mxm_new,
1709 .pci = nv40_pci_new, 1709 .pci = nv40_pci_new,
@@ -1740,7 +1740,7 @@ nve7_chipset = {
1740 .ibus = gk104_ibus_new, 1740 .ibus = gk104_ibus_new,
1741 .imem = nv50_instmem_new, 1741 .imem = nv50_instmem_new,
1742 .ltc = gk104_ltc_new, 1742 .ltc = gk104_ltc_new,
1743 .mc = gf106_mc_new, 1743 .mc = gf100_mc_new,
1744 .mmu = gf100_mmu_new, 1744 .mmu = gf100_mmu_new,
1745 .mxm = nv50_mxm_new, 1745 .mxm = nv50_mxm_new,
1746 .pci = nv40_pci_new, 1746 .pci = nv40_pci_new,
@@ -1801,7 +1801,7 @@ nvf0_chipset = {
1801 .ibus = gk104_ibus_new, 1801 .ibus = gk104_ibus_new,
1802 .imem = nv50_instmem_new, 1802 .imem = nv50_instmem_new,
1803 .ltc = gk104_ltc_new, 1803 .ltc = gk104_ltc_new,
1804 .mc = gf106_mc_new, 1804 .mc = gf100_mc_new,
1805 .mmu = gf100_mmu_new, 1805 .mmu = gf100_mmu_new,
1806 .mxm = nv50_mxm_new, 1806 .mxm = nv50_mxm_new,
1807 .pci = nv40_pci_new, 1807 .pci = nv40_pci_new,
@@ -1837,7 +1837,7 @@ nvf1_chipset = {
1837 .ibus = gk104_ibus_new, 1837 .ibus = gk104_ibus_new,
1838 .imem = nv50_instmem_new, 1838 .imem = nv50_instmem_new,
1839 .ltc = gk104_ltc_new, 1839 .ltc = gk104_ltc_new,
1840 .mc = gf106_mc_new, 1840 .mc = gf100_mc_new,
1841 .mmu = gf100_mmu_new, 1841 .mmu = gf100_mmu_new,
1842 .mxm = nv50_mxm_new, 1842 .mxm = nv50_mxm_new,
1843 .pci = nv40_pci_new, 1843 .pci = nv40_pci_new,
@@ -2231,11 +2231,17 @@ nvkm_device_init(struct nvkm_device *device)
2231 nvdev_trace(device, "init running...\n"); 2231 nvdev_trace(device, "init running...\n");
2232 time = ktime_to_us(ktime_get()); 2232 time = ktime_to_us(ktime_get());
2233 2233
2234 if (device->func->init) {
2235 ret = device->func->init(device);
2236 if (ret)
2237 goto fail;
2238 }
2239
2234 for (i = 0; i < NVKM_SUBDEV_NR; i++) { 2240 for (i = 0; i < NVKM_SUBDEV_NR; i++) {
2235 if ((subdev = nvkm_device_subdev(device, i))) { 2241 if ((subdev = nvkm_device_subdev(device, i))) {
2236 ret = nvkm_subdev_init(subdev); 2242 ret = nvkm_subdev_init(subdev);
2237 if (ret) 2243 if (ret)
2238 goto fail; 2244 goto fail_subdev;
2239 } 2245 }
2240 } 2246 }
2241 2247
@@ -2245,12 +2251,13 @@ nvkm_device_init(struct nvkm_device *device)
2245 nvdev_trace(device, "init completed in %lldus\n", time); 2251 nvdev_trace(device, "init completed in %lldus\n", time);
2246 return 0; 2252 return 0;
2247 2253
2248fail: 2254fail_subdev:
2249 do { 2255 do {
2250 if ((subdev = nvkm_device_subdev(device, i))) 2256 if ((subdev = nvkm_device_subdev(device, i)))
2251 nvkm_subdev_fini(subdev, false); 2257 nvkm_subdev_fini(subdev, false);
2252 } while (--i >= 0); 2258 } while (--i >= 0);
2253 2259
2260fail:
2254 nvdev_error(device, "init failed with %d\n", ret); 2261 nvdev_error(device, "init failed with %d\n", ret);
2255 return ret; 2262 return ret;
2256} 2263}
@@ -2285,17 +2292,6 @@ nv_device_resource_len(struct nvkm_device *device, unsigned int bar)
2285 } 2292 }
2286} 2293}
2287 2294
2288int
2289nv_device_get_irq(struct nvkm_device *device, bool stall)
2290{
2291 if (nv_device_is_pci(device)) {
2292 return device->pdev->irq;
2293 } else {
2294 return platform_get_irq_byname(device->platformdev,
2295 stall ? "stall" : "nonstall");
2296 }
2297}
2298
2299void 2295void
2300nvkm_device_del(struct nvkm_device **pdevice) 2296nvkm_device_del(struct nvkm_device **pdevice)
2301{ 2297{
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
index 0a5e5b88fee2..2587a17981b2 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
@@ -31,9 +31,54 @@ nvkm_device_tegra(struct nvkm_device *obj)
31 return container_of(obj, struct nvkm_device_tegra, device); 31 return container_of(obj, struct nvkm_device_tegra, device);
32} 32}
33 33
34static irqreturn_t
35nvkm_device_tegra_intr(int irq, void *arg)
36{
37 struct nvkm_device_tegra *tdev = arg;
38 struct nvkm_mc *mc = tdev->device.mc;
39 bool handled = false;
40 if (likely(mc)) {
41 nvkm_mc_intr_unarm(mc);
42 nvkm_mc_intr(mc, &handled);
43 nvkm_mc_intr_rearm(mc);
44 }
45 return handled ? IRQ_HANDLED : IRQ_NONE;
46}
47
48static void
49nvkm_device_tegra_fini(struct nvkm_device *device, bool suspend)
50{
51 struct nvkm_device_tegra *tdev = nvkm_device_tegra(device);
52 if (tdev->irq) {
53 free_irq(tdev->irq, tdev);
54 tdev->irq = 0;
55 };
56}
57
58static int
59nvkm_device_tegra_init(struct nvkm_device *device)
60{
61 struct nvkm_device_tegra *tdev = nvkm_device_tegra(device);
62 int irq, ret;
63
64 irq = platform_get_irq_byname(tdev->pdev, "stall");
65 if (irq < 0)
66 return irq;
67
68 ret = request_irq(irq, nvkm_device_tegra_intr,
69 IRQF_SHARED, "nvkm", tdev);
70 if (ret)
71 return ret;
72
73 tdev->irq = irq;
74 return 0;
75}
76
34static const struct nvkm_device_func 77static const struct nvkm_device_func
35nvkm_device_tegra_func = { 78nvkm_device_tegra_func = {
36 .tegra = nvkm_device_tegra, 79 .tegra = nvkm_device_tegra,
80 .init = nvkm_device_tegra_init,
81 .fini = nvkm_device_tegra_fini,
37}; 82};
38 83
39int 84int
@@ -48,6 +93,7 @@ nvkm_device_tegra_new(struct platform_device *pdev,
48 return -ENOMEM; 93 return -ENOMEM;
49 *pdevice = &tdev->device; 94 *pdevice = &tdev->device;
50 tdev->pdev = pdev; 95 tdev->pdev = pdev;
96 tdev->irq = -1;
51 97
52 return nvkm_device_ctor(&nvkm_device_tegra_func, NULL, pdev, 98 return nvkm_device_ctor(&nvkm_device_tegra_func, NULL, pdev,
53 NVKM_BUS_PLATFORM, pdev->id, NULL, 99 NVKM_BUS_PLATFORM, pdev->id, NULL,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild
index 721643f04bb5..bef325dcb4d0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/Kbuild
@@ -1,11 +1,7 @@
1nvkm-y += nvkm/subdev/mc/base.o 1nvkm-y += nvkm/subdev/mc/base.o
2nvkm-y += nvkm/subdev/mc/nv04.o 2nvkm-y += nvkm/subdev/mc/nv04.o
3nvkm-y += nvkm/subdev/mc/nv40.o
4nvkm-y += nvkm/subdev/mc/nv44.o 3nvkm-y += nvkm/subdev/mc/nv44.o
5nvkm-y += nvkm/subdev/mc/nv4c.o
6nvkm-y += nvkm/subdev/mc/nv50.o 4nvkm-y += nvkm/subdev/mc/nv50.o
7nvkm-y += nvkm/subdev/mc/g94.o
8nvkm-y += nvkm/subdev/mc/g98.o 5nvkm-y += nvkm/subdev/mc/g98.o
9nvkm-y += nvkm/subdev/mc/gf100.o 6nvkm-y += nvkm/subdev/mc/gf100.o
10nvkm-y += nvkm/subdev/mc/gf106.o
11nvkm-y += nvkm/subdev/mc/gk20a.o 7nvkm-y += nvkm/subdev/mc/gk20a.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c
index 6a8d56c7201e..954fbbe56c4b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c
@@ -44,7 +44,7 @@ nvkm_mc_intr_rearm(struct nvkm_mc *mc)
44 return mc->func->intr_rearm(mc); 44 return mc->func->intr_rearm(mc);
45} 45}
46 46
47u32 47static u32
48nvkm_mc_intr_mask(struct nvkm_mc *mc) 48nvkm_mc_intr_mask(struct nvkm_mc *mc)
49{ 49{
50 u32 intr = mc->func->intr_mask(mc); 50 u32 intr = mc->func->intr_mask(mc);
@@ -53,39 +53,28 @@ nvkm_mc_intr_mask(struct nvkm_mc *mc)
53 return intr; 53 return intr;
54} 54}
55 55
56static irqreturn_t 56void
57nvkm_mc_intr(int irq, void *arg) 57nvkm_mc_intr(struct nvkm_mc *mc, bool *handled)
58{ 58{
59 struct nvkm_mc *mc = arg; 59 struct nvkm_device *device = mc->subdev.device;
60 struct nvkm_subdev *subdev = &mc->subdev; 60 struct nvkm_subdev *subdev;
61 struct nvkm_device *device = subdev->device;
62 const struct nvkm_mc_intr *map = mc->func->intr; 61 const struct nvkm_mc_intr *map = mc->func->intr;
63 struct nvkm_subdev *unit; 62 u32 stat, intr;
64 u32 intr; 63
65 64 stat = intr = nvkm_mc_intr_mask(mc);
66 nvkm_mc_intr_unarm(mc); 65 while (map->stat) {
67 intr = nvkm_mc_intr_mask(mc); 66 if (intr & map->stat) {
68 if (mc->use_msi) 67 subdev = nvkm_device_subdev(device, map->unit);
69 mc->func->msi_rearm(mc); 68 if (subdev)
70 69 nvkm_subdev_intr(subdev);
71 if (intr) { 70 stat &= ~map->stat;
72 u32 stat = intr = nvkm_mc_intr_mask(mc);
73 while (map->stat) {
74 if (intr & map->stat) {
75 unit = nvkm_device_subdev(device, map->unit);
76 if (unit)
77 nvkm_subdev_intr(unit);
78 stat &= ~map->stat;
79 }
80 map++;
81 } 71 }
82 72 map++;
83 if (stat)
84 nvkm_error(subdev, "unknown intr %08x\n", stat);
85 } 73 }
86 74
87 nvkm_mc_intr_rearm(mc); 75 if (stat)
88 return intr ? IRQ_HANDLED : IRQ_NONE; 76 nvkm_error(&mc->subdev, "intr %08x\n", stat);
77 *handled = intr != 0;
89} 78}
90 79
91static int 80static int
@@ -97,13 +86,6 @@ nvkm_mc_fini(struct nvkm_subdev *subdev, bool suspend)
97} 86}
98 87
99static int 88static int
100nvkm_mc_oneinit(struct nvkm_subdev *subdev)
101{
102 struct nvkm_mc *mc = nvkm_mc(subdev);
103 return request_irq(mc->irq, nvkm_mc_intr, IRQF_SHARED, "nvkm", mc);
104}
105
106static int
107nvkm_mc_init(struct nvkm_subdev *subdev) 89nvkm_mc_init(struct nvkm_subdev *subdev)
108{ 90{
109 struct nvkm_mc *mc = nvkm_mc(subdev); 91 struct nvkm_mc *mc = nvkm_mc(subdev);
@@ -116,18 +98,12 @@ nvkm_mc_init(struct nvkm_subdev *subdev)
116static void * 98static void *
117nvkm_mc_dtor(struct nvkm_subdev *subdev) 99nvkm_mc_dtor(struct nvkm_subdev *subdev)
118{ 100{
119 struct nvkm_mc *mc = nvkm_mc(subdev); 101 return nvkm_mc(subdev);
120 struct nvkm_device *device = mc->subdev.device;
121 free_irq(mc->irq, mc);
122 if (mc->use_msi)
123 pci_disable_msi(device->pdev);
124 return mc;
125} 102}
126 103
127static const struct nvkm_subdev_func 104static const struct nvkm_subdev_func
128nvkm_mc = { 105nvkm_mc = {
129 .dtor = nvkm_mc_dtor, 106 .dtor = nvkm_mc_dtor,
130 .oneinit = nvkm_mc_oneinit,
131 .init = nvkm_mc_init, 107 .init = nvkm_mc_init,
132 .fini = nvkm_mc_fini, 108 .fini = nvkm_mc_fini,
133}; 109};
@@ -137,48 +113,11 @@ nvkm_mc_new_(const struct nvkm_mc_func *func, struct nvkm_device *device,
137 int index, struct nvkm_mc **pmc) 113 int index, struct nvkm_mc **pmc)
138{ 114{
139 struct nvkm_mc *mc; 115 struct nvkm_mc *mc;
140 int ret;
141 116
142 if (!(mc = *pmc = kzalloc(sizeof(*mc), GFP_KERNEL))) 117 if (!(mc = *pmc = kzalloc(sizeof(*mc), GFP_KERNEL)))
143 return -ENOMEM; 118 return -ENOMEM;
144 119
145 nvkm_subdev_ctor(&nvkm_mc, device, index, 0, &mc->subdev); 120 nvkm_subdev_ctor(&nvkm_mc, device, index, 0, &mc->subdev);
146 mc->func = func; 121 mc->func = func;
147
148 if (nv_device_is_pci(device)) {
149 switch (device->pdev->device & 0x0ff0) {
150 case 0x00f0:
151 case 0x02e0:
152 /* BR02? NFI how these would be handled yet exactly */
153 break;
154 default:
155 switch (device->chipset) {
156 case 0xaa:
157 /* reported broken, nv also disable it */
158 break;
159 default:
160 mc->use_msi = true;
161 break;
162 }
163 }
164
165 mc->use_msi = nvkm_boolopt(device->cfgopt, "NvMSI",
166 mc->use_msi);
167
168 if (mc->use_msi && mc->func->msi_rearm) {
169 mc->use_msi = pci_enable_msi(device->pdev) == 0;
170 if (mc->use_msi) {
171 nvkm_debug(&mc->subdev, "MSI enabled\n");
172 mc->func->msi_rearm(mc);
173 }
174 } else {
175 mc->use_msi = false;
176 }
177 }
178
179 ret = nv_device_get_irq(device, true);
180 if (ret < 0)
181 return ret;
182 mc->irq = ret;
183 return 0; 122 return 0;
184} 123}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g94.c
deleted file mode 100644
index 7d6a87f22b42..000000000000
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g94.c
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24#include "priv.h"
25
26static const struct nvkm_mc_func
27g94_mc = {
28 .init = nv50_mc_init,
29 .intr = nv50_mc_intr,
30 .intr_unarm = nv04_mc_intr_unarm,
31 .intr_rearm = nv04_mc_intr_rearm,
32 .intr_mask = nv04_mc_intr_mask,
33 .msi_rearm = nv40_mc_msi_rearm,
34};
35
36int
37g94_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
38{
39 return nvkm_mc_new_(&g94_mc, device, index, pmc);
40}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c
index 3eec7251b4d3..7344ad659105 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/g98.c
@@ -51,7 +51,6 @@ g98_mc = {
51 .intr_unarm = nv04_mc_intr_unarm, 51 .intr_unarm = nv04_mc_intr_unarm,
52 .intr_rearm = nv04_mc_intr_rearm, 52 .intr_rearm = nv04_mc_intr_rearm,
53 .intr_mask = nv04_mc_intr_mask, 53 .intr_mask = nv04_mc_intr_mask,
54 .msi_rearm = nv40_mc_msi_rearm,
55}; 54};
56 55
57int 56int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
index 6688d233a3e5..122fe69e83e4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c
@@ -74,12 +74,6 @@ gf100_mc_intr_mask(struct nvkm_mc *mc)
74 return intr0 | intr1; 74 return intr0 | intr1;
75} 75}
76 76
77static void
78gf100_mc_msi_rearm(struct nvkm_mc *mc)
79{
80 nvkm_wr32(mc->subdev.device, 0x088704, 0x00000000);
81}
82
83void 77void
84gf100_mc_unk260(struct nvkm_mc *mc, u32 data) 78gf100_mc_unk260(struct nvkm_mc *mc, u32 data)
85{ 79{
@@ -93,7 +87,6 @@ gf100_mc = {
93 .intr_unarm = gf100_mc_intr_unarm, 87 .intr_unarm = gf100_mc_intr_unarm,
94 .intr_rearm = gf100_mc_intr_rearm, 88 .intr_rearm = gf100_mc_intr_rearm,
95 .intr_mask = gf100_mc_intr_mask, 89 .intr_mask = gf100_mc_intr_mask,
96 .msi_rearm = gf100_mc_msi_rearm,
97 .unk260 = gf100_mc_unk260, 90 .unk260 = gf100_mc_unk260,
98}; 91};
99 92
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf106.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf106.c
deleted file mode 100644
index 31223cfa1a0a..000000000000
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf106.c
+++ /dev/null
@@ -1,41 +0,0 @@
1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24#include "priv.h"
25
26static const struct nvkm_mc_func
27gf106_mc = {
28 .init = nv50_mc_init,
29 .intr = gf100_mc_intr,
30 .intr_unarm = gf100_mc_intr_unarm,
31 .intr_rearm = gf100_mc_intr_rearm,
32 .intr_mask = gf100_mc_intr_mask,
33 .msi_rearm = nv40_mc_msi_rearm,
34 .unk260 = gf100_mc_unk260,
35};
36
37int
38gf106_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
39{
40 return nvkm_mc_new_(&gf106_mc, device, index, pmc);
41}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c
index 0592bd54bb82..d92efb33bcc3 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gk20a.c
@@ -30,7 +30,6 @@ gk20a_mc = {
30 .intr_unarm = gf100_mc_intr_unarm, 30 .intr_unarm = gf100_mc_intr_unarm,
31 .intr_rearm = gf100_mc_intr_rearm, 31 .intr_rearm = gf100_mc_intr_rearm,
32 .intr_mask = gf100_mc_intr_mask, 32 .intr_mask = gf100_mc_intr_mask,
33 .msi_rearm = nv40_mc_msi_rearm,
34}; 33};
35 34
36int 35int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv40.c
deleted file mode 100644
index 80912e7d1dec..000000000000
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv40.c
+++ /dev/null
@@ -1,46 +0,0 @@
1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24#include "priv.h"
25
26void
27nv40_mc_msi_rearm(struct nvkm_mc *mc)
28{
29 nvkm_wr08(mc->subdev.device, 0x088068, 0xff);
30}
31
32static const struct nvkm_mc_func
33nv40_mc = {
34 .init = nv04_mc_init,
35 .intr = nv04_mc_intr,
36 .intr_unarm = nv04_mc_intr_unarm,
37 .intr_rearm = nv04_mc_intr_rearm,
38 .intr_mask = nv04_mc_intr_mask,
39 .msi_rearm = nv40_mc_msi_rearm,
40};
41
42int
43nv40_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
44{
45 return nvkm_mc_new_(&nv40_mc, device, index, pmc);
46}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c
index 79958c13a5f8..9a3ac9965be0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv44.c
@@ -44,7 +44,6 @@ nv44_mc = {
44 .intr_unarm = nv04_mc_intr_unarm, 44 .intr_unarm = nv04_mc_intr_unarm,
45 .intr_rearm = nv04_mc_intr_rearm, 45 .intr_rearm = nv04_mc_intr_rearm,
46 .intr_mask = nv04_mc_intr_mask, 46 .intr_mask = nv04_mc_intr_mask,
47 .msi_rearm = nv40_mc_msi_rearm,
48}; 47};
49 48
50int 49int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv4c.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv4c.c
deleted file mode 100644
index 68a4a0477721..000000000000
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv4c.c
+++ /dev/null
@@ -1,39 +0,0 @@
1/*
2 * Copyright 2014 Ilia Mirkin
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ilia Mirkin
23 */
24#include "priv.h"
25
26static const struct nvkm_mc_func
27nv4c_mc = {
28 .init = nv44_mc_init,
29 .intr = nv04_mc_intr,
30 .intr_unarm = nv04_mc_intr_unarm,
31 .intr_rearm = nv04_mc_intr_rearm,
32 .intr_mask = nv04_mc_intr_mask,
33};
34
35int
36nv4c_mc_new(struct nvkm_device *device, int index, struct nvkm_mc **pmc)
37{
38 return nvkm_mc_new_(&nv4c_mc, device, index, pmc);
39}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c
index 325a18232030..5f27d7b8fddd 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/nv50.c
@@ -41,13 +41,6 @@ nv50_mc_intr[] = {
41 {}, 41 {},
42}; 42};
43 43
44static void
45nv50_mc_msi_rearm(struct nvkm_mc *mc)
46{
47 struct nvkm_device *device = mc->subdev.device;
48 pci_write_config_byte(device->pdev, 0x68, 0xff);
49}
50
51void 44void
52nv50_mc_init(struct nvkm_mc *mc) 45nv50_mc_init(struct nvkm_mc *mc)
53{ 46{
@@ -62,7 +55,6 @@ nv50_mc = {
62 .intr_unarm = nv04_mc_intr_unarm, 55 .intr_unarm = nv04_mc_intr_unarm,
63 .intr_rearm = nv04_mc_intr_rearm, 56 .intr_rearm = nv04_mc_intr_rearm,
64 .intr_mask = nv04_mc_intr_mask, 57 .intr_mask = nv04_mc_intr_mask,
65 .msi_rearm = nv50_mc_msi_rearm,
66}; 58};
67 59
68int 60int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h
index 5e10ea605422..307f6c692287 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/priv.h
@@ -20,7 +20,6 @@ struct nvkm_mc_func {
20 void (*intr_rearm)(struct nvkm_mc *); 20 void (*intr_rearm)(struct nvkm_mc *);
21 /* retrieve pending interrupt mask (NV_PMC_INTR) */ 21 /* retrieve pending interrupt mask (NV_PMC_INTR) */
22 u32 (*intr_mask)(struct nvkm_mc *); 22 u32 (*intr_mask)(struct nvkm_mc *);
23 void (*msi_rearm)(struct nvkm_mc *);
24 void (*unk260)(struct nvkm_mc *, u32); 23 void (*unk260)(struct nvkm_mc *, u32);
25}; 24};
26 25
@@ -30,8 +29,6 @@ void nv04_mc_intr_unarm(struct nvkm_mc *);
30void nv04_mc_intr_rearm(struct nvkm_mc *); 29void nv04_mc_intr_rearm(struct nvkm_mc *);
31u32 nv04_mc_intr_mask(struct nvkm_mc *); 30u32 nv04_mc_intr_mask(struct nvkm_mc *);
32 31
33void nv40_mc_msi_rearm(struct nvkm_mc *);
34
35void nv44_mc_init(struct nvkm_mc *); 32void nv44_mc_init(struct nvkm_mc *);
36 33
37void nv50_mc_init(struct nvkm_mc *); 34void nv50_mc_init(struct nvkm_mc *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
index 6a742659a901..e5e0d02f3d88 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
@@ -23,6 +23,10 @@
23 */ 23 */
24#include "priv.h" 24#include "priv.h"
25 25
26#include <core/option.h>
27#include <core/pci.h>
28#include <subdev/mc.h>
29
26u32 30u32
27nvkm_pci_rd32(struct nvkm_pci *pci, u16 addr) 31nvkm_pci_rd32(struct nvkm_pci *pci, u16 addr)
28{ 32{
@@ -52,21 +56,62 @@ nvkm_pci_rom_shadow(struct nvkm_pci *pci, bool shadow)
52 nvkm_pci_wr32(pci, 0x0050, data); 56 nvkm_pci_wr32(pci, 0x0050, data);
53} 57}
54 58
55void 59static irqreturn_t
56nvkm_pci_msi_rearm(struct nvkm_pci *pci) 60nvkm_pci_intr(int irq, void *arg)
61{
62 struct nvkm_pci *pci = arg;
63 struct nvkm_mc *mc = pci->subdev.device->mc;
64 bool handled = false;
65 if (likely(mc)) {
66 nvkm_mc_intr_unarm(mc);
67 if (pci->msi)
68 pci->func->msi_rearm(pci);
69 nvkm_mc_intr(mc, &handled);
70 nvkm_mc_intr_rearm(mc);
71 }
72 return handled ? IRQ_HANDLED : IRQ_NONE;
73}
74
75static int
76nvkm_pci_fini(struct nvkm_subdev *subdev, bool suspend)
57{ 77{
58 pci->func->msi_rearm(pci); 78 struct nvkm_pci *pci = nvkm_pci(subdev);
79 if (pci->irq >= 0) {
80 free_irq(pci->irq, pci);
81 pci->irq = -1;
82 };
83 return 0;
84}
85
86static int
87nvkm_pci_init(struct nvkm_subdev *subdev)
88{
89 struct nvkm_pci *pci = nvkm_pci(subdev);
90 struct pci_dev *pdev = pci->pdev;
91 int ret;
92
93 ret = request_irq(pdev->irq, nvkm_pci_intr, IRQF_SHARED, "nvkm", pci);
94 if (ret)
95 return ret;
96
97 pci->irq = pdev->irq;
98 return ret;
59} 99}
60 100
61static void * 101static void *
62nvkm_pci_dtor(struct nvkm_subdev *subdev) 102nvkm_pci_dtor(struct nvkm_subdev *subdev)
63{ 103{
104 struct nvkm_pci *pci = nvkm_pci(subdev);
105 if (pci->msi)
106 pci_disable_msi(pci->pdev);
64 return nvkm_pci(subdev); 107 return nvkm_pci(subdev);
65} 108}
66 109
67static const struct nvkm_subdev_func 110static const struct nvkm_subdev_func
68nvkm_pci_func = { 111nvkm_pci_func = {
69 .dtor = nvkm_pci_dtor, 112 .dtor = nvkm_pci_dtor,
113 .init = nvkm_pci_init,
114 .fini = nvkm_pci_fini,
70}; 115};
71 116
72int 117int
@@ -74,9 +119,38 @@ nvkm_pci_new_(const struct nvkm_pci_func *func, struct nvkm_device *device,
74 int index, struct nvkm_pci **ppci) 119 int index, struct nvkm_pci **ppci)
75{ 120{
76 struct nvkm_pci *pci; 121 struct nvkm_pci *pci;
122
77 if (!(pci = *ppci = kzalloc(sizeof(**ppci), GFP_KERNEL))) 123 if (!(pci = *ppci = kzalloc(sizeof(**ppci), GFP_KERNEL)))
78 return -ENOMEM; 124 return -ENOMEM;
79 nvkm_subdev_ctor(&nvkm_pci_func, device, index, 0, &pci->subdev); 125 nvkm_subdev_ctor(&nvkm_pci_func, device, index, 0, &pci->subdev);
80 pci->func = func; 126 pci->func = func;
127 pci->pdev = device->func->pci(device)->pdev;
128 pci->irq = -1;
129
130 switch (pci->pdev->device & 0x0ff0) {
131 case 0x00f0:
132 case 0x02e0:
133 /* BR02? NFI how these would be handled yet exactly */
134 break;
135 default:
136 switch (device->chipset) {
137 case 0xaa:
138 /* reported broken, nv also disable it */
139 break;
140 default:
141 pci->msi = true;
142 break;
143 }
144 }
145
146 pci->msi = nvkm_boolopt(device->cfgopt, "NvMSI", pci->msi);
147 if (pci->msi && func->msi_rearm) {
148 pci->msi = pci_enable_msi(pci->pdev) == 0;
149 if (pci->msi)
150 nvkm_debug(&pci->subdev, "MSI enabled\n");
151 } else {
152 pci->msi = false;
153 }
154
81 return 0; 155 return 0;
82} 156}