1 /* drivers/video/msm/src/drv/mdp/mdp_ppp.c
3 * Copyright (C) 2007 Google Incorporated
4 * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <linux/module.h>
17 #include <linux/kernel.h>
18 #include <linux/sched.h>
19 #include <linux/time.h>
20 #include <linux/init.h>
21 #include <linux/interrupt.h>
24 #include <linux/file.h>
25 #include <linux/major.h>
27 #include "linux/proc_fs.h"
29 #include <mach/hardware.h>
32 #include <asm/system.h>
33 #include <asm/mach-types.h>
34 #include <linux/semaphore.h>
39 #define MDP_IS_IMGTYPE_BAD(x) (((x) >= MDP_IMGTYPE_LIMIT) && \
40 (((x) < MDP_IMGTYPE2_START) || \
41 ((x) >= MDP_IMGTYPE_LIMIT2)))
43 static uint32_t bytes_per_pixel
[] = {
50 [MDP_Y_CBCR_H2V1
] = 1,
51 [MDP_Y_CBCR_H2V2
] = 1,
52 [MDP_Y_CRCB_H2V1
] = 1,
53 [MDP_Y_CRCB_H2V2
] = 1,
54 [MDP_YCRYCB_H2V1
] = 2,
58 extern uint32 mdp_plv
[];
59 extern struct semaphore mdp_ppp_mutex
;
61 uint32_t mdp_get_bytes_per_pixel(uint32_t format
)
64 if (format
< ARRAY_SIZE(bytes_per_pixel
))
65 bpp
= bytes_per_pixel
[format
];
71 static uint32
mdp_conv_matx_rgb2yuv(uint32 input_pixel
,
72 uint16
*matrix_and_bias_vector
,
74 uint32
*look_up_table
)
76 uint8 input_C2
, input_C0
, input_C1
;
78 int32 comp_C2
, comp_C1
, comp_C0
, temp
;
79 int32 temp1
, temp2
, temp3
;
82 int32 Y_low_limit
, Y_high_limit
, C_low_limit
, C_high_limit
;
84 uint32 _is_lookup_table_enabled
;
86 input_C2
= (input_pixel
>> 16) & 0xFF;
87 input_C1
= (input_pixel
>> 8) & 0xFF;
88 input_C0
= (input_pixel
>> 0) & 0xFF;
94 for (i
= 0; i
< 9; i
++)
96 ((int32
) (((int32
) matrix_and_bias_vector
[i
]) << 20)) >> 20;
98 bias_vector
[0] = (int32
) (matrix_and_bias_vector
[9] & 0xFF);
99 bias_vector
[1] = (int32
) (matrix_and_bias_vector
[10] & 0xFF);
100 bias_vector
[2] = (int32
) (matrix_and_bias_vector
[11] & 0xFF);
102 Y_low_limit
= (int32
) clamp_vector
[0];
103 Y_high_limit
= (int32
) clamp_vector
[1];
104 C_low_limit
= (int32
) clamp_vector
[2];
105 C_high_limit
= (int32
) clamp_vector
[3];
107 if (look_up_table
== 0) /* check for NULL point */
108 _is_lookup_table_enabled
= 0;
110 _is_lookup_table_enabled
= 1;
112 if (_is_lookup_table_enabled
== 1) {
113 comp_C2
= (look_up_table
[comp_C2
] >> 16) & 0xFF;
114 comp_C1
= (look_up_table
[comp_C1
] >> 8) & 0xFF;
115 comp_C0
= (look_up_table
[comp_C0
] >> 0) & 0xFF;
119 * reorder input colors
126 /* matrix multiplication */
127 temp1
= comp_C0
* matrix
[0] + comp_C1
* matrix
[1] + comp_C2
* matrix
[2];
128 temp2
= comp_C0
* matrix
[3] + comp_C1
* matrix
[4] + comp_C2
* matrix
[5];
129 temp3
= comp_C0
* matrix
[6] + comp_C1
* matrix
[7] + comp_C2
* matrix
[8];
131 comp_C0
= temp1
+ 0x100;
132 comp_C1
= temp2
+ 0x100;
133 comp_C2
= temp3
+ 0x100;
135 /* take interger part */
141 comp_C0
+= bias_vector
[0];
142 comp_C1
+= bias_vector
[1];
143 comp_C2
+= bias_vector
[2];
145 /* limit pixel to 8-bit */
165 if (comp_C0
< Y_low_limit
)
166 comp_C0
= Y_low_limit
;
168 if (comp_C0
> Y_high_limit
)
169 comp_C0
= Y_high_limit
;
171 if (comp_C1
< C_low_limit
)
172 comp_C1
= C_low_limit
;
174 if (comp_C1
> C_high_limit
)
175 comp_C1
= C_high_limit
;
177 if (comp_C2
< C_low_limit
)
178 comp_C2
= C_low_limit
;
180 if (comp_C2
> C_high_limit
)
181 comp_C2
= C_high_limit
;
183 output
= (comp_C2
<< 16) | (comp_C1
<< 8) | comp_C0
;
187 uint32
mdp_conv_matx_yuv2rgb(uint32 input_pixel
,
188 uint16
*matrix_and_bias_vector
,
189 uint32
*clamp_vector
, uint32
*look_up_table
)
191 uint8 input_C2
, input_C0
, input_C1
;
193 int32 comp_C2
, comp_C1
, comp_C0
, temp
;
194 int32 temp1
, temp2
, temp3
;
196 int32 bias_vector
[3];
197 int32 Y_low_limit
, Y_high_limit
, C_low_limit
, C_high_limit
;
199 uint32 _is_lookup_table_enabled
;
201 input_C2
= (input_pixel
>> 16) & 0xFF;
202 input_C1
= (input_pixel
>> 8) & 0xFF;
203 input_C0
= (input_pixel
>> 0) & 0xFF;
209 for (i
= 0; i
< 9; i
++)
211 ((int32
) (((int32
) matrix_and_bias_vector
[i
]) << 20)) >> 20;
213 bias_vector
[0] = (int32
) (matrix_and_bias_vector
[9] & 0xFF);
214 bias_vector
[1] = (int32
) (matrix_and_bias_vector
[10] & 0xFF);
215 bias_vector
[2] = (int32
) (matrix_and_bias_vector
[11] & 0xFF);
217 Y_low_limit
= (int32
) clamp_vector
[0];
218 Y_high_limit
= (int32
) clamp_vector
[1];
219 C_low_limit
= (int32
) clamp_vector
[2];
220 C_high_limit
= (int32
) clamp_vector
[3];
222 if (look_up_table
== 0) /* check for NULL point */
223 _is_lookup_table_enabled
= 0;
225 _is_lookup_table_enabled
= 1;
228 if (comp_C0
< Y_low_limit
)
229 comp_C0
= Y_low_limit
;
231 if (comp_C0
> Y_high_limit
)
232 comp_C0
= Y_high_limit
;
234 if (comp_C1
< C_low_limit
)
235 comp_C1
= C_low_limit
;
237 if (comp_C1
> C_high_limit
)
238 comp_C1
= C_high_limit
;
240 if (comp_C2
< C_low_limit
)
241 comp_C2
= C_low_limit
;
243 if (comp_C2
> C_high_limit
)
244 comp_C2
= C_high_limit
;
250 comp_C0
-= bias_vector
[0];
251 comp_C1
-= bias_vector
[1];
252 comp_C2
-= bias_vector
[2];
254 /* matrix multiplication */
255 temp1
= comp_C0
* matrix
[0] + comp_C1
* matrix
[1] + comp_C2
* matrix
[2];
256 temp2
= comp_C0
* matrix
[3] + comp_C1
* matrix
[4] + comp_C2
* matrix
[5];
257 temp3
= comp_C0
* matrix
[6] + comp_C1
* matrix
[7] + comp_C2
* matrix
[8];
259 comp_C0
= temp1
+ 0x100;
260 comp_C1
= temp2
+ 0x100;
261 comp_C2
= temp3
+ 0x100;
263 /* take interger part */
268 /* reorder output colors */
274 /* limit pixel to 8-bit */
294 if (_is_lookup_table_enabled
== 1) {
295 comp_C2
= (look_up_table
[comp_C2
] >> 16) & 0xFF;
296 comp_C1
= (look_up_table
[comp_C1
] >> 8) & 0xFF;
297 comp_C0
= (look_up_table
[comp_C0
] >> 0) & 0xFF;
300 output
= (comp_C2
<< 16) | (comp_C1
<< 8) | comp_C0
;
304 static uint32
mdp_calc_tpval(MDPIMG
*mdpImg
)
310 if ((mdpImg
->imgType
== MDP_RGB_565
)
311 || (mdpImg
->imgType
== MDP_BGR_565
)) {
313 * transparent color conversion into 24 bpp
316 * left shift the entire bit and or it with the upper most bits
318 plane_tp
= (uint8
) ((mdpImg
->tpVal
& 0xF800) >> 11);
319 tpVal
|= ((plane_tp
<< 3) | ((plane_tp
& 0x1C) >> 2)) << 16;
322 plane_tp
= (uint8
) (mdpImg
->tpVal
& 0x1F);
323 tpVal
|= ((plane_tp
<< 3) | ((plane_tp
& 0x1C) >> 2)) << 8;
326 plane_tp
= (uint8
) ((mdpImg
->tpVal
& 0x7E0) >> 5);
327 tpVal
|= ((plane_tp
<< 2) | ((plane_tp
& 0x30) >> 4));
329 /* 24bit RGB to RBG conversion */
331 tpVal
= (mdpImg
->tpVal
& 0xFF00) >> 8;
332 tpVal
|= (mdpImg
->tpVal
& 0xFF) << 8;
333 tpVal
|= (mdpImg
->tpVal
& 0xFF0000);
339 static uint8
*mdp_get_chroma_addr(MDPIBUF
*iBuf
)
344 switch (iBuf
->ibuf_type
) {
345 case MDP_Y_CBCR_H2V2
:
346 case MDP_Y_CRCB_H2V2
:
347 case MDP_Y_CBCR_H2V1
:
348 case MDP_Y_CRCB_H2V1
:
349 dest1
= (uint8
*) iBuf
->buf
;
350 dest1
+= iBuf
->ibuf_width
* iBuf
->ibuf_height
* iBuf
->bpp
;
360 static void mdp_ppp_setbg(MDPIBUF
*iBuf
)
364 uint32 bg0_ystride
, bg1_ystride
;
365 uint32 ppp_src_cfg_reg
, unpack_pattern
;
366 int v_slice
, h_slice
;
368 v_slice
= h_slice
= 1;
369 bg0_addr
= (uint8
*) iBuf
->buf
;
370 bg1_addr
= mdp_get_chroma_addr(iBuf
);
372 bg0_ystride
= iBuf
->ibuf_width
* iBuf
->bpp
;
373 bg1_ystride
= iBuf
->ibuf_width
* iBuf
->bpp
;
375 switch (iBuf
->ibuf_type
) {
382 ppp_src_cfg_reg
= PPP_SRC_C2R_5BITS
| PPP_SRC_C0G_6BITS
|
383 PPP_SRC_C1B_5BITS
| PPP_SRC_BPP_INTERLVD_2BYTES
|
384 PPP_SRC_INTERLVD_3COMPONENTS
| PPP_SRC_UNPACK_TIGHT
|
385 PPP_SRC_UNPACK_ALIGN_LSB
|
386 PPP_SRC_FETCH_PLANES_INTERLVD
;
388 if (iBuf
->ibuf_type
== MDP_RGB_565
)
390 MDP_GET_PACK_PATTERN(0, CLR_R
, CLR_G
, CLR_B
, 8);
393 MDP_GET_PACK_PATTERN(0, CLR_B
, CLR_G
, CLR_R
, 8);
402 ppp_src_cfg_reg
= PPP_SRC_C2R_8BITS
| PPP_SRC_C0G_8BITS
|
403 PPP_SRC_C1B_8BITS
| PPP_SRC_BPP_INTERLVD_3BYTES
|
404 PPP_SRC_INTERLVD_3COMPONENTS
| PPP_SRC_UNPACK_TIGHT
|
405 PPP_SRC_UNPACK_ALIGN_LSB
| PPP_SRC_FETCH_PLANES_INTERLVD
;
408 MDP_GET_PACK_PATTERN(0, CLR_R
, CLR_G
, CLR_B
, 8);
420 ppp_src_cfg_reg
= PPP_SRC_C2R_8BITS
| PPP_SRC_C0G_8BITS
|
421 PPP_SRC_C1B_8BITS
| PPP_SRC_C3A_8BITS
| PPP_SRC_C3_ALPHA_EN
|
422 PPP_SRC_BPP_INTERLVD_4BYTES
| PPP_SRC_INTERLVD_4COMPONENTS
|
423 PPP_SRC_UNPACK_TIGHT
| PPP_SRC_UNPACK_ALIGN_LSB
|
424 PPP_SRC_FETCH_PLANES_INTERLVD
;
426 if (iBuf
->ibuf_type
== MDP_BGRA_8888
)
428 MDP_GET_PACK_PATTERN(CLR_ALPHA
, CLR_R
, CLR_G
, CLR_B
,
430 else if (iBuf
->ibuf_type
== MDP_RGBA_8888
)
432 MDP_GET_PACK_PATTERN(CLR_ALPHA
, CLR_B
, CLR_G
, CLR_R
,
436 MDP_GET_PACK_PATTERN(CLR_ALPHA
, CLR_R
, CLR_G
, CLR_B
,
440 case MDP_Y_CBCR_H2V2
:
441 case MDP_Y_CRCB_H2V2
:
442 ppp_src_cfg_reg
= PPP_SRC_C2R_8BITS
|
446 PPP_SRC_BPP_INTERLVD_2BYTES
|
447 PPP_SRC_INTERLVD_2COMPONENTS
|
448 PPP_SRC_UNPACK_TIGHT
|
449 PPP_SRC_UNPACK_ALIGN_LSB
| PPP_SRC_FETCH_PLANES_PSEUDOPLNR
;
451 if (iBuf
->ibuf_type
== MDP_Y_CBCR_H2V1
)
453 MDP_GET_PACK_PATTERN(0, 0, CLR_CB
, CLR_CR
, 8);
456 MDP_GET_PACK_PATTERN(0, 0, CLR_CR
, CLR_CB
, 8);
457 v_slice
= h_slice
= 2;
460 case MDP_YCRYCB_H2V1
:
461 ppp_src_cfg_reg
= PPP_SRC_C2R_8BITS
|
465 PPP_SRC_BPP_INTERLVD_2BYTES
|
466 PPP_SRC_INTERLVD_4COMPONENTS
|
467 PPP_SRC_UNPACK_TIGHT
| PPP_SRC_UNPACK_ALIGN_LSB
;
470 MDP_GET_PACK_PATTERN(CLR_Y
, CLR_CR
, CLR_Y
, CLR_CB
, 8);
474 case MDP_Y_CBCR_H2V1
:
475 case MDP_Y_CRCB_H2V1
:
476 ppp_src_cfg_reg
= PPP_SRC_C2R_8BITS
|
480 PPP_SRC_BPP_INTERLVD_2BYTES
|
481 PPP_SRC_INTERLVD_2COMPONENTS
|
482 PPP_SRC_UNPACK_TIGHT
|
483 PPP_SRC_UNPACK_ALIGN_LSB
| PPP_SRC_FETCH_PLANES_PSEUDOPLNR
;
485 if (iBuf
->ibuf_type
== MDP_Y_CBCR_H2V1
)
487 MDP_GET_PACK_PATTERN(0, 0, CLR_CB
, CLR_CR
, 8);
490 MDP_GET_PACK_PATTERN(0, 0, CLR_CR
, CLR_CB
, 8);
498 /* starting input address adjustment */
499 mdp_adjust_start_addr(&bg0_addr
, &bg1_addr
, v_slice
, h_slice
,
500 iBuf
->roi
.lcd_x
, iBuf
->roi
.lcd_y
,
501 iBuf
->ibuf_width
, iBuf
->ibuf_height
, iBuf
->bpp
,
505 * 0x01c0: background plane 0 addr
506 * 0x01c4: background plane 1 addr
507 * 0x01c8: background plane 2 addr
508 * 0x01cc: bg y stride for plane 0 and 1
509 * 0x01d0: bg y stride for plane 2
510 * 0x01d4: bg src PPP config
511 * 0x01d8: unpack pattern
513 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x01c0, bg0_addr
);
514 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x01c4, bg1_addr
);
516 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x01cc,
517 (bg1_ystride
<< 16) | bg0_ystride
);
518 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x01d4, ppp_src_cfg_reg
);
520 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x01d8, unpack_pattern
);
523 #define IS_PSEUDOPLNR(img) ((img == MDP_Y_CRCB_H2V2) | \
524 (img == MDP_Y_CBCR_H2V2) | \
525 (img == MDP_Y_CRCB_H2V1) | \
526 (img == MDP_Y_CBCR_H2V1))
528 #define IMG_LEN(rect_h, w, rect_w, bpp) (((rect_h) * w) * bpp)
530 #define Y_TO_CRCB_RATIO(format) \
531 ((format == MDP_Y_CBCR_H2V2 || format == MDP_Y_CRCB_H2V2) ? 2 :\
532 (format == MDP_Y_CBCR_H2V1 || format == MDP_Y_CRCB_H2V1) ? 1 : 1)
534 static void get_len(struct mdp_img
*img
, struct mdp_rect
*rect
, uint32_t bpp
,
535 uint32_t *len0
, uint32_t *len1
)
537 *len0
= IMG_LEN(rect
->h
, img
->width
, rect
->w
, bpp
);
538 if (IS_PSEUDOPLNR(img
->format
))
539 *len1
= *len0
/Y_TO_CRCB_RATIO(img
->format
);
544 static void flush_imgs(struct mdp_blit_req
*req
, int src_bpp
, int dst_bpp
,
545 struct file
*p_src_file
, struct file
*p_dst_file
)
547 #ifdef CONFIG_ANDROID_PMEM
548 uint32_t src0_len
, src1_len
, dst0_len
, dst1_len
;
550 /* flush src images to memory before dma to mdp */
551 get_len(&req
->src
, &req
->src_rect
, src_bpp
,
552 &src0_len
, &src1_len
);
554 flush_pmem_file(p_src_file
,
555 req
->src
.offset
, src0_len
);
557 if (IS_PSEUDOPLNR(req
->src
.format
))
558 flush_pmem_file(p_src_file
,
559 req
->src
.offset
+ src0_len
, src1_len
);
561 get_len(&req
->dst
, &req
->dst_rect
, dst_bpp
, &dst0_len
, &dst1_len
);
562 flush_pmem_file(p_dst_file
, req
->dst
.offset
, dst0_len
);
564 if (IS_PSEUDOPLNR(req
->dst
.format
))
565 flush_pmem_file(p_dst_file
,
566 req
->dst
.offset
+ dst0_len
, dst1_len
);
570 static void mdp_start_ppp(struct msm_fb_data_type
*mfd
, MDPIBUF
*iBuf
,
571 struct mdp_blit_req
*req
, struct file
*p_src_file
, struct file
*p_dst_file
)
574 uint8
*dest0
, *dest1
;
576 uint32 dest0_ystride
;
580 uint32 dst_roi_width
;
581 uint32 dst_roi_height
;
582 uint32 ppp_src_cfg_reg
, ppp_operation_reg
, ppp_dst_cfg_reg
;
585 uint32 dst_packPattern
;
586 boolean inputRGB
, outputRGB
, pseudoplanr_output
;
587 int sv_slice
, sh_slice
;
588 int dv_slice
, dh_slice
;
589 boolean perPixelAlpha
= FALSE
;
590 boolean ppp_lookUp_enable
= FALSE
;
592 sv_slice
= sh_slice
= dv_slice
= dh_slice
= 1;
594 src_width
= iBuf
->mdpImg
.width
;
595 src_height
= iBuf
->roi
.y
+ iBuf
->roi
.height
;
599 inputRGB
= outputRGB
= TRUE
;
600 pseudoplanr_output
= FALSE
;
601 ppp_operation_reg
= 0;
605 /* Wait for the pipe to clear */
606 do { } while (mdp_ppp_pipe_wait() <= 0);
611 switch (iBuf
->ibuf_type
) {
614 MDP_GET_PACK_PATTERN(0, CLR_R
, CLR_G
, CLR_B
, 8);
616 PPP_DST_C0G_8BIT
| PPP_DST_C1B_8BIT
| PPP_DST_C2R_8BIT
|
617 PPP_DST_PACKET_CNT_INTERLVD_3ELEM
| PPP_DST_PACK_TIGHT
|
618 PPP_DST_PACK_ALIGN_LSB
| PPP_DST_OUT_SEL_AXI
|
619 PPP_DST_BPP_3BYTES
| PPP_DST_PLANE_INTERLVD
;
625 if (iBuf
->ibuf_type
== MDP_BGRA_8888
)
627 MDP_GET_PACK_PATTERN(CLR_ALPHA
, CLR_R
, CLR_G
, CLR_B
,
629 else if (iBuf
->ibuf_type
== MDP_RGBA_8888
)
631 MDP_GET_PACK_PATTERN(CLR_ALPHA
, CLR_B
, CLR_G
, CLR_R
,
635 MDP_GET_PACK_PATTERN(CLR_ALPHA
, CLR_R
, CLR_G
, CLR_B
,
638 ppp_dst_cfg_reg
= PPP_DST_C0G_8BIT
|
643 PPP_DST_PACKET_CNT_INTERLVD_4ELEM
|
645 PPP_DST_PACK_ALIGN_LSB
|
646 PPP_DST_OUT_SEL_AXI
|
647 PPP_DST_BPP_4BYTES
| PPP_DST_PLANE_INTERLVD
;
650 case MDP_Y_CBCR_H2V2
:
651 case MDP_Y_CRCB_H2V2
:
652 if (iBuf
->ibuf_type
== MDP_Y_CBCR_H2V2
)
654 MDP_GET_PACK_PATTERN(0, 0, CLR_CB
, CLR_CR
, 8);
657 MDP_GET_PACK_PATTERN(0, 0, CLR_CR
, CLR_CB
, 8);
659 ppp_dst_cfg_reg
= PPP_DST_C2R_8BIT
|
663 PPP_DST_PACKET_CNT_INTERLVD_2ELEM
|
665 PPP_DST_PACK_ALIGN_LSB
|
666 PPP_DST_OUT_SEL_AXI
| PPP_DST_BPP_2BYTES
;
668 ppp_operation_reg
|= PPP_OP_DST_CHROMA_420
;
670 pseudoplanr_output
= TRUE
;
672 * vertically (y direction) and horizontally (x direction)
673 * sample reduction by 2
677 * H2V2(YUV420) Cosite
686 dv_slice
= dh_slice
= 2;
688 /* (x,y) and (width,height) must be even numbern */
689 iBuf
->roi
.lcd_x
= (iBuf
->roi
.lcd_x
/ 2) * 2;
690 iBuf
->roi
.dst_width
= (iBuf
->roi
.dst_width
/ 2) * 2;
691 iBuf
->roi
.x
= (iBuf
->roi
.x
/ 2) * 2;
692 iBuf
->roi
.width
= (iBuf
->roi
.width
/ 2) * 2;
694 iBuf
->roi
.lcd_y
= (iBuf
->roi
.lcd_y
/ 2) * 2;
695 iBuf
->roi
.dst_height
= (iBuf
->roi
.dst_height
/ 2) * 2;
696 iBuf
->roi
.y
= (iBuf
->roi
.y
/ 2) * 2;
697 iBuf
->roi
.height
= (iBuf
->roi
.height
/ 2) * 2;
700 case MDP_YCRYCB_H2V1
:
702 MDP_GET_PACK_PATTERN(CLR_Y
, CLR_CR
, CLR_Y
, CLR_CB
, 8);
704 PPP_DST_C2R_8BIT
| PPP_DST_C0G_8BIT
| PPP_DST_C1B_8BIT
|
705 PPP_DST_C3A_8BIT
| PPP_DST_PACKET_CNT_INTERLVD_4ELEM
|
706 PPP_DST_PACK_TIGHT
| PPP_DST_PACK_ALIGN_LSB
|
707 PPP_DST_OUT_SEL_AXI
| PPP_DST_BPP_2BYTES
|
708 PPP_DST_PLANE_INTERLVD
;
710 ppp_operation_reg
|= PPP_OP_DST_CHROMA_H2V1
;
713 * horizontally (x direction) sample reduction by 2
715 * H2V1(YUV422) Cosite
725 * if it's TV-Out/MDP_YCRYCB_H2V1, let's go through the
726 * preloaded gamma setting of 2.2 when the content is
727 * non-linear ppp_lookUp_enable = TRUE;
730 /* x and width must be even number */
731 iBuf
->roi
.lcd_x
= (iBuf
->roi
.lcd_x
/ 2) * 2;
732 iBuf
->roi
.dst_width
= (iBuf
->roi
.dst_width
/ 2) * 2;
733 iBuf
->roi
.x
= (iBuf
->roi
.x
/ 2) * 2;
734 iBuf
->roi
.width
= (iBuf
->roi
.width
/ 2) * 2;
737 case MDP_Y_CBCR_H2V1
:
738 case MDP_Y_CRCB_H2V1
:
739 if (iBuf
->ibuf_type
== MDP_Y_CBCR_H2V1
)
741 MDP_GET_PACK_PATTERN(0, 0, CLR_CB
, CLR_CR
, 8);
744 MDP_GET_PACK_PATTERN(0, 0, CLR_CR
, CLR_CB
, 8);
746 ppp_dst_cfg_reg
= PPP_DST_C2R_8BIT
|
750 PPP_DST_PACKET_CNT_INTERLVD_2ELEM
|
752 PPP_DST_PACK_ALIGN_LSB
|
753 PPP_DST_OUT_SEL_AXI
| PPP_DST_BPP_2BYTES
;
755 ppp_operation_reg
|= PPP_OP_DST_CHROMA_H2V1
;
757 pseudoplanr_output
= TRUE
;
758 /* horizontally (x direction) sample reduction by 2 */
761 /* x and width must be even number */
762 iBuf
->roi
.lcd_x
= (iBuf
->roi
.lcd_x
/ 2) * 2;
763 iBuf
->roi
.dst_width
= (iBuf
->roi
.dst_width
/ 2) * 2;
764 iBuf
->roi
.x
= (iBuf
->roi
.x
/ 2) * 2;
765 iBuf
->roi
.width
= (iBuf
->roi
.width
/ 2) * 2;
771 if (iBuf
->ibuf_type
== MDP_RGB_565
)
773 MDP_GET_PACK_PATTERN(0, CLR_R
, CLR_G
, CLR_B
, 8);
776 MDP_GET_PACK_PATTERN(0, CLR_B
, CLR_G
, CLR_R
, 8);
778 ppp_dst_cfg_reg
= PPP_DST_C0G_6BIT
|
781 PPP_DST_PACKET_CNT_INTERLVD_3ELEM
|
783 PPP_DST_PACK_ALIGN_LSB
|
784 PPP_DST_OUT_SEL_AXI
|
785 PPP_DST_BPP_2BYTES
| PPP_DST_PLANE_INTERLVD
;
790 switch (iBuf
->mdpImg
.imgType
) {
798 ppp_src_cfg_reg
= PPP_SRC_C2R_8BITS
| PPP_SRC_C0G_8BITS
|
799 PPP_SRC_C1B_8BITS
| PPP_SRC_BPP_INTERLVD_3BYTES
|
800 PPP_SRC_INTERLVD_3COMPONENTS
| PPP_SRC_UNPACK_TIGHT
|
801 PPP_SRC_UNPACK_ALIGN_LSB
|
802 PPP_SRC_FETCH_PLANES_INTERLVD
;
804 packPattern
= MDP_GET_PACK_PATTERN(0, CLR_R
, CLR_G
, CLR_B
, 8);
806 ppp_operation_reg
|= PPP_OP_COLOR_SPACE_RGB
|
807 PPP_OP_SRC_CHROMA_RGB
| PPP_OP_DST_CHROMA_RGB
;
813 perPixelAlpha
= TRUE
;
821 ppp_src_cfg_reg
= PPP_SRC_C2R_8BITS
| PPP_SRC_C0G_8BITS
|
822 PPP_SRC_C1B_8BITS
| PPP_SRC_C3A_8BITS
|
823 PPP_SRC_C3_ALPHA_EN
| PPP_SRC_BPP_INTERLVD_4BYTES
|
824 PPP_SRC_INTERLVD_4COMPONENTS
| PPP_SRC_UNPACK_TIGHT
|
825 PPP_SRC_UNPACK_ALIGN_LSB
|
826 PPP_SRC_FETCH_PLANES_INTERLVD
;
828 if (iBuf
->mdpImg
.imgType
== MDP_BGRA_8888
)
830 MDP_GET_PACK_PATTERN(CLR_ALPHA
, CLR_R
, CLR_G
, CLR_B
,
832 else if (iBuf
->mdpImg
.imgType
== MDP_RGBA_8888
)
834 MDP_GET_PACK_PATTERN(CLR_ALPHA
, CLR_B
, CLR_G
, CLR_R
,
838 MDP_GET_PACK_PATTERN(CLR_ALPHA
, CLR_R
, CLR_G
, CLR_B
,
841 ppp_operation_reg
|= PPP_OP_COLOR_SPACE_RGB
|
842 PPP_OP_SRC_CHROMA_RGB
| PPP_OP_DST_CHROMA_RGB
;
845 case MDP_Y_CBCR_H2V2
:
846 case MDP_Y_CRCB_H2V2
:
848 src1
= (uint8
*) iBuf
->mdpImg
.cbcr_addr
;
855 ppp_src_cfg_reg
= PPP_SRC_C2R_8BITS
| PPP_SRC_C0G_8BITS
|
856 PPP_SRC_C1B_8BITS
| PPP_SRC_BPP_INTERLVD_2BYTES
|
857 PPP_SRC_INTERLVD_2COMPONENTS
| PPP_SRC_UNPACK_TIGHT
|
858 PPP_SRC_UNPACK_ALIGN_LSB
|
859 PPP_SRC_FETCH_PLANES_PSEUDOPLNR
;
861 if (iBuf
->mdpImg
.imgType
== MDP_Y_CRCB_H2V2
)
863 MDP_GET_PACK_PATTERN(0, 0, CLR_CR
, CLR_CB
, 8);
866 MDP_GET_PACK_PATTERN(0, 0, CLR_CB
, CLR_CR
, 8);
868 ppp_operation_reg
|= PPP_OP_COLOR_SPACE_YCBCR
|
869 PPP_OP_SRC_CHROMA_420
|
870 PPP_OP_SRC_CHROMA_COSITE
|
871 PPP_OP_DST_CHROMA_RGB
| PPP_OP_DST_CHROMA_COSITE
;
874 sh_slice
= sv_slice
= 2;
877 case MDP_YCRYCB_H2V1
:
879 ppp_src_cfg_reg
= PPP_SRC_C2R_8BITS
|
883 PPP_SRC_BPP_INTERLVD_2BYTES
|
884 PPP_SRC_INTERLVD_4COMPONENTS
|
885 PPP_SRC_UNPACK_TIGHT
| PPP_SRC_UNPACK_ALIGN_LSB
;
888 MDP_GET_PACK_PATTERN(CLR_Y
, CLR_CR
, CLR_Y
, CLR_CB
, 8);
890 ppp_operation_reg
|= PPP_OP_SRC_CHROMA_H2V1
|
891 PPP_OP_SRC_CHROMA_COSITE
| PPP_OP_DST_CHROMA_COSITE
;
894 * if it's TV-Out/MDP_YCRYCB_H2V1, let's go through the
895 * preloaded inverse gamma setting of 2.2 since they're
896 * symetric when the content is non-linear
897 * ppp_lookUp_enable = TRUE;
900 /* x and width must be even number */
901 iBuf
->roi
.lcd_x
= (iBuf
->roi
.lcd_x
/ 2) * 2;
902 iBuf
->roi
.dst_width
= (iBuf
->roi
.dst_width
/ 2) * 2;
903 iBuf
->roi
.x
= (iBuf
->roi
.x
/ 2) * 2;
904 iBuf
->roi
.width
= (iBuf
->roi
.width
/ 2) * 2;
910 case MDP_Y_CBCR_H2V1
:
911 case MDP_Y_CRCB_H2V1
:
913 src1
= (uint8
*) iBuf
->mdpImg
.cbcr_addr
;
915 ppp_src_cfg_reg
= PPP_SRC_C2R_8BITS
|
919 PPP_SRC_BPP_INTERLVD_2BYTES
|
920 PPP_SRC_INTERLVD_2COMPONENTS
|
921 PPP_SRC_UNPACK_TIGHT
|
922 PPP_SRC_UNPACK_ALIGN_LSB
| PPP_SRC_FETCH_PLANES_PSEUDOPLNR
;
924 if (iBuf
->mdpImg
.imgType
== MDP_Y_CBCR_H2V1
)
926 MDP_GET_PACK_PATTERN(0, 0, CLR_CB
, CLR_CR
, 8);
929 MDP_GET_PACK_PATTERN(0, 0, CLR_CR
, CLR_CB
, 8);
931 ppp_operation_reg
|= PPP_OP_SRC_CHROMA_H2V1
|
932 PPP_OP_SRC_CHROMA_COSITE
| PPP_OP_DST_CHROMA_COSITE
;
946 ppp_src_cfg_reg
= PPP_SRC_C2R_5BITS
| PPP_SRC_C0G_6BITS
|
947 PPP_SRC_C1B_5BITS
| PPP_SRC_BPP_INTERLVD_2BYTES
|
948 PPP_SRC_INTERLVD_3COMPONENTS
| PPP_SRC_UNPACK_TIGHT
|
949 PPP_SRC_UNPACK_ALIGN_LSB
|
950 PPP_SRC_FETCH_PLANES_INTERLVD
;
952 if (iBuf
->mdpImg
.imgType
== MDP_RGB_565
)
954 MDP_GET_PACK_PATTERN(0, CLR_R
, CLR_G
, CLR_B
, 8);
957 MDP_GET_PACK_PATTERN(0, CLR_B
, CLR_G
, CLR_R
, 8);
959 ppp_operation_reg
|= PPP_OP_COLOR_SPACE_RGB
|
960 PPP_OP_SRC_CHROMA_RGB
| PPP_OP_DST_CHROMA_RGB
;
965 if (pseudoplanr_output
)
966 ppp_dst_cfg_reg
|= PPP_DST_PLANE_PSEUDOPLN
;
968 /* YCbCr to RGB color conversion flag */
969 if ((!inputRGB
) && (outputRGB
)) {
970 ppp_operation_reg
|= PPP_OP_CONVERT_YCBCR2RGB
|
974 * primary/secondary is sort of misleading term...but
975 * in mdp2.2/3.0 we only use primary matrix (forward/rev)
976 * in mdp3.1 we use set1(prim) and set2(secd)
978 #ifdef CONFIG_FB_MSM_MDP31
979 ppp_operation_reg
|= PPP_OP_CONVERT_MATRIX_SECONDARY
|
981 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x0240, 0);
984 if (ppp_lookUp_enable
) {
985 ppp_operation_reg
|= PPP_OP_LUT_C0_ON
|
986 PPP_OP_LUT_C1_ON
| PPP_OP_LUT_C2_ON
;
989 /* RGB to YCbCr color conversion flag */
990 if ((inputRGB
) && (!outputRGB
)) {
991 ppp_operation_reg
|= PPP_OP_CONVERT_RGB2YCBCR
|
994 #ifdef CONFIG_FB_MSM_MDP31
995 ppp_operation_reg
|= PPP_OP_CONVERT_MATRIX_PRIMARY
|
997 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x0240, 0x1e);
1000 if (ppp_lookUp_enable
) {
1001 ppp_operation_reg
|= PPP_OP_LUT_C0_ON
|
1002 PPP_OP_LUT_C1_ON
| PPP_OP_LUT_C2_ON
;
1005 /* YCbCr to YCbCr color conversion flag */
1006 if ((!inputRGB
) && (!outputRGB
)) {
1007 if ((ppp_lookUp_enable
) &&
1008 (iBuf
->mdpImg
.imgType
!= iBuf
->ibuf_type
)) {
1009 ppp_operation_reg
|= PPP_OP_LUT_C0_ON
;
1013 ppp_src_cfg_reg
|= (iBuf
->roi
.x
% 2) ? PPP_SRC_BPP_ROI_ODD_X
: 0;
1014 ppp_src_cfg_reg
|= (iBuf
->roi
.y
% 2) ? PPP_SRC_BPP_ROI_ODD_Y
: 0;
1016 if (req
->flags
& MDP_DEINTERLACE
)
1017 ppp_operation_reg
|= PPP_OP_DEINT_EN
;
1019 /* Dither at DMA side only since iBuf format is RGB888 */
1020 if (iBuf
->mdpImg
.mdpOp
& MDPOP_DITHER
)
1021 ppp_operation_reg
|= PPP_OP_DITHER_EN
;
1023 if (iBuf
->mdpImg
.mdpOp
& MDPOP_ROTATION
) {
1024 ppp_operation_reg
|= PPP_OP_ROT_ON
;
1026 if (iBuf
->mdpImg
.mdpOp
& MDPOP_ROT90
) {
1027 ppp_operation_reg
|= PPP_OP_ROT_90
;
1029 if (iBuf
->mdpImg
.mdpOp
& MDPOP_LR
) {
1030 ppp_operation_reg
|= PPP_OP_FLIP_LR
;
1032 if (iBuf
->mdpImg
.mdpOp
& MDPOP_UD
) {
1033 ppp_operation_reg
|= PPP_OP_FLIP_UD
;
1037 src0_ystride
= src_width
* inpBpp
;
1038 dest0_ystride
= iBuf
->ibuf_width
* iBuf
->bpp
;
1040 /* no need to care about rotation since it's the real-XY. */
1041 dst_roi_width
= iBuf
->roi
.dst_width
;
1042 dst_roi_height
= iBuf
->roi
.dst_height
;
1044 src0
= (uint8
*) iBuf
->mdpImg
.bmy_addr
;
1045 dest0
= (uint8
*) iBuf
->buf
;
1047 /* Jumping from Y-Plane to Chroma Plane */
1048 dest1
= mdp_get_chroma_addr(iBuf
);
1050 /* first pixel addr calculation */
1051 mdp_adjust_start_addr(&src0
, &src1
, sv_slice
, sh_slice
, iBuf
->roi
.x
,
1052 iBuf
->roi
.y
, src_width
, src_height
, inpBpp
, iBuf
,
1054 mdp_adjust_start_addr(&dest0
, &dest1
, dv_slice
, dh_slice
,
1055 iBuf
->roi
.lcd_x
, iBuf
->roi
.lcd_y
,
1056 iBuf
->ibuf_width
, iBuf
->ibuf_height
, iBuf
->bpp
,
1059 /* set scale operation */
1060 mdp_set_scale(iBuf
, dst_roi_width
, dst_roi_height
,
1061 inputRGB
, outputRGB
, &ppp_operation_reg
);
1064 * setting background source for blending
1066 mdp_set_blend_attr(iBuf
, &alpha
, &tpVal
, perPixelAlpha
,
1067 &ppp_operation_reg
);
1069 if (ppp_operation_reg
& PPP_OP_BLEND_ON
) {
1070 mdp_ppp_setbg(iBuf
);
1072 if (iBuf
->ibuf_type
== MDP_YCRYCB_H2V1
) {
1073 ppp_operation_reg
|= PPP_OP_BG_CHROMA_H2V1
;
1075 if (iBuf
->mdpImg
.mdpOp
& MDPOP_TRANSP
) {
1076 tpVal
= mdp_conv_matx_rgb2yuv(tpVal
,
1085 * 0x0004: enable dbg bus
1086 * 0x0100: "don't care" Edge Condit until scaling is on
1087 * 0x0104: xrc tile x&y size u7.6 format = 7bit.6bit
1088 * 0x0108: src pixel size
1089 * 0x010c: component plane 0 starting address
1090 * 0x011c: component plane 0 ystride
1091 * 0x0124: PPP source config register
1092 * 0x0128: unpacked pattern from lsb to msb (eg. RGB->BGR)
1094 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x0108, (iBuf
->roi
.height
<< 16 |
1096 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x010c, src0
); /* comp.plane 0 */
1097 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x0110, src1
); /* comp.plane 1 */
1098 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x011c,
1099 (src0_ystride
<< 16 | src0_ystride
));
1101 /* setup for rgb 565 */
1102 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x0124, ppp_src_cfg_reg
);
1103 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x0128, packPattern
);
1105 * 0x0138: PPP destination operation register
1106 * 0x014c: constant_alpha|transparent_color
1107 * 0x0150: PPP destination config register
1108 * 0x0154: PPP packing pattern
1110 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x0138, ppp_operation_reg
);
1111 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x014c, alpha
<< 24 | tpVal
);
1112 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x0150, ppp_dst_cfg_reg
);
1113 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x0154, dst_packPattern
);
1116 * 0x0164: ROI height and width
1117 * 0x0168: Component Plane 0 starting addr
1118 * 0x016c: Component Plane 1 starting addr
1119 * 0x0178: Component Plane 1/0 y stride
1121 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x0164,
1122 (dst_roi_height
<< 16 | dst_roi_width
));
1123 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x0168, dest0
);
1124 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x016c, dest1
);
1125 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE
+ 0x0178,
1126 (dest0_ystride
<< 16 | dest0_ystride
));
1128 flush_imgs(req
, inpBpp
, iBuf
->bpp
, p_src_file
, p_dst_file
);
1129 #ifdef CONFIG_MDP_PPP_ASYNC_OP
1130 mdp_ppp_process_curr_djob();
1132 mdp_pipe_kickoff(MDP_PPP_TERM
, mfd
);
1136 static int mdp_ppp_verify_req(struct mdp_blit_req
*req
)
1138 u32 src_width
, src_height
, dst_width
, dst_height
;
1143 if (MDP_IS_IMGTYPE_BAD(req
->src
.format
) ||
1144 MDP_IS_IMGTYPE_BAD(req
->dst
.format
))
1147 if ((req
->src
.width
== 0) || (req
->src
.height
== 0) ||
1148 (req
->src_rect
.w
== 0) || (req
->src_rect
.h
== 0) ||
1149 (req
->dst
.width
== 0) || (req
->dst
.height
== 0) ||
1150 (req
->dst_rect
.w
== 0) || (req
->dst_rect
.h
== 0))
1154 if (((req
->src_rect
.x
+ req
->src_rect
.w
) > req
->src
.width
) ||
1155 ((req
->src_rect
.y
+ req
->src_rect
.h
) > req
->src
.height
))
1158 if (((req
->dst_rect
.x
+ req
->dst_rect
.w
) > req
->dst
.width
) ||
1159 ((req
->dst_rect
.y
+ req
->dst_rect
.h
) > req
->dst
.height
))
1163 * scaling range check
1165 src_width
= req
->src_rect
.w
;
1166 src_height
= req
->src_rect
.h
;
1168 if (req
->flags
& MDP_ROT_90
) {
1169 dst_width
= req
->dst_rect
.h
;
1170 dst_height
= req
->dst_rect
.w
;
1172 dst_width
= req
->dst_rect
.w
;
1173 dst_height
= req
->dst_rect
.h
;
1176 switch (req
->dst
.format
) {
1177 case MDP_Y_CRCB_H2V2
:
1178 case MDP_Y_CBCR_H2V2
:
1179 src_width
= (src_width
/ 2) * 2;
1180 src_height
= (src_height
/ 2) * 2;
1181 dst_width
= (src_width
/ 2) * 2;
1182 dst_height
= (src_height
/ 2) * 2;
1185 case MDP_Y_CRCB_H2V1
:
1186 case MDP_Y_CBCR_H2V1
:
1187 case MDP_YCRYCB_H2V1
:
1188 src_width
= (src_width
/ 2) * 2;
1189 dst_width
= (src_width
/ 2) * 2;
1196 if (((MDP_SCALE_Q_FACTOR
* dst_width
) / src_width
>
1197 MDP_MAX_X_SCALE_FACTOR
)
1198 || ((MDP_SCALE_Q_FACTOR
* dst_width
) / src_width
<
1199 MDP_MIN_X_SCALE_FACTOR
))
1202 if (((MDP_SCALE_Q_FACTOR
* dst_height
) / src_height
>
1203 MDP_MAX_Y_SCALE_FACTOR
)
1204 || ((MDP_SCALE_Q_FACTOR
* dst_height
) / src_height
<
1205 MDP_MIN_Y_SCALE_FACTOR
))
1212 * get_gem_img() - retrieve drm obj's start address and size
1213 * @img: contains drm file descriptor and gem handle
1214 * @start: repository of starting address of drm obj allocated memory
1215 * @len: repository of size of drm obj alloacted memory
1218 int get_gem_img(struct mdp_img
*img
, unsigned long *start
, unsigned long *len
)
1220 panic("waaaaaaaah");
1221 //return kgsl_gem_obj_addr(img->memory_id, (int)img->priv, start, len);
1224 int get_img(struct mdp_img
*img
, struct fb_info
*info
, unsigned long *start
,
1225 unsigned long *len
, struct file
**pp_file
)
1227 int put_needed
, ret
= 0;
1229 unsigned long vstart
;
1230 #ifdef CONFIG_ANDROID_PMEM
1231 if (!get_pmem_file(img
->memory_id
, start
, &vstart
, len
, pp_file
))
1234 file
= fget_light(img
->memory_id
, &put_needed
);
1238 if (MAJOR(file
->f_dentry
->d_inode
->i_rdev
) == FB_MAJOR
) {
1239 *start
= info
->fix
.smem_start
;
1240 *len
= info
->fix
.smem_len
;
1244 fput_light(file
, put_needed
);
1249 int mdp_ppp_blit(struct fb_info
*info
, struct mdp_blit_req
*req
,
1250 struct file
**pp_src_file
, struct file
**pp_dst_file
)
1252 unsigned long src_start
, dst_start
;
1253 unsigned long src_len
= 0;
1254 unsigned long dst_len
= 0;
1256 u32 dst_width
, dst_height
;
1257 struct file
*p_src_file
= 0 , *p_dst_file
= 0;
1258 struct msm_fb_data_type
*mfd
= (struct msm_fb_data_type
*)info
->par
;
1260 if (req
->dst
.format
== MDP_FB_FORMAT
)
1261 req
->dst
.format
= mfd
->fb_imgType
;
1262 if (req
->src
.format
== MDP_FB_FORMAT
)
1263 req
->src
.format
= mfd
->fb_imgType
;
1265 if (req
->flags
& MDP_BLIT_SRC_GEM
) {
1266 if (get_gem_img(&req
->src
, &src_start
, &src_len
) < 0)
1269 get_img(&req
->src
, info
, &src_start
, &src_len
, &p_src_file
);
1272 printk(KERN_ERR
"mdp_ppp: could not retrieve image from "
1277 if (req
->flags
& MDP_BLIT_DST_GEM
) {
1278 if (get_gem_img(&req
->dst
, &dst_start
, &dst_len
) < 0)
1281 get_img(&req
->dst
, info
, &dst_start
, &dst_len
, &p_dst_file
);
1284 printk(KERN_ERR
"mdp_ppp: could not retrieve image from "
1288 *pp_src_file
= p_src_file
;
1289 *pp_dst_file
= p_dst_file
;
1290 if (mdp_ppp_verify_req(req
)) {
1291 printk(KERN_ERR
"mdp_ppp: invalid image!\n");
1295 iBuf
.ibuf_width
= req
->dst
.width
;
1296 iBuf
.ibuf_height
= req
->dst
.height
;
1297 iBuf
.bpp
= bytes_per_pixel
[req
->dst
.format
];
1299 iBuf
.ibuf_type
= req
->dst
.format
;
1300 iBuf
.buf
= (uint8
*) dst_start
;
1301 iBuf
.buf
+= req
->dst
.offset
;
1303 iBuf
.roi
.lcd_x
= req
->dst_rect
.x
;
1304 iBuf
.roi
.lcd_y
= req
->dst_rect
.y
;
1305 iBuf
.roi
.dst_width
= req
->dst_rect
.w
;
1306 iBuf
.roi
.dst_height
= req
->dst_rect
.h
;
1308 iBuf
.roi
.x
= req
->src_rect
.x
;
1309 iBuf
.roi
.width
= req
->src_rect
.w
;
1310 iBuf
.roi
.y
= req
->src_rect
.y
;
1311 iBuf
.roi
.height
= req
->src_rect
.h
;
1313 iBuf
.mdpImg
.width
= req
->src
.width
;
1314 iBuf
.mdpImg
.imgType
= req
->src
.format
;
1316 iBuf
.mdpImg
.bmy_addr
= (uint32
*) (src_start
+ req
->src
.offset
);
1317 iBuf
.mdpImg
.cbcr_addr
=
1318 (uint32
*) ((uint32
) iBuf
.mdpImg
.bmy_addr
+
1319 req
->src
.width
* req
->src
.height
);
1321 iBuf
.mdpImg
.mdpOp
= MDPOP_NOP
;
1323 /* blending check */
1324 if (req
->transp_mask
!= MDP_TRANSP_NOP
) {
1325 iBuf
.mdpImg
.mdpOp
|= MDPOP_TRANSP
;
1326 iBuf
.mdpImg
.tpVal
= req
->transp_mask
;
1327 iBuf
.mdpImg
.tpVal
= mdp_calc_tpval(&iBuf
.mdpImg
);
1331 if (req
->alpha
< MDP_ALPHA_NOP
) {
1332 iBuf
.mdpImg
.mdpOp
|= MDPOP_ALPHAB
;
1333 iBuf
.mdpImg
.alpha
= req
->alpha
;
1336 /* rotation check */
1337 if (req
->flags
& MDP_FLIP_LR
)
1338 iBuf
.mdpImg
.mdpOp
|= MDPOP_LR
;
1339 if (req
->flags
& MDP_FLIP_UD
)
1340 iBuf
.mdpImg
.mdpOp
|= MDPOP_UD
;
1341 if (req
->flags
& MDP_ROT_90
)
1342 iBuf
.mdpImg
.mdpOp
|= MDPOP_ROT90
;
1343 if (req
->flags
& MDP_DITHER
)
1344 iBuf
.mdpImg
.mdpOp
|= MDPOP_DITHER
;
1346 if (req
->flags
& MDP_BLEND_FG_PREMULT
) {
1347 #ifdef CONFIG_FB_MSM_MDP31
1348 iBuf
.mdpImg
.mdpOp
|= MDPOP_FG_PM_ALPHA
;
1354 if (req
->flags
& MDP_DEINTERLACE
) {
1355 #ifdef CONFIG_FB_MSM_MDP31
1356 if ((req
->src
.format
!= MDP_Y_CBCR_H2V2
) &&
1357 (req
->src
.format
!= MDP_Y_CRCB_H2V2
))
1363 if (req
->flags
& MDP_ROT_90
) {
1364 dst_width
= req
->dst_rect
.h
;
1365 dst_height
= req
->dst_rect
.w
;
1367 dst_width
= req
->dst_rect
.w
;
1368 dst_height
= req
->dst_rect
.h
;
1371 if ((iBuf
.roi
.width
!= dst_width
) || (iBuf
.roi
.height
!= dst_height
))
1372 iBuf
.mdpImg
.mdpOp
|= MDPOP_ASCALE
;
1374 if (req
->flags
& MDP_BLUR
) {
1375 #ifdef CONFIG_FB_MSM_MDP31
1376 if (req
->flags
& MDP_SHARPENING
)
1378 "mdp: MDP_SHARPENING is set with MDP_BLUR!\n");
1379 req
->flags
|= MDP_SHARPENING
;
1380 req
->sharpening_strength
= -127;
1382 iBuf
.mdpImg
.mdpOp
|= MDPOP_ASCALE
| MDPOP_BLUR
;
1387 if (req
->flags
& MDP_SHARPENING
) {
1388 #ifdef CONFIG_FB_MSM_MDP31
1389 if ((req
->sharpening_strength
> 127) ||
1390 (req
->sharpening_strength
< -127)) {
1392 "%s: sharpening strength out of range\n",
1397 iBuf
.mdpImg
.mdpOp
|= MDPOP_ASCALE
| MDPOP_SHARPENING
;
1398 iBuf
.mdpImg
.sp_value
= req
->sharpening_strength
& 0xff;
1404 down(&mdp_ppp_mutex
);
1405 /* MDP cmd block enable */
1406 mdp_pipe_ctrl(MDP_CMD_BLOCK
, MDP_BLOCK_POWER_ON
, FALSE
);
1408 #ifdef CONFIG_FB_MSM_MDP31
1409 mdp_start_ppp(mfd
, &iBuf
, req
, p_src_file
, p_dst_file
);
1411 /* bg tile fetching HW workaround */
1412 if (((iBuf
.mdpImg
.mdpOp
& (MDPOP_TRANSP
| MDPOP_ALPHAB
)) ||
1413 (req
->src
.format
== MDP_ARGB_8888
) ||
1414 (req
->src
.format
== MDP_BGRA_8888
) ||
1415 (req
->src
.format
== MDP_RGBA_8888
)) &&
1416 (iBuf
.mdpImg
.mdpOp
& MDPOP_ROT90
) && (req
->dst_rect
.w
<= 16)) {
1417 int dst_h
, src_w
, i
;
1419 src_w
= req
->src_rect
.w
;
1420 dst_h
= iBuf
.roi
.dst_height
;
1422 for (i
= 0; i
< (req
->dst_rect
.h
/ 16); i
++) {
1423 /* this tile size */
1424 iBuf
.roi
.dst_height
= 16;
1426 (16 * req
->src_rect
.w
) / req
->dst_rect
.h
;
1428 /* if it's out of scale range... */
1429 if (((MDP_SCALE_Q_FACTOR
* iBuf
.roi
.dst_height
) /
1430 iBuf
.roi
.width
) > MDP_MAX_X_SCALE_FACTOR
)
1432 (MDP_SCALE_Q_FACTOR
* iBuf
.roi
.dst_height
) /
1433 MDP_MAX_X_SCALE_FACTOR
;
1434 else if (((MDP_SCALE_Q_FACTOR
* iBuf
.roi
.dst_height
) /
1435 iBuf
.roi
.width
) < MDP_MIN_X_SCALE_FACTOR
)
1437 (MDP_SCALE_Q_FACTOR
* iBuf
.roi
.dst_height
) /
1438 MDP_MIN_X_SCALE_FACTOR
;
1440 mdp_start_ppp(mfd
, &iBuf
, req
, p_src_file
, p_dst_file
);
1442 /* next tile location */
1443 iBuf
.roi
.lcd_y
+= 16;
1444 iBuf
.roi
.x
+= iBuf
.roi
.width
;
1446 /* this is for a remainder update */
1448 src_w
-= iBuf
.roi
.width
;
1451 if ((dst_h
< 0) || (src_w
< 0))
1453 ("msm_fb: mdp_blt_ex() unexpected result! line:%d\n",
1456 /* remainder update */
1457 if ((dst_h
> 0) && (src_w
> 0)) {
1460 iBuf
.roi
.dst_height
= dst_h
;
1461 iBuf
.roi
.width
= src_w
;
1463 if (((MDP_SCALE_Q_FACTOR
* iBuf
.roi
.dst_height
) /
1464 iBuf
.roi
.width
) > MDP_MAX_X_SCALE_FACTOR
) {
1466 (MDP_SCALE_Q_FACTOR
* iBuf
.roi
.dst_height
) /
1467 MDP_MAX_X_SCALE_FACTOR
+
1468 (MDP_SCALE_Q_FACTOR
* iBuf
.roi
.dst_height
) %
1469 MDP_MAX_X_SCALE_FACTOR
? 1 : 0;
1471 /* move x location as roi width gets bigger */
1472 iBuf
.roi
.x
-= tmp_v
- iBuf
.roi
.width
;
1473 iBuf
.roi
.width
= tmp_v
;
1475 if (((MDP_SCALE_Q_FACTOR
* iBuf
.roi
.dst_height
) /
1476 iBuf
.roi
.width
) < MDP_MIN_X_SCALE_FACTOR
) {
1478 (MDP_SCALE_Q_FACTOR
* iBuf
.roi
.dst_height
) /
1479 MDP_MIN_X_SCALE_FACTOR
+
1480 (MDP_SCALE_Q_FACTOR
* iBuf
.roi
.dst_height
) %
1481 MDP_MIN_X_SCALE_FACTOR
? 1 : 0;
1484 * we don't move x location for continuity of
1487 iBuf
.roi
.width
= tmp_v
;
1490 mdp_start_ppp(mfd
, &iBuf
, req
, p_src_file
, p_dst_file
);
1493 mdp_start_ppp(mfd
, &iBuf
, req
, p_src_file
, p_dst_file
);
1497 /* MDP cmd block disable */
1498 mdp_pipe_ctrl(MDP_CMD_BLOCK
, MDP_BLOCK_POWER_OFF
, FALSE
);