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