11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  ATI Mach64 CT/VT/GT/LT Cursor Support
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fb.h>
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h>
819757fc8432ac97a07a890d6310cccc1896a1b36Tomi Valkeinen#include "../core/fb_draw.h"
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h>
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef __sparc__
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/fbio.h>
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <video/mach64.h>
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "atyfb.h"
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The hardware cursor definition requires 2 bits per pixel. The
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Cursor size reguardless of the visible cursor size is 64 pixels
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * by 64 lines. The total memory required to define the cursor is
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 16 bytes / line for 64 lines or 1024 bytes of data. The data
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * must be in a contigiuos format. The 2 bit cursor code values are
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * as follows:
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	00 - pixel colour = CURSOR_CLR_0
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	01 - pixel colour = CURSOR_CLR_1
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	10 - pixel colour = transparent (current display pixel)
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	11 - pixel colour = 1's complement of current display pixel
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Cursor Offset        64 pixels		 Actual Displayed Area
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *            \_________________________/
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	      |			|	|	|
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	      |<--------------->|	|	|
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	      | CURS_HORZ_OFFSET|	|	|
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	      |			|_______|	|  64 Lines
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	      |			   ^	|	|
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	      |			   |	|	|
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	      |		CURS_VERT_OFFSET|	|
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	      |			   |	|	|
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	      |____________________|____|	|
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The Screen position of the top left corner of the displayed
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * cursor is specificed by CURS_HORZ_VERT_POSN. Care must be taken
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * when the cursor hot spot is not the top left corner and the
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * physical cursor position becomes negative. It will be be displayed
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * if either the horizontal or vertical cursor position is negative
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If x becomes negative the cursor manager must adjust the CURS_HORZ_OFFSET
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to a larger number and saturate CUR_HORZ_POSN to zero.
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * if Y becomes negative, CUR_VERT_OFFSET must be adjusted to a larger number,
5525985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * CUR_OFFSET must be adjusted to a point to the appropriate line in the cursor
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * definitation and CUR_VERT_POSN must be saturated to zero.
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    /*
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds     *  Hardware Cursor support.
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds     */
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const u8 cursor_bits_lookup[16] = {
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct atyfb_par *par = (struct atyfb_par *) info->par;
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u16 xoff, yoff;
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int x, y, h;
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef __sparc__
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (par->mmaped)
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EPERM;
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (par->asleep)
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EPERM;
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	wait_for_fifo(1, par);
812f682fae611df642acfb99b5f2fd665f001cd253Krzysztof Helt	if (cursor->enable)
822f682fae611df642acfb99b5f2fd665f001cd253Krzysztof Helt		aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
832f682fae611df642acfb99b5f2fd665f001cd253Krzysztof Helt			    | HWCURSOR_ENABLE, par);
842f682fae611df642acfb99b5f2fd665f001cd253Krzysztof Helt	else
852f682fae611df642acfb99b5f2fd665f001cd253Krzysztof Helt		aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
862f682fae611df642acfb99b5f2fd665f001cd253Krzysztof Helt				& ~HWCURSOR_ENABLE, par);
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* set position */
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (cursor->set & FB_CUR_SETPOS) {
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		x = cursor->image.dx - cursor->hot.x - info->var.xoffset;
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (x < 0) {
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			xoff = -x;
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			x = 0;
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			xoff = 0;
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		y = cursor->image.dy - cursor->hot.y - info->var.yoffset;
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (y < 0) {
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			yoff = -y;
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			y = 0;
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			yoff = 0;
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		h = cursor->image.height;
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * In doublescan mode, the cursor location
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * and heigh also needs to be doubled.
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 */
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds                if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN) {
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			y<<=1;
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			h<<=1;
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1162f682fae611df642acfb99b5f2fd665f001cd253Krzysztof Helt		wait_for_fifo(3, par);
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		aty_st_le32(CUR_OFFSET, (info->fix.smem_len >> 3) + (yoff << 1), par);
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		aty_st_le32(CUR_HORZ_VERT_OFF,
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    ((u32) (64 - h + yoff) << 16) | xoff, par);
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		aty_st_le32(CUR_HORZ_VERT_POSN, ((u32) y << 16) | x, par);
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Set color map */
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (cursor->set & FB_CUR_SETCMAP) {
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		u32 fg_idx, bg_idx, fg, bg;
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		fg_idx = cursor->image.fg_color;
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		bg_idx = cursor->image.bg_color;
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13072c24cc51aef31219f2e258b4dcb68e09399e040Antonino A. Daplas		fg = ((info->cmap.red[fg_idx] & 0xff) << 24) |
13172c24cc51aef31219f2e258b4dcb68e09399e040Antonino A. Daplas		     ((info->cmap.green[fg_idx] & 0xff) << 16) |
13272c24cc51aef31219f2e258b4dcb68e09399e040Antonino A. Daplas		     ((info->cmap.blue[fg_idx] & 0xff) << 8) | 0xff;
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13472c24cc51aef31219f2e258b4dcb68e09399e040Antonino A. Daplas		bg = ((info->cmap.red[bg_idx] & 0xff) << 24) |
13572c24cc51aef31219f2e258b4dcb68e09399e040Antonino A. Daplas		     ((info->cmap.green[bg_idx] & 0xff) << 16) |
13672c24cc51aef31219f2e258b4dcb68e09399e040Antonino A. Daplas		     ((info->cmap.blue[bg_idx] & 0xff) << 8);
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		wait_for_fifo(2, par);
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		aty_st_le32(CUR_CLR0, bg, par);
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		aty_st_le32(CUR_CLR1, fg, par);
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    u8 *src = (u8 *)cursor->image.data;
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    u8 *msk = (u8 *)cursor->mask;
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    u8 __iomem *dst = (u8 __iomem *)info->sprite.addr;
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    unsigned int width = (cursor->image.width + 7) >> 3;
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    unsigned int height = cursor->image.height;
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    unsigned int align = info->sprite.scan_align;
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    unsigned int i, j, offset;
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    u8 m, b;
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    // Clear cursor image with 1010101010...
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    fb_memset(dst, 0xaa, 1024);
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    offset = align - width*2;
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    for (i = 0; i < height; i++) {
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (j = 0; j < width; j++) {
16143751a1b8ee2e70ce392bf31ef3133da324e68b3Mikulas Patocka			u16 l = 0xaaaa;
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			b = *src++;
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			m = *msk++;
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			switch (cursor->rop) {
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case ROP_XOR:
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    // Upper 4 bits of mask data
16743751a1b8ee2e70ce392bf31ef3133da324e68b3Mikulas Patocka			    l = cursor_bits_lookup[(b ^ m) >> 4] |
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    // Lower 4 bits of mask
16943751a1b8ee2e70ce392bf31ef3133da324e68b3Mikulas Patocka				    (cursor_bits_lookup[(b ^ m) & 0x0f] << 8);
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    break;
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			case ROP_COPY:
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    // Upper 4 bits of mask data
17343751a1b8ee2e70ce392bf31ef3133da324e68b3Mikulas Patocka			    l = cursor_bits_lookup[(b & m) >> 4] |
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    // Lower 4 bits of mask
17543751a1b8ee2e70ce392bf31ef3133da324e68b3Mikulas Patocka				    (cursor_bits_lookup[(b & m) & 0x0f] << 8);
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    break;
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
17843751a1b8ee2e70ce392bf31ef3133da324e68b3Mikulas Patocka			/*
17943751a1b8ee2e70ce392bf31ef3133da324e68b3Mikulas Patocka			 * If cursor size is not a multiple of 8 characters
18043751a1b8ee2e70ce392bf31ef3133da324e68b3Mikulas Patocka			 * we must pad it with transparent pattern (0xaaaa).
18143751a1b8ee2e70ce392bf31ef3133da324e68b3Mikulas Patocka			 */
18243751a1b8ee2e70ce392bf31ef3133da324e68b3Mikulas Patocka			if ((j + 1) * 8 > cursor->image.width) {
18343751a1b8ee2e70ce392bf31ef3133da324e68b3Mikulas Patocka				l = comp(l, 0xaaaa,
18443751a1b8ee2e70ce392bf31ef3133da324e68b3Mikulas Patocka				    (1 << ((cursor->image.width & 7) * 2)) - 1);
18543751a1b8ee2e70ce392bf31ef3133da324e68b3Mikulas Patocka			}
18643751a1b8ee2e70ce392bf31ef3133da324e68b3Mikulas Patocka			fb_writeb(l & 0xff, dst++);
18743751a1b8ee2e70ce392bf31ef3133da324e68b3Mikulas Patocka			fb_writeb(l >> 8, dst++);
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dst += offset;
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    }
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19648c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanint aty_init_cursor(struct fb_info *info)
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long addr;
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	info->fix.smem_len -= PAGE_SIZE;
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef __sparc__
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	addr = (unsigned long) info->screen_base - 0x800000 + info->fix.smem_len;
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	info->sprite.addr = (u8 *) addr;
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef __BIG_ENDIAN
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	addr = info->fix.smem_start - 0x800000 + info->fix.smem_len;
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	info->sprite.addr = (u8 *) ioremap(addr, 1024);
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	addr = (unsigned long) info->screen_base + info->fix.smem_len;
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	info->sprite.addr = (u8 *) addr;
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!info->sprite.addr)
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENXIO;
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	info->sprite.size = PAGE_SIZE;
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	info->sprite.scan_align = 16;	/* Scratch pad 64 bytes wide */
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	info->sprite.buf_align = 16; 	/* and 64 lines tall. */
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	info->sprite.flags = FB_PIXMAP_IO;
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	info->fbops->fb_cursor = atyfb_cursor;
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
226