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 #error "pl110_template.h is only for inclusion by pl110.c"
14 #endif
15
16 #if ORDER == 0
17 #define NAME glue(lblp_, BORDER)
18 #if HOST_BIG_ENDIAN
19 #define SWAP_WORDS 1
20 #endif
21 #elif ORDER == 1
22 #define NAME glue(bbbp_, BORDER)
23 #if !HOST_BIG_ENDIAN
24 #define SWAP_WORDS 1
25 #endif
26 #else
27 #define SWAP_PIXELS 1
28 #define NAME glue(lbbp_, BORDER)
29 #if HOST_BIG_ENDIAN
30 #define SWAP_WORDS 1
31 #endif
32 #endif
33
34 #define FN_2(x, y) FN(x, y) FN(x+1, y)
35 #define FN_4(x, y) FN_2(x, y) FN_2(x+2, y)
36 #define FN_8(y) FN_4(0, y) FN_4(4, y)
37
glue(pl110_draw_line1_,NAME)38 static void glue(pl110_draw_line1_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
39 {
40 uint32_t *palette = opaque;
41 uint32_t data;
42 while (width > 0) {
43 data = *(uint32_t *)src;
44 #ifdef SWAP_PIXELS
45 #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 7 - (x))) & 1]);
46 #else
47 #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x) + y)) & 1]);
48 #endif
49 #ifdef SWAP_WORDS
50 FN_8(24)
51 FN_8(16)
52 FN_8(8)
53 FN_8(0)
54 #else
55 FN_8(0)
56 FN_8(8)
57 FN_8(16)
58 FN_8(24)
59 #endif
60 #undef FN
61 width -= 32;
62 src += 4;
63 }
64 }
65
glue(pl110_draw_line2_,NAME)66 static void glue(pl110_draw_line2_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
67 {
68 uint32_t *palette = opaque;
69 uint32_t data;
70 while (width > 0) {
71 data = *(uint32_t *)src;
72 #ifdef SWAP_PIXELS
73 #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 6 - (x)*2)) & 3]);
74 #else
75 #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*2 + y)) & 3]);
76 #endif
77 #ifdef SWAP_WORDS
78 FN_4(0, 24)
79 FN_4(0, 16)
80 FN_4(0, 8)
81 FN_4(0, 0)
82 #else
83 FN_4(0, 0)
84 FN_4(0, 8)
85 FN_4(0, 16)
86 FN_4(0, 24)
87 #endif
88 #undef FN
89 width -= 16;
90 src += 4;
91 }
92 }
93
glue(pl110_draw_line4_,NAME)94 static void glue(pl110_draw_line4_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
95 {
96 uint32_t *palette = opaque;
97 uint32_t data;
98 while (width > 0) {
99 data = *(uint32_t *)src;
100 #ifdef SWAP_PIXELS
101 #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 4 - (x)*4)) & 0xf]);
102 #else
103 #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*4 + y)) & 0xf]);
104 #endif
105 #ifdef SWAP_WORDS
106 FN_2(0, 24)
107 FN_2(0, 16)
108 FN_2(0, 8)
109 FN_2(0, 0)
110 #else
111 FN_2(0, 0)
112 FN_2(0, 8)
113 FN_2(0, 16)
114 FN_2(0, 24)
115 #endif
116 #undef FN
117 width -= 8;
118 src += 4;
119 }
120 }
121
glue(pl110_draw_line8_,NAME)122 static void glue(pl110_draw_line8_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
123 {
124 uint32_t *palette = opaque;
125 uint32_t data;
126 while (width > 0) {
127 data = *(uint32_t *)src;
128 #define FN(x) COPY_PIXEL(d, palette[(data >> (x)) & 0xff]);
129 #ifdef SWAP_WORDS
130 FN(24)
131 FN(16)
132 FN(8)
133 FN(0)
134 #else
135 FN(0)
136 FN(8)
137 FN(16)
138 FN(24)
139 #endif
140 #undef FN
141 width -= 4;
142 src += 4;
143 }
144 }
145
glue(pl110_draw_line16_,NAME)146 static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
147 {
148 uint32_t data;
149 unsigned int r, g, b;
150 while (width > 0) {
151 data = *(uint32_t *)src;
152 #ifdef SWAP_WORDS
153 data = bswap32(data);
154 #endif
155 #ifdef RGB
156 #define LSB r
157 #define MSB b
158 #else
159 #define LSB b
160 #define MSB r
161 #endif
162 #if 0
163 LSB = data & 0x1f;
164 data >>= 5;
165 g = data & 0x3f;
166 data >>= 6;
167 MSB = data & 0x1f;
168 data >>= 5;
169 #else
170 LSB = (data & 0x1f) << 3;
171 data >>= 5;
172 g = (data & 0x3f) << 2;
173 data >>= 6;
174 MSB = (data & 0x1f) << 3;
175 data >>= 5;
176 #endif
177 COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
178 LSB = (data & 0x1f) << 3;
179 data >>= 5;
180 g = (data & 0x3f) << 2;
181 data >>= 6;
182 MSB = (data & 0x1f) << 3;
183 data >>= 5;
184 COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
185 #undef MSB
186 #undef LSB
187 width -= 2;
188 src += 4;
189 }
190 }
191
glue(pl110_draw_line32_,NAME)192 static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
193 {
194 uint32_t data;
195 unsigned int r, g, b;
196 while (width > 0) {
197 data = *(uint32_t *)src;
198 #ifdef RGB
199 #define LSB r
200 #define MSB b
201 #else
202 #define LSB b
203 #define MSB r
204 #endif
205 #ifndef SWAP_WORDS
206 LSB = data & 0xff;
207 g = (data >> 8) & 0xff;
208 MSB = (data >> 16) & 0xff;
209 #else
210 LSB = (data >> 24) & 0xff;
211 g = (data >> 16) & 0xff;
212 MSB = (data >> 8) & 0xff;
213 #endif
214 COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
215 #undef MSB
216 #undef LSB
217 width--;
218 src += 4;
219 }
220 }
221
glue(pl110_draw_line16_555_,NAME)222 static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
223 {
224 /* RGB 555 plus an intensity bit (which we ignore) */
225 uint32_t data;
226 unsigned int r, g, b;
227 while (width > 0) {
228 data = *(uint32_t *)src;
229 #ifdef SWAP_WORDS
230 data = bswap32(data);
231 #endif
232 #ifdef RGB
233 #define LSB r
234 #define MSB b
235 #else
236 #define LSB b
237 #define MSB r
238 #endif
239 LSB = (data & 0x1f) << 3;
240 data >>= 5;
241 g = (data & 0x1f) << 3;
242 data >>= 5;
243 MSB = (data & 0x1f) << 3;
244 data >>= 5;
245 COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
246 LSB = (data & 0x1f) << 3;
247 data >>= 5;
248 g = (data & 0x1f) << 3;
249 data >>= 5;
250 MSB = (data & 0x1f) << 3;
251 data >>= 6;
252 COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
253 #undef MSB
254 #undef LSB
255 width -= 2;
256 src += 4;
257 }
258 }
259
glue(pl110_draw_line12_,NAME)260 static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
261 {
262 /* RGB 444 with 4 bits of zeroes at the top of each halfword */
263 uint32_t data;
264 unsigned int r, g, b;
265 while (width > 0) {
266 data = *(uint32_t *)src;
267 #ifdef SWAP_WORDS
268 data = bswap32(data);
269 #endif
270 #ifdef RGB
271 #define LSB r
272 #define MSB b
273 #else
274 #define LSB b
275 #define MSB r
276 #endif
277 LSB = (data & 0xf) << 4;
278 data >>= 4;
279 g = (data & 0xf) << 4;
280 data >>= 4;
281 MSB = (data & 0xf) << 4;
282 data >>= 8;
283 COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
284 LSB = (data & 0xf) << 4;
285 data >>= 4;
286 g = (data & 0xf) << 4;
287 data >>= 4;
288 MSB = (data & 0xf) << 4;
289 data >>= 8;
290 COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
291 #undef MSB
292 #undef LSB
293 width -= 2;
294 src += 4;
295 }
296 }
297
298 #undef SWAP_PIXELS
299 #undef NAME
300 #undef SWAP_WORDS
301 #undef ORDER
302