aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_irq.c35
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c9
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");
115int nouveau_perflvl_wr; 115int nouveau_perflvl_wr;
116module_param_named(perflvl_wr, nouveau_perflvl_wr, int, 0400); 116module_param_named(perflvl_wr, nouveau_perflvl_wr, int, 0400);
117 117
118MODULE_PARM_DESC(msi, "Enable MSI (default: off)\n");
119int nouveau_msi;
120module_param_named(msi, nouveau_msi, int, 0400);
121
118int nouveau_fbpercrtc; 122int nouveau_fbpercrtc;
119#if 0 123#if 0
120module_param_named(fbpercrtc, nouveau_fbpercrtc, int, 0400); 124module_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;
754extern int nouveau_override_conntype; 756extern int nouveau_override_conntype;
755extern char *nouveau_perflvl; 757extern char *nouveau_perflvl;
756extern int nouveau_perflvl_wr; 758extern int nouveau_perflvl_wr;
759extern int nouveau_msi;
757 760
758extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state); 761extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state);
759extern int nouveau_pci_resume(struct pci_dev *pdev); 762extern 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 */
878extern int nouveau_irq_init(struct drm_device *);
879extern void nouveau_irq_fini(struct drm_device *);
875extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS); 880extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS);
876extern void nouveau_irq_preinstall(struct drm_device *); 881extern void nouveau_irq_preinstall(struct drm_device *);
877extern int nouveau_irq_postinstall(struct drm_device *); 882extern 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)
68int 68int
69nouveau_irq_postinstall(struct drm_device *dev) 69nouveau_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
1277int
1278nouveau_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
1294void
1295nouveau_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)
701out_fence: 698out_fence:
702 nouveau_fence_fini(dev); 699 nouveau_fence_fini(dev);
703out_irq: 700out_irq:
704 drm_irq_uninstall(dev); 701 nouveau_irq_fini(dev);
705out_display: 702out_display:
706 engine->display.destroy(dev); 703 engine->display.destroy(dev);
707out_fifo: 704out_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);