aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nvd0_display.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-07-07 23:17:01 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-09-20 02:07:42 -0400
commitf20ce9629f820c00e581acc4c9938fbf6e34475d (patch)
tree27809bdb64b0d6fa49f3f6a6ec3dbd1598be595c /drivers/gpu/drm/nouveau/nvd0_display.c
parent3b6d83d1b9f9be1c9778c2c6fa6761b440734fdd (diff)
drm/nvd0/disp: do modeset irq handling from tasklet
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvd0_display.c')
-rw-r--r--drivers/gpu/drm/nouveau/nvd0_display.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c
index 1a561d308215..b6a8c6def64c 100644
--- a/drivers/gpu/drm/nouveau/nvd0_display.c
+++ b/drivers/gpu/drm/nouveau/nvd0_display.c
@@ -44,9 +44,12 @@ struct nvd0_display {
44 dma_addr_t handle; 44 dma_addr_t handle;
45 u32 *ptr; 45 u32 *ptr;
46 } evo[1]; 46 } evo[1];
47
48 struct tasklet_struct tasklet;
47 struct { 49 struct {
48 struct dcb_entry *dis; 50 struct dcb_entry *dis;
49 struct dcb_entry *ena; 51 struct dcb_entry *ena;
52 u32 modeset;
50 int crtc; 53 int crtc;
51 int pclk; 54 int pclk;
52 u16 cfg; 55 u16 cfg;
@@ -1115,8 +1118,23 @@ ack:
1115} 1118}
1116 1119
1117static void 1120static void
1121nvd0_display_bh(unsigned long data)
1122{
1123 struct drm_device *dev = (struct drm_device *)data;
1124 struct nvd0_display *disp = nvd0_display(dev);
1125
1126 if (disp->irq.modeset & 0x00000001)
1127 nvd0_display_unk1_handler(dev);
1128 if (disp->irq.modeset & 0x00000002)
1129 nvd0_display_unk2_handler(dev);
1130 if (disp->irq.modeset & 0x00000004)
1131 nvd0_display_unk4_handler(dev);
1132}
1133
1134static void
1118nvd0_display_intr(struct drm_device *dev) 1135nvd0_display_intr(struct drm_device *dev)
1119{ 1136{
1137 struct nvd0_display *disp = nvd0_display(dev);
1120 u32 intr = nv_rd32(dev, 0x610088); 1138 u32 intr = nv_rd32(dev, 0x610088);
1121 1139
1122 if (intr & 0x00000002) { 1140 if (intr & 0x00000002) {
@@ -1141,14 +1159,10 @@ nvd0_display_intr(struct drm_device *dev)
1141 u32 stat = nv_rd32(dev, 0x6100ac); 1159 u32 stat = nv_rd32(dev, 0x6100ac);
1142 1160
1143 if (stat & 0x00000007) { 1161 if (stat & 0x00000007) {
1144 nv_wr32(dev, 0x6100ac, (stat & 0x00000007)); 1162 disp->irq.modeset = stat;
1163 tasklet_schedule(&disp->tasklet);
1145 1164
1146 if (stat & 0x00000001) 1165 nv_wr32(dev, 0x6100ac, (stat & 0x00000007));
1147 nvd0_display_unk1_handler(dev);
1148 if (stat & 0x00000002)
1149 nvd0_display_unk2_handler(dev);
1150 if (stat & 0x00000004)
1151 nvd0_display_unk4_handler(dev);
1152 stat &= ~0x00000007; 1166 stat &= ~0x00000007;
1153 } 1167 }
1154 1168
@@ -1371,6 +1385,7 @@ nvd0_display_create(struct drm_device *dev)
1371 } 1385 }
1372 1386
1373 /* setup interrupt handling */ 1387 /* setup interrupt handling */
1388 tasklet_init(&disp->tasklet, nvd0_display_bh, (unsigned long)dev);
1374 nouveau_irq_register(dev, 26, nvd0_display_intr); 1389 nouveau_irq_register(dev, 26, nvd0_display_intr);
1375 1390
1376 /* hash table and dma objects for the memory areas we care about */ 1391 /* hash table and dma objects for the memory areas we care about */