OSDN Git Service

missing bits
[android-x86/external-libdrm.git] / shared-core / i915_irq.c
1 /* i915_irq.c -- IRQ support for the I915 -*- linux-c -*-
2  */
3 /*
4  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
5  * All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the
9  * "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sub license, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice (including the
16  * next paragraph) shall be included in all copies or substantial portions
17  * of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26  *
27  */
28
29 #include "drmP.h"
30 #include "drm.h"
31 #include "i915_drm.h"
32 #include "i915_drv.h"
33
34 #include "intel_drv.h"
35
36 #define USER_INT_FLAG (1<<1)
37 #define VSYNC_PIPEB_FLAG (1<<5)
38 #define VSYNC_PIPEA_FLAG (1<<7)
39 #define HOTPLUG_FLAG (1 << 17)
40
41 #define MAX_NOPID ((u32)~0)
42
43 /**
44  * i915_get_pipe - return the the pipe associated with a given plane
45  * @dev: DRM device
46  * @plane: plane to look for
47  *
48  * The Intel Mesa & 2D drivers call the vblank routines with a plane number
49  * rather than a pipe number, since they may not always be equal.  This routine
50  * maps the given @plane back to a pipe number.
51  */
52 static int
53 i915_get_pipe(struct drm_device *dev, int plane)
54 {
55         struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
56         u32 dspcntr;
57
58         dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR);
59
60         return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0;
61 }
62
63 /**
64  * i915_get_plane - return the the plane associated with a given pipe
65  * @dev: DRM device
66  * @pipe: pipe to look for
67  *
68  * The Intel Mesa & 2D drivers call the vblank routines with a plane number
69  * rather than a plane number, since they may not always be equal.  This routine
70  * maps the given @pipe back to a plane number.
71  */
72 static int
73 i915_get_plane(struct drm_device *dev, int pipe)
74 {
75         if (i915_get_pipe(dev, 0) == pipe)
76                 return 0;
77         return 1;
78 }
79
80 /**
81  * i915_pipe_enabled - check if a pipe is enabled
82  * @dev: DRM device
83  * @pipe: pipe to check
84  *
85  * Reading certain registers when the pipe is disabled can hang the chip.
86  * Use this routine to make sure the PLL is running and the pipe is active
87  * before reading such registers if unsure.
88  */
89 static int
90 i915_pipe_enabled(struct drm_device *dev, int pipe)
91 {
92         struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
93         unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF;
94
95         if (I915_READ(pipeconf) & PIPEACONF_ENABLE)
96                 return 1;
97
98         return 0;
99 }
100
101 /**
102  * Emit a synchronous flip.
103  *
104  * This function must be called with the drawable spinlock held.
105  */
106 static void
107 i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw,
108                          int plane)
109 {
110         struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
111         struct drm_i915_sarea *sarea_priv = master_priv->sarea_priv;
112         u16 x1, y1, x2, y2;
113         int pf_planes = 1 << plane;
114
115         DRM_SPINLOCK_ASSERT(&dev->drw_lock);
116
117         /* If the window is visible on the other plane, we have to flip on that
118          * plane as well.
119          */
120         if (plane == 1) {
121                 x1 = sarea_priv->planeA_x;
122                 y1 = sarea_priv->planeA_y;
123                 x2 = x1 + sarea_priv->planeA_w;
124                 y2 = y1 + sarea_priv->planeA_h;
125         } else {
126                 x1 = sarea_priv->planeB_x;
127                 y1 = sarea_priv->planeB_y;
128                 x2 = x1 + sarea_priv->planeB_w;
129                 y2 = y1 + sarea_priv->planeB_h;
130         }
131
132         if (x2 > 0 && y2 > 0) {
133                 int i, num_rects = drw->num_rects;
134                 struct drm_clip_rect *rect = drw->rects;
135
136                 for (i = 0; i < num_rects; i++)
137                         if (!(rect[i].x1 >= x2 || rect[i].y1 >= y2 ||
138                               rect[i].x2 <= x1 || rect[i].y2 <= y1)) {
139                                 pf_planes = 0x3;
140
141                                 break;
142                         }
143         }
144
145         i915_dispatch_flip(dev, pf_planes, 1);
146 }
147
148 /**
149  * Emit blits for scheduled buffer swaps.
150  *
151  * This function will be called with the HW lock held.
152  */
153 static void i915_vblank_tasklet(struct drm_device *dev)
154 {
155         struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
156         struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
157         struct list_head *list, *tmp, hits, *hit;
158         int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages;
159         unsigned counter[2];
160         struct drm_drawable_info *drw;
161         struct drm_i915_sarea *sarea_priv;
162         u32 cpp = dev_priv->cpp,  offsets[3];
163         u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
164                                 XY_SRC_COPY_BLT_WRITE_ALPHA |
165                                 XY_SRC_COPY_BLT_WRITE_RGB)
166                              : XY_SRC_COPY_BLT_CMD;
167         u32 pitchropcpp;
168         RING_LOCALS;
169
170         counter[0] = drm_vblank_count(dev, 0);
171         counter[1] = drm_vblank_count(dev, 1);
172
173         DRM_DEBUG("\n");
174
175         INIT_LIST_HEAD(&hits);
176
177         nhits = nrects = 0;
178
179         /* No irqsave/restore necessary.  This tasklet may be run in an
180          * interrupt context or normal context, but we don't have to worry
181          * about getting interrupted by something acquiring the lock, because
182          * we are the interrupt context thing that acquires the lock.
183          */
184         DRM_SPINLOCK(&dev_priv->swaps_lock);
185
186         /* Find buffer swaps scheduled for this vertical blank */
187         list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
188                 struct drm_i915_vbl_swap *vbl_swap =
189                         list_entry(list, struct drm_i915_vbl_swap, head);
190                 int pipe = i915_get_pipe(dev, vbl_swap->plane);
191
192                 if ((counter[pipe] - vbl_swap->sequence) > (1<<23))
193                         continue;
194
195                 master_priv = vbl_swap->minor->master->driver_priv;
196                 sarea_priv = master_priv->sarea_priv;
197                 
198                 pitchropcpp = (sarea_priv->pitch * cpp) | (0xcc << 16) |
199                         (cpp << 23) | (1 << 24);
200
201                 list_del(list);
202                 dev_priv->swaps_pending--;
203                 drm_vblank_put(dev, pipe);
204
205                 DRM_SPINUNLOCK(&dev_priv->swaps_lock);
206                 DRM_SPINLOCK(&dev->drw_lock);
207
208                 drw = drm_get_drawable_info(dev, vbl_swap->drw_id);
209
210                 if (!drw) {
211                         DRM_SPINUNLOCK(&dev->drw_lock);
212                         drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
213                         DRM_SPINLOCK(&dev_priv->swaps_lock);
214                         continue;
215                 }
216
217                 list_for_each(hit, &hits) {
218                         struct drm_i915_vbl_swap *swap_cmp =
219                                 list_entry(hit, struct drm_i915_vbl_swap, head);
220                         struct drm_drawable_info *drw_cmp =
221                                 drm_get_drawable_info(dev, swap_cmp->drw_id);
222
223                         if (drw_cmp &&
224                             drw_cmp->rects[0].y1 > drw->rects[0].y1) {
225                                 list_add_tail(list, hit);
226                                 break;
227                         }
228                 }
229
230                 DRM_SPINUNLOCK(&dev->drw_lock);
231
232                 /* List of hits was empty, or we reached the end of it */
233                 if (hit == &hits)
234                         list_add_tail(list, hits.prev);
235
236                 nhits++;
237
238                 DRM_SPINLOCK(&dev_priv->swaps_lock);
239         }
240
241         DRM_SPINUNLOCK(&dev_priv->swaps_lock);
242
243         if (nhits == 0) {
244                 return;
245         }
246
247         i915_kernel_lost_context(dev);
248
249         upper[0] = upper[1] = 0;
250         slice[0] = max(sarea_priv->planeA_h / nhits, 1);
251         slice[1] = max(sarea_priv->planeB_h / nhits, 1);
252         lower[0] = sarea_priv->planeA_y + slice[0];
253         lower[1] = sarea_priv->planeB_y + slice[0];
254
255         offsets[0] = sarea_priv->front_offset;
256         offsets[1] = sarea_priv->back_offset;
257         offsets[2] = sarea_priv->third_offset;
258         num_pages = sarea_priv->third_handle ? 3 : 2;
259
260         DRM_SPINLOCK(&dev->drw_lock);
261
262         /* Emit blits for buffer swaps, partitioning both outputs into as many
263          * slices as there are buffer swaps scheduled in order to avoid tearing
264          * (based on the assumption that a single buffer swap would always
265          * complete before scanout starts).
266          */
267         for (i = 0; i++ < nhits;
268              upper[0] = lower[0], lower[0] += slice[0],
269              upper[1] = lower[1], lower[1] += slice[1]) {
270                 int init_drawrect = 1;
271
272                 if (i == nhits)
273                         lower[0] = lower[1] = sarea_priv->height;
274
275                 list_for_each(hit, &hits) {
276                         struct drm_i915_vbl_swap *swap_hit =
277                                 list_entry(hit, struct drm_i915_vbl_swap, head);
278                         struct drm_clip_rect *rect;
279                         int num_rects, plane, front, back;
280                         unsigned short top, bottom;
281
282                         drw = drm_get_drawable_info(dev, swap_hit->drw_id);
283
284                         if (!drw)
285                                 continue;
286
287                         plane = swap_hit->plane;
288
289                         if (swap_hit->flip) {
290                                 i915_dispatch_vsync_flip(dev, drw, plane);
291                                 continue;
292                         }
293
294                         if (init_drawrect) {
295                                 BEGIN_LP_RING(6);
296
297                                 OUT_RING(GFX_OP_DRAWRECT_INFO);
298                                 OUT_RING(0);
299                                 OUT_RING(0);
300                                 OUT_RING(sarea_priv->width | sarea_priv->height << 16);
301                                 OUT_RING(sarea_priv->width | sarea_priv->height << 16);
302                                 OUT_RING(0);
303
304                                 ADVANCE_LP_RING();
305
306                                 sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT;
307
308                                 init_drawrect = 0;
309                         }
310
311                         rect = drw->rects;
312                         top = upper[plane];
313                         bottom = lower[plane];
314
315                         front = (master_priv->sarea_priv->pf_current_page >>
316                                  (2 * plane)) & 0x3;
317                         back = (front + 1) % num_pages;
318
319                         for (num_rects = drw->num_rects; num_rects--; rect++) {
320                                 int y1 = max(rect->y1, top);
321                                 int y2 = min(rect->y2, bottom);
322
323                                 if (y1 >= y2)
324                                         continue;
325
326                                 BEGIN_LP_RING(8);
327
328                                 OUT_RING(cmd);
329                                 OUT_RING(pitchropcpp);
330                                 OUT_RING((y1 << 16) | rect->x1);
331                                 OUT_RING((y2 << 16) | rect->x2);
332                                 OUT_RING(offsets[front]);
333                                 OUT_RING((y1 << 16) | rect->x1);
334                                 OUT_RING(pitchropcpp & 0xffff);
335                                 OUT_RING(offsets[back]);
336
337                                 ADVANCE_LP_RING();
338                         }
339                 }
340         }
341
342         DRM_SPINUNLOCK(&dev->drw_lock);
343
344         list_for_each_safe(hit, tmp, &hits) {
345                 struct drm_i915_vbl_swap *swap_hit =
346                         list_entry(hit, struct drm_i915_vbl_swap, head);
347
348                 list_del(hit);
349
350                 drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER);
351         }
352 }
353 #if 0
354 static int i915_in_vblank(struct drm_device *dev, int pipe)
355 {
356         struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
357         unsigned long pipedsl, vblank, vtotal;
358         unsigned long vbl_start, vbl_end, cur_line;
359
360         pipedsl = pipe ? PIPEBDSL : PIPEADSL;
361         vblank = pipe ? VBLANK_B : VBLANK_A;
362         vtotal = pipe ? VTOTAL_B : VTOTAL_A;
363
364         vbl_start = I915_READ(vblank) & VBLANK_START_MASK;
365         vbl_end = (I915_READ(vblank) >> VBLANK_END_SHIFT) & VBLANK_END_MASK;
366
367         cur_line = I915_READ(pipedsl);
368
369         if (cur_line >= vbl_start)
370                 return 1;
371
372         return 0;
373 }
374 #endif
375 u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
376 {
377         struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
378         unsigned long high_frame;
379         unsigned long low_frame;
380         u32 high1, high2, low, count;
381         int pipe;
382
383         pipe = i915_get_pipe(dev, plane);
384         high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
385         low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
386
387         if (!i915_pipe_enabled(dev, pipe)) {
388             printk(KERN_ERR "trying to get vblank count for disabled "
389                    "pipe %d\n", pipe);
390             return 0;
391         }
392
393         /*
394          * High & low register fields aren't synchronized, so make sure
395          * we get a low value that's stable across two reads of the high
396          * register.
397          */
398         do {
399                 high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
400                          PIPE_FRAME_HIGH_SHIFT);
401                 low =  ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
402                         PIPE_FRAME_LOW_SHIFT);
403                 high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
404                          PIPE_FRAME_HIGH_SHIFT);
405         } while (high1 != high2);
406
407         count = (high1 << 8) | low;
408
409         /*
410          * If we're in the middle of the vblank period, the
411          * above regs won't have been updated yet, so return
412          * an incremented count to stay accurate
413          */
414 #if 0
415         if (i915_in_vblank(dev, pipe))
416                 count++;
417 #endif
418         return count;
419 }
420
421 #define HOTPLUG_CMD_CRT 1
422 #define HOTPLUG_CMD_CRT_DIS 2
423 #define HOTPLUG_CMD_SDVOB 4
424 #define HOTPLUG_CMD_SDVOC 8
425
426 static struct drm_device *hotplug_dev;
427 static int hotplug_cmd = 0;
428 static spinlock_t hotplug_lock = SPIN_LOCK_UNLOCKED;
429
430 static void i915_hotplug_crt(struct drm_device *dev, bool connected)
431 {
432         struct drm_output *output;
433         struct intel_output *iout;
434
435         mutex_lock(&dev->mode_config.mutex);
436
437         /* find the crt output */
438         list_for_each_entry(output, &dev->mode_config.output_list, head) {
439                 iout = output->driver_private;
440                 if (iout->type == INTEL_OUTPUT_ANALOG)
441                         break;
442                 else
443                         iout = 0;
444         }
445
446         if (iout == 0)
447                 goto unlock;
448
449         drm_hotplug_stage_two(dev, output, connected);
450
451 unlock:
452         mutex_unlock(&dev->mode_config.mutex);
453 }
454
455 static void i915_hotplug_sdvo(struct drm_device *dev, int sdvoB)
456 {
457         struct drm_output *output = 0;
458         enum drm_output_status status;
459
460         mutex_lock(&dev->mode_config.mutex);
461
462         output = intel_sdvo_find(dev, sdvoB);
463
464         if (!output) {
465                 DRM_ERROR("could not find sdvo%s output\n", sdvoB ? "B" : "C");
466                 goto unlock;
467         }
468
469         status = output->funcs->detect(output);
470
471         if (status != output_status_connected)
472                 drm_hotplug_stage_two(dev, output, false);
473         else
474                 drm_hotplug_stage_two(dev, output, true);
475
476         /* wierd hw bug, sdvo stop sending interupts */
477         intel_sdvo_set_hotplug(output, 1);
478
479 unlock:
480         mutex_unlock(&dev->mode_config.mutex);
481 }
482 /*
483  * This code is called in a more safe envirmoent to handle the hotplugs.
484  * Add code here for hotplug love to userspace.
485  */
486 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
487 static void i915_hotplug_work_func(void *work)
488 #else
489 static void i915_hotplug_work_func(struct work_struct *work)
490 #endif
491 {
492         struct drm_device *dev = hotplug_dev;
493         int crt;
494         int crtDis;
495         int sdvoB;
496         int sdvoC;
497
498         spin_lock(&hotplug_lock);
499         crt = hotplug_cmd & HOTPLUG_CMD_CRT;
500         crtDis = hotplug_cmd & HOTPLUG_CMD_CRT_DIS;
501         sdvoB = hotplug_cmd & HOTPLUG_CMD_SDVOB;
502         sdvoC = hotplug_cmd & HOTPLUG_CMD_SDVOC;
503         hotplug_cmd = 0;
504         spin_unlock(&hotplug_lock);
505
506         if (crt)
507                 i915_hotplug_crt(dev, true);
508         if (crtDis)
509                 i915_hotplug_crt(dev, false);
510
511         if (sdvoB)
512                 i915_hotplug_sdvo(dev, 1);
513
514         if (sdvoC)
515                 i915_hotplug_sdvo(dev, 0);
516
517 }
518
519 static int i915_run_hotplug_tasklet(struct drm_device *dev, uint32_t stat)
520 {
521 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
522         static DECLARE_WORK(hotplug, i915_hotplug_work_func, NULL);
523 #else
524         static DECLARE_WORK(hotplug, i915_hotplug_work_func);
525 #endif
526         struct drm_i915_private *dev_priv = dev->dev_private;
527
528         hotplug_dev = dev;
529
530         if (stat & CRT_HOTPLUG_INT_STATUS) {
531                 DRM_DEBUG("CRT event\n");
532
533                 if (stat & CRT_HOTPLUG_MONITOR_MASK) {
534                         spin_lock(&hotplug_lock);
535                         hotplug_cmd |= HOTPLUG_CMD_CRT;
536                         spin_unlock(&hotplug_lock);
537                 } else {
538                         spin_lock(&hotplug_lock);
539                         hotplug_cmd |= HOTPLUG_CMD_CRT_DIS;
540                         spin_unlock(&hotplug_lock);
541                 }
542         }
543
544         if (stat & SDVOB_HOTPLUG_INT_STATUS) {
545                 DRM_DEBUG("sDVOB event\n");
546
547                 spin_lock(&hotplug_lock);
548                 hotplug_cmd |= HOTPLUG_CMD_SDVOB;
549                 spin_unlock(&hotplug_lock);
550         }
551
552         if (stat & SDVOC_HOTPLUG_INT_STATUS) {
553                 DRM_DEBUG("sDVOC event\n");
554
555                 spin_lock(&hotplug_lock);
556                 hotplug_cmd |= HOTPLUG_CMD_SDVOC;
557                 spin_unlock(&hotplug_lock);
558         }
559
560         queue_work(dev_priv->wq, &hotplug);
561
562         return 0;
563 }
564
565 irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
566 {
567         struct drm_device *dev = (struct drm_device *) arg;
568         struct drm_i915_master_private *master_priv;
569         struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
570         u32 temp = 0;
571         u32 temp2;
572         u32 pipea_stats, pipeb_stats;
573
574         pipea_stats = I915_READ(I915REG_PIPEASTAT);
575         pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
576
577         /* On i8xx hw the IIR and IER are 16bit on i9xx its 32bit */
578         if (IS_I9XX(dev))
579                 temp = I915_READ(I915REG_INT_IDENTITY_R);
580         else
581                 temp = I915_READ16(I915REG_INT_IDENTITY_R);
582
583         temp2 = temp;
584         temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG);
585
586 #if 0
587         /* ugly despamification of pipeb event irq */
588         if (temp & (0xFFFFFFF ^ ((1 << 5) | (1 << 7)))) {
589                 DRM_DEBUG("IIR %08x\n", temp2);
590                 DRM_DEBUG("MSK %08x\n", dev_priv->irq_enable_reg | USER_INT_FLAG);
591                 DRM_DEBUG("M&I %08x\n", temp);
592                 DRM_DEBUG("HOT %08x\n", I915_READ(PORT_HOTPLUG_STAT));
593         }
594 #else
595 #if 0
596         DRM_DEBUG("flag=%08x\n", temp);
597 #endif
598 #endif
599
600         if (temp == 0)
601                 return IRQ_NONE;
602
603         if (IS_I9XX(dev)) {
604                 I915_WRITE(I915REG_INT_IDENTITY_R, temp);
605                 (void) I915_READ(I915REG_INT_IDENTITY_R);
606         } else {
607                 I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
608                 (void) I915_READ16(I915REG_INT_IDENTITY_R);
609         }
610
611         /*
612          * Clear the PIPE(A|B)STAT regs before the IIR otherwise
613          * we may get extra interrupts.
614          */
615         if (temp & VSYNC_PIPEA_FLAG) {
616                 drm_handle_vblank(dev, i915_get_plane(dev, 0));
617                 I915_WRITE(I915REG_PIPEASTAT,
618                            pipea_stats | I915_VBLANK_INTERRUPT_ENABLE |
619                            I915_VBLANK_CLEAR);
620         }
621
622         if (temp & VSYNC_PIPEB_FLAG) {
623                 drm_handle_vblank(dev, i915_get_plane(dev, 1));
624                 I915_WRITE(I915REG_PIPEBSTAT,
625                            pipeb_stats | I915_VBLANK_INTERRUPT_ENABLE |
626                            I915_VBLANK_CLEAR);
627         }
628
629         I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
630         (void) I915_READ16(I915REG_INT_IDENTITY_R); /* Flush posted write */
631
632         DRM_READMEMORYBARRIER();
633
634         temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG | VSYNC_PIPEA_FLAG |
635                  VSYNC_PIPEB_FLAG);
636
637         if (dev->primary->master) {
638                 master_priv = dev->primary->master->driver_priv;
639                 master_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
640         }
641
642         if (temp & USER_INT_FLAG) {
643                 DRM_WAKEUP(&dev_priv->irq_queue);
644 #ifdef I915_HAVE_FENCE
645                 i915_fence_handler(dev);
646 #endif
647         }
648
649         if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
650                 if (dev_priv->swaps_pending > 0)
651                         drm_locked_tasklet(dev, i915_vblank_tasklet);
652         }
653
654         /* for now lest just ack it */
655         if (temp & (1 << 17)) {
656                 DRM_DEBUG("Hotplug event received\n");
657
658                 temp2 = I915_READ(PORT_HOTPLUG_STAT);
659
660                 i915_run_hotplug_tasklet(dev, temp2);
661
662                 I915_WRITE(PORT_HOTPLUG_STAT,temp2);
663         }
664
665         return IRQ_HANDLED;
666 }
667
668 int i915_emit_irq(struct drm_device *dev)
669 {
670         struct drm_i915_private *dev_priv = dev->dev_private;
671         RING_LOCALS;
672
673         i915_kernel_lost_context(dev);
674
675         DRM_DEBUG("\n");
676
677         i915_emit_breadcrumb(dev);
678
679         BEGIN_LP_RING(2);
680         OUT_RING(0);
681         OUT_RING(GFX_OP_USER_INTERRUPT);
682         ADVANCE_LP_RING();
683
684         return dev_priv->counter;
685 }
686
687 void i915_user_irq_on(struct drm_i915_private *dev_priv)
688 {
689         DRM_SPINLOCK(&dev_priv->user_irq_lock);
690         if (dev_priv->irq_enabled && (++dev_priv->user_irq_refcount == 1)){
691                 dev_priv->irq_enable_reg |= USER_INT_FLAG;
692                 I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
693         }
694         DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
695
696 }
697                 
698 void i915_user_irq_off(struct drm_i915_private *dev_priv)
699 {
700         DRM_SPINLOCK(&dev_priv->user_irq_lock);
701         if (dev_priv->irq_enabled && (--dev_priv->user_irq_refcount == 0)) {
702                 //              dev_priv->irq_enable_reg &= ~USER_INT_FLAG;
703                 //              I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
704         }
705         DRM_SPINUNLOCK(&dev_priv->user_irq_lock);
706 }
707
708
709 static int i915_wait_irq(struct drm_device * dev, int irq_nr)
710 {
711         struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
712         struct drm_i915_master_private *master_priv;
713         int ret = 0;
714
715         DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
716                   READ_BREADCRUMB(dev_priv));
717
718         if (READ_BREADCRUMB(dev_priv) >= irq_nr)
719                 return 0;
720
721         i915_user_irq_on(dev_priv);
722         DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
723                     READ_BREADCRUMB(dev_priv) >= irq_nr);
724         i915_user_irq_off(dev_priv);
725
726         if (ret == -EBUSY) {
727                 DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
728                           READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
729         }
730         
731         if (dev->primary->master) {
732                 master_priv = dev->primary->master->driver_priv;
733                 master_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
734         }
735
736         return ret;
737 }
738
739 /* Needs the lock as it touches the ring.
740  */
741 int i915_irq_emit(struct drm_device *dev, void *data,
742                          struct drm_file *file_priv)
743 {
744         struct drm_i915_private *dev_priv = dev->dev_private;
745         struct drm_i915_irq_emit *emit = data;
746         int result;
747
748         LOCK_TEST_WITH_RETURN(dev, file_priv);
749
750         if (!dev_priv) {
751                 DRM_ERROR("called with no initialization\n");
752                 return -EINVAL;
753         }
754
755         result = i915_emit_irq(dev);
756
757         if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) {
758                 DRM_ERROR("copy_to_user\n");
759                 return -EFAULT;
760         }
761
762         return 0;
763 }
764
765 /* Doesn't need the hardware lock.
766  */
767 int i915_irq_wait(struct drm_device *dev, void *data,
768                   struct drm_file *file_priv)
769 {
770         struct drm_i915_private *dev_priv = dev->dev_private;
771         struct drm_i915_irq_wait *irqwait = data;
772
773         if (!dev_priv) {
774                 DRM_ERROR("called with no initialization\n");
775                 return -EINVAL;
776         }
777
778         return i915_wait_irq(dev, irqwait->irq_seq);
779 }
780
781 int i915_enable_vblank(struct drm_device *dev, int plane)
782 {
783         struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
784         int pipe = i915_get_pipe(dev, plane);
785         
786         switch (pipe) {
787         case 0:
788                 dev_priv->irq_enable_reg |= VSYNC_PIPEA_FLAG;
789                 break;
790         case 1:
791                 dev_priv->irq_enable_reg |= VSYNC_PIPEB_FLAG;
792                 break;
793         default:
794                 DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
795                           pipe);
796                 break;
797         }
798
799         I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
800
801         return 0;
802 }
803
804 void i915_disable_vblank(struct drm_device *dev, int plane)
805 {
806         struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
807         int pipe = i915_get_pipe(dev, plane);
808
809         switch (pipe) {
810         case 0:
811                 dev_priv->irq_enable_reg &= ~VSYNC_PIPEA_FLAG;
812                 break;
813         case 1:
814                 dev_priv->irq_enable_reg &= ~VSYNC_PIPEB_FLAG;
815                 break;
816         default:
817                 DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
818                           pipe);
819                 break;
820         }
821
822         I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
823 }
824
825 void i915_enable_interrupt (struct drm_device *dev)
826 {
827         struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
828         struct drm_output *o;
829
830         dev_priv->irq_enable_reg |= USER_INT_FLAG;
831
832         if (IS_I9XX(dev) && dev->mode_config.num_output) {
833                 dev_priv->irq_enable_reg |= HOTPLUG_FLAG;
834
835                 /* Activate the CRT */
836                 I915_WRITE(PORT_HOTPLUG_EN, CRT_HOTPLUG_INT_EN);
837
838                 /* SDVOB */
839                 o = intel_sdvo_find(dev, 1);
840                 if (o && intel_sdvo_supports_hotplug(o)) {
841                         intel_sdvo_set_hotplug(o, 1);
842                         I915_WRITE(PORT_HOTPLUG_EN, SDVOB_HOTPLUG_INT_EN);
843                 }
844
845                 /* SDVOC */
846                 o = intel_sdvo_find(dev, 0);
847                 if (o && intel_sdvo_supports_hotplug(o)) {
848                         intel_sdvo_set_hotplug(o, 1);
849                         I915_WRITE(PORT_HOTPLUG_EN, SDVOC_HOTPLUG_INT_EN);
850                 }
851
852         }
853
854         if (IS_I9XX(dev)) {
855                 I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
856         } else {
857                 I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
858         }
859
860         DRM_DEBUG("HEN %08x\n",I915_READ(PORT_HOTPLUG_EN));
861         DRM_DEBUG("HST %08x\n",I915_READ(PORT_HOTPLUG_STAT));
862         DRM_DEBUG("IER %08x\n",I915_READ(I915REG_INT_ENABLE_R));
863         DRM_DEBUG("SDB %08x\n",I915_READ(SDVOB));
864
865         I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
866
867         dev_priv->irq_enabled = 1;
868 }
869
870 /* Set the vblank monitor pipe
871  */
872 int i915_vblank_pipe_set(struct drm_device *dev, void *data,
873                          struct drm_file *file_priv)
874 {
875         struct drm_i915_private *dev_priv = dev->dev_private;
876         struct drm_i915_vblank_pipe *pipe = data;
877
878         if (!dev_priv) {
879                 DRM_ERROR("called with no initialization\n");
880                 return -EINVAL;
881         }
882
883         if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
884                 DRM_ERROR("called with invalid pipe 0x%x\n", pipe->pipe);
885                 return -EINVAL;
886         }
887
888         dev_priv->vblank_pipe = pipe->pipe;
889
890         return 0;
891 }
892
893 int i915_vblank_pipe_get(struct drm_device *dev, void *data,
894                          struct drm_file *file_priv)
895 {
896         struct drm_i915_private *dev_priv = dev->dev_private;
897         struct drm_i915_vblank_pipe *pipe = data;
898         u16 flag;
899
900         if (!dev_priv) {
901                 DRM_ERROR("called with no initialization\n");
902                 return -EINVAL;
903         }
904
905         flag = I915_READ(I915REG_INT_ENABLE_R);
906         pipe->pipe = 0;
907         if (flag & VSYNC_PIPEA_FLAG)
908                 pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
909         if (flag & VSYNC_PIPEB_FLAG)
910                 pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
911
912         return 0;
913 }
914
915 /**
916  * Schedule buffer swap at given vertical blank.
917  */
918 int i915_vblank_swap(struct drm_device *dev, void *data,
919                      struct drm_file *file_priv)
920 {
921         struct drm_i915_private *dev_priv = dev->dev_private;
922         struct drm_i915_master_private *master_priv;
923         struct drm_i915_vblank_swap *swap = data;
924         struct drm_i915_vbl_swap *vbl_swap;
925         unsigned int pipe, seqtype, curseq, plane;
926         unsigned long irqflags;
927         struct list_head *list;
928         int ret;
929
930         if (!dev_priv) {
931                 DRM_ERROR("%s called with no initialization\n", __func__);
932                 return -EINVAL;
933         }
934
935         if (!dev->primary->master)
936                 return -EINVAL;
937
938         master_priv = dev->primary->master->driver_priv;
939
940         if (master_priv->sarea_priv->rotation) {
941                 DRM_DEBUG("Rotation not supported\n");
942                 return -EINVAL;
943         }
944
945         if (swap->seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE |
946                              _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS |
947                              _DRM_VBLANK_FLIP)) {
948                 DRM_ERROR("Invalid sequence type 0x%x\n", swap->seqtype);
949                 return -EINVAL;
950         }
951
952         plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
953         pipe = i915_get_pipe(dev, plane);
954
955         seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);
956
957         if (!(dev_priv->vblank_pipe & (1 << pipe))) {
958                 DRM_ERROR("Invalid pipe %d\n", pipe);
959                 return -EINVAL;
960         }
961
962         DRM_SPINLOCK_IRQSAVE(&dev->drw_lock, irqflags);
963
964         /* It makes no sense to schedule a swap for a drawable that doesn't have
965          * valid information at this point. E.g. this could mean that the X
966          * server is too old to push drawable information to the DRM, in which
967          * case all such swaps would become ineffective.
968          */
969         if (!drm_get_drawable_info(dev, swap->drawable)) {
970                 DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags);
971                 DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable);
972                 return -EINVAL;
973         }
974
975         DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags);
976
977         drm_update_vblank_count(dev, pipe);
978         curseq = drm_vblank_count(dev, pipe);
979
980         if (seqtype == _DRM_VBLANK_RELATIVE)
981                 swap->sequence += curseq;
982
983         if ((curseq - swap->sequence) <= (1<<23)) {
984                 if (swap->seqtype & _DRM_VBLANK_NEXTONMISS) {
985                         swap->sequence = curseq + 1;
986                 } else {
987                         DRM_DEBUG("Missed target sequence\n");
988                         return -EINVAL;
989                 }
990         }
991
992         if (swap->seqtype & _DRM_VBLANK_FLIP) {
993                 swap->sequence--;
994
995                 if ((curseq - swap->sequence) <= (1<<23)) {
996                         struct drm_drawable_info *drw;
997
998                         LOCK_TEST_WITH_RETURN(dev, file_priv);
999
1000                         DRM_SPINLOCK_IRQSAVE(&dev->drw_lock, irqflags);
1001
1002                         drw = drm_get_drawable_info(dev, swap->drawable);
1003
1004                         if (!drw) {
1005                                 DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock,
1006                                     irqflags);
1007                                 DRM_DEBUG("Invalid drawable ID %d\n",
1008                                           swap->drawable);
1009                                 return -EINVAL;
1010                         }
1011
1012                         i915_dispatch_vsync_flip(dev, drw, plane);
1013
1014                         DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags);
1015
1016                         return 0;
1017                 }
1018         }
1019
1020         DRM_SPINLOCK_IRQSAVE(&dev_priv->swaps_lock, irqflags);
1021
1022         list_for_each(list, &dev_priv->vbl_swaps.head) {
1023                 vbl_swap = list_entry(list, struct drm_i915_vbl_swap, head);
1024
1025                 if (vbl_swap->drw_id == swap->drawable &&
1026                     vbl_swap->plane == plane &&
1027                     vbl_swap->sequence == swap->sequence) {
1028                         vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP);
1029                         DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->swaps_lock, irqflags);
1030                         DRM_DEBUG("Already scheduled\n");
1031                         return 0;
1032                 }
1033         }
1034
1035         DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->swaps_lock, irqflags);
1036
1037         if (dev_priv->swaps_pending >= 100) {
1038                 DRM_DEBUG("Too many swaps queued\n");
1039                 return -EBUSY;
1040         }
1041
1042         vbl_swap = drm_calloc(1, sizeof(*vbl_swap), DRM_MEM_DRIVER);
1043
1044         if (!vbl_swap) {
1045                 DRM_ERROR("Failed to allocate memory to queue swap\n");
1046                 return -ENOMEM;
1047         }
1048
1049         DRM_DEBUG("\n");
1050
1051         ret = drm_vblank_get(dev, pipe);
1052         if (ret) {
1053                 drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
1054                 return ret;
1055         }
1056
1057         vbl_swap->drw_id = swap->drawable;
1058         vbl_swap->plane = plane;
1059         vbl_swap->sequence = swap->sequence;
1060         vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP);
1061         vbl_swap->minor = file_priv->minor;
1062
1063         if (vbl_swap->flip)
1064                 swap->sequence++;
1065
1066         DRM_SPINLOCK_IRQSAVE(&dev_priv->swaps_lock, irqflags);
1067
1068         list_add_tail(&vbl_swap->head, &dev_priv->vbl_swaps.head);
1069         dev_priv->swaps_pending++;
1070
1071         DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->swaps_lock, irqflags);
1072
1073         return 0;
1074 }
1075
1076 /* drm_dma.h hooks
1077 */
1078 void i915_driver_irq_preinstall(struct drm_device * dev)
1079 {
1080         struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
1081
1082         I915_WRITE16(I915REG_HWSTAM, 0xeffe);
1083         if (IS_I9XX(dev)) {
1084                 I915_WRITE(I915REG_INT_MASK_R, 0x0);
1085                 I915_WRITE(I915REG_INT_ENABLE_R, 0x0);
1086         } else {
1087                 I915_WRITE16(I915REG_INT_MASK_R, 0x0);
1088                 I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
1089         }
1090
1091 }
1092
1093 int i915_driver_irq_postinstall(struct drm_device * dev)
1094 {
1095         struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
1096         int ret, num_pipes = 2;
1097
1098         DRM_SPININIT(&dev_priv->swaps_lock, "swap");
1099         INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
1100         dev_priv->swaps_pending = 0;
1101
1102         DRM_SPININIT(&dev_priv->user_irq_lock, "userirq");
1103         dev_priv->user_irq_refcount = 0;
1104         dev_priv->irq_enable_reg = 0;
1105
1106         ret = drm_vblank_init(dev, num_pipes);
1107         if (ret)
1108                 return ret;
1109
1110         dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
1111
1112         i915_enable_interrupt(dev);
1113         DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
1114
1115         /*
1116          * Initialize the hardware status page IRQ location.
1117          */
1118
1119         I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21));
1120         return 0;
1121 }
1122
1123 void i915_driver_irq_uninstall(struct drm_device * dev)
1124 {
1125         struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
1126         u32 temp;
1127
1128         if (!dev_priv)
1129                 return;
1130
1131         dev_priv->irq_enabled = 0;
1132
1133
1134         if(IS_I9XX(dev)) {
1135                 I915_WRITE(I915REG_HWSTAM, 0xffffffff);
1136                 I915_WRITE(I915REG_INT_MASK_R, 0xffffffff);
1137                 I915_WRITE(I915REG_INT_ENABLE_R, 0x0);
1138
1139                 temp = I915_READ(I915REG_INT_IDENTITY_R);
1140                 I915_WRITE(I915REG_INT_IDENTITY_R, temp);
1141         } else {
1142                 I915_WRITE16(I915REG_HWSTAM, 0xffff);
1143                 I915_WRITE16(I915REG_INT_MASK_R, 0xffff);
1144                 I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
1145
1146                 temp = I915_READ16(I915REG_INT_IDENTITY_R);
1147                 I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
1148         }
1149 }