From 6effec7e3521992f6889ab285db543943fbe8cd4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 8 Jul 2011 13:17:01 +1000 Subject: [PATCH] --- yaml --- r: 269647 b: refs/heads/master c: f20ce9629f820c00e581acc4c9938fbf6e34475d h: refs/heads/master i: 269645: be1441e9b55f508d7e5d0ca85ada4faded7bbe85 269643: ffb00b6de1239bef34b6b7e23402c44d6fc587e6 269639: 2b1b354d09c56718475a131feeea704e2fe67210 269631: 46338ca2154ea388e64b473864ea6cb5be06b208 v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/nouveau/nvd0_display.c | 29 +++++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/[refs] b/[refs] index 414fe1694816..25042d8c2a84 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3b6d83d1b9f9be1c9778c2c6fa6761b440734fdd +refs/heads/master: f20ce9629f820c00e581acc4c9938fbf6e34475d diff --git a/trunk/drivers/gpu/drm/nouveau/nvd0_display.c b/trunk/drivers/gpu/drm/nouveau/nvd0_display.c index 1a561d308215..b6a8c6def64c 100644 --- a/trunk/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/trunk/drivers/gpu/drm/nouveau/nvd0_display.c @@ -44,9 +44,12 @@ struct nvd0_display { dma_addr_t handle; u32 *ptr; } evo[1]; + + struct tasklet_struct tasklet; struct { struct dcb_entry *dis; struct dcb_entry *ena; + u32 modeset; int crtc; int pclk; u16 cfg; @@ -1114,9 +1117,24 @@ nvd0_display_unk4_handler(struct drm_device *dev) nv_wr32(dev, 0x6101d0, 0x80000000); } +static void +nvd0_display_bh(unsigned long data) +{ + struct drm_device *dev = (struct drm_device *)data; + struct nvd0_display *disp = nvd0_display(dev); + + if (disp->irq.modeset & 0x00000001) + nvd0_display_unk1_handler(dev); + if (disp->irq.modeset & 0x00000002) + nvd0_display_unk2_handler(dev); + if (disp->irq.modeset & 0x00000004) + nvd0_display_unk4_handler(dev); +} + static void nvd0_display_intr(struct drm_device *dev) { + struct nvd0_display *disp = nvd0_display(dev); u32 intr = nv_rd32(dev, 0x610088); if (intr & 0x00000002) { @@ -1141,14 +1159,10 @@ nvd0_display_intr(struct drm_device *dev) u32 stat = nv_rd32(dev, 0x6100ac); if (stat & 0x00000007) { - nv_wr32(dev, 0x6100ac, (stat & 0x00000007)); + disp->irq.modeset = stat; + tasklet_schedule(&disp->tasklet); - if (stat & 0x00000001) - nvd0_display_unk1_handler(dev); - if (stat & 0x00000002) - nvd0_display_unk2_handler(dev); - if (stat & 0x00000004) - nvd0_display_unk4_handler(dev); + nv_wr32(dev, 0x6100ac, (stat & 0x00000007)); stat &= ~0x00000007; } @@ -1371,6 +1385,7 @@ nvd0_display_create(struct drm_device *dev) } /* setup interrupt handling */ + tasklet_init(&disp->tasklet, nvd0_display_bh, (unsigned long)dev); nouveau_irq_register(dev, 26, nvd0_display_intr); /* hash table and dma objects for the memory areas we care about */