|
|
|
@ -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) { |
|
|
|
|