diff options
author | Anton Vorontsov <avorontsov@ru.mvista.com> | 2008-04-28 05:14:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-28 11:58:35 -0400 |
commit | e4c690e061b909127ab0f12e929f82f3f39ec953 (patch) | |
tree | b798bbda541f615cd4830cad96ed3f58db1fd19c /drivers/video/sysimgblt.c | |
parent | 6b745b6fd02213f4b2fef2f2635985929fc5b8cc (diff) |
fb: add support for foreign endianness
Add support for the framebuffers with non-native endianness. This is done via
FBINFO_FOREIGN_ENDIAN flag that will be used by the drivers. Depending on the
host endianness this flag will be overwritten by FBINFO_BE_MATH internal flag,
or cleared.
Tested to work on MPC8360E-RDK (BE) + Fujitsu MINT framebuffer (LE).
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: <Valdis.Kletnieks@vt.edu>
Cc: Clemens Koller <clemens.koller@anagramm.de>
Cc: Krzysztof Helt <krzysztof.h1@poczta.fm>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/sysimgblt.c')
-rw-r--r-- | drivers/video/sysimgblt.c | 47 |
1 files changed, 22 insertions, 25 deletions
diff --git a/drivers/video/sysimgblt.c b/drivers/video/sysimgblt.c index bd7e7e9d155f..88daa9b6f69a 100644 --- a/drivers/video/sysimgblt.c +++ b/drivers/video/sysimgblt.c | |||
@@ -23,30 +23,26 @@ | |||
23 | #define DPRINTK(fmt, args...) | 23 | #define DPRINTK(fmt, args...) |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | static const u32 cfb_tab8[] = { | 26 | static const u32 cfb_tab8_be[] = { |
27 | #if defined(__BIG_ENDIAN) | ||
28 | 0x00000000,0x000000ff,0x0000ff00,0x0000ffff, | 27 | 0x00000000,0x000000ff,0x0000ff00,0x0000ffff, |
29 | 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff, | 28 | 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff, |
30 | 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff, | 29 | 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff, |
31 | 0xffff0000,0xffff00ff,0xffffff00,0xffffffff | 30 | 0xffff0000,0xffff00ff,0xffffff00,0xffffffff |
32 | #elif defined(__LITTLE_ENDIAN) | 31 | }; |
32 | |||
33 | static const u32 cfb_tab8_le[] = { | ||
33 | 0x00000000,0xff000000,0x00ff0000,0xffff0000, | 34 | 0x00000000,0xff000000,0x00ff0000,0xffff0000, |
34 | 0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00, | 35 | 0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00, |
35 | 0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff, | 36 | 0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff, |
36 | 0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff | 37 | 0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff |
37 | #else | ||
38 | #error FIXME: No endianness?? | ||
39 | #endif | ||
40 | }; | 38 | }; |
41 | 39 | ||
42 | static const u32 cfb_tab16[] = { | 40 | static const u32 cfb_tab16_be[] = { |
43 | #if defined(__BIG_ENDIAN) | ||
44 | 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff | 41 | 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff |
45 | #elif defined(__LITTLE_ENDIAN) | 42 | }; |
43 | |||
44 | static const u32 cfb_tab16_le[] = { | ||
46 | 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff | 45 | 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff |
47 | #else | ||
48 | #error FIXME: No endianness?? | ||
49 | #endif | ||
50 | }; | 46 | }; |
51 | 47 | ||
52 | static const u32 cfb_tab32[] = { | 48 | static const u32 cfb_tab32[] = { |
@@ -72,7 +68,7 @@ static void color_imageblit(const struct fb_image *image, struct fb_info *p, | |||
72 | val = 0; | 68 | val = 0; |
73 | 69 | ||
74 | if (start_index) { | 70 | if (start_index) { |
75 | u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0, | 71 | u32 start_mask = ~(FB_SHIFT_HIGH(p, ~(u32)0, |
76 | start_index)); | 72 | start_index)); |
77 | val = *dst & start_mask; | 73 | val = *dst & start_mask; |
78 | shift = start_index; | 74 | shift = start_index; |
@@ -83,20 +79,20 @@ static void color_imageblit(const struct fb_image *image, struct fb_info *p, | |||
83 | color = palette[*src]; | 79 | color = palette[*src]; |
84 | else | 80 | else |
85 | color = *src; | 81 | color = *src; |
86 | color <<= FB_LEFT_POS(bpp); | 82 | color <<= FB_LEFT_POS(p, bpp); |
87 | val |= FB_SHIFT_HIGH(color, shift); | 83 | val |= FB_SHIFT_HIGH(p, color, shift); |
88 | if (shift >= null_bits) { | 84 | if (shift >= null_bits) { |
89 | *dst++ = val; | 85 | *dst++ = val; |
90 | 86 | ||
91 | val = (shift == null_bits) ? 0 : | 87 | val = (shift == null_bits) ? 0 : |
92 | FB_SHIFT_LOW(color, 32 - shift); | 88 | FB_SHIFT_LOW(p, color, 32 - shift); |
93 | } | 89 | } |
94 | shift += bpp; | 90 | shift += bpp; |
95 | shift &= (32 - 1); | 91 | shift &= (32 - 1); |
96 | src++; | 92 | src++; |
97 | } | 93 | } |
98 | if (shift) { | 94 | if (shift) { |
99 | u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift); | 95 | u32 end_mask = FB_SHIFT_HIGH(p, ~(u32)0, shift); |
100 | 96 | ||
101 | *dst &= end_mask; | 97 | *dst &= end_mask; |
102 | *dst |= val; | 98 | *dst |= val; |
@@ -125,8 +121,8 @@ static void slow_imageblit(const struct fb_image *image, struct fb_info *p, | |||
125 | u32 i, j, l; | 121 | u32 i, j, l; |
126 | 122 | ||
127 | dst2 = dst1; | 123 | dst2 = dst1; |
128 | fgcolor <<= FB_LEFT_POS(bpp); | 124 | fgcolor <<= FB_LEFT_POS(p, bpp); |
129 | bgcolor <<= FB_LEFT_POS(bpp); | 125 | bgcolor <<= FB_LEFT_POS(p, bpp); |
130 | 126 | ||
131 | for (i = image->height; i--; ) { | 127 | for (i = image->height; i--; ) { |
132 | shift = val = 0; | 128 | shift = val = 0; |
@@ -137,7 +133,8 @@ static void slow_imageblit(const struct fb_image *image, struct fb_info *p, | |||
137 | 133 | ||
138 | /* write leading bits */ | 134 | /* write leading bits */ |
139 | if (start_index) { | 135 | if (start_index) { |
140 | u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0,start_index)); | 136 | u32 start_mask = ~(FB_SHIFT_HIGH(p, ~(u32)0, |
137 | start_index)); | ||
141 | val = *dst & start_mask; | 138 | val = *dst & start_mask; |
142 | shift = start_index; | 139 | shift = start_index; |
143 | } | 140 | } |
@@ -145,13 +142,13 @@ static void slow_imageblit(const struct fb_image *image, struct fb_info *p, | |||
145 | while (j--) { | 142 | while (j--) { |
146 | l--; | 143 | l--; |
147 | color = (*s & (1 << l)) ? fgcolor : bgcolor; | 144 | color = (*s & (1 << l)) ? fgcolor : bgcolor; |
148 | val |= FB_SHIFT_HIGH(color, shift); | 145 | val |= FB_SHIFT_HIGH(p, color, shift); |
149 | 146 | ||
150 | /* Did the bitshift spill bits to the next long? */ | 147 | /* Did the bitshift spill bits to the next long? */ |
151 | if (shift >= null_bits) { | 148 | if (shift >= null_bits) { |
152 | *dst++ = val; | 149 | *dst++ = val; |
153 | val = (shift == null_bits) ? 0 : | 150 | val = (shift == null_bits) ? 0 : |
154 | FB_SHIFT_LOW(color,32 - shift); | 151 | FB_SHIFT_LOW(p, color, 32 - shift); |
155 | } | 152 | } |
156 | shift += bpp; | 153 | shift += bpp; |
157 | shift &= (32 - 1); | 154 | shift &= (32 - 1); |
@@ -160,7 +157,7 @@ static void slow_imageblit(const struct fb_image *image, struct fb_info *p, | |||
160 | 157 | ||
161 | /* write trailing bits */ | 158 | /* write trailing bits */ |
162 | if (shift) { | 159 | if (shift) { |
163 | u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift); | 160 | u32 end_mask = FB_SHIFT_HIGH(p, ~(u32)0, shift); |
164 | 161 | ||
165 | *dst &= end_mask; | 162 | *dst &= end_mask; |
166 | *dst |= val; | 163 | *dst |= val; |
@@ -199,10 +196,10 @@ static void fast_imageblit(const struct fb_image *image, struct fb_info *p, | |||
199 | 196 | ||
200 | switch (bpp) { | 197 | switch (bpp) { |
201 | case 8: | 198 | case 8: |
202 | tab = cfb_tab8; | 199 | tab = fb_be_math(p) ? cfb_tab8_be : cfb_tab8_le; |
203 | break; | 200 | break; |
204 | case 16: | 201 | case 16: |
205 | tab = cfb_tab16; | 202 | tab = fb_be_math(p) ? cfb_tab16_be : cfb_tab16_le; |
206 | break; | 203 | break; |
207 | case 32: | 204 | case 32: |
208 | default: | 205 | default: |