aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/radeon/radeon.h3
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c181
2 files changed, 93 insertions, 91 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 29d9cc04c04e..b7204500a9a6 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -684,10 +684,9 @@ struct radeon_flip_work {
684 struct work_struct unpin_work; 684 struct work_struct unpin_work;
685 struct radeon_device *rdev; 685 struct radeon_device *rdev;
686 int crtc_id; 686 int crtc_id;
687 struct drm_framebuffer *fb; 687 uint64_t base;
688 struct drm_pending_vblank_event *event; 688 struct drm_pending_vblank_event *event;
689 struct radeon_bo *old_rbo; 689 struct radeon_bo *old_rbo;
690 struct radeon_bo *new_rbo;
691 struct radeon_fence *fence; 690 struct radeon_fence *fence;
692}; 691};
693 692
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 65501af453be..8de579473645 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -386,11 +386,6 @@ static void radeon_flip_work_func(struct work_struct *__work)
386 struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[work->crtc_id]; 386 struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[work->crtc_id];
387 387
388 struct drm_crtc *crtc = &radeon_crtc->base; 388 struct drm_crtc *crtc = &radeon_crtc->base;
389 struct drm_framebuffer *fb = work->fb;
390
391 uint32_t tiling_flags, pitch_pixels;
392 uint64_t base;
393
394 unsigned long flags; 389 unsigned long flags;
395 int r; 390 int r;
396 391
@@ -411,26 +406,94 @@ static void radeon_flip_work_func(struct work_struct *__work)
411 radeon_fence_unref(&work->fence); 406 radeon_fence_unref(&work->fence);
412 } 407 }
413 408
409 /* do the flip (mmio) */
410 radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base);
411
412 /* We borrow the event spin lock for protecting flip_status */
413 spin_lock_irqsave(&crtc->dev->event_lock, flags);
414
415 /* set the proper interrupt */
416 radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id);
417
418 radeon_crtc->flip_status = RADEON_FLIP_SUBMITTED;
419 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
420 up_read(&rdev->exclusive_lock);
421
422 return;
423
424cleanup:
425 drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
426 radeon_fence_unref(&work->fence);
427 kfree(work);
428 up_read(&rdev->exclusive_lock);
429}
430
431static int radeon_crtc_page_flip(struct drm_crtc *crtc,
432 struct drm_framebuffer *fb,
433 struct drm_pending_vblank_event *event,
434 uint32_t page_flip_flags)
435{
436 struct drm_device *dev = crtc->dev;
437 struct radeon_device *rdev = dev->dev_private;
438 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
439 struct radeon_framebuffer *old_radeon_fb;
440 struct radeon_framebuffer *new_radeon_fb;
441 struct drm_gem_object *obj;
442 struct radeon_flip_work *work;
443 struct radeon_bo *new_rbo;
444 uint32_t tiling_flags, pitch_pixels;
445 uint64_t base;
446 unsigned long flags;
447 int r;
448
449 work = kzalloc(sizeof *work, GFP_KERNEL);
450 if (work == NULL)
451 return -ENOMEM;
452
453 INIT_WORK(&work->flip_work, radeon_flip_work_func);
454 INIT_WORK(&work->unpin_work, radeon_unpin_work_func);
455
456 work->rdev = rdev;
457 work->crtc_id = radeon_crtc->crtc_id;
458 work->event = event;
459
460 /* schedule unpin of the old buffer */
461 old_radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
462 obj = old_radeon_fb->obj;
463
464 /* take a reference to the old object */
465 drm_gem_object_reference(obj);
466 work->old_rbo = gem_to_radeon_bo(obj);
467
468 new_radeon_fb = to_radeon_framebuffer(fb);
469 obj = new_radeon_fb->obj;
470 new_rbo = gem_to_radeon_bo(obj);
471
472 spin_lock(&new_rbo->tbo.bdev->fence_lock);
473 if (new_rbo->tbo.sync_obj)
474 work->fence = radeon_fence_ref(new_rbo->tbo.sync_obj);
475 spin_unlock(&new_rbo->tbo.bdev->fence_lock);
476
414 /* pin the new buffer */ 477 /* pin the new buffer */
415 DRM_DEBUG_DRIVER("flip-ioctl() cur_fbo = %p, cur_bbo = %p\n", 478 DRM_DEBUG_DRIVER("flip-ioctl() cur_rbo = %p, new_rbo = %p\n",
416 work->old_rbo, work->new_rbo); 479 work->old_rbo, new_rbo);
417 480
418 r = radeon_bo_reserve(work->new_rbo, false); 481 r = radeon_bo_reserve(new_rbo, false);
419 if (unlikely(r != 0)) { 482 if (unlikely(r != 0)) {
420 DRM_ERROR("failed to reserve new rbo buffer before flip\n"); 483 DRM_ERROR("failed to reserve new rbo buffer before flip\n");
421 goto cleanup; 484 goto cleanup;
422 } 485 }
423 /* Only 27 bit offset for legacy CRTC */ 486 /* Only 27 bit offset for legacy CRTC */
424 r = radeon_bo_pin_restricted(work->new_rbo, RADEON_GEM_DOMAIN_VRAM, 487 r = radeon_bo_pin_restricted(new_rbo, RADEON_GEM_DOMAIN_VRAM,
425 ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, &base); 488 ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, &base);
426 if (unlikely(r != 0)) { 489 if (unlikely(r != 0)) {
427 radeon_bo_unreserve(work->new_rbo); 490 radeon_bo_unreserve(new_rbo);
428 r = -EINVAL; 491 r = -EINVAL;
429 DRM_ERROR("failed to pin new rbo buffer before flip\n"); 492 DRM_ERROR("failed to pin new rbo buffer before flip\n");
430 goto cleanup; 493 goto cleanup;
431 } 494 }
432 radeon_bo_get_tiling_flags(work->new_rbo, &tiling_flags, NULL); 495 radeon_bo_get_tiling_flags(new_rbo, &tiling_flags, NULL);
433 radeon_bo_unreserve(work->new_rbo); 496 radeon_bo_unreserve(new_rbo);
434 497
435 if (!ASIC_IS_AVIVO(rdev)) { 498 if (!ASIC_IS_AVIVO(rdev)) {
436 /* crtc offset is from display base addr not FB location */ 499 /* crtc offset is from display base addr not FB location */
@@ -467,6 +530,7 @@ static void radeon_flip_work_func(struct work_struct *__work)
467 } 530 }
468 base &= ~7; 531 base &= ~7;
469 } 532 }
533 work->base = base;
470 534
471 r = drm_vblank_get(crtc->dev, radeon_crtc->crtc_id); 535 r = drm_vblank_get(crtc->dev, radeon_crtc->crtc_id);
472 if (r) { 536 if (r) {
@@ -477,100 +541,39 @@ static void radeon_flip_work_func(struct work_struct *__work)
477 /* We borrow the event spin lock for protecting flip_work */ 541 /* We borrow the event spin lock for protecting flip_work */
478 spin_lock_irqsave(&crtc->dev->event_lock, flags); 542 spin_lock_irqsave(&crtc->dev->event_lock, flags);
479 543
480 /* set the proper interrupt */ 544 if (radeon_crtc->flip_status != RADEON_FLIP_NONE) {
481 radeon_irq_kms_pflip_irq_get(rdev, radeon_crtc->crtc_id); 545 DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
546 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
547 r = -EBUSY;
548 goto pflip_cleanup;
549 }
550 radeon_crtc->flip_status = RADEON_FLIP_PENDING;
551 radeon_crtc->flip_work = work;
482 552
483 /* do the flip (mmio) */ 553 /* update crtc fb */
484 radeon_page_flip(rdev, radeon_crtc->crtc_id, base); 554 crtc->primary->fb = fb;
485 555
486 radeon_crtc->flip_status = RADEON_FLIP_SUBMITTED;
487 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 556 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
488 up_read(&rdev->exclusive_lock);
489 557
490 return; 558 queue_work(radeon_crtc->flip_queue, &work->flip_work);
559 return 0;
491 560
492pflip_cleanup: 561pflip_cleanup:
493 if (unlikely(radeon_bo_reserve(work->new_rbo, false) != 0)) { 562 if (unlikely(radeon_bo_reserve(new_rbo, false) != 0)) {
494 DRM_ERROR("failed to reserve new rbo in error path\n"); 563 DRM_ERROR("failed to reserve new rbo in error path\n");
495 goto cleanup; 564 goto cleanup;
496 } 565 }
497 if (unlikely(radeon_bo_unpin(work->new_rbo) != 0)) { 566 if (unlikely(radeon_bo_unpin(new_rbo) != 0)) {
498 DRM_ERROR("failed to unpin new rbo in error path\n"); 567 DRM_ERROR("failed to unpin new rbo in error path\n");
499 } 568 }
500 radeon_bo_unreserve(work->new_rbo); 569 radeon_bo_unreserve(new_rbo);
501 570
502cleanup: 571cleanup:
503 drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); 572 drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
504 radeon_fence_unref(&work->fence); 573 radeon_fence_unref(&work->fence);
505 kfree(work); 574 kfree(work);
506 up_read(&rdev->exclusive_lock);
507}
508
509static int radeon_crtc_page_flip(struct drm_crtc *crtc,
510 struct drm_framebuffer *fb,
511 struct drm_pending_vblank_event *event,
512 uint32_t page_flip_flags)
513{
514 struct drm_device *dev = crtc->dev;
515 struct radeon_device *rdev = dev->dev_private;
516 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
517 struct radeon_framebuffer *old_radeon_fb;
518 struct radeon_framebuffer *new_radeon_fb;
519 struct drm_gem_object *obj;
520 struct radeon_flip_work *work;
521 unsigned long flags;
522
523 work = kzalloc(sizeof *work, GFP_KERNEL);
524 if (work == NULL)
525 return -ENOMEM;
526
527 INIT_WORK(&work->flip_work, radeon_flip_work_func);
528 INIT_WORK(&work->unpin_work, radeon_unpin_work_func);
529 575
530 work->rdev = rdev; 576 return r;
531 work->crtc_id = radeon_crtc->crtc_id;
532 work->fb = fb;
533 work->event = event;
534
535 /* schedule unpin of the old buffer */
536 old_radeon_fb = to_radeon_framebuffer(crtc->primary->fb);
537 obj = old_radeon_fb->obj;
538
539 /* take a reference to the old object */
540 drm_gem_object_reference(obj);
541 work->old_rbo = gem_to_radeon_bo(obj);
542
543 new_radeon_fb = to_radeon_framebuffer(fb);
544 obj = new_radeon_fb->obj;
545 work->new_rbo = gem_to_radeon_bo(obj);
546
547 spin_lock(&work->new_rbo->tbo.bdev->fence_lock);
548 if (work->new_rbo->tbo.sync_obj)
549 work->fence = radeon_fence_ref(work->new_rbo->tbo.sync_obj);
550 spin_unlock(&work->new_rbo->tbo.bdev->fence_lock);
551
552 /* We borrow the event spin lock for protecting flip_work */
553 spin_lock_irqsave(&crtc->dev->event_lock, flags);
554
555 if (radeon_crtc->flip_status != RADEON_FLIP_NONE) {
556 DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
557 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
558 drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
559 radeon_fence_unref(&work->fence);
560 kfree(work);
561 return -EBUSY;
562 }
563 radeon_crtc->flip_status = RADEON_FLIP_PENDING;
564 radeon_crtc->flip_work = work;
565
566 /* update crtc fb */
567 crtc->primary->fb = fb;
568
569 spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
570
571 queue_work(radeon_crtc->flip_queue, &work->flip_work);
572
573 return 0;
574} 577}
575 578
576static int 579static int