Merge branch 'crestline-qa', adding support for the 965GM chipset.
[profile/ivi/libdrm.git] / shared-core / i915_dma.c
1 /* i915_dma.c -- DMA 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 #define IS_I965G(dev)  (dev->pci_device == 0x2972 || \
35                         dev->pci_device == 0x2982 || \
36                         dev->pci_device == 0x2992 || \
37                         dev->pci_device == 0x29A2 || \
38                         dev->pci_device == 0x2A02)
39
40
41 /* Really want an OS-independent resettable timer.  Would like to have
42  * this loop run for (eg) 3 sec, but have the timer reset every time
43  * the head pointer changes, so that EBUSY only happens if the ring
44  * actually stalls for (eg) 3 seconds.
45  */
46 int i915_wait_ring(drm_device_t * dev, int n, const char *caller)
47 {
48         drm_i915_private_t *dev_priv = dev->dev_private;
49         drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
50         u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
51         int i;
52
53         for (i = 0; i < 10000; i++) {
54                 ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
55                 ring->space = ring->head - (ring->tail + 8);
56                 if (ring->space < 0)
57                         ring->space += ring->Size;
58                 if (ring->space >= n)
59                         return 0;
60
61                 dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
62
63                 if (ring->head != last_head)
64                         i = 0;
65
66                 last_head = ring->head;
67                 DRM_UDELAY(1);
68         }
69
70         return DRM_ERR(EBUSY);
71 }
72
73 void i915_kernel_lost_context(drm_device_t * dev)
74 {
75         drm_i915_private_t *dev_priv = dev->dev_private;
76         drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
77
78         ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
79         ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
80         ring->space = ring->head - (ring->tail + 8);
81         if (ring->space < 0)
82                 ring->space += ring->Size;
83
84         if (ring->head == ring->tail)
85                 dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
86 }
87
88 static int i915_dma_cleanup(drm_device_t * dev)
89 {
90         /* Make sure interrupts are disabled here because the uninstall ioctl
91          * may not have been called from userspace and after dev_private
92          * is freed, it's too late.
93          */
94         if (dev->irq)
95                 drm_irq_uninstall(dev);
96
97         if (dev->dev_private) {
98                 drm_i915_private_t *dev_priv =
99                     (drm_i915_private_t *) dev->dev_private;
100
101                 if (dev_priv->ring.virtual_start) {
102                         drm_core_ioremapfree(&dev_priv->ring.map, dev);
103                 }
104
105                 if (dev_priv->status_page_dmah) {
106                         drm_pci_free(dev, dev_priv->status_page_dmah);
107                         /* Need to rewrite hardware status page */
108                         I915_WRITE(0x02080, 0x1ffff000);
109                 }
110
111                 drm_free(dev->dev_private, sizeof(drm_i915_private_t),
112                          DRM_MEM_DRIVER);
113
114                 dev->dev_private = NULL;
115         }
116
117         return 0;
118 }
119
120 static int i915_initialize(drm_device_t * dev,
121                            drm_i915_private_t * dev_priv,
122                            drm_i915_init_t * init)
123 {
124         memset(dev_priv, 0, sizeof(drm_i915_private_t));
125
126         DRM_GETSAREA();
127         if (!dev_priv->sarea) {
128                 DRM_ERROR("can not find sarea!\n");
129                 dev->dev_private = (void *)dev_priv;
130                 i915_dma_cleanup(dev);
131                 return DRM_ERR(EINVAL);
132         }
133
134         dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
135         if (!dev_priv->mmio_map) {
136                 dev->dev_private = (void *)dev_priv;
137                 i915_dma_cleanup(dev);
138                 DRM_ERROR("can not find mmio map!\n");
139                 return DRM_ERR(EINVAL);
140         }
141
142         dev_priv->sarea_priv = (drm_i915_sarea_t *)
143             ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
144
145         dev_priv->ring.Start = init->ring_start;
146         dev_priv->ring.End = init->ring_end;
147         dev_priv->ring.Size = init->ring_size;
148         dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
149
150         dev_priv->ring.map.offset = init->ring_start;
151         dev_priv->ring.map.size = init->ring_size;
152         dev_priv->ring.map.type = 0;
153         dev_priv->ring.map.flags = 0;
154         dev_priv->ring.map.mtrr = 0;
155
156         drm_core_ioremap(&dev_priv->ring.map, dev);
157
158         if (dev_priv->ring.map.handle == NULL) {
159                 dev->dev_private = (void *)dev_priv;
160                 i915_dma_cleanup(dev);
161                 DRM_ERROR("can not ioremap virtual address for"
162                           " ring buffer\n");
163                 return DRM_ERR(ENOMEM);
164         }
165
166         dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
167
168         dev_priv->cpp = init->cpp;
169         dev_priv->sarea_priv->pf_current_page = 0;
170
171         /* We are using separate values as placeholders for mechanisms for
172          * private backbuffer/depthbuffer usage.
173          */
174         dev_priv->use_mi_batchbuffer_start = 0;
175
176         /* Allow hardware batchbuffers unless told otherwise.
177          */
178         dev_priv->allow_batchbuffer = 1;
179
180         /* Program Hardware Status Page */
181         dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 
182             0xffffffff);
183
184         if (!dev_priv->status_page_dmah) {
185                 dev->dev_private = (void *)dev_priv;
186                 i915_dma_cleanup(dev);
187                 DRM_ERROR("Can not allocate hardware status page\n");
188                 return DRM_ERR(ENOMEM);
189         }
190         dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
191         dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
192         
193         memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
194         DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
195
196         I915_WRITE(0x02080, dev_priv->dma_status_page);
197         DRM_DEBUG("Enabled hardware status page\n");
198         dev->dev_private = (void *)dev_priv;
199         return 0;
200 }
201
202 static int i915_dma_resume(drm_device_t * dev)
203 {
204         drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
205
206         DRM_DEBUG("%s\n", __FUNCTION__);
207
208         if (!dev_priv->sarea) {
209                 DRM_ERROR("can not find sarea!\n");
210                 return DRM_ERR(EINVAL);
211         }
212
213         if (!dev_priv->mmio_map) {
214                 DRM_ERROR("can not find mmio map!\n");
215                 return DRM_ERR(EINVAL);
216         }
217
218         if (dev_priv->ring.map.handle == NULL) {
219                 DRM_ERROR("can not ioremap virtual address for"
220                           " ring buffer\n");
221                 return DRM_ERR(ENOMEM);
222         }
223
224         /* Program Hardware Status Page */
225         if (!dev_priv->hw_status_page) {
226                 DRM_ERROR("Can not find hardware status page\n");
227                 return DRM_ERR(EINVAL);
228         }
229         DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
230
231         I915_WRITE(0x02080, dev_priv->dma_status_page);
232         DRM_DEBUG("Enabled hardware status page\n");
233
234         return 0;
235 }
236
237 static int i915_dma_init(DRM_IOCTL_ARGS)
238 {
239         DRM_DEVICE;
240         drm_i915_private_t *dev_priv;
241         drm_i915_init_t init;
242         int retcode = 0;
243
244         DRM_COPY_FROM_USER_IOCTL(init, (drm_i915_init_t __user *) data,
245                                  sizeof(init));
246
247         switch (init.func) {
248         case I915_INIT_DMA:
249                 dev_priv = drm_alloc(sizeof(drm_i915_private_t),
250                                      DRM_MEM_DRIVER);
251                 if (dev_priv == NULL)
252                         return DRM_ERR(ENOMEM);
253                 retcode = i915_initialize(dev, dev_priv, &init);
254                 break;
255         case I915_CLEANUP_DMA:
256                 retcode = i915_dma_cleanup(dev);
257                 break;
258         case I915_RESUME_DMA:
259                 retcode = i915_dma_resume(dev);
260                 break;
261         default:
262                 retcode = DRM_ERR(EINVAL);
263                 break;
264         }
265
266         return retcode;
267 }
268
269 /* Implement basically the same security restrictions as hardware does
270  * for MI_BATCH_NON_SECURE.  These can be made stricter at any time.
271  *
272  * Most of the calculations below involve calculating the size of a
273  * particular instruction.  It's important to get the size right as
274  * that tells us where the next instruction to check is.  Any illegal
275  * instruction detected will be given a size of zero, which is a
276  * signal to abort the rest of the buffer.
277  */
278 static int do_validate_cmd(int cmd)
279 {
280         switch (((cmd >> 29) & 0x7)) {
281         case 0x0:
282                 switch ((cmd >> 23) & 0x3f) {
283                 case 0x0:
284                         return 1;       /* MI_NOOP */
285                 case 0x4:
286                         return 1;       /* MI_FLUSH */
287                 default:
288                         return 0;       /* disallow everything else */
289                 }
290                 break;
291         case 0x1:
292                 return 0;       /* reserved */
293         case 0x2:
294                 return (cmd & 0xff) + 2;        /* 2d commands */
295         case 0x3:
296                 if (((cmd >> 24) & 0x1f) <= 0x18)
297                         return 1;
298
299                 switch ((cmd >> 24) & 0x1f) {
300                 case 0x1c:
301                         return 1;
302                 case 0x1d:
303                         switch ((cmd >> 16) & 0xff) {
304                         case 0x3:
305                                 return (cmd & 0x1f) + 2;
306                         case 0x4:
307                                 return (cmd & 0xf) + 2;
308                         default:
309                                 return (cmd & 0xffff) + 2;
310                         }
311                 case 0x1e:
312                         if (cmd & (1 << 23))
313                                 return (cmd & 0xffff) + 1;
314                         else
315                                 return 1;
316                 case 0x1f:
317                         if ((cmd & (1 << 23)) == 0)     /* inline vertices */
318                                 return (cmd & 0x1ffff) + 2;
319                         else if (cmd & (1 << 17))       /* indirect random */
320                                 if ((cmd & 0xffff) == 0)
321                                         return 0;       /* unknown length, too hard */
322                                 else
323                                         return (((cmd & 0xffff) + 1) / 2) + 1;
324                         else
325                                 return 2;       /* indirect sequential */
326                 default:
327                         return 0;
328                 }
329         default:
330                 return 0;
331         }
332
333         return 0;
334 }
335
336 static int validate_cmd(int cmd)
337 {
338         int ret = do_validate_cmd(cmd);
339
340 /*      printk("validate_cmd( %x ): %d\n", cmd, ret); */
341
342         return ret;
343 }
344
345 static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords)
346 {
347         drm_i915_private_t *dev_priv = dev->dev_private;
348         int i;
349         RING_LOCALS;
350
351         if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8)
352                 return DRM_ERR(EINVAL);
353
354         BEGIN_LP_RING((dwords+1)&~1);
355
356         for (i = 0; i < dwords;) {
357                 int cmd, sz;
358
359                 if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd)))
360                         return DRM_ERR(EINVAL);
361
362                 if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords)
363                         return DRM_ERR(EINVAL);
364
365                 OUT_RING(cmd);
366
367                 while (++i, --sz) {
368                         if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i],
369                                                          sizeof(cmd))) {
370                                 return DRM_ERR(EINVAL);
371                         }
372                         OUT_RING(cmd);
373                 }
374         }
375                 
376         if (dwords & 1)
377                 OUT_RING(0);
378
379         ADVANCE_LP_RING();
380                 
381         return 0;
382 }
383
384 static int i915_emit_box(drm_device_t * dev,
385                          drm_clip_rect_t __user * boxes,
386                          int i, int DR1, int DR4)
387 {
388         drm_i915_private_t *dev_priv = dev->dev_private;
389         drm_clip_rect_t box;
390         RING_LOCALS;
391
392         if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) {
393                 return DRM_ERR(EFAULT);
394         }
395
396         if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) {
397                 DRM_ERROR("Bad box %d,%d..%d,%d\n",
398                           box.x1, box.y1, box.x2, box.y2);
399                 return DRM_ERR(EINVAL);
400         }
401
402         if (IS_I965G(dev)) {
403                 BEGIN_LP_RING(4);
404                 OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
405                 OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
406                 OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
407                 OUT_RING(DR4);
408                 ADVANCE_LP_RING();
409         } else {
410                 BEGIN_LP_RING(6);
411                 OUT_RING(GFX_OP_DRAWRECT_INFO);
412                 OUT_RING(DR1);
413                 OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
414                 OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
415                 OUT_RING(DR4);
416                 OUT_RING(0);
417                 ADVANCE_LP_RING();
418         }
419
420         return 0;
421 }
422
423 /* XXX: Emitting the counter should really be moved to part of the IRQ
424  * emit.  For now, do it in both places:
425  */
426
427 void i915_emit_breadcrumb(drm_device_t *dev)
428 {
429         drm_i915_private_t *dev_priv = dev->dev_private;
430         RING_LOCALS;
431
432         dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
433
434         if (dev_priv->counter > 0x7FFFFFFFUL)
435                  dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
436
437         BEGIN_LP_RING(4);
438         OUT_RING(CMD_STORE_DWORD_IDX);
439         OUT_RING(20);
440         OUT_RING(dev_priv->counter);
441         OUT_RING(0);
442         ADVANCE_LP_RING();
443 }
444
445
446 int i915_emit_mi_flush(drm_device_t *dev, uint32_t flush)
447 {
448         drm_i915_private_t *dev_priv = dev->dev_private;
449         uint32_t flush_cmd = CMD_MI_FLUSH;
450         RING_LOCALS;
451
452         flush_cmd |= flush;
453
454         i915_kernel_lost_context(dev);
455
456         BEGIN_LP_RING(4);
457         OUT_RING(flush_cmd);
458         OUT_RING(0);
459         OUT_RING(0);
460         OUT_RING(0);
461         ADVANCE_LP_RING();
462
463         return 0;
464 }
465
466
467 static int i915_dispatch_cmdbuffer(drm_device_t * dev,
468                                    drm_i915_cmdbuffer_t * cmd)
469 {
470         drm_i915_private_t *dev_priv = dev->dev_private;
471         int nbox = cmd->num_cliprects;
472         int i = 0, count, ret;
473
474         if (cmd->sz & 0x3) {
475                 DRM_ERROR("alignment");
476                 return DRM_ERR(EINVAL);
477         }
478
479         i915_kernel_lost_context(dev);
480
481         count = nbox ? nbox : 1;
482
483         for (i = 0; i < count; i++) {
484                 if (i < nbox) {
485                         ret = i915_emit_box(dev, cmd->cliprects, i,
486                                             cmd->DR1, cmd->DR4);
487                         if (ret)
488                                 return ret;
489                 }
490
491                 ret = i915_emit_cmds(dev, (int __user *)cmd->buf, cmd->sz / 4);
492                 if (ret)
493                         return ret;
494         }
495
496         i915_emit_breadcrumb( dev );
497 #ifdef I915_HAVE_FENCE
498         drm_fence_flush_old(dev, 0, dev_priv->counter);
499 #endif
500         return 0;
501 }
502
503 static int i915_dispatch_batchbuffer(drm_device_t * dev,
504                                      drm_i915_batchbuffer_t * batch)
505 {
506         drm_i915_private_t *dev_priv = dev->dev_private;
507         drm_clip_rect_t __user *boxes = batch->cliprects;
508         int nbox = batch->num_cliprects;
509         int i = 0, count;
510         RING_LOCALS;
511
512         if ((batch->start | batch->used) & 0x7) {
513                 DRM_ERROR("alignment");
514                 return DRM_ERR(EINVAL);
515         }
516
517         i915_kernel_lost_context(dev);
518
519         count = nbox ? nbox : 1;
520
521         for (i = 0; i < count; i++) {
522                 if (i < nbox) {
523                         int ret = i915_emit_box(dev, boxes, i,
524                                                 batch->DR1, batch->DR4);
525                         if (ret)
526                                 return ret;
527                 }
528
529                 if (dev_priv->use_mi_batchbuffer_start) {
530                         BEGIN_LP_RING(2);
531                         OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
532                         OUT_RING(batch->start | MI_BATCH_NON_SECURE);
533                         ADVANCE_LP_RING();
534                 } else {
535                         BEGIN_LP_RING(4);
536                         OUT_RING(MI_BATCH_BUFFER);
537                         OUT_RING(batch->start | MI_BATCH_NON_SECURE);
538                         OUT_RING(batch->start + batch->used - 4);
539                         OUT_RING(0);
540                         ADVANCE_LP_RING();
541                 }
542         }
543
544         i915_emit_breadcrumb( dev );
545 #ifdef I915_HAVE_FENCE
546         drm_fence_flush_old(dev, 0, dev_priv->counter);
547 #endif
548         return 0;
549 }
550
551 static void i915_do_dispatch_flip(drm_device_t * dev, int pipe, int sync)
552 {
553         drm_i915_private_t *dev_priv = dev->dev_private;
554         u32 num_pages, current_page, next_page, dspbase;
555         int shift = 2 * pipe, x, y;
556         RING_LOCALS;
557
558         /* Calculate display base offset */
559         num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
560         current_page = (dev_priv->sarea_priv->pf_current_page >> shift) & 0x3;
561         next_page = (current_page + 1) % num_pages;
562
563         switch (next_page) {
564         default:
565         case 0:
566                 dspbase = dev_priv->sarea_priv->front_offset;
567                 break;
568         case 1:
569                 dspbase = dev_priv->sarea_priv->back_offset;
570                 break;
571         case 2:
572                 dspbase = dev_priv->sarea_priv->third_offset;
573                 break;
574         }
575
576         if (pipe == 0) {
577                 x = dev_priv->sarea_priv->pipeA_x;
578                 y = dev_priv->sarea_priv->pipeA_y;
579         } else {
580                 x = dev_priv->sarea_priv->pipeB_x;
581                 y = dev_priv->sarea_priv->pipeB_y;
582         }
583
584         dspbase += (y * dev_priv->sarea_priv->pitch + x) * dev_priv->cpp;
585
586         DRM_DEBUG("pipe=%d current_page=%d dspbase=0x%x\n", pipe, current_page,
587                   dspbase);
588
589         BEGIN_LP_RING(4);
590         OUT_RING(sync ? 0 :
591                  (MI_WAIT_FOR_EVENT | (pipe ? MI_WAIT_FOR_PLANE_B_FLIP :
592                                        MI_WAIT_FOR_PLANE_A_FLIP)));
593         OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | (sync ? 0 : ASYNC_FLIP) |
594                  (pipe ? DISPLAY_PLANE_B : DISPLAY_PLANE_A));
595         OUT_RING(dev_priv->sarea_priv->pitch * dev_priv->cpp);
596         OUT_RING(dspbase);
597         ADVANCE_LP_RING();
598
599         dev_priv->sarea_priv->pf_current_page &= ~(0x3 << shift);
600         dev_priv->sarea_priv->pf_current_page |= next_page << shift;
601 }
602
603 void i915_dispatch_flip(drm_device_t * dev, int pipes, int sync)
604 {
605         drm_i915_private_t *dev_priv = dev->dev_private;
606         int i;
607
608         DRM_DEBUG("%s: pipes=0x%x pfCurrentPage=%d\n",
609                   __FUNCTION__,
610                   pipes, dev_priv->sarea_priv->pf_current_page);
611
612         i915_emit_mi_flush(dev, MI_READ_FLUSH | MI_EXE_FLUSH);
613
614         for (i = 0; i < 2; i++)
615                 if (pipes & (1 << i))
616                         i915_do_dispatch_flip(dev, i, sync);
617
618         i915_emit_breadcrumb(dev);
619 #ifdef I915_HAVE_FENCE
620         if (!sync)
621                 drm_fence_flush_old(dev, 0, dev_priv->counter);
622 #endif
623 }
624
625 static int i915_quiescent(drm_device_t * dev)
626 {
627         drm_i915_private_t *dev_priv = dev->dev_private;
628
629         i915_kernel_lost_context(dev);
630         return i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
631 }
632
633 static int i915_flush_ioctl(DRM_IOCTL_ARGS)
634 {
635         DRM_DEVICE;
636
637         LOCK_TEST_WITH_RETURN(dev, filp);
638
639         return i915_quiescent(dev);
640 }
641
642 static int i915_batchbuffer(DRM_IOCTL_ARGS)
643 {
644         DRM_DEVICE;
645         drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
646         u32 *hw_status = dev_priv->hw_status_page;
647         drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
648             dev_priv->sarea_priv;
649         drm_i915_batchbuffer_t batch;
650         int ret;
651
652         if (!dev_priv->allow_batchbuffer) {
653                 DRM_ERROR("Batchbuffer ioctl disabled\n");
654                 return DRM_ERR(EINVAL);
655         }
656
657         DRM_COPY_FROM_USER_IOCTL(batch, (drm_i915_batchbuffer_t __user *) data,
658                                  sizeof(batch));
659
660         DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n",
661                   batch.start, batch.used, batch.num_cliprects);
662
663         LOCK_TEST_WITH_RETURN(dev, filp);
664
665         if (batch.num_cliprects && DRM_VERIFYAREA_READ(batch.cliprects,
666                                                        batch.num_cliprects *
667                                                        sizeof(drm_clip_rect_t)))
668                 return DRM_ERR(EFAULT);
669
670         ret = i915_dispatch_batchbuffer(dev, &batch);
671
672         sarea_priv->last_dispatch = (int)hw_status[5];
673         return ret;
674 }
675
676 static int i915_cmdbuffer(DRM_IOCTL_ARGS)
677 {
678         DRM_DEVICE;
679         drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
680         u32 *hw_status = dev_priv->hw_status_page;
681         drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
682             dev_priv->sarea_priv;
683         drm_i915_cmdbuffer_t cmdbuf;
684         int ret;
685
686         DRM_COPY_FROM_USER_IOCTL(cmdbuf, (drm_i915_cmdbuffer_t __user *) data,
687                                  sizeof(cmdbuf));
688
689         DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
690                   cmdbuf.buf, cmdbuf.sz, cmdbuf.num_cliprects);
691
692         LOCK_TEST_WITH_RETURN(dev, filp);
693
694         if (cmdbuf.num_cliprects &&
695             DRM_VERIFYAREA_READ(cmdbuf.cliprects,
696                                 cmdbuf.num_cliprects *
697                                 sizeof(drm_clip_rect_t))) {
698                 DRM_ERROR("Fault accessing cliprects\n");
699                 return DRM_ERR(EFAULT);
700         }
701
702         ret = i915_dispatch_cmdbuffer(dev, &cmdbuf);
703         if (ret) {
704                 DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
705                 return ret;
706         }
707
708         sarea_priv->last_dispatch = (int)hw_status[5];
709         return 0;
710 }
711
712 static int i915_do_cleanup_pageflip(drm_device_t * dev)
713 {
714         drm_i915_private_t *dev_priv = dev->dev_private;
715         int i, pipes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
716
717         DRM_DEBUG("%s\n", __FUNCTION__);
718
719         for (i = 0, pipes = 0; i < 2; i++)
720                 if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) {
721                         dev_priv->sarea_priv->pf_current_page =
722                                 (dev_priv->sarea_priv->pf_current_page &
723                                  ~(0x3 << (2 * i))) | (num_pages - 1) << (2 * i);
724
725                         pipes |= 1 << i;
726                 }
727
728         if (pipes)
729                 i915_dispatch_flip(dev, pipes, 0);
730
731         return 0;
732 }
733
734 static int i915_flip_bufs(DRM_IOCTL_ARGS)
735 {
736         DRM_DEVICE;
737         drm_i915_flip_t param;
738
739         DRM_DEBUG("%s\n", __FUNCTION__);
740
741         LOCK_TEST_WITH_RETURN(dev, filp);
742
743         DRM_COPY_FROM_USER_IOCTL(param, (drm_i915_flip_t __user *) data,
744                                  sizeof(param));
745
746         if (param.pipes & ~0x3) {
747                 DRM_ERROR("Invalid pipes 0x%x, only <= 0x3 is valid\n",
748                           param.pipes);
749                 return DRM_ERR(EINVAL);
750         }
751
752         i915_dispatch_flip(dev, param.pipes, 0);
753
754         return 0;
755 }
756
757
758 static int i915_getparam(DRM_IOCTL_ARGS)
759 {
760         DRM_DEVICE;
761         drm_i915_private_t *dev_priv = dev->dev_private;
762         drm_i915_getparam_t param;
763         int value;
764
765         if (!dev_priv) {
766                 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
767                 return DRM_ERR(EINVAL);
768         }
769
770         DRM_COPY_FROM_USER_IOCTL(param, (drm_i915_getparam_t __user *) data,
771                                  sizeof(param));
772
773         switch (param.param) {
774         case I915_PARAM_IRQ_ACTIVE:
775                 value = dev->irq ? 1 : 0;
776                 break;
777         case I915_PARAM_ALLOW_BATCHBUFFER:
778                 value = dev_priv->allow_batchbuffer ? 1 : 0;
779                 break;
780         case I915_PARAM_LAST_DISPATCH:
781                 value = READ_BREADCRUMB(dev_priv);
782                 break;
783         default:
784                 DRM_ERROR("Unknown parameter %d\n", param.param);
785                 return DRM_ERR(EINVAL);
786         }
787
788         if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) {
789                 DRM_ERROR("DRM_COPY_TO_USER failed\n");
790                 return DRM_ERR(EFAULT);
791         }
792
793         return 0;
794 }
795
796 static int i915_setparam(DRM_IOCTL_ARGS)
797 {
798         DRM_DEVICE;
799         drm_i915_private_t *dev_priv = dev->dev_private;
800         drm_i915_setparam_t param;
801
802         if (!dev_priv) {
803                 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
804                 return DRM_ERR(EINVAL);
805         }
806
807         DRM_COPY_FROM_USER_IOCTL(param, (drm_i915_setparam_t __user *) data,
808                                  sizeof(param));
809
810         switch (param.param) {
811         case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
812                 dev_priv->use_mi_batchbuffer_start = param.value;
813                 break;
814         case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
815                 dev_priv->tex_lru_log_granularity = param.value;
816                 break;
817         case I915_SETPARAM_ALLOW_BATCHBUFFER:
818                 dev_priv->allow_batchbuffer = param.value;
819                 break;
820         default:
821                 DRM_ERROR("unknown parameter %d\n", param.param);
822                 return DRM_ERR(EINVAL);
823         }
824
825         return 0;
826 }
827
828 drm_i915_mmio_entry_t mmio_table[] = {
829         [MMIO_REGS_PS_DEPTH_COUNT] = {
830                 I915_MMIO_MAY_READ|I915_MMIO_MAY_WRITE,
831                 0x2350,
832                 8
833         }       
834 };
835
836 static int mmio_table_size = sizeof(mmio_table)/sizeof(drm_i915_mmio_entry_t);
837
838 static int i915_mmio(DRM_IOCTL_ARGS)
839 {
840         char buf[32];
841         DRM_DEVICE;
842         drm_i915_private_t *dev_priv = dev->dev_private;
843         drm_i915_mmio_entry_t *e;        
844         drm_i915_mmio_t mmio;
845         void __iomem *base;
846         if (!dev_priv) {
847                 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
848                 return DRM_ERR(EINVAL);
849         }
850         DRM_COPY_FROM_USER_IOCTL(mmio, (drm_i915_mmio_t __user *) data,
851                                  sizeof(mmio));
852
853         if (mmio.reg >= mmio_table_size)
854                 return DRM_ERR(EINVAL);
855
856         e = &mmio_table[mmio.reg];
857         base = dev_priv->mmio_map->handle + e->offset;
858
859         switch (mmio.read_write) {
860                 case I915_MMIO_READ:
861                         if (!(e->flag & I915_MMIO_MAY_READ))
862                                 return DRM_ERR(EINVAL);
863                         memcpy_fromio(buf, base, e->size);
864                         if (DRM_COPY_TO_USER(mmio.data, buf, e->size)) {
865                                 DRM_ERROR("DRM_COPY_TO_USER failed\n");
866                                 return DRM_ERR(EFAULT);
867                         }
868                         break;
869
870                 case I915_MMIO_WRITE:
871                         if (!(e->flag & I915_MMIO_MAY_WRITE))
872                                 return DRM_ERR(EINVAL);
873                         if(DRM_COPY_FROM_USER(buf, mmio.data, e->size)) {
874                                 DRM_ERROR("DRM_COPY_TO_USER failed\n");
875                                 return DRM_ERR(EFAULT);
876                         }
877                         memcpy_toio(base, buf, e->size);
878                         break;
879         }
880         return 0;
881 }
882
883 int i915_driver_load(drm_device_t *dev, unsigned long flags)
884 {
885         /* i915 has 4 more counters */
886         dev->counters += 4;
887         dev->types[6] = _DRM_STAT_IRQ;
888         dev->types[7] = _DRM_STAT_PRIMARY;
889         dev->types[8] = _DRM_STAT_SECONDARY;
890         dev->types[9] = _DRM_STAT_DMA;
891
892         return 0;
893 }
894
895 void i915_driver_lastclose(drm_device_t * dev)
896 {
897         if (dev->dev_private) {
898                 drm_i915_private_t *dev_priv = dev->dev_private;
899                 i915_do_cleanup_pageflip(dev);
900                 i915_mem_takedown(&(dev_priv->agp_heap));
901         }
902         i915_dma_cleanup(dev);
903 }
904
905 void i915_driver_preclose(drm_device_t * dev, DRMFILE filp)
906 {
907         if (dev->dev_private) {
908                 drm_i915_private_t *dev_priv = dev->dev_private;
909                 i915_mem_release(dev, filp, dev_priv->agp_heap);
910         }
911 }
912
913 drm_ioctl_desc_t i915_ioctls[] = {
914         [DRM_IOCTL_NR(DRM_I915_INIT)] = {i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
915         [DRM_IOCTL_NR(DRM_I915_FLUSH)] = {i915_flush_ioctl, DRM_AUTH},
916         [DRM_IOCTL_NR(DRM_I915_FLIP)] = {i915_flip_bufs, DRM_AUTH},
917         [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] = {i915_batchbuffer, DRM_AUTH},
918         [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] = {i915_irq_emit, DRM_AUTH},
919         [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] = {i915_irq_wait, DRM_AUTH},
920         [DRM_IOCTL_NR(DRM_I915_GETPARAM)] = {i915_getparam, DRM_AUTH},
921         [DRM_IOCTL_NR(DRM_I915_SETPARAM)] = {i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
922         [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH},
923         [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH},
924         [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
925         [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH},
926         [DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
927         [DRM_IOCTL_NR(DRM_I915_SET_VBLANK_PIPE)] = { i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
928         [DRM_IOCTL_NR(DRM_I915_GET_VBLANK_PIPE)] = { i915_vblank_pipe_get, DRM_AUTH },
929         [DRM_IOCTL_NR(DRM_I915_VBLANK_SWAP)] = {i915_vblank_swap, DRM_AUTH},
930         [DRM_IOCTL_NR(DRM_I915_MMIO)] = {i915_mmio, DRM_AUTH},
931 };
932
933 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
934
935 /**
936  * Determine if the device really is AGP or not.
937  *
938  * All Intel graphics chipsets are treated as AGP, even if they are really
939  * PCI-e.
940  *
941  * \param dev   The device to be tested.
942  *
943  * \returns
944  * A value of 1 is always retured to indictate every i9x5 is AGP.
945  */
946 int i915_driver_device_is_agp(drm_device_t * dev)
947 {
948         return 1;
949 }
950
951 int i915_driver_firstopen(struct drm_device *dev)
952 {
953 #ifdef I915_HAVE_BUFFER
954         drm_bo_driver_init(dev);
955 #endif
956         return 0;
957 }