aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_dma.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2009-04-05 02:14:15 -0400
committerLen Brown <len.brown@intel.com>2009-04-05 02:14:15 -0400
commit478c6a43fcbc6c11609f8cee7c7b57223907754f (patch)
treea7f7952099da60d33032aed6de9c0c56c9f8779e /drivers/gpu/drm/i915/i915_dma.c
parent8a3f257c704e02aee9869decd069a806b45be3f1 (diff)
parent6bb597507f9839b13498781e481f5458aea33620 (diff)
Merge branch 'linus' into release
Conflicts: arch/x86/kernel/cpu/cpufreq/longhaul.c Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_dma.c')
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c129
1 files changed, 82 insertions, 47 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 638686904e0..a000cf02882 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -41,7 +41,6 @@
41int i915_wait_ring(struct drm_device * dev, int n, const char *caller) 41int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
42{ 42{
43 drm_i915_private_t *dev_priv = dev->dev_private; 43 drm_i915_private_t *dev_priv = dev->dev_private;
44 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
45 drm_i915_ring_buffer_t *ring = &(dev_priv->ring); 44 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
46 u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD; 45 u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
47 u32 last_acthd = I915_READ(acthd_reg); 46 u32 last_acthd = I915_READ(acthd_reg);
@@ -58,8 +57,12 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
58 if (ring->space >= n) 57 if (ring->space >= n)
59 return 0; 58 return 0;
60 59
61 if (master_priv->sarea_priv) 60 if (dev->primary->master) {
62 master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; 61 struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
62 if (master_priv->sarea_priv)
63 master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
64 }
65
63 66
64 if (ring->head != last_head) 67 if (ring->head != last_head)
65 i = 0; 68 i = 0;
@@ -356,7 +359,7 @@ static int validate_cmd(int cmd)
356 return ret; 359 return ret;
357} 360}
358 361
359static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwords) 362static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords)
360{ 363{
361 drm_i915_private_t *dev_priv = dev->dev_private; 364 drm_i915_private_t *dev_priv = dev->dev_private;
362 int i; 365 int i;
@@ -370,8 +373,7 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor
370 for (i = 0; i < dwords;) { 373 for (i = 0; i < dwords;) {
371 int cmd, sz; 374 int cmd, sz;
372 375
373 if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) 376 cmd = buffer[i];
374 return -EINVAL;
375 377
376 if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) 378 if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords)
377 return -EINVAL; 379 return -EINVAL;
@@ -379,11 +381,7 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor
379 OUT_RING(cmd); 381 OUT_RING(cmd);
380 382
381 while (++i, --sz) { 383 while (++i, --sz) {
382 if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], 384 OUT_RING(buffer[i]);
383 sizeof(cmd))) {
384 return -EINVAL;
385 }
386 OUT_RING(cmd);
387 } 385 }
388 } 386 }
389 387
@@ -397,17 +395,13 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor
397 395
398int 396int
399i915_emit_box(struct drm_device *dev, 397i915_emit_box(struct drm_device *dev,
400 struct drm_clip_rect __user *boxes, 398 struct drm_clip_rect *boxes,
401 int i, int DR1, int DR4) 399 int i, int DR1, int DR4)
402{ 400{
403 drm_i915_private_t *dev_priv = dev->dev_private; 401 drm_i915_private_t *dev_priv = dev->dev_private;
404 struct drm_clip_rect box; 402 struct drm_clip_rect box = boxes[i];
405 RING_LOCALS; 403 RING_LOCALS;
406 404
407 if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) {
408 return -EFAULT;
409 }
410
411 if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { 405 if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) {
412 DRM_ERROR("Bad box %d,%d..%d,%d\n", 406 DRM_ERROR("Bad box %d,%d..%d,%d\n",
413 box.x1, box.y1, box.x2, box.y2); 407 box.x1, box.y1, box.x2, box.y2);
@@ -460,7 +454,9 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
460} 454}
461 455
462static int i915_dispatch_cmdbuffer(struct drm_device * dev, 456static int i915_dispatch_cmdbuffer(struct drm_device * dev,
463 drm_i915_cmdbuffer_t * cmd) 457 drm_i915_cmdbuffer_t *cmd,
458 struct drm_clip_rect *cliprects,
459 void *cmdbuf)
464{ 460{
465 int nbox = cmd->num_cliprects; 461 int nbox = cmd->num_cliprects;
466 int i = 0, count, ret; 462 int i = 0, count, ret;
@@ -476,13 +472,13 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev,
476 472
477 for (i = 0; i < count; i++) { 473 for (i = 0; i < count; i++) {
478 if (i < nbox) { 474 if (i < nbox) {
479 ret = i915_emit_box(dev, cmd->cliprects, i, 475 ret = i915_emit_box(dev, cliprects, i,
480 cmd->DR1, cmd->DR4); 476 cmd->DR1, cmd->DR4);
481 if (ret) 477 if (ret)
482 return ret; 478 return ret;
483 } 479 }
484 480
485 ret = i915_emit_cmds(dev, (int __user *)cmd->buf, cmd->sz / 4); 481 ret = i915_emit_cmds(dev, cmdbuf, cmd->sz / 4);
486 if (ret) 482 if (ret)
487 return ret; 483 return ret;
488 } 484 }
@@ -492,10 +488,10 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev,
492} 488}
493 489
494static int i915_dispatch_batchbuffer(struct drm_device * dev, 490static int i915_dispatch_batchbuffer(struct drm_device * dev,
495 drm_i915_batchbuffer_t * batch) 491 drm_i915_batchbuffer_t * batch,
492 struct drm_clip_rect *cliprects)
496{ 493{
497 drm_i915_private_t *dev_priv = dev->dev_private; 494 drm_i915_private_t *dev_priv = dev->dev_private;
498 struct drm_clip_rect __user *boxes = batch->cliprects;
499 int nbox = batch->num_cliprects; 495 int nbox = batch->num_cliprects;
500 int i = 0, count; 496 int i = 0, count;
501 RING_LOCALS; 497 RING_LOCALS;
@@ -511,7 +507,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
511 507
512 for (i = 0; i < count; i++) { 508 for (i = 0; i < count; i++) {
513 if (i < nbox) { 509 if (i < nbox) {
514 int ret = i915_emit_box(dev, boxes, i, 510 int ret = i915_emit_box(dev, cliprects, i,
515 batch->DR1, batch->DR4); 511 batch->DR1, batch->DR4);
516 if (ret) 512 if (ret)
517 return ret; 513 return ret;
@@ -626,6 +622,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
626 master_priv->sarea_priv; 622 master_priv->sarea_priv;
627 drm_i915_batchbuffer_t *batch = data; 623 drm_i915_batchbuffer_t *batch = data;
628 int ret; 624 int ret;
625 struct drm_clip_rect *cliprects = NULL;
629 626
630 if (!dev_priv->allow_batchbuffer) { 627 if (!dev_priv->allow_batchbuffer) {
631 DRM_ERROR("Batchbuffer ioctl disabled\n"); 628 DRM_ERROR("Batchbuffer ioctl disabled\n");
@@ -637,17 +634,35 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
637 634
638 RING_LOCK_TEST_WITH_RETURN(dev, file_priv); 635 RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
639 636
640 if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects, 637 if (batch->num_cliprects < 0)
641 batch->num_cliprects * 638 return -EINVAL;
642 sizeof(struct drm_clip_rect))) 639
643 return -EFAULT; 640 if (batch->num_cliprects) {
641 cliprects = drm_calloc(batch->num_cliprects,
642 sizeof(struct drm_clip_rect),
643 DRM_MEM_DRIVER);
644 if (cliprects == NULL)
645 return -ENOMEM;
646
647 ret = copy_from_user(cliprects, batch->cliprects,
648 batch->num_cliprects *
649 sizeof(struct drm_clip_rect));
650 if (ret != 0)
651 goto fail_free;
652 }
644 653
645 mutex_lock(&dev->struct_mutex); 654 mutex_lock(&dev->struct_mutex);
646 ret = i915_dispatch_batchbuffer(dev, batch); 655 ret = i915_dispatch_batchbuffer(dev, batch, cliprects);
647 mutex_unlock(&dev->struct_mutex); 656 mutex_unlock(&dev->struct_mutex);
648 657
649 if (sarea_priv) 658 if (sarea_priv)
650 sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); 659 sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
660
661fail_free:
662 drm_free(cliprects,
663 batch->num_cliprects * sizeof(struct drm_clip_rect),
664 DRM_MEM_DRIVER);
665
651 return ret; 666 return ret;
652} 667}
653 668
@@ -659,6 +674,8 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
659 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 674 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
660 master_priv->sarea_priv; 675 master_priv->sarea_priv;
661 drm_i915_cmdbuffer_t *cmdbuf = data; 676 drm_i915_cmdbuffer_t *cmdbuf = data;
677 struct drm_clip_rect *cliprects = NULL;
678 void *batch_data;
662 int ret; 679 int ret;
663 680
664 DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n", 681 DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
@@ -666,25 +683,50 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
666 683
667 RING_LOCK_TEST_WITH_RETURN(dev, file_priv); 684 RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
668 685
669 if (cmdbuf->num_cliprects && 686 if (cmdbuf->num_cliprects < 0)
670 DRM_VERIFYAREA_READ(cmdbuf->cliprects, 687 return -EINVAL;
671 cmdbuf->num_cliprects * 688
672 sizeof(struct drm_clip_rect))) { 689 batch_data = drm_alloc(cmdbuf->sz, DRM_MEM_DRIVER);
673 DRM_ERROR("Fault accessing cliprects\n"); 690 if (batch_data == NULL)
674 return -EFAULT; 691 return -ENOMEM;
692
693 ret = copy_from_user(batch_data, cmdbuf->buf, cmdbuf->sz);
694 if (ret != 0)
695 goto fail_batch_free;
696
697 if (cmdbuf->num_cliprects) {
698 cliprects = drm_calloc(cmdbuf->num_cliprects,
699 sizeof(struct drm_clip_rect),
700 DRM_MEM_DRIVER);
701 if (cliprects == NULL)
702 goto fail_batch_free;
703
704 ret = copy_from_user(cliprects, cmdbuf->cliprects,
705 cmdbuf->num_cliprects *
706 sizeof(struct drm_clip_rect));
707 if (ret != 0)
708 goto fail_clip_free;
675 } 709 }
676 710
677 mutex_lock(&dev->struct_mutex); 711 mutex_lock(&dev->struct_mutex);
678 ret = i915_dispatch_cmdbuffer(dev, cmdbuf); 712 ret = i915_dispatch_cmdbuffer(dev, cmdbuf, cliprects, batch_data);
679 mutex_unlock(&dev->struct_mutex); 713 mutex_unlock(&dev->struct_mutex);
680 if (ret) { 714 if (ret) {
681 DRM_ERROR("i915_dispatch_cmdbuffer failed\n"); 715 DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
682 return ret; 716 goto fail_batch_free;
683 } 717 }
684 718
685 if (sarea_priv) 719 if (sarea_priv)
686 sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); 720 sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
687 return 0; 721
722fail_batch_free:
723 drm_free(batch_data, cmdbuf->sz, DRM_MEM_DRIVER);
724fail_clip_free:
725 drm_free(cliprects,
726 cmdbuf->num_cliprects * sizeof(struct drm_clip_rect),
727 DRM_MEM_DRIVER);
728
729 return ret;
688} 730}
689 731
690static int i915_flip_bufs(struct drm_device *dev, void *data, 732static int i915_flip_bufs(struct drm_device *dev, void *data,
@@ -880,7 +922,7 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size,
880 * Some of the preallocated space is taken by the GTT 922 * Some of the preallocated space is taken by the GTT
881 * and popup. GTT is 1K per MB of aperture size, and popup is 4K. 923 * and popup. GTT is 1K per MB of aperture size, and popup is 4K.
882 */ 924 */
883 if (IS_G4X(dev)) 925 if (IS_G4X(dev) || IS_IGD(dev))
884 overhead = 4096; 926 overhead = 4096;
885 else 927 else
886 overhead = (*aperture_size / 1024) + 4096; 928 overhead = (*aperture_size / 1024) + 4096;
@@ -988,13 +1030,6 @@ static int i915_load_modeset_init(struct drm_device *dev)
988 if (ret) 1030 if (ret)
989 goto destroy_ringbuffer; 1031 goto destroy_ringbuffer;
990 1032
991 /* FIXME: re-add hotplug support */
992#if 0
993 ret = drm_hotplug_init(dev);
994 if (ret)
995 goto destroy_ringbuffer;
996#endif
997
998 /* Always safe in the mode setting case. */ 1033 /* Always safe in the mode setting case. */
999 /* FIXME: do pre/post-mode set stuff in core KMS code */ 1034 /* FIXME: do pre/post-mode set stuff in core KMS code */
1000 dev->vblank_disable_allowed = 1; 1035 dev->vblank_disable_allowed = 1;
@@ -1007,7 +1042,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
1007 1042
1008 intel_modeset_init(dev); 1043 intel_modeset_init(dev);
1009 1044
1010 drm_helper_initial_config(dev, false); 1045 drm_helper_initial_config(dev);
1011 1046
1012 return 0; 1047 return 0;
1013 1048
@@ -1057,7 +1092,7 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master)
1057int i915_driver_load(struct drm_device *dev, unsigned long flags) 1092int i915_driver_load(struct drm_device *dev, unsigned long flags)
1058{ 1093{
1059 struct drm_i915_private *dev_priv = dev->dev_private; 1094 struct drm_i915_private *dev_priv = dev->dev_private;
1060 unsigned long base, size; 1095 resource_size_t base, size;
1061 int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1; 1096 int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1;
1062 1097
1063 /* i915 has 4 more counters */ 1098 /* i915 has 4 more counters */