aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorJeremy Erickson <jerickso@cs.unc.edu>2014-04-11 13:24:45 -0400
committerJeremy Erickson <jerickso@cs.unc.edu>2014-04-11 13:24:45 -0400
commit438145c7ef5c9445f25bb8fc4d52e2c9d11fdc7c (patch)
tree76941991e36f4a32bf1be0db3854959053f24619 /drivers/gpu/drm/nouveau
parent9ddd1b8ad8abd321964b8add5581910de6d67c2a (diff)
Update from 2.6.36 to 2.6.36.4wip-dissipation-jerickso
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_irq.c1
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c35
3 files changed, 33 insertions, 9 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index b1be617373b6..c926d8891a46 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -531,6 +531,12 @@ struct drm_nouveau_private {
531 struct work_struct irq_work; 531 struct work_struct irq_work;
532 struct work_struct hpd_work; 532 struct work_struct hpd_work;
533 533
534 struct {
535 spinlock_t lock;
536 uint32_t hpd0_bits;
537 uint32_t hpd1_bits;
538 } hpd_state;
539
534 struct list_head vbl_waiting; 540 struct list_head vbl_waiting;
535 541
536 struct { 542 struct {
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c
index 794b0ee30cf6..b62a601737a4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_irq.c
+++ b/drivers/gpu/drm/nouveau/nouveau_irq.c
@@ -52,6 +52,7 @@ nouveau_irq_preinstall(struct drm_device *dev)
52 if (dev_priv->card_type >= NV_50) { 52 if (dev_priv->card_type >= NV_50) {
53 INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh); 53 INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh);
54 INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh); 54 INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh);
55 spin_lock_init(&dev_priv->hpd_state.lock);
55 INIT_LIST_HEAD(&dev_priv->vbl_waiting); 56 INIT_LIST_HEAD(&dev_priv->vbl_waiting);
56 } 57 }
57} 58}
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 612fa6d6a0cb..d967cb65d641 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -1012,11 +1012,18 @@ nv50_display_irq_hotplug_bh(struct work_struct *work)
1012 struct drm_connector *connector; 1012 struct drm_connector *connector;
1013 const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; 1013 const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
1014 uint32_t unplug_mask, plug_mask, change_mask; 1014 uint32_t unplug_mask, plug_mask, change_mask;
1015 uint32_t hpd0, hpd1 = 0; 1015 uint32_t hpd0, hpd1;
1016 1016
1017 hpd0 = nv_rd32(dev, 0xe054) & nv_rd32(dev, 0xe050); 1017 spin_lock_irq(&dev_priv->hpd_state.lock);
1018 hpd0 = dev_priv->hpd_state.hpd0_bits;
1019 dev_priv->hpd_state.hpd0_bits = 0;
1020 hpd1 = dev_priv->hpd_state.hpd1_bits;
1021 dev_priv->hpd_state.hpd1_bits = 0;
1022 spin_unlock_irq(&dev_priv->hpd_state.lock);
1023
1024 hpd0 &= nv_rd32(dev, 0xe050);
1018 if (dev_priv->chipset >= 0x90) 1025 if (dev_priv->chipset >= 0x90)
1019 hpd1 = nv_rd32(dev, 0xe074) & nv_rd32(dev, 0xe070); 1026 hpd1 &= nv_rd32(dev, 0xe070);
1020 1027
1021 plug_mask = (hpd0 & 0x0000ffff) | (hpd1 << 16); 1028 plug_mask = (hpd0 & 0x0000ffff) | (hpd1 << 16);
1022 unplug_mask = (hpd0 >> 16) | (hpd1 & 0xffff0000); 1029 unplug_mask = (hpd0 >> 16) | (hpd1 & 0xffff0000);
@@ -1058,10 +1065,6 @@ nv50_display_irq_hotplug_bh(struct work_struct *work)
1058 helper->dpms(connector->encoder, DRM_MODE_DPMS_OFF); 1065 helper->dpms(connector->encoder, DRM_MODE_DPMS_OFF);
1059 } 1066 }
1060 1067
1061 nv_wr32(dev, 0xe054, nv_rd32(dev, 0xe054));
1062 if (dev_priv->chipset >= 0x90)
1063 nv_wr32(dev, 0xe074, nv_rd32(dev, 0xe074));
1064
1065 drm_helper_hpd_irq_event(dev); 1068 drm_helper_hpd_irq_event(dev);
1066} 1069}
1067 1070
@@ -1072,8 +1075,22 @@ nv50_display_irq_handler(struct drm_device *dev)
1072 uint32_t delayed = 0; 1075 uint32_t delayed = 0;
1073 1076
1074 if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) { 1077 if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) {
1075 if (!work_pending(&dev_priv->hpd_work)) 1078 uint32_t hpd0_bits, hpd1_bits = 0;
1076 queue_work(dev_priv->wq, &dev_priv->hpd_work); 1079
1080 hpd0_bits = nv_rd32(dev, 0xe054);
1081 nv_wr32(dev, 0xe054, hpd0_bits);
1082
1083 if (dev_priv->chipset >= 0x90) {
1084 hpd1_bits = nv_rd32(dev, 0xe074);
1085 nv_wr32(dev, 0xe074, hpd1_bits);
1086 }
1087
1088 spin_lock(&dev_priv->hpd_state.lock);
1089 dev_priv->hpd_state.hpd0_bits |= hpd0_bits;
1090 dev_priv->hpd_state.hpd1_bits |= hpd1_bits;
1091 spin_unlock(&dev_priv->hpd_state.lock);
1092
1093 queue_work(dev_priv->wq, &dev_priv->hpd_work);
1077 } 1094 }
1078 1095
1079 while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) { 1096 while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) {