GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / msm / mdp_ppp.c
blobbc7c3d45eec49eaa60cae5e53b8ad869a9eecc86
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>
22 #include <linux/fb.h>
23 #include <msm_mdp.h>
24 #include <linux/file.h>
25 #include <linux/major.h>
27 #include "linux/proc_fs.h"
29 #include <mach/hardware.h>
30 #include <linux/io.h>
32 #include <asm/system.h>
33 #include <asm/mach-types.h>
34 #include <linux/semaphore.h>
36 #include "mdp.h"
37 #include "msm_fb.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[] = {
44 [MDP_RGB_565] = 2,
45 [MDP_RGB_888] = 3,
46 [MDP_XRGB_8888] = 4,
47 [MDP_ARGB_8888] = 4,
48 [MDP_RGBA_8888] = 4,
49 [MDP_BGRA_8888] = 4,
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,
55 [MDP_BGR_565] = 2
58 extern uint32 mdp_plv[];
59 extern struct semaphore mdp_ppp_mutex;
61 uint32_t mdp_get_bytes_per_pixel(uint32_t format)
63 uint32_t bpp = 0;
64 if (format < ARRAY_SIZE(bytes_per_pixel))
65 bpp = bytes_per_pixel[format];
67 BUG_ON(!bpp);
68 return bpp;
71 static uint32 mdp_conv_matx_rgb2yuv(uint32 input_pixel,
72 uint16 *matrix_and_bias_vector,
73 uint32 *clamp_vector,
74 uint32 *look_up_table)
76 uint8 input_C2, input_C0, input_C1;
77 uint32 output;
78 int32 comp_C2, comp_C1, comp_C0, temp;
79 int32 temp1, temp2, temp3;
80 int32 matrix[9];
81 int32 bias_vector[3];
82 int32 Y_low_limit, Y_high_limit, C_low_limit, C_high_limit;
83 int32 i;
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;
90 comp_C0 = input_C0;
91 comp_C1 = input_C1;
92 comp_C2 = input_C2;
94 for (i = 0; i < 9; i++)
95 matrix[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;
109 else
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;
118 * Color Conversion
119 * reorder input colors
121 temp = comp_C2;
122 comp_C2 = comp_C1;
123 comp_C1 = comp_C0;
124 comp_C0 = temp;
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 */
136 comp_C0 >>= 9;
137 comp_C1 >>= 9;
138 comp_C2 >>= 9;
140 /* post bias (+) */
141 comp_C0 += bias_vector[0];
142 comp_C1 += bias_vector[1];
143 comp_C2 += bias_vector[2];
145 /* limit pixel to 8-bit */
146 if (comp_C0 < 0)
147 comp_C0 = 0;
149 if (comp_C0 > 255)
150 comp_C0 = 255;
152 if (comp_C1 < 0)
153 comp_C1 = 0;
155 if (comp_C1 > 255)
156 comp_C1 = 255;
158 if (comp_C2 < 0)
159 comp_C2 = 0;
161 if (comp_C2 > 255)
162 comp_C2 = 255;
164 /* clamp */
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;
184 return output;
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;
192 uint32 output;
193 int32 comp_C2, comp_C1, comp_C0, temp;
194 int32 temp1, temp2, temp3;
195 int32 matrix[9];
196 int32 bias_vector[3];
197 int32 Y_low_limit, Y_high_limit, C_low_limit, C_high_limit;
198 int32 i;
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;
205 comp_C0 = input_C0;
206 comp_C1 = input_C1;
207 comp_C2 = input_C2;
209 for (i = 0; i < 9; i++)
210 matrix[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;
224 else
225 _is_lookup_table_enabled = 1;
227 /* clamp */
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;
247 * Color Conversion
248 * pre bias (-)
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 */
264 comp_C0 >>= 9;
265 comp_C1 >>= 9;
266 comp_C2 >>= 9;
268 /* reorder output colors */
269 temp = comp_C0;
270 comp_C0 = comp_C1;
271 comp_C1 = comp_C2;
272 comp_C2 = temp;
274 /* limit pixel to 8-bit */
275 if (comp_C0 < 0)
276 comp_C0 = 0;
278 if (comp_C0 > 255)
279 comp_C0 = 255;
281 if (comp_C1 < 0)
282 comp_C1 = 0;
284 if (comp_C1 > 255)
285 comp_C1 = 255;
287 if (comp_C2 < 0)
288 comp_C2 = 0;
290 if (comp_C2 > 255)
291 comp_C2 = 255;
293 /* Look-up table */
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;
301 return output;
304 static uint32 mdp_calc_tpval(MDPIMG *mdpImg)
306 uint32 tpVal;
307 uint8 plane_tp;
309 tpVal = 0;
310 if ((mdpImg->imgType == MDP_RGB_565)
311 || (mdpImg->imgType == MDP_BGR_565)) {
313 * transparent color conversion into 24 bpp
315 * C2R_8BIT
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;
321 /* C1B_8BIT */
322 plane_tp = (uint8) (mdpImg->tpVal & 0x1F);
323 tpVal |= ((plane_tp << 3) | ((plane_tp & 0x1C) >> 2)) << 8;
325 /* C0G_8BIT */
326 plane_tp = (uint8) ((mdpImg->tpVal & 0x7E0) >> 5);
327 tpVal |= ((plane_tp << 2) | ((plane_tp & 0x30) >> 4));
328 } else {
329 /* 24bit RGB to RBG conversion */
331 tpVal = (mdpImg->tpVal & 0xFF00) >> 8;
332 tpVal |= (mdpImg->tpVal & 0xFF) << 8;
333 tpVal |= (mdpImg->tpVal & 0xFF0000);
336 return tpVal;
339 static uint8 *mdp_get_chroma_addr(MDPIBUF *iBuf)
341 uint8 *dest1;
343 dest1 = NULL;
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;
351 break;
353 default:
354 break;
357 return dest1;
360 static void mdp_ppp_setbg(MDPIBUF *iBuf)
362 uint8 *bg0_addr;
363 uint8 *bg1_addr;
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) {
376 case MDP_BGR_565:
377 case MDP_RGB_565:
378 /* 888 = 3bytes
379 * RGB = 3Components
380 * RGB interleaved
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)
389 unpack_pattern =
390 MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
391 else
392 unpack_pattern =
393 MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8);
394 break;
396 case MDP_RGB_888:
398 * 888 = 3bytes
399 * RGB = 3Components
400 * RGB interleaved
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;
407 unpack_pattern =
408 MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
409 break;
411 case MDP_BGRA_8888:
412 case MDP_RGBA_8888:
413 case MDP_ARGB_8888:
414 case MDP_XRGB_8888:
416 * 8888 = 4bytes
417 * ARGB = 4Components
418 * ARGB interleaved
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)
427 unpack_pattern =
428 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
430 else if (iBuf->ibuf_type == MDP_RGBA_8888)
431 unpack_pattern =
432 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R,
434 else
435 unpack_pattern =
436 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
438 break;
440 case MDP_Y_CBCR_H2V2:
441 case MDP_Y_CRCB_H2V2:
442 ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
443 PPP_SRC_C0G_8BITS |
444 PPP_SRC_C1B_8BITS |
445 PPP_SRC_C3A_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)
452 unpack_pattern =
453 MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
454 else
455 unpack_pattern =
456 MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
457 v_slice = h_slice = 2;
458 break;
460 case MDP_YCRYCB_H2V1:
461 ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
462 PPP_SRC_C0G_8BITS |
463 PPP_SRC_C1B_8BITS |
464 PPP_SRC_C3A_8BITS |
465 PPP_SRC_BPP_INTERLVD_2BYTES |
466 PPP_SRC_INTERLVD_4COMPONENTS |
467 PPP_SRC_UNPACK_TIGHT | PPP_SRC_UNPACK_ALIGN_LSB;
469 unpack_pattern =
470 MDP_GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8);
471 h_slice = 2;
472 break;
474 case MDP_Y_CBCR_H2V1:
475 case MDP_Y_CRCB_H2V1:
476 ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
477 PPP_SRC_C0G_8BITS |
478 PPP_SRC_C1B_8BITS |
479 PPP_SRC_C3A_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)
486 unpack_pattern =
487 MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
488 else
489 unpack_pattern =
490 MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
491 h_slice = 2;
492 break;
494 default:
495 return;
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,
502 iBuf, 1);
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);
540 else
541 *len1 = 0;
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);
567 #endif
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)
573 uint8 *src0, *src1;
574 uint8 *dest0, *dest1;
575 uint16 inpBpp;
576 uint32 dest0_ystride;
577 uint32 src_width;
578 uint32 src_height;
579 uint32 src0_ystride;
580 uint32 dst_roi_width;
581 uint32 dst_roi_height;
582 uint32 ppp_src_cfg_reg, ppp_operation_reg, ppp_dst_cfg_reg;
583 uint32 alpha, tpVal;
584 uint32 packPattern;
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;
593 alpha = tpVal = 0;
594 src_width = iBuf->mdpImg.width;
595 src_height = iBuf->roi.y + iBuf->roi.height;
596 src1 = NULL;
597 dest1 = NULL;
599 inputRGB = outputRGB = TRUE;
600 pseudoplanr_output = FALSE;
601 ppp_operation_reg = 0;
602 ppp_dst_cfg_reg = 0;
603 ppp_src_cfg_reg = 0;
605 /* Wait for the pipe to clear */
606 do { } while (mdp_ppp_pipe_wait() <= 0);
609 * destination config
611 switch (iBuf->ibuf_type) {
612 case MDP_RGB_888:
613 dst_packPattern =
614 MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
615 ppp_dst_cfg_reg =
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;
620 break;
622 case MDP_XRGB_8888:
623 case MDP_ARGB_8888:
624 case MDP_RGBA_8888:
625 if (iBuf->ibuf_type == MDP_BGRA_8888)
626 dst_packPattern =
627 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
629 else if (iBuf->ibuf_type == MDP_RGBA_8888)
630 dst_packPattern =
631 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R,
633 else
634 dst_packPattern =
635 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
638 ppp_dst_cfg_reg = PPP_DST_C0G_8BIT |
639 PPP_DST_C1B_8BIT |
640 PPP_DST_C2R_8BIT |
641 PPP_DST_C3A_8BIT |
642 PPP_DST_C3ALPHA_EN |
643 PPP_DST_PACKET_CNT_INTERLVD_4ELEM |
644 PPP_DST_PACK_TIGHT |
645 PPP_DST_PACK_ALIGN_LSB |
646 PPP_DST_OUT_SEL_AXI |
647 PPP_DST_BPP_4BYTES | PPP_DST_PLANE_INTERLVD;
648 break;
650 case MDP_Y_CBCR_H2V2:
651 case MDP_Y_CRCB_H2V2:
652 if (iBuf->ibuf_type == MDP_Y_CBCR_H2V2)
653 dst_packPattern =
654 MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
655 else
656 dst_packPattern =
657 MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
659 ppp_dst_cfg_reg = PPP_DST_C2R_8BIT |
660 PPP_DST_C0G_8BIT |
661 PPP_DST_C1B_8BIT |
662 PPP_DST_C3A_8BIT |
663 PPP_DST_PACKET_CNT_INTERLVD_2ELEM |
664 PPP_DST_PACK_TIGHT |
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;
669 outputRGB = FALSE;
670 pseudoplanr_output = TRUE;
672 * vertically (y direction) and horizontally (x direction)
673 * sample reduction by 2
677 * H2V2(YUV420) Cosite
679 * Y Y Y Y
680 * CbCr CbCr
681 * Y Y Y Y
682 * Y Y Y Y
683 * CbCr CbCr
684 * Y Y Y Y
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;
698 break;
700 case MDP_YCRYCB_H2V1:
701 dst_packPattern =
702 MDP_GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8);
703 ppp_dst_cfg_reg =
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;
711 outputRGB = FALSE;
713 * horizontally (x direction) sample reduction by 2
715 * H2V1(YUV422) Cosite
717 * YCbCr Y YCbCr Y
718 * YCbCr Y YCbCr Y
719 * YCbCr Y YCbCr Y
720 * YCbCr Y YCbCr Y
722 dh_slice = 2;
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;
735 break;
737 case MDP_Y_CBCR_H2V1:
738 case MDP_Y_CRCB_H2V1:
739 if (iBuf->ibuf_type == MDP_Y_CBCR_H2V1)
740 dst_packPattern =
741 MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
742 else
743 dst_packPattern =
744 MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
746 ppp_dst_cfg_reg = PPP_DST_C2R_8BIT |
747 PPP_DST_C0G_8BIT |
748 PPP_DST_C1B_8BIT |
749 PPP_DST_C3A_8BIT |
750 PPP_DST_PACKET_CNT_INTERLVD_2ELEM |
751 PPP_DST_PACK_TIGHT |
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;
756 outputRGB = FALSE;
757 pseudoplanr_output = TRUE;
758 /* horizontally (x direction) sample reduction by 2 */
759 dh_slice = 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;
766 break;
768 case MDP_BGR_565:
769 case MDP_RGB_565:
770 default:
771 if (iBuf->ibuf_type == MDP_RGB_565)
772 dst_packPattern =
773 MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
774 else
775 dst_packPattern =
776 MDP_GET_PACK_PATTERN(0, CLR_B, CLR_G, CLR_R, 8);
778 ppp_dst_cfg_reg = PPP_DST_C0G_6BIT |
779 PPP_DST_C1B_5BIT |
780 PPP_DST_C2R_5BIT |
781 PPP_DST_PACKET_CNT_INTERLVD_3ELEM |
782 PPP_DST_PACK_TIGHT |
783 PPP_DST_PACK_ALIGN_LSB |
784 PPP_DST_OUT_SEL_AXI |
785 PPP_DST_BPP_2BYTES | PPP_DST_PLANE_INTERLVD;
786 break;
789 /* source config */
790 switch (iBuf->mdpImg.imgType) {
791 case MDP_RGB_888:
792 inpBpp = 3;
794 * 565 = 2bytes
795 * RGB = 3Components
796 * RGB interleaved
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;
808 break;
810 case MDP_BGRA_8888:
811 case MDP_RGBA_8888:
812 case MDP_ARGB_8888:
813 perPixelAlpha = TRUE;
814 case MDP_XRGB_8888:
815 inpBpp = 4;
817 * 8888 = 4bytes
818 * ARGB = 4Components
819 * ARGB interleaved
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)
829 packPattern =
830 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_R, CLR_G, CLR_B,
832 else if (iBuf->mdpImg.imgType == MDP_RGBA_8888)
833 packPattern =
834 MDP_GET_PACK_PATTERN(CLR_ALPHA, CLR_B, CLR_G, CLR_R,
836 else
837 packPattern =
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;
843 break;
845 case MDP_Y_CBCR_H2V2:
846 case MDP_Y_CRCB_H2V2:
847 inpBpp = 1;
848 src1 = (uint8 *) iBuf->mdpImg.cbcr_addr;
851 * CbCr = 2bytes
852 * CbCr = 2Components
853 * Y+CbCr
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)
862 packPattern =
863 MDP_GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8);
864 else
865 packPattern =
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;
873 inputRGB = FALSE;
874 sh_slice = sv_slice = 2;
875 break;
877 case MDP_YCRYCB_H2V1:
878 inpBpp = 2;
879 ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
880 PPP_SRC_C0G_8BITS |
881 PPP_SRC_C1B_8BITS |
882 PPP_SRC_C3A_8BITS |
883 PPP_SRC_BPP_INTERLVD_2BYTES |
884 PPP_SRC_INTERLVD_4COMPONENTS |
885 PPP_SRC_UNPACK_TIGHT | PPP_SRC_UNPACK_ALIGN_LSB;
887 packPattern =
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;
906 inputRGB = FALSE;
907 sh_slice = 2;
908 break;
910 case MDP_Y_CBCR_H2V1:
911 case MDP_Y_CRCB_H2V1:
912 inpBpp = 1;
913 src1 = (uint8 *) iBuf->mdpImg.cbcr_addr;
915 ppp_src_cfg_reg = PPP_SRC_C2R_8BITS |
916 PPP_SRC_C0G_8BITS |
917 PPP_SRC_C1B_8BITS |
918 PPP_SRC_C3A_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)
925 packPattern =
926 MDP_GET_PACK_PATTERN(0, 0, CLR_CB, CLR_CR, 8);
927 else
928 packPattern =
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;
933 inputRGB = FALSE;
934 sh_slice = 2;
935 break;
937 case MDP_BGR_565:
938 case MDP_RGB_565:
939 default:
940 inpBpp = 2;
942 * 565 = 2bytes
943 * RGB = 3Components
944 * RGB interleaved
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)
953 packPattern =
954 MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 8);
955 else
956 packPattern =
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;
961 break;
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 |
971 PPP_OP_CONVERT_ON;
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 |
980 PPP_OP_DST_RGB;
981 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0240, 0);
982 #endif
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 |
992 PPP_OP_CONVERT_ON;
994 #ifdef CONFIG_FB_MSM_MDP31
995 ppp_operation_reg |= PPP_OP_CONVERT_MATRIX_PRIMARY |
996 PPP_OP_DST_YCBCR;
997 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0240, 0x1e);
998 #endif
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,
1057 iBuf, 2);
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,
1077 (uint16 *) &
1078 mdp_ccs_rgb2yuv,
1079 &mdp_plv[0], NULL);
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 |
1095 iBuf->roi.width));
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();
1131 #else
1132 mdp_pipe_kickoff(MDP_PPP_TERM, mfd);
1133 #endif
1136 static int mdp_ppp_verify_req(struct mdp_blit_req *req)
1138 u32 src_width, src_height, dst_width, dst_height;
1140 if (req == NULL)
1141 return -1;
1143 if (MDP_IS_IMGTYPE_BAD(req->src.format) ||
1144 MDP_IS_IMGTYPE_BAD(req->dst.format))
1145 return -1;
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))
1152 return -1;
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))
1156 return -1;
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))
1160 return -1;
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;
1171 } else {
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;
1183 break;
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;
1190 break;
1192 default:
1193 break;
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))
1200 return -1;
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))
1206 return -1;
1208 return 0;
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;
1228 struct file *file;
1229 unsigned long vstart;
1230 #ifdef CONFIG_ANDROID_PMEM
1231 if (!get_pmem_file(img->memory_id, start, &vstart, len, pp_file))
1232 return 0;
1233 #endif
1234 file = fget_light(img->memory_id, &put_needed);
1235 if (file == NULL)
1236 return -1;
1238 if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
1239 *start = info->fix.smem_start;
1240 *len = info->fix.smem_len;
1241 *pp_file = file;
1242 } else {
1243 ret = -1;
1244 fput_light(file, put_needed);
1246 return ret;
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;
1255 MDPIBUF iBuf;
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)
1267 return -1;
1268 } else {
1269 get_img(&req->src, info, &src_start, &src_len, &p_src_file);
1271 if (src_len == 0) {
1272 printk(KERN_ERR "mdp_ppp: could not retrieve image from "
1273 "memory\n");
1274 return -1;
1277 if (req->flags & MDP_BLIT_DST_GEM) {
1278 if (get_gem_img(&req->dst, &dst_start, &dst_len) < 0)
1279 return -1;
1280 } else {
1281 get_img(&req->dst, info, &dst_start, &dst_len, &p_dst_file);
1283 if (dst_len == 0) {
1284 printk(KERN_ERR "mdp_ppp: could not retrieve image from "
1285 "memory\n");
1286 return -1;
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");
1292 return -1;
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);
1330 req->alpha &= 0xff;
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;
1349 #else
1350 return -EINVAL;
1351 #endif
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))
1358 #endif
1359 return -EINVAL;
1362 /* scale check */
1363 if (req->flags & MDP_ROT_90) {
1364 dst_width = req->dst_rect.h;
1365 dst_height = req->dst_rect.w;
1366 } else {
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)
1377 printk(KERN_WARNING
1378 "mdp: MDP_SHARPENING is set with MDP_BLUR!\n");
1379 req->flags |= MDP_SHARPENING;
1380 req->sharpening_strength = -127;
1381 #else
1382 iBuf.mdpImg.mdpOp |= MDPOP_ASCALE | MDPOP_BLUR;
1384 #endif
1387 if (req->flags & MDP_SHARPENING) {
1388 #ifdef CONFIG_FB_MSM_MDP31
1389 if ((req->sharpening_strength > 127) ||
1390 (req->sharpening_strength < -127)) {
1391 printk(KERN_ERR
1392 "%s: sharpening strength out of range\n",
1393 __func__);
1394 return -EINVAL;
1397 iBuf.mdpImg.mdpOp |= MDPOP_ASCALE | MDPOP_SHARPENING;
1398 iBuf.mdpImg.sp_value = req->sharpening_strength & 0xff;
1399 #else
1400 return -EINVAL;
1401 #endif
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);
1410 #else
1411 if (((iBuf.mdpImg.mdpOp & (MDPOP_TRANSP | MDPOP_ALPHAB)) ||
1412 (req->src.format == MDP_ARGB_8888) ||
1413 (req->src.format == MDP_BGRA_8888) ||
1414 (req->src.format == MDP_RGBA_8888)) &&
1415 (iBuf.mdpImg.mdpOp & MDPOP_ROT90) && (req->dst_rect.w <= 16)) {
1416 int dst_h, src_w, i;
1418 src_w = req->src_rect.w;
1419 dst_h = iBuf.roi.dst_height;
1421 for (i = 0; i < (req->dst_rect.h / 16); i++) {
1422 /* this tile size */
1423 iBuf.roi.dst_height = 16;
1424 iBuf.roi.width =
1425 (16 * req->src_rect.w) / req->dst_rect.h;
1427 /* if it's out of scale range... */
1428 if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
1429 iBuf.roi.width) > MDP_MAX_X_SCALE_FACTOR)
1430 iBuf.roi.width =
1431 (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
1432 MDP_MAX_X_SCALE_FACTOR;
1433 else if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
1434 iBuf.roi.width) < MDP_MIN_X_SCALE_FACTOR)
1435 iBuf.roi.width =
1436 (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
1437 MDP_MIN_X_SCALE_FACTOR;
1439 mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file);
1441 /* next tile location */
1442 iBuf.roi.lcd_y += 16;
1443 iBuf.roi.x += iBuf.roi.width;
1445 /* this is for a remainder update */
1446 dst_h -= 16;
1447 src_w -= iBuf.roi.width;
1450 if ((dst_h < 0) || (src_w < 0))
1451 printk
1452 ("msm_fb: mdp_blt_ex() unexpected result! line:%d\n",
1453 __LINE__);
1455 /* remainder update */
1456 if ((dst_h > 0) && (src_w > 0)) {
1457 u32 tmp_v;
1459 iBuf.roi.dst_height = dst_h;
1460 iBuf.roi.width = src_w;
1462 if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
1463 iBuf.roi.width) > MDP_MAX_X_SCALE_FACTOR) {
1464 tmp_v =
1465 (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
1466 MDP_MAX_X_SCALE_FACTOR +
1467 (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) %
1468 MDP_MAX_X_SCALE_FACTOR ? 1 : 0;
1470 /* move x location as roi width gets bigger */
1471 iBuf.roi.x -= tmp_v - iBuf.roi.width;
1472 iBuf.roi.width = tmp_v;
1473 } else
1474 if (((MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
1475 iBuf.roi.width) < MDP_MIN_X_SCALE_FACTOR) {
1476 tmp_v =
1477 (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) /
1478 MDP_MIN_X_SCALE_FACTOR +
1479 (MDP_SCALE_Q_FACTOR * iBuf.roi.dst_height) %
1480 MDP_MIN_X_SCALE_FACTOR ? 1 : 0;
1483 * we don't move x location for continuity of
1484 * source image
1486 iBuf.roi.width = tmp_v;
1489 mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file);
1491 } else {
1492 mdp_start_ppp(mfd, &iBuf, req, p_src_file, p_dst_file);
1494 #endif
1496 /* MDP cmd block disable */
1497 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1498 up(&mdp_ppp_mutex);
1500 return 0;