xref: /openbmc/linux/drivers/video/fbdev/c2p_core.h (revision ea665892)
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 
15ea665892SGeert Uytterhoeven #include <linux/build_bug.h>
16ea665892SGeert 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 
51ea665892SGeert 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 
94ea665892SGeert 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 
121ea665892SGeert 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 
141ea665892SGeert 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