blob: 72a11a2ed700acb09657481559bbe1ac3ec86852 [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 },
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -070074 {
75 .pipe_type = OVERLAY_TYPE_BF,
76 .pipe_num = OVERLAY_PIPE_RGB3,
77 .pipe_ndx = 5,
78 .mixer_num = MDP4_MIXER0,
79 },
80 {
81 .pipe_type = OVERLAY_TYPE_BF,
82 .pipe_num = OVERLAY_PIPE_VG3,
83 .pipe_ndx = 6,
84 .mixer_num = MDP4_MIXER1,
85 },
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070086 },
87};
88
89static struct mdp4_overlay_ctrl *ctrl = &mdp4_overlay_db;
kuogee hsieh9452ecb2011-08-01 18:26:23 -070090static int new_perf_level;
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -070091
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070092/* static array with index 0 for unset status and 1 for set status */
93static bool overlay_status[MDP4_OVERLAY_TYPE_MAX];
94
95void mdp4_overlay_status_write(enum mdp4_overlay_status type, bool val)
96{
97 overlay_status[type] = val;
98}
99
100bool mdp4_overlay_status_read(enum mdp4_overlay_status type)
101{
102 return overlay_status[type];
103}
104
105int mdp4_overlay_mixer_play(int mixer_num)
106{
107 if (mixer_num == MDP4_MIXER1)
108 return ctrl->mixer1_played;
109 else
110 return ctrl->mixer0_played;
111}
112
113void mdp4_overlay_panel_3d(int mixer_num, uint32 panel_3d)
114{
115 ctrl->panel_3d = panel_3d;
116}
117
118void mdp4_overlay_panel_mode(int mixer_num, uint32 mode)
119{
120 ctrl->panel_mode |= mode;
121}
122
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -0700123void mdp4_overlay_panel_mode_unset(int mixer_num, uint32 mode)
124{
125 ctrl->panel_mode &= ~mode;
126}
127
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700128uint32 mdp4_overlay_panel_list(void)
129{
130 return ctrl->panel_mode;
131}
132
133void mdp4_overlay_dmae_cfg(struct msm_fb_data_type *mfd, int atv)
134{
135 uint32 dmae_cfg_reg;
136
137 if (atv)
138 dmae_cfg_reg = DMA_DEFLKR_EN;
139 else
140 dmae_cfg_reg = 0;
141
142 if (mfd->fb_imgType == MDP_BGR_565)
143 dmae_cfg_reg |= DMA_PACK_PATTERN_BGR;
144 else
145 dmae_cfg_reg |= DMA_PACK_PATTERN_RGB;
146
147
148 if (mfd->panel_info.bpp == 18) {
149 dmae_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */
150 DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
151 } else if (mfd->panel_info.bpp == 16) {
152 dmae_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */
153 DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
154 } else {
155 dmae_cfg_reg |= DMA_DSTC0G_8BITS | /* 888 16BPP */
156 DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
157 }
158
159 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
160
161 /* dma2 config register */
162 MDP_OUTP(MDP_BASE + 0xb0000, dmae_cfg_reg);
163 if (atv) {
164 MDP_OUTP(MDP_BASE + 0xb0070, 0xeb0010);
165 MDP_OUTP(MDP_BASE + 0xb0074, 0xf00010);
166 MDP_OUTP(MDP_BASE + 0xb0078, 0xf00010);
167 MDP_OUTP(MDP_BASE + 0xb3000, 0x80);
168 MDP_OUTP(MDP_BASE + 0xb3010, 0x1800040);
169 MDP_OUTP(MDP_BASE + 0xb3014, 0x1000080);
170 MDP_OUTP(MDP_BASE + 0xb4004, 0x67686970);
171 } else {
172 MDP_OUTP(MDP_BASE + 0xb0070, 0xff0000);
173 MDP_OUTP(MDP_BASE + 0xb0074, 0xff0000);
174 MDP_OUTP(MDP_BASE + 0xb0078, 0xff0000);
175 }
176
177 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
178}
179
Manoj Raob91fa712011-06-29 09:07:55 -0700180#ifdef CONFIG_FB_MSM_HDMI_3D
181void unfill_black_screen(void) { return; }
182#else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700183void unfill_black_screen(void)
184{
185 uint32 temp_src_format;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700186 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
187 /*
188 * VG2 Constant Color
189 */
190 temp_src_format = inpdw(MDP_BASE + 0x30050);
191 MDP_OUTP(MDP_BASE + 0x30050, temp_src_format&(~BIT(22)));
192 /*
193 * MDP_OVERLAY_REG_FLUSH
194 */
195 MDP_OUTP(MDP_BASE + 0x18000, BIT(3));
196 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
Manoj Raob91fa712011-06-29 09:07:55 -0700197 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700198}
Manoj Raob91fa712011-06-29 09:07:55 -0700199#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700200
Manoj Raob91fa712011-06-29 09:07:55 -0700201#ifdef CONFIG_FB_MSM_HDMI_3D
202void fill_black_screen(void) { return; }
203#else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700204void fill_black_screen(void)
205{
206 /*Black color*/
207 uint32 color = 0x00000000;
208 uint32 temp_src_format;
209 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
210 /*
211 * VG2 Constant Color
212 */
213 MDP_OUTP(MDP_BASE + 0x31008, color);
214 /*
215 * MDP_VG2_SRC_FORMAT
216 */
217 temp_src_format = inpdw(MDP_BASE + 0x30050);
218 MDP_OUTP(MDP_BASE + 0x30050, temp_src_format | BIT(22));
219 /*
220 * MDP_OVERLAY_REG_FLUSH
221 */
222 MDP_OUTP(MDP_BASE + 0x18000, BIT(3));
223 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
Manoj Raob91fa712011-06-29 09:07:55 -0700224 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700225}
Manoj Raob91fa712011-06-29 09:07:55 -0700226#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700227
228void mdp4_overlay_dmae_xy(struct mdp4_overlay_pipe *pipe)
229{
230
231 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
232
233 /* dma_p source */
234 MDP_OUTP(MDP_BASE + 0xb0004,
235 (pipe->src_height << 16 | pipe->src_width));
236 MDP_OUTP(MDP_BASE + 0xb0008, pipe->srcp0_addr);
237 MDP_OUTP(MDP_BASE + 0xb000c, pipe->srcp0_ystride);
238
239 /* dma_p dest */
240 MDP_OUTP(MDP_BASE + 0xb0010, (pipe->dst_y << 16 | pipe->dst_x));
241
242 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
243}
244
245void mdp4_overlay_dmap_cfg(struct msm_fb_data_type *mfd, int lcdc)
246{
247 uint32 dma2_cfg_reg;
248
249 dma2_cfg_reg = DMA_DITHER_EN;
250#ifdef BLT_RGB565
251 /* RGB888 is 0 */
252 dma2_cfg_reg |= DMA_BUF_FORMAT_RGB565; /* blt only */
253#endif
254
255 if (mfd->fb_imgType == MDP_BGR_565)
256 dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
257 else
258 dma2_cfg_reg |= DMA_PACK_PATTERN_RGB;
259
260
261 if (mfd->panel_info.bpp == 18) {
262 dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 666 18BPP */
263 DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
264 } else if (mfd->panel_info.bpp == 16) {
265 dma2_cfg_reg |= DMA_DSTC0G_6BITS | /* 565 16BPP */
266 DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
267 } else {
268 dma2_cfg_reg |= DMA_DSTC0G_8BITS | /* 888 16BPP */
269 DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
270 }
271
272 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
273
274#ifndef CONFIG_FB_MSM_LCDC_CHIMEI_WXGA_PANEL
275 if (lcdc)
276 dma2_cfg_reg |= DMA_PACK_ALIGN_MSB;
277#endif
278
279 /* dma2 config register */
280 MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg);
281
282 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
283}
284
285/*
286 * mdp4_overlay_dmap_xy: called form baselayer only
287 */
288void mdp4_overlay_dmap_xy(struct mdp4_overlay_pipe *pipe)
289{
290 uint32 off, bpp;
291
292 if (mdp_is_in_isr == FALSE)
293 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
294
295 /* dma_p source */
296 MDP_OUTP(MDP_BASE + 0x90004,
297 (pipe->src_height << 16 | pipe->src_width));
298 if (pipe->blt_addr) {
299#ifdef BLT_RGB565
300 bpp = 2; /* overlay ouput is RGB565 */
301#else
302 bpp = 3; /* overlay ouput is RGB888 */
303#endif
304 off = 0;
305 if (pipe->dmap_cnt & 0x01)
306 off = pipe->src_height * pipe->src_width * bpp;
307 MDP_OUTP(MDP_BASE + 0x90008, pipe->blt_addr + off);
308 /* RGB888, output of overlay blending */
309 MDP_OUTP(MDP_BASE + 0x9000c, pipe->src_width * bpp);
310 } else {
311 MDP_OUTP(MDP_BASE + 0x90008, pipe->srcp0_addr);
312 MDP_OUTP(MDP_BASE + 0x9000c, pipe->srcp0_ystride);
313 }
314
315 /* dma_p dest */
316 MDP_OUTP(MDP_BASE + 0x90010, (pipe->dst_y << 16 | pipe->dst_x));
317
318 if (mdp_is_in_isr == FALSE)
319 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
320}
321
322#define MDP4_VG_PHASE_STEP_DEFAULT 0x20000000
323#define MDP4_VG_PHASE_STEP_SHIFT 29
324
325static int mdp4_leading_0(uint32 num)
326{
327 uint32 bit = 0x80000000;
328 int i;
329
330 for (i = 0; i < 32; i++) {
331 if (bit & num)
332 return i;
333 bit >>= 1;
334 }
335
336 return i;
337}
338
339static uint32 mdp4_scale_phase_step(int f_num, uint32 src, uint32 dst)
340{
341 uint32 val;
342 int n;
343
344 n = mdp4_leading_0(src);
345 if (n > f_num)
346 n = f_num;
347 val = src << n; /* maximum to reduce lose of resolution */
348 val /= dst;
349 if (n < f_num) {
350 n = f_num - n;
351 val <<= n;
352 }
353
354 return val;
355}
356
357static void mdp4_scale_setup(struct mdp4_overlay_pipe *pipe)
358{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700359 pipe->phasex_step = MDP4_VG_PHASE_STEP_DEFAULT;
360 pipe->phasey_step = MDP4_VG_PHASE_STEP_DEFAULT;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700361
362 if (pipe->dst_h && pipe->src_h != pipe->dst_h) {
363 if (pipe->dst_h > pipe->src_h * 8) /* too much */
364 return;
365 pipe->op_mode |= MDP4_OP_SCALEY_EN;
366
367 if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -0700368 if (pipe->alpha_enable)
369 pipe->op_mode |= MDP4_OP_SCALEY_PIXEL_RPT;
370 else if (pipe->dst_h <= (pipe->src_h / 4))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700371 pipe->op_mode |= MDP4_OP_SCALEY_MN_PHASE;
372 else
373 pipe->op_mode |= MDP4_OP_SCALEY_FIR;
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -0700374 } else { /* RGB pipe */
375 pipe->op_mode |= MDP4_OP_SCALE_RGB_BILINEAR;
376 pipe->op_mode |= MDP4_OP_SCALE_ALPHA_BILINEAR;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700377 }
378
379 pipe->phasey_step = mdp4_scale_phase_step(29,
380 pipe->src_h, pipe->dst_h);
381 }
382
383 if (pipe->dst_w && pipe->src_w != pipe->dst_w) {
384 if (pipe->dst_w > pipe->src_w * 8) /* too much */
385 return;
386 pipe->op_mode |= MDP4_OP_SCALEX_EN;
387
388 if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -0700389 if (pipe->alpha_enable)
390 pipe->op_mode |= MDP4_OP_SCALEX_PIXEL_RPT;
391 else if (pipe->dst_w <= (pipe->src_w / 4))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700392 pipe->op_mode |= MDP4_OP_SCALEX_MN_PHASE;
393 else
394 pipe->op_mode |= MDP4_OP_SCALEX_FIR;
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -0700395 } else { /* RGB pipe */
396 pipe->op_mode |= MDP4_OP_SCALE_RGB_BILINEAR;
397 pipe->op_mode |= MDP4_OP_SCALE_ALPHA_BILINEAR;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700398 }
399
400 pipe->phasex_step = mdp4_scale_phase_step(29,
401 pipe->src_w, pipe->dst_w);
402 }
403}
404
405void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe)
406{
407 char *rgb_base;
408 uint32 src_size, src_xy, dst_size, dst_xy;
409 uint32 format, pattern;
410
411 rgb_base = MDP_BASE + MDP4_RGB_BASE;
412 rgb_base += (MDP4_RGB_OFF * pipe->pipe_num);
413
414 src_size = ((pipe->src_h << 16) | pipe->src_w);
415 src_xy = ((pipe->src_y << 16) | pipe->src_x);
416 dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
417 dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
418
419 format = mdp4_overlay_format(pipe);
420 pattern = mdp4_overlay_unpack_pattern(pipe);
421
422#ifdef MDP4_IGC_LUT_ENABLE
423 pipe->op_mode |= MDP4_OP_IGC_LUT_EN;
424#endif
425
426 mdp4_scale_setup(pipe);
427
428 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
429
430 outpdw(rgb_base + 0x0000, src_size); /* MDP_RGB_SRC_SIZE */
431 outpdw(rgb_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */
432 outpdw(rgb_base + 0x0008, dst_size); /* MDP_RGB_DST_SIZE */
433 outpdw(rgb_base + 0x000c, dst_xy); /* MDP_RGB_DST_XY */
434
435 outpdw(rgb_base + 0x0010, pipe->srcp0_addr);
436 outpdw(rgb_base + 0x0040, pipe->srcp0_ystride);
437
438 outpdw(rgb_base + 0x0050, format);/* MDP_RGB_SRC_FORMAT */
439 outpdw(rgb_base + 0x0054, pattern);/* MDP_RGB_SRC_UNPACK_PATTERN */
440 outpdw(rgb_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */
441 outpdw(rgb_base + 0x005c, pipe->phasex_step);
442 outpdw(rgb_base + 0x0060, pipe->phasey_step);
443
444 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
445
446 mdp4_stat.pipe[pipe->pipe_num]++;
447}
448
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700449
450static void mdp4_overlay_vg_get_src_offset(struct mdp4_overlay_pipe *pipe,
451 char *vg_base, uint32 *luma_off, uint32 *chroma_off)
452{
453 uint32 src_xy;
454 *luma_off = 0;
455 *chroma_off = 0;
456
Nagamalleswararao Ganji1c8fc4a2011-10-10 20:51:31 -0700457 if (pipe->src_x && (pipe->frame_format ==
458 MDP4_FRAME_FORMAT_LINEAR)) {
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700459 src_xy = (pipe->src_y << 16) | pipe->src_x;
460 src_xy &= 0xffff0000;
461 outpdw(vg_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */
462
463 switch (pipe->src_format) {
464 case MDP_Y_CR_CB_H2V2:
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +0530465 case MDP_Y_CR_CB_GH2V2:
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700466 case MDP_Y_CB_CR_H2V2:
467 *luma_off = pipe->src_x;
468 *chroma_off = pipe->src_x/2;
469 break;
470
471 case MDP_Y_CBCR_H2V2_TILE:
472 case MDP_Y_CRCB_H2V2_TILE:
473 case MDP_Y_CBCR_H2V2:
474 case MDP_Y_CRCB_H2V2:
475 case MDP_Y_CRCB_H1V1:
476 case MDP_Y_CBCR_H1V1:
477 case MDP_Y_CRCB_H2V1:
478 case MDP_Y_CBCR_H2V1:
479 *luma_off = pipe->src_x;
480 *chroma_off = pipe->src_x;
481 break;
482
483 case MDP_YCRYCB_H2V1:
484 if (pipe->src_x & 0x1)
485 pipe->src_x += 1;
486 *luma_off += pipe->src_x * 2;
487 break;
488
489 case MDP_ARGB_8888:
490 case MDP_RGBA_8888:
491 case MDP_BGRA_8888:
492 case MDP_RGBX_8888:
493 case MDP_RGB_565:
494 case MDP_BGR_565:
495 case MDP_XRGB_8888:
496 case MDP_RGB_888:
497 *luma_off = pipe->src_x * pipe->bpp;
498 break;
499
500 default:
501 pr_err("Source format %u not supported for x offset adjustment\n",
502 pipe->src_format);
503 break;
504 }
505 }
506}
507
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700508void mdp4_overlay_vg_setup(struct mdp4_overlay_pipe *pipe)
509{
510 char *vg_base;
511 uint32 frame_size, src_size, src_xy, dst_size, dst_xy;
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700512 uint32 format, pattern, luma_offset, chroma_offset;
kuogee hsieh4b910f22011-11-15 09:43:04 -0800513 uint32 mask;
kuogee hsiehe1ed1ae2011-09-02 08:53:36 -0700514 int pnum, ptype;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700515
516 pnum = pipe->pipe_num - OVERLAY_PIPE_VG1; /* start from 0 */
517 vg_base = MDP_BASE + MDP4_VIDEO_BASE;
518 vg_base += (MDP4_VIDEO_OFF * pnum);
519
520 frame_size = ((pipe->src_height << 16) | pipe->src_width);
521 src_size = ((pipe->src_h << 16) | pipe->src_w);
522 src_xy = ((pipe->src_y << 16) | pipe->src_x);
523 dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
524 dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
525
kuogee hsiehe1ed1ae2011-09-02 08:53:36 -0700526 ptype = mdp4_overlay_format2type(pipe->src_format);
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +0530527 if (pipe->src_format == MDP_Y_CR_CB_GH2V2) {
528 frame_size = ((pipe->src_height << 16) |
529 ALIGN(pipe->src_width, 16));
530 src_size = ((pipe->src_h << 16) | ALIGN(pipe->src_w, 16));
531 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700532 format = mdp4_overlay_format(pipe);
533 pattern = mdp4_overlay_unpack_pattern(pipe);
534
535 /* not RGB use VG pipe, pure VG pipe */
kuogee hsiehe1ed1ae2011-09-02 08:53:36 -0700536 if (ptype != OVERLAY_TYPE_RGB)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700537 pipe->op_mode |= (MDP4_OP_CSC_EN | MDP4_OP_SRC_DATA_YCBCR);
kuogee hsiehe1ed1ae2011-09-02 08:53:36 -0700538
539#ifdef MDP4_IGC_LUT_ENABLE
540 pipe->op_mode |= MDP4_OP_IGC_LUT_EN;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700541#endif
542
543 mdp4_scale_setup(pipe);
544
545 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
546
547 outpdw(vg_base + 0x0000, src_size); /* MDP_RGB_SRC_SIZE */
548 outpdw(vg_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */
549 outpdw(vg_base + 0x0008, dst_size); /* MDP_RGB_DST_SIZE */
550 outpdw(vg_base + 0x000c, dst_xy); /* MDP_RGB_DST_XY */
Nagamalleswararao Ganjic6ecb832011-09-14 10:00:18 -0700551
Nagamalleswararao Ganji1c8fc4a2011-10-10 20:51:31 -0700552 if (pipe->frame_format != MDP4_FRAME_FORMAT_LINEAR)
Nagamalleswararao Ganjic6ecb832011-09-14 10:00:18 -0700553 outpdw(vg_base + 0x0048, frame_size); /* TILE frame size */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700554
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700555 /*
556 * Adjust src X offset to avoid MDP from overfetching pixels
557 * present before the offset. This is required for video
558 * frames coming with unused green pixels along the left margin
559 */
kuogee hsiehe1ed1ae2011-09-02 08:53:36 -0700560 /* not RGB use VG pipe, pure VG pipe */
561 if (ptype != OVERLAY_TYPE_RGB) {
562 mdp4_overlay_vg_get_src_offset(pipe, vg_base, &luma_offset,
563 &chroma_offset);
564 } else {
565 luma_offset = 0;
566 chroma_offset = 0;
567 }
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700568
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700569 /* luma component plane */
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700570 outpdw(vg_base + 0x0010, pipe->srcp0_addr + luma_offset);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700571
572 /* chroma component plane or planar color 1 */
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700573 outpdw(vg_base + 0x0014, pipe->srcp1_addr + chroma_offset);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700574
575 /* planar color 2 */
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700576 outpdw(vg_base + 0x0018, pipe->srcp2_addr + chroma_offset);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700577
578 outpdw(vg_base + 0x0040,
579 pipe->srcp1_ystride << 16 | pipe->srcp0_ystride);
580
581 outpdw(vg_base + 0x0044,
582 pipe->srcp3_ystride << 16 | pipe->srcp2_ystride);
583
584 outpdw(vg_base + 0x0050, format); /* MDP_RGB_SRC_FORMAT */
585 outpdw(vg_base + 0x0054, pattern); /* MDP_RGB_SRC_UNPACK_PATTERN */
586 outpdw(vg_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */
587 outpdw(vg_base + 0x005c, pipe->phasex_step);
588 outpdw(vg_base + 0x0060, pipe->phasey_step);
589
590 if (pipe->op_mode & MDP4_OP_DITHER_EN) {
591 outpdw(vg_base + 0x0068,
592 pipe->r_bit << 4 | pipe->b_bit << 2 | pipe->g_bit);
593 }
594
595 if (pipe->flags & MDP_SHARPENING) {
596 outpdw(vg_base + 0x8200,
597 mdp4_ss_table_value(pipe->req_data.dpp.sharp_strength,
598 0));
599 outpdw(vg_base + 0x8204,
600 mdp4_ss_table_value(pipe->req_data.dpp.sharp_strength,
601 1));
602 }
603
kuogee hsieh4b910f22011-11-15 09:43:04 -0800604 if (mdp_rev > MDP_REV_41) {
605 /* mdp chip select controller */
606 mask = 0;
607 if (pipe->pipe_num == OVERLAY_PIPE_VG1)
608 mask = 0x020; /* bit 5 */
609 else if (pipe->pipe_num == OVERLAY_PIPE_VG2)
610 mask = 0x02000; /* bit 13 */
611 if (mask) {
612 if (pipe->op_mode & MDP4_OP_SCALEY_MN_PHASE)
613 ctrl->cs_controller &= ~mask;
614 else
615 ctrl->cs_controller |= mask;
616 /* NOT double buffered */
617 outpdw(MDP_BASE + 0x00c0, ctrl->cs_controller);
618 }
619 }
620
621
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700622 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
623
624 mdp4_stat.pipe[pipe->pipe_num]++;
625}
626
627int mdp4_overlay_format2type(uint32 format)
628{
629 switch (format) {
630 case MDP_RGB_565:
631 case MDP_RGB_888:
632 case MDP_BGR_565:
633 case MDP_XRGB_8888:
634 case MDP_ARGB_8888:
635 case MDP_RGBA_8888:
636 case MDP_BGRA_8888:
637 case MDP_RGBX_8888:
638 return OVERLAY_TYPE_RGB;
639 case MDP_YCRYCB_H2V1:
640 case MDP_Y_CRCB_H2V1:
641 case MDP_Y_CBCR_H2V1:
642 case MDP_Y_CRCB_H2V2:
643 case MDP_Y_CBCR_H2V2:
644 case MDP_Y_CBCR_H2V2_TILE:
645 case MDP_Y_CRCB_H2V2_TILE:
646 case MDP_Y_CR_CB_H2V2:
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +0530647 case MDP_Y_CR_CB_GH2V2:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700648 case MDP_Y_CB_CR_H2V2:
649 case MDP_Y_CRCB_H1V1:
650 case MDP_Y_CBCR_H1V1:
651 return OVERLAY_TYPE_VIDEO;
652 default:
653 mdp4_stat.err_format++;
654 return -ERANGE;
655 }
656
657}
658
659#define C3_ALPHA 3 /* alpha */
660#define C2_R_Cr 2 /* R/Cr */
661#define C1_B_Cb 1 /* B/Cb */
662#define C0_G_Y 0 /* G/luma */
663#define YUV_444_MAX_WIDTH 1280 /* Max width for YUV 444*/
664
665int mdp4_overlay_format2pipe(struct mdp4_overlay_pipe *pipe)
666{
667 switch (pipe->src_format) {
668 case MDP_RGB_565:
669 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
670 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
671 pipe->a_bit = 0;
672 pipe->r_bit = 1; /* R, 5 bits */
673 pipe->b_bit = 1; /* B, 5 bits */
674 pipe->g_bit = 2; /* G, 6 bits */
675 pipe->alpha_enable = 0;
676 pipe->unpack_tight = 1;
677 pipe->unpack_align_msb = 0;
678 pipe->unpack_count = 2;
679 pipe->element2 = C2_R_Cr; /* R */
680 pipe->element1 = C0_G_Y; /* G */
681 pipe->element0 = C1_B_Cb; /* B */
682 pipe->bpp = 2; /* 2 bpp */
683 break;
684 case MDP_RGB_888:
685 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
686 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
687 pipe->a_bit = 0;
688 pipe->r_bit = 3; /* R, 8 bits */
689 pipe->b_bit = 3; /* B, 8 bits */
690 pipe->g_bit = 3; /* G, 8 bits */
691 pipe->alpha_enable = 0;
692 pipe->unpack_tight = 1;
693 pipe->unpack_align_msb = 0;
694 pipe->unpack_count = 2;
695 pipe->element2 = C2_R_Cr; /* R */
696 pipe->element1 = C0_G_Y; /* G */
697 pipe->element0 = C1_B_Cb; /* B */
698 pipe->bpp = 3; /* 3 bpp */
699 break;
700 case MDP_BGR_565:
701 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
702 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
703 pipe->a_bit = 0;
704 pipe->r_bit = 1; /* R, 5 bits */
705 pipe->b_bit = 1; /* B, 5 bits */
706 pipe->g_bit = 2; /* G, 6 bits */
707 pipe->alpha_enable = 0;
708 pipe->unpack_tight = 1;
709 pipe->unpack_align_msb = 0;
710 pipe->unpack_count = 2;
711 pipe->element2 = C1_B_Cb; /* B */
712 pipe->element1 = C0_G_Y; /* G */
713 pipe->element0 = C2_R_Cr; /* R */
714 pipe->bpp = 2; /* 2 bpp */
715 break;
716 case MDP_XRGB_8888:
717 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
718 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
719 pipe->a_bit = 3; /* alpha, 4 bits */
720 pipe->r_bit = 3; /* R, 8 bits */
721 pipe->b_bit = 3; /* B, 8 bits */
722 pipe->g_bit = 3; /* G, 8 bits */
723 pipe->alpha_enable = 0;
724 pipe->unpack_tight = 1;
725 pipe->unpack_align_msb = 0;
726 pipe->unpack_count = 3;
727 pipe->element3 = C3_ALPHA; /* alpha */
728 pipe->element2 = C2_R_Cr; /* R */
729 pipe->element1 = C0_G_Y; /* G */
730 pipe->element0 = C1_B_Cb; /* B */
731 pipe->bpp = 4; /* 4 bpp */
732 break;
733 case MDP_ARGB_8888:
734 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
735 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
736 pipe->a_bit = 3; /* alpha, 4 bits */
737 pipe->r_bit = 3; /* R, 8 bits */
738 pipe->b_bit = 3; /* B, 8 bits */
739 pipe->g_bit = 3; /* G, 8 bits */
740 pipe->alpha_enable = 1;
741 pipe->unpack_tight = 1;
742 pipe->unpack_align_msb = 0;
743 pipe->unpack_count = 3;
744 pipe->element3 = C3_ALPHA; /* alpha */
745 pipe->element2 = C2_R_Cr; /* R */
746 pipe->element1 = C0_G_Y; /* G */
747 pipe->element0 = C1_B_Cb; /* B */
748 pipe->bpp = 4; /* 4 bpp */
749 break;
750 case MDP_RGBA_8888:
751 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
752 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
753 pipe->a_bit = 3; /* alpha, 4 bits */
754 pipe->r_bit = 3; /* R, 8 bits */
755 pipe->b_bit = 3; /* B, 8 bits */
756 pipe->g_bit = 3; /* G, 8 bits */
757 pipe->alpha_enable = 1;
758 pipe->unpack_tight = 1;
759 pipe->unpack_align_msb = 0;
760 pipe->unpack_count = 3;
761 pipe->element3 = C3_ALPHA; /* alpha */
762 pipe->element2 = C1_B_Cb; /* B */
763 pipe->element1 = C0_G_Y; /* G */
764 pipe->element0 = C2_R_Cr; /* R */
765 pipe->bpp = 4; /* 4 bpp */
766 break;
767 case MDP_RGBX_8888:
768 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
769 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
770 pipe->a_bit = 3;
771 pipe->r_bit = 3; /* R, 8 bits */
772 pipe->b_bit = 3; /* B, 8 bits */
773 pipe->g_bit = 3; /* G, 8 bits */
774 pipe->alpha_enable = 0;
775 pipe->unpack_tight = 1;
776 pipe->unpack_align_msb = 0;
777 pipe->unpack_count = 3;
778 pipe->element3 = C3_ALPHA; /* alpha */
779 pipe->element2 = C1_B_Cb; /* B */
780 pipe->element1 = C0_G_Y; /* G */
781 pipe->element0 = C2_R_Cr; /* R */
782 pipe->bpp = 4; /* 4 bpp */
783 break;
784 case MDP_BGRA_8888:
785 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
786 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
787 pipe->a_bit = 3; /* alpha, 4 bits */
788 pipe->r_bit = 3; /* R, 8 bits */
789 pipe->b_bit = 3; /* B, 8 bits */
790 pipe->g_bit = 3; /* G, 8 bits */
791 pipe->alpha_enable = 1;
792 pipe->unpack_tight = 1;
793 pipe->unpack_align_msb = 0;
794 pipe->unpack_count = 3;
795 pipe->element3 = C3_ALPHA; /* alpha */
796 pipe->element2 = C2_R_Cr; /* R */
797 pipe->element1 = C0_G_Y; /* G */
798 pipe->element0 = C1_B_Cb; /* B */
799 pipe->bpp = 4; /* 4 bpp */
800 break;
801 case MDP_YCRYCB_H2V1:
802 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
803 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
804 pipe->a_bit = 0; /* alpha, 4 bits */
805 pipe->r_bit = 3; /* R, 8 bits */
806 pipe->b_bit = 3; /* B, 8 bits */
807 pipe->g_bit = 3; /* G, 8 bits */
808 pipe->alpha_enable = 0;
809 pipe->unpack_tight = 1;
810 pipe->unpack_align_msb = 0;
811 pipe->unpack_count = 3;
812 pipe->element3 = C0_G_Y; /* G */
813 pipe->element2 = C2_R_Cr; /* R */
814 pipe->element1 = C0_G_Y; /* G */
815 pipe->element0 = C1_B_Cb; /* B */
816 pipe->bpp = 2; /* 2 bpp */
817 pipe->chroma_sample = MDP4_CHROMA_H2V1;
818 break;
819 case MDP_Y_CRCB_H2V1:
820 case MDP_Y_CBCR_H2V1:
821 case MDP_Y_CRCB_H2V2:
822 case MDP_Y_CBCR_H2V2:
823 case MDP_Y_CRCB_H1V1:
824 case MDP_Y_CBCR_H1V1:
825 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
826 pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_PLANAR;
827 pipe->a_bit = 0;
828 pipe->r_bit = 3; /* R, 8 bits */
829 pipe->b_bit = 3; /* B, 8 bits */
830 pipe->g_bit = 3; /* G, 8 bits */
831 pipe->alpha_enable = 0;
832 pipe->unpack_tight = 1;
833 pipe->unpack_align_msb = 0;
834 pipe->unpack_count = 1; /* 2 */
835 pipe->element3 = C0_G_Y; /* not used */
836 pipe->element2 = C0_G_Y; /* not used */
837 if (pipe->src_format == MDP_Y_CRCB_H2V1) {
838 pipe->element1 = C2_R_Cr; /* R */
839 pipe->element0 = C1_B_Cb; /* B */
840 pipe->chroma_sample = MDP4_CHROMA_H2V1;
841 } else if (pipe->src_format == MDP_Y_CRCB_H1V1) {
842 pipe->element1 = C2_R_Cr; /* R */
843 pipe->element0 = C1_B_Cb; /* B */
844 if (pipe->src_width > YUV_444_MAX_WIDTH)
845 pipe->chroma_sample = MDP4_CHROMA_H1V2;
846 else
847 pipe->chroma_sample = MDP4_CHROMA_RGB;
848 } else if (pipe->src_format == MDP_Y_CBCR_H2V1) {
849 pipe->element1 = C1_B_Cb; /* B */
850 pipe->element0 = C2_R_Cr; /* R */
851 pipe->chroma_sample = MDP4_CHROMA_H2V1;
852 } else if (pipe->src_format == MDP_Y_CBCR_H1V1) {
853 pipe->element1 = C1_B_Cb; /* B */
854 pipe->element0 = C2_R_Cr; /* R */
855 if (pipe->src_width > YUV_444_MAX_WIDTH)
856 pipe->chroma_sample = MDP4_CHROMA_H1V2;
857 else
858 pipe->chroma_sample = MDP4_CHROMA_RGB;
859 } else if (pipe->src_format == MDP_Y_CRCB_H2V2) {
860 pipe->element1 = C2_R_Cr; /* R */
861 pipe->element0 = C1_B_Cb; /* B */
862 pipe->chroma_sample = MDP4_CHROMA_420;
863 } else if (pipe->src_format == MDP_Y_CBCR_H2V2) {
864 pipe->element1 = C1_B_Cb; /* B */
865 pipe->element0 = C2_R_Cr; /* R */
866 pipe->chroma_sample = MDP4_CHROMA_420;
867 }
868 pipe->bpp = 2; /* 2 bpp */
869 break;
870 case MDP_Y_CBCR_H2V2_TILE:
871 case MDP_Y_CRCB_H2V2_TILE:
872 pipe->frame_format = MDP4_FRAME_FORMAT_VIDEO_SUPERTILE;
873 pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_PLANAR;
874 pipe->a_bit = 0;
875 pipe->r_bit = 3; /* R, 8 bits */
876 pipe->b_bit = 3; /* B, 8 bits */
877 pipe->g_bit = 3; /* G, 8 bits */
878 pipe->alpha_enable = 0;
879 pipe->unpack_tight = 1;
880 pipe->unpack_align_msb = 0;
881 pipe->unpack_count = 1; /* 2 */
882 pipe->element3 = C0_G_Y; /* not used */
883 pipe->element2 = C0_G_Y; /* not used */
884 if (pipe->src_format == MDP_Y_CRCB_H2V2_TILE) {
885 pipe->element1 = C2_R_Cr; /* R */
886 pipe->element0 = C1_B_Cb; /* B */
887 pipe->chroma_sample = MDP4_CHROMA_420;
888 } else if (pipe->src_format == MDP_Y_CBCR_H2V2_TILE) {
889 pipe->element1 = C1_B_Cb; /* B */
890 pipe->element0 = C2_R_Cr; /* R */
891 pipe->chroma_sample = MDP4_CHROMA_420;
892 }
893 pipe->bpp = 2; /* 2 bpp */
894 break;
895 case MDP_Y_CR_CB_H2V2:
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +0530896 case MDP_Y_CR_CB_GH2V2:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700897 case MDP_Y_CB_CR_H2V2:
898 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
899 pipe->fetch_plane = OVERLAY_PLANE_PLANAR;
900 pipe->a_bit = 0;
901 pipe->r_bit = 3; /* R, 8 bits */
902 pipe->b_bit = 3; /* B, 8 bits */
903 pipe->g_bit = 3; /* G, 8 bits */
904 pipe->alpha_enable = 0;
Adrian Salido-Moreno33dc7b92011-08-18 16:16:12 -0700905 pipe->chroma_sample = MDP4_CHROMA_420;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700906 pipe->bpp = 2; /* 2 bpp */
907 break;
908 default:
909 /* not likely */
910 mdp4_stat.err_format++;
911 return -ERANGE;
912 }
913
914 return 0;
915}
916
917/*
918 * color_key_convert: output with 12 bits color key
919 */
920static uint32 color_key_convert(int start, int num, uint32 color)
921{
922 uint32 data;
923
924 data = (color >> start) & ((1 << num) - 1);
925
926 /* convert to 8 bits */
927 if (num == 5)
928 data = ((data << 3) | (data >> 2));
929 else if (num == 6)
930 data = ((data << 2) | (data >> 4));
931
932 /* convert 8 bits to 12 bits */
933 data = (data << 4) | (data >> 4);
934
935 return data;
936}
937
938void transp_color_key(int format, uint32 transp,
939 uint32 *c0, uint32 *c1, uint32 *c2)
940{
941 int b_start, g_start, r_start;
942 int b_num, g_num, r_num;
943
944 switch (format) {
945 case MDP_RGB_565:
946 b_start = 0;
947 g_start = 5;
948 r_start = 11;
949 r_num = 5;
950 g_num = 6;
951 b_num = 5;
952 break;
953 case MDP_RGB_888:
954 case MDP_XRGB_8888:
955 case MDP_ARGB_8888:
956 case MDP_BGRA_8888:
957 b_start = 0;
958 g_start = 8;
959 r_start = 16;
960 r_num = 8;
961 g_num = 8;
962 b_num = 8;
963 break;
964 case MDP_RGBA_8888:
965 case MDP_RGBX_8888:
966 b_start = 16;
967 g_start = 8;
968 r_start = 0;
969 r_num = 8;
970 g_num = 8;
971 b_num = 8;
972 break;
973 case MDP_BGR_565:
974 b_start = 11;
975 g_start = 5;
976 r_start = 0;
977 r_num = 5;
978 g_num = 6;
979 b_num = 5;
980 break;
981 case MDP_Y_CB_CR_H2V2:
982 case MDP_Y_CBCR_H2V2:
983 case MDP_Y_CBCR_H2V1:
984 b_start = 8;
985 g_start = 16;
986 r_start = 0;
987 r_num = 8;
988 g_num = 8;
989 b_num = 8;
990 break;
991 case MDP_Y_CR_CB_H2V2:
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +0530992 case MDP_Y_CR_CB_GH2V2:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700993 case MDP_Y_CRCB_H2V2:
994 case MDP_Y_CRCB_H2V1:
995 case MDP_Y_CRCB_H1V1:
996 case MDP_Y_CBCR_H1V1:
997 b_start = 0;
998 g_start = 16;
999 r_start = 8;
1000 r_num = 8;
1001 g_num = 8;
1002 b_num = 8;
1003 break;
1004 default:
1005 b_start = 0;
1006 g_start = 8;
1007 r_start = 16;
1008 r_num = 8;
1009 g_num = 8;
1010 b_num = 8;
1011 break;
1012 }
1013
1014 *c0 = color_key_convert(g_start, g_num, transp);
1015 *c1 = color_key_convert(b_start, b_num, transp);
1016 *c2 = color_key_convert(r_start, r_num, transp);
1017}
1018
1019uint32 mdp4_overlay_format(struct mdp4_overlay_pipe *pipe)
1020{
1021 uint32 format;
1022
1023 format = 0;
1024
1025 if (pipe->solid_fill)
1026 format |= MDP4_FORMAT_SOLID_FILL;
1027
1028 if (pipe->unpack_align_msb)
1029 format |= MDP4_FORMAT_UNPACK_ALIGN_MSB;
1030
1031 if (pipe->unpack_tight)
1032 format |= MDP4_FORMAT_UNPACK_TIGHT;
1033
1034 if (pipe->alpha_enable)
1035 format |= MDP4_FORMAT_ALPHA_ENABLE;
1036
1037 if (pipe->flags & MDP_SOURCE_ROTATED_90)
1038 format |= MDP4_FORMAT_90_ROTATED;
1039 format |= (pipe->unpack_count << 13);
1040 format |= ((pipe->bpp - 1) << 9);
1041 format |= (pipe->a_bit << 6);
1042 format |= (pipe->r_bit << 4);
1043 format |= (pipe->b_bit << 2);
1044 format |= pipe->g_bit;
1045
1046 format |= (pipe->frame_format << 29);
1047
1048 if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR ||
1049 pipe->fetch_plane == OVERLAY_PLANE_PLANAR) {
1050 /* video/graphic */
1051 format |= (pipe->fetch_plane << 19);
1052 format |= (pipe->chroma_site << 28);
1053 format |= (pipe->chroma_sample << 26);
1054 }
1055
1056 return format;
1057}
1058
1059uint32 mdp4_overlay_unpack_pattern(struct mdp4_overlay_pipe *pipe)
1060{
1061 return (pipe->element3 << 24) | (pipe->element2 << 16) |
1062 (pipe->element1 << 8) | pipe->element0;
1063}
1064
1065/*
1066 * mdp4_overlayproc_cfg: only be called from base layer
1067 */
1068void mdp4_overlayproc_cfg(struct mdp4_overlay_pipe *pipe)
1069{
1070 uint32 data, intf;
1071 char *overlay_base;
1072
1073 intf = 0;
1074 if (pipe->mixer_num == MDP4_MIXER1) {
1075 overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
1076 intf = inpdw(MDP_BASE + 0x0038); /* MDP_DISP_INTF_SEL */
1077 intf >>= 4;
1078 intf &= 0x03;
1079 } else
1080 overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
1081
1082 if (mdp_is_in_isr == FALSE)
1083 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1084
1085 /*
1086 * BLT only siupport at primary display
1087 */
Vinay Kalia27020d12011-10-14 17:50:29 -07001088 if (pipe->blt_addr) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001089 int off, bpp;
1090#ifdef BLT_RGB565
1091 bpp = 2; /* overlay ouput is RGB565 */
1092#else
1093 bpp = 3; /* overlay ouput is RGB888 */
1094#endif
1095 data = pipe->src_height;
1096 data <<= 16;
1097 data |= pipe->src_width;
1098 outpdw(overlay_base + 0x0008, data); /* ROI, height + width */
Vinay Kalia27020d12011-10-14 17:50:29 -07001099 if (pipe->mixer_num == MDP4_MIXER0) {
1100 off = 0;
1101 if (pipe->ov_cnt & 0x01)
1102 off = pipe->src_height * pipe->src_width * bpp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001103
Vinay Kalia27020d12011-10-14 17:50:29 -07001104 outpdw(overlay_base + 0x000c, pipe->blt_addr + off);
1105 /* overlay ouput is RGB888 */
1106 outpdw(overlay_base + 0x0010, pipe->src_width * bpp);
1107 outpdw(overlay_base + 0x001c, pipe->blt_addr + off);
1108 /* MDDI - BLT + on demand */
1109 outpdw(overlay_base + 0x0004, 0x08);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001110#ifdef BLT_RGB565
Vinay Kalia27020d12011-10-14 17:50:29 -07001111 outpdw(overlay_base + 0x0014, 0x1); /* RGB565 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001112#else
Vinay Kalia27020d12011-10-14 17:50:29 -07001113 outpdw(overlay_base + 0x0014, 0x0); /* RGB888 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001114#endif
Vinay Kalia27020d12011-10-14 17:50:29 -07001115 } else {
1116 if (ctrl->panel_mode & MDP4_PANEL_WRITEBACK) {
1117 off = 0;
1118 bpp = 2;
1119 if (pipe->ov_cnt & 0x01)
1120 off = pipe->src_height *
1121 pipe->src_width * bpp;
1122
1123 outpdw(overlay_base + 0x000c,
1124 pipe->blt_addr + off);
1125 /* overlay ouput is RGB888 */
1126 outpdw(overlay_base + 0x0010,
1127 pipe->src_width * bpp);
1128 outpdw(overlay_base + 0x001c,
1129 pipe->blt_addr + off);
1130 /* MDDI - BLT + on demand */
1131 outpdw(overlay_base + 0x0004, 0x08);
1132 outpdw(overlay_base + 0x0014, 0x1); /* RGB565 */
1133 }
1134 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001135 } else {
1136 data = pipe->src_height;
1137 data <<= 16;
1138 data |= pipe->src_width;
1139 outpdw(overlay_base + 0x0008, data); /* ROI, height + width */
1140 outpdw(overlay_base + 0x000c, pipe->srcp0_addr);
1141 outpdw(overlay_base + 0x0010, pipe->srcp0_ystride);
1142 outpdw(overlay_base + 0x0004, 0x01); /* directout */
1143 }
1144
1145 if (pipe->mixer_num == MDP4_MIXER1) {
1146 if (intf == TV_INTF) {
1147 outpdw(overlay_base + 0x0014, 0x02); /* yuv422 */
1148 /* overlay1 CSC config */
1149 outpdw(overlay_base + 0x0200, 0x05); /* rgb->yuv */
1150 }
1151 }
1152
1153#ifdef MDP4_IGC_LUT_ENABLE
1154 outpdw(overlay_base + 0x0014, 0x4); /* GC_LUT_EN, 888 */
1155#endif
1156
1157 if (mdp_is_in_isr == FALSE)
1158 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1159}
1160
1161int mdp4_overlay_pipe_staged(int mixer)
1162{
1163 uint32 data, mask, i;
1164 int p1, p2;
1165
1166 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1167 data = inpdw(MDP_BASE + 0x10100);
1168 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1169 p1 = 0;
1170 p2 = 0;
1171 for (i = 0; i < 8; i++) {
1172 mask = data & 0x0f;
1173 if (mask) {
1174 if (mask <= 4)
1175 p1++;
1176 else
1177 p2++;
1178 }
1179 data >>= 4;
1180 }
1181
1182 if (mixer)
1183 return p2;
1184 else
1185 return p1;
1186}
1187
kuogee hsieh405dc302011-07-21 15:06:59 -07001188int mdp4_mixer_info(int mixer_num, struct mdp_mixer_info *info)
1189{
1190
1191 int ndx, cnt;
1192 struct mdp4_overlay_pipe *pipe;
1193
1194 if (mixer_num > MDP4_MIXER_MAX)
1195 return -ENODEV;
1196
1197 cnt = 0;
1198 ndx = 1; /* ndx 0 if not used */
1199
1200 for ( ; ndx < MDP4_MIXER_STAGE_MAX; ndx++) {
1201 pipe = ctrl->stage[mixer_num][ndx];
1202 if (pipe == NULL)
1203 continue;
1204 info->z_order = pipe->mixer_stage - MDP4_MIXER_STAGE0;
1205 info->ptype = pipe->pipe_type;
1206 info->pnum = pipe->pipe_num;
1207 info->pndx = pipe->pipe_ndx;
1208 info->mixer_num = pipe->mixer_num;
1209 info++;
1210 cnt++;
1211 }
1212 return cnt;
1213}
1214
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001215void mdp4_mixer_stage_up(struct mdp4_overlay_pipe *pipe)
1216{
1217 uint32 data, mask, snum, stage, mixer, pnum;
Adrian Salido-Morenoc4302232011-09-26 12:54:03 -07001218 struct mdp4_overlay_pipe *spipe;
1219
1220 spipe = mdp4_overlay_stage_pipe(pipe->mixer_num, pipe->mixer_stage);
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001221 if ((spipe != NULL) && (spipe->pipe_num != pipe->pipe_num)) {
Adrian Salido-Morenoc4302232011-09-26 12:54:03 -07001222 pr_err("%s: unable to stage pipe=%d at mixer_stage=%d\n",
1223 __func__, pipe->pipe_ndx, pipe->mixer_stage);
1224 return;
1225 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001226
1227 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1228
1229 stage = pipe->mixer_stage;
1230 mixer = pipe->mixer_num;
1231 pnum = pipe->pipe_num;
1232
1233 /* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1 */
1234 data = inpdw(MDP_BASE + 0x10100);
1235
1236 if (mixer == MDP4_MIXER1)
1237 stage += 8;
1238
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001239 if (pipe->pipe_type == OVERLAY_TYPE_BF) {
1240 snum = 16 + (4 * mixer);
1241 } else if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {/* VG1 and VG2 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001242 pnum -= OVERLAY_PIPE_VG1; /* start from 0 */
1243 snum = 0;
1244 snum += (4 * pnum);
1245 } else {
1246 snum = 8;
1247 snum += (4 * pnum); /* RGB1 and RGB2 */
1248 }
1249
1250 mask = 0x0f;
1251 mask <<= snum;
1252 stage <<= snum;
1253 data &= ~mask; /* clear old bits */
1254
1255 data |= stage;
1256
1257 outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
1258
1259 data = inpdw(MDP_BASE + 0x10100);
1260
1261 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1262
1263 ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = pipe; /* keep it */
1264}
1265
1266void mdp4_mixer_stage_down(struct mdp4_overlay_pipe *pipe)
1267{
1268 uint32 data, mask, snum, stage, mixer, pnum;
1269
1270 stage = pipe->mixer_stage;
1271 mixer = pipe->mixer_num;
1272 pnum = pipe->pipe_num;
1273
1274 if (pipe != ctrl->stage[mixer][stage]) /* not runing */
1275 return;
1276
1277 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1278
1279 /* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1 */
1280 data = inpdw(MDP_BASE + 0x10100);
1281
1282 if (mixer == MDP4_MIXER1)
1283 stage += 8;
1284
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001285 if (pipe->pipe_type == OVERLAY_TYPE_BF) {
1286 snum = 16 + (4 * mixer);
1287 } else if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001288 pnum -= OVERLAY_PIPE_VG1; /* start from 0 */
1289 snum = 0;
1290 snum += (4 * pnum);
1291 } else {
1292 snum = 8;
1293 snum += (4 * pnum); /* RGB1 and RGB2 */
1294 }
1295
1296 mask = 0x0f;
1297 mask <<= snum;
1298 data &= ~mask; /* clear old bits */
1299
1300 outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
1301
1302 data = inpdw(MDP_BASE + 0x10100);
1303
1304 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1305
1306 ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = NULL; /* clear it */
1307}
1308
1309void mdp4_mixer_blend_setup(struct mdp4_overlay_pipe *pipe)
1310{
1311 struct mdp4_overlay_pipe *bg_pipe;
1312 unsigned char *overlay_base, *rgb_base;
1313 uint32 c0, c1, c2, blend_op, constant_color = 0, rgb_src_format;
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001314 uint32 fg_color3_out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001315 int off;
1316
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001317 if (pipe->mixer_stage == MDP4_MIXER_STAGE_BASE)
1318 return;
1319
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001320 if (pipe->mixer_num) /* mixer number, /dev/fb0, /dev/fb1 */
1321 overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
1322 else
1323 overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
1324
1325 /* stage 0 to stage 2 */
1326 off = 0x20 * (pipe->mixer_stage - MDP4_MIXER_STAGE0);
1327
1328 bg_pipe = mdp4_overlay_stage_pipe(pipe->mixer_num,
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001329 MDP4_MIXER_STAGE_BASE);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001330 if (bg_pipe == NULL) {
1331 pr_err("%s: Error: no bg_pipe\n", __func__);
1332 return;
1333 }
1334
1335 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1336
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001337 blend_op = (MDP4_BLEND_FG_ALPHA_FG_CONST |
1338 MDP4_BLEND_BG_ALPHA_BG_CONST);
1339 outpdw(overlay_base + off + 0x108, pipe->alpha);
1340 outpdw(overlay_base + off + 0x10c, 0xff - pipe->alpha);
1341 fg_color3_out = 0; /* keep bg alpha by default */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001342
1343 if (pipe->is_fg) {
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001344 if (pipe->alpha == 0xff &&
1345 bg_pipe->pipe_num <= OVERLAY_PIPE_RGB2) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001346 rgb_base = MDP_BASE + MDP4_RGB_BASE;
1347 rgb_base += MDP4_RGB_OFF * bg_pipe->pipe_num;
1348 rgb_src_format = inpdw(rgb_base + 0x50);
1349 rgb_src_format |= MDP4_FORMAT_SOLID_FILL;
1350 outpdw(rgb_base + 0x50, rgb_src_format);
1351 outpdw(rgb_base + 0x1008, constant_color);
1352 }
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001353 } else if (pipe->alpha_enable) {
1354 /* pick fg alpha */
1355 blend_op = (MDP4_BLEND_BG_ALPHA_FG_PIXEL |
1356 MDP4_BLEND_FG_ALPHA_FG_PIXEL |
1357 MDP4_BLEND_BG_INV_ALPHA);
1358 fg_color3_out = 1; /* keep fg alpha */
1359 } else if (bg_pipe->alpha_enable) {
1360 /* pick bg alpha */
1361 blend_op = (MDP4_BLEND_BG_ALPHA_BG_PIXEL |
1362 MDP4_BLEND_FG_ALPHA_BG_PIXEL |
1363 MDP4_BLEND_FG_INV_ALPHA);
1364 fg_color3_out = 0; /* keep bg alpha */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001365 }
1366
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001367 if (pipe->transp != MDP_TRANSP_NOP) {
1368 if (pipe->is_fg) {
1369 transp_color_key(pipe->src_format, pipe->transp,
1370 &c0, &c1, &c2);
1371 /* Fg blocked */
1372 blend_op |= MDP4_BLEND_FG_TRANSP_EN;
1373 /* lower limit */
1374 outpdw(overlay_base + off + 0x110,
1375 (c1 << 16 | c0));/* low */
1376 outpdw(overlay_base + off + 0x114, c2);/* low */
1377 /* upper limit */
1378 outpdw(overlay_base + off + 0x118,
1379 (c1 << 16 | c0));
1380 outpdw(overlay_base + off + 0x11c, c2);
1381 } else {
1382 transp_color_key(bg_pipe->src_format,
1383 pipe->transp, &c0, &c1, &c2);
1384 /* bg blocked */
1385 blend_op |= MDP4_BLEND_BG_TRANSP_EN;
1386 /* lower limit */
1387 outpdw(overlay_base + 0x180,
1388 (c1 << 16 | c0));/* low */
1389 outpdw(overlay_base + 0x184, c2);/* low */
1390 /* upper limit */
1391 outpdw(overlay_base + 0x188,
1392 (c1 << 16 | c0));/* high */
1393 outpdw(overlay_base + 0x18c, c2);/* high */
1394 }
1395 }
1396
1397 outpdw(overlay_base + off + 0x104, blend_op);
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001398 outpdw(overlay_base + (off << 5) + 0x1004, fg_color3_out);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001399
1400 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1401}
1402
1403void mdp4_overlay_reg_flush(struct mdp4_overlay_pipe *pipe, int all)
1404{
1405 struct mdp4_overlay_pipe *bg_pipe;
1406 uint32 bits = 0;
1407
1408 if (pipe->mixer_num == MDP4_MIXER1)
1409 bits |= 0x02;
1410 else
1411 bits |= 0x01;
1412
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001413 if (all && pipe->pipe_type != OVERLAY_TYPE_BF) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001414 if (pipe->pipe_num <= OVERLAY_PIPE_RGB2) {
1415 if (pipe->pipe_num == OVERLAY_PIPE_RGB2)
1416 bits |= 0x20;
1417 else
1418 bits |= 0x10;
1419 } else {
1420 if (pipe->is_fg && pipe->alpha == 0xFF) {
1421 bg_pipe = mdp4_overlay_stage_pipe(
1422 pipe->mixer_num,
1423 MDP4_MIXER_STAGE_BASE);
1424 if (bg_pipe->pipe_num <= OVERLAY_PIPE_RGB2) {
1425 if (bg_pipe->pipe_num ==
1426 OVERLAY_PIPE_RGB2)
1427 bits |= 0x20;
1428 else
1429 bits |= 0x10;
1430 }
1431 }
1432 if (pipe->pipe_num == OVERLAY_PIPE_VG2)
1433 bits |= 0x08;
1434 else
1435 bits |= 0x04;
1436 }
1437 }
1438
1439 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1440 outpdw(MDP_BASE + 0x18000, bits); /* MDP_OVERLAY_REG_FLUSH */
1441 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1442}
1443
1444struct mdp4_overlay_pipe *mdp4_overlay_stage_pipe(int mixer, int stage)
1445{
1446 return ctrl->stage[mixer][stage];
1447}
1448
1449struct mdp4_overlay_pipe *mdp4_overlay_ndx2pipe(int ndx)
1450{
1451 struct mdp4_overlay_pipe *pipe;
1452
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001453 if (ndx <= 0 || ndx > OVERLAY_PIPE_MAX)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001454 return NULL;
1455
1456 pipe = &ctrl->plist[ndx - 1]; /* ndx start from 1 */
1457
1458 if (pipe->pipe_used == 0)
1459 return NULL;
1460
1461 return pipe;
1462}
1463
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001464struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(int ptype, int mixer)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001465{
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001466 int i;
1467 struct mdp4_overlay_pipe *pipe;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001468
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001469 for (i = 0; i < OVERLAY_PIPE_MAX; i++) {
1470 pipe = &ctrl->plist[i];
1471 if ((pipe->pipe_used == 0) && ((pipe->pipe_type == ptype) ||
1472 (ptype == OVERLAY_TYPE_RGB &&
1473 pipe->pipe_type == OVERLAY_TYPE_VIDEO))) {
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001474 if (ptype == OVERLAY_TYPE_BF &&
1475 mixer != pipe->mixer_num)
1476 continue;
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001477 init_completion(&pipe->comp);
1478 init_completion(&pipe->dmas_comp);
1479 pr_info("%s: pipe=%x ndx=%d num=%d\n", __func__,
1480 (int)pipe, pipe->pipe_ndx, pipe->pipe_num);
1481 return pipe;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001482 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001483 }
1484
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001485 pr_err("%s: ptype=%d FAILED\n", __func__, ptype);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001486
1487 return NULL;
1488}
1489
1490
1491void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe)
1492{
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001493 uint32 ptype, num, ndx, mixer;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001494
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001495 pr_info("%s: pipe=%x ndx=%d\n", __func__, (int)pipe, pipe->pipe_ndx);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001496
1497 ptype = pipe->pipe_type;
1498 num = pipe->pipe_num;
1499 ndx = pipe->pipe_ndx;
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001500 mixer = pipe->mixer_num;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001501
1502 memset(pipe, 0, sizeof(*pipe));
1503
1504 pipe->pipe_type = ptype;
1505 pipe->pipe_num = num;
1506 pipe->pipe_ndx = ndx;
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001507 pipe->mixer_num = mixer;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001508}
1509
1510int mdp4_overlay_req_check(uint32 id, uint32 z_order, uint32 mixer)
1511{
1512 struct mdp4_overlay_pipe *pipe;
1513
1514 pipe = ctrl->stage[mixer][z_order];
1515
1516 if (pipe == NULL)
1517 return 0;
1518
1519 if (pipe->pipe_ndx == id) /* same req, recycle */
1520 return 0;
1521
1522 if (id == MSMFB_NEW_REQUEST) { /* new request */
1523 if (pipe->pipe_num >= OVERLAY_PIPE_VG1) /* share pipe */
1524 return 0;
1525 }
1526
1527 return -EPERM;
1528}
1529
1530static int mdp4_overlay_validate_downscale(struct mdp_overlay *req,
1531 struct msm_fb_data_type *mfd, uint32 perf_level, uint32 pclk_rate)
1532{
1533 __u32 panel_clk_khz, mdp_clk_khz;
1534 __u32 num_hsync_pix_clks, mdp_clks_per_hsync, src_wh;
1535 __u32 hsync_period_ps, mdp_period_ps, total_hsync_period_ps;
1536 unsigned long fill_rate_y_dir, fill_rate_x_dir;
1537 unsigned long fillratex100, mdp_pixels_produced;
1538 unsigned long mdp_clk_hz;
1539
1540 pr_debug("%s: LCDC Mode Downscale validation with MDP Core"
1541 " Clk rate\n", __func__);
1542 pr_debug("src_w %u, src_h %u, dst_w %u, dst_h %u\n",
1543 req->src_rect.w, req->src_rect.h, req->dst_rect.w,
1544 req->dst_rect.h);
1545
1546
1547 panel_clk_khz = pclk_rate/1000;
1548 mdp_clk_hz = mdp_perf_level2clk_rate(perf_level);
1549
Ravishangar Kalyanamc42862a2011-09-14 11:42:34 -07001550 if (!mdp_clk_hz || !req->dst_rect.w || !req->dst_rect.h) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001551 pr_debug("mdp_perf_level2clk_rate returned 0,"
Ravishangar Kalyanamc42862a2011-09-14 11:42:34 -07001552 "or dst_rect height/width is 0,"
1553 "Downscale Validation incomplete\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001554 return 0;
1555 }
1556
1557 mdp_clk_khz = mdp_clk_hz/1000;
1558
1559 num_hsync_pix_clks = mfd->panel_info.lcdc.h_back_porch +
1560 mfd->panel_info.lcdc.h_front_porch +
1561 mfd->panel_info.lcdc.h_pulse_width +
1562 mfd->panel_info.xres;
1563
1564 hsync_period_ps = 1000000000/panel_clk_khz;
1565 mdp_period_ps = 1000000000/mdp_clk_khz;
1566
1567 total_hsync_period_ps = num_hsync_pix_clks * hsync_period_ps;
1568 mdp_clks_per_hsync = total_hsync_period_ps/mdp_period_ps;
1569
1570 pr_debug("hsync_period_ps %u, mdp_period_ps %u,"
1571 "total_hsync_period_ps %u\n", hsync_period_ps,
1572 mdp_period_ps, total_hsync_period_ps);
1573
1574 src_wh = req->src_rect.w * req->src_rect.h;
1575 if (src_wh % req->dst_rect.h)
1576 fill_rate_y_dir = (src_wh / req->dst_rect.h) + 1;
1577 else
1578 fill_rate_y_dir = (src_wh / req->dst_rect.h);
1579
1580 fill_rate_x_dir = (mfd->panel_info.xres - req->dst_rect.w)
1581 + req->src_rect.w;
1582
1583 if (fill_rate_y_dir >= fill_rate_x_dir)
1584 fillratex100 = 100 * fill_rate_y_dir / mfd->panel_info.xres;
1585 else
1586 fillratex100 = 100 * fill_rate_x_dir / mfd->panel_info.xres;
1587
1588 pr_debug("mdp_clks_per_hsync %u, fill_rate_y_dir %lu,"
1589 "fill_rate_x_dir %lu\n", mdp_clks_per_hsync,
1590 fill_rate_y_dir, fill_rate_x_dir);
1591
1592 mdp_pixels_produced = 100 * mdp_clks_per_hsync/fillratex100;
1593 pr_debug("fillratex100 %lu, mdp_pixels_produced %lu\n",
1594 fillratex100, mdp_pixels_produced);
1595 if (mdp_pixels_produced <= mfd->panel_info.xres) {
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07001596 pr_err("%s():display underflow detected with downscale"
1597 " params\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001598 return -ERANGE;
1599 }
1600
1601 return 0;
1602}
1603
1604static int mdp4_overlay_req2pipe(struct mdp_overlay *req, int mixer,
1605 struct mdp4_overlay_pipe **ppipe,
1606 struct msm_fb_data_type *mfd)
1607{
1608 struct mdp4_overlay_pipe *pipe;
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001609 int ret, ptype;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001610
1611 if (mfd == NULL) {
1612 pr_err("%s: mfd == NULL, -ENODEV\n", __func__);
1613 return -ENODEV;
1614 }
1615
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001616 if (mixer >= MDP4_MIXER_MAX) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001617 pr_err("%s: mixer out of range!\n", __func__);
1618 mdp4_stat.err_mixer++;
1619 return -ERANGE;
1620 }
1621
1622 if (req->z_order < 0 || req->z_order > 2) {
1623 pr_err("%s: z_order=%d out of range!\n", __func__,
1624 req->z_order);
1625 mdp4_stat.err_zorder++;
1626 return -ERANGE;
1627 }
1628
1629 if (req->src_rect.h == 0 || req->src_rect.w == 0) {
1630 pr_err("%s: src img of zero size!\n", __func__);
1631 mdp4_stat.err_size++;
1632 return -EINVAL;
1633 }
1634
1635
1636 if (req->dst_rect.h > (req->src_rect.h * 8)) { /* too much */
1637 mdp4_stat.err_scale++;
1638 pr_err("%s: scale up, too much (h)!\n", __func__);
1639 return -ERANGE;
1640 }
1641
1642 if (req->src_rect.h > (req->dst_rect.h * 8)) { /* too little */
1643 mdp4_stat.err_scale++;
1644 pr_err("%s: scale down, too little (h)!\n", __func__);
1645 return -ERANGE;
1646 }
1647
1648 if (req->dst_rect.w > (req->src_rect.w * 8)) { /* too much */
1649 mdp4_stat.err_scale++;
1650 pr_err("%s: scale up, too much (w)!\n", __func__);
1651 return -ERANGE;
1652 }
1653
1654 if (req->src_rect.w > (req->dst_rect.w * 8)) { /* too little */
1655 mdp4_stat.err_scale++;
1656 pr_err("%s: scale down, too little (w)!\n", __func__);
1657 return -ERANGE;
1658 }
1659
1660 if (mdp_hw_revision == MDP4_REVISION_V1) {
1661 /* non integer down saceling ratio smaller than 1/4
1662 * is not supportted
1663 */
1664 if (req->src_rect.h > (req->dst_rect.h * 4)) {
1665 if (req->src_rect.h % req->dst_rect.h) {
1666 mdp4_stat.err_scale++;
1667 pr_err("%s: need integer (h)!\n", __func__);
1668 return -ERANGE;
1669 }
1670 }
1671
1672 if (req->src_rect.w > (req->dst_rect.w * 4)) {
1673 if (req->src_rect.w % req->dst_rect.w) {
1674 mdp4_stat.err_scale++;
1675 pr_err("%s: need integer (w)!\n", __func__);
1676 return -ERANGE;
1677 }
1678 }
1679 }
1680
1681 if (((req->src_rect.x + req->src_rect.w) > req->src.width) ||
1682 ((req->src_rect.y + req->src_rect.h) > req->src.height)) {
1683 mdp4_stat.err_size++;
1684 pr_err("%s invalid src rectangle\n", __func__);
1685 return -ERANGE;
1686 }
1687
1688 if (ctrl->panel_3d != MDP4_3D_SIDE_BY_SIDE) {
1689 int xres;
1690 int yres;
1691
1692 xres = mfd->panel_info.xres;
1693 yres = mfd->panel_info.yres;
1694
1695 if (((req->dst_rect.x + req->dst_rect.w) > xres) ||
1696 ((req->dst_rect.y + req->dst_rect.h) > yres)) {
1697 mdp4_stat.err_size++;
1698 pr_err("%s invalid dst rectangle\n", __func__);
1699 return -ERANGE;
1700 }
1701 }
1702
1703 ptype = mdp4_overlay_format2type(req->src.format);
1704 if (ptype < 0) {
1705 pr_err("%s: mdp4_overlay_format2type!\n", __func__);
1706 return ptype;
1707 }
1708
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001709 if (req->flags & MDP_OV_PIPE_SHARE)
1710 ptype = OVERLAY_TYPE_VIDEO; /* VG pipe supports both RGB+YUV */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001711
1712 if (req->id == MSMFB_NEW_REQUEST) /* new request */
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001713 pipe = mdp4_overlay_pipe_alloc(ptype, mixer);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001714 else
1715 pipe = mdp4_overlay_ndx2pipe(req->id);
1716
1717 if (pipe == NULL) {
1718 pr_err("%s: pipe == NULL!\n", __func__);
1719 return -ENOMEM;
1720 }
1721
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001722 pipe->src_format = req->src.format;
1723 ret = mdp4_overlay_format2pipe(pipe);
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001724
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001725 if (ret < 0) {
1726 pr_err("%s: mdp4_overlay_format2pipe!\n", __func__);
1727 return ret;
1728 }
1729
1730 /*
1731 * base layer == 1, reserved for frame buffer
1732 * zorder 0 == stage 0 == 2
1733 * zorder 1 == stage 1 == 3
1734 * zorder 2 == stage 2 == 4
1735 */
1736 if (req->id == MSMFB_NEW_REQUEST) { /* new request */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001737 pipe->pipe_used++;
1738 pipe->mixer_num = mixer;
1739 pipe->mixer_stage = req->z_order + MDP4_MIXER_STAGE0;
1740 pr_debug("%s: zorder=%d pipe ndx=%d num=%d\n", __func__,
1741 req->z_order, pipe->pipe_ndx, pipe->pipe_num);
1742
1743 }
1744
1745 pipe->src_width = req->src.width & 0x07ff; /* source img width */
1746 pipe->src_height = req->src.height & 0x07ff; /* source img height */
1747 pipe->src_h = req->src_rect.h & 0x07ff;
1748 pipe->src_w = req->src_rect.w & 0x07ff;
1749 pipe->src_y = req->src_rect.y & 0x07ff;
1750 pipe->src_x = req->src_rect.x & 0x07ff;
1751 pipe->dst_h = req->dst_rect.h & 0x07ff;
1752 pipe->dst_w = req->dst_rect.w & 0x07ff;
1753 pipe->dst_y = req->dst_rect.y & 0x07ff;
1754 pipe->dst_x = req->dst_rect.x & 0x07ff;
1755
1756 pipe->op_mode = 0;
1757
1758 if (req->flags & MDP_FLIP_LR)
1759 pipe->op_mode |= MDP4_OP_FLIP_LR;
1760
1761 if (req->flags & MDP_FLIP_UD)
1762 pipe->op_mode |= MDP4_OP_FLIP_UD;
1763
1764 if (req->flags & MDP_DITHER)
1765 pipe->op_mode |= MDP4_OP_DITHER_EN;
1766
1767 if (req->flags & MDP_DEINTERLACE)
1768 pipe->op_mode |= MDP4_OP_DEINT_EN;
1769
1770 if (req->flags & MDP_DEINTERLACE_ODD)
1771 pipe->op_mode |= MDP4_OP_DEINT_ODD_REF;
1772
1773 pipe->is_fg = req->is_fg;/* control alpha and color key */
1774
1775 pipe->alpha = req->alpha & 0x0ff;
1776
1777 pipe->transp = req->transp_mask;
1778
1779 *ppipe = pipe;
1780
1781 return 0;
1782}
1783
1784static int get_img(struct msmfb_data *img, struct fb_info *info,
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001785 unsigned long *start, unsigned long *len, struct file **srcp_file,
1786 struct ion_handle **srcp_ihdl)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001787{
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001788#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
1789 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1790#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001791 struct file *file;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001792 int put_needed, ret = 0, fb_num;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001793#ifdef CONFIG_ANDROID_PMEM
1794 unsigned long vstart;
1795#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001796 if (img->flags & MDP_BLIT_SRC_GEM) {
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001797 *srcp_file = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001798 return kgsl_gem_obj_addr(img->memory_id, (int) img->priv,
1799 start, len);
1800 }
1801
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001802 if (img->flags & MDP_MEMORY_ID_TYPE_FB) {
1803 file = fget_light(img->memory_id, &put_needed);
1804 if (file == NULL)
1805 return -EINVAL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001806
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001807 if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
1808 fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
1809 if (get_fb_phys_info(start, len, fb_num))
1810 ret = -1;
1811 else
1812 *srcp_file = file;
1813 } else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001814 ret = -1;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001815 if (ret)
1816 fput_light(file, put_needed);
1817 return ret;
1818 }
1819
1820#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
1821 *srcp_ihdl = ion_import_fd(mfd->client, img->memory_id);
1822 if (IS_ERR_OR_NULL(*srcp_ihdl))
1823 return PTR_ERR(*srcp_ihdl);
1824 if (!ion_phys(mfd->client, *srcp_ihdl, start, (size_t *) len))
1825 return 0;
1826 else
1827 return -EINVAL;
1828#endif
1829#ifdef CONFIG_ANDROID_PMEM
1830 if (!get_pmem_file(img->memory_id, start, &vstart,
1831 len, srcp_file))
1832 return 0;
1833 else
1834 return -EINVAL;
1835#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001836}
1837
kuogee hsieh4aea2742011-07-06 11:05:05 -07001838#ifdef CONFIG_FB_MSM_MIPI_DSI
1839int mdp4_overlay_3d_sbys(struct fb_info *info, struct msmfb_overlay_3d *req)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001840{
1841 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1842 int ret = -EPERM;
1843
1844 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
1845 return -EINTR;
1846
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001847 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
kuogee hsieh4aea2742011-07-06 11:05:05 -07001848 mdp4_dsi_cmd_3d_sbys(mfd, req);
1849 ret = 0;
1850 } else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
1851 mdp4_dsi_video_3d_sbys(mfd, req);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001852 ret = 0;
1853 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001854 mutex_unlock(&mfd->dma->ov_mutex);
1855
1856 return ret;
1857}
kuogee hsieh4aea2742011-07-06 11:05:05 -07001858#else
1859int mdp4_overlay_3d_sbys(struct fb_info *info, struct msmfb_overlay_3d *req)
1860{
1861 /* do nothing */
1862 return -EPERM;
1863}
1864#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001865
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001866int mdp4_overlay_blt(struct fb_info *info, struct msmfb_overlay_blt *req)
1867{
1868 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1869
1870 if (mfd == NULL)
1871 return -ENODEV;
1872
1873 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
1874 return -EINTR;
1875
1876 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
1877 mdp4_dsi_overlay_blt(mfd, req);
1878 else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
1879 mdp4_dsi_video_overlay_blt(mfd, req);
1880 else if (ctrl->panel_mode & MDP4_PANEL_LCDC)
1881 mdp4_lcdc_overlay_blt(mfd, req);
1882
1883 mutex_unlock(&mfd->dma->ov_mutex);
1884
1885 return 0;
1886}
1887
1888int mdp4_overlay_blt_offset(struct fb_info *info, struct msmfb_overlay_blt *req)
1889{
1890 int ret = 0;
1891
1892 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1893
1894 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
1895 return -EINTR;
1896
1897 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
1898 ret = mdp4_dsi_overlay_blt_offset(mfd, req);
1899 else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
1900 ret = mdp4_dsi_video_overlay_blt_offset(mfd, req);
1901 else if (ctrl->panel_mode & MDP4_PANEL_LCDC)
1902 ret = mdp4_lcdc_overlay_blt_offset(mfd, req);
1903
1904 mutex_unlock(&mfd->dma->ov_mutex);
1905
1906 return ret;
1907}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001908
1909int mdp4_overlay_get(struct fb_info *info, struct mdp_overlay *req)
1910{
1911 struct mdp4_overlay_pipe *pipe;
1912
1913 pipe = mdp4_overlay_ndx2pipe(req->id);
1914 if (pipe == NULL)
1915 return -ENODEV;
1916
1917 *req = pipe->req_data;
1918
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001919 if (mdp4_overlay_borderfill_supported())
1920 req->flags |= MDP_BORDERFILL_SUPPORTED;
1921
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001922 return 0;
1923}
1924
1925#define OVERLAY_VGA_SIZE 0x04B000
1926#define OVERLAY_720P_TILE_SIZE 0x0E6000
1927#define OVERLAY_WSVGA_SIZE 0x98000 /* 1024x608, align 600 to 32bit */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001928
1929#ifdef CONFIG_MSM_BUS_SCALING
1930#define OVERLAY_BUS_SCALE_TABLE_BASE 6
1931#endif
1932
1933static int mdp4_overlay_is_rgb_type(int format)
1934{
1935 switch (format) {
1936 case MDP_RGB_565:
1937 case MDP_RGB_888:
1938 case MDP_BGR_565:
1939 case MDP_XRGB_8888:
1940 case MDP_ARGB_8888:
1941 case MDP_RGBA_8888:
1942 case MDP_BGRA_8888:
1943 case MDP_RGBX_8888:
1944 return 1;
1945 default:
1946 return 0;
1947 }
1948}
1949
1950static uint32 mdp4_overlay_get_perf_level(struct mdp_overlay *req)
1951{
1952 int is_fg;
1953
1954 if (req->is_fg && ((req->alpha & 0x0ff) == 0xff))
1955 is_fg = 1;
1956
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -07001957 if (mdp4_extn_disp)
1958 return OVERLAY_PERF_LEVEL1;
1959
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001960 if (req->flags & MDP_DEINTERLACE)
1961 return OVERLAY_PERF_LEVEL1;
1962
1963 if (mdp4_overlay_is_rgb_type(req->src.format) && is_fg &&
1964 ((req->src.width * req->src.height) <= OVERLAY_WSVGA_SIZE))
1965 return OVERLAY_PERF_LEVEL4;
1966 else if (mdp4_overlay_is_rgb_type(req->src.format))
1967 return OVERLAY_PERF_LEVEL1;
1968
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001969 if (ctrl->plist[OVERLAY_PIPE_VG1].pipe_used &&
1970 ctrl->plist[OVERLAY_PIPE_VG2].pipe_used)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001971 return OVERLAY_PERF_LEVEL1;
1972
1973 if (req->src.width*req->src.height <= OVERLAY_VGA_SIZE)
1974 return OVERLAY_PERF_LEVEL3;
1975 else if (req->src.width*req->src.height <= OVERLAY_720P_TILE_SIZE)
1976 return OVERLAY_PERF_LEVEL2;
1977 else
1978 return OVERLAY_PERF_LEVEL1;
1979}
1980
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -07001981void mdp4_update_perf_level(u32 perf_level)
1982{
1983 new_perf_level = perf_level;
1984}
1985
kuogee hsiehc4b8b2f2011-07-12 13:32:14 -07001986void mdp4_set_perf_level(void)
1987{
1988 static int old_perf_level;
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -07001989 int cur_perf_level;
kuogee hsiehc4b8b2f2011-07-12 13:32:14 -07001990
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -07001991 if (mdp4_extn_disp)
1992 cur_perf_level = OVERLAY_PERF_LEVEL1;
1993 else
1994 cur_perf_level = new_perf_level;
1995
1996 if (old_perf_level != cur_perf_level) {
1997 mdp_set_core_clk(cur_perf_level);
1998 old_perf_level = cur_perf_level;
kuogee hsiehc4b8b2f2011-07-12 13:32:14 -07001999 }
2000}
2001
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07002002static void mdp4_overlay_update_blt_mode(struct msm_fb_data_type *mfd)
2003{
2004 if (mfd->use_ov0_blt) {
2005 if (mfd->panel_info.type == LCDC_PANEL)
2006 mdp4_lcdc_overlay_blt_start(mfd);
2007 else if (mfd->panel_info.type == MIPI_VIDEO_PANEL)
2008 mdp4_dsi_video_blt_start(mfd);
2009 else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
2010 mdp4_dsi_overlay_blt_start(mfd);
2011 } else {
2012 if (mfd->panel_info.type == LCDC_PANEL)
2013 mdp4_lcdc_overlay_blt_stop(mfd);
2014 else if (mfd->panel_info.type == MIPI_VIDEO_PANEL)
2015 mdp4_dsi_video_blt_stop(mfd);
2016 else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
2017 mdp4_dsi_overlay_blt_stop(mfd);
2018 }
2019}
2020
2021static u32 mdp4_overlay_blt_enable(struct mdp_overlay *req,
2022 struct msm_fb_data_type *mfd, uint32 perf_level)
2023{
2024 u32 clk_rate = mfd->panel_info.clk_rate;
2025 u32 pull_mode = 0, use_blt = 0;
2026
2027 if (mfd->panel_info.type == MIPI_VIDEO_PANEL)
2028 clk_rate = (&mfd->panel_info.mipi)->dsi_pclk_rate;
2029
2030 if ((mfd->panel_info.type == LCDC_PANEL) ||
2031 (mfd->panel_info.type == MIPI_VIDEO_PANEL))
2032 pull_mode = 1;
2033
2034 if (pull_mode && (req->src_rect.h > req->dst_rect.h ||
2035 req->src_rect.w > req->dst_rect.w)) {
2036 if (mdp4_overlay_validate_downscale(req, mfd, perf_level,
2037 clk_rate))
2038 use_blt = 1;
2039 }
2040
2041 if (mfd->mdp_rev == MDP_REV_41) {
2042 /*
2043 * writeback (blt) mode to provide work around for
2044 * dsi cmd mode interface hardware bug.
2045 */
2046 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
2047 if (req->dst_rect.x != 0)
2048 use_blt = 1;
2049 }
2050 if (mfd->panel_info.xres > 1280)
2051 use_blt = 1;
2052 }
2053 return use_blt;
2054}
2055
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002056int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req)
2057{
2058 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
kuogee hsiehc4b8b2f2011-07-12 13:32:14 -07002059 int ret, mixer, perf_level;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002060 struct mdp4_overlay_pipe *pipe;
2061
2062 if (mfd == NULL) {
2063 pr_err("%s: mfd == NULL, -ENODEV\n", __func__);
2064 return -ENODEV;
2065 }
2066
2067 if (!mfd->panel_power_on) /* suspended */
2068 return -EPERM;
2069
2070 if (req->src.format == MDP_FB_FORMAT)
2071 req->src.format = mfd->fb_imgType;
2072
2073 if (mutex_lock_interruptible(&mfd->dma->ov_mutex)) {
2074 pr_err("%s: mutex_lock_interruptible, -EINTR\n", __func__);
2075 return -EINTR;
2076 }
2077
2078 perf_level = mdp4_overlay_get_perf_level(req);
2079
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002080 mixer = mfd->panel_info.pdest; /* DISPLAY_1 or DISPLAY_2 */
2081
2082 ret = mdp4_overlay_req2pipe(req, mixer, &pipe, mfd);
2083 if (ret < 0) {
2084 mutex_unlock(&mfd->dma->ov_mutex);
2085 pr_err("%s: mdp4_overlay_req2pipe, ret=%d\n", __func__, ret);
2086 return ret;
2087 }
2088
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07002089 if (mixer == MDP4_MIXER0) {
2090 u32 use_blt = mdp4_overlay_blt_enable(req, mfd, perf_level);
2091 mfd->use_ov0_blt &= ~(1 << (pipe->pipe_ndx-1));
2092 mfd->use_ov0_blt |= (use_blt << (pipe->pipe_ndx-1));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002093 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002094
2095 /* return id back to user */
2096 req->id = pipe->pipe_ndx; /* pipe_ndx start from 1 */
2097 pipe->req_data = *req; /* keep original req */
2098
2099 pipe->flags = req->flags;
2100
2101 if (pipe->flags & MDP_SHARPENING) {
2102 bool test = ((pipe->req_data.dpp.sharp_strength > 0) &&
2103 ((req->src_rect.w > req->dst_rect.w) &&
2104 (req->src_rect.h > req->dst_rect.h)));
2105 if (test) {
2106 pr_warn("%s: No sharpening while downscaling.\n",
2107 __func__);
2108 pipe->flags &= ~MDP_SHARPENING;
2109 }
2110 }
2111
Liyuan Lid9736632011-11-11 13:47:59 -08002112 /* precompute HSIC matrices */
2113 if (req->flags & MDP_DPP_HSIC)
2114 mdp4_hsic_set(pipe, &(req->dpp));
2115
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002116 mdp4_stat.overlay_set[pipe->mixer_num]++;
2117
2118 if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
2119 if (mdp_hw_revision == MDP4_REVISION_V2_1 &&
2120 pipe->mixer_num == MDP4_MIXER0)
2121 mdp4_overlay_status_write(MDP4_OVERLAY_TYPE_SET, true);
2122 }
2123
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07002124 if (ctrl->panel_mode & MDP4_PANEL_DTV &&
2125 pipe->mixer_num == MDP4_MIXER1)
2126 mdp4_overlay_dtv_set(mfd, pipe);
2127
Adrian Salido-Moreno5e912032011-08-29 11:15:47 -07002128 if (new_perf_level != perf_level) {
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -07002129 mdp4_update_perf_level(perf_level);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002130
Adrian Salido-Moreno5e912032011-08-29 11:15:47 -07002131 /* change clck base on perf level */
Adrian Salido-Moreno5e912032011-08-29 11:15:47 -07002132 if (pipe->mixer_num == MDP4_MIXER0) {
2133 if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
kuogee hsiehaff429a2011-09-22 17:50:05 -07002134 mdp4_overlay_dsi_video_set_perf(mfd);
Adrian Salido-Moreno5e912032011-08-29 11:15:47 -07002135 } else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
2136 mdp4_dsi_cmd_dma_busy_wait(mfd);
2137 mdp4_dsi_blt_dmap_busy_wait(mfd);
2138 mdp4_set_perf_level();
2139 } else if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
kuogee hsiehaff429a2011-09-22 17:50:05 -07002140 mdp4_overlay_lcdc_set_perf(mfd);
Adrian Salido-Moreno5e912032011-08-29 11:15:47 -07002141 } else if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
2142 mdp4_mddi_dma_busy_wait(mfd);
2143 mdp4_set_perf_level();
2144 }
2145 } else {
2146 if (ctrl->panel_mode & MDP4_PANEL_DTV)
2147 mdp4_overlay_dtv_vsync_push(mfd, pipe);
kuogee hsieh9452ecb2011-08-01 18:26:23 -07002148 }
kuogee hsieh9452ecb2011-08-01 18:26:23 -07002149 }
kuogee hsieh9452ecb2011-08-01 18:26:23 -07002150 mutex_unlock(&mfd->dma->ov_mutex);
2151
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002152#ifdef CONFIG_MSM_BUS_SCALING
2153 if (pipe->mixer_num == MDP4_MIXER0) {
2154 mdp_bus_scale_update_request(OVERLAY_BUS_SCALE_TABLE_BASE
2155 - perf_level);
2156 }
2157#endif
2158
2159 return 0;
2160}
2161
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002162int mdp4_overlay_unset(struct fb_info *info, int ndx)
2163{
2164 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
2165 struct mdp4_overlay_pipe *pipe;
2166 uint32 flags;
Liyuan Lid9736632011-11-11 13:47:59 -08002167 struct dpp_ctrl dpp;
2168 int i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002169
2170 if (mfd == NULL)
2171 return -ENODEV;
2172
2173 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
2174 return -EINTR;
2175
2176 pipe = mdp4_overlay_ndx2pipe(ndx);
2177
2178 if (pipe == NULL) {
2179 mutex_unlock(&mfd->dma->ov_mutex);
2180 return -ENODEV;
2181 }
2182
2183 if (pipe->mixer_num == MDP4_MIXER1)
2184 ctrl->mixer1_played = 0;
2185 else {
2186 /* mixer 0 */
2187 ctrl->mixer0_played = 0;
2188#ifdef CONFIG_FB_MSM_MIPI_DSI
2189 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
2190 if (mfd->panel_power_on) {
2191 mdp4_dsi_blt_dmap_busy_wait(mfd);
2192 }
2193 }
2194#else
2195 if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
2196 if (mfd->panel_power_on)
2197 mdp4_mddi_dma_busy_wait(mfd);
2198 }
2199#endif
2200 }
2201
2202 mdp4_mixer_stage_down(pipe);
2203
2204 if (pipe->mixer_num == MDP4_MIXER0) {
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07002205
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002206#ifdef CONFIG_FB_MSM_MIPI_DSI
2207 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
2208 if (mfd->panel_power_on)
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07002209 mdp4_dsi_cmd_overlay_restore();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002210 } else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
kuogee hsiehebca0c72011-07-14 13:30:33 -07002211 mdp4_overlay_reg_flush(pipe, 1);
kuogee hsieh5c6cfbf2011-09-06 19:01:31 -07002212 if (mfd->panel_power_on) {
2213 flags = pipe->flags;
2214 pipe->flags &= ~MDP_OV_PLAY_NOWAIT;
2215 mdp4_overlay_dsi_video_vsync_push(mfd, pipe);
2216 pipe->flags = flags;
2217 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002218 }
2219#else
2220 if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
2221 if (mdp_hw_revision == MDP4_REVISION_V2_1)
2222 mdp4_overlay_status_write(
2223 MDP4_OVERLAY_TYPE_UNSET, true);
2224 if (mfd->panel_power_on)
2225 mdp4_mddi_overlay_restore();
2226 }
2227#endif
2228 else if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
kuogee hsiehebca0c72011-07-14 13:30:33 -07002229 mdp4_overlay_reg_flush(pipe, 1);
kuogee hsieh5c6cfbf2011-09-06 19:01:31 -07002230 if (mfd->panel_power_on) {
2231 flags = pipe->flags;
2232 pipe->flags &= ~MDP_OV_PLAY_NOWAIT;
2233 mdp4_overlay_lcdc_vsync_push(mfd, pipe);
2234 pipe->flags = flags;
2235 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002236 }
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07002237
2238 mfd->use_ov0_blt &= ~(1 << (pipe->pipe_ndx-1));
2239 mdp4_overlay_update_blt_mode(mfd);
2240 mfd->ov0_blt_state = mfd->use_ov0_blt;
2241
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002242 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002243 else { /* mixer1, DTV, ATV */
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07002244 if (ctrl->panel_mode & MDP4_PANEL_DTV)
2245 mdp4_overlay_dtv_unset(mfd, pipe);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002246 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002247
Liyuan Lid9736632011-11-11 13:47:59 -08002248 /* Reset any HSIC settings to default */
2249 if (pipe->flags & MDP_DPP_HSIC) {
2250 for (i = 0; i < NUM_HSIC_PARAM; i++)
2251 dpp.hsic_params[i] = 0;
2252
2253 mdp4_hsic_set(pipe, &dpp);
2254 mdp4_hsic_update(pipe);
2255 }
2256
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002257 mdp4_stat.overlay_unset[pipe->mixer_num]++;
2258
2259 mdp4_overlay_pipe_free(pipe);
2260
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07002261 if (!(ctrl->plist[OVERLAY_PIPE_VG1].pipe_used +
2262 ctrl->plist[OVERLAY_PIPE_VG2].pipe_used))
2263 mdp4_update_perf_level(OVERLAY_PERF_LEVEL4);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002264
2265 mutex_unlock(&mfd->dma->ov_mutex);
2266
2267#ifdef CONFIG_MSM_BUS_SCALING
2268 if (pipe->mixer_num == MDP4_MIXER0)
2269 if (mfd->panel_power_on)
2270 mdp_bus_scale_update_request(2);
2271#endif
2272 return 0;
2273}
2274
2275struct tile_desc {
2276 uint32 width; /* tile's width */
2277 uint32 height; /* tile's height */
2278 uint32 row_tile_w; /* tiles per row's width */
2279 uint32 row_tile_h; /* tiles per row's height */
2280};
2281
2282void tile_samsung(struct tile_desc *tp)
2283{
2284 /*
2285 * each row of samsung tile consists of two tiles in height
2286 * and two tiles in width which means width should align to
2287 * 64 x 2 bytes and height should align to 32 x 2 bytes.
2288 * video decoder generate two tiles in width and one tile
2289 * in height which ends up height align to 32 X 1 bytes.
2290 */
2291 tp->width = 64; /* 64 bytes */
2292 tp->row_tile_w = 2; /* 2 tiles per row's width */
2293 tp->height = 32; /* 32 bytes */
2294 tp->row_tile_h = 1; /* 1 tiles per row's height */
2295}
2296
2297uint32 tile_mem_size(struct mdp4_overlay_pipe *pipe, struct tile_desc *tp)
2298{
2299 uint32 tile_w, tile_h;
2300 uint32 row_num_w, row_num_h;
2301
2302
2303 tile_w = tp->width * tp->row_tile_w;
2304 tile_h = tp->height * tp->row_tile_h;
2305
2306 row_num_w = (pipe->src_width + tile_w - 1) / tile_w;
2307 row_num_h = (pipe->src_height + tile_h - 1) / tile_h;
2308 return ((row_num_w * row_num_h * tile_w * tile_h) + 8191) & ~8191;
2309}
2310
Nagamalleswararao Ganji0737d652011-10-14 02:02:33 -07002311int mdp4_overlay_play_wait(struct fb_info *info, struct msmfb_overlay_data *req)
2312{
2313 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
2314 struct mdp4_overlay_pipe *pipe;
2315
2316 if (mfd == NULL)
2317 return -ENODEV;
2318
2319 if (!mfd->panel_power_on) /* suspended */
2320 return -EPERM;
2321
2322 pipe = mdp4_overlay_ndx2pipe(req->id);
2323
2324 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
2325 return -EINTR;
2326
2327 mdp4_overlay_dtv_wait_for_ov(mfd, pipe);
2328
2329 mutex_unlock(&mfd->dma->ov_mutex);
2330
2331 return 0;
2332}
2333
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002334int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002335{
2336 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
2337 struct msmfb_data *img;
2338 struct mdp4_overlay_pipe *pipe;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002339 ulong start, addr;
2340 ulong len = 0;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002341 struct file *srcp0_file = NULL;
2342 struct file *srcp1_file = NULL, *srcp2_file = NULL;
2343 struct ion_handle *srcp0_ihdl = NULL;
2344 struct ion_handle *srcp1_ihdl = NULL, *srcp2_ihdl = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002345 uint32_t overlay_version = 0;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002346 int ret = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002347
2348 if (mfd == NULL)
2349 return -ENODEV;
2350
2351 if (!mfd->panel_power_on) /* suspended */
2352 return -EPERM;
2353
2354 pipe = mdp4_overlay_ndx2pipe(req->id);
2355 if (pipe == NULL) {
2356 pr_err("%s: req_id=%d Error\n", __func__, req->id);
2357 return -ENODEV;
2358 }
2359
2360 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
2361 return -EINTR;
2362
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002363 img = &req->data;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002364 get_img(img, info, &start, &len, &srcp0_file, &srcp0_ihdl);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002365 if (len == 0) {
2366 mutex_unlock(&mfd->dma->ov_mutex);
2367 pr_err("%s: pmem Error\n", __func__);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002368 ret = -1;
2369 goto end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002370 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002371
2372 addr = start + img->offset;
2373 pipe->srcp0_addr = addr;
2374 pipe->srcp0_ystride = pipe->src_width * pipe->bpp;
2375
2376 if ((req->version_key & VERSION_KEY_MASK) == 0xF9E8D700)
2377 overlay_version = (req->version_key & ~VERSION_KEY_MASK);
2378
2379 if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR) {
2380 if (overlay_version > 0) {
2381 img = &req->plane1_data;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002382 get_img(img, info, &start, &len, &srcp1_file,
2383 &srcp1_ihdl);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002384 if (len == 0) {
2385 mutex_unlock(&mfd->dma->ov_mutex);
2386 pr_err("%s: Error to get plane1\n", __func__);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002387 ret = -EINVAL;
2388 goto end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002389 }
2390 pipe->srcp1_addr = start + img->offset;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002391 } else if (pipe->frame_format ==
2392 MDP4_FRAME_FORMAT_VIDEO_SUPERTILE) {
2393 struct tile_desc tile;
2394
2395 tile_samsung(&tile);
2396 pipe->srcp1_addr = addr + tile_mem_size(pipe, &tile);
2397 } else {
2398 pipe->srcp1_addr = addr + (pipe->src_width *
2399 pipe->src_height);
2400 }
2401 pipe->srcp0_ystride = pipe->src_width;
2402 if ((pipe->src_format == MDP_Y_CRCB_H1V1) ||
2403 (pipe->src_format == MDP_Y_CBCR_H1V1)) {
2404 if (pipe->src_width > YUV_444_MAX_WIDTH)
2405 pipe->srcp1_ystride = pipe->src_width << 2;
2406 else
2407 pipe->srcp1_ystride = pipe->src_width << 1;
2408 } else
2409 pipe->srcp1_ystride = pipe->src_width;
2410
2411 } else if (pipe->fetch_plane == OVERLAY_PLANE_PLANAR) {
2412 if (overlay_version > 0) {
2413 img = &req->plane1_data;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002414 get_img(img, info, &start, &len, &srcp1_file,
2415 &srcp1_ihdl);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002416 if (len == 0) {
2417 mutex_unlock(&mfd->dma->ov_mutex);
2418 pr_err("%s: Error to get plane1\n", __func__);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002419 ret = -EINVAL;
2420 goto end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002421 }
2422 pipe->srcp1_addr = start + img->offset;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002423
2424 img = &req->plane2_data;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002425 get_img(img, info, &start, &len, &srcp2_file,
2426 &srcp2_ihdl);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002427 if (len == 0) {
2428 mutex_unlock(&mfd->dma->ov_mutex);
2429 pr_err("%s: Error to get plane2\n", __func__);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002430 ret = -EINVAL;
2431 goto end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002432 }
2433 pipe->srcp2_addr = start + img->offset;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002434 } else {
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +05302435 if (pipe->src_format == MDP_Y_CR_CB_GH2V2) {
2436 addr += (ALIGN(pipe->src_width, 16) *
2437 pipe->src_height);
2438 pipe->srcp1_addr = addr;
2439 addr += ((ALIGN((pipe->src_width / 2), 16)) *
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002440 (pipe->src_height / 2));
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +05302441 pipe->srcp2_addr = addr;
2442 } else {
2443 addr += (pipe->src_width * pipe->src_height);
2444 pipe->srcp1_addr = addr;
2445 addr += ((pipe->src_width / 2) *
2446 (pipe->src_height / 2));
2447 pipe->srcp2_addr = addr;
2448 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002449 }
Adrian Salido-Moreno33dc7b92011-08-18 16:16:12 -07002450 /* mdp planar format expects Cb in srcp1 and Cr in p2 */
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +05302451 if ((pipe->src_format == MDP_Y_CR_CB_H2V2) ||
2452 (pipe->src_format == MDP_Y_CR_CB_GH2V2))
Adrian Salido-Moreno33dc7b92011-08-18 16:16:12 -07002453 swap(pipe->srcp1_addr, pipe->srcp2_addr);
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +05302454
2455 if (pipe->src_format == MDP_Y_CR_CB_GH2V2) {
2456 pipe->srcp0_ystride = ALIGN(pipe->src_width, 16);
2457 pipe->srcp1_ystride = ALIGN(pipe->src_width / 2, 16);
2458 pipe->srcp2_ystride = ALIGN(pipe->src_width / 2, 16);
2459 } else {
2460 pipe->srcp0_ystride = pipe->src_width;
2461 pipe->srcp1_ystride = pipe->src_width / 2;
2462 pipe->srcp2_ystride = pipe->src_width / 2;
2463 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002464 }
2465
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07002466 if (mfd->use_ov0_blt != mfd->ov0_blt_state) {
2467 mdp4_overlay_update_blt_mode(mfd);
2468 mfd->ov0_blt_state = mfd->use_ov0_blt;
2469 }
2470
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002471 if (pipe->pipe_num >= OVERLAY_PIPE_VG1)
2472 mdp4_overlay_vg_setup(pipe); /* video/graphic pipe */
2473 else {
2474 if (pipe->flags & MDP_SHARPENING) {
2475 pr_warn(
2476 "%s: Sharpening/Smoothing not supported on RGB pipe\n",
2477 __func__);
2478 pipe->flags &= ~MDP_SHARPENING;
2479 }
2480 mdp4_overlay_rgb_setup(pipe); /* rgb pipe */
2481 }
2482
2483 mdp4_mixer_blend_setup(pipe);
2484 mdp4_mixer_stage_up(pipe);
2485
2486 if (pipe->mixer_num == MDP4_MIXER1) {
2487 ctrl->mixer1_played++;
2488 /* enternal interface */
2489 if (ctrl->panel_mode & MDP4_PANEL_DTV)
2490#ifdef CONFIG_FB_MSM_DTV
2491 mdp4_overlay_dtv_ov_done_push(mfd, pipe);
2492#else
2493 mdp4_overlay_reg_flush(pipe, 1);
2494#endif
2495 else if (ctrl->panel_mode & MDP4_PANEL_ATV)
2496 mdp4_overlay_reg_flush(pipe, 1);
Vinay Kalia27020d12011-10-14 17:50:29 -07002497#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
2498 else if (ctrl->panel_mode & MDP4_PANEL_WRITEBACK) {
2499 mdp4_writeback_dma_busy_wait(mfd);
2500 mdp4_writeback_kickoff_video(mfd, pipe);
2501 }
2502#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002503 } else {
2504 /* primary interface */
2505 ctrl->mixer0_played++;
kuogee hsieh3de11f32011-07-08 14:09:11 -07002506 if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
2507 mdp4_overlay_reg_flush(pipe, 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002508 mdp4_overlay_lcdc_vsync_push(mfd, pipe);
kuogee hsieh3de11f32011-07-08 14:09:11 -07002509 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002510#ifdef CONFIG_FB_MSM_MIPI_DSI
kuogee hsieh3de11f32011-07-08 14:09:11 -07002511 else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
2512 mdp4_overlay_reg_flush(pipe, 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002513 mdp4_overlay_dsi_video_vsync_push(mfd, pipe);
kuogee hsieh3de11f32011-07-08 14:09:11 -07002514 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002515#endif
2516 else {
2517 /* mddi & mipi dsi cmd mode */
2518 if (pipe->flags & MDP_OV_PLAY_NOWAIT) {
2519 mdp4_stat.overlay_play[pipe->mixer_num]++;
2520 mutex_unlock(&mfd->dma->ov_mutex);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002521 goto end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002522 }
2523#ifdef CONFIG_FB_MSM_MIPI_DSI
2524 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
2525 mdp4_dsi_cmd_dma_busy_wait(mfd);
2526 mdp4_dsi_cmd_kickoff_video(mfd, pipe);
2527 }
2528#else
2529 if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
2530 mdp4_mddi_dma_busy_wait(mfd);
2531 mdp4_mddi_kickoff_video(mfd, pipe);
2532 }
2533#endif
2534 }
2535 }
2536
Liyuan Lid9736632011-11-11 13:47:59 -08002537 /* write out DPP HSIC registers */
2538 if (pipe->flags & MDP_DPP_HSIC)
2539 mdp4_hsic_update(pipe);
2540
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002541 mdp4_stat.overlay_play[pipe->mixer_num]++;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002542 mutex_unlock(&mfd->dma->ov_mutex);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002543end:
2544#ifdef CONFIG_ANDROID_PMEM
2545 if (srcp0_file)
2546 put_pmem_file(srcp0_file);
2547 if (srcp1_file)
2548 put_pmem_file(srcp1_file);
2549 if (srcp2_file)
2550 put_pmem_file(srcp2_file);
2551#endif
2552#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
2553 if (!IS_ERR_OR_NULL(srcp0_ihdl))
2554 ion_free(mfd->client, srcp0_ihdl);
2555 if (!IS_ERR_OR_NULL(srcp1_ihdl))
2556 ion_free(mfd->client, srcp1_ihdl);
2557 if (!IS_ERR_OR_NULL(srcp2_ihdl))
2558 ion_free(mfd->client, srcp2_ihdl);
2559#endif
2560 return ret;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002561}