1 /*
2 * drivers/video/fbdev/sunxi/disp2/disp/de/disp_rotation_sw/disp_rotation_sw.h
3 *
4 * Copyright (c) 2007-2018 Allwinnertech Co., Ltd.
5 * Author: zhengxiaobin <zhengxiaobin@allwinnertech.com>
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17 #ifndef _DISP_ROTATION_SW_H_
18 #define _DISP_ROTATION_SW_H_
19
20 #include "disp_private.h"
21
22
23 s32 disp_init_rotation_sw(struct disp_bsp_init_para *para);
24 extern void *disp_malloc(u32 num_bytes, u32 *phys_addr);
25 extern void disp_free(void *virt_addr, void *phy_addr, u32 num_bytes);
26 extern void *Fb_map_kernel(unsigned long phys_addr, unsigned long size);
27 extern s32 bsp_disp_get_output_type(u32 disp);
28 extern s32 bsp_disp_get_screen_width_from_output_type(u32 disp,
29 u32 output_type, u32 output_mode);
30 extern s32 bsp_disp_get_screen_height_from_output_type(u32 disp,
31 u32 output_type, u32 output_mode);
32 extern void *sunxi_buf_alloc_cache(unsigned int size, unsigned int *paddr);
33
34 static inline void
rot_0_u8(unsigned char * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned char * dst_addr,const unsigned int dst_widthstep)35 rot_0_u8(unsigned char *src_addr, const unsigned int src_widthstep,
36 const unsigned int src_width, const unsigned int src_height,
37 unsigned char *dst_addr, const unsigned int dst_widthstep)
38 {
39 unsigned char *src_addr_end = src_addr + src_widthstep * src_height;
40 for (; src_addr != src_addr_end;) {
41 memcpy((void *)dst_addr, (void *)src_addr, src_width);
42 dst_addr += dst_widthstep;
43 src_addr += src_widthstep;
44 }
45 }
46
47 static inline void
rot_0_u16(unsigned short * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned short * dst_addr,const unsigned int dst_widthstep)48 rot_0_u16(unsigned short *src_addr, const unsigned int src_widthstep,
49 const unsigned int src_width, const unsigned int src_height,
50 unsigned short *dst_addr, const unsigned int dst_widthstep)
51 {
52 const unsigned int width_size = src_width << 1;
53 rot_0_u8((unsigned char *)src_addr, src_widthstep, width_size,
54 src_height, (unsigned char *)dst_addr, dst_widthstep);
55 }
56
57 static inline void
rot_0_u32(unsigned int * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned int * dst_addr,const unsigned int dst_widthstep)58 rot_0_u32(unsigned int *src_addr, const unsigned int src_widthstep,
59 const unsigned int src_width, const unsigned int src_height,
60 unsigned int *dst_addr, const unsigned int dst_widthstep)
61 {
62 const unsigned int width_size = src_width << 2;
63 rot_0_u8((unsigned char *)src_addr, src_widthstep, width_size,
64 src_height, (unsigned char *)dst_addr, dst_widthstep);
65 }
66
67 static inline void
rot_180_u8(unsigned char * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned char * dst_addr,const unsigned int dst_widthstep)68 rot_180_u8(unsigned char *src_addr, const unsigned int src_widthstep,
69 const unsigned int src_width, const unsigned int src_height,
70 unsigned char *dst_addr, const unsigned int dst_widthstep)
71 {
72 unsigned char *p_src, *p_src_end, *p_dst;
73 unsigned char *dst_addr_end = dst_addr - dst_widthstep + src_width - 1;
74 dst_addr = dst_addr_end + dst_widthstep * src_height;
75 for (; dst_addr != dst_addr_end;) {
76 p_src = src_addr;
77 p_src_end = p_src + src_width;
78 p_dst = dst_addr;
79 for (; p_src != p_src_end;) {
80 *p_dst-- = *p_src++;
81 }
82 src_addr += src_widthstep;
83 dst_addr -= dst_widthstep;
84 }
85 }
86
87 static inline void
rot_180_u16(unsigned short * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned short * dst_addr,const unsigned int dst_widthstep)88 rot_180_u16(unsigned short *src_addr, const unsigned int src_widthstep,
89 const unsigned int src_width, const unsigned int src_height,
90 unsigned short *dst_addr, const unsigned int dst_widthstep)
91 {
92 unsigned short *p_src, *p_src_end, *p_dst;
93 unsigned short *dst_addr_end = dst_addr + src_width - 1;
94 dst_addr_end = (unsigned short *)((char *)dst_addr_end - dst_widthstep);
95 dst_addr = (unsigned short *)((char *)dst_addr_end +
96 dst_widthstep * src_height);
97 for (; dst_addr != dst_addr_end;) {
98 p_src = src_addr;
99 p_src_end = p_src + src_width;
100 p_dst = dst_addr;
101 for (; p_src != p_src_end;) {
102 *p_dst-- = *p_src++;
103 }
104 src_addr = (unsigned short *)((char *)src_addr + src_widthstep);
105 dst_addr = (unsigned short *)((char *)dst_addr - dst_widthstep);
106 }
107 }
108
109 static inline void
rot_180_u32(unsigned int * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned int * dst_addr,const unsigned int dst_widthstep)110 rot_180_u32(unsigned int *src_addr, const unsigned int src_widthstep,
111 const unsigned int src_width, const unsigned int src_height,
112 unsigned int *dst_addr, const unsigned int dst_widthstep)
113 {
114 unsigned int *p_src, *p_src_end, *p_dst;
115 unsigned int *dst_addr_end = dst_addr + src_width - 1;
116 dst_addr_end = (unsigned int *)((char *)dst_addr_end - dst_widthstep);
117 dst_addr =
118 (unsigned int *)((char *)dst_addr_end + dst_widthstep * src_height);
119 for (; dst_addr != dst_addr_end;) {
120 p_src = src_addr;
121 p_src_end = p_src + src_width;
122 p_dst = dst_addr;
123 for (; p_src != p_src_end;) {
124 *p_dst-- = *p_src++;
125 }
126 src_addr = (unsigned int *)((char *)src_addr + src_widthstep);
127 dst_addr = (unsigned int *)((char *)dst_addr - dst_widthstep);
128 }
129 }
130
131 static inline void
rot_270_u8(unsigned char * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned char * dst_addr,const unsigned int dst_widthstep)132 rot_270_u8(unsigned char *src_addr, const unsigned int src_widthstep,
133 const unsigned int src_width, const unsigned int src_height,
134 unsigned char *dst_addr, const unsigned int dst_widthstep)
135 {
136 unsigned char *p_src, *p_src_end, *p_dst, *dst_addr_end;
137 dst_addr += (dst_widthstep * (src_width - 1));
138 dst_addr_end = dst_addr + src_height;
139 for (; dst_addr != dst_addr_end; dst_addr++) {
140 p_src = src_addr;
141 p_src_end = p_src + src_width;
142 p_dst = dst_addr;
143 for (; p_src != p_src_end;) {
144 *p_dst = *p_src++;
145 p_dst -= dst_widthstep;
146 }
147 src_addr += src_widthstep;
148 }
149 }
150
151 static inline void
rot_270_u16(unsigned short * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned short * dst_addr,const unsigned int dst_widthstep)152 rot_270_u16(unsigned short *src_addr, const unsigned int src_widthstep,
153 const unsigned int src_width, const unsigned int src_height,
154 unsigned short *dst_addr, const unsigned int dst_widthstep)
155 {
156 unsigned short *p_src, *p_src_end, *p_dst, *dst_addr_end;
157 dst_addr = (unsigned short *)((char *)dst_addr +
158 dst_widthstep * (src_width - 1));
159 dst_addr_end = dst_addr + src_height;
160 for (; dst_addr != dst_addr_end; dst_addr++) {
161 p_src = src_addr;
162 p_src_end = p_src + src_width;
163 p_dst = dst_addr;
164 for (; p_src != p_src_end;) {
165 *p_dst = *p_src++;
166 p_dst =
167 (unsigned short *)((char *)p_dst - dst_widthstep);
168 }
169 src_addr = (unsigned short *)((char *)src_addr + src_widthstep);
170 }
171 }
172
173 static inline void
rot_270_u32(unsigned int * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned int * dst_addr,const unsigned int dst_widthstep)174 rot_270_u32(unsigned int *src_addr, const unsigned int src_widthstep,
175 const unsigned int src_width, const unsigned int src_height,
176 unsigned int *dst_addr, const unsigned int dst_widthstep)
177 {
178 unsigned int *p_src, *p_src_end, *p_dst, *dst_addr_end;
179 dst_addr = (unsigned int *)((char *)dst_addr +
180 dst_widthstep * (src_width - 1));
181 dst_addr_end = dst_addr + src_height;
182 for (; dst_addr != dst_addr_end; dst_addr++) {
183 p_src = src_addr;
184 p_src_end = p_src + src_width;
185 p_dst = dst_addr;
186 for (; p_src != p_src_end;) {
187 *p_dst = *p_src++;
188 p_dst = (unsigned int *)((char *)p_dst - dst_widthstep);
189 }
190 src_addr = (unsigned int *)((char *)src_addr + src_widthstep);
191 }
192 }
193
194 static inline void
rot_90_u8(unsigned char * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned char * dst_addr,const unsigned int dst_widthstep)195 rot_90_u8(unsigned char *src_addr, const unsigned int src_widthstep,
196 const unsigned int src_width, const unsigned int src_height,
197 unsigned char *dst_addr, const unsigned int dst_widthstep)
198 {
199 unsigned char *p_src, *p_src_end, *p_dst;
200 unsigned char *dst_addr_end = dst_addr - 1;
201 dst_addr = dst_addr_end + src_height;
202 for (; dst_addr != dst_addr_end; dst_addr--) {
203 p_src = src_addr;
204 p_src_end = p_src + src_width;
205 p_dst = dst_addr;
206 for (; p_src != p_src_end;) {
207 *p_dst = *p_src++;
208 p_dst += dst_widthstep;
209 }
210 src_addr += src_widthstep;
211 }
212 }
213
214 static inline void
rot_90_u16(unsigned short * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned short * dst_addr,const unsigned int dst_widthstep)215 rot_90_u16(unsigned short *src_addr, const unsigned int src_widthstep,
216 const unsigned int src_width, const unsigned int src_height,
217 unsigned short *dst_addr, const unsigned int dst_widthstep)
218 {
219 unsigned short *p_src, *p_src_end, *p_dst;
220 unsigned short *dst_addr_end = dst_addr - 1;
221 dst_addr = dst_addr_end + src_height;
222 for (; dst_addr != dst_addr_end; dst_addr--) {
223 p_src = src_addr;
224 p_src_end = p_src + src_width;
225 p_dst = dst_addr;
226 for (; p_src != p_src_end;) {
227 *p_dst = *p_src++;
228 p_dst =
229 (unsigned short *)((char *)p_dst + dst_widthstep);
230 }
231 src_addr = (unsigned short *)((char *)src_addr + src_widthstep);
232 }
233 }
234
235 #ifndef CONFIG_DISP2_SUNXI_NEON_ROTATION
236 static inline void
rot_90_u32(unsigned int * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned int * dst_addr,const unsigned int dst_widthstep)237 rot_90_u32(unsigned int *src_addr, const unsigned int src_widthstep,
238 const unsigned int src_width, const unsigned int src_height,
239 unsigned int *dst_addr, const unsigned int dst_widthstep)
240 {
241 unsigned int *p_src, *p_src_end, *p_dst;
242 unsigned int *dst_addr_end = dst_addr - 1;
243 dst_addr = dst_addr_end + src_height;
244 for (; dst_addr != dst_addr_end; dst_addr--) {
245 p_src = src_addr;
246 p_src_end = p_src + src_width;
247 p_dst = dst_addr;
248 for (; p_src != p_src_end;) {
249 *p_dst = *p_src++;
250 p_dst = (unsigned int *)((char *)p_dst + dst_widthstep);
251 }
252 src_addr = (unsigned int *)((char *)src_addr + src_widthstep);
253 }
254 }
255 #endif
256
257 #ifdef WRITE_SEQUENTIAL_CONFIG
258
259 static inline void
rot_180_seq_w_u8(unsigned char * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned char * dst_addr,const unsigned int dst_widthstep)260 rot_180_seq_w_u8(unsigned char *src_addr, const unsigned int src_widthstep,
261 const unsigned int src_width, const unsigned int src_height,
262 unsigned char *dst_addr, const unsigned int dst_widthstep)
263 {
264 unsigned char *p_src, *p_dst, *p_dst_end;
265 unsigned char *src_addr_end = src_addr - src_widthstep + src_width - 1;
266 src_addr = src_addr_end + src_widthstep * src_height;
267 for (; src_addr != src_addr_end;) {
268 p_src = src_addr;
269 p_dst = dst_addr;
270 p_dst_end = p_dst + src_width;
271 for (; p_dst != p_dst_end;) {
272 *p_dst++ = *p_src--;
273 }
274 dst_addr += dst_widthstep;
275 src_addr -= src_widthstep;
276 }
277 }
278
279 static inline void
rot_180_seq_w_u16(unsigned short * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned short * dst_addr,const unsigned int dst_widthstep)280 rot_180_seq_w_u16(unsigned short *src_addr, const unsigned int src_widthstep,
281 const unsigned int src_width, const unsigned int src_height,
282 unsigned short *dst_addr, const unsigned int dst_widthstep)
283 {
284 unsigned short *p_src, *p_dst, *p_dst_end;
285 unsigned short *src_addr_end = src_addr + src_width - 1;
286 src_addr_end = (unsigned short *)((char *)src_addr_end - src_widthstep);
287 src_addr = (unsigned short *)((char *)src_addr_end +
288 src_widthstep * src_height);
289 for (; src_addr != src_addr_end;) {
290 p_src = src_addr;
291 p_dst = dst_addr;
292 p_dst_end = p_dst + src_width;
293 for (; p_dst != p_dst_end;) {
294 *p_dst++ = *p_src--;
295 }
296 src_addr = (unsigned short *)((char *)src_addr - src_widthstep);
297 dst_addr = (unsigned short *)((char *)dst_addr + dst_widthstep);
298 }
299 }
300
301 static inline void
rot_180_seq_w_u32(unsigned int * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned int * dst_addr,const unsigned int dst_widthstep)302 rot_180_seq_w_u32(unsigned int *src_addr, const unsigned int src_widthstep,
303 const unsigned int src_width, const unsigned int src_height,
304 unsigned int *dst_addr, const unsigned int dst_widthstep)
305 {
306 unsigned int *p_src, *p_dst, *p_dst_end;
307 unsigned int *src_addr_end = src_addr + src_width - 1;
308 src_addr_end = (unsigned int *)((char *)src_addr_end - src_widthstep);
309 src_addr =
310 (unsigned int *)((char *)src_addr_end + src_widthstep * src_height);
311 for (; src_addr != src_addr_end;) {
312 p_src = src_addr;
313 p_dst = dst_addr;
314 p_dst_end = p_dst + src_width;
315 for (; p_dst != p_dst_end;) {
316 *p_dst++ = *p_src--;
317 }
318 src_addr = (unsigned int *)((char *)src_addr - src_widthstep);
319 dst_addr = (unsigned int *)((char *)dst_addr + dst_widthstep);
320 }
321 }
322
323 static inline void
rot_90_seq_w_u8(unsigned char * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned char * dst_addr,const unsigned int dst_widthstep)324 rot_90_seq_w_u8(unsigned char *src_addr, const unsigned int src_widthstep,
325 const unsigned int src_width, const unsigned int src_height,
326 unsigned char *dst_addr, const unsigned int dst_widthstep)
327 {
328 unsigned char *p_src, *src_addr_end, *p_dst, *p_dst_end;
329 src_addr += (src_widthstep * (src_height - 1));
330 src_addr_end = src_addr + src_width;
331 for (; src_addr != src_addr_end; src_addr++) {
332 p_src = src_addr;
333 p_dst = dst_addr;
334 p_dst_end = p_dst + src_height;
335 for (; p_dst != p_dst_end;) {
336 *p_dst++ = *p_src;
337 p_src -= src_widthstep;
338 }
339 dst_addr += dst_widthstep;
340 }
341 }
342
343 static inline void
rot_90_seq_w_u16(unsigned short * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned short * dst_addr,const unsigned int dst_widthstep)344 rot_90_seq_w_u16(unsigned short *src_addr, const unsigned int src_widthstep,
345 const unsigned int src_width, const unsigned int src_height,
346 unsigned short *dst_addr, const unsigned int dst_widthstep)
347 {
348 unsigned short *p_src, *src_addr_end, *p_dst, *p_dst_end;
349 src_addr = (unsigned short *)((char *)src_addr +
350 (src_widthstep * (src_height - 1)));
351 src_addr_end = src_addr + src_width;
352 for (; src_addr != src_addr_end; src_addr++) {
353 p_src = src_addr;
354 p_dst = dst_addr;
355 p_dst_end = p_dst + src_height;
356 for (; p_dst != p_dst_end;) {
357 *p_dst++ = *p_src;
358 p_src =
359 (unsigned short *)((char *)p_src - src_widthstep);
360 }
361 dst_addr = (unsigned short *)((char *)dst_addr + dst_widthstep);
362 }
363 }
364
365 static inline void
rot_90_seq_w_u32(unsigned int * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned int * dst_addr,const unsigned int dst_widthstep)366 rot_90_seq_w_u32(unsigned int *src_addr, const unsigned int src_widthstep,
367 const unsigned int src_width, const unsigned int src_height,
368 unsigned int *dst_addr, const unsigned int dst_widthstep)
369 {
370 unsigned int *p_src, *src_addr_end, *p_dst, *p_dst_end;
371 src_addr = (unsigned int *)((char *)src_addr +
372 src_widthstep * (src_height - 1));
373 src_addr_end = src_addr + src_width;
374 for (; src_addr != src_addr_end; src_addr++) {
375 p_src = src_addr;
376 p_dst = dst_addr;
377 p_dst_end = p_dst + src_height;
378 for (; p_dst != p_dst_end;) {
379 *p_dst++ = *p_src;
380 p_src = (unsigned int *)((char *)p_src - src_widthstep);
381 }
382 dst_addr = (unsigned int *)((char *)dst_addr + dst_widthstep);
383 }
384 }
385
386 static inline void
rot_270_seq_w_u8(unsigned char * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned char * dst_addr,const unsigned int dst_widthstep)387 rot_270_seq_w_u8(unsigned char *src_addr, const unsigned int src_widthstep,
388 const unsigned int src_width, const unsigned int src_height,
389 unsigned char *dst_addr, const unsigned int dst_widthstep)
390 {
391 unsigned char *p_src, *p_dst, *p_dst_end;
392 unsigned char *src_addr_end = src_addr - 1;
393 src_addr = src_addr_end + src_width;
394 for (; src_addr != src_addr_end; src_addr--) {
395 p_src = src_addr;
396 p_dst = dst_addr;
397 p_dst_end = p_dst + src_height;
398 for (; p_dst != p_dst_end;) {
399 *p_dst++ = *p_src;
400 p_src += src_widthstep;
401 }
402 dst_addr += dst_widthstep;
403 }
404 }
405
406 static inline void
rot_270_seq_w_u16(unsigned short * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned short * dst_addr,const unsigned int dst_widthstep)407 rot_270_seq_w_u16(unsigned short *src_addr, const unsigned int src_widthstep,
408 const unsigned int src_width, const unsigned int src_height,
409 unsigned short *dst_addr, const unsigned int dst_widthstep)
410 {
411 unsigned short *p_src, *p_dst, *p_dst_end;
412 unsigned short *src_addr_end = src_addr - 1;
413 src_addr = src_addr_end + src_width;
414 for (; src_addr != src_addr_end; src_addr--) {
415 p_src = src_addr;
416 p_dst = dst_addr;
417 p_dst_end = p_dst + src_height;
418 for (; p_dst != p_dst_end;) {
419 *p_dst++ = *p_src;
420 p_src =
421 (unsigned short *)((char *)p_src + src_widthstep);
422 }
423 dst_addr = (unsigned short *)((char *)dst_addr + dst_widthstep);
424 }
425 }
426
427 static inline void
rot_270_seq_w_u32(unsigned int * src_addr,const unsigned int src_widthstep,const unsigned int src_width,const unsigned int src_height,unsigned int * dst_addr,const unsigned int dst_widthstep)428 rot_270_seq_w_u32(unsigned int *src_addr, const unsigned int src_widthstep,
429 const unsigned int src_width, const unsigned int src_height,
430 unsigned int *dst_addr, const unsigned int dst_widthstep)
431 {
432 unsigned int *p_src, *p_dst, *p_dst_end;
433 unsigned int *src_addr_end = src_addr - 1;
434 src_addr = src_addr_end + src_width;
435 for (; src_addr != src_addr_end; src_addr--) {
436 p_src = src_addr;
437 p_dst = dst_addr;
438 p_dst_end = dst_addr + src_height;
439 for (; p_dst != p_dst_end;) {
440 *p_dst++ = *p_src;
441 p_src = (unsigned int *)((char *)p_src + src_widthstep);
442 }
443 dst_addr = (unsigned int *)((char *)dst_addr + dst_widthstep);
444 }
445 }
446 #endif
447 #endif
448