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