diff options
author | Alex Deucher <alex@cube.(none)> | 2008-04-30 18:33:04 -0400 |
---|---|---|
committer | Alex Deucher <alex@cube.(none)> | 2008-04-30 18:33:04 -0400 |
commit | 3d469cbc3225d890a895dac7cbc1ab7e08054b48 (patch) | |
tree | ea09f05b439462f63d5a212028786b103333ce08 /src | |
parent | 445b71021843665ba32f37b2ce5c9d2857c07cc7 (diff) |
RADEON: lock the cursors when updating
this should fix occasional corruption seen when updating
the cursor.
Diffstat (limited to 'src')
-rw-r--r-- | src/radeon_cursor.c | 24 | ||||
-rw-r--r-- | src/radeon_reg.h | 2 |
2 files changed, 26 insertions, 0 deletions
diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c index de64deec..b82484e5 100644 --- a/src/radeon_cursor.c +++ b/src/radeon_cursor.c @@ -108,6 +108,24 @@ avivo_setup_cursor(xf86CrtcPtr crtc, Bool enable) } } +static void +avivo_lock_cursor(xf86CrtcPtr crtc, Bool lock) +{ + RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + RADEONInfoPtr info = RADEONPTR(crtc->scrn); + unsigned char *RADEONMMIO = info->MMIO; + CARD32 tmp; + + tmp = INREG(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset); + + if (lock) + tmp |= AVIVO_D1CURSOR_UPDATE_LOCK; + else + tmp &= ~AVIVO_D1CURSOR_UPDATE_LOCK; + + OUTREG(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset, tmp); +} + void radeon_crtc_show_cursor (xf86CrtcPtr crtc) { @@ -118,10 +136,12 @@ radeon_crtc_show_cursor (xf86CrtcPtr crtc) unsigned char *RADEONMMIO = info->MMIO; if (IS_AVIVO_VARIANT) { + avivo_lock_cursor(crtc, TRUE); OUTREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset, INREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset) | AVIVO_D1CURSOR_EN); avivo_setup_cursor(crtc, TRUE); + avivo_lock_cursor(crtc, FALSE); } else { switch (crtc_id) { case 0: @@ -149,10 +169,12 @@ radeon_crtc_hide_cursor (xf86CrtcPtr crtc) unsigned char *RADEONMMIO = info->MMIO; if (IS_AVIVO_VARIANT) { + avivo_lock_cursor(crtc, TRUE); OUTREG(AVIVO_D1CUR_CONTROL+ radeon_crtc->crtc_offset, INREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset) & ~(AVIVO_D1CURSOR_EN)); avivo_setup_cursor(crtc, FALSE); + avivo_lock_cursor(crtc, FALSE); } else { switch(crtc_id) { case 0: @@ -195,9 +217,11 @@ radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y) /* avivo cursor spans the full fb width */ x += crtc->x; y += crtc->y; + avivo_lock_cursor(crtc, TRUE); OUTREG(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset, ((xorigin ? 0 : x) << 16) | (yorigin ? 0 : y)); OUTREG(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin); + avivo_lock_cursor(crtc, FALSE); } else { if (crtc_id == 0) { OUTREG(RADEON_CUR_HORZ_VERT_OFF, (RADEON_CUR_LOCK diff --git a/src/radeon_reg.h b/src/radeon_reg.h index 0d684a59..815bcaac 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -3540,6 +3540,8 @@ #define AVIVO_D1CUR_SIZE 0x6410 #define AVIVO_D1CUR_POSITION 0x6414 #define AVIVO_D1CUR_HOT_SPOT 0x6418 +#define AVIVO_D1CUR_UPDATE 0x6424 +# define AVIVO_D1CURSOR_UPDATE_LOCK (1 << 16) #define AVIVO_DC_LUT_RW_SELECT 0x6480 #define AVIVO_DC_LUT_RW_MODE 0x6484 |