summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-01-26 12:10:02 -0500
committerAlex Deucher <alexdeucher@gmail.com>2010-02-01 12:07:26 -0500
commit65246545c3dd9bfef73e8a0f200bd5909b89a167 (patch)
tree9a94895816d446d31a004d29bce6ccf011e5c134
parentc05cad56b69d239fa2e69905d15f4f08b9db4c55 (diff)
evergreen: add hw cursor support
-rw-r--r--src/radeon_cursor.c68
1 files changed, 64 insertions, 4 deletions
diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index cf5e9a04..2e607108 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -137,6 +137,48 @@ avivo_lock_cursor(xf86CrtcPtr crtc, Bool lock)
OUTREG(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset, tmp);
}
+static void
+evergreen_setup_cursor(xf86CrtcPtr crtc, Bool enable)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ RADEONInfoPtr info = RADEONPTR(crtc->scrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ /* always use the same cursor mode even if the cursor is disabled,
+ * otherwise you may end up with cursor curruption bands
+ */
+ OUTREG(EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset,
+ EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT));
+
+ if (enable) {
+ OUTREG(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, 0);
+ OUTREG(EVERGREEN_CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
+ (info->fbLocation + radeon_crtc->cursor_offset + pScrn->fbOffset)
+ & EVERGREEN_CUR_SURFACE_ADDRESS_MASK);
+ OUTREG(EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset,
+ EVERGREEN_CURSOR_EN | EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT));
+ }
+}
+
+static void
+evergreen_lock_cursor(xf86CrtcPtr crtc, Bool lock)
+{
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ RADEONInfoPtr info = RADEONPTR(crtc->scrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ uint32_t tmp;
+
+ tmp = INREG(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset);
+
+ if (lock)
+ tmp |= EVERGREEN_CURSOR_UPDATE_LOCK;
+ else
+ tmp &= ~EVERGREEN_CURSOR_UPDATE_LOCK;
+
+ OUTREG(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset, tmp);
+}
+
void
radeon_crtc_show_cursor (xf86CrtcPtr crtc)
{
@@ -146,7 +188,11 @@ radeon_crtc_show_cursor (xf86CrtcPtr crtc)
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- if (IS_AVIVO_VARIANT) {
+ if (IS_DCE4_VARIANT) {
+ evergreen_lock_cursor(crtc, TRUE);
+ evergreen_setup_cursor(crtc, TRUE);
+ evergreen_lock_cursor(crtc, FALSE);
+ } else if (IS_AVIVO_VARIANT) {
avivo_lock_cursor(crtc, TRUE);
avivo_setup_cursor(crtc, TRUE);
avivo_lock_cursor(crtc, FALSE);
@@ -162,7 +208,7 @@ radeon_crtc_show_cursor (xf86CrtcPtr crtc)
return;
}
- OUTREGP(RADEON_MM_DATA, RADEON_CRTC_CUR_EN | 2 << 20,
+ OUTREGP(RADEON_MM_DATA, RADEON_CRTC_CUR_EN | 2 << 20,
~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK));
}
}
@@ -176,7 +222,11 @@ radeon_crtc_hide_cursor (xf86CrtcPtr crtc)
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- if (IS_AVIVO_VARIANT) {
+ if (IS_DCE4_VARIANT) {
+ evergreen_lock_cursor(crtc, TRUE);
+ evergreen_setup_cursor(crtc, FALSE);
+ evergreen_lock_cursor(crtc, TRUE);
+ } else if (IS_AVIVO_VARIANT) {
avivo_lock_cursor(crtc, TRUE);
avivo_setup_cursor(crtc, FALSE);
avivo_lock_cursor(crtc, FALSE);
@@ -214,7 +264,16 @@ radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
if (xorigin >= CURSOR_WIDTH) xorigin = CURSOR_WIDTH - 1;
if (yorigin >= CURSOR_HEIGHT) yorigin = CURSOR_HEIGHT - 1;
- if (IS_AVIVO_VARIANT) {
+ if (IS_DCE4_VARIANT) {
+ /* XXX - does evergreen need a similar hack as below? */
+ evergreen_lock_cursor(crtc, TRUE);
+ OUTREG(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, ((xorigin ? 0 : x) << 16)
+ | (yorigin ? 0 : y));
+ OUTREG(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin);
+ OUTREG(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset,
+ ((CURSOR_WIDTH - 1) << 16) | (CURSOR_HEIGHT - 1));
+ evergreen_lock_cursor(crtc, FALSE);
+ } else if (IS_AVIVO_VARIANT) {
int w = CURSOR_WIDTH;
/* avivo cursor spans the full fb width */
@@ -373,6 +432,7 @@ Bool RADEONCursorInit(ScreenPtr pScreen)
(unsigned int)radeon_crtc->cursor_offset);
}
/* set the cursor mode the same on both crtcs to avoid corruption */
+ /* XXX check if this is needed on evergreen */
if (IS_AVIVO_VARIANT)
OUTREG(AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset,
(AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));