Skip to content

Commit c841e55

Browse files
Zhenneng Lialexdeucher
authored andcommitted
drm/radeon: Update pitch for page flip
When primary bo is updated, crtc's pitch may have not been updated, this will lead to show disorder content when user changes display mode, we update crtc's pitch in page flip to avoid this bug. This refers to amdgpu's pageflip. v1->v2: Update all of the pitch in all of the page_flip functions in radeon rather than just the evergreen one. v2->v3: Update pitch set method for r100 according to radeon_legacy_crtc.c Cc: Alex Deucher <[email protected]> Cc: "Christian König" <[email protected]> Cc: "Pan, Xinhui" <[email protected]> Cc: David Airlie <[email protected]> Cc: Daniel Vetter <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Signed-off-by: Zhenneng Li <[email protected]> Reviewed-by: Alex Deucher <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 9d6fa9c commit c841e55

File tree

4 files changed

+30
-3
lines changed

4 files changed

+30
-3
lines changed

drivers/gpu/drm/radeon/evergreen.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
#include <drm/drm_vblank.h>
3030
#include <drm/radeon_drm.h>
31+
#include <drm/drm_fourcc.h>
3132

3233
#include "atom.h"
3334
#include "avivod.h"
@@ -1414,10 +1415,15 @@ void evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base,
14141415
bool async)
14151416
{
14161417
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
1418+
struct drm_framebuffer *fb = radeon_crtc->base.primary->fb;
14171419

1418-
/* update the scanout addresses */
1420+
/* flip at hsync for async, default is vsync */
14191421
WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset,
14201422
async ? EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN : 0);
1423+
/* update pitch */
1424+
WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset,
1425+
fb->pitches[0] / fb->format->cpp[0]);
1426+
/* update the scanout addresses */
14211427
WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
14221428
upper_32_bits(crtc_base));
14231429
WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,

drivers/gpu/drm/radeon/r100.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,22 @@ void r100_wait_for_vblank(struct radeon_device *rdev, int crtc)
162162
void r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base, bool async)
163163
{
164164
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
165+
uint32_t crtc_pitch, pitch_pixels;
166+
struct drm_framebuffer *fb = radeon_crtc->base.primary->fb;
165167
u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK;
166168
int i;
167169

168170
/* Lock the graphics update lock */
169171
/* update the scanout addresses */
170172
WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp);
171173

174+
/* update pitch */
175+
pitch_pixels = fb->pitches[0] / fb->format->cpp[0];
176+
crtc_pitch = DIV_ROUND_UP(pitch_pixels * fb->format->cpp[0] * 8,
177+
fb->format->cpp[0] * 8 * 8);
178+
crtc_pitch |= crtc_pitch << 16;
179+
WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch);
180+
172181
/* Wait for update_pending to go high. */
173182
for (i = 0; i < rdev->usec_timeout; i++) {
174183
if (RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)

drivers/gpu/drm/radeon/rs600.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
#include <drm/drm_device.h>
4343
#include <drm/drm_vblank.h>
44+
#include <drm/drm_fourcc.h>
4445

4546
#include "atom.h"
4647
#include "radeon.h"
@@ -118,16 +119,21 @@ void avivo_wait_for_vblank(struct radeon_device *rdev, int crtc)
118119
void rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base, bool async)
119120
{
120121
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
122+
struct drm_framebuffer *fb = radeon_crtc->base.primary->fb;
121123
u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
122124
int i;
123125

124126
/* Lock the graphics update lock */
125127
tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
126128
WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
127129

128-
/* update the scanout addresses */
130+
/* flip at hsync for async, default is vsync */
129131
WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset,
130132
async ? AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN : 0);
133+
/* update pitch */
134+
WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset,
135+
fb->pitches[0] / fb->format->cpp[0]);
136+
/* update the scanout addresses */
131137
WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
132138
(u32)crtc_base);
133139
WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,

drivers/gpu/drm/radeon/rv770.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
#include <drm/drm_device.h>
3434
#include <drm/radeon_drm.h>
35+
#include <drm/drm_fourcc.h>
3536

3637
#include "atom.h"
3738
#include "avivod.h"
@@ -809,16 +810,21 @@ u32 rv770_get_xclk(struct radeon_device *rdev)
809810
void rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base, bool async)
810811
{
811812
struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
813+
struct drm_framebuffer *fb = radeon_crtc->base.primary->fb;
812814
u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset);
813815
int i;
814816

815817
/* Lock the graphics update lock */
816818
tmp |= AVIVO_D1GRPH_UPDATE_LOCK;
817819
WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp);
818820

819-
/* update the scanout addresses */
821+
/* flip at hsync for async, default is vsync */
820822
WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset,
821823
async ? AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN : 0);
824+
/* update pitch */
825+
WREG32(AVIVO_D1GRPH_PITCH + radeon_crtc->crtc_offset,
826+
fb->pitches[0] / fb->format->cpp[0]);
827+
/* update the scanout addresses */
822828
if (radeon_crtc->crtc_id) {
823829
WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base));
824830
WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base));

0 commit comments

Comments
 (0)