diff options
-rw-r--r-- | drivers/video/c2p.c | 238 |
1 files changed, 120 insertions, 118 deletions
diff --git a/drivers/video/c2p.c b/drivers/video/c2p.c index 376bc07ff952..f102b578ce10 100644 --- a/drivers/video/c2p.c +++ b/drivers/video/c2p.c | |||
@@ -21,71 +21,71 @@ | |||
21 | * Basic transpose step | 21 | * Basic transpose step |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #define _transp(d, i1, i2, shift, mask) \ | 24 | #define _transp(d, i1, i2, shift, mask) \ |
25 | do { \ | 25 | do { \ |
26 | u32 t = (d[i1] ^ (d[i2] >> shift)) & mask; \ | 26 | u32 t = (d[i1] ^ (d[i2] >> shift)) & mask; \ |
27 | d[i1] ^= t; \ | 27 | d[i1] ^= t; \ |
28 | d[i2] ^= t << shift; \ | 28 | d[i2] ^= t << shift; \ |
29 | } while (0) | 29 | } while (0) |
30 | 30 | ||
31 | static inline u32 get_mask(int n) | 31 | static inline u32 get_mask(int n) |
32 | { | 32 | { |
33 | switch (n) { | 33 | switch (n) { |
34 | case 1: | 34 | case 1: |
35 | return 0x55555555; | 35 | return 0x55555555; |
36 | break; | 36 | break; |
37 | 37 | ||
38 | case 2: | 38 | case 2: |
39 | return 0x33333333; | 39 | return 0x33333333; |
40 | break; | 40 | break; |
41 | 41 | ||
42 | case 4: | 42 | case 4: |
43 | return 0x0f0f0f0f; | 43 | return 0x0f0f0f0f; |
44 | break; | 44 | break; |
45 | 45 | ||
46 | case 8: | 46 | case 8: |
47 | return 0x00ff00ff; | 47 | return 0x00ff00ff; |
48 | break; | 48 | break; |
49 | 49 | ||
50 | case 16: | 50 | case 16: |
51 | return 0x0000ffff; | 51 | return 0x0000ffff; |
52 | break; | 52 | break; |
53 | } | 53 | } |
54 | return 0; | 54 | return 0; |
55 | } | 55 | } |
56 | 56 | ||
57 | #define transp_nx1(d, n) \ | 57 | #define transp_nx1(d, n) \ |
58 | do { \ | 58 | do { \ |
59 | u32 mask = get_mask(n); \ | 59 | u32 mask = get_mask(n); \ |
60 | /* First block */ \ | 60 | /* First block */ \ |
61 | _transp(d, 0, 1, n, mask); \ | 61 | _transp(d, 0, 1, n, mask); \ |
62 | /* Second block */ \ | 62 | /* Second block */ \ |
63 | _transp(d, 2, 3, n, mask); \ | 63 | _transp(d, 2, 3, n, mask); \ |
64 | /* Third block */ \ | 64 | /* Third block */ \ |
65 | _transp(d, 4, 5, n, mask); \ | 65 | _transp(d, 4, 5, n, mask); \ |
66 | /* Fourth block */ \ | 66 | /* Fourth block */ \ |
67 | _transp(d, 6, 7, n, mask); \ | 67 | _transp(d, 6, 7, n, mask); \ |
68 | } while (0) | 68 | } while (0) |
69 | 69 | ||
70 | #define transp_nx2(d, n) \ | 70 | #define transp_nx2(d, n) \ |
71 | do { \ | 71 | do { \ |
72 | u32 mask = get_mask(n); \ | 72 | u32 mask = get_mask(n); \ |
73 | /* First block */ \ | 73 | /* First block */ \ |
74 | _transp(d, 0, 2, n, mask); \ | 74 | _transp(d, 0, 2, n, mask); \ |
75 | _transp(d, 1, 3, n, mask); \ | 75 | _transp(d, 1, 3, n, mask); \ |
76 | /* Second block */ \ | 76 | /* Second block */ \ |
77 | _transp(d, 4, 6, n, mask); \ | 77 | _transp(d, 4, 6, n, mask); \ |
78 | _transp(d, 5, 7, n, mask); \ | 78 | _transp(d, 5, 7, n, mask); \ |
79 | } while (0) | 79 | } while (0) |
80 | 80 | ||
81 | #define transp_nx4(d, n) \ | 81 | #define transp_nx4(d, n) \ |
82 | do { \ | 82 | do { \ |
83 | u32 mask = get_mask(n); \ | 83 | u32 mask = get_mask(n); \ |
84 | _transp(d, 0, 4, n, mask); \ | 84 | _transp(d, 0, 4, n, mask); \ |
85 | _transp(d, 1, 5, n, mask); \ | 85 | _transp(d, 1, 5, n, mask); \ |
86 | _transp(d, 2, 6, n, mask); \ | 86 | _transp(d, 2, 6, n, mask); \ |
87 | _transp(d, 3, 7, n, mask); \ | 87 | _transp(d, 3, 7, n, mask); \ |
88 | } while (0) | 88 | } while (0) |
89 | 89 | ||
90 | #define transp(d, n, m) transp_nx ## m(d, n) | 90 | #define transp(d, n, m) transp_nx ## m(d, n) |
91 | 91 | ||
@@ -99,11 +99,11 @@ static inline u32 get_mask(int n) | |||
99 | 99 | ||
100 | static void c2p_8bpp(u32 d[8]) | 100 | static void c2p_8bpp(u32 d[8]) |
101 | { | 101 | { |
102 | transp(d, 16, 4); | 102 | transp(d, 16, 4); |
103 | transp(d, 8, 2); | 103 | transp(d, 8, 2); |
104 | transp(d, 4, 1); | 104 | transp(d, 4, 1); |
105 | transp(d, 2, 4); | 105 | transp(d, 2, 4); |
106 | transp(d, 1, 2); | 106 | transp(d, 1, 2); |
107 | } | 107 | } |
108 | 108 | ||
109 | 109 | ||
@@ -132,10 +132,10 @@ static inline unsigned long comp(unsigned long a, unsigned long b, | |||
132 | 132 | ||
133 | static inline void store_planar(char *dst, u32 dst_inc, u32 bpp, u32 d[8]) | 133 | static inline void store_planar(char *dst, u32 dst_inc, u32 bpp, u32 d[8]) |
134 | { | 134 | { |
135 | int i; | 135 | int i; |
136 | 136 | ||
137 | for (i = 0; i < bpp; i++, dst += dst_inc) | 137 | for (i = 0; i < bpp; i++, dst += dst_inc) |
138 | *(u32 *)dst = d[perm_c2p_8bpp[i]]; | 138 | *(u32 *)dst = d[perm_c2p_8bpp[i]]; |
139 | } | 139 | } |
140 | 140 | ||
141 | 141 | ||
@@ -146,10 +146,10 @@ static inline void store_planar(char *dst, u32 dst_inc, u32 bpp, u32 d[8]) | |||
146 | static inline void store_planar_masked(char *dst, u32 dst_inc, u32 bpp, | 146 | static inline void store_planar_masked(char *dst, u32 dst_inc, u32 bpp, |
147 | u32 d[8], u32 mask) | 147 | u32 d[8], u32 mask) |
148 | { | 148 | { |
149 | int i; | 149 | int i; |
150 | 150 | ||
151 | for (i = 0; i < bpp; i++, dst += dst_inc) | 151 | for (i = 0; i < bpp; i++, dst += dst_inc) |
152 | *(u32 *)dst = comp(d[perm_c2p_8bpp[i]], *(u32 *)dst, mask); | 152 | *(u32 *)dst = comp(d[perm_c2p_8bpp[i]], *(u32 *)dst, mask); |
153 | } | 153 | } |
154 | 154 | ||
155 | 155 | ||
@@ -169,63 +169,65 @@ static inline void store_planar_masked(char *dst, u32 dst_inc, u32 bpp, | |||
169 | void c2p(u8 *dst, const u8 *src, u32 dx, u32 dy, u32 width, u32 height, | 169 | void c2p(u8 *dst, const u8 *src, u32 dx, u32 dy, u32 width, u32 height, |
170 | u32 dst_nextline, u32 dst_nextplane, u32 src_nextline, u32 bpp) | 170 | u32 dst_nextline, u32 dst_nextplane, u32 src_nextline, u32 bpp) |
171 | { | 171 | { |
172 | int dst_idx; | 172 | int dst_idx; |
173 | u32 d[8], first, last, w; | 173 | u32 d[8], first, last, w; |
174 | const u8 *c; | 174 | const u8 *c; |
175 | u8 *p; | 175 | u8 *p; |
176 | 176 | ||
177 | dst += dy*dst_nextline+(dx & ~31); | 177 | dst += dy*dst_nextline+(dx & ~31); |
178 | dst_idx = dx % 32; | 178 | dst_idx = dx % 32; |
179 | first = ~0UL >> dst_idx; | 179 | first = ~0UL >> dst_idx; |
180 | last = ~(~0UL >> ((dst_idx+width) % 32)); | 180 | last = ~(~0UL >> ((dst_idx+width) % 32)); |
181 | while (height--) { | 181 | while (height--) { |
182 | c = src; | 182 | c = src; |
183 | p = dst; | 183 | p = dst; |
184 | w = width; | 184 | w = width; |
185 | if (dst_idx+width <= 32) { | 185 | if (dst_idx+width <= 32) { |
186 | /* Single destination word */ | 186 | /* Single destination word */ |
187 | first &= last; | 187 | first &= last; |
188 | memset(d, 0, sizeof(d)); | 188 | memset(d, 0, sizeof(d)); |
189 | memcpy((u8 *)d+dst_idx, c, width); | 189 | memcpy((u8 *)d+dst_idx, c, width); |
190 | c += width; | 190 | c += width; |
191 | c2p_8bpp(d); | 191 | c2p_8bpp(d); |
192 | store_planar_masked(p, dst_nextplane, bpp, d, first); | 192 | store_planar_masked(p, dst_nextplane, bpp, d, first); |
193 | p += 4; | 193 | p += 4; |
194 | } else { | 194 | } else { |
195 | /* Multiple destination words */ | 195 | /* Multiple destination words */ |
196 | w = width; | 196 | w = width; |
197 | /* Leading bits */ | 197 | /* Leading bits */ |
198 | if (dst_idx) { | 198 | if (dst_idx) { |
199 | w = 32 - dst_idx; | 199 | w = 32 - dst_idx; |
200 | memset(d, 0, dst_idx); | 200 | memset(d, 0, dst_idx); |
201 | memcpy((u8 *)d+dst_idx, c, w); | 201 | memcpy((u8 *)d+dst_idx, c, w); |
202 | c += w; | 202 | c += w; |
203 | c2p_8bpp(d); | 203 | c2p_8bpp(d); |
204 | store_planar_masked(p, dst_nextplane, bpp, d, first); | 204 | store_planar_masked(p, dst_nextplane, bpp, d, |
205 | p += 4; | 205 | first); |
206 | w = width-w; | 206 | p += 4; |
207 | } | 207 | w = width-w; |
208 | /* Main chunk */ | 208 | } |
209 | while (w >= 32) { | 209 | /* Main chunk */ |
210 | memcpy(d, c, 32); | 210 | while (w >= 32) { |
211 | c += 32; | 211 | memcpy(d, c, 32); |
212 | c2p_8bpp(d); | 212 | c += 32; |
213 | store_planar(p, dst_nextplane, bpp, d); | 213 | c2p_8bpp(d); |
214 | p += 4; | 214 | store_planar(p, dst_nextplane, bpp, d); |
215 | w -= 32; | 215 | p += 4; |
216 | } | 216 | w -= 32; |
217 | /* Trailing bits */ | 217 | } |
218 | w %= 32; | 218 | /* Trailing bits */ |
219 | if (w > 0) { | 219 | w %= 32; |
220 | memcpy(d, c, w); | 220 | if (w > 0) { |
221 | memset((u8 *)d+w, 0, 32-w); | 221 | memcpy(d, c, w); |
222 | c2p_8bpp(d); | 222 | memset((u8 *)d+w, 0, 32-w); |
223 | store_planar_masked(p, dst_nextplane, bpp, d, last); | 223 | c2p_8bpp(d); |
224 | } | 224 | store_planar_masked(p, dst_nextplane, bpp, d, |
225 | last); | ||
226 | } | ||
227 | } | ||
228 | src += src_nextline; | ||
229 | dst += dst_nextline; | ||
225 | } | 230 | } |
226 | src += src_nextline; | ||
227 | dst += dst_nextline; | ||
228 | } | ||
229 | } | 231 | } |
230 | EXPORT_SYMBOL_GPL(c2p); | 232 | EXPORT_SYMBOL_GPL(c2p); |
231 | 233 | ||