Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon: Modify radeon_pm_in_vbl to use radeon_get_crtc_scanoutpos()

radeon_pm_in_vbl() didn't report in vblank status accurately. Make
it a wrapper around radeon_get_crtc_scanoutpos() which corrects for
biases, so it reports accurately.

radeon_pm_in_vbl() will only report in_vbl if all active crtc's
are currently inside vblank.

agd5f: use rdev->num_crtc rather than hardcoding the crtc count

Signed-off-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

authored by

Mario Kleiner and committed by
Dave Airlie
75fa0b08 6383cf7d

+9 -61
+9 -61
drivers/gpu/drm/radeon/radeon_pm.c
··· 712 712 713 713 static bool radeon_pm_in_vbl(struct radeon_device *rdev) 714 714 { 715 - u32 stat_crtc = 0, vbl = 0, position = 0; 715 + int crtc, vpos, hpos, vbl_status; 716 716 bool in_vbl = true; 717 717 718 - if (ASIC_IS_DCE4(rdev)) { 719 - if (rdev->pm.active_crtcs & (1 << 0)) { 720 - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + 721 - EVERGREEN_CRTC0_REGISTER_OFFSET) & 0xfff; 722 - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + 723 - EVERGREEN_CRTC0_REGISTER_OFFSET) & 0xfff; 724 - } 725 - if (rdev->pm.active_crtcs & (1 << 1)) { 726 - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + 727 - EVERGREEN_CRTC1_REGISTER_OFFSET) & 0xfff; 728 - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + 729 - EVERGREEN_CRTC1_REGISTER_OFFSET) & 0xfff; 730 - } 731 - if (rdev->pm.active_crtcs & (1 << 2)) { 732 - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + 733 - EVERGREEN_CRTC2_REGISTER_OFFSET) & 0xfff; 734 - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + 735 - EVERGREEN_CRTC2_REGISTER_OFFSET) & 0xfff; 736 - } 737 - if (rdev->pm.active_crtcs & (1 << 3)) { 738 - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + 739 - EVERGREEN_CRTC3_REGISTER_OFFSET) & 0xfff; 740 - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + 741 - EVERGREEN_CRTC3_REGISTER_OFFSET) & 0xfff; 742 - } 743 - if (rdev->pm.active_crtcs & (1 << 4)) { 744 - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + 745 - EVERGREEN_CRTC4_REGISTER_OFFSET) & 0xfff; 746 - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + 747 - EVERGREEN_CRTC4_REGISTER_OFFSET) & 0xfff; 748 - } 749 - if (rdev->pm.active_crtcs & (1 << 5)) { 750 - vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + 751 - EVERGREEN_CRTC5_REGISTER_OFFSET) & 0xfff; 752 - position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + 753 - EVERGREEN_CRTC5_REGISTER_OFFSET) & 0xfff; 754 - } 755 - } else if (ASIC_IS_AVIVO(rdev)) { 756 - if (rdev->pm.active_crtcs & (1 << 0)) { 757 - vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END) & 0xfff; 758 - position = RREG32(AVIVO_D1CRTC_STATUS_POSITION) & 0xfff; 759 - } 760 - if (rdev->pm.active_crtcs & (1 << 1)) { 761 - vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END) & 0xfff; 762 - position = RREG32(AVIVO_D2CRTC_STATUS_POSITION) & 0xfff; 763 - } 764 - if (position < vbl && position > 1) 765 - in_vbl = false; 766 - } else { 767 - if (rdev->pm.active_crtcs & (1 << 0)) { 768 - stat_crtc = RREG32(RADEON_CRTC_STATUS); 769 - if (!(stat_crtc & 1)) 770 - in_vbl = false; 771 - } 772 - if (rdev->pm.active_crtcs & (1 << 1)) { 773 - stat_crtc = RREG32(RADEON_CRTC2_STATUS); 774 - if (!(stat_crtc & 1)) 718 + /* Iterate over all active crtc's. All crtc's must be in vblank, 719 + * otherwise return in_vbl == false. 720 + */ 721 + for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { 722 + if (rdev->pm.active_crtcs & (1 << crtc)) { 723 + vbl_status = radeon_get_crtc_scanoutpos(rdev, crtc, &vpos, &hpos); 724 + if ((vbl_status & RADEON_SCANOUTPOS_VALID) && 725 + !(vbl_status & RADEON_SCANOUTPOS_INVBL)) 775 726 in_vbl = false; 776 727 } 777 728 } 778 - 779 - if (position < vbl && position > 1) 780 - in_vbl = false; 781 729 782 730 return in_vbl; 783 731 }