diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-10-20 00:23:29 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-12-03 00:10:58 -0500 |
commit | 97e2000f757c19bb53e032320669f9a0d0b2a989 (patch) | |
tree | d732c6f3ef4fdd403862f132456d71a0d44e55e3 | |
parent | 43ce028ff2b1df68c690f0af14a109288d3e9e86 (diff) |
drm/nv50: improve evo error handler when more than just channel 0 active
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_reg.h | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_graph.c | 11 |
3 files changed, 39 insertions, 33 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index d0ce86c24ebf..b6384d36d5d0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h | |||
@@ -715,20 +715,21 @@ | |||
715 | #define NV50_PDISPLAY_INTR_1_CLK_UNK10 0x00000010 | 715 | #define NV50_PDISPLAY_INTR_1_CLK_UNK10 0x00000010 |
716 | #define NV50_PDISPLAY_INTR_1_CLK_UNK20 0x00000020 | 716 | #define NV50_PDISPLAY_INTR_1_CLK_UNK20 0x00000020 |
717 | #define NV50_PDISPLAY_INTR_1_CLK_UNK40 0x00000040 | 717 | #define NV50_PDISPLAY_INTR_1_CLK_UNK40 0x00000040 |
718 | #define NV50_PDISPLAY_INTR_EN 0x0061002c | 718 | #define NV50_PDISPLAY_INTR_EN_0 0x00610028 |
719 | #define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC 0x0000000c | 719 | #define NV50_PDISPLAY_INTR_EN_1 0x0061002c |
720 | #define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(n) (1 << ((n) + 2)) | 720 | #define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC 0x0000000c |
721 | #define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_0 0x00000004 | 721 | #define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(n) (1 << ((n) + 2)) |
722 | #define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_1 0x00000008 | 722 | #define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_0 0x00000004 |
723 | #define NV50_PDISPLAY_INTR_EN_CLK_UNK10 0x00000010 | 723 | #define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_1 0x00000008 |
724 | #define NV50_PDISPLAY_INTR_EN_CLK_UNK20 0x00000020 | 724 | #define NV50_PDISPLAY_INTR_EN_1_CLK_UNK10 0x00000010 |
725 | #define NV50_PDISPLAY_INTR_EN_CLK_UNK40 0x00000040 | 725 | #define NV50_PDISPLAY_INTR_EN_1_CLK_UNK20 0x00000020 |
726 | #define NV50_PDISPLAY_INTR_EN_1_CLK_UNK40 0x00000040 | ||
726 | #define NV50_PDISPLAY_UNK30_CTRL 0x00610030 | 727 | #define NV50_PDISPLAY_UNK30_CTRL 0x00610030 |
727 | #define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK0 0x00000200 | 728 | #define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK0 0x00000200 |
728 | #define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK1 0x00000400 | 729 | #define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK1 0x00000400 |
729 | #define NV50_PDISPLAY_UNK30_CTRL_PENDING 0x80000000 | 730 | #define NV50_PDISPLAY_UNK30_CTRL_PENDING 0x80000000 |
730 | #define NV50_PDISPLAY_TRAPPED_ADDR 0x00610080 | 731 | #define NV50_PDISPLAY_TRAPPED_ADDR(i) ((i) * 0x08 + 0x00610080) |
731 | #define NV50_PDISPLAY_TRAPPED_DATA 0x00610084 | 732 | #define NV50_PDISPLAY_TRAPPED_DATA(i) ((i) * 0x08 + 0x00610084) |
732 | #define NV50_PDISPLAY_EVO_CTRL(i) ((i) * 0x10 + 0x00610200) | 733 | #define NV50_PDISPLAY_EVO_CTRL(i) ((i) * 0x10 + 0x00610200) |
733 | #define NV50_PDISPLAY_EVO_CTRL_DMA 0x00000010 | 734 | #define NV50_PDISPLAY_EVO_CTRL_DMA 0x00000010 |
734 | #define NV50_PDISPLAY_EVO_CTRL_DMA_DISABLED 0x00000000 | 735 | #define NV50_PDISPLAY_EVO_CTRL_DMA_DISABLED 0x00000000 |
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) | |||
779 | static void | 778 | static void |
780 | nv50_display_error_handler(struct drm_device *dev) | 779 | nv50_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 | ||
794 | void | 800 | void |
@@ -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) { |
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index a764af52a3ba..d441308a09cf 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c | |||
@@ -384,13 +384,12 @@ nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, | |||
384 | if (!chan->nvsw.vblsem || chan->nvsw.vblsem_offset == ~0 || data > 1) | 384 | if (!chan->nvsw.vblsem || chan->nvsw.vblsem_offset == ~0 || data > 1) |
385 | return -EINVAL; | 385 | return -EINVAL; |
386 | 386 | ||
387 | if (!(nv_rd32(dev, NV50_PDISPLAY_INTR_EN) & | 387 | if (!(nv_rd32(dev, NV50_PDISPLAY_INTR_EN_1) & |
388 | NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(data))) { | 388 | NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(data))) { |
389 | nv_wr32(dev, NV50_PDISPLAY_INTR_1, | 389 | nv_wr32(dev, NV50_PDISPLAY_INTR_1, |
390 | NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(data)); | 390 | NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(data)); |
391 | nv_wr32(dev, NV50_PDISPLAY_INTR_EN, nv_rd32(dev, | 391 | nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, 0, |
392 | NV50_PDISPLAY_INTR_EN) | | 392 | NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(data)); |
393 | NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(data)); | ||
394 | } | 393 | } |
395 | 394 | ||
396 | list_add(&chan->nvsw.vbl_wait, &dev_priv->vbl_waiting); | 395 | list_add(&chan->nvsw.vbl_wait, &dev_priv->vbl_waiting); |