sm501: Add missing arbitration control register
[qemu.git] / hw / display / pxa2xx_template.h
1 /*
2 * Intel XScale PXA255/270 LCDC emulation.
3 *
4 * Copyright (c) 2006 Openedhand Ltd.
5 * Written by Andrzej Zaborowski <balrog@zabor.org>
6 *
7 * This code is licensed under the GPLv2.
8 *
9 * Framebuffer format conversion routines.
10 */
11
12 # define SKIP_PIXEL(to) to += deststep
13 #if BITS == 8
14 # define COPY_PIXEL(to, from) do { *to = from; SKIP_PIXEL(to); } while (0)
15 #elif BITS == 15 || BITS == 16
16 # define COPY_PIXEL(to, from) \
17 do { \
18 *(uint16_t *) to = from; \
19 SKIP_PIXEL(to); \
20 } while (0)
21 #elif BITS == 24
22 # define COPY_PIXEL(to, from) \
23 do { \
24 *(uint16_t *) to = from; \
25 *(to + 2) = (from) >> 16; \
26 SKIP_PIXEL(to); \
27 } while (0)
28 #elif BITS == 32
29 # define COPY_PIXEL(to, from) \
30 do { \
31 *(uint32_t *) to = from; \
32 SKIP_PIXEL(to); \
33 } while (0)
34 #else
35 # error unknown bit depth
36 #endif
37
38 #ifdef HOST_WORDS_BIGENDIAN
39 # define SWAP_WORDS 1
40 #endif
41
42 #define FN_2(x) FN(x + 1) FN(x)
43 #define FN_4(x) FN_2(x + 2) FN_2(x)
44
45 static void glue(pxa2xx_draw_line2_, BITS)(void *opaque,
46 uint8_t *dest, const uint8_t *src, int width, int deststep)
47 {
48 uint32_t *palette = opaque;
49 uint32_t data;
50 while (width > 0) {
51 data = *(uint32_t *) src;
52 #define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
53 #ifdef SWAP_WORDS
54 FN_4(12)
55 FN_4(8)
56 FN_4(4)
57 FN_4(0)
58 #else
59 FN_4(0)
60 FN_4(4)
61 FN_4(8)
62 FN_4(12)
63 #endif
64 #undef FN
65 width -= 16;
66 src += 4;
67 }
68 }
69
70 static void glue(pxa2xx_draw_line4_, BITS)(void *opaque,
71 uint8_t *dest, const uint8_t *src, int width, int deststep)
72 {
73 uint32_t *palette = opaque;
74 uint32_t data;
75 while (width > 0) {
76 data = *(uint32_t *) src;
77 #define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
78 #ifdef SWAP_WORDS
79 FN_2(6)
80 FN_2(4)
81 FN_2(2)
82 FN_2(0)
83 #else
84 FN_2(0)
85 FN_2(2)
86 FN_2(4)
87 FN_2(6)
88 #endif
89 #undef FN
90 width -= 8;
91 src += 4;
92 }
93 }
94
95 static void glue(pxa2xx_draw_line8_, BITS)(void *opaque,
96 uint8_t *dest, const uint8_t *src, int width, int deststep)
97 {
98 uint32_t *palette = opaque;
99 uint32_t data;
100 while (width > 0) {
101 data = *(uint32_t *) src;
102 #define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
103 #ifdef SWAP_WORDS
104 FN(24)
105 FN(16)
106 FN(8)
107 FN(0)
108 #else
109 FN(0)
110 FN(8)
111 FN(16)
112 FN(24)
113 #endif
114 #undef FN
115 width -= 4;
116 src += 4;
117 }
118 }
119
120 static void glue(pxa2xx_draw_line16_, BITS)(void *opaque,
121 uint8_t *dest, const uint8_t *src, int width, int deststep)
122 {
123 uint32_t data;
124 unsigned int r, g, b;
125 while (width > 0) {
126 data = *(uint32_t *) src;
127 #ifdef SWAP_WORDS
128 data = bswap32(data);
129 #endif
130 b = (data & 0x1f) << 3;
131 data >>= 5;
132 g = (data & 0x3f) << 2;
133 data >>= 6;
134 r = (data & 0x1f) << 3;
135 data >>= 5;
136 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
137 b = (data & 0x1f) << 3;
138 data >>= 5;
139 g = (data & 0x3f) << 2;
140 data >>= 6;
141 r = (data & 0x1f) << 3;
142 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
143 width -= 2;
144 src += 4;
145 }
146 }
147
148 static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque,
149 uint8_t *dest, const uint8_t *src, int width, int deststep)
150 {
151 uint32_t data;
152 unsigned int r, g, b;
153 while (width > 0) {
154 data = *(uint32_t *) src;
155 #ifdef SWAP_WORDS
156 data = bswap32(data);
157 #endif
158 b = (data & 0x1f) << 3;
159 data >>= 5;
160 g = (data & 0x1f) << 3;
161 data >>= 5;
162 r = (data & 0x1f) << 3;
163 data >>= 5;
164 if (data & 1)
165 SKIP_PIXEL(dest);
166 else
167 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
168 data >>= 1;
169 b = (data & 0x1f) << 3;
170 data >>= 5;
171 g = (data & 0x1f) << 3;
172 data >>= 5;
173 r = (data & 0x1f) << 3;
174 data >>= 5;
175 if (data & 1)
176 SKIP_PIXEL(dest);
177 else
178 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
179 width -= 2;
180 src += 4;
181 }
182 }
183
184 static void glue(pxa2xx_draw_line18_, BITS)(void *opaque,
185 uint8_t *dest, const uint8_t *src, int width, int deststep)
186 {
187 uint32_t data;
188 unsigned int r, g, b;
189 while (width > 0) {
190 data = *(uint32_t *) src;
191 #ifdef SWAP_WORDS
192 data = bswap32(data);
193 #endif
194 b = (data & 0x3f) << 2;
195 data >>= 6;
196 g = (data & 0x3f) << 2;
197 data >>= 6;
198 r = (data & 0x3f) << 2;
199 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
200 width -= 1;
201 src += 4;
202 }
203 }
204
205 /* The wicked packed format */
206 static void glue(pxa2xx_draw_line18p_, BITS)(void *opaque,
207 uint8_t *dest, const uint8_t *src, int width, int deststep)
208 {
209 uint32_t data[3];
210 unsigned int r, g, b;
211 while (width > 0) {
212 data[0] = *(uint32_t *) src;
213 src += 4;
214 data[1] = *(uint32_t *) src;
215 src += 4;
216 data[2] = *(uint32_t *) src;
217 src += 4;
218 #ifdef SWAP_WORDS
219 data[0] = bswap32(data[0]);
220 data[1] = bswap32(data[1]);
221 data[2] = bswap32(data[2]);
222 #endif
223 b = (data[0] & 0x3f) << 2;
224 data[0] >>= 6;
225 g = (data[0] & 0x3f) << 2;
226 data[0] >>= 6;
227 r = (data[0] & 0x3f) << 2;
228 data[0] >>= 12;
229 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
230 b = (data[0] & 0x3f) << 2;
231 data[0] >>= 6;
232 g = ((data[1] & 0xf) << 4) | (data[0] << 2);
233 data[1] >>= 4;
234 r = (data[1] & 0x3f) << 2;
235 data[1] >>= 12;
236 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
237 b = (data[1] & 0x3f) << 2;
238 data[1] >>= 6;
239 g = (data[1] & 0x3f) << 2;
240 data[1] >>= 6;
241 r = ((data[2] & 0x3) << 6) | (data[1] << 2);
242 data[2] >>= 8;
243 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
244 b = (data[2] & 0x3f) << 2;
245 data[2] >>= 6;
246 g = (data[2] & 0x3f) << 2;
247 data[2] >>= 6;
248 r = data[2] << 2;
249 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
250 width -= 4;
251 }
252 }
253
254 static void glue(pxa2xx_draw_line19_, BITS)(void *opaque,
255 uint8_t *dest, const uint8_t *src, int width, int deststep)
256 {
257 uint32_t data;
258 unsigned int r, g, b;
259 while (width > 0) {
260 data = *(uint32_t *) src;
261 #ifdef SWAP_WORDS
262 data = bswap32(data);
263 #endif
264 b = (data & 0x3f) << 2;
265 data >>= 6;
266 g = (data & 0x3f) << 2;
267 data >>= 6;
268 r = (data & 0x3f) << 2;
269 data >>= 6;
270 if (data & 1)
271 SKIP_PIXEL(dest);
272 else
273 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
274 width -= 1;
275 src += 4;
276 }
277 }
278
279 /* The wicked packed format */
280 static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
281 uint8_t *dest, const uint8_t *src, int width, int deststep)
282 {
283 uint32_t data[3];
284 unsigned int r, g, b;
285 while (width > 0) {
286 data[0] = *(uint32_t *) src;
287 src += 4;
288 data[1] = *(uint32_t *) src;
289 src += 4;
290 data[2] = *(uint32_t *) src;
291 src += 4;
292 # ifdef SWAP_WORDS
293 data[0] = bswap32(data[0]);
294 data[1] = bswap32(data[1]);
295 data[2] = bswap32(data[2]);
296 # endif
297 b = (data[0] & 0x3f) << 2;
298 data[0] >>= 6;
299 g = (data[0] & 0x3f) << 2;
300 data[0] >>= 6;
301 r = (data[0] & 0x3f) << 2;
302 data[0] >>= 6;
303 if (data[0] & 1)
304 SKIP_PIXEL(dest);
305 else
306 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
307 data[0] >>= 6;
308 b = (data[0] & 0x3f) << 2;
309 data[0] >>= 6;
310 g = ((data[1] & 0xf) << 4) | (data[0] << 2);
311 data[1] >>= 4;
312 r = (data[1] & 0x3f) << 2;
313 data[1] >>= 6;
314 if (data[1] & 1)
315 SKIP_PIXEL(dest);
316 else
317 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
318 data[1] >>= 6;
319 b = (data[1] & 0x3f) << 2;
320 data[1] >>= 6;
321 g = (data[1] & 0x3f) << 2;
322 data[1] >>= 6;
323 r = ((data[2] & 0x3) << 6) | (data[1] << 2);
324 data[2] >>= 2;
325 if (data[2] & 1)
326 SKIP_PIXEL(dest);
327 else
328 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
329 data[2] >>= 6;
330 b = (data[2] & 0x3f) << 2;
331 data[2] >>= 6;
332 g = (data[2] & 0x3f) << 2;
333 data[2] >>= 6;
334 r = data[2] << 2;
335 data[2] >>= 6;
336 if (data[2] & 1)
337 SKIP_PIXEL(dest);
338 else
339 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
340 width -= 4;
341 }
342 }
343
344 static void glue(pxa2xx_draw_line24_, BITS)(void *opaque,
345 uint8_t *dest, const uint8_t *src, int width, int deststep)
346 {
347 uint32_t data;
348 unsigned int r, g, b;
349 while (width > 0) {
350 data = *(uint32_t *) src;
351 #ifdef SWAP_WORDS
352 data = bswap32(data);
353 #endif
354 b = data & 0xff;
355 data >>= 8;
356 g = data & 0xff;
357 data >>= 8;
358 r = data & 0xff;
359 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
360 width -= 1;
361 src += 4;
362 }
363 }
364
365 static void glue(pxa2xx_draw_line24t_, BITS)(void *opaque,
366 uint8_t *dest, const uint8_t *src, int width, int deststep)
367 {
368 uint32_t data;
369 unsigned int r, g, b;
370 while (width > 0) {
371 data = *(uint32_t *) src;
372 #ifdef SWAP_WORDS
373 data = bswap32(data);
374 #endif
375 b = (data & 0x7f) << 1;
376 data >>= 7;
377 g = data & 0xff;
378 data >>= 8;
379 r = data & 0xff;
380 data >>= 8;
381 if (data & 1)
382 SKIP_PIXEL(dest);
383 else
384 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
385 width -= 1;
386 src += 4;
387 }
388 }
389
390 static void glue(pxa2xx_draw_line25_, BITS)(void *opaque,
391 uint8_t *dest, const uint8_t *src, int width, int deststep)
392 {
393 uint32_t data;
394 unsigned int r, g, b;
395 while (width > 0) {
396 data = *(uint32_t *) src;
397 #ifdef SWAP_WORDS
398 data = bswap32(data);
399 #endif
400 b = data & 0xff;
401 data >>= 8;
402 g = data & 0xff;
403 data >>= 8;
404 r = data & 0xff;
405 data >>= 8;
406 if (data & 1)
407 SKIP_PIXEL(dest);
408 else
409 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
410 width -= 1;
411 src += 4;
412 }
413 }
414
415 /* Overlay planes disabled, no transparency */
416 static drawfn glue(pxa2xx_draw_fn_, BITS)[16] =
417 {
418 [0 ... 0xf] = NULL,
419 [pxa_lcdc_2bpp] = glue(pxa2xx_draw_line2_, BITS),
420 [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS),
421 [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS),
422 [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16_, BITS),
423 [pxa_lcdc_18bpp] = glue(pxa2xx_draw_line18_, BITS),
424 [pxa_lcdc_18pbpp] = glue(pxa2xx_draw_line18p_, BITS),
425 [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24_, BITS),
426 };
427
428 /* Overlay planes enabled, transparency used */
429 static drawfn glue(glue(pxa2xx_draw_fn_, BITS), t)[16] =
430 {
431 [0 ... 0xf] = NULL,
432 [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS),
433 [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS),
434 [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16t_, BITS),
435 [pxa_lcdc_19bpp] = glue(pxa2xx_draw_line19_, BITS),
436 [pxa_lcdc_19pbpp] = glue(pxa2xx_draw_line19p_, BITS),
437 [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24t_, BITS),
438 [pxa_lcdc_25bpp] = glue(pxa2xx_draw_line25_, BITS),
439 };
440
441 #undef BITS
442 #undef COPY_PIXEL
443 #undef SKIP_PIXEL
444
445 #ifdef SWAP_WORDS
446 # undef SWAP_WORDS
447 #endif