diff options
author | Jeremy Erickson <jerickso@cs.unc.edu> | 2014-04-11 13:24:45 -0400 |
---|---|---|
committer | Jeremy Erickson <jerickso@cs.unc.edu> | 2014-04-11 13:24:45 -0400 |
commit | 438145c7ef5c9445f25bb8fc4d52e2c9d11fdc7c (patch) | |
tree | 76941991e36f4a32bf1be0db3854959053f24619 /drivers/gpu/drm/nouveau | |
parent | 9ddd1b8ad8abd321964b8add5581910de6d67c2a (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.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_irq.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 35 |
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) { |