blob: 383a16d44dd22a4b2bc662fbcd420033fdc73ffc [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/sched.h>
17#include <linux/time.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/spinlock.h>
21#include <linux/hrtimer.h>
22#include <linux/clk.h>
23#include <mach/hardware.h>
24#include <linux/io.h>
25#include <linux/debugfs.h>
26#include <linux/fb.h>
27#include <linux/msm_mdp.h>
28#include <linux/file.h>
29#include <linux/android_pmem.h>
30#include <linux/major.h>
31#include <asm/system.h>
32#include <asm/mach-types.h>
33#include <linux/semaphore.h>
34#include <linux/uaccess.h>
35#include <linux/mutex.h>
36#include <linux/msm_kgsl.h>
37#include "mdp.h"
38#include "msm_fb.h"
39#include "mdp4.h"
40
41#define VERSION_KEY_MASK 0xFFFFFF00
42
43struct mdp4_overlay_ctrl {
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -070044 struct mdp4_overlay_pipe plist[OVERLAY_PIPE_MAX];
45 struct mdp4_overlay_pipe *stage[MDP4_MIXER_MAX][MDP4_MIXER_STAGE_MAX];
kuogee hsieh4b910f22011-11-15 09:43:04 -080046 uint32 cs_controller;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070047 uint32 panel_3d;
48 uint32 panel_mode;
49 uint32 mixer0_played;
50 uint32 mixer1_played;
51} mdp4_overlay_db = {
kuogee hsieh4b910f22011-11-15 09:43:04 -080052 .cs_controller = CS_CONTROLLER_0,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070053 .plist = {
54 {
55 .pipe_type = OVERLAY_TYPE_RGB,
56 .pipe_num = OVERLAY_PIPE_RGB1,
57 .pipe_ndx = 1,
58 },
59 {
60 .pipe_type = OVERLAY_TYPE_RGB,
61 .pipe_num = OVERLAY_PIPE_RGB2,
62 .pipe_ndx = 2,
63 },
64 {
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -070065 .pipe_type = OVERLAY_TYPE_VIDEO,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070066 .pipe_num = OVERLAY_PIPE_VG1,
67 .pipe_ndx = 3,
68 },
69 {
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -070070 .pipe_type = OVERLAY_TYPE_VIDEO,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070071 .pipe_num = OVERLAY_PIPE_VG2,
72 .pipe_ndx = 4,
73 },
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070074 },
75};
76
77static struct mdp4_overlay_ctrl *ctrl = &mdp4_overlay_db;
kuogee hsieh9452ecb2011-08-01 18:26:23 -070078static int new_perf_level;
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -070079
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070080/* static array with index 0 for unset status and 1 for set status */
81static bool overlay_status[MDP4_OVERLAY_TYPE_MAX];
82
83void mdp4_overlay_status_write(enum mdp4_overlay_status type, bool val)
84{
85 overlay_status[type] = val;
86}
87
88bool mdp4_overlay_status_read(enum mdp4_overlay_status type)
89{
90 return overlay_status[type];
91}
92
93int mdp4_overlay_mixer_play(int mixer_num)
94{
95 if (mixer_num == MDP4_MIXER1)
96 return ctrl->mixer1_played;
97 else
98 return ctrl->mixer0_played;
99}
100
101void mdp4_overlay_panel_3d(int mixer_num, uint32 panel_3d)
102{
103 ctrl->panel_3d = panel_3d;
104}
105
106void mdp4_overlay_panel_mode(int mixer_num, uint32 mode)
107{
108 ctrl->panel_mode |= mode;
109}
110
111uint32 mdp4_overlay_panel_list(void)
112{
113 return ctrl->panel_mode;
114}
115
116void mdp4_overlay_dmae_cfg(struct msm_fb_data_type *mfd, int atv)
117{
118 uint32 dmae_cfg_reg;
119
120 if (atv)
121 dmae_cfg_reg = DMA_DEFLKR_EN;
122 else
123 dmae_cfg_reg = 0;
124
125 if (mfd->fb_imgType == MDP_BGR_565)
126 dmae_cfg_reg |= DMA_PACK_PATTERN_BGR;
127 else
128 dmae_cfg_reg |= DMA_PACK_PATTERN_RGB;
129
130
131 if (mfd->panel_info.bpp == 18) {
132 dmae_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */
133 DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
134 } else if (mfd->panel_info.bpp == 16) {
135 dmae_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */
136 DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
137 } else {
138 dmae_cfg_reg |= DMA_DSTC0G_8BITS | /* 888 16BPP */
139 DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
140 }
141
142 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
143
144 /* dma2 config register */
145 MDP_OUTP(MDP_BASE + 0xb0000, dmae_cfg_reg);
146 if (atv) {
147 MDP_OUTP(MDP_BASE + 0xb0070, 0xeb0010);
148 MDP_OUTP(MDP_BASE + 0xb0074, 0xf00010);
149 MDP_OUTP(MDP_BASE + 0xb0078, 0xf00010);
150 MDP_OUTP(MDP_BASE + 0xb3000, 0x80);
151 MDP_OUTP(MDP_BASE + 0xb3010, 0x1800040);
152 MDP_OUTP(MDP_BASE + 0xb3014, 0x1000080);
153 MDP_OUTP(MDP_BASE + 0xb4004, 0x67686970);
154 } else {
155 MDP_OUTP(MDP_BASE + 0xb0070, 0xff0000);
156 MDP_OUTP(MDP_BASE + 0xb0074, 0xff0000);
157 MDP_OUTP(MDP_BASE + 0xb0078, 0xff0000);
158 }
159
160 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
161}
162
Manoj Raob91fa712011-06-29 09:07:55 -0700163#ifdef CONFIG_FB_MSM_HDMI_3D
164void unfill_black_screen(void) { return; }
165#else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700166void unfill_black_screen(void)
167{
168 uint32 temp_src_format;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700169 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
170 /*
171 * VG2 Constant Color
172 */
173 temp_src_format = inpdw(MDP_BASE + 0x30050);
174 MDP_OUTP(MDP_BASE + 0x30050, temp_src_format&(~BIT(22)));
175 /*
176 * MDP_OVERLAY_REG_FLUSH
177 */
178 MDP_OUTP(MDP_BASE + 0x18000, BIT(3));
179 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
Manoj Raob91fa712011-06-29 09:07:55 -0700180 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700181}
Manoj Raob91fa712011-06-29 09:07:55 -0700182#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700183
Manoj Raob91fa712011-06-29 09:07:55 -0700184#ifdef CONFIG_FB_MSM_HDMI_3D
185void fill_black_screen(void) { return; }
186#else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700187void fill_black_screen(void)
188{
189 /*Black color*/
190 uint32 color = 0x00000000;
191 uint32 temp_src_format;
192 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
193 /*
194 * VG2 Constant Color
195 */
196 MDP_OUTP(MDP_BASE + 0x31008, color);
197 /*
198 * MDP_VG2_SRC_FORMAT
199 */
200 temp_src_format = inpdw(MDP_BASE + 0x30050);
201 MDP_OUTP(MDP_BASE + 0x30050, temp_src_format | BIT(22));
202 /*
203 * MDP_OVERLAY_REG_FLUSH
204 */
205 MDP_OUTP(MDP_BASE + 0x18000, BIT(3));
206 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
Manoj Raob91fa712011-06-29 09:07:55 -0700207 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700208}
Manoj Raob91fa712011-06-29 09:07:55 -0700209#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700210
211void mdp4_overlay_dmae_xy(struct mdp4_overlay_pipe *pipe)
212{
213
214 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
215
216 /* dma_p source */
217 MDP_OUTP(MDP_BASE + 0xb0004,
218 (pipe->src_height << 16 | pipe->src_width));
219 MDP_OUTP(MDP_BASE + 0xb0008, pipe->srcp0_addr);
220 MDP_OUTP(MDP_BASE + 0xb000c, pipe->srcp0_ystride);
221
222 /* dma_p dest */
223 MDP_OUTP(MDP_BASE + 0xb0010, (pipe->dst_y << 16 | pipe->dst_x));
224
225 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
226}
227
228void mdp4_overlay_dmap_cfg(struct msm_fb_data_type *mfd, int lcdc)
229{
230 uint32 dma2_cfg_reg;
231
232 dma2_cfg_reg = DMA_DITHER_EN;
233#ifdef BLT_RGB565
234 /* RGB888 is 0 */
235 dma2_cfg_reg |= DMA_BUF_FORMAT_RGB565; /* blt only */
236#endif
237
238 if (mfd->fb_imgType == MDP_BGR_565)
239 dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
240 else
241 dma2_cfg_reg |= DMA_PACK_PATTERN_RGB;
242
243
244 if (mfd->panel_info.bpp == 18) {
245 dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */
246 DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
247 } else if (mfd->panel_info.bpp == 16) {
248 dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */
249 DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
250 } else {
251 dma2_cfg_reg |= DMA_DSTC0G_8BITS | /* 888 16BPP */
252 DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
253 }
254
255 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
256
257#ifndef CONFIG_FB_MSM_LCDC_CHIMEI_WXGA_PANEL
258 if (lcdc)
259 dma2_cfg_reg |= DMA_PACK_ALIGN_MSB;
260#endif
261
262 /* dma2 config register */
263 MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg);
264
265 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
266}
267
268/*
269 * mdp4_overlay_dmap_xy: called form baselayer only
270 */
271void mdp4_overlay_dmap_xy(struct mdp4_overlay_pipe *pipe)
272{
273 uint32 off, bpp;
274
275 if (mdp_is_in_isr == FALSE)
276 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
277
278 /* dma_p source */
279 MDP_OUTP(MDP_BASE + 0x90004,
280 (pipe->src_height << 16 | pipe->src_width));
281 if (pipe->blt_addr) {
282#ifdef BLT_RGB565
283 bpp = 2; /* overlay ouput is RGB565 */
284#else
285 bpp = 3; /* overlay ouput is RGB888 */
286#endif
287 off = 0;
288 if (pipe->dmap_cnt & 0x01)
289 off = pipe->src_height * pipe->src_width * bpp;
290 MDP_OUTP(MDP_BASE + 0x90008, pipe->blt_addr + off);
291 /* RGB888, output of overlay blending */
292 MDP_OUTP(MDP_BASE + 0x9000c, pipe->src_width * bpp);
293 } else {
294 MDP_OUTP(MDP_BASE + 0x90008, pipe->srcp0_addr);
295 MDP_OUTP(MDP_BASE + 0x9000c, pipe->srcp0_ystride);
296 }
297
298 /* dma_p dest */
299 MDP_OUTP(MDP_BASE + 0x90010, (pipe->dst_y << 16 | pipe->dst_x));
300
301 if (mdp_is_in_isr == FALSE)
302 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
303}
304
305#define MDP4_VG_PHASE_STEP_DEFAULT 0x20000000
306#define MDP4_VG_PHASE_STEP_SHIFT 29
307
308static int mdp4_leading_0(uint32 num)
309{
310 uint32 bit = 0x80000000;
311 int i;
312
313 for (i = 0; i < 32; i++) {
314 if (bit & num)
315 return i;
316 bit >>= 1;
317 }
318
319 return i;
320}
321
322static uint32 mdp4_scale_phase_step(int f_num, uint32 src, uint32 dst)
323{
324 uint32 val;
325 int n;
326
327 n = mdp4_leading_0(src);
328 if (n > f_num)
329 n = f_num;
330 val = src << n; /* maximum to reduce lose of resolution */
331 val /= dst;
332 if (n < f_num) {
333 n = f_num - n;
334 val <<= n;
335 }
336
337 return val;
338}
339
340static void mdp4_scale_setup(struct mdp4_overlay_pipe *pipe)
341{
342 int ptype;
343
344 pipe->phasex_step = MDP4_VG_PHASE_STEP_DEFAULT;
345 pipe->phasey_step = MDP4_VG_PHASE_STEP_DEFAULT;
346 ptype = mdp4_overlay_format2type(pipe->src_format);
347
348 if (pipe->dst_h && pipe->src_h != pipe->dst_h) {
349 if (pipe->dst_h > pipe->src_h * 8) /* too much */
350 return;
351 pipe->op_mode |= MDP4_OP_SCALEY_EN;
352
353 if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {
354 if (pipe->dst_h <= (pipe->src_h / 4))
355 pipe->op_mode |= MDP4_OP_SCALEY_MN_PHASE;
356 else
357 pipe->op_mode |= MDP4_OP_SCALEY_FIR;
358 }
359
360 pipe->phasey_step = mdp4_scale_phase_step(29,
361 pipe->src_h, pipe->dst_h);
362 }
363
364 if (pipe->dst_w && pipe->src_w != pipe->dst_w) {
365 if (pipe->dst_w > pipe->src_w * 8) /* too much */
366 return;
367 pipe->op_mode |= MDP4_OP_SCALEX_EN;
368
369 if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {
370 if (pipe->dst_w <= (pipe->src_w / 4))
371 pipe->op_mode |= MDP4_OP_SCALEX_MN_PHASE;
372 else
373 pipe->op_mode |= MDP4_OP_SCALEX_FIR;
374 }
375
376 pipe->phasex_step = mdp4_scale_phase_step(29,
377 pipe->src_w, pipe->dst_w);
378 }
379}
380
381void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe)
382{
383 char *rgb_base;
384 uint32 src_size, src_xy, dst_size, dst_xy;
385 uint32 format, pattern;
386
387 rgb_base = MDP_BASE + MDP4_RGB_BASE;
388 rgb_base += (MDP4_RGB_OFF * pipe->pipe_num);
389
390 src_size = ((pipe->src_h << 16) | pipe->src_w);
391 src_xy = ((pipe->src_y << 16) | pipe->src_x);
392 dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
393 dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
394
395 format = mdp4_overlay_format(pipe);
396 pattern = mdp4_overlay_unpack_pattern(pipe);
397
398#ifdef MDP4_IGC_LUT_ENABLE
399 pipe->op_mode |= MDP4_OP_IGC_LUT_EN;
400#endif
401
402 mdp4_scale_setup(pipe);
403
404 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
405
406 outpdw(rgb_base + 0x0000, src_size); /* MDP_RGB_SRC_SIZE */
407 outpdw(rgb_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */
408 outpdw(rgb_base + 0x0008, dst_size); /* MDP_RGB_DST_SIZE */
409 outpdw(rgb_base + 0x000c, dst_xy); /* MDP_RGB_DST_XY */
410
411 outpdw(rgb_base + 0x0010, pipe->srcp0_addr);
412 outpdw(rgb_base + 0x0040, pipe->srcp0_ystride);
413
414 outpdw(rgb_base + 0x0050, format);/* MDP_RGB_SRC_FORMAT */
415 outpdw(rgb_base + 0x0054, pattern);/* MDP_RGB_SRC_UNPACK_PATTERN */
416 outpdw(rgb_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */
417 outpdw(rgb_base + 0x005c, pipe->phasex_step);
418 outpdw(rgb_base + 0x0060, pipe->phasey_step);
419
420 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
421
422 mdp4_stat.pipe[pipe->pipe_num]++;
423}
424
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700425
426static void mdp4_overlay_vg_get_src_offset(struct mdp4_overlay_pipe *pipe,
427 char *vg_base, uint32 *luma_off, uint32 *chroma_off)
428{
429 uint32 src_xy;
430 *luma_off = 0;
431 *chroma_off = 0;
432
Nagamalleswararao Ganji1c8fc4a2011-10-10 20:51:31 -0700433 if (pipe->src_x && (pipe->frame_format ==
434 MDP4_FRAME_FORMAT_LINEAR)) {
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700435 src_xy = (pipe->src_y << 16) | pipe->src_x;
436 src_xy &= 0xffff0000;
437 outpdw(vg_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */
438
439 switch (pipe->src_format) {
440 case MDP_Y_CR_CB_H2V2:
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +0530441 case MDP_Y_CR_CB_GH2V2:
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700442 case MDP_Y_CB_CR_H2V2:
443 *luma_off = pipe->src_x;
444 *chroma_off = pipe->src_x/2;
445 break;
446
447 case MDP_Y_CBCR_H2V2_TILE:
448 case MDP_Y_CRCB_H2V2_TILE:
449 case MDP_Y_CBCR_H2V2:
450 case MDP_Y_CRCB_H2V2:
451 case MDP_Y_CRCB_H1V1:
452 case MDP_Y_CBCR_H1V1:
453 case MDP_Y_CRCB_H2V1:
454 case MDP_Y_CBCR_H2V1:
455 *luma_off = pipe->src_x;
456 *chroma_off = pipe->src_x;
457 break;
458
459 case MDP_YCRYCB_H2V1:
460 if (pipe->src_x & 0x1)
461 pipe->src_x += 1;
462 *luma_off += pipe->src_x * 2;
463 break;
464
465 case MDP_ARGB_8888:
466 case MDP_RGBA_8888:
467 case MDP_BGRA_8888:
468 case MDP_RGBX_8888:
469 case MDP_RGB_565:
470 case MDP_BGR_565:
471 case MDP_XRGB_8888:
472 case MDP_RGB_888:
473 *luma_off = pipe->src_x * pipe->bpp;
474 break;
475
476 default:
477 pr_err("Source format %u not supported for x offset adjustment\n",
478 pipe->src_format);
479 break;
480 }
481 }
482}
483
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700484void mdp4_overlay_vg_setup(struct mdp4_overlay_pipe *pipe)
485{
486 char *vg_base;
487 uint32 frame_size, src_size, src_xy, dst_size, dst_xy;
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700488 uint32 format, pattern, luma_offset, chroma_offset;
kuogee hsieh4b910f22011-11-15 09:43:04 -0800489 uint32 mask;
kuogee hsiehe1ed1ae2011-09-02 08:53:36 -0700490 int pnum, ptype;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700491
492 pnum = pipe->pipe_num - OVERLAY_PIPE_VG1; /* start from 0 */
493 vg_base = MDP_BASE + MDP4_VIDEO_BASE;
494 vg_base += (MDP4_VIDEO_OFF * pnum);
495
496 frame_size = ((pipe->src_height << 16) | pipe->src_width);
497 src_size = ((pipe->src_h << 16) | pipe->src_w);
498 src_xy = ((pipe->src_y << 16) | pipe->src_x);
499 dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
500 dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
501
kuogee hsiehe1ed1ae2011-09-02 08:53:36 -0700502 ptype = mdp4_overlay_format2type(pipe->src_format);
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +0530503 if (pipe->src_format == MDP_Y_CR_CB_GH2V2) {
504 frame_size = ((pipe->src_height << 16) |
505 ALIGN(pipe->src_width, 16));
506 src_size = ((pipe->src_h << 16) | ALIGN(pipe->src_w, 16));
507 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700508 format = mdp4_overlay_format(pipe);
509 pattern = mdp4_overlay_unpack_pattern(pipe);
510
511 /* not RGB use VG pipe, pure VG pipe */
kuogee hsiehe1ed1ae2011-09-02 08:53:36 -0700512 if (ptype != OVERLAY_TYPE_RGB)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700513 pipe->op_mode |= (MDP4_OP_CSC_EN | MDP4_OP_SRC_DATA_YCBCR);
kuogee hsiehe1ed1ae2011-09-02 08:53:36 -0700514
515#ifdef MDP4_IGC_LUT_ENABLE
516 pipe->op_mode |= MDP4_OP_IGC_LUT_EN;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700517#endif
518
519 mdp4_scale_setup(pipe);
520
521 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
522
523 outpdw(vg_base + 0x0000, src_size); /* MDP_RGB_SRC_SIZE */
524 outpdw(vg_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */
525 outpdw(vg_base + 0x0008, dst_size); /* MDP_RGB_DST_SIZE */
526 outpdw(vg_base + 0x000c, dst_xy); /* MDP_RGB_DST_XY */
Nagamalleswararao Ganjic6ecb832011-09-14 10:00:18 -0700527
Nagamalleswararao Ganji1c8fc4a2011-10-10 20:51:31 -0700528 if (pipe->frame_format != MDP4_FRAME_FORMAT_LINEAR)
Nagamalleswararao Ganjic6ecb832011-09-14 10:00:18 -0700529 outpdw(vg_base + 0x0048, frame_size); /* TILE frame size */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700530
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700531 /*
532 * Adjust src X offset to avoid MDP from overfetching pixels
533 * present before the offset. This is required for video
534 * frames coming with unused green pixels along the left margin
535 */
kuogee hsiehe1ed1ae2011-09-02 08:53:36 -0700536 /* not RGB use VG pipe, pure VG pipe */
537 if (ptype != OVERLAY_TYPE_RGB) {
538 mdp4_overlay_vg_get_src_offset(pipe, vg_base, &luma_offset,
539 &chroma_offset);
540 } else {
541 luma_offset = 0;
542 chroma_offset = 0;
543 }
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700544
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700545 /* luma component plane */
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700546 outpdw(vg_base + 0x0010, pipe->srcp0_addr + luma_offset);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700547
548 /* chroma component plane or planar color 1 */
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700549 outpdw(vg_base + 0x0014, pipe->srcp1_addr + chroma_offset);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700550
551 /* planar color 2 */
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700552 outpdw(vg_base + 0x0018, pipe->srcp2_addr + chroma_offset);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700553
554 outpdw(vg_base + 0x0040,
555 pipe->srcp1_ystride << 16 | pipe->srcp0_ystride);
556
557 outpdw(vg_base + 0x0044,
558 pipe->srcp3_ystride << 16 | pipe->srcp2_ystride);
559
560 outpdw(vg_base + 0x0050, format); /* MDP_RGB_SRC_FORMAT */
561 outpdw(vg_base + 0x0054, pattern); /* MDP_RGB_SRC_UNPACK_PATTERN */
562 outpdw(vg_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */
563 outpdw(vg_base + 0x005c, pipe->phasex_step);
564 outpdw(vg_base + 0x0060, pipe->phasey_step);
565
566 if (pipe->op_mode & MDP4_OP_DITHER_EN) {
567 outpdw(vg_base + 0x0068,
568 pipe->r_bit << 4 | pipe->b_bit << 2 | pipe->g_bit);
569 }
570
571 if (pipe->flags & MDP_SHARPENING) {
572 outpdw(vg_base + 0x8200,
573 mdp4_ss_table_value(pipe->req_data.dpp.sharp_strength,
574 0));
575 outpdw(vg_base + 0x8204,
576 mdp4_ss_table_value(pipe->req_data.dpp.sharp_strength,
577 1));
578 }
579
kuogee hsieh4b910f22011-11-15 09:43:04 -0800580 if (mdp_rev > MDP_REV_41) {
581 /* mdp chip select controller */
582 mask = 0;
583 if (pipe->pipe_num == OVERLAY_PIPE_VG1)
584 mask = 0x020; /* bit 5 */
585 else if (pipe->pipe_num == OVERLAY_PIPE_VG2)
586 mask = 0x02000; /* bit 13 */
587 if (mask) {
588 if (pipe->op_mode & MDP4_OP_SCALEY_MN_PHASE)
589 ctrl->cs_controller &= ~mask;
590 else
591 ctrl->cs_controller |= mask;
592 /* NOT double buffered */
593 outpdw(MDP_BASE + 0x00c0, ctrl->cs_controller);
594 }
595 }
596
597
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700598 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
599
600 mdp4_stat.pipe[pipe->pipe_num]++;
601}
602
603int mdp4_overlay_format2type(uint32 format)
604{
605 switch (format) {
606 case MDP_RGB_565:
607 case MDP_RGB_888:
608 case MDP_BGR_565:
609 case MDP_XRGB_8888:
610 case MDP_ARGB_8888:
611 case MDP_RGBA_8888:
612 case MDP_BGRA_8888:
613 case MDP_RGBX_8888:
614 return OVERLAY_TYPE_RGB;
615 case MDP_YCRYCB_H2V1:
616 case MDP_Y_CRCB_H2V1:
617 case MDP_Y_CBCR_H2V1:
618 case MDP_Y_CRCB_H2V2:
619 case MDP_Y_CBCR_H2V2:
620 case MDP_Y_CBCR_H2V2_TILE:
621 case MDP_Y_CRCB_H2V2_TILE:
622 case MDP_Y_CR_CB_H2V2:
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +0530623 case MDP_Y_CR_CB_GH2V2:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700624 case MDP_Y_CB_CR_H2V2:
625 case MDP_Y_CRCB_H1V1:
626 case MDP_Y_CBCR_H1V1:
627 return OVERLAY_TYPE_VIDEO;
628 default:
629 mdp4_stat.err_format++;
630 return -ERANGE;
631 }
632
633}
634
635#define C3_ALPHA 3 /* alpha */
636#define C2_R_Cr 2 /* R/Cr */
637#define C1_B_Cb 1 /* B/Cb */
638#define C0_G_Y 0 /* G/luma */
639#define YUV_444_MAX_WIDTH 1280 /* Max width for YUV 444*/
640
641int mdp4_overlay_format2pipe(struct mdp4_overlay_pipe *pipe)
642{
643 switch (pipe->src_format) {
644 case MDP_RGB_565:
645 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
646 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
647 pipe->a_bit = 0;
648 pipe->r_bit = 1; /* R, 5 bits */
649 pipe->b_bit = 1; /* B, 5 bits */
650 pipe->g_bit = 2; /* G, 6 bits */
651 pipe->alpha_enable = 0;
652 pipe->unpack_tight = 1;
653 pipe->unpack_align_msb = 0;
654 pipe->unpack_count = 2;
655 pipe->element2 = C2_R_Cr; /* R */
656 pipe->element1 = C0_G_Y; /* G */
657 pipe->element0 = C1_B_Cb; /* B */
658 pipe->bpp = 2; /* 2 bpp */
659 break;
660 case MDP_RGB_888:
661 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
662 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
663 pipe->a_bit = 0;
664 pipe->r_bit = 3; /* R, 8 bits */
665 pipe->b_bit = 3; /* B, 8 bits */
666 pipe->g_bit = 3; /* G, 8 bits */
667 pipe->alpha_enable = 0;
668 pipe->unpack_tight = 1;
669 pipe->unpack_align_msb = 0;
670 pipe->unpack_count = 2;
671 pipe->element2 = C2_R_Cr; /* R */
672 pipe->element1 = C0_G_Y; /* G */
673 pipe->element0 = C1_B_Cb; /* B */
674 pipe->bpp = 3; /* 3 bpp */
675 break;
676 case MDP_BGR_565:
677 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
678 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
679 pipe->a_bit = 0;
680 pipe->r_bit = 1; /* R, 5 bits */
681 pipe->b_bit = 1; /* B, 5 bits */
682 pipe->g_bit = 2; /* G, 6 bits */
683 pipe->alpha_enable = 0;
684 pipe->unpack_tight = 1;
685 pipe->unpack_align_msb = 0;
686 pipe->unpack_count = 2;
687 pipe->element2 = C1_B_Cb; /* B */
688 pipe->element1 = C0_G_Y; /* G */
689 pipe->element0 = C2_R_Cr; /* R */
690 pipe->bpp = 2; /* 2 bpp */
691 break;
692 case MDP_XRGB_8888:
693 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
694 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
695 pipe->a_bit = 3; /* alpha, 4 bits */
696 pipe->r_bit = 3; /* R, 8 bits */
697 pipe->b_bit = 3; /* B, 8 bits */
698 pipe->g_bit = 3; /* G, 8 bits */
699 pipe->alpha_enable = 0;
700 pipe->unpack_tight = 1;
701 pipe->unpack_align_msb = 0;
702 pipe->unpack_count = 3;
703 pipe->element3 = C3_ALPHA; /* alpha */
704 pipe->element2 = C2_R_Cr; /* R */
705 pipe->element1 = C0_G_Y; /* G */
706 pipe->element0 = C1_B_Cb; /* B */
707 pipe->bpp = 4; /* 4 bpp */
708 break;
709 case MDP_ARGB_8888:
710 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
711 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
712 pipe->a_bit = 3; /* alpha, 4 bits */
713 pipe->r_bit = 3; /* R, 8 bits */
714 pipe->b_bit = 3; /* B, 8 bits */
715 pipe->g_bit = 3; /* G, 8 bits */
716 pipe->alpha_enable = 1;
717 pipe->unpack_tight = 1;
718 pipe->unpack_align_msb = 0;
719 pipe->unpack_count = 3;
720 pipe->element3 = C3_ALPHA; /* alpha */
721 pipe->element2 = C2_R_Cr; /* R */
722 pipe->element1 = C0_G_Y; /* G */
723 pipe->element0 = C1_B_Cb; /* B */
724 pipe->bpp = 4; /* 4 bpp */
725 break;
726 case MDP_RGBA_8888:
727 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
728 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
729 pipe->a_bit = 3; /* alpha, 4 bits */
730 pipe->r_bit = 3; /* R, 8 bits */
731 pipe->b_bit = 3; /* B, 8 bits */
732 pipe->g_bit = 3; /* G, 8 bits */
733 pipe->alpha_enable = 1;
734 pipe->unpack_tight = 1;
735 pipe->unpack_align_msb = 0;
736 pipe->unpack_count = 3;
737 pipe->element3 = C3_ALPHA; /* alpha */
738 pipe->element2 = C1_B_Cb; /* B */
739 pipe->element1 = C0_G_Y; /* G */
740 pipe->element0 = C2_R_Cr; /* R */
741 pipe->bpp = 4; /* 4 bpp */
742 break;
743 case MDP_RGBX_8888:
744 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
745 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
746 pipe->a_bit = 3;
747 pipe->r_bit = 3; /* R, 8 bits */
748 pipe->b_bit = 3; /* B, 8 bits */
749 pipe->g_bit = 3; /* G, 8 bits */
750 pipe->alpha_enable = 0;
751 pipe->unpack_tight = 1;
752 pipe->unpack_align_msb = 0;
753 pipe->unpack_count = 3;
754 pipe->element3 = C3_ALPHA; /* alpha */
755 pipe->element2 = C1_B_Cb; /* B */
756 pipe->element1 = C0_G_Y; /* G */
757 pipe->element0 = C2_R_Cr; /* R */
758 pipe->bpp = 4; /* 4 bpp */
759 break;
760 case MDP_BGRA_8888:
761 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
762 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
763 pipe->a_bit = 3; /* alpha, 4 bits */
764 pipe->r_bit = 3; /* R, 8 bits */
765 pipe->b_bit = 3; /* B, 8 bits */
766 pipe->g_bit = 3; /* G, 8 bits */
767 pipe->alpha_enable = 1;
768 pipe->unpack_tight = 1;
769 pipe->unpack_align_msb = 0;
770 pipe->unpack_count = 3;
771 pipe->element3 = C3_ALPHA; /* alpha */
772 pipe->element2 = C2_R_Cr; /* R */
773 pipe->element1 = C0_G_Y; /* G */
774 pipe->element0 = C1_B_Cb; /* B */
775 pipe->bpp = 4; /* 4 bpp */
776 break;
777 case MDP_YCRYCB_H2V1:
778 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
779 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
780 pipe->a_bit = 0; /* alpha, 4 bits */
781 pipe->r_bit = 3; /* R, 8 bits */
782 pipe->b_bit = 3; /* B, 8 bits */
783 pipe->g_bit = 3; /* G, 8 bits */
784 pipe->alpha_enable = 0;
785 pipe->unpack_tight = 1;
786 pipe->unpack_align_msb = 0;
787 pipe->unpack_count = 3;
788 pipe->element3 = C0_G_Y; /* G */
789 pipe->element2 = C2_R_Cr; /* R */
790 pipe->element1 = C0_G_Y; /* G */
791 pipe->element0 = C1_B_Cb; /* B */
792 pipe->bpp = 2; /* 2 bpp */
793 pipe->chroma_sample = MDP4_CHROMA_H2V1;
794 break;
795 case MDP_Y_CRCB_H2V1:
796 case MDP_Y_CBCR_H2V1:
797 case MDP_Y_CRCB_H2V2:
798 case MDP_Y_CBCR_H2V2:
799 case MDP_Y_CRCB_H1V1:
800 case MDP_Y_CBCR_H1V1:
801 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
802 pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_PLANAR;
803 pipe->a_bit = 0;
804 pipe->r_bit = 3; /* R, 8 bits */
805 pipe->b_bit = 3; /* B, 8 bits */
806 pipe->g_bit = 3; /* G, 8 bits */
807 pipe->alpha_enable = 0;
808 pipe->unpack_tight = 1;
809 pipe->unpack_align_msb = 0;
810 pipe->unpack_count = 1; /* 2 */
811 pipe->element3 = C0_G_Y; /* not used */
812 pipe->element2 = C0_G_Y; /* not used */
813 if (pipe->src_format == MDP_Y_CRCB_H2V1) {
814 pipe->element1 = C2_R_Cr; /* R */
815 pipe->element0 = C1_B_Cb; /* B */
816 pipe->chroma_sample = MDP4_CHROMA_H2V1;
817 } else if (pipe->src_format == MDP_Y_CRCB_H1V1) {
818 pipe->element1 = C2_R_Cr; /* R */
819 pipe->element0 = C1_B_Cb; /* B */
820 if (pipe->src_width > YUV_444_MAX_WIDTH)
821 pipe->chroma_sample = MDP4_CHROMA_H1V2;
822 else
823 pipe->chroma_sample = MDP4_CHROMA_RGB;
824 } else if (pipe->src_format == MDP_Y_CBCR_H2V1) {
825 pipe->element1 = C1_B_Cb; /* B */
826 pipe->element0 = C2_R_Cr; /* R */
827 pipe->chroma_sample = MDP4_CHROMA_H2V1;
828 } else if (pipe->src_format == MDP_Y_CBCR_H1V1) {
829 pipe->element1 = C1_B_Cb; /* B */
830 pipe->element0 = C2_R_Cr; /* R */
831 if (pipe->src_width > YUV_444_MAX_WIDTH)
832 pipe->chroma_sample = MDP4_CHROMA_H1V2;
833 else
834 pipe->chroma_sample = MDP4_CHROMA_RGB;
835 } else if (pipe->src_format == MDP_Y_CRCB_H2V2) {
836 pipe->element1 = C2_R_Cr; /* R */
837 pipe->element0 = C1_B_Cb; /* B */
838 pipe->chroma_sample = MDP4_CHROMA_420;
839 } else if (pipe->src_format == MDP_Y_CBCR_H2V2) {
840 pipe->element1 = C1_B_Cb; /* B */
841 pipe->element0 = C2_R_Cr; /* R */
842 pipe->chroma_sample = MDP4_CHROMA_420;
843 }
844 pipe->bpp = 2; /* 2 bpp */
845 break;
846 case MDP_Y_CBCR_H2V2_TILE:
847 case MDP_Y_CRCB_H2V2_TILE:
848 pipe->frame_format = MDP4_FRAME_FORMAT_VIDEO_SUPERTILE;
849 pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_PLANAR;
850 pipe->a_bit = 0;
851 pipe->r_bit = 3; /* R, 8 bits */
852 pipe->b_bit = 3; /* B, 8 bits */
853 pipe->g_bit = 3; /* G, 8 bits */
854 pipe->alpha_enable = 0;
855 pipe->unpack_tight = 1;
856 pipe->unpack_align_msb = 0;
857 pipe->unpack_count = 1; /* 2 */
858 pipe->element3 = C0_G_Y; /* not used */
859 pipe->element2 = C0_G_Y; /* not used */
860 if (pipe->src_format == MDP_Y_CRCB_H2V2_TILE) {
861 pipe->element1 = C2_R_Cr; /* R */
862 pipe->element0 = C1_B_Cb; /* B */
863 pipe->chroma_sample = MDP4_CHROMA_420;
864 } else if (pipe->src_format == MDP_Y_CBCR_H2V2_TILE) {
865 pipe->element1 = C1_B_Cb; /* B */
866 pipe->element0 = C2_R_Cr; /* R */
867 pipe->chroma_sample = MDP4_CHROMA_420;
868 }
869 pipe->bpp = 2; /* 2 bpp */
870 break;
871 case MDP_Y_CR_CB_H2V2:
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +0530872 case MDP_Y_CR_CB_GH2V2:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700873 case MDP_Y_CB_CR_H2V2:
874 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
875 pipe->fetch_plane = OVERLAY_PLANE_PLANAR;
876 pipe->a_bit = 0;
877 pipe->r_bit = 3; /* R, 8 bits */
878 pipe->b_bit = 3; /* B, 8 bits */
879 pipe->g_bit = 3; /* G, 8 bits */
880 pipe->alpha_enable = 0;
Adrian Salido-Moreno33dc7b92011-08-18 16:16:12 -0700881 pipe->chroma_sample = MDP4_CHROMA_420;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700882 pipe->bpp = 2; /* 2 bpp */
883 break;
884 default:
885 /* not likely */
886 mdp4_stat.err_format++;
887 return -ERANGE;
888 }
889
890 return 0;
891}
892
893/*
894 * color_key_convert: output with 12 bits color key
895 */
896static uint32 color_key_convert(int start, int num, uint32 color)
897{
898 uint32 data;
899
900 data = (color >> start) & ((1 << num) - 1);
901
902 /* convert to 8 bits */
903 if (num == 5)
904 data = ((data << 3) | (data >> 2));
905 else if (num == 6)
906 data = ((data << 2) | (data >> 4));
907
908 /* convert 8 bits to 12 bits */
909 data = (data << 4) | (data >> 4);
910
911 return data;
912}
913
914void transp_color_key(int format, uint32 transp,
915 uint32 *c0, uint32 *c1, uint32 *c2)
916{
917 int b_start, g_start, r_start;
918 int b_num, g_num, r_num;
919
920 switch (format) {
921 case MDP_RGB_565:
922 b_start = 0;
923 g_start = 5;
924 r_start = 11;
925 r_num = 5;
926 g_num = 6;
927 b_num = 5;
928 break;
929 case MDP_RGB_888:
930 case MDP_XRGB_8888:
931 case MDP_ARGB_8888:
932 case MDP_BGRA_8888:
933 b_start = 0;
934 g_start = 8;
935 r_start = 16;
936 r_num = 8;
937 g_num = 8;
938 b_num = 8;
939 break;
940 case MDP_RGBA_8888:
941 case MDP_RGBX_8888:
942 b_start = 16;
943 g_start = 8;
944 r_start = 0;
945 r_num = 8;
946 g_num = 8;
947 b_num = 8;
948 break;
949 case MDP_BGR_565:
950 b_start = 11;
951 g_start = 5;
952 r_start = 0;
953 r_num = 5;
954 g_num = 6;
955 b_num = 5;
956 break;
957 case MDP_Y_CB_CR_H2V2:
958 case MDP_Y_CBCR_H2V2:
959 case MDP_Y_CBCR_H2V1:
960 b_start = 8;
961 g_start = 16;
962 r_start = 0;
963 r_num = 8;
964 g_num = 8;
965 b_num = 8;
966 break;
967 case MDP_Y_CR_CB_H2V2:
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +0530968 case MDP_Y_CR_CB_GH2V2:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700969 case MDP_Y_CRCB_H2V2:
970 case MDP_Y_CRCB_H2V1:
971 case MDP_Y_CRCB_H1V1:
972 case MDP_Y_CBCR_H1V1:
973 b_start = 0;
974 g_start = 16;
975 r_start = 8;
976 r_num = 8;
977 g_num = 8;
978 b_num = 8;
979 break;
980 default:
981 b_start = 0;
982 g_start = 8;
983 r_start = 16;
984 r_num = 8;
985 g_num = 8;
986 b_num = 8;
987 break;
988 }
989
990 *c0 = color_key_convert(g_start, g_num, transp);
991 *c1 = color_key_convert(b_start, b_num, transp);
992 *c2 = color_key_convert(r_start, r_num, transp);
993}
994
995uint32 mdp4_overlay_format(struct mdp4_overlay_pipe *pipe)
996{
997 uint32 format;
998
999 format = 0;
1000
1001 if (pipe->solid_fill)
1002 format |= MDP4_FORMAT_SOLID_FILL;
1003
1004 if (pipe->unpack_align_msb)
1005 format |= MDP4_FORMAT_UNPACK_ALIGN_MSB;
1006
1007 if (pipe->unpack_tight)
1008 format |= MDP4_FORMAT_UNPACK_TIGHT;
1009
1010 if (pipe->alpha_enable)
1011 format |= MDP4_FORMAT_ALPHA_ENABLE;
1012
1013 if (pipe->flags & MDP_SOURCE_ROTATED_90)
1014 format |= MDP4_FORMAT_90_ROTATED;
1015 format |= (pipe->unpack_count << 13);
1016 format |= ((pipe->bpp - 1) << 9);
1017 format |= (pipe->a_bit << 6);
1018 format |= (pipe->r_bit << 4);
1019 format |= (pipe->b_bit << 2);
1020 format |= pipe->g_bit;
1021
1022 format |= (pipe->frame_format << 29);
1023
1024 if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR ||
1025 pipe->fetch_plane == OVERLAY_PLANE_PLANAR) {
1026 /* video/graphic */
1027 format |= (pipe->fetch_plane << 19);
1028 format |= (pipe->chroma_site << 28);
1029 format |= (pipe->chroma_sample << 26);
1030 }
1031
1032 return format;
1033}
1034
1035uint32 mdp4_overlay_unpack_pattern(struct mdp4_overlay_pipe *pipe)
1036{
1037 return (pipe->element3 << 24) | (pipe->element2 << 16) |
1038 (pipe->element1 << 8) | pipe->element0;
1039}
1040
1041/*
1042 * mdp4_overlayproc_cfg: only be called from base layer
1043 */
1044void mdp4_overlayproc_cfg(struct mdp4_overlay_pipe *pipe)
1045{
1046 uint32 data, intf;
1047 char *overlay_base;
1048
1049 intf = 0;
1050 if (pipe->mixer_num == MDP4_MIXER1) {
1051 overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
1052 intf = inpdw(MDP_BASE + 0x0038); /* MDP_DISP_INTF_SEL */
1053 intf >>= 4;
1054 intf &= 0x03;
1055 } else
1056 overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
1057
1058 if (mdp_is_in_isr == FALSE)
1059 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1060
1061 /*
1062 * BLT only siupport at primary display
1063 */
Vinay Kalia27020d12011-10-14 17:50:29 -07001064 if (pipe->blt_addr) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001065 int off, bpp;
1066#ifdef BLT_RGB565
1067 bpp = 2; /* overlay ouput is RGB565 */
1068#else
1069 bpp = 3; /* overlay ouput is RGB888 */
1070#endif
1071 data = pipe->src_height;
1072 data <<= 16;
1073 data |= pipe->src_width;
1074 outpdw(overlay_base + 0x0008, data); /* ROI, height + width */
Vinay Kalia27020d12011-10-14 17:50:29 -07001075 if (pipe->mixer_num == MDP4_MIXER0) {
1076 off = 0;
1077 if (pipe->ov_cnt & 0x01)
1078 off = pipe->src_height * pipe->src_width * bpp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001079
Vinay Kalia27020d12011-10-14 17:50:29 -07001080 outpdw(overlay_base + 0x000c, pipe->blt_addr + off);
1081 /* overlay ouput is RGB888 */
1082 outpdw(overlay_base + 0x0010, pipe->src_width * bpp);
1083 outpdw(overlay_base + 0x001c, pipe->blt_addr + off);
1084 /* MDDI - BLT + on demand */
1085 outpdw(overlay_base + 0x0004, 0x08);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001086#ifdef BLT_RGB565
Vinay Kalia27020d12011-10-14 17:50:29 -07001087 outpdw(overlay_base + 0x0014, 0x1); /* RGB565 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001088#else
Vinay Kalia27020d12011-10-14 17:50:29 -07001089 outpdw(overlay_base + 0x0014, 0x0); /* RGB888 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001090#endif
Vinay Kalia27020d12011-10-14 17:50:29 -07001091 } else {
1092 if (ctrl->panel_mode & MDP4_PANEL_WRITEBACK) {
1093 off = 0;
1094 bpp = 2;
1095 if (pipe->ov_cnt & 0x01)
1096 off = pipe->src_height *
1097 pipe->src_width * bpp;
1098
1099 outpdw(overlay_base + 0x000c,
1100 pipe->blt_addr + off);
1101 /* overlay ouput is RGB888 */
1102 outpdw(overlay_base + 0x0010,
1103 pipe->src_width * bpp);
1104 outpdw(overlay_base + 0x001c,
1105 pipe->blt_addr + off);
1106 /* MDDI - BLT + on demand */
1107 outpdw(overlay_base + 0x0004, 0x08);
1108 outpdw(overlay_base + 0x0014, 0x1); /* RGB565 */
1109 }
1110 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001111 } else {
1112 data = pipe->src_height;
1113 data <<= 16;
1114 data |= pipe->src_width;
1115 outpdw(overlay_base + 0x0008, data); /* ROI, height + width */
1116 outpdw(overlay_base + 0x000c, pipe->srcp0_addr);
1117 outpdw(overlay_base + 0x0010, pipe->srcp0_ystride);
1118 outpdw(overlay_base + 0x0004, 0x01); /* directout */
1119 }
1120
1121 if (pipe->mixer_num == MDP4_MIXER1) {
1122 if (intf == TV_INTF) {
1123 outpdw(overlay_base + 0x0014, 0x02); /* yuv422 */
1124 /* overlay1 CSC config */
1125 outpdw(overlay_base + 0x0200, 0x05); /* rgb->yuv */
1126 }
1127 }
1128
1129#ifdef MDP4_IGC_LUT_ENABLE
1130 outpdw(overlay_base + 0x0014, 0x4); /* GC_LUT_EN, 888 */
1131#endif
1132
1133 if (mdp_is_in_isr == FALSE)
1134 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1135}
1136
1137int mdp4_overlay_pipe_staged(int mixer)
1138{
1139 uint32 data, mask, i;
1140 int p1, p2;
1141
1142 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1143 data = inpdw(MDP_BASE + 0x10100);
1144 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1145 p1 = 0;
1146 p2 = 0;
1147 for (i = 0; i < 8; i++) {
1148 mask = data & 0x0f;
1149 if (mask) {
1150 if (mask <= 4)
1151 p1++;
1152 else
1153 p2++;
1154 }
1155 data >>= 4;
1156 }
1157
1158 if (mixer)
1159 return p2;
1160 else
1161 return p1;
1162}
1163
kuogee hsieh405dc302011-07-21 15:06:59 -07001164int mdp4_mixer_info(int mixer_num, struct mdp_mixer_info *info)
1165{
1166
1167 int ndx, cnt;
1168 struct mdp4_overlay_pipe *pipe;
1169
1170 if (mixer_num > MDP4_MIXER_MAX)
1171 return -ENODEV;
1172
1173 cnt = 0;
1174 ndx = 1; /* ndx 0 if not used */
1175
1176 for ( ; ndx < MDP4_MIXER_STAGE_MAX; ndx++) {
1177 pipe = ctrl->stage[mixer_num][ndx];
1178 if (pipe == NULL)
1179 continue;
1180 info->z_order = pipe->mixer_stage - MDP4_MIXER_STAGE0;
1181 info->ptype = pipe->pipe_type;
1182 info->pnum = pipe->pipe_num;
1183 info->pndx = pipe->pipe_ndx;
1184 info->mixer_num = pipe->mixer_num;
1185 info++;
1186 cnt++;
1187 }
1188 return cnt;
1189}
1190
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001191void mdp4_mixer_stage_up(struct mdp4_overlay_pipe *pipe)
1192{
1193 uint32 data, mask, snum, stage, mixer, pnum;
Adrian Salido-Morenoc4302232011-09-26 12:54:03 -07001194 struct mdp4_overlay_pipe *spipe;
1195
1196 spipe = mdp4_overlay_stage_pipe(pipe->mixer_num, pipe->mixer_stage);
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001197 if ((spipe != NULL) && (spipe->pipe_num != pipe->pipe_num)) {
Adrian Salido-Morenoc4302232011-09-26 12:54:03 -07001198 pr_err("%s: unable to stage pipe=%d at mixer_stage=%d\n",
1199 __func__, pipe->pipe_ndx, pipe->mixer_stage);
1200 return;
1201 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001202
1203 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1204
1205 stage = pipe->mixer_stage;
1206 mixer = pipe->mixer_num;
1207 pnum = pipe->pipe_num;
1208
1209 /* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1 */
1210 data = inpdw(MDP_BASE + 0x10100);
1211
1212 if (mixer == MDP4_MIXER1)
1213 stage += 8;
1214
1215 if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {/* VG1 and VG2 */
1216 pnum -= OVERLAY_PIPE_VG1; /* start from 0 */
1217 snum = 0;
1218 snum += (4 * pnum);
1219 } else {
1220 snum = 8;
1221 snum += (4 * pnum); /* RGB1 and RGB2 */
1222 }
1223
1224 mask = 0x0f;
1225 mask <<= snum;
1226 stage <<= snum;
1227 data &= ~mask; /* clear old bits */
1228
1229 data |= stage;
1230
1231 outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
1232
1233 data = inpdw(MDP_BASE + 0x10100);
1234
1235 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1236
1237 ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = pipe; /* keep it */
1238}
1239
1240void mdp4_mixer_stage_down(struct mdp4_overlay_pipe *pipe)
1241{
1242 uint32 data, mask, snum, stage, mixer, pnum;
1243
1244 stage = pipe->mixer_stage;
1245 mixer = pipe->mixer_num;
1246 pnum = pipe->pipe_num;
1247
1248 if (pipe != ctrl->stage[mixer][stage]) /* not runing */
1249 return;
1250
1251 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1252
1253 /* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1 */
1254 data = inpdw(MDP_BASE + 0x10100);
1255
1256 if (mixer == MDP4_MIXER1)
1257 stage += 8;
1258
1259 if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {/* VG1 and VG2 */
1260 pnum -= OVERLAY_PIPE_VG1; /* start from 0 */
1261 snum = 0;
1262 snum += (4 * pnum);
1263 } else {
1264 snum = 8;
1265 snum += (4 * pnum); /* RGB1 and RGB2 */
1266 }
1267
1268 mask = 0x0f;
1269 mask <<= snum;
1270 data &= ~mask; /* clear old bits */
1271
1272 outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
1273
1274 data = inpdw(MDP_BASE + 0x10100);
1275
1276 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1277
1278 ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = NULL; /* clear it */
1279}
1280
1281void mdp4_mixer_blend_setup(struct mdp4_overlay_pipe *pipe)
1282{
1283 struct mdp4_overlay_pipe *bg_pipe;
1284 unsigned char *overlay_base, *rgb_base;
1285 uint32 c0, c1, c2, blend_op, constant_color = 0, rgb_src_format;
1286 int off;
1287
1288 if (pipe->mixer_num) /* mixer number, /dev/fb0, /dev/fb1 */
1289 overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
1290 else
1291 overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
1292
1293 /* stage 0 to stage 2 */
1294 off = 0x20 * (pipe->mixer_stage - MDP4_MIXER_STAGE0);
1295
1296 bg_pipe = mdp4_overlay_stage_pipe(pipe->mixer_num,
1297 MDP4_MIXER_STAGE_BASE);
1298 if (bg_pipe == NULL) {
1299 pr_err("%s: Error: no bg_pipe\n", __func__);
1300 return;
1301 }
1302
1303 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1304
1305 blend_op = 0;
1306
1307 if (pipe->is_fg) {
1308 blend_op |= (MDP4_BLEND_FG_ALPHA_FG_CONST |
1309 MDP4_BLEND_BG_ALPHA_BG_CONST);
1310 outpdw(overlay_base + off + 0x108, pipe->alpha);
1311 outpdw(overlay_base + off + 0x10c, 0xff - pipe->alpha);
1312 if (pipe->alpha == 0xff) {
1313 rgb_base = MDP_BASE + MDP4_RGB_BASE;
1314 rgb_base += MDP4_RGB_OFF * bg_pipe->pipe_num;
1315 rgb_src_format = inpdw(rgb_base + 0x50);
1316 rgb_src_format |= MDP4_FORMAT_SOLID_FILL;
1317 outpdw(rgb_base + 0x50, rgb_src_format);
1318 outpdw(rgb_base + 0x1008, constant_color);
1319 }
1320 } else {
1321 if (bg_pipe->alpha_enable && pipe->alpha_enable) {
1322 /* both pipe have alpha */
1323 blend_op |= (MDP4_BLEND_FG_ALPHA_BG_PIXEL |
1324 MDP4_BLEND_FG_INV_ALPHA |
1325 MDP4_BLEND_BG_ALPHA_BG_PIXEL);
1326 } else if (bg_pipe->alpha_enable && pipe->alpha_enable == 0) {
1327 /* no alpha on both pipe */
1328 blend_op = (MDP4_BLEND_BG_ALPHA_BG_PIXEL |
1329 MDP4_BLEND_FG_ALPHA_BG_PIXEL |
1330 MDP4_BLEND_FG_INV_ALPHA);
1331 }
1332 }
1333
1334
1335 if (pipe->transp != MDP_TRANSP_NOP) {
1336 if (pipe->is_fg) {
1337 transp_color_key(pipe->src_format, pipe->transp,
1338 &c0, &c1, &c2);
1339 /* Fg blocked */
1340 blend_op |= MDP4_BLEND_FG_TRANSP_EN;
1341 /* lower limit */
1342 outpdw(overlay_base + off + 0x110,
1343 (c1 << 16 | c0));/* low */
1344 outpdw(overlay_base + off + 0x114, c2);/* low */
1345 /* upper limit */
1346 outpdw(overlay_base + off + 0x118,
1347 (c1 << 16 | c0));
1348 outpdw(overlay_base + off + 0x11c, c2);
1349 } else {
1350 transp_color_key(bg_pipe->src_format,
1351 pipe->transp, &c0, &c1, &c2);
1352 /* bg blocked */
1353 blend_op |= MDP4_BLEND_BG_TRANSP_EN;
1354 /* lower limit */
1355 outpdw(overlay_base + 0x180,
1356 (c1 << 16 | c0));/* low */
1357 outpdw(overlay_base + 0x184, c2);/* low */
1358 /* upper limit */
1359 outpdw(overlay_base + 0x188,
1360 (c1 << 16 | c0));/* high */
1361 outpdw(overlay_base + 0x18c, c2);/* high */
1362 }
1363 }
1364
1365 outpdw(overlay_base + off + 0x104, blend_op);
1366
1367 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1368}
1369
1370void mdp4_overlay_reg_flush(struct mdp4_overlay_pipe *pipe, int all)
1371{
1372 struct mdp4_overlay_pipe *bg_pipe;
1373 uint32 bits = 0;
1374
1375 if (pipe->mixer_num == MDP4_MIXER1)
1376 bits |= 0x02;
1377 else
1378 bits |= 0x01;
1379
1380 if (all) {
1381 if (pipe->pipe_num <= OVERLAY_PIPE_RGB2) {
1382 if (pipe->pipe_num == OVERLAY_PIPE_RGB2)
1383 bits |= 0x20;
1384 else
1385 bits |= 0x10;
1386 } else {
1387 if (pipe->is_fg && pipe->alpha == 0xFF) {
1388 bg_pipe = mdp4_overlay_stage_pipe(
1389 pipe->mixer_num,
1390 MDP4_MIXER_STAGE_BASE);
1391 if (bg_pipe->pipe_num <= OVERLAY_PIPE_RGB2) {
1392 if (bg_pipe->pipe_num ==
1393 OVERLAY_PIPE_RGB2)
1394 bits |= 0x20;
1395 else
1396 bits |= 0x10;
1397 }
1398 }
1399 if (pipe->pipe_num == OVERLAY_PIPE_VG2)
1400 bits |= 0x08;
1401 else
1402 bits |= 0x04;
1403 }
1404 }
1405
1406 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1407 outpdw(MDP_BASE + 0x18000, bits); /* MDP_OVERLAY_REG_FLUSH */
1408 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1409}
1410
1411struct mdp4_overlay_pipe *mdp4_overlay_stage_pipe(int mixer, int stage)
1412{
1413 return ctrl->stage[mixer][stage];
1414}
1415
1416struct mdp4_overlay_pipe *mdp4_overlay_ndx2pipe(int ndx)
1417{
1418 struct mdp4_overlay_pipe *pipe;
1419
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001420 if (ndx <= 0 || ndx > OVERLAY_PIPE_MAX)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001421 return NULL;
1422
1423 pipe = &ctrl->plist[ndx - 1]; /* ndx start from 1 */
1424
1425 if (pipe->pipe_used == 0)
1426 return NULL;
1427
1428 return pipe;
1429}
1430
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001431struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(int ptype, int mixer)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001432{
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001433 int i;
1434 struct mdp4_overlay_pipe *pipe;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001435
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001436 for (i = 0; i < OVERLAY_PIPE_MAX; i++) {
1437 pipe = &ctrl->plist[i];
1438 if ((pipe->pipe_used == 0) && ((pipe->pipe_type == ptype) ||
1439 (ptype == OVERLAY_TYPE_RGB &&
1440 pipe->pipe_type == OVERLAY_TYPE_VIDEO))) {
1441 init_completion(&pipe->comp);
1442 init_completion(&pipe->dmas_comp);
1443 pr_info("%s: pipe=%x ndx=%d num=%d\n", __func__,
1444 (int)pipe, pipe->pipe_ndx, pipe->pipe_num);
1445 return pipe;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001446 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001447 }
1448
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001449 pr_err("%s: ptype=%d FAILED\n", __func__, ptype);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001450
1451 return NULL;
1452}
1453
1454
1455void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe)
1456{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001457 uint32 ptype, num, ndx;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001458
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001459 pr_info("%s: pipe=%x ndx=%d\n", __func__, (int)pipe, pipe->pipe_ndx);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001460
1461 ptype = pipe->pipe_type;
1462 num = pipe->pipe_num;
1463 ndx = pipe->pipe_ndx;
1464
1465 memset(pipe, 0, sizeof(*pipe));
1466
1467 pipe->pipe_type = ptype;
1468 pipe->pipe_num = num;
1469 pipe->pipe_ndx = ndx;
1470}
1471
1472int mdp4_overlay_req_check(uint32 id, uint32 z_order, uint32 mixer)
1473{
1474 struct mdp4_overlay_pipe *pipe;
1475
1476 pipe = ctrl->stage[mixer][z_order];
1477
1478 if (pipe == NULL)
1479 return 0;
1480
1481 if (pipe->pipe_ndx == id) /* same req, recycle */
1482 return 0;
1483
1484 if (id == MSMFB_NEW_REQUEST) { /* new request */
1485 if (pipe->pipe_num >= OVERLAY_PIPE_VG1) /* share pipe */
1486 return 0;
1487 }
1488
1489 return -EPERM;
1490}
1491
1492static int mdp4_overlay_validate_downscale(struct mdp_overlay *req,
1493 struct msm_fb_data_type *mfd, uint32 perf_level, uint32 pclk_rate)
1494{
1495 __u32 panel_clk_khz, mdp_clk_khz;
1496 __u32 num_hsync_pix_clks, mdp_clks_per_hsync, src_wh;
1497 __u32 hsync_period_ps, mdp_period_ps, total_hsync_period_ps;
1498 unsigned long fill_rate_y_dir, fill_rate_x_dir;
1499 unsigned long fillratex100, mdp_pixels_produced;
1500 unsigned long mdp_clk_hz;
1501
1502 pr_debug("%s: LCDC Mode Downscale validation with MDP Core"
1503 " Clk rate\n", __func__);
1504 pr_debug("src_w %u, src_h %u, dst_w %u, dst_h %u\n",
1505 req->src_rect.w, req->src_rect.h, req->dst_rect.w,
1506 req->dst_rect.h);
1507
1508
1509 panel_clk_khz = pclk_rate/1000;
1510 mdp_clk_hz = mdp_perf_level2clk_rate(perf_level);
1511
Ravishangar Kalyanamc42862a2011-09-14 11:42:34 -07001512 if (!mdp_clk_hz || !req->dst_rect.w || !req->dst_rect.h) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001513 pr_debug("mdp_perf_level2clk_rate returned 0,"
Ravishangar Kalyanamc42862a2011-09-14 11:42:34 -07001514 "or dst_rect height/width is 0,"
1515 "Downscale Validation incomplete\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001516 return 0;
1517 }
1518
1519 mdp_clk_khz = mdp_clk_hz/1000;
1520
1521 num_hsync_pix_clks = mfd->panel_info.lcdc.h_back_porch +
1522 mfd->panel_info.lcdc.h_front_porch +
1523 mfd->panel_info.lcdc.h_pulse_width +
1524 mfd->panel_info.xres;
1525
1526 hsync_period_ps = 1000000000/panel_clk_khz;
1527 mdp_period_ps = 1000000000/mdp_clk_khz;
1528
1529 total_hsync_period_ps = num_hsync_pix_clks * hsync_period_ps;
1530 mdp_clks_per_hsync = total_hsync_period_ps/mdp_period_ps;
1531
1532 pr_debug("hsync_period_ps %u, mdp_period_ps %u,"
1533 "total_hsync_period_ps %u\n", hsync_period_ps,
1534 mdp_period_ps, total_hsync_period_ps);
1535
1536 src_wh = req->src_rect.w * req->src_rect.h;
1537 if (src_wh % req->dst_rect.h)
1538 fill_rate_y_dir = (src_wh / req->dst_rect.h) + 1;
1539 else
1540 fill_rate_y_dir = (src_wh / req->dst_rect.h);
1541
1542 fill_rate_x_dir = (mfd->panel_info.xres - req->dst_rect.w)
1543 + req->src_rect.w;
1544
1545 if (fill_rate_y_dir >= fill_rate_x_dir)
1546 fillratex100 = 100 * fill_rate_y_dir / mfd->panel_info.xres;
1547 else
1548 fillratex100 = 100 * fill_rate_x_dir / mfd->panel_info.xres;
1549
1550 pr_debug("mdp_clks_per_hsync %u, fill_rate_y_dir %lu,"
1551 "fill_rate_x_dir %lu\n", mdp_clks_per_hsync,
1552 fill_rate_y_dir, fill_rate_x_dir);
1553
1554 mdp_pixels_produced = 100 * mdp_clks_per_hsync/fillratex100;
1555 pr_debug("fillratex100 %lu, mdp_pixels_produced %lu\n",
1556 fillratex100, mdp_pixels_produced);
1557 if (mdp_pixels_produced <= mfd->panel_info.xres) {
1558 pr_err("%s(): LCDC underflow detected during downscale\n",
1559 __func__);
1560 return -ERANGE;
1561 }
1562
1563 return 0;
1564}
1565
1566static int mdp4_overlay_req2pipe(struct mdp_overlay *req, int mixer,
1567 struct mdp4_overlay_pipe **ppipe,
1568 struct msm_fb_data_type *mfd)
1569{
1570 struct mdp4_overlay_pipe *pipe;
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001571 int ret, ptype;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001572
1573 if (mfd == NULL) {
1574 pr_err("%s: mfd == NULL, -ENODEV\n", __func__);
1575 return -ENODEV;
1576 }
1577
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001578 if (mixer >= MDP4_MIXER_MAX) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001579 pr_err("%s: mixer out of range!\n", __func__);
1580 mdp4_stat.err_mixer++;
1581 return -ERANGE;
1582 }
1583
1584 if (req->z_order < 0 || req->z_order > 2) {
1585 pr_err("%s: z_order=%d out of range!\n", __func__,
1586 req->z_order);
1587 mdp4_stat.err_zorder++;
1588 return -ERANGE;
1589 }
1590
1591 if (req->src_rect.h == 0 || req->src_rect.w == 0) {
1592 pr_err("%s: src img of zero size!\n", __func__);
1593 mdp4_stat.err_size++;
1594 return -EINVAL;
1595 }
1596
1597
1598 if (req->dst_rect.h > (req->src_rect.h * 8)) { /* too much */
1599 mdp4_stat.err_scale++;
1600 pr_err("%s: scale up, too much (h)!\n", __func__);
1601 return -ERANGE;
1602 }
1603
1604 if (req->src_rect.h > (req->dst_rect.h * 8)) { /* too little */
1605 mdp4_stat.err_scale++;
1606 pr_err("%s: scale down, too little (h)!\n", __func__);
1607 return -ERANGE;
1608 }
1609
1610 if (req->dst_rect.w > (req->src_rect.w * 8)) { /* too much */
1611 mdp4_stat.err_scale++;
1612 pr_err("%s: scale up, too much (w)!\n", __func__);
1613 return -ERANGE;
1614 }
1615
1616 if (req->src_rect.w > (req->dst_rect.w * 8)) { /* too little */
1617 mdp4_stat.err_scale++;
1618 pr_err("%s: scale down, too little (w)!\n", __func__);
1619 return -ERANGE;
1620 }
1621
1622 if (mdp_hw_revision == MDP4_REVISION_V1) {
1623 /* non integer down saceling ratio smaller than 1/4
1624 * is not supportted
1625 */
1626 if (req->src_rect.h > (req->dst_rect.h * 4)) {
1627 if (req->src_rect.h % req->dst_rect.h) {
1628 mdp4_stat.err_scale++;
1629 pr_err("%s: need integer (h)!\n", __func__);
1630 return -ERANGE;
1631 }
1632 }
1633
1634 if (req->src_rect.w > (req->dst_rect.w * 4)) {
1635 if (req->src_rect.w % req->dst_rect.w) {
1636 mdp4_stat.err_scale++;
1637 pr_err("%s: need integer (w)!\n", __func__);
1638 return -ERANGE;
1639 }
1640 }
1641 }
1642
1643 if (((req->src_rect.x + req->src_rect.w) > req->src.width) ||
1644 ((req->src_rect.y + req->src_rect.h) > req->src.height)) {
1645 mdp4_stat.err_size++;
1646 pr_err("%s invalid src rectangle\n", __func__);
1647 return -ERANGE;
1648 }
1649
1650 if (ctrl->panel_3d != MDP4_3D_SIDE_BY_SIDE) {
1651 int xres;
1652 int yres;
1653
1654 xres = mfd->panel_info.xres;
1655 yres = mfd->panel_info.yres;
1656
1657 if (((req->dst_rect.x + req->dst_rect.w) > xres) ||
1658 ((req->dst_rect.y + req->dst_rect.h) > yres)) {
1659 mdp4_stat.err_size++;
1660 pr_err("%s invalid dst rectangle\n", __func__);
1661 return -ERANGE;
1662 }
1663 }
1664
1665 ptype = mdp4_overlay_format2type(req->src.format);
1666 if (ptype < 0) {
1667 pr_err("%s: mdp4_overlay_format2type!\n", __func__);
1668 return ptype;
1669 }
1670
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001671 if (req->flags & MDP_OV_PIPE_SHARE)
1672 ptype = OVERLAY_TYPE_VIDEO; /* VG pipe supports both RGB+YUV */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001673
1674 if (req->id == MSMFB_NEW_REQUEST) /* new request */
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001675 pipe = mdp4_overlay_pipe_alloc(ptype, mixer);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001676 else
1677 pipe = mdp4_overlay_ndx2pipe(req->id);
1678
1679 if (pipe == NULL) {
1680 pr_err("%s: pipe == NULL!\n", __func__);
1681 return -ENOMEM;
1682 }
1683
1684 /* no down scale at rgb pipe */
1685 if (pipe->pipe_num <= OVERLAY_PIPE_RGB2) {
1686 if ((req->src_rect.h > req->dst_rect.h) ||
1687 (req->src_rect.w > req->dst_rect.w)) {
1688 pr_err("%s: h>h || w>w!\n", __func__);
1689 return -ERANGE;
1690 }
1691 }
1692
1693 pipe->src_format = req->src.format;
1694 ret = mdp4_overlay_format2pipe(pipe);
1695 if (ret < 0) {
1696 pr_err("%s: mdp4_overlay_format2pipe!\n", __func__);
1697 return ret;
1698 }
1699
1700 /*
1701 * base layer == 1, reserved for frame buffer
1702 * zorder 0 == stage 0 == 2
1703 * zorder 1 == stage 1 == 3
1704 * zorder 2 == stage 2 == 4
1705 */
1706 if (req->id == MSMFB_NEW_REQUEST) { /* new request */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001707 pipe->pipe_used++;
1708 pipe->mixer_num = mixer;
1709 pipe->mixer_stage = req->z_order + MDP4_MIXER_STAGE0;
1710 pr_debug("%s: zorder=%d pipe ndx=%d num=%d\n", __func__,
1711 req->z_order, pipe->pipe_ndx, pipe->pipe_num);
1712
1713 }
1714
1715 pipe->src_width = req->src.width & 0x07ff; /* source img width */
1716 pipe->src_height = req->src.height & 0x07ff; /* source img height */
1717 pipe->src_h = req->src_rect.h & 0x07ff;
1718 pipe->src_w = req->src_rect.w & 0x07ff;
1719 pipe->src_y = req->src_rect.y & 0x07ff;
1720 pipe->src_x = req->src_rect.x & 0x07ff;
1721 pipe->dst_h = req->dst_rect.h & 0x07ff;
1722 pipe->dst_w = req->dst_rect.w & 0x07ff;
1723 pipe->dst_y = req->dst_rect.y & 0x07ff;
1724 pipe->dst_x = req->dst_rect.x & 0x07ff;
1725
1726 pipe->op_mode = 0;
1727
1728 if (req->flags & MDP_FLIP_LR)
1729 pipe->op_mode |= MDP4_OP_FLIP_LR;
1730
1731 if (req->flags & MDP_FLIP_UD)
1732 pipe->op_mode |= MDP4_OP_FLIP_UD;
1733
1734 if (req->flags & MDP_DITHER)
1735 pipe->op_mode |= MDP4_OP_DITHER_EN;
1736
1737 if (req->flags & MDP_DEINTERLACE)
1738 pipe->op_mode |= MDP4_OP_DEINT_EN;
1739
1740 if (req->flags & MDP_DEINTERLACE_ODD)
1741 pipe->op_mode |= MDP4_OP_DEINT_ODD_REF;
1742
1743 pipe->is_fg = req->is_fg;/* control alpha and color key */
1744
1745 pipe->alpha = req->alpha & 0x0ff;
1746
1747 pipe->transp = req->transp_mask;
1748
1749 *ppipe = pipe;
1750
1751 return 0;
1752}
1753
1754static int get_img(struct msmfb_data *img, struct fb_info *info,
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001755 unsigned long *start, unsigned long *len, struct file **srcp_file,
1756 struct ion_handle **srcp_ihdl)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001757{
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001758#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
1759 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1760#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001761 struct file *file;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001762 int put_needed, ret = 0, fb_num;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001763#ifdef CONFIG_ANDROID_PMEM
1764 unsigned long vstart;
1765#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001766 if (img->flags & MDP_BLIT_SRC_GEM) {
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001767 *srcp_file = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001768 return kgsl_gem_obj_addr(img->memory_id, (int) img->priv,
1769 start, len);
1770 }
1771
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001772 if (img->flags & MDP_MEMORY_ID_TYPE_FB) {
1773 file = fget_light(img->memory_id, &put_needed);
1774 if (file == NULL)
1775 return -EINVAL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001776
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001777 if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
1778 fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
1779 if (get_fb_phys_info(start, len, fb_num))
1780 ret = -1;
1781 else
1782 *srcp_file = file;
1783 } else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001784 ret = -1;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001785 if (ret)
1786 fput_light(file, put_needed);
1787 return ret;
1788 }
1789
1790#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
1791 *srcp_ihdl = ion_import_fd(mfd->client, img->memory_id);
1792 if (IS_ERR_OR_NULL(*srcp_ihdl))
1793 return PTR_ERR(*srcp_ihdl);
1794 if (!ion_phys(mfd->client, *srcp_ihdl, start, (size_t *) len))
1795 return 0;
1796 else
1797 return -EINVAL;
1798#endif
1799#ifdef CONFIG_ANDROID_PMEM
1800 if (!get_pmem_file(img->memory_id, start, &vstart,
1801 len, srcp_file))
1802 return 0;
1803 else
1804 return -EINVAL;
1805#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001806}
1807
kuogee hsieh4aea2742011-07-06 11:05:05 -07001808#ifdef CONFIG_FB_MSM_MIPI_DSI
1809int mdp4_overlay_3d_sbys(struct fb_info *info, struct msmfb_overlay_3d *req)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001810{
1811 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1812 int ret = -EPERM;
1813
1814 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
1815 return -EINTR;
1816
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001817 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
kuogee hsieh4aea2742011-07-06 11:05:05 -07001818 mdp4_dsi_cmd_3d_sbys(mfd, req);
1819 ret = 0;
1820 } else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
1821 mdp4_dsi_video_3d_sbys(mfd, req);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001822 ret = 0;
1823 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001824 mutex_unlock(&mfd->dma->ov_mutex);
1825
1826 return ret;
1827}
kuogee hsieh4aea2742011-07-06 11:05:05 -07001828#else
1829int mdp4_overlay_3d_sbys(struct fb_info *info, struct msmfb_overlay_3d *req)
1830{
1831 /* do nothing */
1832 return -EPERM;
1833}
1834#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001835
1836#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
1837int mdp4_overlay_blt(struct fb_info *info, struct msmfb_overlay_blt *req)
1838{
1839 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1840
1841 if (mfd == NULL)
1842 return -ENODEV;
1843
1844 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
1845 return -EINTR;
1846
1847 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
1848 mdp4_dsi_overlay_blt(mfd, req);
1849 else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
1850 mdp4_dsi_video_overlay_blt(mfd, req);
1851 else if (ctrl->panel_mode & MDP4_PANEL_LCDC)
1852 mdp4_lcdc_overlay_blt(mfd, req);
1853
1854 mutex_unlock(&mfd->dma->ov_mutex);
1855
1856 return 0;
1857}
1858
1859int mdp4_overlay_blt_offset(struct fb_info *info, struct msmfb_overlay_blt *req)
1860{
1861 int ret = 0;
1862
1863 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1864
1865 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
1866 return -EINTR;
1867
1868 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
1869 ret = mdp4_dsi_overlay_blt_offset(mfd, req);
1870 else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
1871 ret = mdp4_dsi_video_overlay_blt_offset(mfd, req);
1872 else if (ctrl->panel_mode & MDP4_PANEL_LCDC)
1873 ret = mdp4_lcdc_overlay_blt_offset(mfd, req);
1874
1875 mutex_unlock(&mfd->dma->ov_mutex);
1876
1877 return ret;
1878}
1879#endif
1880
1881int mdp4_overlay_get(struct fb_info *info, struct mdp_overlay *req)
1882{
1883 struct mdp4_overlay_pipe *pipe;
1884
1885 pipe = mdp4_overlay_ndx2pipe(req->id);
1886 if (pipe == NULL)
1887 return -ENODEV;
1888
1889 *req = pipe->req_data;
1890
1891 return 0;
1892}
1893
1894#define OVERLAY_VGA_SIZE 0x04B000
1895#define OVERLAY_720P_TILE_SIZE 0x0E6000
1896#define OVERLAY_WSVGA_SIZE 0x98000 /* 1024x608, align 600 to 32bit */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001897
1898#ifdef CONFIG_MSM_BUS_SCALING
1899#define OVERLAY_BUS_SCALE_TABLE_BASE 6
1900#endif
1901
1902static int mdp4_overlay_is_rgb_type(int format)
1903{
1904 switch (format) {
1905 case MDP_RGB_565:
1906 case MDP_RGB_888:
1907 case MDP_BGR_565:
1908 case MDP_XRGB_8888:
1909 case MDP_ARGB_8888:
1910 case MDP_RGBA_8888:
1911 case MDP_BGRA_8888:
1912 case MDP_RGBX_8888:
1913 return 1;
1914 default:
1915 return 0;
1916 }
1917}
1918
1919static uint32 mdp4_overlay_get_perf_level(struct mdp_overlay *req)
1920{
1921 int is_fg;
1922
1923 if (req->is_fg && ((req->alpha & 0x0ff) == 0xff))
1924 is_fg = 1;
1925
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -07001926 if (mdp4_extn_disp)
1927 return OVERLAY_PERF_LEVEL1;
1928
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001929 if (req->flags & MDP_DEINTERLACE)
1930 return OVERLAY_PERF_LEVEL1;
1931
1932 if (mdp4_overlay_is_rgb_type(req->src.format) && is_fg &&
1933 ((req->src.width * req->src.height) <= OVERLAY_WSVGA_SIZE))
1934 return OVERLAY_PERF_LEVEL4;
1935 else if (mdp4_overlay_is_rgb_type(req->src.format))
1936 return OVERLAY_PERF_LEVEL1;
1937
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001938 if (ctrl->plist[OVERLAY_PIPE_VG1].pipe_used &&
1939 ctrl->plist[OVERLAY_PIPE_VG2].pipe_used)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001940 return OVERLAY_PERF_LEVEL1;
1941
1942 if (req->src.width*req->src.height <= OVERLAY_VGA_SIZE)
1943 return OVERLAY_PERF_LEVEL3;
1944 else if (req->src.width*req->src.height <= OVERLAY_720P_TILE_SIZE)
1945 return OVERLAY_PERF_LEVEL2;
1946 else
1947 return OVERLAY_PERF_LEVEL1;
1948}
1949
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -07001950void mdp4_update_perf_level(u32 perf_level)
1951{
1952 new_perf_level = perf_level;
1953}
1954
kuogee hsiehc4b8b2f2011-07-12 13:32:14 -07001955void mdp4_set_perf_level(void)
1956{
1957 static int old_perf_level;
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -07001958 int cur_perf_level;
kuogee hsiehc4b8b2f2011-07-12 13:32:14 -07001959
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -07001960 if (mdp4_extn_disp)
1961 cur_perf_level = OVERLAY_PERF_LEVEL1;
1962 else
1963 cur_perf_level = new_perf_level;
1964
1965 if (old_perf_level != cur_perf_level) {
1966 mdp_set_core_clk(cur_perf_level);
1967 old_perf_level = cur_perf_level;
kuogee hsiehc4b8b2f2011-07-12 13:32:14 -07001968 }
1969}
1970
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001971int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req)
1972{
1973 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
kuogee hsiehc4b8b2f2011-07-12 13:32:14 -07001974 int ret, mixer, perf_level;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001975 struct mdp4_overlay_pipe *pipe;
1976
1977 if (mfd == NULL) {
1978 pr_err("%s: mfd == NULL, -ENODEV\n", __func__);
1979 return -ENODEV;
1980 }
1981
1982 if (!mfd->panel_power_on) /* suspended */
1983 return -EPERM;
1984
1985 if (req->src.format == MDP_FB_FORMAT)
1986 req->src.format = mfd->fb_imgType;
1987
1988 if (mutex_lock_interruptible(&mfd->dma->ov_mutex)) {
1989 pr_err("%s: mutex_lock_interruptible, -EINTR\n", __func__);
1990 return -EINTR;
1991 }
1992
1993 perf_level = mdp4_overlay_get_perf_level(req);
1994
1995 if ((mfd->panel_info.type == LCDC_PANEL) &&
1996 (req->src_rect.h >
1997 req->dst_rect.h || req->src_rect.w > req->dst_rect.w)) {
1998 if (mdp4_overlay_validate_downscale(req, mfd,
kuogee hsieh21ef2fe2011-08-18 17:12:42 -07001999 perf_level, mfd->panel_info.clk_rate))
2000 mdp4_lcdc_overlay_blt_start(mfd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002001 }
kuogee hsieh4d3c7792011-07-25 11:02:24 -07002002
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002003 if ((mfd->panel_info.type == MIPI_VIDEO_PANEL) &&
2004 (req->src_rect.h >
2005 req->dst_rect.h || req->src_rect.w > req->dst_rect.w)) {
2006 if (mdp4_overlay_validate_downscale(req, mfd,
kuogee hsieh4d3c7792011-07-25 11:02:24 -07002007 perf_level, (&mfd->panel_info.mipi)->dsi_pclk_rate))
kuogee hsieh21ef2fe2011-08-18 17:12:42 -07002008 mdp4_dsi_video_blt_start(mfd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002009 }
kuogee hsieh4d3c7792011-07-25 11:02:24 -07002010
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002011 mixer = mfd->panel_info.pdest; /* DISPLAY_1 or DISPLAY_2 */
2012
2013 ret = mdp4_overlay_req2pipe(req, mixer, &pipe, mfd);
2014 if (ret < 0) {
2015 mutex_unlock(&mfd->dma->ov_mutex);
2016 pr_err("%s: mdp4_overlay_req2pipe, ret=%d\n", __func__, ret);
2017 return ret;
2018 }
2019
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002020 /*
2021 * writeback (blt) mode to provide work around for
2022 * dsi cmd mode interface hardware bug.
2023 */
2024 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
2025 if (mixer == MDP4_MIXER0 && req->dst_rect.x != 0) {
2026 mdp4_dsi_blt_dmap_busy_wait(mfd);
2027 mdp4_dsi_overlay_blt_start(mfd);
2028 }
2029 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002030
2031 /* return id back to user */
2032 req->id = pipe->pipe_ndx; /* pipe_ndx start from 1 */
2033 pipe->req_data = *req; /* keep original req */
2034
2035 pipe->flags = req->flags;
2036
2037 if (pipe->flags & MDP_SHARPENING) {
2038 bool test = ((pipe->req_data.dpp.sharp_strength > 0) &&
2039 ((req->src_rect.w > req->dst_rect.w) &&
2040 (req->src_rect.h > req->dst_rect.h)));
2041 if (test) {
2042 pr_warn("%s: No sharpening while downscaling.\n",
2043 __func__);
2044 pipe->flags &= ~MDP_SHARPENING;
2045 }
2046 }
2047
Liyuan Lid9736632011-11-11 13:47:59 -08002048 /* precompute HSIC matrices */
2049 if (req->flags & MDP_DPP_HSIC)
2050 mdp4_hsic_set(pipe, &(req->dpp));
2051
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002052 mdp4_stat.overlay_set[pipe->mixer_num]++;
2053
2054 if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
2055 if (mdp_hw_revision == MDP4_REVISION_V2_1 &&
2056 pipe->mixer_num == MDP4_MIXER0)
2057 mdp4_overlay_status_write(MDP4_OVERLAY_TYPE_SET, true);
2058 }
2059
Adrian Salido-Moreno5e912032011-08-29 11:15:47 -07002060 if (new_perf_level != perf_level) {
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -07002061 mdp4_update_perf_level(perf_level);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002062
Adrian Salido-Moreno5e912032011-08-29 11:15:47 -07002063 /* change clck base on perf level */
Adrian Salido-Moreno5e912032011-08-29 11:15:47 -07002064 if (pipe->mixer_num == MDP4_MIXER0) {
2065 if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
kuogee hsiehaff429a2011-09-22 17:50:05 -07002066 mdp4_overlay_dsi_video_set_perf(mfd);
Adrian Salido-Moreno5e912032011-08-29 11:15:47 -07002067 } else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
2068 mdp4_dsi_cmd_dma_busy_wait(mfd);
2069 mdp4_dsi_blt_dmap_busy_wait(mfd);
2070 mdp4_set_perf_level();
2071 } else if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
kuogee hsiehaff429a2011-09-22 17:50:05 -07002072 mdp4_overlay_lcdc_set_perf(mfd);
Adrian Salido-Moreno5e912032011-08-29 11:15:47 -07002073 } else if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
2074 mdp4_mddi_dma_busy_wait(mfd);
2075 mdp4_set_perf_level();
2076 }
2077 } else {
2078 if (ctrl->panel_mode & MDP4_PANEL_DTV)
2079 mdp4_overlay_dtv_vsync_push(mfd, pipe);
kuogee hsieh9452ecb2011-08-01 18:26:23 -07002080 }
kuogee hsieh9452ecb2011-08-01 18:26:23 -07002081 }
kuogee hsieh9452ecb2011-08-01 18:26:23 -07002082
2083 mutex_unlock(&mfd->dma->ov_mutex);
2084
2085
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002086#ifdef CONFIG_MSM_BUS_SCALING
2087 if (pipe->mixer_num == MDP4_MIXER0) {
2088 mdp_bus_scale_update_request(OVERLAY_BUS_SCALE_TABLE_BASE
2089 - perf_level);
2090 }
2091#endif
2092
2093 return 0;
2094}
2095
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002096int mdp4_overlay_unset(struct fb_info *info, int ndx)
2097{
2098 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
2099 struct mdp4_overlay_pipe *pipe;
2100 uint32 flags;
Liyuan Lid9736632011-11-11 13:47:59 -08002101 struct dpp_ctrl dpp;
2102 int i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002103
2104 if (mfd == NULL)
2105 return -ENODEV;
2106
2107 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
2108 return -EINTR;
2109
2110 pipe = mdp4_overlay_ndx2pipe(ndx);
2111
2112 if (pipe == NULL) {
2113 mutex_unlock(&mfd->dma->ov_mutex);
2114 return -ENODEV;
2115 }
2116
2117 if (pipe->mixer_num == MDP4_MIXER1)
2118 ctrl->mixer1_played = 0;
2119 else {
2120 /* mixer 0 */
2121 ctrl->mixer0_played = 0;
2122#ifdef CONFIG_FB_MSM_MIPI_DSI
2123 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
2124 if (mfd->panel_power_on) {
2125 mdp4_dsi_blt_dmap_busy_wait(mfd);
2126 }
2127 }
2128#else
2129 if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
2130 if (mfd->panel_power_on)
2131 mdp4_mddi_dma_busy_wait(mfd);
2132 }
2133#endif
2134 }
2135
2136 mdp4_mixer_stage_down(pipe);
2137
2138 if (pipe->mixer_num == MDP4_MIXER0) {
2139#ifdef CONFIG_FB_MSM_MIPI_DSI
2140 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
2141 if (mfd->panel_power_on)
2142 if (mdp4_dsi_overlay_blt_stop(mfd) == 0)
2143 mdp4_dsi_cmd_overlay_restore();
2144 } else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
kuogee hsiehebca0c72011-07-14 13:30:33 -07002145 mdp4_overlay_reg_flush(pipe, 1);
kuogee hsieh5c6cfbf2011-09-06 19:01:31 -07002146 if (mfd->panel_power_on) {
2147 flags = pipe->flags;
2148 pipe->flags &= ~MDP_OV_PLAY_NOWAIT;
2149 mdp4_overlay_dsi_video_vsync_push(mfd, pipe);
2150 pipe->flags = flags;
2151 }
kuogee hsieh4d3c7792011-07-25 11:02:24 -07002152 mdp4_dsi_video_blt_stop(mfd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002153 }
2154#else
2155 if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
2156 if (mdp_hw_revision == MDP4_REVISION_V2_1)
2157 mdp4_overlay_status_write(
2158 MDP4_OVERLAY_TYPE_UNSET, true);
2159 if (mfd->panel_power_on)
2160 mdp4_mddi_overlay_restore();
2161 }
2162#endif
2163 else if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
kuogee hsiehebca0c72011-07-14 13:30:33 -07002164 mdp4_overlay_reg_flush(pipe, 1);
kuogee hsieh5c6cfbf2011-09-06 19:01:31 -07002165 if (mfd->panel_power_on) {
2166 flags = pipe->flags;
2167 pipe->flags &= ~MDP_OV_PLAY_NOWAIT;
2168 mdp4_overlay_lcdc_vsync_push(mfd, pipe);
2169 pipe->flags = flags;
2170 }
kuogee hsieh21ef2fe2011-08-18 17:12:42 -07002171 mdp4_lcdc_overlay_blt_stop(mfd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002172 }
2173 }
2174#ifdef CONFIG_FB_MSM_DTV
2175 else { /* mixer1, DTV, ATV */
kuogee hsieh9452ecb2011-08-01 18:26:23 -07002176 if (ctrl->panel_mode & MDP4_PANEL_DTV) {
kuogee hsieh5c6cfbf2011-09-06 19:01:31 -07002177 if (mfd->panel_power_on) {
2178 flags = pipe->flags;
2179 pipe->flags &= ~MDP_OV_PLAY_NOWAIT;
2180 mdp4_overlay_dtv_vsync_push(mfd, pipe);
2181 pipe->flags = flags;
2182 }
kuogee hsieh9452ecb2011-08-01 18:26:23 -07002183 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002184 }
2185#endif
2186
Liyuan Lid9736632011-11-11 13:47:59 -08002187 /* Reset any HSIC settings to default */
2188 if (pipe->flags & MDP_DPP_HSIC) {
2189 for (i = 0; i < NUM_HSIC_PARAM; i++)
2190 dpp.hsic_params[i] = 0;
2191
2192 mdp4_hsic_set(pipe, &dpp);
2193 mdp4_hsic_update(pipe);
2194 }
2195
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002196 mdp4_stat.overlay_unset[pipe->mixer_num]++;
2197
2198 mdp4_overlay_pipe_free(pipe);
2199
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07002200 if (!(ctrl->plist[OVERLAY_PIPE_VG1].pipe_used +
2201 ctrl->plist[OVERLAY_PIPE_VG2].pipe_used))
2202 mdp4_update_perf_level(OVERLAY_PERF_LEVEL4);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002203
2204 mutex_unlock(&mfd->dma->ov_mutex);
2205
2206#ifdef CONFIG_MSM_BUS_SCALING
2207 if (pipe->mixer_num == MDP4_MIXER0)
2208 if (mfd->panel_power_on)
2209 mdp_bus_scale_update_request(2);
2210#endif
2211 return 0;
2212}
2213
2214struct tile_desc {
2215 uint32 width; /* tile's width */
2216 uint32 height; /* tile's height */
2217 uint32 row_tile_w; /* tiles per row's width */
2218 uint32 row_tile_h; /* tiles per row's height */
2219};
2220
2221void tile_samsung(struct tile_desc *tp)
2222{
2223 /*
2224 * each row of samsung tile consists of two tiles in height
2225 * and two tiles in width which means width should align to
2226 * 64 x 2 bytes and height should align to 32 x 2 bytes.
2227 * video decoder generate two tiles in width and one tile
2228 * in height which ends up height align to 32 X 1 bytes.
2229 */
2230 tp->width = 64; /* 64 bytes */
2231 tp->row_tile_w = 2; /* 2 tiles per row's width */
2232 tp->height = 32; /* 32 bytes */
2233 tp->row_tile_h = 1; /* 1 tiles per row's height */
2234}
2235
2236uint32 tile_mem_size(struct mdp4_overlay_pipe *pipe, struct tile_desc *tp)
2237{
2238 uint32 tile_w, tile_h;
2239 uint32 row_num_w, row_num_h;
2240
2241
2242 tile_w = tp->width * tp->row_tile_w;
2243 tile_h = tp->height * tp->row_tile_h;
2244
2245 row_num_w = (pipe->src_width + tile_w - 1) / tile_w;
2246 row_num_h = (pipe->src_height + tile_h - 1) / tile_h;
2247 return ((row_num_w * row_num_h * tile_w * tile_h) + 8191) & ~8191;
2248}
2249
Nagamalleswararao Ganji0737d652011-10-14 02:02:33 -07002250int mdp4_overlay_play_wait(struct fb_info *info, struct msmfb_overlay_data *req)
2251{
2252 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
2253 struct mdp4_overlay_pipe *pipe;
2254
2255 if (mfd == NULL)
2256 return -ENODEV;
2257
2258 if (!mfd->panel_power_on) /* suspended */
2259 return -EPERM;
2260
2261 pipe = mdp4_overlay_ndx2pipe(req->id);
2262
2263 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
2264 return -EINTR;
2265
2266 mdp4_overlay_dtv_wait_for_ov(mfd, pipe);
2267
2268 mutex_unlock(&mfd->dma->ov_mutex);
2269
2270 return 0;
2271}
2272
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002273int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002274{
2275 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
2276 struct msmfb_data *img;
2277 struct mdp4_overlay_pipe *pipe;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002278 ulong start, addr;
2279 ulong len = 0;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002280 struct file *srcp0_file = NULL;
2281 struct file *srcp1_file = NULL, *srcp2_file = NULL;
2282 struct ion_handle *srcp0_ihdl = NULL;
2283 struct ion_handle *srcp1_ihdl = NULL, *srcp2_ihdl = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002284 uint32_t overlay_version = 0;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002285 int ret = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002286
2287 if (mfd == NULL)
2288 return -ENODEV;
2289
2290 if (!mfd->panel_power_on) /* suspended */
2291 return -EPERM;
2292
2293 pipe = mdp4_overlay_ndx2pipe(req->id);
2294 if (pipe == NULL) {
2295 pr_err("%s: req_id=%d Error\n", __func__, req->id);
2296 return -ENODEV;
2297 }
2298
2299 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
2300 return -EINTR;
2301
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002302 img = &req->data;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002303 get_img(img, info, &start, &len, &srcp0_file, &srcp0_ihdl);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002304 if (len == 0) {
2305 mutex_unlock(&mfd->dma->ov_mutex);
2306 pr_err("%s: pmem Error\n", __func__);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002307 ret = -1;
2308 goto end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002309 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002310
2311 addr = start + img->offset;
2312 pipe->srcp0_addr = addr;
2313 pipe->srcp0_ystride = pipe->src_width * pipe->bpp;
2314
2315 if ((req->version_key & VERSION_KEY_MASK) == 0xF9E8D700)
2316 overlay_version = (req->version_key & ~VERSION_KEY_MASK);
2317
2318 if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR) {
2319 if (overlay_version > 0) {
2320 img = &req->plane1_data;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002321 get_img(img, info, &start, &len, &srcp1_file,
2322 &srcp1_ihdl);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002323 if (len == 0) {
2324 mutex_unlock(&mfd->dma->ov_mutex);
2325 pr_err("%s: Error to get plane1\n", __func__);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002326 ret = -EINVAL;
2327 goto end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002328 }
2329 pipe->srcp1_addr = start + img->offset;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002330 } else if (pipe->frame_format ==
2331 MDP4_FRAME_FORMAT_VIDEO_SUPERTILE) {
2332 struct tile_desc tile;
2333
2334 tile_samsung(&tile);
2335 pipe->srcp1_addr = addr + tile_mem_size(pipe, &tile);
2336 } else {
2337 pipe->srcp1_addr = addr + (pipe->src_width *
2338 pipe->src_height);
2339 }
2340 pipe->srcp0_ystride = pipe->src_width;
2341 if ((pipe->src_format == MDP_Y_CRCB_H1V1) ||
2342 (pipe->src_format == MDP_Y_CBCR_H1V1)) {
2343 if (pipe->src_width > YUV_444_MAX_WIDTH)
2344 pipe->srcp1_ystride = pipe->src_width << 2;
2345 else
2346 pipe->srcp1_ystride = pipe->src_width << 1;
2347 } else
2348 pipe->srcp1_ystride = pipe->src_width;
2349
2350 } else if (pipe->fetch_plane == OVERLAY_PLANE_PLANAR) {
2351 if (overlay_version > 0) {
2352 img = &req->plane1_data;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002353 get_img(img, info, &start, &len, &srcp1_file,
2354 &srcp1_ihdl);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002355 if (len == 0) {
2356 mutex_unlock(&mfd->dma->ov_mutex);
2357 pr_err("%s: Error to get plane1\n", __func__);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002358 ret = -EINVAL;
2359 goto end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002360 }
2361 pipe->srcp1_addr = start + img->offset;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002362
2363 img = &req->plane2_data;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002364 get_img(img, info, &start, &len, &srcp2_file,
2365 &srcp2_ihdl);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002366 if (len == 0) {
2367 mutex_unlock(&mfd->dma->ov_mutex);
2368 pr_err("%s: Error to get plane2\n", __func__);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002369 ret = -EINVAL;
2370 goto end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002371 }
2372 pipe->srcp2_addr = start + img->offset;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002373 } else {
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +05302374 if (pipe->src_format == MDP_Y_CR_CB_GH2V2) {
2375 addr += (ALIGN(pipe->src_width, 16) *
2376 pipe->src_height);
2377 pipe->srcp1_addr = addr;
2378 addr += ((ALIGN((pipe->src_width / 2), 16)) *
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002379 (pipe->src_height / 2));
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +05302380 pipe->srcp2_addr = addr;
2381 } else {
2382 addr += (pipe->src_width * pipe->src_height);
2383 pipe->srcp1_addr = addr;
2384 addr += ((pipe->src_width / 2) *
2385 (pipe->src_height / 2));
2386 pipe->srcp2_addr = addr;
2387 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002388 }
Adrian Salido-Moreno33dc7b92011-08-18 16:16:12 -07002389 /* mdp planar format expects Cb in srcp1 and Cr in p2 */
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +05302390 if ((pipe->src_format == MDP_Y_CR_CB_H2V2) ||
2391 (pipe->src_format == MDP_Y_CR_CB_GH2V2))
Adrian Salido-Moreno33dc7b92011-08-18 16:16:12 -07002392 swap(pipe->srcp1_addr, pipe->srcp2_addr);
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +05302393
2394 if (pipe->src_format == MDP_Y_CR_CB_GH2V2) {
2395 pipe->srcp0_ystride = ALIGN(pipe->src_width, 16);
2396 pipe->srcp1_ystride = ALIGN(pipe->src_width / 2, 16);
2397 pipe->srcp2_ystride = ALIGN(pipe->src_width / 2, 16);
2398 } else {
2399 pipe->srcp0_ystride = pipe->src_width;
2400 pipe->srcp1_ystride = pipe->src_width / 2;
2401 pipe->srcp2_ystride = pipe->src_width / 2;
2402 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002403 }
2404
2405 if (pipe->pipe_num >= OVERLAY_PIPE_VG1)
2406 mdp4_overlay_vg_setup(pipe); /* video/graphic pipe */
2407 else {
2408 if (pipe->flags & MDP_SHARPENING) {
2409 pr_warn(
2410 "%s: Sharpening/Smoothing not supported on RGB pipe\n",
2411 __func__);
2412 pipe->flags &= ~MDP_SHARPENING;
2413 }
2414 mdp4_overlay_rgb_setup(pipe); /* rgb pipe */
2415 }
2416
2417 mdp4_mixer_blend_setup(pipe);
2418 mdp4_mixer_stage_up(pipe);
2419
2420 if (pipe->mixer_num == MDP4_MIXER1) {
2421 ctrl->mixer1_played++;
2422 /* enternal interface */
2423 if (ctrl->panel_mode & MDP4_PANEL_DTV)
2424#ifdef CONFIG_FB_MSM_DTV
2425 mdp4_overlay_dtv_ov_done_push(mfd, pipe);
2426#else
2427 mdp4_overlay_reg_flush(pipe, 1);
2428#endif
2429 else if (ctrl->panel_mode & MDP4_PANEL_ATV)
2430 mdp4_overlay_reg_flush(pipe, 1);
Vinay Kalia27020d12011-10-14 17:50:29 -07002431#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
2432 else if (ctrl->panel_mode & MDP4_PANEL_WRITEBACK) {
2433 mdp4_writeback_dma_busy_wait(mfd);
2434 mdp4_writeback_kickoff_video(mfd, pipe);
2435 }
2436#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002437 } else {
2438 /* primary interface */
2439 ctrl->mixer0_played++;
kuogee hsieh3de11f32011-07-08 14:09:11 -07002440 if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
2441 mdp4_overlay_reg_flush(pipe, 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002442 mdp4_overlay_lcdc_vsync_push(mfd, pipe);
kuogee hsieh3de11f32011-07-08 14:09:11 -07002443 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002444#ifdef CONFIG_FB_MSM_MIPI_DSI
kuogee hsieh3de11f32011-07-08 14:09:11 -07002445 else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
2446 mdp4_overlay_reg_flush(pipe, 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002447 mdp4_overlay_dsi_video_vsync_push(mfd, pipe);
kuogee hsieh3de11f32011-07-08 14:09:11 -07002448 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002449#endif
2450 else {
2451 /* mddi & mipi dsi cmd mode */
2452 if (pipe->flags & MDP_OV_PLAY_NOWAIT) {
2453 mdp4_stat.overlay_play[pipe->mixer_num]++;
2454 mutex_unlock(&mfd->dma->ov_mutex);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002455 goto end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002456 }
2457#ifdef CONFIG_FB_MSM_MIPI_DSI
2458 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
2459 mdp4_dsi_cmd_dma_busy_wait(mfd);
2460 mdp4_dsi_cmd_kickoff_video(mfd, pipe);
2461 }
2462#else
2463 if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
2464 mdp4_mddi_dma_busy_wait(mfd);
2465 mdp4_mddi_kickoff_video(mfd, pipe);
2466 }
2467#endif
2468 }
2469 }
2470
Liyuan Lid9736632011-11-11 13:47:59 -08002471 /* write out DPP HSIC registers */
2472 if (pipe->flags & MDP_DPP_HSIC)
2473 mdp4_hsic_update(pipe);
2474
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002475 mdp4_stat.overlay_play[pipe->mixer_num]++;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002476 mutex_unlock(&mfd->dma->ov_mutex);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002477end:
2478#ifdef CONFIG_ANDROID_PMEM
2479 if (srcp0_file)
2480 put_pmem_file(srcp0_file);
2481 if (srcp1_file)
2482 put_pmem_file(srcp1_file);
2483 if (srcp2_file)
2484 put_pmem_file(srcp2_file);
2485#endif
2486#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
2487 if (!IS_ERR_OR_NULL(srcp0_ihdl))
2488 ion_free(mfd->client, srcp0_ihdl);
2489 if (!IS_ERR_OR_NULL(srcp1_ihdl))
2490 ion_free(mfd->client, srcp1_ihdl);
2491 if (!IS_ERR_OR_NULL(srcp2_ihdl))
2492 ion_free(mfd->client, srcp2_ihdl);
2493#endif
2494 return ret;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002495}