aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv50_display.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-10-20 00:23:29 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-12-03 00:10:58 -0500
commit97e2000f757c19bb53e032320669f9a0d0b2a989 (patch)
treed732c6f3ef4fdd403862f132456d71a0d44e55e3 /drivers/gpu/drm/nouveau/nv50_display.c
parent43ce028ff2b1df68c690f0af14a109288d3e9e86 (diff)
drm/nv50: improve evo error handler when more than just channel 0 active
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_display.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index db100a8f231e..99871e304d10 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -149,13 +149,13 @@ nv50_display_init(struct drm_device *dev)
149 } 149 }
150 150
151 nv_wr32(dev, NV50_PDISPLAY_PIO_CTRL, 0x00000000); 151 nv_wr32(dev, NV50_PDISPLAY_PIO_CTRL, 0x00000000);
152 nv_wr32(dev, 0x610028, 0x00000000);
153 nv_mask(dev, NV50_PDISPLAY_INTR_0, 0x00000000, 0x00000000); 152 nv_mask(dev, NV50_PDISPLAY_INTR_0, 0x00000000, 0x00000000);
153 nv_wr32(dev, NV50_PDISPLAY_INTR_EN_0, 0x00000000);
154 nv_mask(dev, NV50_PDISPLAY_INTR_1, 0x00000000, 0x00000000); 154 nv_mask(dev, NV50_PDISPLAY_INTR_1, 0x00000000, 0x00000000);
155 nv_wr32(dev, NV50_PDISPLAY_INTR_EN, 155 nv_wr32(dev, NV50_PDISPLAY_INTR_EN_1,
156 NV50_PDISPLAY_INTR_EN_CLK_UNK10 | 156 NV50_PDISPLAY_INTR_EN_1_CLK_UNK10 |
157 NV50_PDISPLAY_INTR_EN_CLK_UNK20 | 157 NV50_PDISPLAY_INTR_EN_1_CLK_UNK20 |
158 NV50_PDISPLAY_INTR_EN_CLK_UNK40); 158 NV50_PDISPLAY_INTR_EN_1_CLK_UNK40);
159 159
160 /* enable hotplug interrupts */ 160 /* enable hotplug interrupts */
161 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 161 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
@@ -248,7 +248,7 @@ static int nv50_display_disable(struct drm_device *dev)
248 } 248 }
249 249
250 /* disable interrupts. */ 250 /* disable interrupts. */
251 nv_wr32(dev, NV50_PDISPLAY_INTR_EN, 0x00000000); 251 nv_wr32(dev, NV50_PDISPLAY_INTR_EN_1, 0x00000000);
252 252
253 /* disable hotplug interrupts */ 253 /* disable hotplug interrupts */
254 nv_wr32(dev, 0xe054, 0xffffffff); 254 nv_wr32(dev, 0xe054, 0xffffffff);
@@ -451,8 +451,7 @@ nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr)
451 if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1) 451 if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1)
452 nv50_display_vblank_crtc_handler(dev, 1); 452 nv50_display_vblank_crtc_handler(dev, 1);
453 453
454 nv_wr32(dev, NV50_PDISPLAY_INTR_EN, nv_rd32(dev, 454 nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, intr, 0x00000000);
455 NV50_PDISPLAY_INTR_EN) & ~intr);
456 nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr); 455 nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr);
457} 456}
458 457
@@ -779,16 +778,23 @@ nv50_display_irq_handler_bh(struct work_struct *work)
779static void 778static void
780nv50_display_error_handler(struct drm_device *dev) 779nv50_display_error_handler(struct drm_device *dev)
781{ 780{
782 uint32_t addr, data; 781 u32 channels = (nv_rd32(dev, NV50_PDISPLAY_INTR_0) & 0x001f0000) >> 16;
782 u32 addr, data;
783 int chid;
783 784
784 nv_wr32(dev, NV50_PDISPLAY_INTR_0, 0x00010000); 785 for (chid = 0; chid < 5; chid++) {
785 addr = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_ADDR); 786 if (!(channels & (1 << chid)))
786 data = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_DATA); 787 continue;
787 788
788 NV_ERROR(dev, "EvoCh %d Mthd 0x%04x Data 0x%08x (0x%04x 0x%02x)\n", 789 nv_wr32(dev, NV50_PDISPLAY_INTR_0, 0x00010000 << chid);
789 0, addr & 0xffc, data, addr >> 16, (addr >> 12) & 0xf); 790 addr = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_ADDR(chid));
791 data = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_DATA(chid));
792 NV_ERROR(dev, "EvoCh %d Mthd 0x%04x Data 0x%08x "
793 "(0x%04x 0x%02x)\n", chid,
794 addr & 0xffc, data, addr >> 16, (addr >> 12) & 0xf);
790 795
791 nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR, 0x90000000); 796 nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR(chid), 0x90000000);
797 }
792} 798}
793 799
794void 800void
@@ -891,9 +897,9 @@ nv50_display_irq_handler(struct drm_device *dev)
891 if (!intr0 && !(intr1 & ~delayed)) 897 if (!intr0 && !(intr1 & ~delayed))
892 break; 898 break;
893 899
894 if (intr0 & 0x00010000) { 900 if (intr0 & 0x001f0000) {
895 nv50_display_error_handler(dev); 901 nv50_display_error_handler(dev);
896 intr0 &= ~0x00010000; 902 intr0 &= ~0x001f0000;
897 } 903 }
898 904
899 if (intr1 & NV50_PDISPLAY_INTR_1_VBLANK_CRTC) { 905 if (intr1 & NV50_PDISPLAY_INTR_1_VBLANK_CRTC) {