1f7018c21STomi Valkeinen /*
2f7018c21STomi Valkeinen * Fast C2P (Chunky-to-Planar) Conversion
3f7018c21STomi Valkeinen *
4f7018c21STomi Valkeinen * Copyright (C) 2003-2008 Geert Uytterhoeven
5f7018c21STomi Valkeinen *
6f7018c21STomi Valkeinen * NOTES:
7f7018c21STomi Valkeinen * - This code was inspired by Scout's C2P tutorial
8f7018c21STomi Valkeinen * - It assumes to run on a big endian system
9f7018c21STomi Valkeinen *
10f7018c21STomi Valkeinen * This file is subject to the terms and conditions of the GNU General Public
11f7018c21STomi Valkeinen * License. See the file COPYING in the main directory of this archive
12f7018c21STomi Valkeinen * for more details.
13f7018c21STomi Valkeinen */
14f7018c21STomi Valkeinen
15*ea665892SGeert Uytterhoeven #include <linux/build_bug.h>
16*ea665892SGeert Uytterhoeven
17f7018c21STomi Valkeinen
18f7018c21STomi Valkeinen /*
19f7018c21STomi Valkeinen * Basic transpose step
20f7018c21STomi Valkeinen */
21f7018c21STomi Valkeinen
_transp(u32 d[],unsigned int i1,unsigned int i2,unsigned int shift,u32 mask)22f7018c21STomi Valkeinen static inline void _transp(u32 d[], unsigned int i1, unsigned int i2,
23f7018c21STomi Valkeinen unsigned int shift, u32 mask)
24f7018c21STomi Valkeinen {
25f7018c21STomi Valkeinen u32 t = (d[i1] ^ (d[i2] >> shift)) & mask;
26f7018c21STomi Valkeinen
27f7018c21STomi Valkeinen d[i1] ^= t;
28f7018c21STomi Valkeinen d[i2] ^= t << shift;
29f7018c21STomi Valkeinen }
30f7018c21STomi Valkeinen
31f7018c21STomi Valkeinen
get_mask(unsigned int n)32b330f397SGeert Uytterhoeven static __always_inline u32 get_mask(unsigned int n)
33f7018c21STomi Valkeinen {
34f7018c21STomi Valkeinen switch (n) {
35f7018c21STomi Valkeinen case 1:
36f7018c21STomi Valkeinen return 0x55555555;
37f7018c21STomi Valkeinen
38f7018c21STomi Valkeinen case 2:
39f7018c21STomi Valkeinen return 0x33333333;
40f7018c21STomi Valkeinen
41f7018c21STomi Valkeinen case 4:
42f7018c21STomi Valkeinen return 0x0f0f0f0f;
43f7018c21STomi Valkeinen
44f7018c21STomi Valkeinen case 8:
45f7018c21STomi Valkeinen return 0x00ff00ff;
46f7018c21STomi Valkeinen
47f7018c21STomi Valkeinen case 16:
48f7018c21STomi Valkeinen return 0x0000ffff;
49f7018c21STomi Valkeinen }
50f7018c21STomi Valkeinen
51*ea665892SGeert Uytterhoeven BUILD_BUG();
52f7018c21STomi Valkeinen return 0;
53f7018c21STomi Valkeinen }
54f7018c21STomi Valkeinen
55f7018c21STomi Valkeinen
56f7018c21STomi Valkeinen /*
57f7018c21STomi Valkeinen * Transpose operations on 8 32-bit words
58f7018c21STomi Valkeinen */
59f7018c21STomi Valkeinen
transp8(u32 d[],unsigned int n,unsigned int m)60b330f397SGeert Uytterhoeven static __always_inline void transp8(u32 d[], unsigned int n, unsigned int m)
61f7018c21STomi Valkeinen {
62f7018c21STomi Valkeinen u32 mask = get_mask(n);
63f7018c21STomi Valkeinen
64f7018c21STomi Valkeinen switch (m) {
65f7018c21STomi Valkeinen case 1:
66f7018c21STomi Valkeinen /* First n x 1 block */
67f7018c21STomi Valkeinen _transp(d, 0, 1, n, mask);
68f7018c21STomi Valkeinen /* Second n x 1 block */
69f7018c21STomi Valkeinen _transp(d, 2, 3, n, mask);
70f7018c21STomi Valkeinen /* Third n x 1 block */
71f7018c21STomi Valkeinen _transp(d, 4, 5, n, mask);
72f7018c21STomi Valkeinen /* Fourth n x 1 block */
73f7018c21STomi Valkeinen _transp(d, 6, 7, n, mask);
74f7018c21STomi Valkeinen return;
75f7018c21STomi Valkeinen
76f7018c21STomi Valkeinen case 2:
77f7018c21STomi Valkeinen /* First n x 2 block */
78f7018c21STomi Valkeinen _transp(d, 0, 2, n, mask);
79f7018c21STomi Valkeinen _transp(d, 1, 3, n, mask);
80f7018c21STomi Valkeinen /* Second n x 2 block */
81f7018c21STomi Valkeinen _transp(d, 4, 6, n, mask);
82f7018c21STomi Valkeinen _transp(d, 5, 7, n, mask);
83f7018c21STomi Valkeinen return;
84f7018c21STomi Valkeinen
85f7018c21STomi Valkeinen case 4:
86f7018c21STomi Valkeinen /* Single n x 4 block */
87f7018c21STomi Valkeinen _transp(d, 0, 4, n, mask);
88f7018c21STomi Valkeinen _transp(d, 1, 5, n, mask);
89f7018c21STomi Valkeinen _transp(d, 2, 6, n, mask);
90f7018c21STomi Valkeinen _transp(d, 3, 7, n, mask);
91f7018c21STomi Valkeinen return;
92f7018c21STomi Valkeinen }
93f7018c21STomi Valkeinen
94*ea665892SGeert Uytterhoeven BUILD_BUG();
95f7018c21STomi Valkeinen }
96f7018c21STomi Valkeinen
97f7018c21STomi Valkeinen
98f7018c21STomi Valkeinen /*
99f7018c21STomi Valkeinen * Transpose operations on 4 32-bit words
100f7018c21STomi Valkeinen */
101f7018c21STomi Valkeinen
transp4(u32 d[],unsigned int n,unsigned int m)102b330f397SGeert Uytterhoeven static __always_inline void transp4(u32 d[], unsigned int n, unsigned int m)
103f7018c21STomi Valkeinen {
104f7018c21STomi Valkeinen u32 mask = get_mask(n);
105f7018c21STomi Valkeinen
106f7018c21STomi Valkeinen switch (m) {
107f7018c21STomi Valkeinen case 1:
108f7018c21STomi Valkeinen /* First n x 1 block */
109f7018c21STomi Valkeinen _transp(d, 0, 1, n, mask);
110f7018c21STomi Valkeinen /* Second n x 1 block */
111f7018c21STomi Valkeinen _transp(d, 2, 3, n, mask);
112f7018c21STomi Valkeinen return;
113f7018c21STomi Valkeinen
114f7018c21STomi Valkeinen case 2:
115f7018c21STomi Valkeinen /* Single n x 2 block */
116f7018c21STomi Valkeinen _transp(d, 0, 2, n, mask);
117f7018c21STomi Valkeinen _transp(d, 1, 3, n, mask);
118f7018c21STomi Valkeinen return;
119f7018c21STomi Valkeinen }
120f7018c21STomi Valkeinen
121*ea665892SGeert Uytterhoeven BUILD_BUG();
122f7018c21STomi Valkeinen }
123f7018c21STomi Valkeinen
124f7018c21STomi Valkeinen
125f7018c21STomi Valkeinen /*
126f7018c21STomi Valkeinen * Transpose operations on 4 32-bit words (reverse order)
127f7018c21STomi Valkeinen */
128f7018c21STomi Valkeinen
transp4x(u32 d[],unsigned int n,unsigned int m)129b330f397SGeert Uytterhoeven static __always_inline void transp4x(u32 d[], unsigned int n, unsigned int m)
130f7018c21STomi Valkeinen {
131f7018c21STomi Valkeinen u32 mask = get_mask(n);
132f7018c21STomi Valkeinen
133f7018c21STomi Valkeinen switch (m) {
134f7018c21STomi Valkeinen case 2:
135f7018c21STomi Valkeinen /* Single n x 2 block */
136f7018c21STomi Valkeinen _transp(d, 2, 0, n, mask);
137f7018c21STomi Valkeinen _transp(d, 3, 1, n, mask);
138f7018c21STomi Valkeinen return;
139f7018c21STomi Valkeinen }
140f7018c21STomi Valkeinen
141*ea665892SGeert Uytterhoeven BUILD_BUG();
142f7018c21STomi Valkeinen }
143f7018c21STomi Valkeinen
144f7018c21STomi Valkeinen
145f7018c21STomi Valkeinen /*
146f7018c21STomi Valkeinen * Compose two values, using a bitmask as decision value
147f7018c21STomi Valkeinen * This is equivalent to (a & mask) | (b & ~mask)
148f7018c21STomi Valkeinen */
149f7018c21STomi Valkeinen
comp(u32 a,u32 b,u32 mask)150f7018c21STomi Valkeinen static inline u32 comp(u32 a, u32 b, u32 mask)
151f7018c21STomi Valkeinen {
152f7018c21STomi Valkeinen return ((a ^ b) & mask) ^ b;
153f7018c21STomi Valkeinen }
154