Add qemu 2.4.0
[kvmfornfv.git] / qemu / 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