Am 26.06.2014 11:29, schrieb Michel D?nzer: > From: Michel D?nzer <michel.daenzer at amd.com> > > Prevents radeon_crtc_handle_flip() from running before > radeon_flip_work_func(), resulting in a kernel panic due to the BUG_ON() > in drm_vblank_put(). > > Tested-by: Dieter N?tzel <Dieter at nuetzel-hh.de> > Signed-off-by: Michel D?nzer <michel.daenzer at amd.com>
Does patch #2 alone fixes the problem as well? I would rather want to avoid turning the pflip interrupt on and off. Christian. > --- > drivers/gpu/drm/radeon/cik.c | 18 ++++++++++-------- > drivers/gpu/drm/radeon/evergreen.c | 18 ++++++++++-------- > drivers/gpu/drm/radeon/r600.c | 12 ++++++++---- > drivers/gpu/drm/radeon/si.c | 18 ++++++++++-------- > 4 files changed, 38 insertions(+), 28 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c > index 0f4b38f..7f522a4 100644 > --- a/drivers/gpu/drm/radeon/cik.c > +++ b/drivers/gpu/drm/radeon/cik.c > @@ -7145,21 +7145,21 @@ int cik_irq_set(struct radeon_device *rdev) > > if (rdev->num_crtc >= 2) { > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[0]) ? GRPH_PFLIP_INT_MASK : > 0); > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[1]) ? GRPH_PFLIP_INT_MASK : > 0); > } > if (rdev->num_crtc >= 4) { > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[2]) ? GRPH_PFLIP_INT_MASK : > 0); > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[3]) ? GRPH_PFLIP_INT_MASK : > 0); > } > if (rdev->num_crtc >= 6) { > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[4]) ? GRPH_PFLIP_INT_MASK : > 0); > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[5]) ? GRPH_PFLIP_INT_MASK : > 0); > } > > WREG32(DC_HPD1_INT_CONTROL, hpd1); > @@ -7611,8 +7611,10 @@ restart_ih: > case 14: /* D4 page flip */ > case 16: /* D5 page flip */ > case 18: /* D6 page flip */ > - DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1); > - radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1); > + src_id = (src_id - 8) >> 1; > + DRM_DEBUG("IH: D%d flip\n", src_id + 1); > + if (atomic_read(&rdev->irq.pflip[src_id])) > + radeon_crtc_handle_flip(rdev, src_id); > break; > case 42: /* HPD hotplug */ > switch (src_data) { > diff --git a/drivers/gpu/drm/radeon/evergreen.c > b/drivers/gpu/drm/radeon/evergreen.c > index 0443183..fa6e320 100644 > --- a/drivers/gpu/drm/radeon/evergreen.c > +++ b/drivers/gpu/drm/radeon/evergreen.c > @@ -4542,20 +4542,20 @@ int evergreen_irq_set(struct radeon_device *rdev) > } > > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[0]) ? GRPH_PFLIP_INT_MASK : 0); > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[1]) ? GRPH_PFLIP_INT_MASK : 0); > if (rdev->num_crtc >= 4) { > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[2]) ? GRPH_PFLIP_INT_MASK : > 0); > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[3]) ? GRPH_PFLIP_INT_MASK : > 0); > } > if (rdev->num_crtc >= 6) { > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[4]) ? GRPH_PFLIP_INT_MASK : > 0); > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[5]) ? GRPH_PFLIP_INT_MASK : > 0); > } > > WREG32(DC_HPD1_INT_CONTROL, hpd1); > @@ -4950,8 +4950,10 @@ restart_ih: > case 14: /* D4 page flip */ > case 16: /* D5 page flip */ > case 18: /* D6 page flip */ > - DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1); > - radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1); > + src_id = (src_id - 8) >> 1; > + DRM_DEBUG("IH: D%d flip\n", src_id + 1); > + if (atomic_read(&rdev->irq.pflip[src_id])) > + radeon_crtc_handle_flip(rdev, src_id); > break; > case 42: /* HPD hotplug */ > switch (src_data) { > diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c > index ae54f76..2f9a2af 100644 > --- a/drivers/gpu/drm/radeon/r600.c > +++ b/drivers/gpu/drm/radeon/r600.c > @@ -3614,8 +3614,10 @@ int r600_irq_set(struct radeon_device *rdev) > WREG32(CP_INT_CNTL, cp_int_cntl); > WREG32(DMA_CNTL, dma_cntl); > WREG32(DxMODE_INT_MASK, mode_int); > - WREG32(D1GRPH_INTERRUPT_CONTROL, DxGRPH_PFLIP_INT_MASK); > - WREG32(D2GRPH_INTERRUPT_CONTROL, DxGRPH_PFLIP_INT_MASK); > + WREG32(D1GRPH_INTERRUPT_CONTROL, > + atomic_read(&rdev->irq.pflip[0]) ? DxGRPH_PFLIP_INT_MASK : 0); > + WREG32(D2GRPH_INTERRUPT_CONTROL, > + atomic_read(&rdev->irq.pflip[1]) ? DxGRPH_PFLIP_INT_MASK : 0); > WREG32(GRBM_INT_CNTL, grbm_int_cntl); > if (ASIC_IS_DCE3(rdev)) { > WREG32(DC_HPD1_INT_CONTROL, hpd1); > @@ -3920,11 +3922,13 @@ restart_ih: > break; > case 9: /* D1 pflip */ > DRM_DEBUG("IH: D1 flip\n"); > - radeon_crtc_handle_flip(rdev, 0); > + if (atomic_read(&rdev->irq.pflip[0])) > + radeon_crtc_handle_flip(rdev, 0); > break; > case 11: /* D2 pflip */ > DRM_DEBUG("IH: D2 flip\n"); > - radeon_crtc_handle_flip(rdev, 1); > + if (atomic_read(&rdev->irq.pflip[1])) > + radeon_crtc_handle_flip(rdev, 1); > break; > case 19: /* HPD/DAC hotplug */ > switch (src_data) { > diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c > index c128bde..5d37ea5 100644 > --- a/drivers/gpu/drm/radeon/si.c > +++ b/drivers/gpu/drm/radeon/si.c > @@ -5919,21 +5919,21 @@ int si_irq_set(struct radeon_device *rdev) > > if (rdev->num_crtc >= 2) { > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[0]) ? GRPH_PFLIP_INT_MASK : > 0); > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[1]) ? GRPH_PFLIP_INT_MASK : > 0); > } > if (rdev->num_crtc >= 4) { > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[2]) ? GRPH_PFLIP_INT_MASK : > 0); > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[3]) ? GRPH_PFLIP_INT_MASK : > 0); > } > if (rdev->num_crtc >= 6) { > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[4]) ? GRPH_PFLIP_INT_MASK : > 0); > WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, > - GRPH_PFLIP_INT_MASK); > + atomic_read(&rdev->irq.pflip[5]) ? GRPH_PFLIP_INT_MASK : > 0); > } > > if (!ASIC_IS_NODCE(rdev)) { > @@ -6303,8 +6303,10 @@ restart_ih: > case 14: /* D4 page flip */ > case 16: /* D5 page flip */ > case 18: /* D6 page flip */ > - DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1); > - radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1); > + src_id = (src_id - 8) >> 1; > + DRM_DEBUG("IH: D%d flip\n", src_id + 1); > + if (atomic_read(&rdev->irq.pflip[src_id])) > + radeon_crtc_handle_flip(rdev, src_id); > break; > case 42: /* HPD hotplug */ > switch (src_data) {