mirror of https://gitee.com/openkylin/linux.git
drm/nv50: improve evo error handler when more than just channel 0 active
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
43ce028ff2
commit
97e2000f75
|
@ -715,20 +715,21 @@
|
|||
#define NV50_PDISPLAY_INTR_1_CLK_UNK10 0x00000010
|
||||
#define NV50_PDISPLAY_INTR_1_CLK_UNK20 0x00000020
|
||||
#define NV50_PDISPLAY_INTR_1_CLK_UNK40 0x00000040
|
||||
#define NV50_PDISPLAY_INTR_EN 0x0061002c
|
||||
#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC 0x0000000c
|
||||
#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(n) (1 << ((n) + 2))
|
||||
#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_0 0x00000004
|
||||
#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_1 0x00000008
|
||||
#define NV50_PDISPLAY_INTR_EN_CLK_UNK10 0x00000010
|
||||
#define NV50_PDISPLAY_INTR_EN_CLK_UNK20 0x00000020
|
||||
#define NV50_PDISPLAY_INTR_EN_CLK_UNK40 0x00000040
|
||||
#define NV50_PDISPLAY_INTR_EN_0 0x00610028
|
||||
#define NV50_PDISPLAY_INTR_EN_1 0x0061002c
|
||||
#define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC 0x0000000c
|
||||
#define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(n) (1 << ((n) + 2))
|
||||
#define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_0 0x00000004
|
||||
#define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_1 0x00000008
|
||||
#define NV50_PDISPLAY_INTR_EN_1_CLK_UNK10 0x00000010
|
||||
#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_UPDATE_VCLK0 0x00000200
|
||||
#define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK1 0x00000400
|
||||
#define NV50_PDISPLAY_UNK30_CTRL_PENDING 0x80000000
|
||||
#define NV50_PDISPLAY_TRAPPED_ADDR 0x00610080
|
||||
#define NV50_PDISPLAY_TRAPPED_DATA 0x00610084
|
||||
#define NV50_PDISPLAY_TRAPPED_ADDR(i) ((i) * 0x08 + 0x00610080)
|
||||
#define NV50_PDISPLAY_TRAPPED_DATA(i) ((i) * 0x08 + 0x00610084)
|
||||
#define NV50_PDISPLAY_EVO_CTRL(i) ((i) * 0x10 + 0x00610200)
|
||||
#define NV50_PDISPLAY_EVO_CTRL_DMA 0x00000010
|
||||
#define NV50_PDISPLAY_EVO_CTRL_DMA_DISABLED 0x00000000
|
||||
|
|
|
@ -149,13 +149,13 @@ nv50_display_init(struct drm_device *dev)
|
|||
}
|
||||
|
||||
nv_wr32(dev, NV50_PDISPLAY_PIO_CTRL, 0x00000000);
|
||||
nv_wr32(dev, 0x610028, 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_wr32(dev, NV50_PDISPLAY_INTR_EN,
|
||||
NV50_PDISPLAY_INTR_EN_CLK_UNK10 |
|
||||
NV50_PDISPLAY_INTR_EN_CLK_UNK20 |
|
||||
NV50_PDISPLAY_INTR_EN_CLK_UNK40);
|
||||
nv_wr32(dev, NV50_PDISPLAY_INTR_EN_1,
|
||||
NV50_PDISPLAY_INTR_EN_1_CLK_UNK10 |
|
||||
NV50_PDISPLAY_INTR_EN_1_CLK_UNK20 |
|
||||
NV50_PDISPLAY_INTR_EN_1_CLK_UNK40);
|
||||
|
||||
/* enable hotplug interrupts */
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
|
@ -248,7 +248,7 @@ static int nv50_display_disable(struct drm_device *dev)
|
|||
}
|
||||
|
||||
/* disable interrupts. */
|
||||
nv_wr32(dev, NV50_PDISPLAY_INTR_EN, 0x00000000);
|
||||
nv_wr32(dev, NV50_PDISPLAY_INTR_EN_1, 0x00000000);
|
||||
|
||||
/* disable hotplug interrupts */
|
||||
nv_wr32(dev, 0xe054, 0xffffffff);
|
||||
|
@ -451,8 +451,7 @@ nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr)
|
|||
if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1)
|
||||
nv50_display_vblank_crtc_handler(dev, 1);
|
||||
|
||||
nv_wr32(dev, NV50_PDISPLAY_INTR_EN, nv_rd32(dev,
|
||||
NV50_PDISPLAY_INTR_EN) & ~intr);
|
||||
nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, intr, 0x00000000);
|
||||
nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr);
|
||||
}
|
||||
|
||||
|
@ -779,16 +778,23 @@ nv50_display_irq_handler_bh(struct work_struct *work)
|
|||
static void
|
||||
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);
|
||||
addr = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_ADDR);
|
||||
data = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_DATA);
|
||||
for (chid = 0; chid < 5; chid++) {
|
||||
if (!(channels & (1 << chid)))
|
||||
continue;
|
||||
|
||||
NV_ERROR(dev, "EvoCh %d Mthd 0x%04x Data 0x%08x (0x%04x 0x%02x)\n",
|
||||
0, addr & 0xffc, data, addr >> 16, (addr >> 12) & 0xf);
|
||||
nv_wr32(dev, NV50_PDISPLAY_INTR_0, 0x00010000 << chid);
|
||||
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
|
||||
|
@ -891,9 +897,9 @@ nv50_display_irq_handler(struct drm_device *dev)
|
|||
if (!intr0 && !(intr1 & ~delayed))
|
||||
break;
|
||||
|
||||
if (intr0 & 0x00010000) {
|
||||
if (intr0 & 0x001f0000) {
|
||||
nv50_display_error_handler(dev);
|
||||
intr0 &= ~0x00010000;
|
||||
intr0 &= ~0x001f0000;
|
||||
}
|
||||
|
||||
if (intr1 & NV50_PDISPLAY_INTR_1_VBLANK_CRTC) {
|
||||
|
|
|
@ -384,13 +384,12 @@ nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan,
|
|||
if (!chan->nvsw.vblsem || chan->nvsw.vblsem_offset == ~0 || data > 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (!(nv_rd32(dev, NV50_PDISPLAY_INTR_EN) &
|
||||
NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(data))) {
|
||||
if (!(nv_rd32(dev, NV50_PDISPLAY_INTR_EN_1) &
|
||||
NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(data))) {
|
||||
nv_wr32(dev, NV50_PDISPLAY_INTR_1,
|
||||
NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(data));
|
||||
nv_wr32(dev, NV50_PDISPLAY_INTR_EN, nv_rd32(dev,
|
||||
NV50_PDISPLAY_INTR_EN) |
|
||||
NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(data));
|
||||
NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(data));
|
||||
nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, 0,
|
||||
NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(data));
|
||||
}
|
||||
|
||||
list_add(&chan->nvsw.vbl_wait, &dev_priv->vbl_waiting);
|
||||
|
|
Loading…
Reference in New Issue