aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/i915_dma.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2008-05-06 22:15:39 -0400
committerDave Airlie <airlied@linux.ie>2008-05-06 22:15:39 -0400
commitaf6061af0d9f84a4665f88186dc1ff9e4fb78330 (patch)
tree90281b9188338cc702f92329ed3725313d248eea /drivers/char/drm/i915_dma.c
parentc0a18111e571138747a98af18b3a2124df56a0d1 (diff)
Revert "drm/vbl rework: rework how the drm deals with vblank."
This reverts commit ac741ab71bb39e6977694ac0cc26678d8673cda4. Okay this looks like wasn't as fully baked as I'd led myself to believe. Revert for now for further baking. Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/char/drm/i915_dma.c')
-rw-r--r--drivers/char/drm/i915_dma.c160
1 files changed, 41 insertions, 119 deletions
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index f47e46e3529f..88974342933c 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -415,13 +415,10 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
415 drm_i915_private_t *dev_priv = dev->dev_private; 415 drm_i915_private_t *dev_priv = dev->dev_private;
416 RING_LOCALS; 416 RING_LOCALS;
417 417
418 if (++dev_priv->counter > BREADCRUMB_MASK) { 418 dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
419 dev_priv->counter = 1;
420 DRM_DEBUG("Breadcrumb counter wrapped around\n");
421 }
422 419
423 if (dev_priv->sarea_priv) 420 if (dev_priv->counter > 0x7FFFFFFFUL)
424 dev_priv->sarea_priv->last_enqueue = dev_priv->counter; 421 dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
425 422
426 BEGIN_LP_RING(4); 423 BEGIN_LP_RING(4);
427 OUT_RING(CMD_STORE_DWORD_IDX); 424 OUT_RING(CMD_STORE_DWORD_IDX);
@@ -431,26 +428,6 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
431 ADVANCE_LP_RING(); 428 ADVANCE_LP_RING();
432} 429}
433 430
434int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush)
435{
436 drm_i915_private_t *dev_priv = dev->dev_private;
437 uint32_t flush_cmd = CMD_MI_FLUSH;
438 RING_LOCALS;
439
440 flush_cmd |= flush;
441
442 i915_kernel_lost_context(dev);
443
444 BEGIN_LP_RING(4);
445 OUT_RING(flush_cmd);
446 OUT_RING(0);
447 OUT_RING(0);
448 OUT_RING(0);
449 ADVANCE_LP_RING();
450
451 return 0;
452}
453
454static int i915_dispatch_cmdbuffer(struct drm_device * dev, 431static int i915_dispatch_cmdbuffer(struct drm_device * dev,
455 drm_i915_cmdbuffer_t * cmd) 432 drm_i915_cmdbuffer_t * cmd)
456{ 433{
@@ -534,74 +511,52 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
534 return 0; 511 return 0;
535} 512}
536 513
537static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync) 514static int i915_dispatch_flip(struct drm_device * dev)
538{ 515{
539 drm_i915_private_t *dev_priv = dev->dev_private; 516 drm_i915_private_t *dev_priv = dev->dev_private;
540 u32 num_pages, current_page, next_page, dspbase;
541 int shift = 2 * plane, x, y;
542 RING_LOCALS; 517 RING_LOCALS;
543 518
544 /* Calculate display base offset */ 519 DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
545 num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2; 520 __FUNCTION__,
546 current_page = (dev_priv->sarea_priv->pf_current_page >> shift) & 0x3; 521 dev_priv->current_page,
547 next_page = (current_page + 1) % num_pages; 522 dev_priv->sarea_priv->pf_current_page);
548 523
549 switch (next_page) { 524 i915_kernel_lost_context(dev);
550 default: 525
551 case 0: 526 BEGIN_LP_RING(2);
552 dspbase = dev_priv->sarea_priv->front_offset; 527 OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
553 break; 528 OUT_RING(0);
554 case 1: 529 ADVANCE_LP_RING();
555 dspbase = dev_priv->sarea_priv->back_offset;
556 break;
557 case 2:
558 dspbase = dev_priv->sarea_priv->third_offset;
559 break;
560 }
561 530
562 if (plane == 0) { 531 BEGIN_LP_RING(6);
563 x = dev_priv->sarea_priv->planeA_x; 532 OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP);
564 y = dev_priv->sarea_priv->planeA_y; 533 OUT_RING(0);
534 if (dev_priv->current_page == 0) {
535 OUT_RING(dev_priv->back_offset);
536 dev_priv->current_page = 1;
565 } else { 537 } else {
566 x = dev_priv->sarea_priv->planeB_x; 538 OUT_RING(dev_priv->front_offset);
567 y = dev_priv->sarea_priv->planeB_y; 539 dev_priv->current_page = 0;
568 } 540 }
541 OUT_RING(0);
542 ADVANCE_LP_RING();
569 543
570 dspbase += (y * dev_priv->sarea_priv->pitch + x) * dev_priv->cpp; 544 BEGIN_LP_RING(2);
545 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP);
546 OUT_RING(0);
547 ADVANCE_LP_RING();
571 548
572 DRM_DEBUG("plane=%d current_page=%d dspbase=0x%x\n", plane, current_page, 549 dev_priv->sarea_priv->last_enqueue = dev_priv->counter++;
573 dspbase);
574 550
575 BEGIN_LP_RING(4); 551 BEGIN_LP_RING(4);
576 OUT_RING(sync ? 0 : 552 OUT_RING(CMD_STORE_DWORD_IDX);
577 (MI_WAIT_FOR_EVENT | (plane ? MI_WAIT_FOR_PLANE_B_FLIP : 553 OUT_RING(20);
578 MI_WAIT_FOR_PLANE_A_FLIP))); 554 OUT_RING(dev_priv->counter);
579 OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | (sync ? 0 : ASYNC_FLIP) | 555 OUT_RING(0);
580 (plane ? DISPLAY_PLANE_B : DISPLAY_PLANE_A));
581 OUT_RING(dev_priv->sarea_priv->pitch * dev_priv->cpp);
582 OUT_RING(dspbase);
583 ADVANCE_LP_RING(); 556 ADVANCE_LP_RING();
584 557
585 dev_priv->sarea_priv->pf_current_page &= ~(0x3 << shift); 558 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
586 dev_priv->sarea_priv->pf_current_page |= next_page << shift; 559 return 0;
587}
588
589void i915_dispatch_flip(struct drm_device * dev, int planes, int sync)
590{
591 drm_i915_private_t *dev_priv = dev->dev_private;
592 int i;
593
594 DRM_DEBUG("planes=0x%x pfCurrentPage=%d\n",
595 planes, dev_priv->sarea_priv->pf_current_page);
596
597 i915_emit_mi_flush(dev, MI_READ_FLUSH | MI_EXE_FLUSH);
598
599 for (i = 0; i < 2; i++)
600 if (planes & (1 << i))
601 i915_do_dispatch_flip(dev, i, sync);
602
603 i915_emit_breadcrumb(dev);
604
605} 560}
606 561
607static int i915_quiescent(struct drm_device * dev) 562static int i915_quiescent(struct drm_device * dev)
@@ -624,6 +579,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
624 struct drm_file *file_priv) 579 struct drm_file *file_priv)
625{ 580{
626 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 581 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
582 u32 *hw_status = dev_priv->hw_status_page;
627 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 583 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
628 dev_priv->sarea_priv; 584 dev_priv->sarea_priv;
629 drm_i915_batchbuffer_t *batch = data; 585 drm_i915_batchbuffer_t *batch = data;
@@ -646,7 +602,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
646 602
647 ret = i915_dispatch_batchbuffer(dev, batch); 603 ret = i915_dispatch_batchbuffer(dev, batch);
648 604
649 sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); 605 sarea_priv->last_dispatch = (int)hw_status[5];
650 return ret; 606 return ret;
651} 607}
652 608
@@ -654,6 +610,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
654 struct drm_file *file_priv) 610 struct drm_file *file_priv)
655{ 611{
656 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 612 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
613 u32 *hw_status = dev_priv->hw_status_page;
657 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *) 614 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
658 dev_priv->sarea_priv; 615 dev_priv->sarea_priv;
659 drm_i915_cmdbuffer_t *cmdbuf = data; 616 drm_i915_cmdbuffer_t *cmdbuf = data;
@@ -678,51 +635,18 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
678 return ret; 635 return ret;
679 } 636 }
680 637
681 sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); 638 sarea_priv->last_dispatch = (int)hw_status[5];
682 return 0;
683}
684
685static int i915_do_cleanup_pageflip(struct drm_device * dev)
686{
687 drm_i915_private_t *dev_priv = dev->dev_private;
688 int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
689
690 DRM_DEBUG("\n");
691
692 for (i = 0, planes = 0; i < 2; i++)
693 if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) {
694 dev_priv->sarea_priv->pf_current_page =
695 (dev_priv->sarea_priv->pf_current_page &
696 ~(0x3 << (2 * i))) | ((num_pages - 1) << (2 * i));
697
698 planes |= 1 << i;
699 }
700
701 if (planes)
702 i915_dispatch_flip(dev, planes, 0);
703
704 return 0; 639 return 0;
705} 640}
706 641
707static int i915_flip_bufs(struct drm_device *dev, void *data, 642static int i915_flip_bufs(struct drm_device *dev, void *data,
708 struct drm_file *file_priv) 643 struct drm_file *file_priv)
709{ 644{
710 drm_i915_flip_t *param = data; 645 DRM_DEBUG("%s\n", __FUNCTION__);
711
712 DRM_DEBUG("\n");
713 646
714 LOCK_TEST_WITH_RETURN(dev, file_priv); 647 LOCK_TEST_WITH_RETURN(dev, file_priv);
715 648
716 /* This is really planes */ 649 return i915_dispatch_flip(dev);
717 if (param->pipes & ~0x3) {
718 DRM_ERROR("Invalid planes 0x%x, only <= 0x3 is valid\n",
719 param->pipes);
720 return -EINVAL;
721 }
722
723 i915_dispatch_flip(dev, param->pipes, 0);
724
725 return 0;
726} 650}
727 651
728static int i915_getparam(struct drm_device *dev, void *data, 652static int i915_getparam(struct drm_device *dev, void *data,
@@ -883,8 +807,6 @@ void i915_driver_lastclose(struct drm_device * dev)
883 if (!dev_priv) 807 if (!dev_priv)
884 return; 808 return;
885 809
886 if (drm_getsarea(dev) && dev_priv->sarea_priv)
887 i915_do_cleanup_pageflip(dev);
888 if (dev_priv->agp_heap) 810 if (dev_priv->agp_heap)
889 i915_mem_takedown(&(dev_priv->agp_heap)); 811 i915_mem_takedown(&(dev_priv->agp_heap));
890 812