diff options
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_irq.c | 35 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 9 |
4 files changed, 47 insertions, 6 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 6dbb8818c530..db926ecf5b6f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c | |||
@@ -115,6 +115,10 @@ MODULE_PARM_DESC(perflvl_wr, "Allow perflvl changes (warning: dangerous!)\n"); | |||
115 | int nouveau_perflvl_wr; | 115 | int nouveau_perflvl_wr; |
116 | module_param_named(perflvl_wr, nouveau_perflvl_wr, int, 0400); | 116 | module_param_named(perflvl_wr, nouveau_perflvl_wr, int, 0400); |
117 | 117 | ||
118 | MODULE_PARM_DESC(msi, "Enable MSI (default: off)\n"); | ||
119 | int nouveau_msi; | ||
120 | module_param_named(msi, nouveau_msi, int, 0400); | ||
121 | |||
118 | int nouveau_fbpercrtc; | 122 | int nouveau_fbpercrtc; |
119 | #if 0 | 123 | #if 0 |
120 | module_param_named(fbpercrtc, nouveau_fbpercrtc, int, 0400); | 124 | module_param_named(fbpercrtc, nouveau_fbpercrtc, int, 0400); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index bf34f25c7a54..9ab7dc8ede4e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -593,6 +593,8 @@ struct drm_nouveau_private { | |||
593 | 593 | ||
594 | struct nouveau_bo *vga_ram; | 594 | struct nouveau_bo *vga_ram; |
595 | 595 | ||
596 | /* interrupt handling */ | ||
597 | bool msi_enabled; | ||
596 | struct workqueue_struct *wq; | 598 | struct workqueue_struct *wq; |
597 | struct work_struct irq_work; | 599 | struct work_struct irq_work; |
598 | struct work_struct hpd_work; | 600 | struct work_struct hpd_work; |
@@ -754,6 +756,7 @@ extern int nouveau_force_post; | |||
754 | extern int nouveau_override_conntype; | 756 | extern int nouveau_override_conntype; |
755 | extern char *nouveau_perflvl; | 757 | extern char *nouveau_perflvl; |
756 | extern int nouveau_perflvl_wr; | 758 | extern int nouveau_perflvl_wr; |
759 | extern int nouveau_msi; | ||
757 | 760 | ||
758 | extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state); | 761 | extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state); |
759 | extern int nouveau_pci_resume(struct pci_dev *pdev); | 762 | extern int nouveau_pci_resume(struct pci_dev *pdev); |
@@ -872,6 +875,8 @@ extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, | |||
872 | struct drm_file *); | 875 | struct drm_file *); |
873 | 876 | ||
874 | /* nouveau_irq.c */ | 877 | /* nouveau_irq.c */ |
878 | extern int nouveau_irq_init(struct drm_device *); | ||
879 | extern void nouveau_irq_fini(struct drm_device *); | ||
875 | extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS); | 880 | extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS); |
876 | extern void nouveau_irq_preinstall(struct drm_device *); | 881 | extern void nouveau_irq_preinstall(struct drm_device *); |
877 | extern int nouveau_irq_postinstall(struct drm_device *); | 882 | extern int nouveau_irq_postinstall(struct drm_device *); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index ca9b969f4f9c..17e2fa86cde7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c | |||
@@ -68,8 +68,13 @@ nouveau_irq_preinstall(struct drm_device *dev) | |||
68 | int | 68 | int |
69 | nouveau_irq_postinstall(struct drm_device *dev) | 69 | nouveau_irq_postinstall(struct drm_device *dev) |
70 | { | 70 | { |
71 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
72 | |||
71 | /* Master enable */ | 73 | /* Master enable */ |
72 | nv_wr32(dev, NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE); | 74 | nv_wr32(dev, NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE); |
75 | if (dev_priv->msi_enabled) | ||
76 | nv_wr08(dev, 0x00088068, 0xff); | ||
77 | |||
73 | return 0; | 78 | return 0; |
74 | } | 79 | } |
75 | 80 | ||
@@ -1263,5 +1268,35 @@ nouveau_irq_handler(DRM_IRQ_ARGS) | |||
1263 | 1268 | ||
1264 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | 1269 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); |
1265 | 1270 | ||
1271 | if (dev_priv->msi_enabled) | ||
1272 | nv_wr08(dev, 0x00088068, 0xff); | ||
1273 | |||
1266 | return IRQ_HANDLED; | 1274 | return IRQ_HANDLED; |
1267 | } | 1275 | } |
1276 | |||
1277 | int | ||
1278 | nouveau_irq_init(struct drm_device *dev) | ||
1279 | { | ||
1280 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
1281 | int ret; | ||
1282 | |||
1283 | if (nouveau_msi != 0 && dev_priv->card_type >= NV_50) { | ||
1284 | ret = pci_enable_msi(dev->pdev); | ||
1285 | if (ret == 0) { | ||
1286 | NV_INFO(dev, "enabled MSI\n"); | ||
1287 | dev_priv->msi_enabled = true; | ||
1288 | } | ||
1289 | } | ||
1290 | |||
1291 | return drm_irq_install(dev); | ||
1292 | } | ||
1293 | |||
1294 | void | ||
1295 | nouveau_irq_fini(struct drm_device *dev) | ||
1296 | { | ||
1297 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
1298 | |||
1299 | drm_irq_uninstall(dev); | ||
1300 | if (dev_priv->msi_enabled) | ||
1301 | pci_disable_msi(dev->pdev); | ||
1302 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index f13134aa8c4f..410a79f5e0cd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -667,10 +667,7 @@ nouveau_card_init(struct drm_device *dev) | |||
667 | if (ret) | 667 | if (ret) |
668 | goto out_fifo; | 668 | goto out_fifo; |
669 | 669 | ||
670 | /* this call irq_preinstall, register irq handler and | 670 | ret = nouveau_irq_init(dev); |
671 | * call irq_postinstall | ||
672 | */ | ||
673 | ret = drm_irq_install(dev); | ||
674 | if (ret) | 671 | if (ret) |
675 | goto out_display; | 672 | goto out_display; |
676 | 673 | ||
@@ -701,7 +698,7 @@ nouveau_card_init(struct drm_device *dev) | |||
701 | out_fence: | 698 | out_fence: |
702 | nouveau_fence_fini(dev); | 699 | nouveau_fence_fini(dev); |
703 | out_irq: | 700 | out_irq: |
704 | drm_irq_uninstall(dev); | 701 | nouveau_irq_fini(dev); |
705 | out_display: | 702 | out_display: |
706 | engine->display.destroy(dev); | 703 | engine->display.destroy(dev); |
707 | out_fifo: | 704 | out_fifo: |
@@ -772,7 +769,7 @@ static void nouveau_card_takedown(struct drm_device *dev) | |||
772 | nouveau_gpuobj_takedown(dev); | 769 | nouveau_gpuobj_takedown(dev); |
773 | nouveau_mem_vram_fini(dev); | 770 | nouveau_mem_vram_fini(dev); |
774 | 771 | ||
775 | drm_irq_uninstall(dev); | 772 | nouveau_irq_fini(dev); |
776 | 773 | ||
777 | nouveau_pm_fini(dev); | 774 | nouveau_pm_fini(dev); |
778 | nouveau_bios_takedown(dev); | 775 | nouveau_bios_takedown(dev); |