Message ID | 1435896187-25908-1-git-send-email-mario.kleiner.de@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 03.07.2015 06:03, Mario Kleiner wrote: > Trying to resolve issues with missed vblanks and impossible > values inside delivered kms pageflip completion events showed > that radeon's irq handling sometimes doesn't handle valid irqs, > but silently skips them. This was observed for vblank interrupts. > > Although those irqs have corresponding events queued in the gpu's > irq ring at time of interrupt, and therefore the corresponding > handling code gets triggered by these events, the handling code > sometimes silently skipped processing the irq. The reason for those > skips is that the handling code double-checks for each irq event if > the corresponding irq status bits in the irq status registers > are set. Sometimes those bits are not set at time of check > for valid irqs, maybe due to some hardware race on some setups? > > The problem only seems to happen on some machine + card combos > sometimes, e.g., never happened during my testing of different PC > cards of the DCE-2/3/4 generation a year ago, but happens consistently > now on two different Apple Mac cards (RV730, DCE-3, Apple iMac and > Evergreen JUNIPER, DCE-4 in a Apple MacPro). It also doesn't happen > at each interrupt but only occassionally every couple of > hundred or thousand vblank interrupts. > > This results in XOrg warning messages like > > "[ 7084.472] (WW) RADEON(0): radeon_dri2_flip_event_handler: > Pageflip completion event has impossible msc 420120 < target_msc 420121" > > as well as skipped frames and problems for applications that > use kms pageflip events or vblank events, e.g., users of DRI2 and > DRI3/Present, Waylands Weston compositor, etc. See also > > https://bugs.freedesktop.org/show_bug.cgi?id=85203 > > After some talking to Alex and Michel, we decided to fix this > by turning the double-check for asserted irq status bits into a > warning. Whenever a irq event is queued in the IH ring, always > execute the corresponding interrupt handler. Still check the irq > status bits, but only to log a DRM_DEBUG message on a mismatch. > > This fixed the problems reliably on both previously failing > cards, RV-730 dual-head tested on both crtcs (pipes D1 and D2) > and a triple-output Juniper HD-5770 card tested on all three > available crtcs (D1/D2/D3). The r600 and evergreen irq handling > is therefore tested, but the cik an si handling is only compile > tested due to lack of hw. > > Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> > CC: Michel Dänzer <michel.daenzer@amd.com> > CC: Alex Deucher <alexander.deucher@amd.com> > > CC: <stable@vger.kernel.org> # v3.16+ I've always wondered why we do so, but simply assumed that there was a good reason for filtering those. Both patches are Reviewed-by: Christian König <christian.koenig@amd.com> Regards, Christian. > --- > drivers/gpu/drm/radeon/cik.c | 336 +++++++++++++++++-------------- > drivers/gpu/drm/radeon/evergreen.c | 392 ++++++++++++++++++++----------------- > drivers/gpu/drm/radeon/r600.c | 155 ++++++++------- > drivers/gpu/drm/radeon/si.c | 336 +++++++++++++++++-------------- > 4 files changed, 688 insertions(+), 531 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c > index b0688b0..35917e7 100644 > --- a/drivers/gpu/drm/radeon/cik.c > +++ b/drivers/gpu/drm/radeon/cik.c > @@ -7930,23 +7930,27 @@ restart_ih: > case 1: /* D1 vblank/vline */ > switch (src_data) { > case 0: /* D1 vblank */ > - if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[0]) { > - drm_handle_vblank(rdev->ddev, 0); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[0])) > - radeon_crtc_handle_vblank(rdev, 0); > - rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D1 vblank\n"); > + if (!(rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[0]) { > + drm_handle_vblank(rdev->ddev, 0); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[0])) > + radeon_crtc_handle_vblank(rdev, 0); > + rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D1 vblank\n"); > + > break; > case 1: /* D1 vline */ > - if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D1 vline\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D1 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -7956,23 +7960,27 @@ restart_ih: > case 2: /* D2 vblank/vline */ > switch (src_data) { > case 0: /* D2 vblank */ > - if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[1]) { > - drm_handle_vblank(rdev->ddev, 1); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[1])) > - radeon_crtc_handle_vblank(rdev, 1); > - rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D2 vblank\n"); > + if (!(rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[1]) { > + drm_handle_vblank(rdev->ddev, 1); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[1])) > + radeon_crtc_handle_vblank(rdev, 1); > + rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D2 vblank\n"); > + > break; > case 1: /* D2 vline */ > - if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D2 vline\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D2 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -7982,23 +7990,27 @@ restart_ih: > case 3: /* D3 vblank/vline */ > switch (src_data) { > case 0: /* D3 vblank */ > - if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[2]) { > - drm_handle_vblank(rdev->ddev, 2); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[2])) > - radeon_crtc_handle_vblank(rdev, 2); > - rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D3 vblank\n"); > + if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[2]) { > + drm_handle_vblank(rdev->ddev, 2); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[2])) > + radeon_crtc_handle_vblank(rdev, 2); > + rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D3 vblank\n"); > + > break; > case 1: /* D3 vline */ > - if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D3 vline\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D3 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -8008,23 +8020,27 @@ restart_ih: > case 4: /* D4 vblank/vline */ > switch (src_data) { > case 0: /* D4 vblank */ > - if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[3]) { > - drm_handle_vblank(rdev->ddev, 3); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[3])) > - radeon_crtc_handle_vblank(rdev, 3); > - rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D4 vblank\n"); > + if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[3]) { > + drm_handle_vblank(rdev->ddev, 3); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[3])) > + radeon_crtc_handle_vblank(rdev, 3); > + rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D4 vblank\n"); > + > break; > case 1: /* D4 vline */ > - if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D4 vline\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D4 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -8034,23 +8050,27 @@ restart_ih: > case 5: /* D5 vblank/vline */ > switch (src_data) { > case 0: /* D5 vblank */ > - if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[4]) { > - drm_handle_vblank(rdev->ddev, 4); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[4])) > - radeon_crtc_handle_vblank(rdev, 4); > - rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D5 vblank\n"); > + if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[4]) { > + drm_handle_vblank(rdev->ddev, 4); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[4])) > + radeon_crtc_handle_vblank(rdev, 4); > + rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D5 vblank\n"); > + > break; > case 1: /* D5 vline */ > - if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D5 vline\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D5 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -8060,23 +8080,27 @@ restart_ih: > case 6: /* D6 vblank/vline */ > switch (src_data) { > case 0: /* D6 vblank */ > - if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[5]) { > - drm_handle_vblank(rdev->ddev, 5); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[5])) > - radeon_crtc_handle_vblank(rdev, 5); > - rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D6 vblank\n"); > + if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[5]) { > + drm_handle_vblank(rdev->ddev, 5); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[5])) > + radeon_crtc_handle_vblank(rdev, 5); > + rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D6 vblank\n"); > + > break; > case 1: /* D6 vline */ > - if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D6 vline\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D6 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -8096,88 +8120,112 @@ restart_ih: > case 42: /* HPD hotplug */ > switch (src_data) { > case 0: > - if (rdev->irq.stat_regs.cik.disp_int & DC_HPD1_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD1\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int & DC_HPD1_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD1\n"); > + > break; > case 1: > - if (rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD2\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD2\n"); > + > break; > case 2: > - if (rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD3\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD3\n"); > + > break; > case 3: > - if (rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD4\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD4\n"); > + > break; > case 4: > - if (rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD5\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD5\n"); > + > break; > case 5: > - if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD6\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD6\n"); > + > break; > case 6: > - if (rdev->irq.stat_regs.cik.disp_int & DC_HPD1_RX_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 1\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int & DC_HPD1_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 1\n"); > + > break; > case 7: > - if (rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_RX_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 2\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 2\n"); > + > break; > case 8: > - if (rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 3\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 3\n"); > + > break; > case 9: > - if (rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 4\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 4\n"); > + > break; > case 10: > - if (rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 5\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 5\n"); > + > break; > case 11: > - if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) { > - rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 6\n"); > - } > + if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 6\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c > index 3a6d483..0acde19 100644 > --- a/drivers/gpu/drm/radeon/evergreen.c > +++ b/drivers/gpu/drm/radeon/evergreen.c > @@ -4924,7 +4924,7 @@ restart_ih: > return IRQ_NONE; > > rptr = rdev->ih.rptr; > - DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); > + DRM_DEBUG("evergreen_irq_process start: rptr %d, wptr %d\n", rptr, wptr); > > /* Order reading of wptr vs. reading of IH ring data */ > rmb(); > @@ -4942,23 +4942,27 @@ restart_ih: > case 1: /* D1 vblank/vline */ > switch (src_data) { > case 0: /* D1 vblank */ > - if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[0]) { > - drm_handle_vblank(rdev->ddev, 0); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[0])) > - radeon_crtc_handle_vblank(rdev, 0); > - rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D1 vblank\n"); > + if (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: D1 vblank - IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[0]) { > + drm_handle_vblank(rdev->ddev, 0); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[0])) > + radeon_crtc_handle_vblank(rdev, 0); > + rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D1 vblank\n"); > + > break; > case 1: /* D1 vline */ > - if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D1 vline\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: D1 vline - IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D1 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -4968,23 +4972,27 @@ restart_ih: > case 2: /* D2 vblank/vline */ > switch (src_data) { > case 0: /* D2 vblank */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[1]) { > - drm_handle_vblank(rdev->ddev, 1); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[1])) > - radeon_crtc_handle_vblank(rdev, 1); > - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D2 vblank\n"); > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: D2 vblank - IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[1]) { > + drm_handle_vblank(rdev->ddev, 1); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[1])) > + radeon_crtc_handle_vblank(rdev, 1); > + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D2 vblank\n"); > + > break; > case 1: /* D2 vline */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D2 vline\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: D2 vline - IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D2 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -4994,23 +5002,27 @@ restart_ih: > case 3: /* D3 vblank/vline */ > switch (src_data) { > case 0: /* D3 vblank */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[2]) { > - drm_handle_vblank(rdev->ddev, 2); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[2])) > - radeon_crtc_handle_vblank(rdev, 2); > - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D3 vblank\n"); > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: D3 vblank - IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[2]) { > + drm_handle_vblank(rdev->ddev, 2); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[2])) > + radeon_crtc_handle_vblank(rdev, 2); > + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D3 vblank\n"); > + > break; > case 1: /* D3 vline */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D3 vline\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: D3 vline - IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D3 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -5020,23 +5032,27 @@ restart_ih: > case 4: /* D4 vblank/vline */ > switch (src_data) { > case 0: /* D4 vblank */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[3]) { > - drm_handle_vblank(rdev->ddev, 3); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[3])) > - radeon_crtc_handle_vblank(rdev, 3); > - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D4 vblank\n"); > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: D4 vblank - IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[3]) { > + drm_handle_vblank(rdev->ddev, 3); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[3])) > + radeon_crtc_handle_vblank(rdev, 3); > + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D4 vblank\n"); > + > break; > case 1: /* D4 vline */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D4 vline\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: D4 vline - IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D4 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -5046,23 +5062,27 @@ restart_ih: > case 5: /* D5 vblank/vline */ > switch (src_data) { > case 0: /* D5 vblank */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[4]) { > - drm_handle_vblank(rdev->ddev, 4); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[4])) > - radeon_crtc_handle_vblank(rdev, 4); > - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D5 vblank\n"); > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: D5 vblank - IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[4]) { > + drm_handle_vblank(rdev->ddev, 4); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[4])) > + radeon_crtc_handle_vblank(rdev, 4); > + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D5 vblank\n"); > + > break; > case 1: /* D5 vline */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D5 vline\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: D5 vline - IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D5 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -5072,23 +5092,27 @@ restart_ih: > case 6: /* D6 vblank/vline */ > switch (src_data) { > case 0: /* D6 vblank */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[5]) { > - drm_handle_vblank(rdev->ddev, 5); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[5])) > - radeon_crtc_handle_vblank(rdev, 5); > - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D6 vblank\n"); > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: D6 vblank - IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[5]) { > + drm_handle_vblank(rdev->ddev, 5); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[5])) > + radeon_crtc_handle_vblank(rdev, 5); > + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D6 vblank\n"); > + > break; > case 1: /* D6 vline */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D6 vline\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: D6 vline - IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D6 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -5108,88 +5132,100 @@ restart_ih: > case 42: /* HPD hotplug */ > switch (src_data) { > case 0: > - if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD1\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD1\n"); > break; > case 1: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD2\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD2\n"); > break; > case 2: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD3\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD3\n"); > break; > case 3: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD4\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD4\n"); > break; > case 4: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD5\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD5\n"); > break; > case 5: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD6\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD6\n"); > break; > case 6: > - if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 1\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 1\n"); > break; > case 7: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 2\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 2\n"); > break; > case 8: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 3\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 3\n"); > break; > case 9: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 4\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 4\n"); > break; > case 10: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 5\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 5\n"); > break; > case 11: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 6\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 6\n"); > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -5199,46 +5235,52 @@ restart_ih: > case 44: /* hdmi */ > switch (src_data) { > case 0: > - if (rdev->irq.stat_regs.evergreen.afmt_status1 & AFMT_AZ_FORMAT_WTRIG) { > - rdev->irq.stat_regs.evergreen.afmt_status1 &= ~AFMT_AZ_FORMAT_WTRIG; > - queue_hdmi = true; > - DRM_DEBUG("IH: HDMI0\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.afmt_status1 & AFMT_AZ_FORMAT_WTRIG)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.afmt_status1 &= ~AFMT_AZ_FORMAT_WTRIG; > + queue_hdmi = true; > + DRM_DEBUG("IH: HDMI0\n"); > break; > case 1: > - if (rdev->irq.stat_regs.evergreen.afmt_status2 & AFMT_AZ_FORMAT_WTRIG) { > - rdev->irq.stat_regs.evergreen.afmt_status2 &= ~AFMT_AZ_FORMAT_WTRIG; > - queue_hdmi = true; > - DRM_DEBUG("IH: HDMI1\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.afmt_status2 & AFMT_AZ_FORMAT_WTRIG)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.afmt_status2 &= ~AFMT_AZ_FORMAT_WTRIG; > + queue_hdmi = true; > + DRM_DEBUG("IH: HDMI1\n"); > break; > case 2: > - if (rdev->irq.stat_regs.evergreen.afmt_status3 & AFMT_AZ_FORMAT_WTRIG) { > - rdev->irq.stat_regs.evergreen.afmt_status3 &= ~AFMT_AZ_FORMAT_WTRIG; > - queue_hdmi = true; > - DRM_DEBUG("IH: HDMI2\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.afmt_status3 & AFMT_AZ_FORMAT_WTRIG)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.afmt_status3 &= ~AFMT_AZ_FORMAT_WTRIG; > + queue_hdmi = true; > + DRM_DEBUG("IH: HDMI2\n"); > break; > case 3: > - if (rdev->irq.stat_regs.evergreen.afmt_status4 & AFMT_AZ_FORMAT_WTRIG) { > - rdev->irq.stat_regs.evergreen.afmt_status4 &= ~AFMT_AZ_FORMAT_WTRIG; > - queue_hdmi = true; > - DRM_DEBUG("IH: HDMI3\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.afmt_status4 & AFMT_AZ_FORMAT_WTRIG)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.afmt_status4 &= ~AFMT_AZ_FORMAT_WTRIG; > + queue_hdmi = true; > + DRM_DEBUG("IH: HDMI3\n"); > break; > case 4: > - if (rdev->irq.stat_regs.evergreen.afmt_status5 & AFMT_AZ_FORMAT_WTRIG) { > - rdev->irq.stat_regs.evergreen.afmt_status5 &= ~AFMT_AZ_FORMAT_WTRIG; > - queue_hdmi = true; > - DRM_DEBUG("IH: HDMI4\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.afmt_status5 & AFMT_AZ_FORMAT_WTRIG)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.afmt_status5 &= ~AFMT_AZ_FORMAT_WTRIG; > + queue_hdmi = true; > + DRM_DEBUG("IH: HDMI4\n"); > break; > case 5: > - if (rdev->irq.stat_regs.evergreen.afmt_status6 & AFMT_AZ_FORMAT_WTRIG) { > - rdev->irq.stat_regs.evergreen.afmt_status6 &= ~AFMT_AZ_FORMAT_WTRIG; > - queue_hdmi = true; > - DRM_DEBUG("IH: HDMI5\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.afmt_status6 & AFMT_AZ_FORMAT_WTRIG)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.afmt_status6 &= ~AFMT_AZ_FORMAT_WTRIG; > + queue_hdmi = true; > + DRM_DEBUG("IH: HDMI5\n"); > break; > default: > DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); > diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c > index 35dafd7..4ea5b10 100644 > --- a/drivers/gpu/drm/radeon/r600.c > +++ b/drivers/gpu/drm/radeon/r600.c > @@ -4086,23 +4086,27 @@ restart_ih: > case 1: /* D1 vblank/vline */ > switch (src_data) { > case 0: /* D1 vblank */ > - if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[0]) { > - drm_handle_vblank(rdev->ddev, 0); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[0])) > - radeon_crtc_handle_vblank(rdev, 0); > - rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D1 vblank\n"); > + if (!(rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: D1 vblank - IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[0]) { > + drm_handle_vblank(rdev->ddev, 0); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[0])) > + radeon_crtc_handle_vblank(rdev, 0); > + rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D1 vblank\n"); > + > break; > case 1: /* D1 vline */ > - if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D1 vline\n"); > - } > + if (!(rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: D1 vline - IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D1 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -4112,23 +4116,27 @@ restart_ih: > case 5: /* D2 vblank/vline */ > switch (src_data) { > case 0: /* D2 vblank */ > - if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[1]) { > - drm_handle_vblank(rdev->ddev, 1); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[1])) > - radeon_crtc_handle_vblank(rdev, 1); > - rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D2 vblank\n"); > + if (!(rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: D2 vblank - IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[1]) { > + drm_handle_vblank(rdev->ddev, 1); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[1])) > + radeon_crtc_handle_vblank(rdev, 1); > + rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D2 vblank\n"); > + > break; > case 1: /* D1 vline */ > - if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D2 vline\n"); > - } > + if (!(rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: D2 vline - IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D2 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -4148,46 +4156,53 @@ restart_ih: > case 19: /* HPD/DAC hotplug */ > switch (src_data) { > case 0: > - if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) { > - rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD1\n"); > - } > + if (!(rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT)) > + DRM_DEBUG("IH: HPD1 - IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD1\n"); > break; > case 1: > - if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) { > - rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD2\n"); > - } > + if (!(rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT)) > + DRM_DEBUG("IH: HPD2 - IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD2\n"); > break; > case 4: > - if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) { > - rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD3\n"); > - } > + if (!(rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT)) > + DRM_DEBUG("IH: HPD3 - IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD3\n"); > break; > case 5: > - if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) { > - rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD4\n"); > - } > + if (!(rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT)) > + DRM_DEBUG("IH: HPD4 - IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD4\n"); > break; > case 10: > - if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) { > - rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD5\n"); > - } > + if (!(rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT)) > + DRM_DEBUG("IH: HPD5 - IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD5\n"); > break; > case 12: > - if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) { > - rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD6\n"); > - } > + if (!(rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT)) > + DRM_DEBUG("IH: HPD6 - IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD6\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -4197,18 +4212,22 @@ restart_ih: > case 21: /* hdmi */ > switch (src_data) { > case 4: > - if (rdev->irq.stat_regs.r600.hdmi0_status & HDMI0_AZ_FORMAT_WTRIG) { > - rdev->irq.stat_regs.r600.hdmi0_status &= ~HDMI0_AZ_FORMAT_WTRIG; > - queue_hdmi = true; > - DRM_DEBUG("IH: HDMI0\n"); > - } > + if (!(rdev->irq.stat_regs.r600.hdmi0_status & HDMI0_AZ_FORMAT_WTRIG)) > + DRM_DEBUG("IH: HDMI0 - IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.r600.hdmi0_status &= ~HDMI0_AZ_FORMAT_WTRIG; > + queue_hdmi = true; > + DRM_DEBUG("IH: HDMI0\n"); > + > break; > case 5: > - if (rdev->irq.stat_regs.r600.hdmi1_status & HDMI0_AZ_FORMAT_WTRIG) { > - rdev->irq.stat_regs.r600.hdmi1_status &= ~HDMI0_AZ_FORMAT_WTRIG; > - queue_hdmi = true; > - DRM_DEBUG("IH: HDMI1\n"); > - } > + if (!(rdev->irq.stat_regs.r600.hdmi1_status & HDMI0_AZ_FORMAT_WTRIG)) > + DRM_DEBUG("IH: HDMI1 - IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.r600.hdmi1_status &= ~HDMI0_AZ_FORMAT_WTRIG; > + queue_hdmi = true; > + DRM_DEBUG("IH: HDMI1\n"); > + > break; > default: > DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); > diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c > index 26388b5..07037e3 100644 > --- a/drivers/gpu/drm/radeon/si.c > +++ b/drivers/gpu/drm/radeon/si.c > @@ -6466,23 +6466,27 @@ restart_ih: > case 1: /* D1 vblank/vline */ > switch (src_data) { > case 0: /* D1 vblank */ > - if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[0]) { > - drm_handle_vblank(rdev->ddev, 0); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[0])) > - radeon_crtc_handle_vblank(rdev, 0); > - rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D1 vblank\n"); > + if (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[0]) { > + drm_handle_vblank(rdev->ddev, 0); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[0])) > + radeon_crtc_handle_vblank(rdev, 0); > + rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D1 vblank\n"); > + > break; > case 1: /* D1 vline */ > - if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D1 vline\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D1 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -6492,23 +6496,27 @@ restart_ih: > case 2: /* D2 vblank/vline */ > switch (src_data) { > case 0: /* D2 vblank */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[1]) { > - drm_handle_vblank(rdev->ddev, 1); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[1])) > - radeon_crtc_handle_vblank(rdev, 1); > - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D2 vblank\n"); > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[1]) { > + drm_handle_vblank(rdev->ddev, 1); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[1])) > + radeon_crtc_handle_vblank(rdev, 1); > + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D2 vblank\n"); > + > break; > case 1: /* D2 vline */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D2 vline\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D2 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -6518,23 +6526,27 @@ restart_ih: > case 3: /* D3 vblank/vline */ > switch (src_data) { > case 0: /* D3 vblank */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[2]) { > - drm_handle_vblank(rdev->ddev, 2); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[2])) > - radeon_crtc_handle_vblank(rdev, 2); > - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D3 vblank\n"); > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[2]) { > + drm_handle_vblank(rdev->ddev, 2); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[2])) > + radeon_crtc_handle_vblank(rdev, 2); > + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D3 vblank\n"); > + > break; > case 1: /* D3 vline */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D3 vline\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D3 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -6544,23 +6556,27 @@ restart_ih: > case 4: /* D4 vblank/vline */ > switch (src_data) { > case 0: /* D4 vblank */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[3]) { > - drm_handle_vblank(rdev->ddev, 3); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[3])) > - radeon_crtc_handle_vblank(rdev, 3); > - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D4 vblank\n"); > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[3]) { > + drm_handle_vblank(rdev->ddev, 3); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[3])) > + radeon_crtc_handle_vblank(rdev, 3); > + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D4 vblank\n"); > + > break; > case 1: /* D4 vline */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D4 vline\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D4 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -6570,23 +6586,27 @@ restart_ih: > case 5: /* D5 vblank/vline */ > switch (src_data) { > case 0: /* D5 vblank */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[4]) { > - drm_handle_vblank(rdev->ddev, 4); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[4])) > - radeon_crtc_handle_vblank(rdev, 4); > - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D5 vblank\n"); > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[4]) { > + drm_handle_vblank(rdev->ddev, 4); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[4])) > + radeon_crtc_handle_vblank(rdev, 4); > + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D5 vblank\n"); > + > break; > case 1: /* D5 vline */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D5 vline\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D5 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -6596,23 +6616,27 @@ restart_ih: > case 6: /* D6 vblank/vline */ > switch (src_data) { > case 0: /* D6 vblank */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { > - if (rdev->irq.crtc_vblank_int[5]) { > - drm_handle_vblank(rdev->ddev, 5); > - rdev->pm.vblank_sync = true; > - wake_up(&rdev->irq.vblank_queue); > - } > - if (atomic_read(&rdev->irq.pflip[5])) > - radeon_crtc_handle_vblank(rdev, 5); > - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; > - DRM_DEBUG("IH: D6 vblank\n"); > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + if (rdev->irq.crtc_vblank_int[5]) { > + drm_handle_vblank(rdev->ddev, 5); > + rdev->pm.vblank_sync = true; > + wake_up(&rdev->irq.vblank_queue); > } > + if (atomic_read(&rdev->irq.pflip[5])) > + radeon_crtc_handle_vblank(rdev, 5); > + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; > + DRM_DEBUG("IH: D6 vblank\n"); > + > break; > case 1: /* D6 vline */ > - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; > - DRM_DEBUG("IH: D6 vline\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; > + DRM_DEBUG("IH: D6 vline\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); > @@ -6632,88 +6656,112 @@ restart_ih: > case 42: /* HPD hotplug */ > switch (src_data) { > case 0: > - if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD1\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD1\n"); > + > break; > case 1: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD2\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD2\n"); > + > break; > case 2: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD3\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD3\n"); > + > break; > case 3: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD4\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD4\n"); > + > break; > case 4: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD5\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD5\n"); > + > break; > case 5: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; > - queue_hotplug = true; > - DRM_DEBUG("IH: HPD6\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; > + queue_hotplug = true; > + DRM_DEBUG("IH: HPD6\n"); > + > break; > case 6: > - if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 1\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 1\n"); > + > break; > case 7: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 2\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 2\n"); > + > break; > case 8: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 3\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 3\n"); > + > break; > case 9: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 4\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 4\n"); > + > break; > case 10: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 5\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 5\n"); > + > break; > case 11: > - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) { > - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT; > - queue_dp = true; > - DRM_DEBUG("IH: HPD_RX 6\n"); > - } > + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT)) > + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); > + > + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT; > + queue_dp = true; > + DRM_DEBUG("IH: HPD_RX 6\n"); > + > break; > default: > DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
On Fri, Jul 3, 2015 at 5:51 AM, Christian König <deathsimple@vodafone.de> wrote: > On 03.07.2015 06:03, Mario Kleiner wrote: >> >> Trying to resolve issues with missed vblanks and impossible >> values inside delivered kms pageflip completion events showed >> that radeon's irq handling sometimes doesn't handle valid irqs, >> but silently skips them. This was observed for vblank interrupts. >> >> Although those irqs have corresponding events queued in the gpu's >> irq ring at time of interrupt, and therefore the corresponding >> handling code gets triggered by these events, the handling code >> sometimes silently skipped processing the irq. The reason for those >> skips is that the handling code double-checks for each irq event if >> the corresponding irq status bits in the irq status registers >> are set. Sometimes those bits are not set at time of check >> for valid irqs, maybe due to some hardware race on some setups? >> >> The problem only seems to happen on some machine + card combos >> sometimes, e.g., never happened during my testing of different PC >> cards of the DCE-2/3/4 generation a year ago, but happens consistently >> now on two different Apple Mac cards (RV730, DCE-3, Apple iMac and >> Evergreen JUNIPER, DCE-4 in a Apple MacPro). It also doesn't happen >> at each interrupt but only occassionally every couple of >> hundred or thousand vblank interrupts. >> >> This results in XOrg warning messages like >> >> "[ 7084.472] (WW) RADEON(0): radeon_dri2_flip_event_handler: >> Pageflip completion event has impossible msc 420120 < target_msc 420121" >> >> as well as skipped frames and problems for applications that >> use kms pageflip events or vblank events, e.g., users of DRI2 and >> DRI3/Present, Waylands Weston compositor, etc. See also >> >> https://bugs.freedesktop.org/show_bug.cgi?id=85203 >> >> After some talking to Alex and Michel, we decided to fix this >> by turning the double-check for asserted irq status bits into a >> warning. Whenever a irq event is queued in the IH ring, always >> execute the corresponding interrupt handler. Still check the irq >> status bits, but only to log a DRM_DEBUG message on a mismatch. >> >> This fixed the problems reliably on both previously failing >> cards, RV-730 dual-head tested on both crtcs (pipes D1 and D2) >> and a triple-output Juniper HD-5770 card tested on all three >> available crtcs (D1/D2/D3). The r600 and evergreen irq handling >> is therefore tested, but the cik an si handling is only compile >> tested due to lack of hw. >> >> Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> >> CC: Michel Dänzer <michel.daenzer@amd.com> >> CC: Alex Deucher <alexander.deucher@amd.com> >> >> CC: <stable@vger.kernel.org> # v3.16+ > Applied the series. Thanks! Alex > > I've always wondered why we do so, but simply assumed that there was a good > reason for filtering those. > > Both patches are Reviewed-by: Christian König <christian.koenig@amd.com> > > Regards, > Christian. > >> --- >> drivers/gpu/drm/radeon/cik.c | 336 +++++++++++++++++-------------- >> drivers/gpu/drm/radeon/evergreen.c | 392 >> ++++++++++++++++++++----------------- >> drivers/gpu/drm/radeon/r600.c | 155 ++++++++------- >> drivers/gpu/drm/radeon/si.c | 336 +++++++++++++++++-------------- >> 4 files changed, 688 insertions(+), 531 deletions(-) >> >> diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c >> index b0688b0..35917e7 100644 >> --- a/drivers/gpu/drm/radeon/cik.c >> +++ b/drivers/gpu/drm/radeon/cik.c >> @@ -7930,23 +7930,27 @@ restart_ih: >> case 1: /* D1 vblank/vline */ >> switch (src_data) { >> case 0: /* D1 vblank */ >> - if (rdev->irq.stat_regs.cik.disp_int & >> LB_D1_VBLANK_INTERRUPT) { >> - if (rdev->irq.crtc_vblank_int[0]) >> { >> - >> drm_handle_vblank(rdev->ddev, 0); >> - rdev->pm.vblank_sync = >> true; >> - >> wake_up(&rdev->irq.vblank_queue); >> - } >> - if >> (atomic_read(&rdev->irq.pflip[0])) >> - >> radeon_crtc_handle_vblank(rdev, 0); >> - rdev->irq.stat_regs.cik.disp_int >> &= ~LB_D1_VBLANK_INTERRUPT; >> - DRM_DEBUG("IH: D1 vblank\n"); >> + if (!(rdev->irq.stat_regs.cik.disp_int & >> LB_D1_VBLANK_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + if (rdev->irq.crtc_vblank_int[0]) { >> + drm_handle_vblank(rdev->ddev, 0); >> + rdev->pm.vblank_sync = true; >> + wake_up(&rdev->irq.vblank_queue); >> } >> + if (atomic_read(&rdev->irq.pflip[0])) >> + radeon_crtc_handle_vblank(rdev, >> 0); >> + rdev->irq.stat_regs.cik.disp_int &= >> ~LB_D1_VBLANK_INTERRUPT; >> + DRM_DEBUG("IH: D1 vblank\n"); >> + >> break; >> case 1: /* D1 vline */ >> - if (rdev->irq.stat_regs.cik.disp_int & >> LB_D1_VLINE_INTERRUPT) { >> - rdev->irq.stat_regs.cik.disp_int >> &= ~LB_D1_VLINE_INTERRUPT; >> - DRM_DEBUG("IH: D1 vline\n"); >> - } >> + if (!(rdev->irq.stat_regs.cik.disp_int & >> LB_D1_VLINE_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int &= >> ~LB_D1_VLINE_INTERRUPT; >> + DRM_DEBUG("IH: D1 vline\n"); >> + >> break; >> default: >> DRM_DEBUG("Unhandled interrupt: %d %d\n", >> src_id, src_data); >> @@ -7956,23 +7960,27 @@ restart_ih: >> case 2: /* D2 vblank/vline */ >> switch (src_data) { >> case 0: /* D2 vblank */ >> - if (rdev->irq.stat_regs.cik.disp_int_cont >> & LB_D2_VBLANK_INTERRUPT) { >> - if (rdev->irq.crtc_vblank_int[1]) >> { >> - >> drm_handle_vblank(rdev->ddev, 1); >> - rdev->pm.vblank_sync = >> true; >> - >> wake_up(&rdev->irq.vblank_queue); >> - } >> - if >> (atomic_read(&rdev->irq.pflip[1])) >> - >> radeon_crtc_handle_vblank(rdev, 1); >> - >> rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; >> - DRM_DEBUG("IH: D2 vblank\n"); >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + if (rdev->irq.crtc_vblank_int[1]) { >> + drm_handle_vblank(rdev->ddev, 1); >> + rdev->pm.vblank_sync = true; >> + wake_up(&rdev->irq.vblank_queue); >> } >> + if (atomic_read(&rdev->irq.pflip[1])) >> + radeon_crtc_handle_vblank(rdev, >> 1); >> + rdev->irq.stat_regs.cik.disp_int_cont &= >> ~LB_D2_VBLANK_INTERRUPT; >> + DRM_DEBUG("IH: D2 vblank\n"); >> + >> break; >> case 1: /* D2 vline */ >> - if (rdev->irq.stat_regs.cik.disp_int_cont >> & LB_D2_VLINE_INTERRUPT) { >> - >> rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; >> - DRM_DEBUG("IH: D2 vline\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int_cont &= >> ~LB_D2_VLINE_INTERRUPT; >> + DRM_DEBUG("IH: D2 vline\n"); >> + >> break; >> default: >> DRM_DEBUG("Unhandled interrupt: %d %d\n", >> src_id, src_data); >> @@ -7982,23 +7990,27 @@ restart_ih: >> case 3: /* D3 vblank/vline */ >> switch (src_data) { >> case 0: /* D3 vblank */ >> - if (rdev->irq.stat_regs.cik.disp_int_cont2 >> & LB_D3_VBLANK_INTERRUPT) { >> - if (rdev->irq.crtc_vblank_int[2]) >> { >> - >> drm_handle_vblank(rdev->ddev, 2); >> - rdev->pm.vblank_sync = >> true; >> - >> wake_up(&rdev->irq.vblank_queue); >> - } >> - if >> (atomic_read(&rdev->irq.pflip[2])) >> - >> radeon_crtc_handle_vblank(rdev, 2); >> - >> rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; >> - DRM_DEBUG("IH: D3 vblank\n"); >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + if (rdev->irq.crtc_vblank_int[2]) { >> + drm_handle_vblank(rdev->ddev, 2); >> + rdev->pm.vblank_sync = true; >> + wake_up(&rdev->irq.vblank_queue); >> } >> + if (atomic_read(&rdev->irq.pflip[2])) >> + radeon_crtc_handle_vblank(rdev, >> 2); >> + rdev->irq.stat_regs.cik.disp_int_cont2 &= >> ~LB_D3_VBLANK_INTERRUPT; >> + DRM_DEBUG("IH: D3 vblank\n"); >> + >> break; >> case 1: /* D3 vline */ >> - if (rdev->irq.stat_regs.cik.disp_int_cont2 >> & LB_D3_VLINE_INTERRUPT) { >> - >> rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; >> - DRM_DEBUG("IH: D3 vline\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int_cont2 &= >> ~LB_D3_VLINE_INTERRUPT; >> + DRM_DEBUG("IH: D3 vline\n"); >> + >> break; >> default: >> DRM_DEBUG("Unhandled interrupt: %d %d\n", >> src_id, src_data); >> @@ -8008,23 +8020,27 @@ restart_ih: >> case 4: /* D4 vblank/vline */ >> switch (src_data) { >> case 0: /* D4 vblank */ >> - if (rdev->irq.stat_regs.cik.disp_int_cont3 >> & LB_D4_VBLANK_INTERRUPT) { >> - if (rdev->irq.crtc_vblank_int[3]) >> { >> - >> drm_handle_vblank(rdev->ddev, 3); >> - rdev->pm.vblank_sync = >> true; >> - >> wake_up(&rdev->irq.vblank_queue); >> - } >> - if >> (atomic_read(&rdev->irq.pflip[3])) >> - >> radeon_crtc_handle_vblank(rdev, 3); >> - >> rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; >> - DRM_DEBUG("IH: D4 vblank\n"); >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + if (rdev->irq.crtc_vblank_int[3]) { >> + drm_handle_vblank(rdev->ddev, 3); >> + rdev->pm.vblank_sync = true; >> + wake_up(&rdev->irq.vblank_queue); >> } >> + if (atomic_read(&rdev->irq.pflip[3])) >> + radeon_crtc_handle_vblank(rdev, >> 3); >> + rdev->irq.stat_regs.cik.disp_int_cont3 &= >> ~LB_D4_VBLANK_INTERRUPT; >> + DRM_DEBUG("IH: D4 vblank\n"); >> + >> break; >> case 1: /* D4 vline */ >> - if (rdev->irq.stat_regs.cik.disp_int_cont3 >> & LB_D4_VLINE_INTERRUPT) { >> - >> rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; >> - DRM_DEBUG("IH: D4 vline\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int_cont3 &= >> ~LB_D4_VLINE_INTERRUPT; >> + DRM_DEBUG("IH: D4 vline\n"); >> + >> break; >> default: >> DRM_DEBUG("Unhandled interrupt: %d %d\n", >> src_id, src_data); >> @@ -8034,23 +8050,27 @@ restart_ih: >> case 5: /* D5 vblank/vline */ >> switch (src_data) { >> case 0: /* D5 vblank */ >> - if (rdev->irq.stat_regs.cik.disp_int_cont4 >> & LB_D5_VBLANK_INTERRUPT) { >> - if (rdev->irq.crtc_vblank_int[4]) >> { >> - >> drm_handle_vblank(rdev->ddev, 4); >> - rdev->pm.vblank_sync = >> true; >> - >> wake_up(&rdev->irq.vblank_queue); >> - } >> - if >> (atomic_read(&rdev->irq.pflip[4])) >> - >> radeon_crtc_handle_vblank(rdev, 4); >> - >> rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; >> - DRM_DEBUG("IH: D5 vblank\n"); >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + if (rdev->irq.crtc_vblank_int[4]) { >> + drm_handle_vblank(rdev->ddev, 4); >> + rdev->pm.vblank_sync = true; >> + wake_up(&rdev->irq.vblank_queue); >> } >> + if (atomic_read(&rdev->irq.pflip[4])) >> + radeon_crtc_handle_vblank(rdev, >> 4); >> + rdev->irq.stat_regs.cik.disp_int_cont4 &= >> ~LB_D5_VBLANK_INTERRUPT; >> + DRM_DEBUG("IH: D5 vblank\n"); >> + >> break; >> case 1: /* D5 vline */ >> - if (rdev->irq.stat_regs.cik.disp_int_cont4 >> & LB_D5_VLINE_INTERRUPT) { >> - >> rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; >> - DRM_DEBUG("IH: D5 vline\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int_cont4 &= >> ~LB_D5_VLINE_INTERRUPT; >> + DRM_DEBUG("IH: D5 vline\n"); >> + >> break; >> default: >> DRM_DEBUG("Unhandled interrupt: %d %d\n", >> src_id, src_data); >> @@ -8060,23 +8080,27 @@ restart_ih: >> case 6: /* D6 vblank/vline */ >> switch (src_data) { >> case 0: /* D6 vblank */ >> - if (rdev->irq.stat_regs.cik.disp_int_cont5 >> & LB_D6_VBLANK_INTERRUPT) { >> - if (rdev->irq.crtc_vblank_int[5]) >> { >> - >> drm_handle_vblank(rdev->ddev, 5); >> - rdev->pm.vblank_sync = >> true; >> - >> wake_up(&rdev->irq.vblank_queue); >> - } >> - if >> (atomic_read(&rdev->irq.pflip[5])) >> - >> radeon_crtc_handle_vblank(rdev, 5); >> - >> rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; >> - DRM_DEBUG("IH: D6 vblank\n"); >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + if (rdev->irq.crtc_vblank_int[5]) { >> + drm_handle_vblank(rdev->ddev, 5); >> + rdev->pm.vblank_sync = true; >> + wake_up(&rdev->irq.vblank_queue); >> } >> + if (atomic_read(&rdev->irq.pflip[5])) >> + radeon_crtc_handle_vblank(rdev, >> 5); >> + rdev->irq.stat_regs.cik.disp_int_cont5 &= >> ~LB_D6_VBLANK_INTERRUPT; >> + DRM_DEBUG("IH: D6 vblank\n"); >> + >> break; >> case 1: /* D6 vline */ >> - if (rdev->irq.stat_regs.cik.disp_int_cont5 >> & LB_D6_VLINE_INTERRUPT) { >> - >> rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; >> - DRM_DEBUG("IH: D6 vline\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int_cont5 &= >> ~LB_D6_VLINE_INTERRUPT; >> + DRM_DEBUG("IH: D6 vline\n"); >> + >> break; >> default: >> DRM_DEBUG("Unhandled interrupt: %d %d\n", >> src_id, src_data); >> @@ -8096,88 +8120,112 @@ restart_ih: >> case 42: /* HPD hotplug */ >> switch (src_data) { >> case 0: >> - if (rdev->irq.stat_regs.cik.disp_int & >> DC_HPD1_INTERRUPT) { >> - rdev->irq.stat_regs.cik.disp_int >> &= ~DC_HPD1_INTERRUPT; >> - queue_hotplug = true; >> - DRM_DEBUG("IH: HPD1\n"); >> - } >> + if (!(rdev->irq.stat_regs.cik.disp_int & >> DC_HPD1_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int &= >> ~DC_HPD1_INTERRUPT; >> + queue_hotplug = true; >> + DRM_DEBUG("IH: HPD1\n"); >> + >> break; >> case 1: >> - if (rdev->irq.stat_regs.cik.disp_int_cont >> & DC_HPD2_INTERRUPT) { >> - >> rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_INTERRUPT; >> - queue_hotplug = true; >> - DRM_DEBUG("IH: HPD2\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int_cont &= >> ~DC_HPD2_INTERRUPT; >> + queue_hotplug = true; >> + DRM_DEBUG("IH: HPD2\n"); >> + >> break; >> case 2: >> - if (rdev->irq.stat_regs.cik.disp_int_cont2 >> & DC_HPD3_INTERRUPT) { >> - >> rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; >> - queue_hotplug = true; >> - DRM_DEBUG("IH: HPD3\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int_cont2 &= >> ~DC_HPD3_INTERRUPT; >> + queue_hotplug = true; >> + DRM_DEBUG("IH: HPD3\n"); >> + >> break; >> case 3: >> - if (rdev->irq.stat_regs.cik.disp_int_cont3 >> & DC_HPD4_INTERRUPT) { >> - >> rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; >> - queue_hotplug = true; >> - DRM_DEBUG("IH: HPD4\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int_cont3 &= >> ~DC_HPD4_INTERRUPT; >> + queue_hotplug = true; >> + DRM_DEBUG("IH: HPD4\n"); >> + >> break; >> case 4: >> - if (rdev->irq.stat_regs.cik.disp_int_cont4 >> & DC_HPD5_INTERRUPT) { >> - >> rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; >> - queue_hotplug = true; >> - DRM_DEBUG("IH: HPD5\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int_cont4 &= >> ~DC_HPD5_INTERRUPT; >> + queue_hotplug = true; >> + DRM_DEBUG("IH: HPD5\n"); >> + >> break; >> case 5: >> - if (rdev->irq.stat_regs.cik.disp_int_cont5 >> & DC_HPD6_INTERRUPT) { >> - >> rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; >> - queue_hotplug = true; >> - DRM_DEBUG("IH: HPD6\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int_cont5 &= >> ~DC_HPD6_INTERRUPT; >> + queue_hotplug = true; >> + DRM_DEBUG("IH: HPD6\n"); >> + >> break; >> case 6: >> - if (rdev->irq.stat_regs.cik.disp_int & >> DC_HPD1_RX_INTERRUPT) { >> - rdev->irq.stat_regs.cik.disp_int >> &= ~DC_HPD1_RX_INTERRUPT; >> - queue_dp = true; >> - DRM_DEBUG("IH: HPD_RX 1\n"); >> - } >> + if (!(rdev->irq.stat_regs.cik.disp_int & >> DC_HPD1_RX_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int &= >> ~DC_HPD1_RX_INTERRUPT; >> + queue_dp = true; >> + DRM_DEBUG("IH: HPD_RX 1\n"); >> + >> break; >> case 7: >> - if (rdev->irq.stat_regs.cik.disp_int_cont >> & DC_HPD2_RX_INTERRUPT) { >> - >> rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT; >> - queue_dp = true; >> - DRM_DEBUG("IH: HPD_RX 2\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_RX_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int_cont &= >> ~DC_HPD2_RX_INTERRUPT; >> + queue_dp = true; >> + DRM_DEBUG("IH: HPD_RX 2\n"); >> + >> break; >> case 8: >> - if (rdev->irq.stat_regs.cik.disp_int_cont2 >> & DC_HPD3_RX_INTERRUPT) { >> - >> rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT; >> - queue_dp = true; >> - DRM_DEBUG("IH: HPD_RX 3\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_RX_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int_cont2 &= >> ~DC_HPD3_RX_INTERRUPT; >> + queue_dp = true; >> + DRM_DEBUG("IH: HPD_RX 3\n"); >> + >> break; >> case 9: >> - if (rdev->irq.stat_regs.cik.disp_int_cont3 >> & DC_HPD4_RX_INTERRUPT) { >> - >> rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT; >> - queue_dp = true; >> - DRM_DEBUG("IH: HPD_RX 4\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_RX_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int_cont3 &= >> ~DC_HPD4_RX_INTERRUPT; >> + queue_dp = true; >> + DRM_DEBUG("IH: HPD_RX 4\n"); >> + >> break; >> case 10: >> - if (rdev->irq.stat_regs.cik.disp_int_cont4 >> & DC_HPD5_RX_INTERRUPT) { >> - >> rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT; >> - queue_dp = true; >> - DRM_DEBUG("IH: HPD_RX 5\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_RX_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int_cont4 &= >> ~DC_HPD5_RX_INTERRUPT; >> + queue_dp = true; >> + DRM_DEBUG("IH: HPD_RX 5\n"); >> + >> break; >> case 11: >> - if (rdev->irq.stat_regs.cik.disp_int_cont5 >> & DC_HPD6_RX_INTERRUPT) { >> - >> rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT; >> - queue_dp = true; >> - DRM_DEBUG("IH: HPD_RX 6\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_RX_INTERRUPT)) >> + DRM_DEBUG("IH: IH event w/o >> asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.cik.disp_int_cont5 &= >> ~DC_HPD6_RX_INTERRUPT; >> + queue_dp = true; >> + DRM_DEBUG("IH: HPD_RX 6\n"); >> + >> break; >> default: >> DRM_DEBUG("Unhandled interrupt: %d %d\n", >> src_id, src_data); >> diff --git a/drivers/gpu/drm/radeon/evergreen.c >> b/drivers/gpu/drm/radeon/evergreen.c >> index 3a6d483..0acde19 100644 >> --- a/drivers/gpu/drm/radeon/evergreen.c >> +++ b/drivers/gpu/drm/radeon/evergreen.c >> @@ -4924,7 +4924,7 @@ restart_ih: >> return IRQ_NONE; >> rptr = rdev->ih.rptr; >> - DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, >> wptr); >> + DRM_DEBUG("evergreen_irq_process start: rptr %d, wptr %d\n", rptr, >> wptr); >> /* Order reading of wptr vs. reading of IH ring data */ >> rmb(); >> @@ -4942,23 +4942,27 @@ restart_ih: >> case 1: /* D1 vblank/vline */ >> switch (src_data) { >> case 0: /* D1 vblank */ >> - if (rdev->irq.stat_regs.evergreen.disp_int >> & LB_D1_VBLANK_INTERRUPT) { >> - if (rdev->irq.crtc_vblank_int[0]) >> { >> - >> drm_handle_vblank(rdev->ddev, 0); >> - rdev->pm.vblank_sync = >> true; >> - >> wake_up(&rdev->irq.vblank_queue); >> - } >> - if >> (atomic_read(&rdev->irq.pflip[0])) >> - >> radeon_crtc_handle_vblank(rdev, 0); >> - >> rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; >> - DRM_DEBUG("IH: D1 vblank\n"); >> + if >> (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT)) >> + DRM_DEBUG("IH: D1 vblank - IH >> event w/o asserted irq bit?\n"); >> + >> + if (rdev->irq.crtc_vblank_int[0]) { >> + drm_handle_vblank(rdev->ddev, 0); >> + rdev->pm.vblank_sync = true; >> + wake_up(&rdev->irq.vblank_queue); >> } >> + if (atomic_read(&rdev->irq.pflip[0])) >> + radeon_crtc_handle_vblank(rdev, >> 0); >> + rdev->irq.stat_regs.evergreen.disp_int &= >> ~LB_D1_VBLANK_INTERRUPT; >> + DRM_DEBUG("IH: D1 vblank\n"); >> + >> break; >> case 1: /* D1 vline */ >> - if (rdev->irq.stat_regs.evergreen.disp_int >> & LB_D1_VLINE_INTERRUPT) { >> - >> rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT; >> - DRM_DEBUG("IH: D1 vline\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT)) >> + DRM_DEBUG("IH: D1 vline - IH event >> w/o asserted irq bit?\n"); >> + >> + rdev->irq.stat_regs.evergreen.disp_int &= >> ~LB_D1_VLINE_INTERRUPT; >> + DRM_DEBUG("IH: D1 vline\n"); >> + >> break; >> default: >> DRM_DEBUG("Unhandled interrupt: %d %d\n", >> src_id, src_data); >> @@ -4968,23 +4972,27 @@ restart_ih: >> case 2: /* D2 vblank/vline */ >> switch (src_data) { >> case 0: /* D2 vblank */ >> - if >> (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) { >> - if (rdev->irq.crtc_vblank_int[1]) >> { >> - >> drm_handle_vblank(rdev->ddev, 1); >> - rdev->pm.vblank_sync = >> true; >> - >> wake_up(&rdev->irq.vblank_queue); >> - } >> - if >> (atomic_read(&rdev->irq.pflip[1])) >> - >> radeon_crtc_handle_vblank(rdev, 1); >> - >> rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; >> - DRM_DEBUG("IH: D2 vblank\n"); >> + if >> (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT)) >> + DRM_DEBUG("IH: D2 vblank - IH >> event w/o asserted irq bit?\n"); >> + >> + if (rdev->irq.crtc_vblank_int[1]) { >> + drm_handle_vblank(rdev->ddev, 1); >> + rdev->pm.vblank_sync = true; >> + wake_up(&rdev->irq.vblank_queue); >> } >> + if (atomic_read(&rdev->irq.pflip[1])) >> + radeon_crtc_handle_vblank(rdev, >> 1); >> + >> rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; >> + DRM_DEBUG("IH: D2 vblank\n"); >> + >> break; >> case 1: /* D2 vline */ >> - if >> (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) { >> - >> rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; >> - DRM_DEBUG("IH: D2 vline\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT)) >> + DRM_DEBUG("IH: D2 vline - IH event >> w/o asserted irq bit?\n"); >> + >> + >> rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; >> + DRM_DEBUG("IH: D2 vline\n"); >> + >> break; >> default: >> DRM_DEBUG("Unhandled interrupt: %d %d\n", >> src_id, src_data); >> @@ -4994,23 +5002,27 @@ restart_ih: >> case 3: /* D3 vblank/vline */ >> switch (src_data) { >> case 0: /* D3 vblank */ >> - if >> (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { >> - if (rdev->irq.crtc_vblank_int[2]) >> { >> - >> drm_handle_vblank(rdev->ddev, 2); >> - rdev->pm.vblank_sync = >> true; >> - >> wake_up(&rdev->irq.vblank_queue); >> - } >> - if >> (atomic_read(&rdev->irq.pflip[2])) >> - >> radeon_crtc_handle_vblank(rdev, 2); >> - >> rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; >> - DRM_DEBUG("IH: D3 vblank\n"); >> + if >> (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)) >> + DRM_DEBUG("IH: D3 vblank - IH >> event w/o asserted irq bit?\n"); >> + >> + if (rdev->irq.crtc_vblank_int[2]) { >> + drm_handle_vblank(rdev->ddev, 2); >> + rdev->pm.vblank_sync = true; >> + wake_up(&rdev->irq.vblank_queue); >> } >> + if (atomic_read(&rdev->irq.pflip[2])) >> + radeon_crtc_handle_vblank(rdev, >> 2); >> + >> rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; >> + DRM_DEBUG("IH: D3 vblank\n"); >> + >> break; >> case 1: /* D3 vline */ >> - if >> (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) { >> - >> rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; >> - DRM_DEBUG("IH: D3 vline\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)) >> + DRM_DEBUG("IH: D3 vline - IH event >> w/o asserted irq bit?\n"); >> + >> + >> rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; >> + DRM_DEBUG("IH: D3 vline\n"); >> + >> break; >> default: >> DRM_DEBUG("Unhandled interrupt: %d %d\n", >> src_id, src_data); >> @@ -5020,23 +5032,27 @@ restart_ih: >> case 4: /* D4 vblank/vline */ >> switch (src_data) { >> case 0: /* D4 vblank */ >> - if >> (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { >> - if (rdev->irq.crtc_vblank_int[3]) >> { >> - >> drm_handle_vblank(rdev->ddev, 3); >> - rdev->pm.vblank_sync = >> true; >> - >> wake_up(&rdev->irq.vblank_queue); >> - } >> - if >> (atomic_read(&rdev->irq.pflip[3])) >> - >> radeon_crtc_handle_vblank(rdev, 3); >> - >> rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; >> - DRM_DEBUG("IH: D4 vblank\n"); >> + if >> (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)) >> + DRM_DEBUG("IH: D4 vblank - IH >> event w/o asserted irq bit?\n"); >> + >> + if (rdev->irq.crtc_vblank_int[3]) { >> + drm_handle_vblank(rdev->ddev, 3); >> + rdev->pm.vblank_sync = true; >> + wake_up(&rdev->irq.vblank_queue); >> } >> + if (atomic_read(&rdev->irq.pflip[3])) >> + radeon_crtc_handle_vblank(rdev, >> 3); >> + >> rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; >> + DRM_DEBUG("IH: D4 vblank\n"); >> + >> break; >> case 1: /* D4 vline */ >> - if >> (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) { >> - >> rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; >> - DRM_DEBUG("IH: D4 vline\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)) >> + DRM_DEBUG("IH: D4 vline - IH event >> w/o asserted irq bit?\n"); >> + >> + >> rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; >> + DRM_DEBUG("IH: D4 vline\n"); >> + >> break; >> default: >> DRM_DEBUG("Unhandled interrupt: %d %d\n", >> src_id, src_data); >> @@ -5046,23 +5062,27 @@ restart_ih: >> case 5: /* D5 vblank/vline */ >> switch (src_data) { >> case 0: /* D5 vblank */ >> - if >> (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { >> - if (rdev->irq.crtc_vblank_int[4]) >> { >> - >> drm_handle_vblank(rdev->ddev, 4); >> - rdev->pm.vblank_sync = >> true; >> - >> wake_up(&rdev->irq.vblank_queue); >> - } >> - if >> (atomic_read(&rdev->irq.pflip[4])) >> - >> radeon_crtc_handle_vblank(rdev, 4); >> - >> rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; >> - DRM_DEBUG("IH: D5 vblank\n"); >> + if >> (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)) >> + DRM_DEBUG("IH: D5 vblank - IH >> event w/o asserted irq bit?\n"); >> + >> + if (rdev->irq.crtc_vblank_int[4]) { >> + drm_handle_vblank(rdev->ddev, 4); >> + rdev->pm.vblank_sync = true; >> + wake_up(&rdev->irq.vblank_queue); >> } >> + if (atomic_read(&rdev->irq.pflip[4])) >> + radeon_crtc_handle_vblank(rdev, >> 4); >> + >> rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; >> + DRM_DEBUG("IH: D5 vblank\n"); >> + >> break; >> case 1: /* D5 vline */ >> - if >> (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) { >> - >> rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; >> - DRM_DEBUG("IH: D5 vline\n"); >> - } >> + if >> (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)) >> + DRM_DEBUG("IH: D5 vline - IH event >> w/o asserted irq bit?\n"); >> + >> + >> rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; >> + DRM_DEBUG("IH: D5 vline\n"); >> + >> break; >> default: >> DRM_DEBUG("Unhandled interrupt: %d %d\n", >> src_id, src_data); >> @@ -5072,23 +5092,27 @@ restart_ih: >> case 6: /* D6 vblank/vline */ >> switch (src_data) { >> case 0: /* D6 vblank */ >> - if >> (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { >> - if (rdev->irq.crtc_vblank_int[5]) >> { >> - >> drm_handle_vblank(rdev->ddev, 5); >> - rdev->pm.vblank_sync = >> true; >> - >> wake_up(&rdev->irq.vblank_queue); >> - } >> - if >> (atomic_read(&rdev->irq.pflip[5])) >> - >> radeon_crtc_handle_vblank(rdev, 5); >> - >> rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; >> - DRM_DEBUG("IH: D6 vblank\n"); >> + if >> (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT))
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index b0688b0..35917e7 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -7930,23 +7930,27 @@ restart_ih: case 1: /* D1 vblank/vline */ switch (src_data) { case 0: /* D1 vblank */ - if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[0]) { - drm_handle_vblank(rdev->ddev, 0); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[0])) - radeon_crtc_handle_vblank(rdev, 0); - rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D1 vblank\n"); + if (!(rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[0]) { + drm_handle_vblank(rdev->ddev, 0); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[0])) + radeon_crtc_handle_vblank(rdev, 0); + rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D1 vblank\n"); + break; case 1: /* D1 vline */ - if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VLINE_INTERRUPT; - DRM_DEBUG("IH: D1 vline\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VLINE_INTERRUPT; + DRM_DEBUG("IH: D1 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -7956,23 +7960,27 @@ restart_ih: case 2: /* D2 vblank/vline */ switch (src_data) { case 0: /* D2 vblank */ - if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[1]) { - drm_handle_vblank(rdev->ddev, 1); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[1])) - radeon_crtc_handle_vblank(rdev, 1); - rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D2 vblank\n"); + if (!(rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[1]) { + drm_handle_vblank(rdev->ddev, 1); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[1])) + radeon_crtc_handle_vblank(rdev, 1); + rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D2 vblank\n"); + break; case 1: /* D2 vline */ - if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; - DRM_DEBUG("IH: D2 vline\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; + DRM_DEBUG("IH: D2 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -7982,23 +7990,27 @@ restart_ih: case 3: /* D3 vblank/vline */ switch (src_data) { case 0: /* D3 vblank */ - if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[2]) { - drm_handle_vblank(rdev->ddev, 2); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[2])) - radeon_crtc_handle_vblank(rdev, 2); - rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D3 vblank\n"); + if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[2]) { + drm_handle_vblank(rdev->ddev, 2); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[2])) + radeon_crtc_handle_vblank(rdev, 2); + rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D3 vblank\n"); + break; case 1: /* D3 vline */ - if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; - DRM_DEBUG("IH: D3 vline\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; + DRM_DEBUG("IH: D3 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -8008,23 +8020,27 @@ restart_ih: case 4: /* D4 vblank/vline */ switch (src_data) { case 0: /* D4 vblank */ - if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[3]) { - drm_handle_vblank(rdev->ddev, 3); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[3])) - radeon_crtc_handle_vblank(rdev, 3); - rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D4 vblank\n"); + if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[3]) { + drm_handle_vblank(rdev->ddev, 3); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[3])) + radeon_crtc_handle_vblank(rdev, 3); + rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D4 vblank\n"); + break; case 1: /* D4 vline */ - if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; - DRM_DEBUG("IH: D4 vline\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; + DRM_DEBUG("IH: D4 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -8034,23 +8050,27 @@ restart_ih: case 5: /* D5 vblank/vline */ switch (src_data) { case 0: /* D5 vblank */ - if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[4]) { - drm_handle_vblank(rdev->ddev, 4); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[4])) - radeon_crtc_handle_vblank(rdev, 4); - rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D5 vblank\n"); + if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[4]) { + drm_handle_vblank(rdev->ddev, 4); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[4])) + radeon_crtc_handle_vblank(rdev, 4); + rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D5 vblank\n"); + break; case 1: /* D5 vline */ - if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; - DRM_DEBUG("IH: D5 vline\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; + DRM_DEBUG("IH: D5 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -8060,23 +8080,27 @@ restart_ih: case 6: /* D6 vblank/vline */ switch (src_data) { case 0: /* D6 vblank */ - if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[5]) { - drm_handle_vblank(rdev->ddev, 5); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[5])) - radeon_crtc_handle_vblank(rdev, 5); - rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D6 vblank\n"); + if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[5]) { + drm_handle_vblank(rdev->ddev, 5); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[5])) + radeon_crtc_handle_vblank(rdev, 5); + rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D6 vblank\n"); + break; case 1: /* D6 vline */ - if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; - DRM_DEBUG("IH: D6 vline\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; + DRM_DEBUG("IH: D6 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -8096,88 +8120,112 @@ restart_ih: case 42: /* HPD hotplug */ switch (src_data) { case 0: - if (rdev->irq.stat_regs.cik.disp_int & DC_HPD1_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD1\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int & DC_HPD1_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD1\n"); + break; case 1: - if (rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD2\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD2\n"); + break; case 2: - if (rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD3\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD3\n"); + break; case 3: - if (rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD4\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD4\n"); + break; case 4: - if (rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD5\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD5\n"); + break; case 5: - if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD6\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD6\n"); + break; case 6: - if (rdev->irq.stat_regs.cik.disp_int & DC_HPD1_RX_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 1\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int & DC_HPD1_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 1\n"); + break; case 7: - if (rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_RX_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 2\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 2\n"); + break; case 8: - if (rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 3\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 3\n"); + break; case 9: - if (rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 4\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 4\n"); + break; case 10: - if (rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 5\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 5\n"); + break; case 11: - if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) { - rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 6\n"); - } + if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 6\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 3a6d483..0acde19 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -4924,7 +4924,7 @@ restart_ih: return IRQ_NONE; rptr = rdev->ih.rptr; - DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); + DRM_DEBUG("evergreen_irq_process start: rptr %d, wptr %d\n", rptr, wptr); /* Order reading of wptr vs. reading of IH ring data */ rmb(); @@ -4942,23 +4942,27 @@ restart_ih: case 1: /* D1 vblank/vline */ switch (src_data) { case 0: /* D1 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[0]) { - drm_handle_vblank(rdev->ddev, 0); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[0])) - radeon_crtc_handle_vblank(rdev, 0); - rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D1 vblank\n"); + if (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: D1 vblank - IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[0]) { + drm_handle_vblank(rdev->ddev, 0); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[0])) + radeon_crtc_handle_vblank(rdev, 0); + rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D1 vblank\n"); + break; case 1: /* D1 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT; - DRM_DEBUG("IH: D1 vline\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT)) + DRM_DEBUG("IH: D1 vline - IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT; + DRM_DEBUG("IH: D1 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -4968,23 +4972,27 @@ restart_ih: case 2: /* D2 vblank/vline */ switch (src_data) { case 0: /* D2 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[1]) { - drm_handle_vblank(rdev->ddev, 1); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[1])) - radeon_crtc_handle_vblank(rdev, 1); - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D2 vblank\n"); + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: D2 vblank - IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[1]) { + drm_handle_vblank(rdev->ddev, 1); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[1])) + radeon_crtc_handle_vblank(rdev, 1); + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D2 vblank\n"); + break; case 1: /* D2 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; - DRM_DEBUG("IH: D2 vline\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT)) + DRM_DEBUG("IH: D2 vline - IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; + DRM_DEBUG("IH: D2 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -4994,23 +5002,27 @@ restart_ih: case 3: /* D3 vblank/vline */ switch (src_data) { case 0: /* D3 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[2]) { - drm_handle_vblank(rdev->ddev, 2); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[2])) - radeon_crtc_handle_vblank(rdev, 2); - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D3 vblank\n"); + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: D3 vblank - IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[2]) { + drm_handle_vblank(rdev->ddev, 2); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[2])) + radeon_crtc_handle_vblank(rdev, 2); + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D3 vblank\n"); + break; case 1: /* D3 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; - DRM_DEBUG("IH: D3 vline\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)) + DRM_DEBUG("IH: D3 vline - IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; + DRM_DEBUG("IH: D3 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -5020,23 +5032,27 @@ restart_ih: case 4: /* D4 vblank/vline */ switch (src_data) { case 0: /* D4 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[3]) { - drm_handle_vblank(rdev->ddev, 3); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[3])) - radeon_crtc_handle_vblank(rdev, 3); - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D4 vblank\n"); + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: D4 vblank - IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[3]) { + drm_handle_vblank(rdev->ddev, 3); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[3])) + radeon_crtc_handle_vblank(rdev, 3); + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D4 vblank\n"); + break; case 1: /* D4 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; - DRM_DEBUG("IH: D4 vline\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)) + DRM_DEBUG("IH: D4 vline - IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; + DRM_DEBUG("IH: D4 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -5046,23 +5062,27 @@ restart_ih: case 5: /* D5 vblank/vline */ switch (src_data) { case 0: /* D5 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[4]) { - drm_handle_vblank(rdev->ddev, 4); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[4])) - radeon_crtc_handle_vblank(rdev, 4); - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D5 vblank\n"); + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: D5 vblank - IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[4]) { + drm_handle_vblank(rdev->ddev, 4); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[4])) + radeon_crtc_handle_vblank(rdev, 4); + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D5 vblank\n"); + break; case 1: /* D5 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; - DRM_DEBUG("IH: D5 vline\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)) + DRM_DEBUG("IH: D5 vline - IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; + DRM_DEBUG("IH: D5 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -5072,23 +5092,27 @@ restart_ih: case 6: /* D6 vblank/vline */ switch (src_data) { case 0: /* D6 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[5]) { - drm_handle_vblank(rdev->ddev, 5); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[5])) - radeon_crtc_handle_vblank(rdev, 5); - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D6 vblank\n"); + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: D6 vblank - IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[5]) { + drm_handle_vblank(rdev->ddev, 5); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[5])) + radeon_crtc_handle_vblank(rdev, 5); + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D6 vblank\n"); + break; case 1: /* D6 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; - DRM_DEBUG("IH: D6 vline\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)) + DRM_DEBUG("IH: D6 vline - IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; + DRM_DEBUG("IH: D6 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -5108,88 +5132,100 @@ restart_ih: case 42: /* HPD hotplug */ switch (src_data) { case 0: - if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD1\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD1\n"); break; case 1: - if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD2\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD2\n"); break; case 2: - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD3\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD3\n"); break; case 3: - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD4\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD4\n"); break; case 4: - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD5\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD5\n"); break; case 5: - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD6\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD6\n"); break; case 6: - if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 1\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 1\n"); break; case 7: - if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 2\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 2\n"); break; case 8: - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 3\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 3\n"); break; case 9: - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 4\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 4\n"); break; case 10: - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 5\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 5\n"); break; case 11: - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 6\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 6\n"); break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -5199,46 +5235,52 @@ restart_ih: case 44: /* hdmi */ switch (src_data) { case 0: - if (rdev->irq.stat_regs.evergreen.afmt_status1 & AFMT_AZ_FORMAT_WTRIG) { - rdev->irq.stat_regs.evergreen.afmt_status1 &= ~AFMT_AZ_FORMAT_WTRIG; - queue_hdmi = true; - DRM_DEBUG("IH: HDMI0\n"); - } + if (!(rdev->irq.stat_regs.evergreen.afmt_status1 & AFMT_AZ_FORMAT_WTRIG)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.afmt_status1 &= ~AFMT_AZ_FORMAT_WTRIG; + queue_hdmi = true; + DRM_DEBUG("IH: HDMI0\n"); break; case 1: - if (rdev->irq.stat_regs.evergreen.afmt_status2 & AFMT_AZ_FORMAT_WTRIG) { - rdev->irq.stat_regs.evergreen.afmt_status2 &= ~AFMT_AZ_FORMAT_WTRIG; - queue_hdmi = true; - DRM_DEBUG("IH: HDMI1\n"); - } + if (!(rdev->irq.stat_regs.evergreen.afmt_status2 & AFMT_AZ_FORMAT_WTRIG)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.afmt_status2 &= ~AFMT_AZ_FORMAT_WTRIG; + queue_hdmi = true; + DRM_DEBUG("IH: HDMI1\n"); break; case 2: - if (rdev->irq.stat_regs.evergreen.afmt_status3 & AFMT_AZ_FORMAT_WTRIG) { - rdev->irq.stat_regs.evergreen.afmt_status3 &= ~AFMT_AZ_FORMAT_WTRIG; - queue_hdmi = true; - DRM_DEBUG("IH: HDMI2\n"); - } + if (!(rdev->irq.stat_regs.evergreen.afmt_status3 & AFMT_AZ_FORMAT_WTRIG)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.afmt_status3 &= ~AFMT_AZ_FORMAT_WTRIG; + queue_hdmi = true; + DRM_DEBUG("IH: HDMI2\n"); break; case 3: - if (rdev->irq.stat_regs.evergreen.afmt_status4 & AFMT_AZ_FORMAT_WTRIG) { - rdev->irq.stat_regs.evergreen.afmt_status4 &= ~AFMT_AZ_FORMAT_WTRIG; - queue_hdmi = true; - DRM_DEBUG("IH: HDMI3\n"); - } + if (!(rdev->irq.stat_regs.evergreen.afmt_status4 & AFMT_AZ_FORMAT_WTRIG)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.afmt_status4 &= ~AFMT_AZ_FORMAT_WTRIG; + queue_hdmi = true; + DRM_DEBUG("IH: HDMI3\n"); break; case 4: - if (rdev->irq.stat_regs.evergreen.afmt_status5 & AFMT_AZ_FORMAT_WTRIG) { - rdev->irq.stat_regs.evergreen.afmt_status5 &= ~AFMT_AZ_FORMAT_WTRIG; - queue_hdmi = true; - DRM_DEBUG("IH: HDMI4\n"); - } + if (!(rdev->irq.stat_regs.evergreen.afmt_status5 & AFMT_AZ_FORMAT_WTRIG)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.afmt_status5 &= ~AFMT_AZ_FORMAT_WTRIG; + queue_hdmi = true; + DRM_DEBUG("IH: HDMI4\n"); break; case 5: - if (rdev->irq.stat_regs.evergreen.afmt_status6 & AFMT_AZ_FORMAT_WTRIG) { - rdev->irq.stat_regs.evergreen.afmt_status6 &= ~AFMT_AZ_FORMAT_WTRIG; - queue_hdmi = true; - DRM_DEBUG("IH: HDMI5\n"); - } + if (!(rdev->irq.stat_regs.evergreen.afmt_status6 & AFMT_AZ_FORMAT_WTRIG)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.afmt_status6 &= ~AFMT_AZ_FORMAT_WTRIG; + queue_hdmi = true; + DRM_DEBUG("IH: HDMI5\n"); break; default: DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 35dafd7..4ea5b10 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -4086,23 +4086,27 @@ restart_ih: case 1: /* D1 vblank/vline */ switch (src_data) { case 0: /* D1 vblank */ - if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[0]) { - drm_handle_vblank(rdev->ddev, 0); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[0])) - radeon_crtc_handle_vblank(rdev, 0); - rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D1 vblank\n"); + if (!(rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: D1 vblank - IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[0]) { + drm_handle_vblank(rdev->ddev, 0); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[0])) + radeon_crtc_handle_vblank(rdev, 0); + rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D1 vblank\n"); + break; case 1: /* D1 vline */ - if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) { - rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT; - DRM_DEBUG("IH: D1 vline\n"); - } + if (!(rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT)) + DRM_DEBUG("IH: D1 vline - IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT; + DRM_DEBUG("IH: D1 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -4112,23 +4116,27 @@ restart_ih: case 5: /* D2 vblank/vline */ switch (src_data) { case 0: /* D2 vblank */ - if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[1]) { - drm_handle_vblank(rdev->ddev, 1); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[1])) - radeon_crtc_handle_vblank(rdev, 1); - rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D2 vblank\n"); + if (!(rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: D2 vblank - IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[1]) { + drm_handle_vblank(rdev->ddev, 1); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[1])) + radeon_crtc_handle_vblank(rdev, 1); + rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D2 vblank\n"); + break; case 1: /* D1 vline */ - if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) { - rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT; - DRM_DEBUG("IH: D2 vline\n"); - } + if (!(rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT)) + DRM_DEBUG("IH: D2 vline - IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT; + DRM_DEBUG("IH: D2 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -4148,46 +4156,53 @@ restart_ih: case 19: /* HPD/DAC hotplug */ switch (src_data) { case 0: - if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) { - rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD1\n"); - } + if (!(rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT)) + DRM_DEBUG("IH: HPD1 - IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD1\n"); break; case 1: - if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) { - rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD2\n"); - } + if (!(rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT)) + DRM_DEBUG("IH: HPD2 - IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD2\n"); break; case 4: - if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) { - rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD3\n"); - } + if (!(rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT)) + DRM_DEBUG("IH: HPD3 - IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD3\n"); break; case 5: - if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) { - rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD4\n"); - } + if (!(rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT)) + DRM_DEBUG("IH: HPD4 - IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD4\n"); break; case 10: - if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) { - rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD5\n"); - } + if (!(rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT)) + DRM_DEBUG("IH: HPD5 - IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD5\n"); break; case 12: - if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) { - rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD6\n"); - } + if (!(rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT)) + DRM_DEBUG("IH: HPD6 - IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD6\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -4197,18 +4212,22 @@ restart_ih: case 21: /* hdmi */ switch (src_data) { case 4: - if (rdev->irq.stat_regs.r600.hdmi0_status & HDMI0_AZ_FORMAT_WTRIG) { - rdev->irq.stat_regs.r600.hdmi0_status &= ~HDMI0_AZ_FORMAT_WTRIG; - queue_hdmi = true; - DRM_DEBUG("IH: HDMI0\n"); - } + if (!(rdev->irq.stat_regs.r600.hdmi0_status & HDMI0_AZ_FORMAT_WTRIG)) + DRM_DEBUG("IH: HDMI0 - IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.r600.hdmi0_status &= ~HDMI0_AZ_FORMAT_WTRIG; + queue_hdmi = true; + DRM_DEBUG("IH: HDMI0\n"); + break; case 5: - if (rdev->irq.stat_regs.r600.hdmi1_status & HDMI0_AZ_FORMAT_WTRIG) { - rdev->irq.stat_regs.r600.hdmi1_status &= ~HDMI0_AZ_FORMAT_WTRIG; - queue_hdmi = true; - DRM_DEBUG("IH: HDMI1\n"); - } + if (!(rdev->irq.stat_regs.r600.hdmi1_status & HDMI0_AZ_FORMAT_WTRIG)) + DRM_DEBUG("IH: HDMI1 - IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.r600.hdmi1_status &= ~HDMI0_AZ_FORMAT_WTRIG; + queue_hdmi = true; + DRM_DEBUG("IH: HDMI1\n"); + break; default: DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 26388b5..07037e3 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -6466,23 +6466,27 @@ restart_ih: case 1: /* D1 vblank/vline */ switch (src_data) { case 0: /* D1 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[0]) { - drm_handle_vblank(rdev->ddev, 0); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[0])) - radeon_crtc_handle_vblank(rdev, 0); - rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D1 vblank\n"); + if (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[0]) { + drm_handle_vblank(rdev->ddev, 0); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[0])) + radeon_crtc_handle_vblank(rdev, 0); + rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D1 vblank\n"); + break; case 1: /* D1 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT; - DRM_DEBUG("IH: D1 vline\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT; + DRM_DEBUG("IH: D1 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -6492,23 +6496,27 @@ restart_ih: case 2: /* D2 vblank/vline */ switch (src_data) { case 0: /* D2 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[1]) { - drm_handle_vblank(rdev->ddev, 1); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[1])) - radeon_crtc_handle_vblank(rdev, 1); - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D2 vblank\n"); + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[1]) { + drm_handle_vblank(rdev->ddev, 1); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[1])) + radeon_crtc_handle_vblank(rdev, 1); + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D2 vblank\n"); + break; case 1: /* D2 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; - DRM_DEBUG("IH: D2 vline\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; + DRM_DEBUG("IH: D2 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -6518,23 +6526,27 @@ restart_ih: case 3: /* D3 vblank/vline */ switch (src_data) { case 0: /* D3 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[2]) { - drm_handle_vblank(rdev->ddev, 2); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[2])) - radeon_crtc_handle_vblank(rdev, 2); - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D3 vblank\n"); + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[2]) { + drm_handle_vblank(rdev->ddev, 2); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[2])) + radeon_crtc_handle_vblank(rdev, 2); + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D3 vblank\n"); + break; case 1: /* D3 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; - DRM_DEBUG("IH: D3 vline\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; + DRM_DEBUG("IH: D3 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -6544,23 +6556,27 @@ restart_ih: case 4: /* D4 vblank/vline */ switch (src_data) { case 0: /* D4 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[3]) { - drm_handle_vblank(rdev->ddev, 3); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[3])) - radeon_crtc_handle_vblank(rdev, 3); - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D4 vblank\n"); + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[3]) { + drm_handle_vblank(rdev->ddev, 3); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[3])) + radeon_crtc_handle_vblank(rdev, 3); + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D4 vblank\n"); + break; case 1: /* D4 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; - DRM_DEBUG("IH: D4 vline\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; + DRM_DEBUG("IH: D4 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -6570,23 +6586,27 @@ restart_ih: case 5: /* D5 vblank/vline */ switch (src_data) { case 0: /* D5 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[4]) { - drm_handle_vblank(rdev->ddev, 4); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[4])) - radeon_crtc_handle_vblank(rdev, 4); - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D5 vblank\n"); + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[4]) { + drm_handle_vblank(rdev->ddev, 4); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[4])) + radeon_crtc_handle_vblank(rdev, 4); + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D5 vblank\n"); + break; case 1: /* D5 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; - DRM_DEBUG("IH: D5 vline\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; + DRM_DEBUG("IH: D5 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -6596,23 +6616,27 @@ restart_ih: case 6: /* D6 vblank/vline */ switch (src_data) { case 0: /* D6 vblank */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { - if (rdev->irq.crtc_vblank_int[5]) { - drm_handle_vblank(rdev->ddev, 5); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - } - if (atomic_read(&rdev->irq.pflip[5])) - radeon_crtc_handle_vblank(rdev, 5); - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; - DRM_DEBUG("IH: D6 vblank\n"); + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + if (rdev->irq.crtc_vblank_int[5]) { + drm_handle_vblank(rdev->ddev, 5); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); } + if (atomic_read(&rdev->irq.pflip[5])) + radeon_crtc_handle_vblank(rdev, 5); + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; + DRM_DEBUG("IH: D6 vblank\n"); + break; case 1: /* D6 vline */ - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; - DRM_DEBUG("IH: D6 vline\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; + DRM_DEBUG("IH: D6 vline\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); @@ -6632,88 +6656,112 @@ restart_ih: case 42: /* HPD hotplug */ switch (src_data) { case 0: - if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD1\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD1\n"); + break; case 1: - if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD2\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD2\n"); + break; case 2: - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD3\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD3\n"); + break; case 3: - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD4\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD4\n"); + break; case 4: - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD5\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD5\n"); + break; case 5: - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; - queue_hotplug = true; - DRM_DEBUG("IH: HPD6\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; + queue_hotplug = true; + DRM_DEBUG("IH: HPD6\n"); + break; case 6: - if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 1\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 1\n"); + break; case 7: - if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 2\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 2\n"); + break; case 8: - if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 3\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 3\n"); + break; case 9: - if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 4\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 4\n"); + break; case 10: - if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 5\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 5\n"); + break; case 11: - if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) { - rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT; - queue_dp = true; - DRM_DEBUG("IH: HPD_RX 6\n"); - } + if (!(rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_RX_INTERRUPT)) + DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); + + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT; + queue_dp = true; + DRM_DEBUG("IH: HPD_RX 6\n"); + break; default: DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
Trying to resolve issues with missed vblanks and impossible values inside delivered kms pageflip completion events showed that radeon's irq handling sometimes doesn't handle valid irqs, but silently skips them. This was observed for vblank interrupts. Although those irqs have corresponding events queued in the gpu's irq ring at time of interrupt, and therefore the corresponding handling code gets triggered by these events, the handling code sometimes silently skipped processing the irq. The reason for those skips is that the handling code double-checks for each irq event if the corresponding irq status bits in the irq status registers are set. Sometimes those bits are not set at time of check for valid irqs, maybe due to some hardware race on some setups? The problem only seems to happen on some machine + card combos sometimes, e.g., never happened during my testing of different PC cards of the DCE-2/3/4 generation a year ago, but happens consistently now on two different Apple Mac cards (RV730, DCE-3, Apple iMac and Evergreen JUNIPER, DCE-4 in a Apple MacPro). It also doesn't happen at each interrupt but only occassionally every couple of hundred or thousand vblank interrupts. This results in XOrg warning messages like "[ 7084.472] (WW) RADEON(0): radeon_dri2_flip_event_handler: Pageflip completion event has impossible msc 420120 < target_msc 420121" as well as skipped frames and problems for applications that use kms pageflip events or vblank events, e.g., users of DRI2 and DRI3/Present, Waylands Weston compositor, etc. See also https://bugs.freedesktop.org/show_bug.cgi?id=85203 After some talking to Alex and Michel, we decided to fix this by turning the double-check for asserted irq status bits into a warning. Whenever a irq event is queued in the IH ring, always execute the corresponding interrupt handler. Still check the irq status bits, but only to log a DRM_DEBUG message on a mismatch. This fixed the problems reliably on both previously failing cards, RV-730 dual-head tested on both crtcs (pipes D1 and D2) and a triple-output Juniper HD-5770 card tested on all three available crtcs (D1/D2/D3). The r600 and evergreen irq handling is therefore tested, but the cik an si handling is only compile tested due to lack of hw. Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> CC: Michel Dänzer <michel.daenzer@amd.com> CC: Alex Deucher <alexander.deucher@amd.com> CC: <stable@vger.kernel.org> # v3.16+ --- drivers/gpu/drm/radeon/cik.c | 336 +++++++++++++++++-------------- drivers/gpu/drm/radeon/evergreen.c | 392 ++++++++++++++++++++----------------- drivers/gpu/drm/radeon/r600.c | 155 ++++++++------- drivers/gpu/drm/radeon/si.c | 336 +++++++++++++++++-------------- 4 files changed, 688 insertions(+), 531 deletions(-)