aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
diff options
context:
space:
mode:
authorEmily Deng <Emily.Deng@amd.com>2016-08-07 23:31:37 -0400
committerAlex Deucher <alexander.deucher@amd.com>2016-08-08 13:57:04 -0400
commite13273d4a4702f7cb21a5f6e94919a5b52c45c32 (patch)
tree4a694c684464494a0b21ce8a88ccc1ed86a2d9e0 /drivers/gpu/drm/amd/amdgpu/dce_virtual.c
parent8e6de75bd1d6fa84c4338f6e2276eb2bc339f5c9 (diff)
drm/amdgpu: Initialize crtc, pageflip irq funcs (v2)
For virtual display feature, initialize dce_virtual_crtc_irq_funcs, dce_virtual_pageflip_irq_funcs. As it has no dce engine, so the pageflip interrupt won't be generated, and the vsync interrupt will be generated by smu's periodic timer or software timer which will be implemented later. v2: agd: rebase on upstream Signed-off-by: Emily Deng <Emily.Deng@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/dce_virtual.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_virtual.c130
1 files changed, 118 insertions, 12 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
index 2da8847f8938..985b276e6b25 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_virtual.c
@@ -473,19 +473,128 @@ static void dce_virtual_set_display_funcs(struct amdgpu_device *adev)
473 adev->mode_info.funcs = &dce_virtual_display_funcs; 473 adev->mode_info.funcs = &dce_virtual_display_funcs;
474} 474}
475 475
476static void dce_virtual_set_crtc_vblank_interrupt_state(struct amdgpu_device *adev,
477 int crtc,
478 enum amdgpu_interrupt_state state)
479{
480 if (crtc >= adev->mode_info.num_crtc) {
481 DRM_DEBUG("invalid crtc %d\n", crtc);
482 return;
483 }
484}
485
486static int dce_virtual_set_crtc_irq_state(struct amdgpu_device *adev,
487 struct amdgpu_irq_src *source,
488 unsigned type,
489 enum amdgpu_interrupt_state state)
490{
491 switch (type) {
492 case AMDGPU_CRTC_IRQ_VBLANK1:
493 dce_virtual_set_crtc_vblank_interrupt_state(adev, 0, state);
494 break;
495 default:
496 break;
497 }
498 return 0;
499}
500
501static void dce_virtual_crtc_vblank_int_ack(struct amdgpu_device *adev,
502 int crtc)
503{
504 if (crtc >= adev->mode_info.num_crtc) {
505 DRM_DEBUG("invalid crtc %d\n", crtc);
506 return;
507 }
508}
509
510static int dce_virtual_crtc_irq(struct amdgpu_device *adev,
511 struct amdgpu_irq_src *source,
512 struct amdgpu_iv_entry *entry)
513{
514 unsigned crtc = 0;
515 unsigned irq_type = AMDGPU_CRTC_IRQ_VBLANK1;
516
517 adev->ddev->vblank[crtc].count++;
518 dce_virtual_crtc_vblank_int_ack(adev, crtc);
519
520 if (amdgpu_irq_enabled(adev, source, irq_type)) {
521 drm_handle_vblank(adev->ddev, crtc);
522 }
523
524 DRM_DEBUG("IH: D%d vblank\n", crtc + 1);
525 return 0;
526}
527
528static int dce_virtual_set_pageflip_irq_state(struct amdgpu_device *adev,
529 struct amdgpu_irq_src *src,
530 unsigned type,
531 enum amdgpu_interrupt_state state)
532{
533 if (type >= adev->mode_info.num_crtc) {
534 DRM_ERROR("invalid pageflip crtc %d\n", type);
535 return -EINVAL;
536 }
537 DRM_DEBUG("[FM]set pageflip irq type %d state %d\n", type, state);
538
539 return 0;
540}
541
542static int dce_virtual_pageflip_irq(struct amdgpu_device *adev,
543 struct amdgpu_irq_src *source,
544 struct amdgpu_iv_entry *entry)
545{
546 unsigned long flags;
547 unsigned crtc_id = 0;
548 struct amdgpu_crtc *amdgpu_crtc;
549 struct amdgpu_flip_work *works;
550
551 crtc_id = 0;
552 amdgpu_crtc = adev->mode_info.crtcs[crtc_id];
553
554 if (crtc_id >= adev->mode_info.num_crtc) {
555 DRM_ERROR("invalid pageflip crtc %d\n", crtc_id);
556 return -EINVAL;
557 }
558
559 /* IRQ could occur when in initial stage */
560 if (amdgpu_crtc == NULL)
561 return 0;
562
563 spin_lock_irqsave(&adev->ddev->event_lock, flags);
564 works = amdgpu_crtc->pflip_works;
565 if (amdgpu_crtc->pflip_status != AMDGPU_FLIP_SUBMITTED) {
566 DRM_DEBUG_DRIVER("amdgpu_crtc->pflip_status = %d != "
567 "AMDGPU_FLIP_SUBMITTED(%d)\n",
568 amdgpu_crtc->pflip_status,
569 AMDGPU_FLIP_SUBMITTED);
570 spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
571 return 0;
572 }
573
574 /* page flip completed. clean up */
575 amdgpu_crtc->pflip_status = AMDGPU_FLIP_NONE;
576 amdgpu_crtc->pflip_works = NULL;
577
578 /* wakeup usersapce */
579 if (works->event)
580 drm_crtc_send_vblank_event(&amdgpu_crtc->base, works->event);
581
582 spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
583
584 drm_crtc_vblank_put(&amdgpu_crtc->base);
585 schedule_work(&works->unpin_work);
586
587 return 0;
588}
589
476static const struct amdgpu_irq_src_funcs dce_virtual_crtc_irq_funcs = { 590static const struct amdgpu_irq_src_funcs dce_virtual_crtc_irq_funcs = {
477 .set = NULL, 591 .set = dce_virtual_set_crtc_irq_state,
478 .process = NULL, 592 .process = dce_virtual_crtc_irq,
479}; 593};
480 594
481static const struct amdgpu_irq_src_funcs dce_virtual_pageflip_irq_funcs = { 595static const struct amdgpu_irq_src_funcs dce_virtual_pageflip_irq_funcs = {
482 .set = NULL, 596 .set = dce_virtual_set_pageflip_irq_state,
483 .process = NULL, 597 .process = dce_virtual_pageflip_irq,
484};
485
486static const struct amdgpu_irq_src_funcs dce_virtual_hpd_irq_funcs = {
487 .set = NULL,
488 .process = NULL,
489}; 598};
490 599
491static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev) 600static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev)
@@ -495,8 +604,5 @@ static void dce_virtual_set_irq_funcs(struct amdgpu_device *adev)
495 604
496 adev->pageflip_irq.num_types = AMDGPU_PAGEFLIP_IRQ_LAST; 605 adev->pageflip_irq.num_types = AMDGPU_PAGEFLIP_IRQ_LAST;
497 adev->pageflip_irq.funcs = &dce_virtual_pageflip_irq_funcs; 606 adev->pageflip_irq.funcs = &dce_virtual_pageflip_irq_funcs;
498
499 adev->hpd_irq.num_types = AMDGPU_HPD_LAST;
500 adev->hpd_irq.funcs = &dce_virtual_hpd_irq_funcs;
501} 607}
502 608