xref: /openbmc/qemu/hw/display/pl110_template.h (revision 2993683b)
1 /*
2  * Arm PrimeCell PL110 Color LCD Controller
3  *
4  * Copyright (c) 2005 CodeSourcery, LLC.
5  * Written by Paul Brook
6  *
7  * This code is licensed under the GNU LGPL
8  *
9  * Framebuffer format conversion routines.
10  */
11 
12 #ifndef ORDER
13 
14 #if BITS == 8
15 #define COPY_PIXEL(to, from) *(to++) = from
16 #elif BITS == 15 || BITS == 16
17 #define COPY_PIXEL(to, from) *(uint16_t *)to = from; to += 2;
18 #elif BITS == 24
19 #define COPY_PIXEL(to, from) \
20   *(to++) = from; *(to++) = (from) >> 8; *(to++) = (from) >> 16
21 #elif BITS == 32
22 #define COPY_PIXEL(to, from) *(uint32_t *)to = from; to += 4;
23 #else
24 #error unknown bit depth
25 #endif
26 
27 #undef RGB
28 #define BORDER bgr
29 #define ORDER 0
30 #include "pl110_template.h"
31 #define ORDER 1
32 #include "pl110_template.h"
33 #define ORDER 2
34 #include "pl110_template.h"
35 #undef BORDER
36 #define RGB
37 #define BORDER rgb
38 #define ORDER 0
39 #include "pl110_template.h"
40 #define ORDER 1
41 #include "pl110_template.h"
42 #define ORDER 2
43 #include "pl110_template.h"
44 #undef BORDER
45 
46 static drawfn glue(pl110_draw_fn_,BITS)[48] =
47 {
48     glue(pl110_draw_line1_lblp_bgr,BITS),
49     glue(pl110_draw_line2_lblp_bgr,BITS),
50     glue(pl110_draw_line4_lblp_bgr,BITS),
51     glue(pl110_draw_line8_lblp_bgr,BITS),
52     glue(pl110_draw_line16_555_lblp_bgr,BITS),
53     glue(pl110_draw_line32_lblp_bgr,BITS),
54     glue(pl110_draw_line16_lblp_bgr,BITS),
55     glue(pl110_draw_line12_lblp_bgr,BITS),
56 
57     glue(pl110_draw_line1_bbbp_bgr,BITS),
58     glue(pl110_draw_line2_bbbp_bgr,BITS),
59     glue(pl110_draw_line4_bbbp_bgr,BITS),
60     glue(pl110_draw_line8_bbbp_bgr,BITS),
61     glue(pl110_draw_line16_555_bbbp_bgr,BITS),
62     glue(pl110_draw_line32_bbbp_bgr,BITS),
63     glue(pl110_draw_line16_bbbp_bgr,BITS),
64     glue(pl110_draw_line12_bbbp_bgr,BITS),
65 
66     glue(pl110_draw_line1_lbbp_bgr,BITS),
67     glue(pl110_draw_line2_lbbp_bgr,BITS),
68     glue(pl110_draw_line4_lbbp_bgr,BITS),
69     glue(pl110_draw_line8_lbbp_bgr,BITS),
70     glue(pl110_draw_line16_555_lbbp_bgr,BITS),
71     glue(pl110_draw_line32_lbbp_bgr,BITS),
72     glue(pl110_draw_line16_lbbp_bgr,BITS),
73     glue(pl110_draw_line12_lbbp_bgr,BITS),
74 
75     glue(pl110_draw_line1_lblp_rgb,BITS),
76     glue(pl110_draw_line2_lblp_rgb,BITS),
77     glue(pl110_draw_line4_lblp_rgb,BITS),
78     glue(pl110_draw_line8_lblp_rgb,BITS),
79     glue(pl110_draw_line16_555_lblp_rgb,BITS),
80     glue(pl110_draw_line32_lblp_rgb,BITS),
81     glue(pl110_draw_line16_lblp_rgb,BITS),
82     glue(pl110_draw_line12_lblp_rgb,BITS),
83 
84     glue(pl110_draw_line1_bbbp_rgb,BITS),
85     glue(pl110_draw_line2_bbbp_rgb,BITS),
86     glue(pl110_draw_line4_bbbp_rgb,BITS),
87     glue(pl110_draw_line8_bbbp_rgb,BITS),
88     glue(pl110_draw_line16_555_bbbp_rgb,BITS),
89     glue(pl110_draw_line32_bbbp_rgb,BITS),
90     glue(pl110_draw_line16_bbbp_rgb,BITS),
91     glue(pl110_draw_line12_bbbp_rgb,BITS),
92 
93     glue(pl110_draw_line1_lbbp_rgb,BITS),
94     glue(pl110_draw_line2_lbbp_rgb,BITS),
95     glue(pl110_draw_line4_lbbp_rgb,BITS),
96     glue(pl110_draw_line8_lbbp_rgb,BITS),
97     glue(pl110_draw_line16_555_lbbp_rgb,BITS),
98     glue(pl110_draw_line32_lbbp_rgb,BITS),
99     glue(pl110_draw_line16_lbbp_rgb,BITS),
100     glue(pl110_draw_line12_lbbp_rgb,BITS),
101 };
102 
103 #undef BITS
104 #undef COPY_PIXEL
105 
106 #else
107 
108 #if ORDER == 0
109 #define NAME glue(glue(lblp_, BORDER), BITS)
110 #ifdef HOST_WORDS_BIGENDIAN
111 #define SWAP_WORDS 1
112 #endif
113 #elif ORDER == 1
114 #define NAME glue(glue(bbbp_, BORDER), BITS)
115 #ifndef HOST_WORDS_BIGENDIAN
116 #define SWAP_WORDS 1
117 #endif
118 #else
119 #define SWAP_PIXELS 1
120 #define NAME glue(glue(lbbp_, BORDER), BITS)
121 #ifdef HOST_WORDS_BIGENDIAN
122 #define SWAP_WORDS 1
123 #endif
124 #endif
125 
126 #define FN_2(x, y) FN(x, y) FN(x+1, y)
127 #define FN_4(x, y) FN_2(x, y) FN_2(x+2, y)
128 #define FN_8(y) FN_4(0, y) FN_4(4, y)
129 
130 static void glue(pl110_draw_line1_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
131 {
132     uint32_t *palette = opaque;
133     uint32_t data;
134     while (width > 0) {
135         data = *(uint32_t *)src;
136 #ifdef SWAP_PIXELS
137 #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 7 - (x))) & 1]);
138 #else
139 #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x) + y)) & 1]);
140 #endif
141 #ifdef SWAP_WORDS
142         FN_8(24)
143         FN_8(16)
144         FN_8(8)
145         FN_8(0)
146 #else
147         FN_8(0)
148         FN_8(8)
149         FN_8(16)
150         FN_8(24)
151 #endif
152 #undef FN
153         width -= 32;
154         src += 4;
155     }
156 }
157 
158 static void glue(pl110_draw_line2_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
159 {
160     uint32_t *palette = opaque;
161     uint32_t data;
162     while (width > 0) {
163         data = *(uint32_t *)src;
164 #ifdef SWAP_PIXELS
165 #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 6 - (x)*2)) & 3]);
166 #else
167 #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*2 + y)) & 3]);
168 #endif
169 #ifdef SWAP_WORDS
170         FN_4(0, 24)
171         FN_4(0, 16)
172         FN_4(0, 8)
173         FN_4(0, 0)
174 #else
175         FN_4(0, 0)
176         FN_4(0, 8)
177         FN_4(0, 16)
178         FN_4(0, 24)
179 #endif
180 #undef FN
181         width -= 16;
182         src += 4;
183     }
184 }
185 
186 static void glue(pl110_draw_line4_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
187 {
188     uint32_t *palette = opaque;
189     uint32_t data;
190     while (width > 0) {
191         data = *(uint32_t *)src;
192 #ifdef SWAP_PIXELS
193 #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 4 - (x)*4)) & 0xf]);
194 #else
195 #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*4 + y)) & 0xf]);
196 #endif
197 #ifdef SWAP_WORDS
198         FN_2(0, 24)
199         FN_2(0, 16)
200         FN_2(0, 8)
201         FN_2(0, 0)
202 #else
203         FN_2(0, 0)
204         FN_2(0, 8)
205         FN_2(0, 16)
206         FN_2(0, 24)
207 #endif
208 #undef FN
209         width -= 8;
210         src += 4;
211     }
212 }
213 
214 static void glue(pl110_draw_line8_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
215 {
216     uint32_t *palette = opaque;
217     uint32_t data;
218     while (width > 0) {
219         data = *(uint32_t *)src;
220 #define FN(x) COPY_PIXEL(d, palette[(data >> (x)) & 0xff]);
221 #ifdef SWAP_WORDS
222         FN(24)
223         FN(16)
224         FN(8)
225         FN(0)
226 #else
227         FN(0)
228         FN(8)
229         FN(16)
230         FN(24)
231 #endif
232 #undef FN
233         width -= 4;
234         src += 4;
235     }
236 }
237 
238 static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
239 {
240     uint32_t data;
241     unsigned int r, g, b;
242     while (width > 0) {
243         data = *(uint32_t *)src;
244 #ifdef SWAP_WORDS
245         data = bswap32(data);
246 #endif
247 #ifdef RGB
248 #define LSB r
249 #define MSB b
250 #else
251 #define LSB b
252 #define MSB r
253 #endif
254 #if 0
255         LSB = data & 0x1f;
256         data >>= 5;
257         g = data & 0x3f;
258         data >>= 6;
259         MSB = data & 0x1f;
260         data >>= 5;
261 #else
262         LSB = (data & 0x1f) << 3;
263         data >>= 5;
264         g = (data & 0x3f) << 2;
265         data >>= 6;
266         MSB = (data & 0x1f) << 3;
267         data >>= 5;
268 #endif
269         COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
270         LSB = (data & 0x1f) << 3;
271         data >>= 5;
272         g = (data & 0x3f) << 2;
273         data >>= 6;
274         MSB = (data & 0x1f) << 3;
275         data >>= 5;
276         COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
277 #undef MSB
278 #undef LSB
279         width -= 2;
280         src += 4;
281     }
282 }
283 
284 static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
285 {
286     uint32_t data;
287     unsigned int r, g, b;
288     while (width > 0) {
289         data = *(uint32_t *)src;
290 #ifdef RGB
291 #define LSB r
292 #define MSB b
293 #else
294 #define LSB b
295 #define MSB r
296 #endif
297 #ifndef SWAP_WORDS
298         LSB = data & 0xff;
299         g = (data >> 8) & 0xff;
300         MSB = (data >> 16) & 0xff;
301 #else
302         LSB = (data >> 24) & 0xff;
303         g = (data >> 16) & 0xff;
304         MSB = (data >> 8) & 0xff;
305 #endif
306         COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
307 #undef MSB
308 #undef LSB
309         width--;
310         src += 4;
311     }
312 }
313 
314 static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
315 {
316     /* RGB 555 plus an intensity bit (which we ignore) */
317     uint32_t data;
318     unsigned int r, g, b;
319     while (width > 0) {
320         data = *(uint32_t *)src;
321 #ifdef SWAP_WORDS
322         data = bswap32(data);
323 #endif
324 #ifdef RGB
325 #define LSB r
326 #define MSB b
327 #else
328 #define LSB b
329 #define MSB r
330 #endif
331         LSB = (data & 0x1f) << 3;
332         data >>= 5;
333         g = (data & 0x1f) << 3;
334         data >>= 5;
335         MSB = (data & 0x1f) << 3;
336         data >>= 5;
337         COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
338         LSB = (data & 0x1f) << 3;
339         data >>= 5;
340         g = (data & 0x1f) << 3;
341         data >>= 5;
342         MSB = (data & 0x1f) << 3;
343         data >>= 6;
344         COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
345 #undef MSB
346 #undef LSB
347         width -= 2;
348         src += 4;
349     }
350 }
351 
352 static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
353 {
354     /* RGB 444 with 4 bits of zeroes at the top of each halfword */
355     uint32_t data;
356     unsigned int r, g, b;
357     while (width > 0) {
358         data = *(uint32_t *)src;
359 #ifdef SWAP_WORDS
360         data = bswap32(data);
361 #endif
362 #ifdef RGB
363 #define LSB r
364 #define MSB b
365 #else
366 #define LSB b
367 #define MSB r
368 #endif
369         LSB = (data & 0xf) << 4;
370         data >>= 4;
371         g = (data & 0xf) << 4;
372         data >>= 4;
373         MSB = (data & 0xf) << 4;
374         data >>= 8;
375         COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
376         LSB = (data & 0xf) << 4;
377         data >>= 4;
378         g = (data & 0xf) << 4;
379         data >>= 4;
380         MSB = (data & 0xf) << 4;
381         data >>= 8;
382         COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
383 #undef MSB
384 #undef LSB
385         width -= 2;
386         src += 4;
387     }
388 }
389 
390 #undef SWAP_PIXELS
391 #undef NAME
392 #undef SWAP_WORDS
393 #undef ORDER
394 
395 #endif
396