Commit 97e2000f authored by Ben Skeggs's avatar Ben Skeggs

drm/nv50: improve evo error handler when more than just channel 0 active

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 43ce028f
...@@ -715,20 +715,21 @@ ...@@ -715,20 +715,21 @@
#define NV50_PDISPLAY_INTR_1_CLK_UNK10 0x00000010 #define NV50_PDISPLAY_INTR_1_CLK_UNK10 0x00000010
#define NV50_PDISPLAY_INTR_1_CLK_UNK20 0x00000020 #define NV50_PDISPLAY_INTR_1_CLK_UNK20 0x00000020
#define NV50_PDISPLAY_INTR_1_CLK_UNK40 0x00000040 #define NV50_PDISPLAY_INTR_1_CLK_UNK40 0x00000040
#define NV50_PDISPLAY_INTR_EN 0x0061002c #define NV50_PDISPLAY_INTR_EN_0 0x00610028
#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC 0x0000000c #define NV50_PDISPLAY_INTR_EN_1 0x0061002c
#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(n) (1 << ((n) + 2)) #define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC 0x0000000c
#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_0 0x00000004 #define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(n) (1 << ((n) + 2))
#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_1 0x00000008 #define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_0 0x00000004
#define NV50_PDISPLAY_INTR_EN_CLK_UNK10 0x00000010 #define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_1 0x00000008
#define NV50_PDISPLAY_INTR_EN_CLK_UNK20 0x00000020 #define NV50_PDISPLAY_INTR_EN_1_CLK_UNK10 0x00000010
#define NV50_PDISPLAY_INTR_EN_CLK_UNK40 0x00000040 #define NV50_PDISPLAY_INTR_EN_1_CLK_UNK20 0x00000020
#define NV50_PDISPLAY_INTR_EN_1_CLK_UNK40 0x00000040
#define NV50_PDISPLAY_UNK30_CTRL 0x00610030 #define NV50_PDISPLAY_UNK30_CTRL 0x00610030
#define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK0 0x00000200 #define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK0 0x00000200
#define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK1 0x00000400 #define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK1 0x00000400
#define NV50_PDISPLAY_UNK30_CTRL_PENDING 0x80000000 #define NV50_PDISPLAY_UNK30_CTRL_PENDING 0x80000000
#define NV50_PDISPLAY_TRAPPED_ADDR 0x00610080 #define NV50_PDISPLAY_TRAPPED_ADDR(i) ((i) * 0x08 + 0x00610080)
#define NV50_PDISPLAY_TRAPPED_DATA 0x00610084 #define NV50_PDISPLAY_TRAPPED_DATA(i) ((i) * 0x08 + 0x00610084)
#define NV50_PDISPLAY_EVO_CTRL(i) ((i) * 0x10 + 0x00610200) #define NV50_PDISPLAY_EVO_CTRL(i) ((i) * 0x10 + 0x00610200)
#define NV50_PDISPLAY_EVO_CTRL_DMA 0x00000010 #define NV50_PDISPLAY_EVO_CTRL_DMA 0x00000010
#define NV50_PDISPLAY_EVO_CTRL_DMA_DISABLED 0x00000000 #define NV50_PDISPLAY_EVO_CTRL_DMA_DISABLED 0x00000000
......
...@@ -149,13 +149,13 @@ nv50_display_init(struct drm_device *dev) ...@@ -149,13 +149,13 @@ nv50_display_init(struct drm_device *dev)
} }
nv_wr32(dev, NV50_PDISPLAY_PIO_CTRL, 0x00000000); nv_wr32(dev, NV50_PDISPLAY_PIO_CTRL, 0x00000000);
nv_wr32(dev, 0x610028, 0x00000000);
nv_mask(dev, NV50_PDISPLAY_INTR_0, 0x00000000, 0x00000000); nv_mask(dev, NV50_PDISPLAY_INTR_0, 0x00000000, 0x00000000);
nv_wr32(dev, NV50_PDISPLAY_INTR_EN_0, 0x00000000);
nv_mask(dev, NV50_PDISPLAY_INTR_1, 0x00000000, 0x00000000); nv_mask(dev, NV50_PDISPLAY_INTR_1, 0x00000000, 0x00000000);
nv_wr32(dev, NV50_PDISPLAY_INTR_EN, nv_wr32(dev, NV50_PDISPLAY_INTR_EN_1,
NV50_PDISPLAY_INTR_EN_CLK_UNK10 | NV50_PDISPLAY_INTR_EN_1_CLK_UNK10 |
NV50_PDISPLAY_INTR_EN_CLK_UNK20 | NV50_PDISPLAY_INTR_EN_1_CLK_UNK20 |
NV50_PDISPLAY_INTR_EN_CLK_UNK40); NV50_PDISPLAY_INTR_EN_1_CLK_UNK40);
/* enable hotplug interrupts */ /* enable hotplug interrupts */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 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,7 +248,7 @@ static int nv50_display_disable(struct drm_device *dev)
} }
/* disable interrupts. */ /* disable interrupts. */
nv_wr32(dev, NV50_PDISPLAY_INTR_EN, 0x00000000); nv_wr32(dev, NV50_PDISPLAY_INTR_EN_1, 0x00000000);
/* disable hotplug interrupts */ /* disable hotplug interrupts */
nv_wr32(dev, 0xe054, 0xffffffff); nv_wr32(dev, 0xe054, 0xffffffff);
...@@ -451,8 +451,7 @@ nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr) ...@@ -451,8 +451,7 @@ nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr)
if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1) if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1)
nv50_display_vblank_crtc_handler(dev, 1); nv50_display_vblank_crtc_handler(dev, 1);
nv_wr32(dev, NV50_PDISPLAY_INTR_EN, nv_rd32(dev, nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, intr, 0x00000000);
NV50_PDISPLAY_INTR_EN) & ~intr);
nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr); nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr);
} }
...@@ -779,16 +778,23 @@ nv50_display_irq_handler_bh(struct work_struct *work) ...@@ -779,16 +778,23 @@ nv50_display_irq_handler_bh(struct work_struct *work)
static void static void
nv50_display_error_handler(struct drm_device *dev) nv50_display_error_handler(struct drm_device *dev)
{ {
uint32_t addr, data; u32 channels = (nv_rd32(dev, NV50_PDISPLAY_INTR_0) & 0x001f0000) >> 16;
u32 addr, data;
int chid;
nv_wr32(dev, NV50_PDISPLAY_INTR_0, 0x00010000); for (chid = 0; chid < 5; chid++) {
addr = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_ADDR); if (!(channels & (1 << chid)))
data = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_DATA); continue;
NV_ERROR(dev, "EvoCh %d Mthd 0x%04x Data 0x%08x (0x%04x 0x%02x)\n", nv_wr32(dev, NV50_PDISPLAY_INTR_0, 0x00010000 << chid);
0, addr & 0xffc, data, addr >> 16, (addr >> 12) & 0xf); addr = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_ADDR(chid));
data = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_DATA(chid));
NV_ERROR(dev, "EvoCh %d Mthd 0x%04x Data 0x%08x "
"(0x%04x 0x%02x)\n", chid,
addr & 0xffc, data, addr >> 16, (addr >> 12) & 0xf);
nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR, 0x90000000); nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR(chid), 0x90000000);
}
} }
void void
...@@ -891,9 +897,9 @@ nv50_display_irq_handler(struct drm_device *dev) ...@@ -891,9 +897,9 @@ nv50_display_irq_handler(struct drm_device *dev)
if (!intr0 && !(intr1 & ~delayed)) if (!intr0 && !(intr1 & ~delayed))
break; break;
if (intr0 & 0x00010000) { if (intr0 & 0x001f0000) {
nv50_display_error_handler(dev); nv50_display_error_handler(dev);
intr0 &= ~0x00010000; intr0 &= ~0x001f0000;
} }
if (intr1 & NV50_PDISPLAY_INTR_1_VBLANK_CRTC) { if (intr1 & NV50_PDISPLAY_INTR_1_VBLANK_CRTC) {
......
...@@ -384,13 +384,12 @@ nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, ...@@ -384,13 +384,12 @@ nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan,
if (!chan->nvsw.vblsem || chan->nvsw.vblsem_offset == ~0 || data > 1) if (!chan->nvsw.vblsem || chan->nvsw.vblsem_offset == ~0 || data > 1)
return -EINVAL; return -EINVAL;
if (!(nv_rd32(dev, NV50_PDISPLAY_INTR_EN) & if (!(nv_rd32(dev, NV50_PDISPLAY_INTR_EN_1) &
NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(data))) { NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(data))) {
nv_wr32(dev, NV50_PDISPLAY_INTR_1, nv_wr32(dev, NV50_PDISPLAY_INTR_1,
NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(data)); NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(data));
nv_wr32(dev, NV50_PDISPLAY_INTR_EN, nv_rd32(dev, nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, 0,
NV50_PDISPLAY_INTR_EN) | NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(data));
NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(data));
} }
list_add(&chan->nvsw.vbl_wait, &dev_priv->vbl_waiting); list_add(&chan->nvsw.vbl_wait, &dev_priv->vbl_waiting);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment