xref: /openbmc/qemu/hw/display/pl110_template.h (revision e03b5686)
147b43a1fSPaolo Bonzini /*
247b43a1fSPaolo Bonzini  * Arm PrimeCell PL110 Color LCD Controller
347b43a1fSPaolo Bonzini  *
447b43a1fSPaolo Bonzini  * Copyright (c) 2005 CodeSourcery, LLC.
547b43a1fSPaolo Bonzini  * Written by Paul Brook
647b43a1fSPaolo Bonzini  *
747b43a1fSPaolo Bonzini  * This code is licensed under the GNU LGPL
847b43a1fSPaolo Bonzini  *
947b43a1fSPaolo Bonzini  * Framebuffer format conversion routines.
1047b43a1fSPaolo Bonzini  */
1147b43a1fSPaolo Bonzini 
1247b43a1fSPaolo Bonzini #ifndef ORDER
13560ebce6SPeter Maydell #error "pl110_template.h is only for inclusion by pl110.c"
1447b43a1fSPaolo Bonzini #endif
1547b43a1fSPaolo Bonzini 
1647b43a1fSPaolo Bonzini #if ORDER == 0
17ba1c16e4SPeter Maydell #define NAME glue(lblp_, BORDER)
18*e03b5686SMarc-André Lureau #if HOST_BIG_ENDIAN
1947b43a1fSPaolo Bonzini #define SWAP_WORDS 1
2047b43a1fSPaolo Bonzini #endif
2147b43a1fSPaolo Bonzini #elif ORDER == 1
22ba1c16e4SPeter Maydell #define NAME glue(bbbp_, BORDER)
23*e03b5686SMarc-André Lureau #if !HOST_BIG_ENDIAN
2447b43a1fSPaolo Bonzini #define SWAP_WORDS 1
2547b43a1fSPaolo Bonzini #endif
2647b43a1fSPaolo Bonzini #else
2747b43a1fSPaolo Bonzini #define SWAP_PIXELS 1
28ba1c16e4SPeter Maydell #define NAME glue(lbbp_, BORDER)
29*e03b5686SMarc-André Lureau #if HOST_BIG_ENDIAN
3047b43a1fSPaolo Bonzini #define SWAP_WORDS 1
3147b43a1fSPaolo Bonzini #endif
3247b43a1fSPaolo Bonzini #endif
3347b43a1fSPaolo Bonzini 
3447b43a1fSPaolo Bonzini #define FN_2(x, y) FN(x, y) FN(x+1, y)
3547b43a1fSPaolo Bonzini #define FN_4(x, y) FN_2(x, y) FN_2(x+2, y)
3647b43a1fSPaolo Bonzini #define FN_8(y) FN_4(0, y) FN_4(4, y)
3747b43a1fSPaolo Bonzini 
glue(pl110_draw_line1_,NAME)3847b43a1fSPaolo Bonzini static void glue(pl110_draw_line1_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
3947b43a1fSPaolo Bonzini {
4047b43a1fSPaolo Bonzini     uint32_t *palette = opaque;
4147b43a1fSPaolo Bonzini     uint32_t data;
4247b43a1fSPaolo Bonzini     while (width > 0) {
4347b43a1fSPaolo Bonzini         data = *(uint32_t *)src;
4447b43a1fSPaolo Bonzini #ifdef SWAP_PIXELS
4547b43a1fSPaolo Bonzini #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 7 - (x))) & 1]);
4647b43a1fSPaolo Bonzini #else
4747b43a1fSPaolo Bonzini #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x) + y)) & 1]);
4847b43a1fSPaolo Bonzini #endif
4947b43a1fSPaolo Bonzini #ifdef SWAP_WORDS
5047b43a1fSPaolo Bonzini         FN_8(24)
5147b43a1fSPaolo Bonzini         FN_8(16)
5247b43a1fSPaolo Bonzini         FN_8(8)
5347b43a1fSPaolo Bonzini         FN_8(0)
5447b43a1fSPaolo Bonzini #else
5547b43a1fSPaolo Bonzini         FN_8(0)
5647b43a1fSPaolo Bonzini         FN_8(8)
5747b43a1fSPaolo Bonzini         FN_8(16)
5847b43a1fSPaolo Bonzini         FN_8(24)
5947b43a1fSPaolo Bonzini #endif
6047b43a1fSPaolo Bonzini #undef FN
6147b43a1fSPaolo Bonzini         width -= 32;
6247b43a1fSPaolo Bonzini         src += 4;
6347b43a1fSPaolo Bonzini     }
6447b43a1fSPaolo Bonzini }
6547b43a1fSPaolo Bonzini 
glue(pl110_draw_line2_,NAME)6647b43a1fSPaolo Bonzini static void glue(pl110_draw_line2_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
6747b43a1fSPaolo Bonzini {
6847b43a1fSPaolo Bonzini     uint32_t *palette = opaque;
6947b43a1fSPaolo Bonzini     uint32_t data;
7047b43a1fSPaolo Bonzini     while (width > 0) {
7147b43a1fSPaolo Bonzini         data = *(uint32_t *)src;
7247b43a1fSPaolo Bonzini #ifdef SWAP_PIXELS
7347b43a1fSPaolo Bonzini #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 6 - (x)*2)) & 3]);
7447b43a1fSPaolo Bonzini #else
7547b43a1fSPaolo Bonzini #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*2 + y)) & 3]);
7647b43a1fSPaolo Bonzini #endif
7747b43a1fSPaolo Bonzini #ifdef SWAP_WORDS
7847b43a1fSPaolo Bonzini         FN_4(0, 24)
7947b43a1fSPaolo Bonzini         FN_4(0, 16)
8047b43a1fSPaolo Bonzini         FN_4(0, 8)
8147b43a1fSPaolo Bonzini         FN_4(0, 0)
8247b43a1fSPaolo Bonzini #else
8347b43a1fSPaolo Bonzini         FN_4(0, 0)
8447b43a1fSPaolo Bonzini         FN_4(0, 8)
8547b43a1fSPaolo Bonzini         FN_4(0, 16)
8647b43a1fSPaolo Bonzini         FN_4(0, 24)
8747b43a1fSPaolo Bonzini #endif
8847b43a1fSPaolo Bonzini #undef FN
8947b43a1fSPaolo Bonzini         width -= 16;
9047b43a1fSPaolo Bonzini         src += 4;
9147b43a1fSPaolo Bonzini     }
9247b43a1fSPaolo Bonzini }
9347b43a1fSPaolo Bonzini 
glue(pl110_draw_line4_,NAME)9447b43a1fSPaolo Bonzini static void glue(pl110_draw_line4_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
9547b43a1fSPaolo Bonzini {
9647b43a1fSPaolo Bonzini     uint32_t *palette = opaque;
9747b43a1fSPaolo Bonzini     uint32_t data;
9847b43a1fSPaolo Bonzini     while (width > 0) {
9947b43a1fSPaolo Bonzini         data = *(uint32_t *)src;
10047b43a1fSPaolo Bonzini #ifdef SWAP_PIXELS
10147b43a1fSPaolo Bonzini #define FN(x, y) COPY_PIXEL(d, palette[(data >> (y + 4 - (x)*4)) & 0xf]);
10247b43a1fSPaolo Bonzini #else
10347b43a1fSPaolo Bonzini #define FN(x, y) COPY_PIXEL(d, palette[(data >> ((x)*4 + y)) & 0xf]);
10447b43a1fSPaolo Bonzini #endif
10547b43a1fSPaolo Bonzini #ifdef SWAP_WORDS
10647b43a1fSPaolo Bonzini         FN_2(0, 24)
10747b43a1fSPaolo Bonzini         FN_2(0, 16)
10847b43a1fSPaolo Bonzini         FN_2(0, 8)
10947b43a1fSPaolo Bonzini         FN_2(0, 0)
11047b43a1fSPaolo Bonzini #else
11147b43a1fSPaolo Bonzini         FN_2(0, 0)
11247b43a1fSPaolo Bonzini         FN_2(0, 8)
11347b43a1fSPaolo Bonzini         FN_2(0, 16)
11447b43a1fSPaolo Bonzini         FN_2(0, 24)
11547b43a1fSPaolo Bonzini #endif
11647b43a1fSPaolo Bonzini #undef FN
11747b43a1fSPaolo Bonzini         width -= 8;
11847b43a1fSPaolo Bonzini         src += 4;
11947b43a1fSPaolo Bonzini     }
12047b43a1fSPaolo Bonzini }
12147b43a1fSPaolo Bonzini 
glue(pl110_draw_line8_,NAME)12247b43a1fSPaolo Bonzini static void glue(pl110_draw_line8_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
12347b43a1fSPaolo Bonzini {
12447b43a1fSPaolo Bonzini     uint32_t *palette = opaque;
12547b43a1fSPaolo Bonzini     uint32_t data;
12647b43a1fSPaolo Bonzini     while (width > 0) {
12747b43a1fSPaolo Bonzini         data = *(uint32_t *)src;
12847b43a1fSPaolo Bonzini #define FN(x) COPY_PIXEL(d, palette[(data >> (x)) & 0xff]);
12947b43a1fSPaolo Bonzini #ifdef SWAP_WORDS
13047b43a1fSPaolo Bonzini         FN(24)
13147b43a1fSPaolo Bonzini         FN(16)
13247b43a1fSPaolo Bonzini         FN(8)
13347b43a1fSPaolo Bonzini         FN(0)
13447b43a1fSPaolo Bonzini #else
13547b43a1fSPaolo Bonzini         FN(0)
13647b43a1fSPaolo Bonzini         FN(8)
13747b43a1fSPaolo Bonzini         FN(16)
13847b43a1fSPaolo Bonzini         FN(24)
13947b43a1fSPaolo Bonzini #endif
14047b43a1fSPaolo Bonzini #undef FN
14147b43a1fSPaolo Bonzini         width -= 4;
14247b43a1fSPaolo Bonzini         src += 4;
14347b43a1fSPaolo Bonzini     }
14447b43a1fSPaolo Bonzini }
14547b43a1fSPaolo Bonzini 
glue(pl110_draw_line16_,NAME)14647b43a1fSPaolo Bonzini static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
14747b43a1fSPaolo Bonzini {
14847b43a1fSPaolo Bonzini     uint32_t data;
14947b43a1fSPaolo Bonzini     unsigned int r, g, b;
15047b43a1fSPaolo Bonzini     while (width > 0) {
15147b43a1fSPaolo Bonzini         data = *(uint32_t *)src;
15247b43a1fSPaolo Bonzini #ifdef SWAP_WORDS
15347b43a1fSPaolo Bonzini         data = bswap32(data);
15447b43a1fSPaolo Bonzini #endif
15547b43a1fSPaolo Bonzini #ifdef RGB
15647b43a1fSPaolo Bonzini #define LSB r
15747b43a1fSPaolo Bonzini #define MSB b
15847b43a1fSPaolo Bonzini #else
15947b43a1fSPaolo Bonzini #define LSB b
16047b43a1fSPaolo Bonzini #define MSB r
16147b43a1fSPaolo Bonzini #endif
16247b43a1fSPaolo Bonzini #if 0
16347b43a1fSPaolo Bonzini         LSB = data & 0x1f;
16447b43a1fSPaolo Bonzini         data >>= 5;
16547b43a1fSPaolo Bonzini         g = data & 0x3f;
16647b43a1fSPaolo Bonzini         data >>= 6;
16747b43a1fSPaolo Bonzini         MSB = data & 0x1f;
16847b43a1fSPaolo Bonzini         data >>= 5;
16947b43a1fSPaolo Bonzini #else
17047b43a1fSPaolo Bonzini         LSB = (data & 0x1f) << 3;
17147b43a1fSPaolo Bonzini         data >>= 5;
17247b43a1fSPaolo Bonzini         g = (data & 0x3f) << 2;
17347b43a1fSPaolo Bonzini         data >>= 6;
17447b43a1fSPaolo Bonzini         MSB = (data & 0x1f) << 3;
17547b43a1fSPaolo Bonzini         data >>= 5;
17647b43a1fSPaolo Bonzini #endif
177ba1c16e4SPeter Maydell         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
17847b43a1fSPaolo Bonzini         LSB = (data & 0x1f) << 3;
17947b43a1fSPaolo Bonzini         data >>= 5;
18047b43a1fSPaolo Bonzini         g = (data & 0x3f) << 2;
18147b43a1fSPaolo Bonzini         data >>= 6;
18247b43a1fSPaolo Bonzini         MSB = (data & 0x1f) << 3;
18347b43a1fSPaolo Bonzini         data >>= 5;
184ba1c16e4SPeter Maydell         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
18547b43a1fSPaolo Bonzini #undef MSB
18647b43a1fSPaolo Bonzini #undef LSB
18747b43a1fSPaolo Bonzini         width -= 2;
18847b43a1fSPaolo Bonzini         src += 4;
18947b43a1fSPaolo Bonzini     }
19047b43a1fSPaolo Bonzini }
19147b43a1fSPaolo Bonzini 
glue(pl110_draw_line32_,NAME)19247b43a1fSPaolo Bonzini static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
19347b43a1fSPaolo Bonzini {
19447b43a1fSPaolo Bonzini     uint32_t data;
19547b43a1fSPaolo Bonzini     unsigned int r, g, b;
19647b43a1fSPaolo Bonzini     while (width > 0) {
19747b43a1fSPaolo Bonzini         data = *(uint32_t *)src;
19847b43a1fSPaolo Bonzini #ifdef RGB
19947b43a1fSPaolo Bonzini #define LSB r
20047b43a1fSPaolo Bonzini #define MSB b
20147b43a1fSPaolo Bonzini #else
20247b43a1fSPaolo Bonzini #define LSB b
20347b43a1fSPaolo Bonzini #define MSB r
20447b43a1fSPaolo Bonzini #endif
20547b43a1fSPaolo Bonzini #ifndef SWAP_WORDS
20647b43a1fSPaolo Bonzini         LSB = data & 0xff;
20747b43a1fSPaolo Bonzini         g = (data >> 8) & 0xff;
20847b43a1fSPaolo Bonzini         MSB = (data >> 16) & 0xff;
20947b43a1fSPaolo Bonzini #else
21047b43a1fSPaolo Bonzini         LSB = (data >> 24) & 0xff;
21147b43a1fSPaolo Bonzini         g = (data >> 16) & 0xff;
21247b43a1fSPaolo Bonzini         MSB = (data >> 8) & 0xff;
21347b43a1fSPaolo Bonzini #endif
214ba1c16e4SPeter Maydell         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
21547b43a1fSPaolo Bonzini #undef MSB
21647b43a1fSPaolo Bonzini #undef LSB
21747b43a1fSPaolo Bonzini         width--;
21847b43a1fSPaolo Bonzini         src += 4;
21947b43a1fSPaolo Bonzini     }
22047b43a1fSPaolo Bonzini }
22147b43a1fSPaolo Bonzini 
glue(pl110_draw_line16_555_,NAME)22247b43a1fSPaolo Bonzini static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
22347b43a1fSPaolo Bonzini {
22447b43a1fSPaolo Bonzini     /* RGB 555 plus an intensity bit (which we ignore) */
22547b43a1fSPaolo Bonzini     uint32_t data;
22647b43a1fSPaolo Bonzini     unsigned int r, g, b;
22747b43a1fSPaolo Bonzini     while (width > 0) {
22847b43a1fSPaolo Bonzini         data = *(uint32_t *)src;
22947b43a1fSPaolo Bonzini #ifdef SWAP_WORDS
23047b43a1fSPaolo Bonzini         data = bswap32(data);
23147b43a1fSPaolo Bonzini #endif
23247b43a1fSPaolo Bonzini #ifdef RGB
23347b43a1fSPaolo Bonzini #define LSB r
23447b43a1fSPaolo Bonzini #define MSB b
23547b43a1fSPaolo Bonzini #else
23647b43a1fSPaolo Bonzini #define LSB b
23747b43a1fSPaolo Bonzini #define MSB r
23847b43a1fSPaolo Bonzini #endif
23947b43a1fSPaolo Bonzini         LSB = (data & 0x1f) << 3;
24047b43a1fSPaolo Bonzini         data >>= 5;
24147b43a1fSPaolo Bonzini         g = (data & 0x1f) << 3;
24247b43a1fSPaolo Bonzini         data >>= 5;
24347b43a1fSPaolo Bonzini         MSB = (data & 0x1f) << 3;
24447b43a1fSPaolo Bonzini         data >>= 5;
245ba1c16e4SPeter Maydell         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
24647b43a1fSPaolo Bonzini         LSB = (data & 0x1f) << 3;
24747b43a1fSPaolo Bonzini         data >>= 5;
24847b43a1fSPaolo Bonzini         g = (data & 0x1f) << 3;
24947b43a1fSPaolo Bonzini         data >>= 5;
25047b43a1fSPaolo Bonzini         MSB = (data & 0x1f) << 3;
25147b43a1fSPaolo Bonzini         data >>= 6;
252ba1c16e4SPeter Maydell         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
25347b43a1fSPaolo Bonzini #undef MSB
25447b43a1fSPaolo Bonzini #undef LSB
25547b43a1fSPaolo Bonzini         width -= 2;
25647b43a1fSPaolo Bonzini         src += 4;
25747b43a1fSPaolo Bonzini     }
25847b43a1fSPaolo Bonzini }
25947b43a1fSPaolo Bonzini 
glue(pl110_draw_line12_,NAME)26047b43a1fSPaolo Bonzini static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
26147b43a1fSPaolo Bonzini {
26247b43a1fSPaolo Bonzini     /* RGB 444 with 4 bits of zeroes at the top of each halfword */
26347b43a1fSPaolo Bonzini     uint32_t data;
26447b43a1fSPaolo Bonzini     unsigned int r, g, b;
26547b43a1fSPaolo Bonzini     while (width > 0) {
26647b43a1fSPaolo Bonzini         data = *(uint32_t *)src;
26747b43a1fSPaolo Bonzini #ifdef SWAP_WORDS
26847b43a1fSPaolo Bonzini         data = bswap32(data);
26947b43a1fSPaolo Bonzini #endif
27047b43a1fSPaolo Bonzini #ifdef RGB
27147b43a1fSPaolo Bonzini #define LSB r
27247b43a1fSPaolo Bonzini #define MSB b
27347b43a1fSPaolo Bonzini #else
27447b43a1fSPaolo Bonzini #define LSB b
27547b43a1fSPaolo Bonzini #define MSB r
27647b43a1fSPaolo Bonzini #endif
27747b43a1fSPaolo Bonzini         LSB = (data & 0xf) << 4;
27847b43a1fSPaolo Bonzini         data >>= 4;
27947b43a1fSPaolo Bonzini         g = (data & 0xf) << 4;
28047b43a1fSPaolo Bonzini         data >>= 4;
28147b43a1fSPaolo Bonzini         MSB = (data & 0xf) << 4;
28247b43a1fSPaolo Bonzini         data >>= 8;
283ba1c16e4SPeter Maydell         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
28447b43a1fSPaolo Bonzini         LSB = (data & 0xf) << 4;
28547b43a1fSPaolo Bonzini         data >>= 4;
28647b43a1fSPaolo Bonzini         g = (data & 0xf) << 4;
28747b43a1fSPaolo Bonzini         data >>= 4;
28847b43a1fSPaolo Bonzini         MSB = (data & 0xf) << 4;
28947b43a1fSPaolo Bonzini         data >>= 8;
290ba1c16e4SPeter Maydell         COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
29147b43a1fSPaolo Bonzini #undef MSB
29247b43a1fSPaolo Bonzini #undef LSB
29347b43a1fSPaolo Bonzini         width -= 2;
29447b43a1fSPaolo Bonzini         src += 4;
29547b43a1fSPaolo Bonzini     }
29647b43a1fSPaolo Bonzini }
29747b43a1fSPaolo Bonzini 
29847b43a1fSPaolo Bonzini #undef SWAP_PIXELS
29947b43a1fSPaolo Bonzini #undef NAME
30047b43a1fSPaolo Bonzini #undef SWAP_WORDS
30147b43a1fSPaolo Bonzini #undef ORDER
302