On Fri, Apr 1, 2016 at 8:39 AM, Christian König <deathsimple@xxxxxxxxxxx> wrote: > Am 01.04.2016 um 11:51 schrieb Michel Dänzer: >> >> From: Michel Dänzer <michel.daenzer@xxxxxxx> >> >> When this flag is set, we program the hardware to execute the flip >> during horizontal blank (i.e. for the next scanline) instead of during >> vertical blank (i.e. for the next frame). >> >> Currently this is only supported on ASICs which have a page flip >> completion interrupt (>= R600), and only if the use_pflipirq parameter >> has value 2 (the default). >> >> Signed-off-by: Michel Dänzer <michel.daenzer@xxxxxxx> > > > Reviewed-by: Christian König <christian.koenig@xxxxxxx> > Applied. thanks! Alex > >> --- >> drivers/gpu/drm/radeon/atombios_crtc.c | 24 +++++++++++------------- >> drivers/gpu/drm/radeon/evergreen.c | 5 ++++- >> drivers/gpu/drm/radeon/r100.c | 2 +- >> drivers/gpu/drm/radeon/radeon.h | 5 +++-- >> drivers/gpu/drm/radeon/radeon_asic.h | 9 +++++---- >> drivers/gpu/drm/radeon/radeon_display.c | 6 +++++- >> drivers/gpu/drm/radeon/rs600.c | 4 +++- >> drivers/gpu/drm/radeon/rv770.c | 4 +++- >> 8 files changed, 35 insertions(+), 24 deletions(-) >> >> diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c >> b/drivers/gpu/drm/radeon/atombios_crtc.c >> index b80b08f..bdc7b9e 100644 >> --- a/drivers/gpu/drm/radeon/atombios_crtc.c >> +++ b/drivers/gpu/drm/radeon/atombios_crtc.c >> @@ -1375,6 +1375,11 @@ static int dce4_crtc_do_set_base(struct drm_crtc >> *crtc, >> break; >> } >> + /* Make sure surface address is updated at vertical blank rather >> than >> + * horizontal blank >> + */ >> + WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, 0); >> + >> WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + >> radeon_crtc->crtc_offset, >> upper_32_bits(fb_location)); >> WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + >> radeon_crtc->crtc_offset, >> @@ -1427,12 +1432,6 @@ static int dce4_crtc_do_set_base(struct drm_crtc >> *crtc, >> WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset, >> (viewport_w << 16) | viewport_h); >> - /* pageflip setup */ >> - /* make sure flip is at vb rather than hb */ >> - tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + >> radeon_crtc->crtc_offset); >> - tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN; >> - WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, >> tmp); >> - >> /* set pageflip to happen only at start of vblank interval (front >> porch) */ >> WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, >> 3); >> @@ -1466,7 +1465,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc >> *crtc, >> uint64_t fb_location; >> uint32_t fb_format, fb_pitch_pixels, tiling_flags; >> u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE; >> - u32 tmp, viewport_w, viewport_h; >> + u32 viewport_w, viewport_h; >> int r; >> bool bypass_lut = false; >> @@ -1581,6 +1580,11 @@ static int avivo_crtc_do_set_base(struct drm_crtc >> *crtc, >> else >> WREG32(AVIVO_D2VGA_CONTROL, 0); >> + /* Make sure surface address is update at vertical blank rather >> than >> + * horizontal blank >> + */ >> + WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, 0); >> + >> if (rdev->family >= CHIP_RV770) { >> if (radeon_crtc->crtc_id) { >> WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, >> upper_32_bits(fb_location)); >> @@ -1627,12 +1631,6 @@ static int avivo_crtc_do_set_base(struct drm_crtc >> *crtc, >> WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, >> (viewport_w << 16) | viewport_h); >> - /* pageflip setup */ >> - /* make sure flip is at vb rather than hb */ >> - tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + >> radeon_crtc->crtc_offset); >> - tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN; >> - WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); >> - >> /* set pageflip to happen only at start of vblank interval (front >> porch) */ >> WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, >> 3); >> diff --git a/drivers/gpu/drm/radeon/evergreen.c >> b/drivers/gpu/drm/radeon/evergreen.c >> index 76c4bdf..e109239 100644 >> --- a/drivers/gpu/drm/radeon/evergreen.c >> +++ b/drivers/gpu/drm/radeon/evergreen.c >> @@ -1407,11 +1407,14 @@ void dce4_wait_for_vblank(struct radeon_device >> *rdev, int crtc) >> * Triggers the actual pageflip by updating the primary >> * surface base address (evergreen+). >> */ >> -void evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 >> crtc_base) >> +void evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 >> crtc_base, >> + bool async) >> { >> struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; >> /* update the scanout addresses */ >> + WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, >> + async ? EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN : 0); >> WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + >> radeon_crtc->crtc_offset, >> upper_32_bits(crtc_base)); >> WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + >> radeon_crtc->crtc_offset, >> diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c >> index 6e478a2..de11a7d 100644 >> --- a/drivers/gpu/drm/radeon/r100.c >> +++ b/drivers/gpu/drm/radeon/r100.c >> @@ -153,7 +153,7 @@ void r100_wait_for_vblank(struct radeon_device *rdev, >> int crtc) >> * bit to go high, when it does, we release the lock, and allow the >> * double buffered update to take place. >> */ >> -void r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 >> crtc_base) >> +void r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 >> crtc_base, bool async) >> { >> struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; >> u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK; >> diff --git a/drivers/gpu/drm/radeon/radeon.h >> b/drivers/gpu/drm/radeon/radeon.h >> index 007be29..f836993 100644 >> --- a/drivers/gpu/drm/radeon/radeon.h >> +++ b/drivers/gpu/drm/radeon/radeon.h >> @@ -744,6 +744,7 @@ struct radeon_flip_work { >> struct drm_pending_vblank_event *event; >> struct radeon_bo *old_rbo; >> struct fence *fence; >> + bool async; >> }; >> struct r500_irq_stat_regs { >> @@ -1998,7 +1999,7 @@ struct radeon_asic { >> } dpm; >> /* pageflipping */ >> struct { >> - void (*page_flip)(struct radeon_device *rdev, int crtc, >> u64 crtc_base); >> + void (*page_flip)(struct radeon_device *rdev, int crtc, >> u64 crtc_base, bool async); >> bool (*page_flip_pending)(struct radeon_device *rdev, int >> crtc); >> } pflip; >> }; >> @@ -2775,7 +2776,7 @@ static inline void radeon_ring_write(struct >> radeon_ring *ring, uint32_t v) >> #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev)) >> #define radeon_pm_init_profile(rdev) >> (rdev)->asic->pm.init_profile((rdev)) >> #define radeon_pm_get_dynpm_state(rdev) >> (rdev)->asic->pm.get_dynpm_state((rdev)) >> -#define radeon_page_flip(rdev, crtc, base) >> (rdev)->asic->pflip.page_flip((rdev), (crtc), (base)) >> +#define radeon_page_flip(rdev, crtc, base, async) >> (rdev)->asic->pflip.page_flip((rdev), (crtc), (base), (async)) >> #define radeon_page_flip_pending(rdev, crtc) >> (rdev)->asic->pflip.page_flip_pending((rdev), (crtc)) >> #define radeon_wait_for_vblank(rdev, crtc) >> (rdev)->asic->display.wait_for_vblank((rdev), (crtc)) >> #define radeon_mc_wait_for_idle(rdev) >> (rdev)->asic->mc_wait_for_idle((rdev)) >> diff --git a/drivers/gpu/drm/radeon/radeon_asic.h >> b/drivers/gpu/drm/radeon/radeon_asic.h >> index e0aa332..a3deed90 100644 >> --- a/drivers/gpu/drm/radeon/radeon_asic.h >> +++ b/drivers/gpu/drm/radeon/radeon_asic.h >> @@ -138,7 +138,7 @@ extern void r100_pm_finish(struct radeon_device >> *rdev); >> extern void r100_pm_init_profile(struct radeon_device *rdev); >> extern void r100_pm_get_dynpm_state(struct radeon_device *rdev); >> extern void r100_page_flip(struct radeon_device *rdev, int crtc, >> - u64 crtc_base); >> + u64 crtc_base, bool async); >> extern bool r100_page_flip_pending(struct radeon_device *rdev, int >> crtc); >> extern void r100_wait_for_vblank(struct radeon_device *rdev, int crtc); >> extern int r100_mc_wait_for_idle(struct radeon_device *rdev); >> @@ -250,7 +250,7 @@ extern void rs600_pm_misc(struct radeon_device *rdev); >> extern void rs600_pm_prepare(struct radeon_device *rdev); >> extern void rs600_pm_finish(struct radeon_device *rdev); >> extern void rs600_page_flip(struct radeon_device *rdev, int crtc, >> - u64 crtc_base); >> + u64 crtc_base, bool async); >> extern bool rs600_page_flip_pending(struct radeon_device *rdev, int >> crtc); >> void rs600_set_safe_registers(struct radeon_device *rdev); >> extern void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc); >> @@ -464,7 +464,8 @@ void rv770_fini(struct radeon_device *rdev); >> int rv770_suspend(struct radeon_device *rdev); >> int rv770_resume(struct radeon_device *rdev); >> void rv770_pm_misc(struct radeon_device *rdev); >> -void rv770_page_flip(struct radeon_device *rdev, int crtc, u64 >> crtc_base); >> +void rv770_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base, >> + bool async); >> bool rv770_page_flip_pending(struct radeon_device *rdev, int crtc); >> void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc >> *mc); >> void r700_cp_stop(struct radeon_device *rdev); >> @@ -534,7 +535,7 @@ extern void btc_pm_init_profile(struct radeon_device >> *rdev); >> int sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); >> int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 >> dclk); >> extern void evergreen_page_flip(struct radeon_device *rdev, int crtc, >> - u64 crtc_base); >> + u64 crtc_base, bool async); >> extern bool evergreen_page_flip_pending(struct radeon_device *rdev, int >> crtc); >> extern void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc); >> void evergreen_disable_interrupt_state(struct radeon_device *rdev); >> diff --git a/drivers/gpu/drm/radeon/radeon_display.c >> b/drivers/gpu/drm/radeon/radeon_display.c >> index fcc7483..7f176ec 100644 >> --- a/drivers/gpu/drm/radeon/radeon_display.c >> +++ b/drivers/gpu/drm/radeon/radeon_display.c >> @@ -490,7 +490,7 @@ static void radeon_flip_work_func(struct work_struct >> *__work) >> vblank->linedur_ns / 1000, stat, vpos, >> hpos); >> /* do the flip (mmio) */ >> - radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base); >> + radeon_page_flip(rdev, radeon_crtc->crtc_id, work->base, >> work->async); >> radeon_crtc->flip_status = RADEON_FLIP_SUBMITTED; >> spin_unlock_irqrestore(&crtc->dev->event_lock, flags); >> @@ -525,6 +525,7 @@ static int radeon_crtc_page_flip(struct drm_crtc >> *crtc, >> work->rdev = rdev; >> work->crtc_id = radeon_crtc->crtc_id; >> work->event = event; >> + work->async = (page_flip_flags & DRM_MODE_PAGE_FLIP_ASYNC) != 0; >> /* schedule unpin of the old buffer */ >> old_radeon_fb = to_radeon_framebuffer(crtc->primary->fb); >> @@ -1630,6 +1631,9 @@ int radeon_modeset_init(struct radeon_device *rdev) >> rdev->ddev->mode_config.funcs = &radeon_mode_funcs; >> + if (radeon_use_pflipirq == 2 && rdev->family >= CHIP_R600) >> + rdev->ddev->mode_config.async_page_flip = true; >> + >> if (ASIC_IS_DCE5(rdev)) { >> rdev->ddev->mode_config.max_width = 16384; >> rdev->ddev->mode_config.max_height = 16384; >> diff --git a/drivers/gpu/drm/radeon/rs600.c >> b/drivers/gpu/drm/radeon/rs600.c >> index 6244f4e..90b04d0 100644 >> --- a/drivers/gpu/drm/radeon/rs600.c >> +++ b/drivers/gpu/drm/radeon/rs600.c >> @@ -110,7 +110,7 @@ void avivo_wait_for_vblank(struct radeon_device *rdev, >> int crtc) >> } >> } >> -void rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 >> crtc_base) >> +void rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 >> crtc_base, bool async) >> { >> struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; >> u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); >> @@ -121,6 +121,8 @@ void rs600_page_flip(struct radeon_device *rdev, int >> crtc_id, u64 crtc_base) >> WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); >> /* update the scanout addresses */ >> + WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, >> + async ? AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN : 0); >> WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + >> radeon_crtc->crtc_offset, >> (u32)crtc_base); >> WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + >> radeon_crtc->crtc_offset, >> diff --git a/drivers/gpu/drm/radeon/rv770.c >> b/drivers/gpu/drm/radeon/rv770.c >> index 01ee96a..2df7901 100644 >> --- a/drivers/gpu/drm/radeon/rv770.c >> +++ b/drivers/gpu/drm/radeon/rv770.c >> @@ -801,7 +801,7 @@ u32 rv770_get_xclk(struct radeon_device *rdev) >> return reference_clock; >> } >> -void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 >> crtc_base) >> +void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 >> crtc_base, bool async) >> { >> struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; >> u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); >> @@ -812,6 +812,8 @@ void rv770_page_flip(struct radeon_device *rdev, int >> crtc_id, u64 crtc_base) >> WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); >> /* update the scanout addresses */ >> + WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, >> + async ? AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN : 0); >> if (radeon_crtc->crtc_id) { >> WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, >> upper_32_bits(crtc_base)); >> WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, >> upper_32_bits(crtc_base)); > > > _______________________________________________ > dri-devel mailing list > dri-devel@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/dri-devel _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel