diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-07-07 23:17:01 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-09-20 02:07:42 -0400 |
commit | f20ce9629f820c00e581acc4c9938fbf6e34475d (patch) | |
tree | 27809bdb64b0d6fa49f3f6a6ec3dbd1598be595c /drivers/gpu/drm/nouveau/nvd0_display.c | |
parent | 3b6d83d1b9f9be1c9778c2c6fa6761b440734fdd (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.c | 29 |
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 | ||
1117 | static void | 1120 | static void |
1121 | nvd0_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 | |||
1134 | static void | ||
1118 | nvd0_display_intr(struct drm_device *dev) | 1135 | nvd0_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 */ |