1/* i810_dma.c -- DMA support for the i810 -*- linux-c -*- 2 * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com 3 * 4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. 5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 6 * All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the next 16 * paragraph) shall be included in all copies or substantial portions of the 17 * Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 * DEALINGS IN THE SOFTWARE. 26 * 27 * Authors: Rickard E. (Rik) Faith <faith@valinux.com> 28 * Jeff Hartmann <jhartmann@valinux.com> 29 * Keith Whitwell <keith@tungstengraphics.com> 30 * 31 */ 32 33#include <drm/drmP.h> 34#include <drm/i810_drm.h> 35#include "i810_drv.h" 36#include <linux/interrupt.h> /* For task queue support */ 37#include <linux/delay.h> 38#include <linux/slab.h> 39#include <linux/pagemap.h> 40 41#define I810_BUF_FREE 2 42#define I810_BUF_CLIENT 1 43#define I810_BUF_HARDWARE 0 44 45#define I810_BUF_UNMAPPED 0 46#define I810_BUF_MAPPED 1 47 48static struct drm_buf *i810_freelist_get(struct drm_device * dev) 49{ 50 struct drm_device_dma *dma = dev->dma; 51 int i; 52 int used; 53 54 /* Linear search might not be the best solution */ 55 56 for (i = 0; i < dma->buf_count; i++) { 57 struct drm_buf *buf = dma->buflist[i]; 58 drm_i810_buf_priv_t *buf_priv = buf->dev_private; 59 /* In use is already a pointer */ 60 used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, 61 I810_BUF_CLIENT); 62 if (used == I810_BUF_FREE) 63 return buf; 64 } 65 return NULL; 66} 67 68/* This should only be called if the buffer is not sent to the hardware 69 * yet, the hardware updates in use for us once its on the ring buffer. 70 */ 71 72static int i810_freelist_put(struct drm_device *dev, struct drm_buf *buf) 73{ 74 drm_i810_buf_priv_t *buf_priv = buf->dev_private; 75 int used; 76 77 /* In use is already a pointer */ 78 used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE); 79 if (used != I810_BUF_CLIENT) { 80 DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx); 81 return -EINVAL; 82 } 83 84 return 0; 85} 86 87static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) 88{ 89 struct drm_file *priv = filp->private_data; 90 struct drm_device *dev; 91 drm_i810_private_t *dev_priv; 92 struct drm_buf *buf; 93 drm_i810_buf_priv_t *buf_priv; 94 95 dev = priv->minor->dev; 96 dev_priv = dev->dev_private; 97 buf = dev_priv->mmap_buffer; 98 buf_priv = buf->dev_private; 99 100 vma->vm_flags |= VM_DONTCOPY; 101 102 buf_priv->currently_mapped = I810_BUF_MAPPED; 103 104 if (io_remap_pfn_range(vma, vma->vm_start, 105 vma->vm_pgoff, 106 vma->vm_end - vma->vm_start, vma->vm_page_prot)) 107 return -EAGAIN; 108 return 0; 109} 110 111static const struct file_operations i810_buffer_fops = { 112 .open = drm_open, 113 .release = drm_release, 114 .unlocked_ioctl = drm_ioctl, 115 .mmap = i810_mmap_buffers, 116#ifdef CONFIG_COMPAT 117 .compat_ioctl = drm_compat_ioctl, 118#endif 119 .llseek = noop_llseek, 120}; 121 122static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv) 123{ 124 struct drm_device *dev = file_priv->minor->dev; 125 drm_i810_buf_priv_t *buf_priv = buf->dev_private; 126 drm_i810_private_t *dev_priv = dev->dev_private; 127 const struct file_operations *old_fops; 128 int retcode = 0; 129 130 if (buf_priv->currently_mapped == I810_BUF_MAPPED) 131 return -EINVAL; 132 133 /* This is all entirely broken */ 134 old_fops = file_priv->filp->f_op; 135 file_priv->filp->f_op = &i810_buffer_fops; 136 dev_priv->mmap_buffer = buf; 137 buf_priv->virtual = (void *)vm_mmap(file_priv->filp, 0, buf->total, 138 PROT_READ | PROT_WRITE, 139 MAP_SHARED, buf->bus_address); 140 dev_priv->mmap_buffer = NULL; 141 file_priv->filp->f_op = old_fops; 142 if (IS_ERR(buf_priv->virtual)) { 143 /* Real error */ 144 DRM_ERROR("mmap error\n"); 145 retcode = PTR_ERR(buf_priv->virtual); 146 buf_priv->virtual = NULL; 147 } 148 149 return retcode; 150} 151 152static int i810_unmap_buffer(struct drm_buf *buf) 153{ 154 drm_i810_buf_priv_t *buf_priv = buf->dev_private; 155 int retcode = 0; 156 157 if (buf_priv->currently_mapped != I810_BUF_MAPPED) 158 return -EINVAL; 159 160 retcode = vm_munmap((unsigned long)buf_priv->virtual, 161 (size_t) buf->total); 162 163 buf_priv->currently_mapped = I810_BUF_UNMAPPED; 164 buf_priv->virtual = NULL; 165 166 return retcode; 167} 168 169static int i810_dma_get_buffer(struct drm_device *dev, drm_i810_dma_t *d, 170 struct drm_file *file_priv) 171{ 172 struct drm_buf *buf; 173 drm_i810_buf_priv_t *buf_priv; 174 int retcode = 0; 175 176 buf = i810_freelist_get(dev); 177 if (!buf) { 178 retcode = -ENOMEM; 179 DRM_DEBUG("retcode=%d\n", retcode); 180 return retcode; 181 } 182 183 retcode = i810_map_buffer(buf, file_priv); 184 if (retcode) { 185 i810_freelist_put(dev, buf); 186 DRM_ERROR("mapbuf failed, retcode %d\n", retcode); 187 return retcode; 188 } 189 buf->file_priv = file_priv; 190 buf_priv = buf->dev_private; 191 d->granted = 1; 192 d->request_idx = buf->idx; 193 d->request_size = buf->total; 194 d->virtual = buf_priv->virtual; 195 196 return retcode; 197} 198 199static int i810_dma_cleanup(struct drm_device *dev) 200{ 201 struct drm_device_dma *dma = dev->dma; 202 203 /* Make sure interrupts are disabled here because the uninstall ioctl 204 * may not have been called from userspace and after dev_private 205 * is freed, it's too late. 206 */ 207 if (drm_core_check_feature(dev, DRIVER_HAVE_IRQ) && dev->irq_enabled) 208 drm_irq_uninstall(dev); 209 210 if (dev->dev_private) { 211 int i; 212 drm_i810_private_t *dev_priv = 213 (drm_i810_private_t *) dev->dev_private; 214 215 if (dev_priv->ring.virtual_start) 216 drm_legacy_ioremapfree(&dev_priv->ring.map, dev); 217 if (dev_priv->hw_status_page) { 218 pci_free_consistent(dev->pdev, PAGE_SIZE, 219 dev_priv->hw_status_page, 220 dev_priv->dma_status_page); 221 } 222 kfree(dev->dev_private); 223 dev->dev_private = NULL; 224 225 for (i = 0; i < dma->buf_count; i++) { 226 struct drm_buf *buf = dma->buflist[i]; 227 drm_i810_buf_priv_t *buf_priv = buf->dev_private; 228 229 if (buf_priv->kernel_virtual && buf->total) 230 drm_legacy_ioremapfree(&buf_priv->map, dev); 231 } 232 } 233 return 0; 234} 235 236static int i810_wait_ring(struct drm_device *dev, int n) 237{ 238 drm_i810_private_t *dev_priv = dev->dev_private; 239 drm_i810_ring_buffer_t *ring = &(dev_priv->ring); 240 int iters = 0; 241 unsigned long end; 242 unsigned int last_head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; 243 244 end = jiffies + (HZ * 3); 245 while (ring->space < n) { 246 ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; 247 ring->space = ring->head - (ring->tail + 8); 248 if (ring->space < 0) 249 ring->space += ring->Size; 250 251 if (ring->head != last_head) { 252 end = jiffies + (HZ * 3); 253 last_head = ring->head; 254 } 255 256 iters++; 257 if (time_before(end, jiffies)) { 258 DRM_ERROR("space: %d wanted %d\n", ring->space, n); 259 DRM_ERROR("lockup\n"); 260 goto out_wait_ring; 261 } 262 udelay(1); 263 } 264 265out_wait_ring: 266 return iters; 267} 268 269static void i810_kernel_lost_context(struct drm_device *dev) 270{ 271 drm_i810_private_t *dev_priv = dev->dev_private; 272 drm_i810_ring_buffer_t *ring = &(dev_priv->ring); 273 274 ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR; 275 ring->tail = I810_READ(LP_RING + RING_TAIL); 276 ring->space = ring->head - (ring->tail + 8); 277 if (ring->space < 0) 278 ring->space += ring->Size; 279} 280 281static int i810_freelist_init(struct drm_device *dev, drm_i810_private_t *dev_priv) 282{ 283 struct drm_device_dma *dma = dev->dma; 284 int my_idx = 24; 285 u32 *hw_status = (u32 *) (dev_priv->hw_status_page + my_idx); 286 int i; 287 288 if (dma->buf_count > 1019) { 289 /* Not enough space in the status page for the freelist */ 290 return -EINVAL; 291 } 292 293 for (i = 0; i < dma->buf_count; i++) { 294 struct drm_buf *buf = dma->buflist[i]; 295 drm_i810_buf_priv_t *buf_priv = buf->dev_private; 296 297 buf_priv->in_use = hw_status++; 298 buf_priv->my_use_idx = my_idx; 299 my_idx += 4; 300 301 *buf_priv->in_use = I810_BUF_FREE; 302 303 buf_priv->map.offset = buf->bus_address; 304 buf_priv->map.size = buf->total; 305 buf_priv->map.type = _DRM_AGP; 306 buf_priv->map.flags = 0; 307 buf_priv->map.mtrr = 0; 308 309 drm_legacy_ioremap(&buf_priv->map, dev); 310 buf_priv->kernel_virtual = buf_priv->map.handle; 311 312 } 313 return 0; 314} 315 316static int i810_dma_initialize(struct drm_device *dev, 317 drm_i810_private_t *dev_priv, 318 drm_i810_init_t *init) 319{ 320 struct drm_map_list *r_list; 321 memset(dev_priv, 0, sizeof(drm_i810_private_t)); 322 323 list_for_each_entry(r_list, &dev->maplist, head) { 324 if (r_list->map && 325 r_list->map->type == _DRM_SHM && 326 r_list->map->flags & _DRM_CONTAINS_LOCK) { 327 dev_priv->sarea_map = r_list->map; 328 break; 329 } 330 } 331 if (!dev_priv->sarea_map) { 332 dev->dev_private = (void *)dev_priv; 333 i810_dma_cleanup(dev); 334 DRM_ERROR("can not find sarea!\n"); 335 return -EINVAL; 336 } 337 dev_priv->mmio_map = drm_legacy_findmap(dev, init->mmio_offset); 338 if (!dev_priv->mmio_map) { 339 dev->dev_private = (void *)dev_priv; 340 i810_dma_cleanup(dev); 341 DRM_ERROR("can not find mmio map!\n"); 342 return -EINVAL; 343 } 344 dev->agp_buffer_token = init->buffers_offset; 345 dev->agp_buffer_map = drm_legacy_findmap(dev, init->buffers_offset); 346 if (!dev->agp_buffer_map) { 347 dev->dev_private = (void *)dev_priv; 348 i810_dma_cleanup(dev); 349 DRM_ERROR("can not find dma buffer map!\n"); 350 return -EINVAL; 351 } 352 353 dev_priv->sarea_priv = (drm_i810_sarea_t *) 354 ((u8 *) dev_priv->sarea_map->handle + init->sarea_priv_offset); 355 356 dev_priv->ring.Start = init->ring_start; 357 dev_priv->ring.End = init->ring_end; 358 dev_priv->ring.Size = init->ring_size; 359 360 dev_priv->ring.map.offset = dev->agp->base + init->ring_start; 361 dev_priv->ring.map.size = init->ring_size; 362 dev_priv->ring.map.type = _DRM_AGP; 363 dev_priv->ring.map.flags = 0; 364 dev_priv->ring.map.mtrr = 0; 365 366 drm_legacy_ioremap(&dev_priv->ring.map, dev); 367 368 if (dev_priv->ring.map.handle == NULL) { 369 dev->dev_private = (void *)dev_priv; 370 i810_dma_cleanup(dev); 371 DRM_ERROR("can not ioremap virtual address for" 372 " ring buffer\n"); 373 return -ENOMEM; 374 } 375 376 dev_priv->ring.virtual_start = dev_priv->ring.map.handle; 377 378 dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; 379 380 dev_priv->w = init->w; 381 dev_priv->h = init->h; 382 dev_priv->pitch = init->pitch; 383 dev_priv->back_offset = init->back_offset; 384 dev_priv->depth_offset = init->depth_offset; 385 dev_priv->front_offset = init->front_offset; 386 387 dev_priv->overlay_offset = init->overlay_offset; 388 dev_priv->overlay_physical = init->overlay_physical; 389 390 dev_priv->front_di1 = init->front_offset | init->pitch_bits; 391 dev_priv->back_di1 = init->back_offset | init->pitch_bits; 392 dev_priv->zi1 = init->depth_offset | init->pitch_bits; 393 394 /* Program Hardware Status Page */ 395 dev_priv->hw_status_page = 396 pci_zalloc_consistent(dev->pdev, PAGE_SIZE, 397 &dev_priv->dma_status_page); 398 if (!dev_priv->hw_status_page) { 399 dev->dev_private = (void *)dev_priv; 400 i810_dma_cleanup(dev); 401 DRM_ERROR("Can not allocate hardware status page\n"); 402 return -ENOMEM; 403 } 404 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); 405 406 I810_WRITE(0x02080, dev_priv->dma_status_page); 407 DRM_DEBUG("Enabled hardware status page\n"); 408 409 /* Now we need to init our freelist */ 410 if (i810_freelist_init(dev, dev_priv) != 0) { 411 dev->dev_private = (void *)dev_priv; 412 i810_dma_cleanup(dev); 413 DRM_ERROR("Not enough space in the status page for" 414 " the freelist\n"); 415 return -ENOMEM; 416 } 417 dev->dev_private = (void *)dev_priv; 418 419 return 0; 420} 421 422static int i810_dma_init(struct drm_device *dev, void *data, 423 struct drm_file *file_priv) 424{ 425 drm_i810_private_t *dev_priv; 426 drm_i810_init_t *init = data; 427 int retcode = 0; 428 429 switch (init->func) { 430 case I810_INIT_DMA_1_4: 431 DRM_INFO("Using v1.4 init.\n"); 432 dev_priv = kmalloc(sizeof(drm_i810_private_t), GFP_KERNEL); 433 if (dev_priv == NULL) 434 return -ENOMEM; 435 retcode = i810_dma_initialize(dev, dev_priv, init); 436 break; 437 438 case I810_CLEANUP_DMA: 439 DRM_INFO("DMA Cleanup\n"); 440 retcode = i810_dma_cleanup(dev); 441 break; 442 default: 443 return -EINVAL; 444 } 445 446 return retcode; 447} 448 449/* Most efficient way to verify state for the i810 is as it is 450 * emitted. Non-conformant state is silently dropped. 451 * 452 * Use 'volatile' & local var tmp to force the emitted values to be 453 * identical to the verified ones. 454 */ 455static void i810EmitContextVerified(struct drm_device *dev, 456 volatile unsigned int *code) 457{ 458 drm_i810_private_t *dev_priv = dev->dev_private; 459 int i, j = 0; 460 unsigned int tmp; 461 RING_LOCALS; 462 463 BEGIN_LP_RING(I810_CTX_SETUP_SIZE); 464 465 OUT_RING(GFX_OP_COLOR_FACTOR); 466 OUT_RING(code[I810_CTXREG_CF1]); 467 468 OUT_RING(GFX_OP_STIPPLE); 469 OUT_RING(code[I810_CTXREG_ST1]); 470 471 for (i = 4; i < I810_CTX_SETUP_SIZE; i++) { 472 tmp = code[i]; 473 474 if ((tmp & (7 << 29)) == (3 << 29) && 475 (tmp & (0x1f << 24)) < (0x1d << 24)) { 476 OUT_RING(tmp); 477 j++; 478 } else 479 printk("constext state dropped!!!\n"); 480 } 481 482 if (j & 1) 483 OUT_RING(0); 484 485 ADVANCE_LP_RING(); 486} 487 488static void i810EmitTexVerified(struct drm_device *dev, volatile unsigned int *code) 489{ 490 drm_i810_private_t *dev_priv = dev->dev_private; 491 int i, j = 0; 492 unsigned int tmp; 493 RING_LOCALS; 494 495 BEGIN_LP_RING(I810_TEX_SETUP_SIZE); 496 497 OUT_RING(GFX_OP_MAP_INFO); 498 OUT_RING(code[I810_TEXREG_MI1]); 499 OUT_RING(code[I810_TEXREG_MI2]); 500 OUT_RING(code[I810_TEXREG_MI3]); 501 502 for (i = 4; i < I810_TEX_SETUP_SIZE; i++) { 503 tmp = code[i]; 504 505 if ((tmp & (7 << 29)) == (3 << 29) && 506 (tmp & (0x1f << 24)) < (0x1d << 24)) { 507 OUT_RING(tmp); 508 j++; 509 } else 510 printk("texture state dropped!!!\n"); 511 } 512 513 if (j & 1) 514 OUT_RING(0); 515 516 ADVANCE_LP_RING(); 517} 518 519/* Need to do some additional checking when setting the dest buffer. 520 */ 521static void i810EmitDestVerified(struct drm_device *dev, 522 volatile unsigned int *code) 523{ 524 drm_i810_private_t *dev_priv = dev->dev_private; 525 unsigned int tmp; 526 RING_LOCALS; 527 528 BEGIN_LP_RING(I810_DEST_SETUP_SIZE + 2); 529 530 tmp = code[I810_DESTREG_DI1]; 531 if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { 532 OUT_RING(CMD_OP_DESTBUFFER_INFO); 533 OUT_RING(tmp); 534 } else 535 DRM_DEBUG("bad di1 %x (allow %x or %x)\n", 536 tmp, dev_priv->front_di1, dev_priv->back_di1); 537 538 /* invarient: 539 */ 540 OUT_RING(CMD_OP_Z_BUFFER_INFO); 541 OUT_RING(dev_priv->zi1); 542 543 OUT_RING(GFX_OP_DESTBUFFER_VARS); 544 OUT_RING(code[I810_DESTREG_DV1]); 545 546 OUT_RING(GFX_OP_DRAWRECT_INFO); 547 OUT_RING(code[I810_DESTREG_DR1]); 548 OUT_RING(code[I810_DESTREG_DR2]); 549 OUT_RING(code[I810_DESTREG_DR3]); 550 OUT_RING(code[I810_DESTREG_DR4]); 551 OUT_RING(0); 552 553 ADVANCE_LP_RING(); 554} 555 556static void i810EmitState(struct drm_device *dev) 557{ 558 drm_i810_private_t *dev_priv = dev->dev_private; 559 drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; 560 unsigned int dirty = sarea_priv->dirty; 561 562 DRM_DEBUG("%x\n", dirty); 563 564 if (dirty & I810_UPLOAD_BUFFERS) { 565 i810EmitDestVerified(dev, sarea_priv->BufferState); 566 sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS; 567 } 568 569 if (dirty & I810_UPLOAD_CTX) { 570 i810EmitContextVerified(dev, sarea_priv->ContextState); 571 sarea_priv->dirty &= ~I810_UPLOAD_CTX; 572 } 573 574 if (dirty & I810_UPLOAD_TEX0) { 575 i810EmitTexVerified(dev, sarea_priv->TexState[0]); 576 sarea_priv->dirty &= ~I810_UPLOAD_TEX0; 577 } 578 579 if (dirty & I810_UPLOAD_TEX1) { 580 i810EmitTexVerified(dev, sarea_priv->TexState[1]); 581 sarea_priv->dirty &= ~I810_UPLOAD_TEX1; 582 } 583} 584 585/* need to verify 586 */ 587static void i810_dma_dispatch_clear(struct drm_device *dev, int flags, 588 unsigned int clear_color, 589 unsigned int clear_zval) 590{ 591 drm_i810_private_t *dev_priv = dev->dev_private; 592 drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; 593 int nbox = sarea_priv->nbox; 594 struct drm_clip_rect *pbox = sarea_priv->boxes; 595 int pitch = dev_priv->pitch; 596 int cpp = 2; 597 int i; 598 RING_LOCALS; 599 600 if (dev_priv->current_page == 1) { 601 unsigned int tmp = flags; 602 603 flags &= ~(I810_FRONT | I810_BACK); 604 if (tmp & I810_FRONT) 605 flags |= I810_BACK; 606 if (tmp & I810_BACK) 607 flags |= I810_FRONT; 608 } 609 610 i810_kernel_lost_context(dev); 611 612 if (nbox > I810_NR_SAREA_CLIPRECTS) 613 nbox = I810_NR_SAREA_CLIPRECTS; 614 615 for (i = 0; i < nbox; i++, pbox++) { 616 unsigned int x = pbox->x1; 617 unsigned int y = pbox->y1; 618 unsigned int width = (pbox->x2 - x) * cpp; 619 unsigned int height = pbox->y2 - y; 620 unsigned int start = y * pitch + x * cpp; 621 622 if (pbox->x1 > pbox->x2 || 623 pbox->y1 > pbox->y2 || 624 pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h) 625 continue; 626 627 if (flags & I810_FRONT) { 628 BEGIN_LP_RING(6); 629 OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3); 630 OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch); 631 OUT_RING((height << 16) | width); 632 OUT_RING(start); 633 OUT_RING(clear_color); 634 OUT_RING(0); 635 ADVANCE_LP_RING(); 636 } 637 638 if (flags & I810_BACK) { 639 BEGIN_LP_RING(6); 640 OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3); 641 OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch); 642 OUT_RING((height << 16) | width); 643 OUT_RING(dev_priv->back_offset + start); 644 OUT_RING(clear_color); 645 OUT_RING(0); 646 ADVANCE_LP_RING(); 647 } 648 649 if (flags & I810_DEPTH) { 650 BEGIN_LP_RING(6); 651 OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3); 652 OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch); 653 OUT_RING((height << 16) | width); 654 OUT_RING(dev_priv->depth_offset + start); 655 OUT_RING(clear_zval); 656 OUT_RING(0); 657 ADVANCE_LP_RING(); 658 } 659 } 660} 661 662static void i810_dma_dispatch_swap(struct drm_device *dev) 663{ 664 drm_i810_private_t *dev_priv = dev->dev_private; 665 drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; 666 int nbox = sarea_priv->nbox; 667 struct drm_clip_rect *pbox = sarea_priv->boxes; 668 int pitch = dev_priv->pitch; 669 int cpp = 2; 670 int i; 671 RING_LOCALS; 672 673 DRM_DEBUG("swapbuffers\n"); 674 675 i810_kernel_lost_context(dev); 676 677 if (nbox > I810_NR_SAREA_CLIPRECTS) 678 nbox = I810_NR_SAREA_CLIPRECTS; 679 680 for (i = 0; i < nbox; i++, pbox++) { 681 unsigned int w = pbox->x2 - pbox->x1; 682 unsigned int h = pbox->y2 - pbox->y1; 683 unsigned int dst = pbox->x1 * cpp + pbox->y1 * pitch; 684 unsigned int start = dst; 685 686 if (pbox->x1 > pbox->x2 || 687 pbox->y1 > pbox->y2 || 688 pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h) 689 continue; 690 691 BEGIN_LP_RING(6); 692 OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4); 693 OUT_RING(pitch | (0xCC << 16)); 694 OUT_RING((h << 16) | (w * cpp)); 695 if (dev_priv->current_page == 0) 696 OUT_RING(dev_priv->front_offset + start); 697 else 698 OUT_RING(dev_priv->back_offset + start); 699 OUT_RING(pitch); 700 if (dev_priv->current_page == 0) 701 OUT_RING(dev_priv->back_offset + start); 702 else 703 OUT_RING(dev_priv->front_offset + start); 704 ADVANCE_LP_RING(); 705 } 706} 707 708static void i810_dma_dispatch_vertex(struct drm_device *dev, 709 struct drm_buf *buf, int discard, int used) 710{ 711 drm_i810_private_t *dev_priv = dev->dev_private; 712 drm_i810_buf_priv_t *buf_priv = buf->dev_private; 713 drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; 714 struct drm_clip_rect *box = sarea_priv->boxes; 715 int nbox = sarea_priv->nbox; 716 unsigned long address = (unsigned long)buf->bus_address; 717 unsigned long start = address - dev->agp->base; 718 int i = 0; 719 RING_LOCALS; 720 721 i810_kernel_lost_context(dev); 722 723 if (nbox > I810_NR_SAREA_CLIPRECTS) 724 nbox = I810_NR_SAREA_CLIPRECTS; 725 726 if (used > 4 * 1024) 727 used = 0; 728 729 if (sarea_priv->dirty) 730 i810EmitState(dev); 731 732 if (buf_priv->currently_mapped == I810_BUF_MAPPED) { 733 unsigned int prim = (sarea_priv->vertex_prim & PR_MASK); 734 735 *(u32 *) buf_priv->kernel_virtual = 736 ((GFX_OP_PRIMITIVE | prim | ((used / 4) - 2))); 737 738 if (used & 4) { 739 *(u32 *) ((char *) buf_priv->kernel_virtual + used) = 0; 740 used += 4; 741 } 742 743 i810_unmap_buffer(buf); 744 } 745 746 if (used) { 747 do { 748 if (i < nbox) { 749 BEGIN_LP_RING(4); 750 OUT_RING(GFX_OP_SCISSOR | SC_UPDATE_SCISSOR | 751 SC_ENABLE); 752 OUT_RING(GFX_OP_SCISSOR_INFO); 753 OUT_RING(box[i].x1 | (box[i].y1 << 16)); 754 OUT_RING((box[i].x2 - 755 1) | ((box[i].y2 - 1) << 16)); 756 ADVANCE_LP_RING(); 757 } 758 759 BEGIN_LP_RING(4); 760 OUT_RING(CMD_OP_BATCH_BUFFER); 761 OUT_RING(start | BB1_PROTECTED); 762 OUT_RING(start + used - 4); 763 OUT_RING(0); 764 ADVANCE_LP_RING(); 765 766 } while (++i < nbox); 767 } 768 769 if (discard) { 770 dev_priv->counter++; 771 772 (void)cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, 773 I810_BUF_HARDWARE); 774 775 BEGIN_LP_RING(8); 776 OUT_RING(CMD_STORE_DWORD_IDX); 777 OUT_RING(20); 778 OUT_RING(dev_priv->counter); 779 OUT_RING(CMD_STORE_DWORD_IDX); 780 OUT_RING(buf_priv->my_use_idx); 781 OUT_RING(I810_BUF_FREE); 782 OUT_RING(CMD_REPORT_HEAD); 783 OUT_RING(0); 784 ADVANCE_LP_RING(); 785 } 786} 787 788static void i810_dma_dispatch_flip(struct drm_device *dev) 789{ 790 drm_i810_private_t *dev_priv = dev->dev_private; 791 int pitch = dev_priv->pitch; 792 RING_LOCALS; 793 794 DRM_DEBUG("page=%d pfCurrentPage=%d\n", 795 dev_priv->current_page, 796 dev_priv->sarea_priv->pf_current_page); 797 798 i810_kernel_lost_context(dev); 799 800 BEGIN_LP_RING(2); 801 OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); 802 OUT_RING(0); 803 ADVANCE_LP_RING(); 804 805 BEGIN_LP_RING(I810_DEST_SETUP_SIZE + 2); 806 /* On i815 at least ASYNC is buggy */ 807 /* pitch<<5 is from 11.2.8 p158, 808 its the pitch / 8 then left shifted 8, 809 so (pitch >> 3) << 8 */ 810 OUT_RING(CMD_OP_FRONTBUFFER_INFO | (pitch << 5) /*| ASYNC_FLIP */ ); 811 if (dev_priv->current_page == 0) { 812 OUT_RING(dev_priv->back_offset); 813 dev_priv->current_page = 1; 814 } else { 815 OUT_RING(dev_priv->front_offset); 816 dev_priv->current_page = 0; 817 } 818 OUT_RING(0); 819 ADVANCE_LP_RING(); 820 821 BEGIN_LP_RING(2); 822 OUT_RING(CMD_OP_WAIT_FOR_EVENT | WAIT_FOR_PLANE_A_FLIP); 823 OUT_RING(0); 824 ADVANCE_LP_RING(); 825 826 /* Increment the frame counter. The client-side 3D driver must 827 * throttle the framerate by waiting for this value before 828 * performing the swapbuffer ioctl. 829 */ 830 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; 831 832} 833 834static void i810_dma_quiescent(struct drm_device *dev) 835{ 836 drm_i810_private_t *dev_priv = dev->dev_private; 837 RING_LOCALS; 838 839 i810_kernel_lost_context(dev); 840 841 BEGIN_LP_RING(4); 842 OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE); 843 OUT_RING(CMD_REPORT_HEAD); 844 OUT_RING(0); 845 OUT_RING(0); 846 ADVANCE_LP_RING(); 847 848 i810_wait_ring(dev, dev_priv->ring.Size - 8); 849} 850 851static int i810_flush_queue(struct drm_device *dev) 852{ 853 drm_i810_private_t *dev_priv = dev->dev_private; 854 struct drm_device_dma *dma = dev->dma; 855 int i, ret = 0; 856 RING_LOCALS; 857 858 i810_kernel_lost_context(dev); 859 860 BEGIN_LP_RING(2); 861 OUT_RING(CMD_REPORT_HEAD); 862 OUT_RING(0); 863 ADVANCE_LP_RING(); 864 865 i810_wait_ring(dev, dev_priv->ring.Size - 8); 866 867 for (i = 0; i < dma->buf_count; i++) { 868 struct drm_buf *buf = dma->buflist[i]; 869 drm_i810_buf_priv_t *buf_priv = buf->dev_private; 870 871 int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE, 872 I810_BUF_FREE); 873 874 if (used == I810_BUF_HARDWARE) 875 DRM_DEBUG("reclaimed from HARDWARE\n"); 876 if (used == I810_BUF_CLIENT) 877 DRM_DEBUG("still on client\n"); 878 } 879 880 return ret; 881} 882 883/* Must be called with the lock held */ 884void i810_driver_reclaim_buffers(struct drm_device *dev, 885 struct drm_file *file_priv) 886{ 887 struct drm_device_dma *dma = dev->dma; 888 int i; 889 890 if (!dma) 891 return; 892 if (!dev->dev_private) 893 return; 894 if (!dma->buflist) 895 return; 896 897 i810_flush_queue(dev); 898 899 for (i = 0; i < dma->buf_count; i++) { 900 struct drm_buf *buf = dma->buflist[i]; 901 drm_i810_buf_priv_t *buf_priv = buf->dev_private; 902 903 if (buf->file_priv == file_priv && buf_priv) { 904 int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, 905 I810_BUF_FREE); 906 907 if (used == I810_BUF_CLIENT) 908 DRM_DEBUG("reclaimed from client\n"); 909 if (buf_priv->currently_mapped == I810_BUF_MAPPED) 910 buf_priv->currently_mapped = I810_BUF_UNMAPPED; 911 } 912 } 913} 914 915static int i810_flush_ioctl(struct drm_device *dev, void *data, 916 struct drm_file *file_priv) 917{ 918 LOCK_TEST_WITH_RETURN(dev, file_priv); 919 920 i810_flush_queue(dev); 921 return 0; 922} 923 924static int i810_dma_vertex(struct drm_device *dev, void *data, 925 struct drm_file *file_priv) 926{ 927 struct drm_device_dma *dma = dev->dma; 928 drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; 929 u32 *hw_status = dev_priv->hw_status_page; 930 drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) 931 dev_priv->sarea_priv; 932 drm_i810_vertex_t *vertex = data; 933 934 LOCK_TEST_WITH_RETURN(dev, file_priv); 935 936 DRM_DEBUG("idx %d used %d discard %d\n", 937 vertex->idx, vertex->used, vertex->discard); 938 939 if (vertex->idx < 0 || vertex->idx > dma->buf_count) 940 return -EINVAL; 941 942 i810_dma_dispatch_vertex(dev, 943 dma->buflist[vertex->idx], 944 vertex->discard, vertex->used); 945 946 sarea_priv->last_enqueue = dev_priv->counter - 1; 947 sarea_priv->last_dispatch = (int)hw_status[5]; 948 949 return 0; 950} 951 952static int i810_clear_bufs(struct drm_device *dev, void *data, 953 struct drm_file *file_priv) 954{ 955 drm_i810_clear_t *clear = data; 956 957 LOCK_TEST_WITH_RETURN(dev, file_priv); 958 959 /* GH: Someone's doing nasty things... */ 960 if (!dev->dev_private) 961 return -EINVAL; 962 963 i810_dma_dispatch_clear(dev, clear->flags, 964 clear->clear_color, clear->clear_depth); 965 return 0; 966} 967 968static int i810_swap_bufs(struct drm_device *dev, void *data, 969 struct drm_file *file_priv) 970{ 971 DRM_DEBUG("\n"); 972 973 LOCK_TEST_WITH_RETURN(dev, file_priv); 974 975 i810_dma_dispatch_swap(dev); 976 return 0; 977} 978 979static int i810_getage(struct drm_device *dev, void *data, 980 struct drm_file *file_priv) 981{ 982 drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; 983 u32 *hw_status = dev_priv->hw_status_page; 984 drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) 985 dev_priv->sarea_priv; 986 987 sarea_priv->last_dispatch = (int)hw_status[5]; 988 return 0; 989} 990 991static int i810_getbuf(struct drm_device *dev, void *data, 992 struct drm_file *file_priv) 993{ 994 int retcode = 0; 995 drm_i810_dma_t *d = data; 996 drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; 997 u32 *hw_status = dev_priv->hw_status_page; 998 drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) 999 dev_priv->sarea_priv; 1000 1001 LOCK_TEST_WITH_RETURN(dev, file_priv); 1002 1003 d->granted = 0; 1004 1005 retcode = i810_dma_get_buffer(dev, d, file_priv); 1006 1007 DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n", 1008 task_pid_nr(current), retcode, d->granted); 1009 1010 sarea_priv->last_dispatch = (int)hw_status[5]; 1011 1012 return retcode; 1013} 1014 1015static int i810_copybuf(struct drm_device *dev, void *data, 1016 struct drm_file *file_priv) 1017{ 1018 /* Never copy - 2.4.x doesn't need it */ 1019 return 0; 1020} 1021 1022static int i810_docopy(struct drm_device *dev, void *data, 1023 struct drm_file *file_priv) 1024{ 1025 /* Never copy - 2.4.x doesn't need it */ 1026 return 0; 1027} 1028 1029static void i810_dma_dispatch_mc(struct drm_device *dev, struct drm_buf *buf, int used, 1030 unsigned int last_render) 1031{ 1032 drm_i810_private_t *dev_priv = dev->dev_private; 1033 drm_i810_buf_priv_t *buf_priv = buf->dev_private; 1034 drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; 1035 unsigned long address = (unsigned long)buf->bus_address; 1036 unsigned long start = address - dev->agp->base; 1037 int u; 1038 RING_LOCALS; 1039 1040 i810_kernel_lost_context(dev); 1041 1042 u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_HARDWARE); 1043 if (u != I810_BUF_CLIENT) 1044 DRM_DEBUG("MC found buffer that isn't mine!\n"); 1045 1046 if (used > 4 * 1024) 1047 used = 0; 1048 1049 sarea_priv->dirty = 0x7f; 1050 1051 DRM_DEBUG("addr 0x%lx, used 0x%x\n", address, used); 1052 1053 dev_priv->counter++; 1054 DRM_DEBUG("dispatch counter : %ld\n", dev_priv->counter); 1055 DRM_DEBUG("start : %lx\n", start); 1056 DRM_DEBUG("used : %d\n", used); 1057 DRM_DEBUG("start + used - 4 : %ld\n", start + used - 4); 1058 1059 if (buf_priv->currently_mapped == I810_BUF_MAPPED) { 1060 if (used & 4) { 1061 *(u32 *) ((char *) buf_priv->virtual + used) = 0; 1062 used += 4; 1063 } 1064 1065 i810_unmap_buffer(buf); 1066 } 1067 BEGIN_LP_RING(4); 1068 OUT_RING(CMD_OP_BATCH_BUFFER); 1069 OUT_RING(start | BB1_PROTECTED); 1070 OUT_RING(start + used - 4); 1071 OUT_RING(0); 1072 ADVANCE_LP_RING(); 1073 1074 BEGIN_LP_RING(8); 1075 OUT_RING(CMD_STORE_DWORD_IDX); 1076 OUT_RING(buf_priv->my_use_idx); 1077 OUT_RING(I810_BUF_FREE); 1078 OUT_RING(0); 1079 1080 OUT_RING(CMD_STORE_DWORD_IDX); 1081 OUT_RING(16); 1082 OUT_RING(last_render); 1083 OUT_RING(0); 1084 ADVANCE_LP_RING(); 1085} 1086 1087static int i810_dma_mc(struct drm_device *dev, void *data, 1088 struct drm_file *file_priv) 1089{ 1090 struct drm_device_dma *dma = dev->dma; 1091 drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; 1092 u32 *hw_status = dev_priv->hw_status_page; 1093 drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *) 1094 dev_priv->sarea_priv; 1095 drm_i810_mc_t *mc = data; 1096 1097 LOCK_TEST_WITH_RETURN(dev, file_priv); 1098 1099 if (mc->idx >= dma->buf_count || mc->idx < 0) 1100 return -EINVAL; 1101 1102 i810_dma_dispatch_mc(dev, dma->buflist[mc->idx], mc->used, 1103 mc->last_render); 1104 1105 sarea_priv->last_enqueue = dev_priv->counter - 1; 1106 sarea_priv->last_dispatch = (int)hw_status[5]; 1107 1108 return 0; 1109} 1110 1111static int i810_rstatus(struct drm_device *dev, void *data, 1112 struct drm_file *file_priv) 1113{ 1114 drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; 1115 1116 return (int)(((u32 *) (dev_priv->hw_status_page))[4]); 1117} 1118 1119static int i810_ov0_info(struct drm_device *dev, void *data, 1120 struct drm_file *file_priv) 1121{ 1122 drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; 1123 drm_i810_overlay_t *ov = data; 1124 1125 ov->offset = dev_priv->overlay_offset; 1126 ov->physical = dev_priv->overlay_physical; 1127 1128 return 0; 1129} 1130 1131static int i810_fstatus(struct drm_device *dev, void *data, 1132 struct drm_file *file_priv) 1133{ 1134 drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; 1135 1136 LOCK_TEST_WITH_RETURN(dev, file_priv); 1137 return I810_READ(0x30008); 1138} 1139 1140static int i810_ov0_flip(struct drm_device *dev, void *data, 1141 struct drm_file *file_priv) 1142{ 1143 drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; 1144 1145 LOCK_TEST_WITH_RETURN(dev, file_priv); 1146 1147 /* Tell the overlay to update */ 1148 I810_WRITE(0x30000, dev_priv->overlay_physical | 0x80000000); 1149 1150 return 0; 1151} 1152 1153/* Not sure why this isn't set all the time: 1154 */ 1155static void i810_do_init_pageflip(struct drm_device *dev) 1156{ 1157 drm_i810_private_t *dev_priv = dev->dev_private; 1158 1159 DRM_DEBUG("\n"); 1160 dev_priv->page_flipping = 1; 1161 dev_priv->current_page = 0; 1162 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page; 1163} 1164 1165static int i810_do_cleanup_pageflip(struct drm_device *dev) 1166{ 1167 drm_i810_private_t *dev_priv = dev->dev_private; 1168 1169 DRM_DEBUG("\n"); 1170 if (dev_priv->current_page != 0) 1171 i810_dma_dispatch_flip(dev); 1172 1173 dev_priv->page_flipping = 0; 1174 return 0; 1175} 1176 1177static int i810_flip_bufs(struct drm_device *dev, void *data, 1178 struct drm_file *file_priv) 1179{ 1180 drm_i810_private_t *dev_priv = dev->dev_private; 1181 1182 DRM_DEBUG("\n"); 1183 1184 LOCK_TEST_WITH_RETURN(dev, file_priv); 1185 1186 if (!dev_priv->page_flipping) 1187 i810_do_init_pageflip(dev); 1188 1189 i810_dma_dispatch_flip(dev); 1190 return 0; 1191} 1192 1193int i810_driver_load(struct drm_device *dev, unsigned long flags) 1194{ 1195 /* Our userspace depends upon the agp mapping support. */ 1196 if (!dev->agp) 1197 return -EINVAL; 1198 1199 pci_set_master(dev->pdev); 1200 1201 return 0; 1202} 1203 1204void i810_driver_lastclose(struct drm_device *dev) 1205{ 1206 i810_dma_cleanup(dev); 1207} 1208 1209void i810_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) 1210{ 1211 if (dev->dev_private) { 1212 drm_i810_private_t *dev_priv = dev->dev_private; 1213 if (dev_priv->page_flipping) 1214 i810_do_cleanup_pageflip(dev); 1215 } 1216 1217 if (file_priv->master && file_priv->master->lock.hw_lock) { 1218 drm_legacy_idlelock_take(&file_priv->master->lock); 1219 i810_driver_reclaim_buffers(dev, file_priv); 1220 drm_legacy_idlelock_release(&file_priv->master->lock); 1221 } else { 1222 /* master disappeared, clean up stuff anyway and hope nothing 1223 * goes wrong */ 1224 i810_driver_reclaim_buffers(dev, file_priv); 1225 } 1226 1227} 1228 1229int i810_driver_dma_quiescent(struct drm_device *dev) 1230{ 1231 i810_dma_quiescent(dev); 1232 return 0; 1233} 1234 1235const struct drm_ioctl_desc i810_ioctls[] = { 1236 DRM_IOCTL_DEF_DRV(I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), 1237 DRM_IOCTL_DEF_DRV(I810_VERTEX, i810_dma_vertex, DRM_AUTH|DRM_UNLOCKED), 1238 DRM_IOCTL_DEF_DRV(I810_CLEAR, i810_clear_bufs, DRM_AUTH|DRM_UNLOCKED), 1239 DRM_IOCTL_DEF_DRV(I810_FLUSH, i810_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), 1240 DRM_IOCTL_DEF_DRV(I810_GETAGE, i810_getage, DRM_AUTH|DRM_UNLOCKED), 1241 DRM_IOCTL_DEF_DRV(I810_GETBUF, i810_getbuf, DRM_AUTH|DRM_UNLOCKED), 1242 DRM_IOCTL_DEF_DRV(I810_SWAP, i810_swap_bufs, DRM_AUTH|DRM_UNLOCKED), 1243 DRM_IOCTL_DEF_DRV(I810_COPY, i810_copybuf, DRM_AUTH|DRM_UNLOCKED), 1244 DRM_IOCTL_DEF_DRV(I810_DOCOPY, i810_docopy, DRM_AUTH|DRM_UNLOCKED), 1245 DRM_IOCTL_DEF_DRV(I810_OV0INFO, i810_ov0_info, DRM_AUTH|DRM_UNLOCKED), 1246 DRM_IOCTL_DEF_DRV(I810_FSTATUS, i810_fstatus, DRM_AUTH|DRM_UNLOCKED), 1247 DRM_IOCTL_DEF_DRV(I810_OV0FLIP, i810_ov0_flip, DRM_AUTH|DRM_UNLOCKED), 1248 DRM_IOCTL_DEF_DRV(I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), 1249 DRM_IOCTL_DEF_DRV(I810_RSTATUS, i810_rstatus, DRM_AUTH|DRM_UNLOCKED), 1250 DRM_IOCTL_DEF_DRV(I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED), 1251}; 1252 1253int i810_max_ioctl = ARRAY_SIZE(i810_ioctls); 1254 1255/** 1256 * Determine if the device really is AGP or not. 1257 * 1258 * All Intel graphics chipsets are treated as AGP, even if they are really 1259 * PCI-e. 1260 * 1261 * \param dev The device to be tested. 1262 * 1263 * \returns 1264 * A value of 1 is always retured to indictate every i810 is AGP. 1265 */ 1266int i810_driver_device_is_agp(struct drm_device *dev) 1267{ 1268 return 1; 1269} 1270