This source file includes following definitions.
- atyfb_cursor
- aty_init_cursor
1
2
3
4
5
6 #include <linux/fb.h>
7 #include <linux/init.h>
8 #include <linux/string.h>
9 #include "../core/fb_draw.h"
10
11 #include <asm/io.h>
12
13 #ifdef __sparc__
14 #include <asm/fbio.h>
15 #endif
16
17 #include <video/mach64.h>
18 #include "atyfb.h"
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 static const u8 cursor_bits_lookup[16] = {
64 0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
65 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55
66 };
67
68 static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
69 {
70 struct atyfb_par *par = (struct atyfb_par *) info->par;
71 u16 xoff, yoff;
72 int x, y, h;
73
74 #ifdef __sparc__
75 if (par->mmaped)
76 return -EPERM;
77 #endif
78 if (par->asleep)
79 return -EPERM;
80
81 wait_for_fifo(1, par);
82 if (cursor->enable)
83 aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
84 | HWCURSOR_ENABLE, par);
85 else
86 aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
87 & ~HWCURSOR_ENABLE, par);
88
89
90 if (cursor->set & FB_CUR_SETPOS) {
91 x = cursor->image.dx - cursor->hot.x - info->var.xoffset;
92 if (x < 0) {
93 xoff = -x;
94 x = 0;
95 } else {
96 xoff = 0;
97 }
98
99 y = cursor->image.dy - cursor->hot.y - info->var.yoffset;
100 if (y < 0) {
101 yoff = -y;
102 y = 0;
103 } else {
104 yoff = 0;
105 }
106
107 h = cursor->image.height;
108
109
110
111
112
113 if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN) {
114 y<<=1;
115 h<<=1;
116 }
117 wait_for_fifo(3, par);
118 aty_st_le32(CUR_OFFSET, (info->fix.smem_len >> 3) + (yoff << 1), par);
119 aty_st_le32(CUR_HORZ_VERT_OFF,
120 ((u32) (64 - h + yoff) << 16) | xoff, par);
121 aty_st_le32(CUR_HORZ_VERT_POSN, ((u32) y << 16) | x, par);
122 }
123
124
125 if (cursor->set & FB_CUR_SETCMAP) {
126 u32 fg_idx, bg_idx, fg, bg;
127
128 fg_idx = cursor->image.fg_color;
129 bg_idx = cursor->image.bg_color;
130
131 fg = ((info->cmap.red[fg_idx] & 0xff) << 24) |
132 ((info->cmap.green[fg_idx] & 0xff) << 16) |
133 ((info->cmap.blue[fg_idx] & 0xff) << 8) | 0xff;
134
135 bg = ((info->cmap.red[bg_idx] & 0xff) << 24) |
136 ((info->cmap.green[bg_idx] & 0xff) << 16) |
137 ((info->cmap.blue[bg_idx] & 0xff) << 8);
138
139 wait_for_fifo(2, par);
140 aty_st_le32(CUR_CLR0, bg, par);
141 aty_st_le32(CUR_CLR1, fg, par);
142 }
143
144 if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
145 u8 *src = (u8 *)cursor->image.data;
146 u8 *msk = (u8 *)cursor->mask;
147 u8 __iomem *dst = (u8 __iomem *)info->sprite.addr;
148 unsigned int width = (cursor->image.width + 7) >> 3;
149 unsigned int height = cursor->image.height;
150 unsigned int align = info->sprite.scan_align;
151
152 unsigned int i, j, offset;
153 u8 m, b;
154
155
156 fb_memset(dst, 0xaa, 1024);
157
158 offset = align - width*2;
159
160 for (i = 0; i < height; i++) {
161 for (j = 0; j < width; j++) {
162 u16 l = 0xaaaa;
163 b = *src++;
164 m = *msk++;
165 switch (cursor->rop) {
166 case ROP_XOR:
167
168 l = cursor_bits_lookup[(b ^ m) >> 4] |
169
170 (cursor_bits_lookup[(b ^ m) & 0x0f] << 8);
171 break;
172 case ROP_COPY:
173
174 l = cursor_bits_lookup[(b & m) >> 4] |
175
176 (cursor_bits_lookup[(b & m) & 0x0f] << 8);
177 break;
178 }
179
180
181
182
183 if ((j + 1) * 8 > cursor->image.width) {
184 l = comp(l, 0xaaaa,
185 (1 << ((cursor->image.width & 7) * 2)) - 1);
186 }
187 fb_writeb(l & 0xff, dst++);
188 fb_writeb(l >> 8, dst++);
189 }
190 dst += offset;
191 }
192 }
193
194 return 0;
195 }
196
197 int aty_init_cursor(struct fb_info *info)
198 {
199 unsigned long addr;
200
201 info->fix.smem_len -= PAGE_SIZE;
202
203 #ifdef __sparc__
204 addr = (unsigned long) info->screen_base - 0x800000 + info->fix.smem_len;
205 info->sprite.addr = (u8 *) addr;
206 #else
207 #ifdef __BIG_ENDIAN
208 addr = info->fix.smem_start - 0x800000 + info->fix.smem_len;
209 info->sprite.addr = (u8 *) ioremap(addr, 1024);
210 #else
211 addr = (unsigned long) info->screen_base + info->fix.smem_len;
212 info->sprite.addr = (u8 *) addr;
213 #endif
214 #endif
215 if (!info->sprite.addr)
216 return -ENXIO;
217 info->sprite.size = PAGE_SIZE;
218 info->sprite.scan_align = 16;
219 info->sprite.buf_align = 16;
220 info->sprite.flags = FB_PIXMAP_IO;
221
222 info->fbops->fb_cursor = atyfb_cursor;
223
224 return 0;
225 }
226