1 /*
2 * drivers/char/sunxi_g2d/g2d_rcq/g2d_rotate.c
3 *
4 * Copyright (c) 2007-2019 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 #include "g2d_rotate.h"
18 #include "g2d_top.h"
19 #include "g2d_driver_i.h"
20 #include <hal_mem.h>
21
22 /* Rotate register */
23 #define G2D_ROT (0x28000)
24 #define ROT_CTL (0x00 + G2D_ROT)
25 #define ROT_INT (0x04 + G2D_ROT)
26 #define ROT_TIMEOUT (0x08 + G2D_ROT)
27 #define ROT_IFMT (0x20 + G2D_ROT)
28 #define ROT_ISIZE (0x24 + G2D_ROT)
29 #define ROT_IPITCH0 (0x30 + G2D_ROT)
30 #define ROT_IPITCH1 (0x34 + G2D_ROT)
31 #define ROT_IPITCH2 (0x38 + G2D_ROT)
32 #define ROT_ILADD0 (0x40 + G2D_ROT)
33 #define ROT_IHADD0 (0x44 + G2D_ROT)
34 #define ROT_ILADD1 (0x48 + G2D_ROT)
35 #define ROT_IHADD1 (0x4C + G2D_ROT)
36 #define ROT_ILADD2 (0x50 + G2D_ROT)
37 #define ROT_IHADD2 (0x54 + G2D_ROT)
38 #define ROT_OSIZE (0x84 + G2D_ROT)
39 #define ROT_OPITCH0 (0x90 + G2D_ROT)
40 #define ROT_OPITCH1 (0x94 + G2D_ROT)
41 #define ROT_OPITCH2 (0x98 + G2D_ROT)
42 #define ROT_OLADD0 (0xA0 + G2D_ROT)
43 #define ROT_OHADD0 (0xA4 + G2D_ROT)
44 #define ROT_OLADD1 (0xA8 + G2D_ROT)
45 #define ROT_OHADD1 (0xAC + G2D_ROT)
46 #define ROT_OLADD2 (0xB0 + G2D_ROT)
47 #define ROT_OHADD2 (0xB4 + G2D_ROT)
48 #define LBC_ENC_CTL (0xC8 + G2D_ROT)
49 #define LBC_CTL (0xCC + G2D_ROT)
50 #define LBC_DEC_CTL (0xD0 + G2D_ROT)
51 #define G2D_AHB_RESET (0x08)
52
53 static unsigned long base_addr;
54 /* #define write_wvalue(addr, data) m_usbwordwrite32( addr, data ) */
55 /* #define write_wvalue(addr, v) put_wvalue(addr, v) */
56 /* #define read_wvalue(addr) get_wvalue(addr) */
57
58 /* byte input */
59 #define get_bvalue(n) (*(volatile uint8_t *)(n))
60 /* byte output */
61 #define put_bvalue(n, c) (*(volatile uint8_t *)(n) = c)
62 /* half word input */
63 #define get_hvalue(n) (*(volatile uint16_t *)(n))
64 /* half word output */
65 #define put_hvalue(n, c) (*(volatile uint16_t *)(n) = (c))
66 /* word input */
67 #define get_wvalue(n) (*(volatile uint32_t *)(n))
68 /* word output */
69 #define put_wvalue(n, c) (*(volatile uint32_t *)(n) = (c))
70
71 /* byte input */
72 #define read_bvalue(offset) get_bvalue(base_addr + offset)
73 /* byte output */
74 #define write_bvalue(offset, value) put_bvalue(base_addr + offset, value)
75 /* half word input */
76 #define read_hvalue(offset) get_hvalue(base_addr + offset)
77 /* half word output */
78 #define write_hvalue(offset, value) put_hvalue(base_addr + offset, value)
79 /* word input */
80 #define read_wvalue(offset) get_wvalue(base_addr + offset)
81 /* word output */
82 #define write_wvalue(offset, value) put_wvalue(base_addr + offset, value)
83
g2d_rot_set_base(unsigned long base)84 void g2d_rot_set_base(unsigned long base)
85 {
86 base_addr = base;
87 }
88
89 /**
90 * G2D IRQ query funct
91 * if the mission finish IRQ flag was set to 1, then clear the flag
92 * and return 1
93 * if the IRQ was set to 0, then return 0
94 */
g2d_rot_irq_query(void)95 __s32 g2d_rot_irq_query(void)
96 {
97 __u32 tmp;
98
99 tmp = read_wvalue(ROT_INT);
100 if (tmp & 0x1) {
101 write_wvalue(ROT_INT, tmp);
102 return 1;
103 }
104 return 0;
105 }
106
g2d_rotate_set_para(g2d_image_enh * src,g2d_image_enh * dst,__u32 flag)107 __s32 g2d_rotate_set_para(g2d_image_enh *src, g2d_image_enh *dst, __u32 flag)
108 {
109 __u32 tmp;
110 __u32 ch, cw, cy, cx;
111 __u32 ycnt, ucnt, vcnt;
112 __s32 ret = -1;
113 __u32 pitch0, pitch1, pitch2;
114 __u64 addr0, addr1, addr2;
115
116 // write_wvalue(G2D_AHB_RESET, 0x0);
117
118
119
120 if (!dst || g2d_image_check(dst))
121 goto OUT;
122 if (!src || g2d_image_check(src))
123 goto OUT;
124
125 // write_wvalue(G2D_AHB_RESET, 0x3);
126
127 tmp = 1;
128 if (flag & G2D_ROT_H)
129 tmp |= 0x1 << 7;
130 if (flag & G2D_ROT_V)
131 tmp |= 0x1 << 6;
132 if ((flag & 0xf00) == G2D_ROT_90)
133 tmp |= 0x1 << 4;
134 if ((flag & 0xf00) == G2D_ROT_180)
135 tmp |= 0x2 << 4;
136 if ((flag & 0xf00) == G2D_ROT_270)
137 tmp |= 0x3 << 4;
138 if ((flag & 0xf00) == G2D_ROT_0)
139 tmp |= 0x0 << 4;
140
141 write_wvalue(ROT_CTL, tmp);
142 write_wvalue(ROT_IFMT, src->format & 0x3F);
143 write_wvalue(ROT_ISIZE, ((((src->clip_rect.h - 1) & 0x1fff) << 16)) |
144 ((src->clip_rect.w - 1) & 0x1fff));
145
146 if ((src->format >= G2D_FORMAT_YUV422UVC_V1U1V0U0) &&
147 (src->format <= G2D_FORMAT_YUV422_PLANAR)) {
148 cw = src->width >> 1;
149 ch = src->height;
150 cx = src->clip_rect.x >> 1;
151 cy = src->clip_rect.y;
152 }
153
154 else if ((src->format >= G2D_FORMAT_YUV420UVC_V1U1V0U0) &&
155 (src->format <= G2D_FORMAT_YUV420_PLANAR)) {
156 cw = src->width >> 1;
157 ch = src->height >> 1;
158 cx = src->clip_rect.x >> 1;
159 cy = src->clip_rect.y >> 1;
160 }
161
162 else if ((src->format >= G2D_FORMAT_YUV411UVC_V1U1V0U0) &&
163 (src->format <= G2D_FORMAT_YUV411_PLANAR)) {
164 cw = src->width >> 2;
165 ch = src->height;
166 cx = src->clip_rect.x >> 2;
167 cy = src->clip_rect.y;
168 }
169
170 else {
171 cw = 0;
172 ch = 0;
173 cx = 0;
174 cy = 0;
175 }
176
177 g2d_byte_cal(src->format, &ycnt, &ucnt, &vcnt);
178 pitch0 = cal_align(ycnt * src->width, src->align[0]);
179 write_wvalue(ROT_IPITCH0, pitch0);
180 pitch1 = cal_align(ucnt * cw, src->align[1]);
181 write_wvalue(ROT_IPITCH1, pitch1);
182 pitch2 = cal_align(vcnt * cw, src->align[2]);
183 write_wvalue(ROT_IPITCH2, pitch2);
184
185 addr0 = src->laddr[0] + ((__u64)src->haddr[0] << 32) +
186 pitch0 * src->clip_rect.y + ycnt * src->clip_rect.x;
187 write_wvalue(ROT_ILADD0, addr0 & 0xffffffff);
188 write_wvalue(ROT_IHADD0, (addr0 >> 32) & 0xff);
189 addr1 = src->laddr[1] + ((__u64)src->haddr[1] << 32) + pitch1 * cy +
190 ucnt * cx;
191 write_wvalue(ROT_ILADD1, addr1 & 0xffffffff);
192 write_wvalue(ROT_IHADD1, (addr1 >> 32) & 0xff);
193 addr2 = src->laddr[2] + ((__u64)src->haddr[2] << 32) + pitch2 * cy +
194 vcnt * cx;
195 write_wvalue(ROT_ILADD2, addr2 & 0xffffffff);
196 write_wvalue(ROT_IHADD2, (addr2 >> 32) & 0xff);
197
198 if (((flag & 0xf00) == G2D_ROT_90) | ((flag & 0xf00) == G2D_ROT_270)) {
199 dst->clip_rect.w = src->clip_rect.h;
200 dst->clip_rect.h = src->clip_rect.w;
201 }
202
203 else {
204 dst->clip_rect.w = src->clip_rect.w;
205 dst->clip_rect.h = src->clip_rect.h;
206 }
207 write_wvalue(ROT_OSIZE, ((((dst->clip_rect.h - 1) & 0x1fff) << 16)) |
208 ((dst->clip_rect.w - 1) & 0x1fff));
209 /* YUV output fmt only support 420 */
210 if (src->format == G2D_FORMAT_YUV422UVC_V1U1V0U0)
211 dst->format = G2D_FORMAT_YUV420UVC_V1U1V0U0;
212 else if (src->format == G2D_FORMAT_YUV422UVC_U1V1U0V0)
213 dst->format = G2D_FORMAT_YUV420UVC_U1V1U0V0;
214 else if (src->format == G2D_FORMAT_YUV422_PLANAR)
215 dst->format = G2D_FORMAT_YUV420_PLANAR;
216 else
217 dst->format = src->format;
218
219 if ((dst->format >= G2D_FORMAT_YUV422UVC_V1U1V0U0) &&
220 (dst->format <= G2D_FORMAT_YUV422_PLANAR)) {
221 cw = dst->width >> 1;
222 ch = dst->height;
223 cx = dst->clip_rect.x >> 1;
224 cy = dst->clip_rect.y;
225 }
226
227 else if ((dst->format >= G2D_FORMAT_YUV420UVC_V1U1V0U0) &&
228 (dst->format <= G2D_FORMAT_YUV420_PLANAR)) {
229 cw = dst->width >> 1;
230 ch = dst->height >> 1;
231 cx = dst->clip_rect.x >> 1;
232 cy = dst->clip_rect.y >> 1;
233 }
234
235 else if ((dst->format >= G2D_FORMAT_YUV411UVC_V1U1V0U0) &&
236 (dst->format <= G2D_FORMAT_YUV411_PLANAR)) {
237 cw = dst->width >> 2;
238 ch = dst->height;
239 cx = dst->clip_rect.x >> 2;
240 cy = dst->clip_rect.y;
241 }
242
243 else {
244 cw = 0;
245 ch = 0;
246 cx = 0;
247 cy = 0;
248 }
249
250 g2d_byte_cal(dst->format, &ycnt, &ucnt, &vcnt);
251
252 pitch0 = cal_align(ycnt * dst->width, dst->align[0]);
253 write_wvalue(ROT_OPITCH0, pitch0);
254 pitch1 = cal_align(ucnt * cw, dst->align[1]);
255 write_wvalue(ROT_OPITCH1, pitch1);
256 pitch2 = cal_align(vcnt * cw, dst->align[2]);
257 write_wvalue(ROT_OPITCH2, pitch2);
258
259 addr0 = dst->laddr[0] + ((__u64)dst->haddr[0] << 32) +
260 pitch0 * dst->clip_rect.y + ycnt * dst->clip_rect.x;
261 write_wvalue(ROT_OLADD0, addr0 & 0xffffffff);
262 write_wvalue(ROT_OHADD0, (addr0 >> 32) & 0xff);
263 addr1 = dst->laddr[1] + ((__u64)dst->haddr[1] << 32) + pitch1 * cy +
264 ucnt * cx;
265 write_wvalue(ROT_OLADD1, addr1 & 0xffffffff);
266 write_wvalue(ROT_OHADD1, (addr1 >> 32) & 0xff);
267 addr2 = dst->laddr[2] + ((__u64)dst->haddr[2] << 32) + pitch2 * cy +
268 vcnt * cx;
269 write_wvalue(ROT_OLADD2, addr2 & 0xffffffff);
270 write_wvalue(ROT_OHADD2, (addr2 >> 32) & 0xff);
271
272 /* start the module */
273 write_wvalue(ROT_INT, 0x10000);
274 tmp = read_wvalue(ROT_CTL);
275 tmp |= (0x1 << 31);
276 write_wvalue(ROT_CTL, tmp);
277
278 ret = g2d_wait_cmd_finish(WAIT_CMD_TIME_MS);
279
280 OUT:
281 return ret;
282 }
283
g2d_lbc_calc_ctrl(u32 flag,u32 frm_width,u32 frm_height,u32 cmp_ratio,u32 enc_is_lossy,u32 dec_is_lossy)284 __s32 g2d_lbc_calc_ctrl(u32 flag, u32 frm_width, u32 frm_height,
285 u32 cmp_ratio, u32 enc_is_lossy, u32 dec_is_lossy)
286 {
287 u32 tmp = 0;
288 u32 seg_width = 16, seg_height = 4;
289 u32 bit_depth = 8;
290 u32 enc_c_ratio = 333;
291 u32 ALIGN = 128;
292 u32 seg_tar_bits, seg_tar_bits_y, seg_tar_bits_c, dec_segline_tar_bits, enc_segline_tar_bits;
293 u32 y_mode_bits, c_mode_bits, y_data_bits, c_data_bits;
294
295 if (enc_is_lossy) {
296 seg_tar_bits = ((seg_width * seg_height * bit_depth * cmp_ratio * 3 / 2000) / ALIGN) * ALIGN;
297 seg_tar_bits_y = seg_tar_bits * (1024 - enc_c_ratio) / 1024;
298 seg_tar_bits_c = seg_tar_bits - seg_tar_bits_y;
299 dec_segline_tar_bits = ((frm_width + seg_width - 1) / seg_width) * seg_tar_bits;
300 if (((flag & 0xf00) == G2D_ROT_90) || ((flag & 0xf00) == G2D_ROT_270))
301 enc_segline_tar_bits = ((frm_height + seg_width - 1) / seg_width) * seg_tar_bits;
302 else
303 enc_segline_tar_bits = dec_segline_tar_bits;
304 } else {
305 y_mode_bits = seg_width / 8 * (3 * 2 + 2);
306 c_mode_bits = 2 * (seg_width / 2 / 8 * 2);
307 y_data_bits = seg_width * seg_height * bit_depth;
308 c_data_bits = seg_width * seg_height * bit_depth / 2 + 2 * (seg_width / 2 / 8) * 4;
309 seg_tar_bits = (y_data_bits + c_data_bits + y_mode_bits + c_mode_bits + ALIGN - 1) / ALIGN * ALIGN;
310 seg_tar_bits_y = seg_tar_bits;
311 seg_tar_bits_c = 0;
312 dec_segline_tar_bits = ((frm_width + seg_width - 1) / seg_width) * seg_tar_bits;
313 if (((flag & 0xf00) == G2D_ROT_90) || ((flag & 0xf00) == G2D_ROT_270))
314 enc_segline_tar_bits = ((frm_height + seg_width - 1) / seg_width) * seg_tar_bits;
315 else
316 enc_segline_tar_bits = dec_segline_tar_bits;
317 }
318 tmp |= (enc_is_lossy << 31);
319 /*tmp |= (0x1 << 30);*///fix me
320 tmp |= (0x1 << 29);/*only 1 frame not care use even */
321 tmp |= ((enc_c_ratio & 0x3ff) << 19);
322 tmp |= ((enc_segline_tar_bits & 0x1ffff) << 2);
323 tmp |= (0x1 << 1);
324 write_wvalue(LBC_ENC_CTL, tmp);
325
326 tmp = read_wvalue(LBC_CTL);
327 tmp |= ((seg_tar_bits_y & 0x7ff) << 21);
328 tmp |= ((seg_tar_bits_c & 0x7ff) << 10);
329 write_wvalue(LBC_CTL, tmp);
330
331 tmp = 0;
332 tmp |= ((dec_segline_tar_bits & 0x1ffff) << 2);
333 tmp |= (dec_is_lossy << 31);
334 write_wvalue(LBC_DEC_CTL, tmp);
335
336 return 0;
337 }
g2d_lbc_rot_set_para(g2d_lbc_rot * para)338 __s32 g2d_lbc_rot_set_para(g2d_lbc_rot *para)
339 {
340 __u32 tmp = 0;
341 __u32 lbc = 0;
342 __u32 ch, cw, cy, cx;
343 __u32 ycnt, ucnt, vcnt;
344 __s32 ret = -1;
345 __u32 pitch0, pitch1, pitch2;
346 __u64 addr0, addr1, addr2;
347 struct dmabuf_item *src_item = NULL;
348 struct dmabuf_item *dst_item = NULL;
349 /* lbc para */
350 u32 frm_width = 0, frm_height = 0;
351 u32 cmp_ratio = 500;
352 u32 enc_is_lossy = 1, dec_is_lossy = 1;
353
354 __u32 flag = para->blt.flag_h;
355 g2d_image_enh *src = ¶->blt.src_image_h;
356 g2d_image_enh *dst = ¶->blt.dst_image_h;
357
358 // write_wvalue(G2D_AHB_RESET, 0x0);
359
360 if (!dst || g2d_image_check(dst))
361 goto OUT;
362 if (!src || g2d_image_check(src))
363 goto OUT;
364
365 if ((src->format != G2D_FORMAT_YUV420_PLANAR) ||
366 (dst->format != G2D_FORMAT_YUV420_PLANAR)) {
367 G2D_ERR_MSG("LBC only support YUV420 plannar fmt!\n");
368 goto OUT;
369 }
370
371 if (((flag & 0xf00) == G2D_ROT_180) || ((flag & 0xf000) == G2D_ROT_V)) {
372 G2D_ERR_MSG("LBC not support 180 and V flip!\n");
373 goto OUT;
374 }
375 /*
376 if (!src->use_phy_addr || !dst->use_phy_addr) {
377 src_item = hal_malloc(sizeof(struct dmabuf_item));
378 if (src_item == NULL) {
379 G2D_ERR_MSG("malloc memory of size %u fail!\n",
380 (unsigned int)sizeof(struct dmabuf_item));
381 goto OUT;
382 }
383 dst_item = hal_malloc(sizeof(struct dmabuf_item));
384 if (dst_item == NULL) {
385 G2D_ERR_MSG("malloc memory of size %u fail!\n",
386 (unsigned int)sizeof(struct dmabuf_item));
387 goto FREE_SRC;
388 }*/
389 /* ret = g2d_dma_map(src->fd, src_item);
390 if (ret != 0) {
391 G2D_ERR_MSG("map src_item fail!\n");
392 goto FREE_DST;
393 }
394 g2d_set_info(src, src_item);
395
396 ret = g2d_dma_map(dst->fd, dst_item);
397 if (ret != 0) {
398 G2D_ERR_MSG("map dst_item fail!\n");
399 goto SRC_DMA_UNMAP;
400 }
401 g2d_set_info(dst, dst_item);
402 }*/
403 // write_wvalue(G2D_AHB_RESET, 0x3);
404
405 /* rotate use same format */
406 dst->format = src->format;
407
408 tmp = 1;
409 write_wvalue(ROT_CTL, tmp);
410
411 if ((flag & 0xf00) == G2D_ROT_0)
412 lbc |= 0x0 << 7;
413 if ((flag & 0xf00) == G2D_ROT_90)
414 lbc |= 0x1 << 7;
415 if ((flag & 0xf00) == G2D_ROT_270)
416 lbc |= 0x2 << 7;
417 if (flag & G2D_ROT_H)
418 lbc |= 0x3 << 7;
419 write_wvalue(LBC_CTL, lbc);
420
421 write_wvalue(ROT_IFMT, src->format & 0x3F);
422 write_wvalue(ROT_ISIZE, ((((src->clip_rect.h - 1) & 0x1fff) << 16)) |
423 ((src->clip_rect.w - 1) & 0x1fff));
424
425 if ((src->format >= G2D_FORMAT_YUV422UVC_V1U1V0U0) &&
426 (src->format <= G2D_FORMAT_YUV422_PLANAR)) {
427 cw = src->width >> 1;
428 ch = src->height;
429 cx = src->clip_rect.x >> 1;
430 cy = src->clip_rect.y;
431 }
432
433 else if ((src->format >= G2D_FORMAT_YUV420UVC_V1U1V0U0) &&
434 (src->format <= G2D_FORMAT_YUV420_PLANAR)) {
435 cw = src->width >> 1;
436 ch = src->height >> 1;
437 cx = src->clip_rect.x >> 1;
438 cy = src->clip_rect.y >> 1;
439 }
440
441 else if ((src->format >= G2D_FORMAT_YUV411UVC_V1U1V0U0) &&
442 (src->format <= G2D_FORMAT_YUV411_PLANAR)) {
443 cw = src->width >> 2;
444 ch = src->height;
445 cx = src->clip_rect.x >> 2;
446 cy = src->clip_rect.y;
447 }
448
449 else {
450 cw = 0;
451 ch = 0;
452 cx = 0;
453 cy = 0;
454 }
455
456 g2d_byte_cal(src->format, &ycnt, &ucnt, &vcnt);
457 pitch0 = cal_align(ycnt * src->width, src->align[0]);
458 write_wvalue(ROT_IPITCH0, pitch0);
459 pitch1 = cal_align(ucnt * cw, src->align[1]);
460 write_wvalue(ROT_IPITCH1, pitch1);
461 pitch2 = cal_align(vcnt * cw, src->align[2]);
462 write_wvalue(ROT_IPITCH2, pitch2);
463
464 addr0 = src->laddr[0] + ((__u64)src->haddr[0] << 32) +
465 pitch0 * src->clip_rect.y + ycnt * src->clip_rect.x;
466 write_wvalue(ROT_ILADD0, addr0 & 0xffffffff);
467 write_wvalue(ROT_IHADD0, (addr0 >> 32) & 0xff);
468 addr1 = src->laddr[1] + ((__u64)src->haddr[1] << 32) + pitch1 * cy +
469 ucnt * cx;
470 write_wvalue(ROT_ILADD1, addr1 & 0xffffffff);
471 write_wvalue(ROT_IHADD1, (addr1 >> 32) & 0xff);
472 addr2 = src->laddr[2] + ((__u64)src->haddr[2] << 32) + pitch2 * cy +
473 vcnt * cx;
474 write_wvalue(ROT_ILADD2, addr2 & 0xffffffff);
475 write_wvalue(ROT_IHADD2, (addr2 >> 32) & 0xff);
476
477 if (((flag & 0xf00) == G2D_ROT_90) || ((flag & 0xf00) == G2D_ROT_270)) {
478 dst->clip_rect.w = src->clip_rect.h;
479 dst->clip_rect.h = src->clip_rect.w;
480 }
481
482 else {
483 dst->clip_rect.w = src->clip_rect.w;
484 dst->clip_rect.h = src->clip_rect.h;
485 }
486 write_wvalue(ROT_OSIZE, ((((dst->clip_rect.h - 1) & 0x1fff) << 16)) |
487 ((dst->clip_rect.w - 1) & 0x1fff));
488
489
490 if ((dst->format >= G2D_FORMAT_YUV422UVC_V1U1V0U0) &&
491 (dst->format <= G2D_FORMAT_YUV422_PLANAR)) {
492 cw = dst->width >> 1;
493 ch = dst->height;
494 cx = dst->clip_rect.x >> 1;
495 cy = dst->clip_rect.y;
496 }
497
498 else if ((dst->format >= G2D_FORMAT_YUV420UVC_V1U1V0U0) &&
499 (dst->format <= G2D_FORMAT_YUV420_PLANAR)) {
500 cw = dst->width >> 1;
501 ch = dst->height >> 1;
502 cx = dst->clip_rect.x >> 1;
503 cy = dst->clip_rect.y >> 1;
504 }
505
506 else if ((dst->format >= G2D_FORMAT_YUV411UVC_V1U1V0U0) &&
507 (dst->format <= G2D_FORMAT_YUV411_PLANAR)) {
508 cw = dst->width >> 2;
509 ch = dst->height;
510 cx = dst->clip_rect.x >> 2;
511 cy = dst->clip_rect.y;
512 }
513
514 else {
515 cw = 0;
516 ch = 0;
517 cx = 0;
518 cy = 0;
519 }
520
521 g2d_byte_cal(dst->format, &ycnt, &ucnt, &vcnt);
522
523 pitch0 = cal_align(ycnt * dst->width, dst->align[0]);
524 write_wvalue(ROT_OPITCH0, pitch0);
525 pitch1 = cal_align(ucnt * cw, dst->align[1]);
526 write_wvalue(ROT_OPITCH1, pitch1);
527 pitch2 = cal_align(vcnt * cw, dst->align[2]);
528 write_wvalue(ROT_OPITCH2, pitch2);
529
530 addr0 = dst->laddr[0] + ((__u64)dst->haddr[0] << 32) +
531 pitch0 * dst->clip_rect.y + ycnt * dst->clip_rect.x;
532 write_wvalue(ROT_OLADD0, addr0 & 0xffffffff);
533 write_wvalue(ROT_OHADD0, (addr0 >> 32) & 0xff);
534 addr1 = dst->laddr[1] + ((__u64)dst->haddr[1] << 32) + pitch1 * cy +
535 ucnt * cx;
536 write_wvalue(ROT_OLADD1, addr1 & 0xffffffff);
537 write_wvalue(ROT_OHADD1, (addr1 >> 32) & 0xff);
538 addr2 = dst->laddr[2] + ((__u64)dst->haddr[2] << 32) + pitch2 * cy +
539 vcnt * cx;
540 write_wvalue(ROT_OLADD2, addr2 & 0xffffffff);
541 write_wvalue(ROT_OHADD2, (addr2 >> 32) & 0xff);
542
543
544 /* lbc */
545
546 frm_width = src->width;
547 frm_height = src->height;
548 cmp_ratio = para->lbc_cmp_ratio;
549 enc_is_lossy = para->enc_is_lossy;
550 dec_is_lossy = para->dec_is_lossy;
551 g2d_lbc_calc_ctrl(flag, frm_width, frm_height, cmp_ratio, enc_is_lossy, dec_is_lossy);
552
553 /* start the module */
554 write_wvalue(ROT_INT, 0x10000);
555 tmp = read_wvalue(ROT_CTL);
556 tmp |= (0x1 << 31);
557 write_wvalue(ROT_CTL, tmp);
558
559 ret = g2d_wait_cmd_finish(WAIT_CMD_TIME_MS);
560
561 /* if (!src->use_phy_addr || !dst->use_phy_addr)
562 g2d_dma_unmap(dst_item);
563 SRC_DMA_UNMAP:
564 if (!src->use_phy_addr || !dst->use_phy_addr)
565 g2d_dma_unmap(src_item);*/
566 FREE_DST:
567 free(dst_item);
568 FREE_SRC:
569 free(src_item);
570 OUT:
571 return ret;
572 }
573