blob: c56828d99dc35786988a60541fefd0df02f73473 [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-Morenoc174d302011-12-13 15:38:26 -0800368 if (pipe->alpha_enable && pipe->dst_h > pipe->src_h)
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -0700369 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 */
Adrian Salido-Morenoc174d302011-12-13 15:38:26 -0800375 pipe->op_mode |= MDP4_OP_SCALE_RGB_ENHANCED |
376 MDP4_OP_SCALE_RGB_BILINEAR |
377 MDP4_OP_SCALE_ALPHA_BILINEAR;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700378 }
379
380 pipe->phasey_step = mdp4_scale_phase_step(29,
381 pipe->src_h, pipe->dst_h);
382 }
383
384 if (pipe->dst_w && pipe->src_w != pipe->dst_w) {
385 if (pipe->dst_w > pipe->src_w * 8) /* too much */
386 return;
387 pipe->op_mode |= MDP4_OP_SCALEX_EN;
388
389 if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {
Adrian Salido-Morenoc174d302011-12-13 15:38:26 -0800390 if (pipe->alpha_enable && pipe->dst_w > pipe->src_w)
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -0700391 pipe->op_mode |= MDP4_OP_SCALEX_PIXEL_RPT;
392 else if (pipe->dst_w <= (pipe->src_w / 4))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700393 pipe->op_mode |= MDP4_OP_SCALEX_MN_PHASE;
394 else
395 pipe->op_mode |= MDP4_OP_SCALEX_FIR;
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -0700396 } else { /* RGB pipe */
Adrian Salido-Morenoc174d302011-12-13 15:38:26 -0800397 pipe->op_mode |= MDP4_OP_SCALE_RGB_ENHANCED |
398 MDP4_OP_SCALE_RGB_BILINEAR |
399 MDP4_OP_SCALE_ALPHA_BILINEAR;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700400 }
401
402 pipe->phasex_step = mdp4_scale_phase_step(29,
403 pipe->src_w, pipe->dst_w);
404 }
405}
406
407void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe)
408{
409 char *rgb_base;
410 uint32 src_size, src_xy, dst_size, dst_xy;
411 uint32 format, pattern;
412
413 rgb_base = MDP_BASE + MDP4_RGB_BASE;
414 rgb_base += (MDP4_RGB_OFF * pipe->pipe_num);
415
416 src_size = ((pipe->src_h << 16) | pipe->src_w);
417 src_xy = ((pipe->src_y << 16) | pipe->src_x);
418 dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
419 dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
420
421 format = mdp4_overlay_format(pipe);
422 pattern = mdp4_overlay_unpack_pattern(pipe);
423
424#ifdef MDP4_IGC_LUT_ENABLE
425 pipe->op_mode |= MDP4_OP_IGC_LUT_EN;
426#endif
427
428 mdp4_scale_setup(pipe);
429
430 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
431
432 outpdw(rgb_base + 0x0000, src_size); /* MDP_RGB_SRC_SIZE */
433 outpdw(rgb_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */
434 outpdw(rgb_base + 0x0008, dst_size); /* MDP_RGB_DST_SIZE */
435 outpdw(rgb_base + 0x000c, dst_xy); /* MDP_RGB_DST_XY */
436
437 outpdw(rgb_base + 0x0010, pipe->srcp0_addr);
438 outpdw(rgb_base + 0x0040, pipe->srcp0_ystride);
439
440 outpdw(rgb_base + 0x0050, format);/* MDP_RGB_SRC_FORMAT */
441 outpdw(rgb_base + 0x0054, pattern);/* MDP_RGB_SRC_UNPACK_PATTERN */
442 outpdw(rgb_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */
443 outpdw(rgb_base + 0x005c, pipe->phasex_step);
444 outpdw(rgb_base + 0x0060, pipe->phasey_step);
445
446 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
447
448 mdp4_stat.pipe[pipe->pipe_num]++;
449}
450
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700451
452static void mdp4_overlay_vg_get_src_offset(struct mdp4_overlay_pipe *pipe,
453 char *vg_base, uint32 *luma_off, uint32 *chroma_off)
454{
455 uint32 src_xy;
456 *luma_off = 0;
457 *chroma_off = 0;
458
Nagamalleswararao Ganji1c8fc4a2011-10-10 20:51:31 -0700459 if (pipe->src_x && (pipe->frame_format ==
460 MDP4_FRAME_FORMAT_LINEAR)) {
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700461 src_xy = (pipe->src_y << 16) | pipe->src_x;
462 src_xy &= 0xffff0000;
463 outpdw(vg_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */
464
465 switch (pipe->src_format) {
466 case MDP_Y_CR_CB_H2V2:
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +0530467 case MDP_Y_CR_CB_GH2V2:
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700468 case MDP_Y_CB_CR_H2V2:
469 *luma_off = pipe->src_x;
470 *chroma_off = pipe->src_x/2;
471 break;
472
473 case MDP_Y_CBCR_H2V2_TILE:
474 case MDP_Y_CRCB_H2V2_TILE:
475 case MDP_Y_CBCR_H2V2:
476 case MDP_Y_CRCB_H2V2:
477 case MDP_Y_CRCB_H1V1:
478 case MDP_Y_CBCR_H1V1:
479 case MDP_Y_CRCB_H2V1:
480 case MDP_Y_CBCR_H2V1:
481 *luma_off = pipe->src_x;
482 *chroma_off = pipe->src_x;
483 break;
484
485 case MDP_YCRYCB_H2V1:
486 if (pipe->src_x & 0x1)
487 pipe->src_x += 1;
488 *luma_off += pipe->src_x * 2;
489 break;
490
491 case MDP_ARGB_8888:
492 case MDP_RGBA_8888:
493 case MDP_BGRA_8888:
494 case MDP_RGBX_8888:
495 case MDP_RGB_565:
496 case MDP_BGR_565:
497 case MDP_XRGB_8888:
498 case MDP_RGB_888:
499 *luma_off = pipe->src_x * pipe->bpp;
500 break;
501
502 default:
503 pr_err("Source format %u not supported for x offset adjustment\n",
504 pipe->src_format);
505 break;
506 }
507 }
508}
509
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700510void mdp4_overlay_vg_setup(struct mdp4_overlay_pipe *pipe)
511{
512 char *vg_base;
513 uint32 frame_size, src_size, src_xy, dst_size, dst_xy;
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700514 uint32 format, pattern, luma_offset, chroma_offset;
kuogee hsieh4b910f22011-11-15 09:43:04 -0800515 uint32 mask;
kuogee hsiehe1ed1ae2011-09-02 08:53:36 -0700516 int pnum, ptype;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700517
518 pnum = pipe->pipe_num - OVERLAY_PIPE_VG1; /* start from 0 */
519 vg_base = MDP_BASE + MDP4_VIDEO_BASE;
520 vg_base += (MDP4_VIDEO_OFF * pnum);
521
522 frame_size = ((pipe->src_height << 16) | pipe->src_width);
523 src_size = ((pipe->src_h << 16) | pipe->src_w);
524 src_xy = ((pipe->src_y << 16) | pipe->src_x);
525 dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
526 dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
527
kuogee hsiehe1ed1ae2011-09-02 08:53:36 -0700528 ptype = mdp4_overlay_format2type(pipe->src_format);
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +0530529 if (pipe->src_format == MDP_Y_CR_CB_GH2V2) {
530 frame_size = ((pipe->src_height << 16) |
531 ALIGN(pipe->src_width, 16));
532 src_size = ((pipe->src_h << 16) | ALIGN(pipe->src_w, 16));
533 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700534 format = mdp4_overlay_format(pipe);
535 pattern = mdp4_overlay_unpack_pattern(pipe);
536
537 /* not RGB use VG pipe, pure VG pipe */
kuogee hsiehe1ed1ae2011-09-02 08:53:36 -0700538 if (ptype != OVERLAY_TYPE_RGB)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700539 pipe->op_mode |= (MDP4_OP_CSC_EN | MDP4_OP_SRC_DATA_YCBCR);
kuogee hsiehe1ed1ae2011-09-02 08:53:36 -0700540
541#ifdef MDP4_IGC_LUT_ENABLE
542 pipe->op_mode |= MDP4_OP_IGC_LUT_EN;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700543#endif
544
545 mdp4_scale_setup(pipe);
546
547 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
548
549 outpdw(vg_base + 0x0000, src_size); /* MDP_RGB_SRC_SIZE */
550 outpdw(vg_base + 0x0004, src_xy); /* MDP_RGB_SRC_XY */
551 outpdw(vg_base + 0x0008, dst_size); /* MDP_RGB_DST_SIZE */
552 outpdw(vg_base + 0x000c, dst_xy); /* MDP_RGB_DST_XY */
Nagamalleswararao Ganjic6ecb832011-09-14 10:00:18 -0700553
Nagamalleswararao Ganji1c8fc4a2011-10-10 20:51:31 -0700554 if (pipe->frame_format != MDP4_FRAME_FORMAT_LINEAR)
Nagamalleswararao Ganjic6ecb832011-09-14 10:00:18 -0700555 outpdw(vg_base + 0x0048, frame_size); /* TILE frame size */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700556
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700557 /*
558 * Adjust src X offset to avoid MDP from overfetching pixels
559 * present before the offset. This is required for video
560 * frames coming with unused green pixels along the left margin
561 */
kuogee hsiehe1ed1ae2011-09-02 08:53:36 -0700562 /* not RGB use VG pipe, pure VG pipe */
563 if (ptype != OVERLAY_TYPE_RGB) {
564 mdp4_overlay_vg_get_src_offset(pipe, vg_base, &luma_offset,
565 &chroma_offset);
566 } else {
567 luma_offset = 0;
568 chroma_offset = 0;
569 }
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700570
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700571 /* luma component plane */
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700572 outpdw(vg_base + 0x0010, pipe->srcp0_addr + luma_offset);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700573
574 /* chroma component plane or planar color 1 */
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700575 outpdw(vg_base + 0x0014, pipe->srcp1_addr + chroma_offset);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700576
577 /* planar color 2 */
Ravishangar Kalyanam01d68282011-07-18 18:45:06 -0700578 outpdw(vg_base + 0x0018, pipe->srcp2_addr + chroma_offset);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700579
580 outpdw(vg_base + 0x0040,
581 pipe->srcp1_ystride << 16 | pipe->srcp0_ystride);
582
583 outpdw(vg_base + 0x0044,
584 pipe->srcp3_ystride << 16 | pipe->srcp2_ystride);
585
586 outpdw(vg_base + 0x0050, format); /* MDP_RGB_SRC_FORMAT */
587 outpdw(vg_base + 0x0054, pattern); /* MDP_RGB_SRC_UNPACK_PATTERN */
588 outpdw(vg_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */
589 outpdw(vg_base + 0x005c, pipe->phasex_step);
590 outpdw(vg_base + 0x0060, pipe->phasey_step);
591
592 if (pipe->op_mode & MDP4_OP_DITHER_EN) {
593 outpdw(vg_base + 0x0068,
594 pipe->r_bit << 4 | pipe->b_bit << 2 | pipe->g_bit);
595 }
596
597 if (pipe->flags & MDP_SHARPENING) {
598 outpdw(vg_base + 0x8200,
599 mdp4_ss_table_value(pipe->req_data.dpp.sharp_strength,
600 0));
601 outpdw(vg_base + 0x8204,
602 mdp4_ss_table_value(pipe->req_data.dpp.sharp_strength,
603 1));
604 }
605
kuogee hsieh4b910f22011-11-15 09:43:04 -0800606 if (mdp_rev > MDP_REV_41) {
607 /* mdp chip select controller */
608 mask = 0;
609 if (pipe->pipe_num == OVERLAY_PIPE_VG1)
610 mask = 0x020; /* bit 5 */
611 else if (pipe->pipe_num == OVERLAY_PIPE_VG2)
612 mask = 0x02000; /* bit 13 */
613 if (mask) {
614 if (pipe->op_mode & MDP4_OP_SCALEY_MN_PHASE)
615 ctrl->cs_controller &= ~mask;
616 else
617 ctrl->cs_controller |= mask;
618 /* NOT double buffered */
619 outpdw(MDP_BASE + 0x00c0, ctrl->cs_controller);
620 }
621 }
622
623
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700624 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
625
626 mdp4_stat.pipe[pipe->pipe_num]++;
627}
628
629int mdp4_overlay_format2type(uint32 format)
630{
631 switch (format) {
632 case MDP_RGB_565:
633 case MDP_RGB_888:
634 case MDP_BGR_565:
635 case MDP_XRGB_8888:
636 case MDP_ARGB_8888:
637 case MDP_RGBA_8888:
638 case MDP_BGRA_8888:
639 case MDP_RGBX_8888:
640 return OVERLAY_TYPE_RGB;
641 case MDP_YCRYCB_H2V1:
642 case MDP_Y_CRCB_H2V1:
643 case MDP_Y_CBCR_H2V1:
644 case MDP_Y_CRCB_H2V2:
645 case MDP_Y_CBCR_H2V2:
646 case MDP_Y_CBCR_H2V2_TILE:
647 case MDP_Y_CRCB_H2V2_TILE:
648 case MDP_Y_CR_CB_H2V2:
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +0530649 case MDP_Y_CR_CB_GH2V2:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700650 case MDP_Y_CB_CR_H2V2:
651 case MDP_Y_CRCB_H1V1:
652 case MDP_Y_CBCR_H1V1:
653 return OVERLAY_TYPE_VIDEO;
654 default:
655 mdp4_stat.err_format++;
656 return -ERANGE;
657 }
658
659}
660
661#define C3_ALPHA 3 /* alpha */
662#define C2_R_Cr 2 /* R/Cr */
663#define C1_B_Cb 1 /* B/Cb */
664#define C0_G_Y 0 /* G/luma */
665#define YUV_444_MAX_WIDTH 1280 /* Max width for YUV 444*/
666
667int mdp4_overlay_format2pipe(struct mdp4_overlay_pipe *pipe)
668{
669 switch (pipe->src_format) {
670 case MDP_RGB_565:
671 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
672 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
673 pipe->a_bit = 0;
674 pipe->r_bit = 1; /* R, 5 bits */
675 pipe->b_bit = 1; /* B, 5 bits */
676 pipe->g_bit = 2; /* G, 6 bits */
677 pipe->alpha_enable = 0;
678 pipe->unpack_tight = 1;
679 pipe->unpack_align_msb = 0;
680 pipe->unpack_count = 2;
681 pipe->element2 = C2_R_Cr; /* R */
682 pipe->element1 = C0_G_Y; /* G */
683 pipe->element0 = C1_B_Cb; /* B */
684 pipe->bpp = 2; /* 2 bpp */
685 break;
686 case MDP_RGB_888:
687 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
688 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
689 pipe->a_bit = 0;
690 pipe->r_bit = 3; /* R, 8 bits */
691 pipe->b_bit = 3; /* B, 8 bits */
692 pipe->g_bit = 3; /* G, 8 bits */
693 pipe->alpha_enable = 0;
694 pipe->unpack_tight = 1;
695 pipe->unpack_align_msb = 0;
696 pipe->unpack_count = 2;
697 pipe->element2 = C2_R_Cr; /* R */
698 pipe->element1 = C0_G_Y; /* G */
699 pipe->element0 = C1_B_Cb; /* B */
700 pipe->bpp = 3; /* 3 bpp */
701 break;
702 case MDP_BGR_565:
703 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
704 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
705 pipe->a_bit = 0;
706 pipe->r_bit = 1; /* R, 5 bits */
707 pipe->b_bit = 1; /* B, 5 bits */
708 pipe->g_bit = 2; /* G, 6 bits */
709 pipe->alpha_enable = 0;
710 pipe->unpack_tight = 1;
711 pipe->unpack_align_msb = 0;
712 pipe->unpack_count = 2;
713 pipe->element2 = C1_B_Cb; /* B */
714 pipe->element1 = C0_G_Y; /* G */
715 pipe->element0 = C2_R_Cr; /* R */
716 pipe->bpp = 2; /* 2 bpp */
717 break;
718 case MDP_XRGB_8888:
719 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
720 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
721 pipe->a_bit = 3; /* alpha, 4 bits */
722 pipe->r_bit = 3; /* R, 8 bits */
723 pipe->b_bit = 3; /* B, 8 bits */
724 pipe->g_bit = 3; /* G, 8 bits */
725 pipe->alpha_enable = 0;
726 pipe->unpack_tight = 1;
727 pipe->unpack_align_msb = 0;
728 pipe->unpack_count = 3;
729 pipe->element3 = C3_ALPHA; /* alpha */
730 pipe->element2 = C2_R_Cr; /* R */
731 pipe->element1 = C0_G_Y; /* G */
732 pipe->element0 = C1_B_Cb; /* B */
733 pipe->bpp = 4; /* 4 bpp */
734 break;
735 case MDP_ARGB_8888:
736 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
737 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
738 pipe->a_bit = 3; /* alpha, 4 bits */
739 pipe->r_bit = 3; /* R, 8 bits */
740 pipe->b_bit = 3; /* B, 8 bits */
741 pipe->g_bit = 3; /* G, 8 bits */
742 pipe->alpha_enable = 1;
743 pipe->unpack_tight = 1;
744 pipe->unpack_align_msb = 0;
745 pipe->unpack_count = 3;
746 pipe->element3 = C3_ALPHA; /* alpha */
747 pipe->element2 = C2_R_Cr; /* R */
748 pipe->element1 = C0_G_Y; /* G */
749 pipe->element0 = C1_B_Cb; /* B */
750 pipe->bpp = 4; /* 4 bpp */
751 break;
752 case MDP_RGBA_8888:
753 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
754 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
755 pipe->a_bit = 3; /* alpha, 4 bits */
756 pipe->r_bit = 3; /* R, 8 bits */
757 pipe->b_bit = 3; /* B, 8 bits */
758 pipe->g_bit = 3; /* G, 8 bits */
759 pipe->alpha_enable = 1;
760 pipe->unpack_tight = 1;
761 pipe->unpack_align_msb = 0;
762 pipe->unpack_count = 3;
763 pipe->element3 = C3_ALPHA; /* alpha */
764 pipe->element2 = C1_B_Cb; /* B */
765 pipe->element1 = C0_G_Y; /* G */
766 pipe->element0 = C2_R_Cr; /* R */
767 pipe->bpp = 4; /* 4 bpp */
768 break;
769 case MDP_RGBX_8888:
770 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
771 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
772 pipe->a_bit = 3;
773 pipe->r_bit = 3; /* R, 8 bits */
774 pipe->b_bit = 3; /* B, 8 bits */
775 pipe->g_bit = 3; /* G, 8 bits */
776 pipe->alpha_enable = 0;
777 pipe->unpack_tight = 1;
778 pipe->unpack_align_msb = 0;
779 pipe->unpack_count = 3;
780 pipe->element3 = C3_ALPHA; /* alpha */
781 pipe->element2 = C1_B_Cb; /* B */
782 pipe->element1 = C0_G_Y; /* G */
783 pipe->element0 = C2_R_Cr; /* R */
784 pipe->bpp = 4; /* 4 bpp */
785 break;
786 case MDP_BGRA_8888:
787 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
788 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
789 pipe->a_bit = 3; /* alpha, 4 bits */
790 pipe->r_bit = 3; /* R, 8 bits */
791 pipe->b_bit = 3; /* B, 8 bits */
792 pipe->g_bit = 3; /* G, 8 bits */
793 pipe->alpha_enable = 1;
794 pipe->unpack_tight = 1;
795 pipe->unpack_align_msb = 0;
796 pipe->unpack_count = 3;
797 pipe->element3 = C3_ALPHA; /* alpha */
798 pipe->element2 = C2_R_Cr; /* R */
799 pipe->element1 = C0_G_Y; /* G */
800 pipe->element0 = C1_B_Cb; /* B */
801 pipe->bpp = 4; /* 4 bpp */
802 break;
803 case MDP_YCRYCB_H2V1:
804 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
805 pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
806 pipe->a_bit = 0; /* alpha, 4 bits */
807 pipe->r_bit = 3; /* R, 8 bits */
808 pipe->b_bit = 3; /* B, 8 bits */
809 pipe->g_bit = 3; /* G, 8 bits */
810 pipe->alpha_enable = 0;
811 pipe->unpack_tight = 1;
812 pipe->unpack_align_msb = 0;
813 pipe->unpack_count = 3;
814 pipe->element3 = C0_G_Y; /* G */
815 pipe->element2 = C2_R_Cr; /* R */
816 pipe->element1 = C0_G_Y; /* G */
817 pipe->element0 = C1_B_Cb; /* B */
818 pipe->bpp = 2; /* 2 bpp */
819 pipe->chroma_sample = MDP4_CHROMA_H2V1;
820 break;
821 case MDP_Y_CRCB_H2V1:
822 case MDP_Y_CBCR_H2V1:
823 case MDP_Y_CRCB_H2V2:
824 case MDP_Y_CBCR_H2V2:
825 case MDP_Y_CRCB_H1V1:
826 case MDP_Y_CBCR_H1V1:
827 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
828 pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_PLANAR;
829 pipe->a_bit = 0;
830 pipe->r_bit = 3; /* R, 8 bits */
831 pipe->b_bit = 3; /* B, 8 bits */
832 pipe->g_bit = 3; /* G, 8 bits */
833 pipe->alpha_enable = 0;
834 pipe->unpack_tight = 1;
835 pipe->unpack_align_msb = 0;
836 pipe->unpack_count = 1; /* 2 */
837 pipe->element3 = C0_G_Y; /* not used */
838 pipe->element2 = C0_G_Y; /* not used */
839 if (pipe->src_format == MDP_Y_CRCB_H2V1) {
840 pipe->element1 = C2_R_Cr; /* R */
841 pipe->element0 = C1_B_Cb; /* B */
842 pipe->chroma_sample = MDP4_CHROMA_H2V1;
843 } else if (pipe->src_format == MDP_Y_CRCB_H1V1) {
844 pipe->element1 = C2_R_Cr; /* R */
845 pipe->element0 = C1_B_Cb; /* B */
846 if (pipe->src_width > YUV_444_MAX_WIDTH)
847 pipe->chroma_sample = MDP4_CHROMA_H1V2;
848 else
849 pipe->chroma_sample = MDP4_CHROMA_RGB;
850 } else if (pipe->src_format == MDP_Y_CBCR_H2V1) {
851 pipe->element1 = C1_B_Cb; /* B */
852 pipe->element0 = C2_R_Cr; /* R */
853 pipe->chroma_sample = MDP4_CHROMA_H2V1;
854 } else if (pipe->src_format == MDP_Y_CBCR_H1V1) {
855 pipe->element1 = C1_B_Cb; /* B */
856 pipe->element0 = C2_R_Cr; /* R */
857 if (pipe->src_width > YUV_444_MAX_WIDTH)
858 pipe->chroma_sample = MDP4_CHROMA_H1V2;
859 else
860 pipe->chroma_sample = MDP4_CHROMA_RGB;
861 } else if (pipe->src_format == MDP_Y_CRCB_H2V2) {
862 pipe->element1 = C2_R_Cr; /* R */
863 pipe->element0 = C1_B_Cb; /* B */
864 pipe->chroma_sample = MDP4_CHROMA_420;
865 } else if (pipe->src_format == MDP_Y_CBCR_H2V2) {
866 pipe->element1 = C1_B_Cb; /* B */
867 pipe->element0 = C2_R_Cr; /* R */
868 pipe->chroma_sample = MDP4_CHROMA_420;
869 }
870 pipe->bpp = 2; /* 2 bpp */
871 break;
872 case MDP_Y_CBCR_H2V2_TILE:
873 case MDP_Y_CRCB_H2V2_TILE:
874 pipe->frame_format = MDP4_FRAME_FORMAT_VIDEO_SUPERTILE;
875 pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_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;
881 pipe->unpack_tight = 1;
882 pipe->unpack_align_msb = 0;
883 pipe->unpack_count = 1; /* 2 */
884 pipe->element3 = C0_G_Y; /* not used */
885 pipe->element2 = C0_G_Y; /* not used */
886 if (pipe->src_format == MDP_Y_CRCB_H2V2_TILE) {
887 pipe->element1 = C2_R_Cr; /* R */
888 pipe->element0 = C1_B_Cb; /* B */
889 pipe->chroma_sample = MDP4_CHROMA_420;
890 } else if (pipe->src_format == MDP_Y_CBCR_H2V2_TILE) {
891 pipe->element1 = C1_B_Cb; /* B */
892 pipe->element0 = C2_R_Cr; /* R */
893 pipe->chroma_sample = MDP4_CHROMA_420;
894 }
895 pipe->bpp = 2; /* 2 bpp */
896 break;
897 case MDP_Y_CR_CB_H2V2:
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +0530898 case MDP_Y_CR_CB_GH2V2:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700899 case MDP_Y_CB_CR_H2V2:
900 pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
901 pipe->fetch_plane = OVERLAY_PLANE_PLANAR;
902 pipe->a_bit = 0;
903 pipe->r_bit = 3; /* R, 8 bits */
904 pipe->b_bit = 3; /* B, 8 bits */
905 pipe->g_bit = 3; /* G, 8 bits */
906 pipe->alpha_enable = 0;
Adrian Salido-Moreno33dc7b92011-08-18 16:16:12 -0700907 pipe->chroma_sample = MDP4_CHROMA_420;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700908 pipe->bpp = 2; /* 2 bpp */
909 break;
910 default:
911 /* not likely */
912 mdp4_stat.err_format++;
913 return -ERANGE;
914 }
915
916 return 0;
917}
918
919/*
920 * color_key_convert: output with 12 bits color key
921 */
922static uint32 color_key_convert(int start, int num, uint32 color)
923{
924 uint32 data;
925
926 data = (color >> start) & ((1 << num) - 1);
927
928 /* convert to 8 bits */
929 if (num == 5)
930 data = ((data << 3) | (data >> 2));
931 else if (num == 6)
932 data = ((data << 2) | (data >> 4));
933
934 /* convert 8 bits to 12 bits */
935 data = (data << 4) | (data >> 4);
936
937 return data;
938}
939
940void transp_color_key(int format, uint32 transp,
941 uint32 *c0, uint32 *c1, uint32 *c2)
942{
943 int b_start, g_start, r_start;
944 int b_num, g_num, r_num;
945
946 switch (format) {
947 case MDP_RGB_565:
948 b_start = 0;
949 g_start = 5;
950 r_start = 11;
951 r_num = 5;
952 g_num = 6;
953 b_num = 5;
954 break;
955 case MDP_RGB_888:
956 case MDP_XRGB_8888:
957 case MDP_ARGB_8888:
958 case MDP_BGRA_8888:
959 b_start = 0;
960 g_start = 8;
961 r_start = 16;
962 r_num = 8;
963 g_num = 8;
964 b_num = 8;
965 break;
966 case MDP_RGBA_8888:
967 case MDP_RGBX_8888:
968 b_start = 16;
969 g_start = 8;
970 r_start = 0;
971 r_num = 8;
972 g_num = 8;
973 b_num = 8;
974 break;
975 case MDP_BGR_565:
976 b_start = 11;
977 g_start = 5;
978 r_start = 0;
979 r_num = 5;
980 g_num = 6;
981 b_num = 5;
982 break;
983 case MDP_Y_CB_CR_H2V2:
984 case MDP_Y_CBCR_H2V2:
985 case MDP_Y_CBCR_H2V1:
986 b_start = 8;
987 g_start = 16;
988 r_start = 0;
989 r_num = 8;
990 g_num = 8;
991 b_num = 8;
992 break;
993 case MDP_Y_CR_CB_H2V2:
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +0530994 case MDP_Y_CR_CB_GH2V2:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700995 case MDP_Y_CRCB_H2V2:
996 case MDP_Y_CRCB_H2V1:
997 case MDP_Y_CRCB_H1V1:
998 case MDP_Y_CBCR_H1V1:
999 b_start = 0;
1000 g_start = 16;
1001 r_start = 8;
1002 r_num = 8;
1003 g_num = 8;
1004 b_num = 8;
1005 break;
1006 default:
1007 b_start = 0;
1008 g_start = 8;
1009 r_start = 16;
1010 r_num = 8;
1011 g_num = 8;
1012 b_num = 8;
1013 break;
1014 }
1015
1016 *c0 = color_key_convert(g_start, g_num, transp);
1017 *c1 = color_key_convert(b_start, b_num, transp);
1018 *c2 = color_key_convert(r_start, r_num, transp);
1019}
1020
1021uint32 mdp4_overlay_format(struct mdp4_overlay_pipe *pipe)
1022{
1023 uint32 format;
1024
1025 format = 0;
1026
1027 if (pipe->solid_fill)
1028 format |= MDP4_FORMAT_SOLID_FILL;
1029
1030 if (pipe->unpack_align_msb)
1031 format |= MDP4_FORMAT_UNPACK_ALIGN_MSB;
1032
1033 if (pipe->unpack_tight)
1034 format |= MDP4_FORMAT_UNPACK_TIGHT;
1035
1036 if (pipe->alpha_enable)
1037 format |= MDP4_FORMAT_ALPHA_ENABLE;
1038
1039 if (pipe->flags & MDP_SOURCE_ROTATED_90)
1040 format |= MDP4_FORMAT_90_ROTATED;
1041 format |= (pipe->unpack_count << 13);
1042 format |= ((pipe->bpp - 1) << 9);
1043 format |= (pipe->a_bit << 6);
1044 format |= (pipe->r_bit << 4);
1045 format |= (pipe->b_bit << 2);
1046 format |= pipe->g_bit;
1047
1048 format |= (pipe->frame_format << 29);
1049
1050 if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR ||
1051 pipe->fetch_plane == OVERLAY_PLANE_PLANAR) {
1052 /* video/graphic */
1053 format |= (pipe->fetch_plane << 19);
1054 format |= (pipe->chroma_site << 28);
1055 format |= (pipe->chroma_sample << 26);
1056 }
1057
1058 return format;
1059}
1060
1061uint32 mdp4_overlay_unpack_pattern(struct mdp4_overlay_pipe *pipe)
1062{
1063 return (pipe->element3 << 24) | (pipe->element2 << 16) |
1064 (pipe->element1 << 8) | pipe->element0;
1065}
1066
1067/*
1068 * mdp4_overlayproc_cfg: only be called from base layer
1069 */
1070void mdp4_overlayproc_cfg(struct mdp4_overlay_pipe *pipe)
1071{
1072 uint32 data, intf;
1073 char *overlay_base;
1074
1075 intf = 0;
1076 if (pipe->mixer_num == MDP4_MIXER1) {
1077 overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
1078 intf = inpdw(MDP_BASE + 0x0038); /* MDP_DISP_INTF_SEL */
1079 intf >>= 4;
1080 intf &= 0x03;
1081 } else
1082 overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
1083
1084 if (mdp_is_in_isr == FALSE)
1085 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1086
1087 /*
1088 * BLT only siupport at primary display
1089 */
Vinay Kalia27020d12011-10-14 17:50:29 -07001090 if (pipe->blt_addr) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001091 int off, bpp;
1092#ifdef BLT_RGB565
1093 bpp = 2; /* overlay ouput is RGB565 */
1094#else
1095 bpp = 3; /* overlay ouput is RGB888 */
1096#endif
1097 data = pipe->src_height;
1098 data <<= 16;
1099 data |= pipe->src_width;
1100 outpdw(overlay_base + 0x0008, data); /* ROI, height + width */
Vinay Kalia27020d12011-10-14 17:50:29 -07001101 if (pipe->mixer_num == MDP4_MIXER0) {
1102 off = 0;
1103 if (pipe->ov_cnt & 0x01)
1104 off = pipe->src_height * pipe->src_width * bpp;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001105
Vinay Kalia27020d12011-10-14 17:50:29 -07001106 outpdw(overlay_base + 0x000c, pipe->blt_addr + off);
1107 /* overlay ouput is RGB888 */
1108 outpdw(overlay_base + 0x0010, pipe->src_width * bpp);
1109 outpdw(overlay_base + 0x001c, pipe->blt_addr + off);
1110 /* MDDI - BLT + on demand */
1111 outpdw(overlay_base + 0x0004, 0x08);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001112#ifdef BLT_RGB565
Vinay Kalia27020d12011-10-14 17:50:29 -07001113 outpdw(overlay_base + 0x0014, 0x1); /* RGB565 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001114#else
Vinay Kalia27020d12011-10-14 17:50:29 -07001115 outpdw(overlay_base + 0x0014, 0x0); /* RGB888 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001116#endif
Vinay Kalia27020d12011-10-14 17:50:29 -07001117 } else {
1118 if (ctrl->panel_mode & MDP4_PANEL_WRITEBACK) {
1119 off = 0;
1120 bpp = 2;
1121 if (pipe->ov_cnt & 0x01)
1122 off = pipe->src_height *
1123 pipe->src_width * bpp;
1124
1125 outpdw(overlay_base + 0x000c,
1126 pipe->blt_addr + off);
1127 /* overlay ouput is RGB888 */
1128 outpdw(overlay_base + 0x0010,
1129 pipe->src_width * bpp);
1130 outpdw(overlay_base + 0x001c,
1131 pipe->blt_addr + off);
1132 /* MDDI - BLT + on demand */
1133 outpdw(overlay_base + 0x0004, 0x08);
1134 outpdw(overlay_base + 0x0014, 0x1); /* RGB565 */
1135 }
1136 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001137 } else {
1138 data = pipe->src_height;
1139 data <<= 16;
1140 data |= pipe->src_width;
1141 outpdw(overlay_base + 0x0008, data); /* ROI, height + width */
1142 outpdw(overlay_base + 0x000c, pipe->srcp0_addr);
1143 outpdw(overlay_base + 0x0010, pipe->srcp0_ystride);
1144 outpdw(overlay_base + 0x0004, 0x01); /* directout */
1145 }
1146
1147 if (pipe->mixer_num == MDP4_MIXER1) {
1148 if (intf == TV_INTF) {
1149 outpdw(overlay_base + 0x0014, 0x02); /* yuv422 */
1150 /* overlay1 CSC config */
1151 outpdw(overlay_base + 0x0200, 0x05); /* rgb->yuv */
1152 }
1153 }
1154
1155#ifdef MDP4_IGC_LUT_ENABLE
1156 outpdw(overlay_base + 0x0014, 0x4); /* GC_LUT_EN, 888 */
1157#endif
1158
1159 if (mdp_is_in_isr == FALSE)
1160 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1161}
1162
1163int mdp4_overlay_pipe_staged(int mixer)
1164{
1165 uint32 data, mask, i;
1166 int p1, p2;
1167
1168 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1169 data = inpdw(MDP_BASE + 0x10100);
1170 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1171 p1 = 0;
1172 p2 = 0;
1173 for (i = 0; i < 8; i++) {
1174 mask = data & 0x0f;
1175 if (mask) {
1176 if (mask <= 4)
1177 p1++;
1178 else
1179 p2++;
1180 }
1181 data >>= 4;
1182 }
1183
1184 if (mixer)
1185 return p2;
1186 else
1187 return p1;
1188}
1189
kuogee hsieh405dc302011-07-21 15:06:59 -07001190int mdp4_mixer_info(int mixer_num, struct mdp_mixer_info *info)
1191{
1192
1193 int ndx, cnt;
1194 struct mdp4_overlay_pipe *pipe;
1195
1196 if (mixer_num > MDP4_MIXER_MAX)
1197 return -ENODEV;
1198
1199 cnt = 0;
1200 ndx = 1; /* ndx 0 if not used */
1201
1202 for ( ; ndx < MDP4_MIXER_STAGE_MAX; ndx++) {
1203 pipe = ctrl->stage[mixer_num][ndx];
1204 if (pipe == NULL)
1205 continue;
1206 info->z_order = pipe->mixer_stage - MDP4_MIXER_STAGE0;
1207 info->ptype = pipe->pipe_type;
1208 info->pnum = pipe->pipe_num;
1209 info->pndx = pipe->pipe_ndx;
1210 info->mixer_num = pipe->mixer_num;
1211 info++;
1212 cnt++;
1213 }
1214 return cnt;
1215}
1216
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001217void mdp4_mixer_stage_up(struct mdp4_overlay_pipe *pipe)
1218{
1219 uint32 data, mask, snum, stage, mixer, pnum;
Adrian Salido-Morenoc4302232011-09-26 12:54:03 -07001220 struct mdp4_overlay_pipe *spipe;
1221
1222 spipe = mdp4_overlay_stage_pipe(pipe->mixer_num, pipe->mixer_stage);
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001223 if ((spipe != NULL) && (spipe->pipe_num != pipe->pipe_num)) {
Adrian Salido-Morenoc4302232011-09-26 12:54:03 -07001224 pr_err("%s: unable to stage pipe=%d at mixer_stage=%d\n",
1225 __func__, pipe->pipe_ndx, pipe->mixer_stage);
1226 return;
1227 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001228
1229 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1230
1231 stage = pipe->mixer_stage;
1232 mixer = pipe->mixer_num;
1233 pnum = pipe->pipe_num;
1234
1235 /* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1 */
1236 data = inpdw(MDP_BASE + 0x10100);
1237
1238 if (mixer == MDP4_MIXER1)
1239 stage += 8;
1240
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001241 if (pipe->pipe_type == OVERLAY_TYPE_BF) {
1242 snum = 16 + (4 * mixer);
1243 } else if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {/* VG1 and VG2 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001244 pnum -= OVERLAY_PIPE_VG1; /* start from 0 */
1245 snum = 0;
1246 snum += (4 * pnum);
1247 } else {
1248 snum = 8;
1249 snum += (4 * pnum); /* RGB1 and RGB2 */
1250 }
1251
1252 mask = 0x0f;
1253 mask <<= snum;
1254 stage <<= snum;
1255 data &= ~mask; /* clear old bits */
1256
1257 data |= stage;
1258
1259 outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
1260
1261 data = inpdw(MDP_BASE + 0x10100);
1262
1263 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1264
1265 ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = pipe; /* keep it */
1266}
1267
1268void mdp4_mixer_stage_down(struct mdp4_overlay_pipe *pipe)
1269{
1270 uint32 data, mask, snum, stage, mixer, pnum;
1271
1272 stage = pipe->mixer_stage;
1273 mixer = pipe->mixer_num;
1274 pnum = pipe->pipe_num;
1275
1276 if (pipe != ctrl->stage[mixer][stage]) /* not runing */
1277 return;
1278
1279 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1280
1281 /* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1 */
1282 data = inpdw(MDP_BASE + 0x10100);
1283
1284 if (mixer == MDP4_MIXER1)
1285 stage += 8;
1286
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001287 if (pipe->pipe_type == OVERLAY_TYPE_BF) {
1288 snum = 16 + (4 * mixer);
1289 } else if (pipe->pipe_num >= OVERLAY_PIPE_VG1) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001290 pnum -= OVERLAY_PIPE_VG1; /* start from 0 */
1291 snum = 0;
1292 snum += (4 * pnum);
1293 } else {
1294 snum = 8;
1295 snum += (4 * pnum); /* RGB1 and RGB2 */
1296 }
1297
1298 mask = 0x0f;
1299 mask <<= snum;
1300 data &= ~mask; /* clear old bits */
1301
1302 outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
1303
1304 data = inpdw(MDP_BASE + 0x10100);
1305
1306 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1307
1308 ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = NULL; /* clear it */
1309}
1310
1311void mdp4_mixer_blend_setup(struct mdp4_overlay_pipe *pipe)
1312{
1313 struct mdp4_overlay_pipe *bg_pipe;
1314 unsigned char *overlay_base, *rgb_base;
1315 uint32 c0, c1, c2, blend_op, constant_color = 0, rgb_src_format;
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001316 uint32 fg_color3_out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001317 int off;
1318
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001319 if (pipe->mixer_stage == MDP4_MIXER_STAGE_BASE)
1320 return;
1321
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001322 if (pipe->mixer_num) /* mixer number, /dev/fb0, /dev/fb1 */
1323 overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
1324 else
1325 overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
1326
1327 /* stage 0 to stage 2 */
1328 off = 0x20 * (pipe->mixer_stage - MDP4_MIXER_STAGE0);
1329
1330 bg_pipe = mdp4_overlay_stage_pipe(pipe->mixer_num,
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001331 MDP4_MIXER_STAGE_BASE);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001332 if (bg_pipe == NULL) {
1333 pr_err("%s: Error: no bg_pipe\n", __func__);
1334 return;
1335 }
1336
1337 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1338
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001339 blend_op = (MDP4_BLEND_FG_ALPHA_FG_CONST |
1340 MDP4_BLEND_BG_ALPHA_BG_CONST);
1341 outpdw(overlay_base + off + 0x108, pipe->alpha);
1342 outpdw(overlay_base + off + 0x10c, 0xff - pipe->alpha);
1343 fg_color3_out = 0; /* keep bg alpha by default */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001344
1345 if (pipe->is_fg) {
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001346 if (pipe->alpha == 0xff &&
1347 bg_pipe->pipe_num <= OVERLAY_PIPE_RGB2) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001348 rgb_base = MDP_BASE + MDP4_RGB_BASE;
1349 rgb_base += MDP4_RGB_OFF * bg_pipe->pipe_num;
1350 rgb_src_format = inpdw(rgb_base + 0x50);
1351 rgb_src_format |= MDP4_FORMAT_SOLID_FILL;
1352 outpdw(rgb_base + 0x50, rgb_src_format);
1353 outpdw(rgb_base + 0x1008, constant_color);
1354 }
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001355 } else if (pipe->alpha_enable) {
1356 /* pick fg alpha */
1357 blend_op = (MDP4_BLEND_BG_ALPHA_FG_PIXEL |
1358 MDP4_BLEND_FG_ALPHA_FG_PIXEL |
1359 MDP4_BLEND_BG_INV_ALPHA);
1360 fg_color3_out = 1; /* keep fg alpha */
1361 } else if (bg_pipe->alpha_enable) {
1362 /* pick bg alpha */
1363 blend_op = (MDP4_BLEND_BG_ALPHA_BG_PIXEL |
1364 MDP4_BLEND_FG_ALPHA_BG_PIXEL |
1365 MDP4_BLEND_FG_INV_ALPHA);
1366 fg_color3_out = 0; /* keep bg alpha */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001367 }
1368
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001369 if (pipe->transp != MDP_TRANSP_NOP) {
1370 if (pipe->is_fg) {
1371 transp_color_key(pipe->src_format, pipe->transp,
1372 &c0, &c1, &c2);
1373 /* Fg blocked */
1374 blend_op |= MDP4_BLEND_FG_TRANSP_EN;
1375 /* lower limit */
1376 outpdw(overlay_base + off + 0x110,
1377 (c1 << 16 | c0));/* low */
1378 outpdw(overlay_base + off + 0x114, c2);/* low */
1379 /* upper limit */
1380 outpdw(overlay_base + off + 0x118,
1381 (c1 << 16 | c0));
1382 outpdw(overlay_base + off + 0x11c, c2);
1383 } else {
1384 transp_color_key(bg_pipe->src_format,
1385 pipe->transp, &c0, &c1, &c2);
1386 /* bg blocked */
1387 blend_op |= MDP4_BLEND_BG_TRANSP_EN;
1388 /* lower limit */
1389 outpdw(overlay_base + 0x180,
1390 (c1 << 16 | c0));/* low */
1391 outpdw(overlay_base + 0x184, c2);/* low */
1392 /* upper limit */
1393 outpdw(overlay_base + 0x188,
1394 (c1 << 16 | c0));/* high */
1395 outpdw(overlay_base + 0x18c, c2);/* high */
1396 }
1397 }
1398
1399 outpdw(overlay_base + off + 0x104, blend_op);
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001400 outpdw(overlay_base + (off << 5) + 0x1004, fg_color3_out);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001401
1402 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1403}
1404
1405void mdp4_overlay_reg_flush(struct mdp4_overlay_pipe *pipe, int all)
1406{
1407 struct mdp4_overlay_pipe *bg_pipe;
1408 uint32 bits = 0;
1409
1410 if (pipe->mixer_num == MDP4_MIXER1)
1411 bits |= 0x02;
1412 else
1413 bits |= 0x01;
1414
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001415 if (all && pipe->pipe_type != OVERLAY_TYPE_BF) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001416 if (pipe->pipe_num <= OVERLAY_PIPE_RGB2) {
1417 if (pipe->pipe_num == OVERLAY_PIPE_RGB2)
1418 bits |= 0x20;
1419 else
1420 bits |= 0x10;
1421 } else {
1422 if (pipe->is_fg && pipe->alpha == 0xFF) {
1423 bg_pipe = mdp4_overlay_stage_pipe(
1424 pipe->mixer_num,
1425 MDP4_MIXER_STAGE_BASE);
1426 if (bg_pipe->pipe_num <= OVERLAY_PIPE_RGB2) {
1427 if (bg_pipe->pipe_num ==
1428 OVERLAY_PIPE_RGB2)
1429 bits |= 0x20;
1430 else
1431 bits |= 0x10;
1432 }
1433 }
1434 if (pipe->pipe_num == OVERLAY_PIPE_VG2)
1435 bits |= 0x08;
1436 else
1437 bits |= 0x04;
1438 }
1439 }
1440
1441 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1442 outpdw(MDP_BASE + 0x18000, bits); /* MDP_OVERLAY_REG_FLUSH */
1443 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1444}
1445
1446struct mdp4_overlay_pipe *mdp4_overlay_stage_pipe(int mixer, int stage)
1447{
1448 return ctrl->stage[mixer][stage];
1449}
1450
1451struct mdp4_overlay_pipe *mdp4_overlay_ndx2pipe(int ndx)
1452{
1453 struct mdp4_overlay_pipe *pipe;
1454
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001455 if (ndx <= 0 || ndx > OVERLAY_PIPE_MAX)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001456 return NULL;
1457
1458 pipe = &ctrl->plist[ndx - 1]; /* ndx start from 1 */
1459
1460 if (pipe->pipe_used == 0)
1461 return NULL;
1462
1463 return pipe;
1464}
1465
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001466struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(int ptype, int mixer)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001467{
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001468 int i;
1469 struct mdp4_overlay_pipe *pipe;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001470
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001471 for (i = 0; i < OVERLAY_PIPE_MAX; i++) {
1472 pipe = &ctrl->plist[i];
1473 if ((pipe->pipe_used == 0) && ((pipe->pipe_type == ptype) ||
1474 (ptype == OVERLAY_TYPE_RGB &&
1475 pipe->pipe_type == OVERLAY_TYPE_VIDEO))) {
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001476 if (ptype == OVERLAY_TYPE_BF &&
1477 mixer != pipe->mixer_num)
1478 continue;
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001479 init_completion(&pipe->comp);
1480 init_completion(&pipe->dmas_comp);
1481 pr_info("%s: pipe=%x ndx=%d num=%d\n", __func__,
1482 (int)pipe, pipe->pipe_ndx, pipe->pipe_num);
1483 return pipe;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001484 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001485 }
1486
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001487 pr_err("%s: ptype=%d FAILED\n", __func__, ptype);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001488
1489 return NULL;
1490}
1491
1492
1493void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe)
1494{
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001495 uint32 ptype, num, ndx, mixer;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001496
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001497 pr_info("%s: pipe=%x ndx=%d\n", __func__, (int)pipe, pipe->pipe_ndx);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001498
1499 ptype = pipe->pipe_type;
1500 num = pipe->pipe_num;
1501 ndx = pipe->pipe_ndx;
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001502 mixer = pipe->mixer_num;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001503
1504 memset(pipe, 0, sizeof(*pipe));
1505
1506 pipe->pipe_type = ptype;
1507 pipe->pipe_num = num;
1508 pipe->pipe_ndx = ndx;
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001509 pipe->mixer_num = mixer;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001510}
1511
1512int mdp4_overlay_req_check(uint32 id, uint32 z_order, uint32 mixer)
1513{
1514 struct mdp4_overlay_pipe *pipe;
1515
1516 pipe = ctrl->stage[mixer][z_order];
1517
1518 if (pipe == NULL)
1519 return 0;
1520
1521 if (pipe->pipe_ndx == id) /* same req, recycle */
1522 return 0;
1523
1524 if (id == MSMFB_NEW_REQUEST) { /* new request */
1525 if (pipe->pipe_num >= OVERLAY_PIPE_VG1) /* share pipe */
1526 return 0;
1527 }
1528
1529 return -EPERM;
1530}
1531
1532static int mdp4_overlay_validate_downscale(struct mdp_overlay *req,
1533 struct msm_fb_data_type *mfd, uint32 perf_level, uint32 pclk_rate)
1534{
1535 __u32 panel_clk_khz, mdp_clk_khz;
1536 __u32 num_hsync_pix_clks, mdp_clks_per_hsync, src_wh;
1537 __u32 hsync_period_ps, mdp_period_ps, total_hsync_period_ps;
1538 unsigned long fill_rate_y_dir, fill_rate_x_dir;
1539 unsigned long fillratex100, mdp_pixels_produced;
1540 unsigned long mdp_clk_hz;
1541
1542 pr_debug("%s: LCDC Mode Downscale validation with MDP Core"
1543 " Clk rate\n", __func__);
1544 pr_debug("src_w %u, src_h %u, dst_w %u, dst_h %u\n",
1545 req->src_rect.w, req->src_rect.h, req->dst_rect.w,
1546 req->dst_rect.h);
1547
1548
1549 panel_clk_khz = pclk_rate/1000;
1550 mdp_clk_hz = mdp_perf_level2clk_rate(perf_level);
1551
Ravishangar Kalyanamc42862a2011-09-14 11:42:34 -07001552 if (!mdp_clk_hz || !req->dst_rect.w || !req->dst_rect.h) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001553 pr_debug("mdp_perf_level2clk_rate returned 0,"
Ravishangar Kalyanamc42862a2011-09-14 11:42:34 -07001554 "or dst_rect height/width is 0,"
1555 "Downscale Validation incomplete\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001556 return 0;
1557 }
1558
1559 mdp_clk_khz = mdp_clk_hz/1000;
1560
1561 num_hsync_pix_clks = mfd->panel_info.lcdc.h_back_porch +
1562 mfd->panel_info.lcdc.h_front_porch +
1563 mfd->panel_info.lcdc.h_pulse_width +
1564 mfd->panel_info.xres;
1565
1566 hsync_period_ps = 1000000000/panel_clk_khz;
1567 mdp_period_ps = 1000000000/mdp_clk_khz;
1568
1569 total_hsync_period_ps = num_hsync_pix_clks * hsync_period_ps;
1570 mdp_clks_per_hsync = total_hsync_period_ps/mdp_period_ps;
1571
1572 pr_debug("hsync_period_ps %u, mdp_period_ps %u,"
1573 "total_hsync_period_ps %u\n", hsync_period_ps,
1574 mdp_period_ps, total_hsync_period_ps);
1575
1576 src_wh = req->src_rect.w * req->src_rect.h;
1577 if (src_wh % req->dst_rect.h)
1578 fill_rate_y_dir = (src_wh / req->dst_rect.h) + 1;
1579 else
1580 fill_rate_y_dir = (src_wh / req->dst_rect.h);
1581
1582 fill_rate_x_dir = (mfd->panel_info.xres - req->dst_rect.w)
1583 + req->src_rect.w;
1584
1585 if (fill_rate_y_dir >= fill_rate_x_dir)
1586 fillratex100 = 100 * fill_rate_y_dir / mfd->panel_info.xres;
1587 else
1588 fillratex100 = 100 * fill_rate_x_dir / mfd->panel_info.xres;
1589
1590 pr_debug("mdp_clks_per_hsync %u, fill_rate_y_dir %lu,"
1591 "fill_rate_x_dir %lu\n", mdp_clks_per_hsync,
1592 fill_rate_y_dir, fill_rate_x_dir);
1593
1594 mdp_pixels_produced = 100 * mdp_clks_per_hsync/fillratex100;
1595 pr_debug("fillratex100 %lu, mdp_pixels_produced %lu\n",
1596 fillratex100, mdp_pixels_produced);
1597 if (mdp_pixels_produced <= mfd->panel_info.xres) {
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07001598 pr_err("%s():display underflow detected with downscale"
1599 " params\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001600 return -ERANGE;
1601 }
1602
1603 return 0;
1604}
1605
1606static int mdp4_overlay_req2pipe(struct mdp_overlay *req, int mixer,
1607 struct mdp4_overlay_pipe **ppipe,
1608 struct msm_fb_data_type *mfd)
1609{
1610 struct mdp4_overlay_pipe *pipe;
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001611 int ret, ptype;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001612
1613 if (mfd == NULL) {
1614 pr_err("%s: mfd == NULL, -ENODEV\n", __func__);
1615 return -ENODEV;
1616 }
1617
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001618 if (mixer >= MDP4_MIXER_MAX) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001619 pr_err("%s: mixer out of range!\n", __func__);
1620 mdp4_stat.err_mixer++;
1621 return -ERANGE;
1622 }
1623
1624 if (req->z_order < 0 || req->z_order > 2) {
1625 pr_err("%s: z_order=%d out of range!\n", __func__,
1626 req->z_order);
1627 mdp4_stat.err_zorder++;
1628 return -ERANGE;
1629 }
1630
1631 if (req->src_rect.h == 0 || req->src_rect.w == 0) {
1632 pr_err("%s: src img of zero size!\n", __func__);
1633 mdp4_stat.err_size++;
1634 return -EINVAL;
1635 }
1636
1637
1638 if (req->dst_rect.h > (req->src_rect.h * 8)) { /* too much */
1639 mdp4_stat.err_scale++;
1640 pr_err("%s: scale up, too much (h)!\n", __func__);
1641 return -ERANGE;
1642 }
1643
1644 if (req->src_rect.h > (req->dst_rect.h * 8)) { /* too little */
1645 mdp4_stat.err_scale++;
1646 pr_err("%s: scale down, too little (h)!\n", __func__);
1647 return -ERANGE;
1648 }
1649
1650 if (req->dst_rect.w > (req->src_rect.w * 8)) { /* too much */
1651 mdp4_stat.err_scale++;
1652 pr_err("%s: scale up, too much (w)!\n", __func__);
1653 return -ERANGE;
1654 }
1655
1656 if (req->src_rect.w > (req->dst_rect.w * 8)) { /* too little */
1657 mdp4_stat.err_scale++;
1658 pr_err("%s: scale down, too little (w)!\n", __func__);
1659 return -ERANGE;
1660 }
1661
1662 if (mdp_hw_revision == MDP4_REVISION_V1) {
1663 /* non integer down saceling ratio smaller than 1/4
1664 * is not supportted
1665 */
1666 if (req->src_rect.h > (req->dst_rect.h * 4)) {
1667 if (req->src_rect.h % req->dst_rect.h) {
1668 mdp4_stat.err_scale++;
1669 pr_err("%s: need integer (h)!\n", __func__);
1670 return -ERANGE;
1671 }
1672 }
1673
1674 if (req->src_rect.w > (req->dst_rect.w * 4)) {
1675 if (req->src_rect.w % req->dst_rect.w) {
1676 mdp4_stat.err_scale++;
1677 pr_err("%s: need integer (w)!\n", __func__);
1678 return -ERANGE;
1679 }
1680 }
1681 }
1682
1683 if (((req->src_rect.x + req->src_rect.w) > req->src.width) ||
1684 ((req->src_rect.y + req->src_rect.h) > req->src.height)) {
1685 mdp4_stat.err_size++;
1686 pr_err("%s invalid src rectangle\n", __func__);
1687 return -ERANGE;
1688 }
1689
1690 if (ctrl->panel_3d != MDP4_3D_SIDE_BY_SIDE) {
1691 int xres;
1692 int yres;
1693
1694 xres = mfd->panel_info.xres;
1695 yres = mfd->panel_info.yres;
1696
1697 if (((req->dst_rect.x + req->dst_rect.w) > xres) ||
1698 ((req->dst_rect.y + req->dst_rect.h) > yres)) {
1699 mdp4_stat.err_size++;
1700 pr_err("%s invalid dst rectangle\n", __func__);
1701 return -ERANGE;
1702 }
1703 }
1704
1705 ptype = mdp4_overlay_format2type(req->src.format);
1706 if (ptype < 0) {
1707 pr_err("%s: mdp4_overlay_format2type!\n", __func__);
1708 return ptype;
1709 }
1710
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001711 if (req->flags & MDP_OV_PIPE_SHARE)
1712 ptype = OVERLAY_TYPE_VIDEO; /* VG pipe supports both RGB+YUV */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001713
1714 if (req->id == MSMFB_NEW_REQUEST) /* new request */
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07001715 pipe = mdp4_overlay_pipe_alloc(ptype, mixer);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001716 else
1717 pipe = mdp4_overlay_ndx2pipe(req->id);
1718
1719 if (pipe == NULL) {
1720 pr_err("%s: pipe == NULL!\n", __func__);
1721 return -ENOMEM;
1722 }
1723
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001724 pipe->src_format = req->src.format;
1725 ret = mdp4_overlay_format2pipe(pipe);
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001726
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001727 if (ret < 0) {
1728 pr_err("%s: mdp4_overlay_format2pipe!\n", __func__);
1729 return ret;
1730 }
1731
1732 /*
1733 * base layer == 1, reserved for frame buffer
1734 * zorder 0 == stage 0 == 2
1735 * zorder 1 == stage 1 == 3
1736 * zorder 2 == stage 2 == 4
1737 */
1738 if (req->id == MSMFB_NEW_REQUEST) { /* new request */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001739 pipe->pipe_used++;
1740 pipe->mixer_num = mixer;
1741 pipe->mixer_stage = req->z_order + MDP4_MIXER_STAGE0;
1742 pr_debug("%s: zorder=%d pipe ndx=%d num=%d\n", __func__,
1743 req->z_order, pipe->pipe_ndx, pipe->pipe_num);
1744
1745 }
1746
1747 pipe->src_width = req->src.width & 0x07ff; /* source img width */
1748 pipe->src_height = req->src.height & 0x07ff; /* source img height */
1749 pipe->src_h = req->src_rect.h & 0x07ff;
1750 pipe->src_w = req->src_rect.w & 0x07ff;
1751 pipe->src_y = req->src_rect.y & 0x07ff;
1752 pipe->src_x = req->src_rect.x & 0x07ff;
1753 pipe->dst_h = req->dst_rect.h & 0x07ff;
1754 pipe->dst_w = req->dst_rect.w & 0x07ff;
1755 pipe->dst_y = req->dst_rect.y & 0x07ff;
1756 pipe->dst_x = req->dst_rect.x & 0x07ff;
1757
1758 pipe->op_mode = 0;
1759
1760 if (req->flags & MDP_FLIP_LR)
1761 pipe->op_mode |= MDP4_OP_FLIP_LR;
1762
1763 if (req->flags & MDP_FLIP_UD)
1764 pipe->op_mode |= MDP4_OP_FLIP_UD;
1765
1766 if (req->flags & MDP_DITHER)
1767 pipe->op_mode |= MDP4_OP_DITHER_EN;
1768
1769 if (req->flags & MDP_DEINTERLACE)
1770 pipe->op_mode |= MDP4_OP_DEINT_EN;
1771
1772 if (req->flags & MDP_DEINTERLACE_ODD)
1773 pipe->op_mode |= MDP4_OP_DEINT_ODD_REF;
1774
1775 pipe->is_fg = req->is_fg;/* control alpha and color key */
1776
1777 pipe->alpha = req->alpha & 0x0ff;
1778
1779 pipe->transp = req->transp_mask;
1780
1781 *ppipe = pipe;
1782
1783 return 0;
1784}
1785
1786static int get_img(struct msmfb_data *img, struct fb_info *info,
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001787 unsigned long *start, unsigned long *len, struct file **srcp_file,
1788 struct ion_handle **srcp_ihdl)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001789{
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001790#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
1791 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1792#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001793 struct file *file;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001794 int put_needed, ret = 0, fb_num;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001795#ifdef CONFIG_ANDROID_PMEM
1796 unsigned long vstart;
1797#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001798 if (img->flags & MDP_BLIT_SRC_GEM) {
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001799 *srcp_file = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001800 return kgsl_gem_obj_addr(img->memory_id, (int) img->priv,
1801 start, len);
1802 }
1803
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001804 if (img->flags & MDP_MEMORY_ID_TYPE_FB) {
1805 file = fget_light(img->memory_id, &put_needed);
1806 if (file == NULL)
1807 return -EINVAL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001808
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001809 if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
1810 fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
1811 if (get_fb_phys_info(start, len, fb_num))
1812 ret = -1;
1813 else
1814 *srcp_file = file;
1815 } else
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001816 ret = -1;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07001817 if (ret)
1818 fput_light(file, put_needed);
1819 return ret;
1820 }
1821
1822#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
1823 *srcp_ihdl = ion_import_fd(mfd->client, img->memory_id);
1824 if (IS_ERR_OR_NULL(*srcp_ihdl))
1825 return PTR_ERR(*srcp_ihdl);
1826 if (!ion_phys(mfd->client, *srcp_ihdl, start, (size_t *) len))
1827 return 0;
1828 else
1829 return -EINVAL;
1830#endif
1831#ifdef CONFIG_ANDROID_PMEM
1832 if (!get_pmem_file(img->memory_id, start, &vstart,
1833 len, srcp_file))
1834 return 0;
1835 else
1836 return -EINVAL;
1837#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001838}
1839
kuogee hsieh4aea2742011-07-06 11:05:05 -07001840#ifdef CONFIG_FB_MSM_MIPI_DSI
1841int mdp4_overlay_3d_sbys(struct fb_info *info, struct msmfb_overlay_3d *req)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001842{
1843 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1844 int ret = -EPERM;
1845
1846 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
1847 return -EINTR;
1848
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001849 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
kuogee hsieh4aea2742011-07-06 11:05:05 -07001850 mdp4_dsi_cmd_3d_sbys(mfd, req);
1851 ret = 0;
1852 } else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
1853 mdp4_dsi_video_3d_sbys(mfd, req);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001854 ret = 0;
1855 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001856 mutex_unlock(&mfd->dma->ov_mutex);
1857
1858 return ret;
1859}
kuogee hsieh4aea2742011-07-06 11:05:05 -07001860#else
1861int mdp4_overlay_3d_sbys(struct fb_info *info, struct msmfb_overlay_3d *req)
1862{
1863 /* do nothing */
1864 return -EPERM;
1865}
1866#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001867
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001868int mdp4_overlay_blt(struct fb_info *info, struct msmfb_overlay_blt *req)
1869{
1870 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1871
1872 if (mfd == NULL)
1873 return -ENODEV;
1874
1875 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
1876 return -EINTR;
1877
1878 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
1879 mdp4_dsi_overlay_blt(mfd, req);
1880 else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
1881 mdp4_dsi_video_overlay_blt(mfd, req);
1882 else if (ctrl->panel_mode & MDP4_PANEL_LCDC)
1883 mdp4_lcdc_overlay_blt(mfd, req);
1884
1885 mutex_unlock(&mfd->dma->ov_mutex);
1886
1887 return 0;
1888}
1889
1890int mdp4_overlay_blt_offset(struct fb_info *info, struct msmfb_overlay_blt *req)
1891{
1892 int ret = 0;
1893
1894 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1895
1896 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
1897 return -EINTR;
1898
1899 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
1900 ret = mdp4_dsi_overlay_blt_offset(mfd, req);
1901 else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO)
1902 ret = mdp4_dsi_video_overlay_blt_offset(mfd, req);
1903 else if (ctrl->panel_mode & MDP4_PANEL_LCDC)
1904 ret = mdp4_lcdc_overlay_blt_offset(mfd, req);
1905
1906 mutex_unlock(&mfd->dma->ov_mutex);
1907
1908 return ret;
1909}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001910
1911int mdp4_overlay_get(struct fb_info *info, struct mdp_overlay *req)
1912{
1913 struct mdp4_overlay_pipe *pipe;
1914
1915 pipe = mdp4_overlay_ndx2pipe(req->id);
1916 if (pipe == NULL)
1917 return -ENODEV;
1918
1919 *req = pipe->req_data;
1920
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07001921 if (mdp4_overlay_borderfill_supported())
1922 req->flags |= MDP_BORDERFILL_SUPPORTED;
1923
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001924 return 0;
1925}
1926
1927#define OVERLAY_VGA_SIZE 0x04B000
1928#define OVERLAY_720P_TILE_SIZE 0x0E6000
1929#define OVERLAY_WSVGA_SIZE 0x98000 /* 1024x608, align 600 to 32bit */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001930
1931#ifdef CONFIG_MSM_BUS_SCALING
1932#define OVERLAY_BUS_SCALE_TABLE_BASE 6
1933#endif
1934
1935static int mdp4_overlay_is_rgb_type(int format)
1936{
1937 switch (format) {
1938 case MDP_RGB_565:
1939 case MDP_RGB_888:
1940 case MDP_BGR_565:
1941 case MDP_XRGB_8888:
1942 case MDP_ARGB_8888:
1943 case MDP_RGBA_8888:
1944 case MDP_BGRA_8888:
1945 case MDP_RGBX_8888:
1946 return 1;
1947 default:
1948 return 0;
1949 }
1950}
1951
1952static uint32 mdp4_overlay_get_perf_level(struct mdp_overlay *req)
1953{
1954 int is_fg;
1955
1956 if (req->is_fg && ((req->alpha & 0x0ff) == 0xff))
1957 is_fg = 1;
1958
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -07001959 if (mdp4_extn_disp)
1960 return OVERLAY_PERF_LEVEL1;
1961
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001962 if (req->flags & MDP_DEINTERLACE)
1963 return OVERLAY_PERF_LEVEL1;
1964
Adrian Salido-Morenoc174d302011-12-13 15:38:26 -08001965 if (ctrl->plist[OVERLAY_PIPE_VG1].pipe_used &&
1966 ctrl->plist[OVERLAY_PIPE_VG2].pipe_used)
1967 return OVERLAY_PERF_LEVEL1;
1968
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001969 if (mdp4_overlay_is_rgb_type(req->src.format) && is_fg &&
1970 ((req->src.width * req->src.height) <= OVERLAY_WSVGA_SIZE))
1971 return OVERLAY_PERF_LEVEL4;
1972 else if (mdp4_overlay_is_rgb_type(req->src.format))
1973 return OVERLAY_PERF_LEVEL1;
1974
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001975 if (req->src.width*req->src.height <= OVERLAY_VGA_SIZE)
1976 return OVERLAY_PERF_LEVEL3;
1977 else if (req->src.width*req->src.height <= OVERLAY_720P_TILE_SIZE)
1978 return OVERLAY_PERF_LEVEL2;
1979 else
1980 return OVERLAY_PERF_LEVEL1;
1981}
1982
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -07001983void mdp4_update_perf_level(u32 perf_level)
1984{
1985 new_perf_level = perf_level;
1986}
1987
kuogee hsiehc4b8b2f2011-07-12 13:32:14 -07001988void mdp4_set_perf_level(void)
1989{
1990 static int old_perf_level;
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -07001991 int cur_perf_level;
kuogee hsiehc4b8b2f2011-07-12 13:32:14 -07001992
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -07001993 if (mdp4_extn_disp)
1994 cur_perf_level = OVERLAY_PERF_LEVEL1;
1995 else
1996 cur_perf_level = new_perf_level;
1997
1998 if (old_perf_level != cur_perf_level) {
1999 mdp_set_core_clk(cur_perf_level);
2000 old_perf_level = cur_perf_level;
kuogee hsiehc4b8b2f2011-07-12 13:32:14 -07002001 }
2002}
2003
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07002004static void mdp4_overlay_update_blt_mode(struct msm_fb_data_type *mfd)
2005{
Adrian Salido-Moreno6a601cd2011-12-13 18:16:25 -08002006 if (mfd->use_ov0_blt == mfd->ov0_blt_state)
2007 return;
2008
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07002009 if (mfd->use_ov0_blt) {
2010 if (mfd->panel_info.type == LCDC_PANEL)
2011 mdp4_lcdc_overlay_blt_start(mfd);
2012 else if (mfd->panel_info.type == MIPI_VIDEO_PANEL)
2013 mdp4_dsi_video_blt_start(mfd);
2014 else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
2015 mdp4_dsi_overlay_blt_start(mfd);
2016 } else {
2017 if (mfd->panel_info.type == LCDC_PANEL)
2018 mdp4_lcdc_overlay_blt_stop(mfd);
2019 else if (mfd->panel_info.type == MIPI_VIDEO_PANEL)
2020 mdp4_dsi_video_blt_stop(mfd);
2021 else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD)
2022 mdp4_dsi_overlay_blt_stop(mfd);
2023 }
Adrian Salido-Moreno6a601cd2011-12-13 18:16:25 -08002024 mfd->ov0_blt_state = mfd->use_ov0_blt;
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07002025}
2026
2027static u32 mdp4_overlay_blt_enable(struct mdp_overlay *req,
2028 struct msm_fb_data_type *mfd, uint32 perf_level)
2029{
2030 u32 clk_rate = mfd->panel_info.clk_rate;
2031 u32 pull_mode = 0, use_blt = 0;
2032
2033 if (mfd->panel_info.type == MIPI_VIDEO_PANEL)
2034 clk_rate = (&mfd->panel_info.mipi)->dsi_pclk_rate;
2035
2036 if ((mfd->panel_info.type == LCDC_PANEL) ||
2037 (mfd->panel_info.type == MIPI_VIDEO_PANEL))
2038 pull_mode = 1;
2039
2040 if (pull_mode && (req->src_rect.h > req->dst_rect.h ||
2041 req->src_rect.w > req->dst_rect.w)) {
2042 if (mdp4_overlay_validate_downscale(req, mfd, perf_level,
2043 clk_rate))
2044 use_blt = 1;
2045 }
2046
2047 if (mfd->mdp_rev == MDP_REV_41) {
2048 /*
2049 * writeback (blt) mode to provide work around for
2050 * dsi cmd mode interface hardware bug.
2051 */
2052 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
2053 if (req->dst_rect.x != 0)
2054 use_blt = 1;
2055 }
2056 if (mfd->panel_info.xres > 1280)
2057 use_blt = 1;
2058 }
2059 return use_blt;
2060}
2061
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002062int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req)
2063{
2064 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
kuogee hsiehc4b8b2f2011-07-12 13:32:14 -07002065 int ret, mixer, perf_level;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002066 struct mdp4_overlay_pipe *pipe;
2067
2068 if (mfd == NULL) {
2069 pr_err("%s: mfd == NULL, -ENODEV\n", __func__);
2070 return -ENODEV;
2071 }
2072
2073 if (!mfd->panel_power_on) /* suspended */
2074 return -EPERM;
2075
2076 if (req->src.format == MDP_FB_FORMAT)
2077 req->src.format = mfd->fb_imgType;
2078
2079 if (mutex_lock_interruptible(&mfd->dma->ov_mutex)) {
2080 pr_err("%s: mutex_lock_interruptible, -EINTR\n", __func__);
2081 return -EINTR;
2082 }
2083
2084 perf_level = mdp4_overlay_get_perf_level(req);
2085
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002086 mixer = mfd->panel_info.pdest; /* DISPLAY_1 or DISPLAY_2 */
2087
2088 ret = mdp4_overlay_req2pipe(req, mixer, &pipe, mfd);
2089 if (ret < 0) {
2090 mutex_unlock(&mfd->dma->ov_mutex);
2091 pr_err("%s: mdp4_overlay_req2pipe, ret=%d\n", __func__, ret);
2092 return ret;
2093 }
2094
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07002095 if (mixer == MDP4_MIXER0) {
2096 u32 use_blt = mdp4_overlay_blt_enable(req, mfd, perf_level);
2097 mfd->use_ov0_blt &= ~(1 << (pipe->pipe_ndx-1));
2098 mfd->use_ov0_blt |= (use_blt << (pipe->pipe_ndx-1));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002099 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002100
2101 /* return id back to user */
2102 req->id = pipe->pipe_ndx; /* pipe_ndx start from 1 */
2103 pipe->req_data = *req; /* keep original req */
2104
2105 pipe->flags = req->flags;
2106
2107 if (pipe->flags & MDP_SHARPENING) {
2108 bool test = ((pipe->req_data.dpp.sharp_strength > 0) &&
2109 ((req->src_rect.w > req->dst_rect.w) &&
2110 (req->src_rect.h > req->dst_rect.h)));
2111 if (test) {
2112 pr_warn("%s: No sharpening while downscaling.\n",
2113 __func__);
2114 pipe->flags &= ~MDP_SHARPENING;
2115 }
2116 }
2117
Liyuan Lid9736632011-11-11 13:47:59 -08002118 /* precompute HSIC matrices */
2119 if (req->flags & MDP_DPP_HSIC)
2120 mdp4_hsic_set(pipe, &(req->dpp));
2121
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002122 mdp4_stat.overlay_set[pipe->mixer_num]++;
2123
2124 if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
2125 if (mdp_hw_revision == MDP4_REVISION_V2_1 &&
2126 pipe->mixer_num == MDP4_MIXER0)
2127 mdp4_overlay_status_write(MDP4_OVERLAY_TYPE_SET, true);
2128 }
2129
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07002130 if (ctrl->panel_mode & MDP4_PANEL_DTV &&
2131 pipe->mixer_num == MDP4_MIXER1)
2132 mdp4_overlay_dtv_set(mfd, pipe);
2133
Adrian Salido-Moreno5e912032011-08-29 11:15:47 -07002134 if (new_perf_level != perf_level) {
Nagamalleswararao Ganji074ee022011-09-02 12:06:37 -07002135 mdp4_update_perf_level(perf_level);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002136
Adrian Salido-Moreno5e912032011-08-29 11:15:47 -07002137 /* change clck base on perf level */
Adrian Salido-Moreno5e912032011-08-29 11:15:47 -07002138 if (pipe->mixer_num == MDP4_MIXER0) {
2139 if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
kuogee hsiehaff429a2011-09-22 17:50:05 -07002140 mdp4_overlay_dsi_video_set_perf(mfd);
Adrian Salido-Moreno5e912032011-08-29 11:15:47 -07002141 } else if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
2142 mdp4_dsi_cmd_dma_busy_wait(mfd);
2143 mdp4_dsi_blt_dmap_busy_wait(mfd);
2144 mdp4_set_perf_level();
2145 } else if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
kuogee hsiehaff429a2011-09-22 17:50:05 -07002146 mdp4_overlay_lcdc_set_perf(mfd);
Adrian Salido-Moreno5e912032011-08-29 11:15:47 -07002147 } else if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
2148 mdp4_mddi_dma_busy_wait(mfd);
2149 mdp4_set_perf_level();
2150 }
2151 } else {
2152 if (ctrl->panel_mode & MDP4_PANEL_DTV)
2153 mdp4_overlay_dtv_vsync_push(mfd, pipe);
kuogee hsieh9452ecb2011-08-01 18:26:23 -07002154 }
kuogee hsieh9452ecb2011-08-01 18:26:23 -07002155 }
kuogee hsieh9452ecb2011-08-01 18:26:23 -07002156 mutex_unlock(&mfd->dma->ov_mutex);
2157
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002158#ifdef CONFIG_MSM_BUS_SCALING
2159 if (pipe->mixer_num == MDP4_MIXER0) {
2160 mdp_bus_scale_update_request(OVERLAY_BUS_SCALE_TABLE_BASE
2161 - perf_level);
2162 }
2163#endif
2164
2165 return 0;
2166}
2167
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002168int mdp4_overlay_unset(struct fb_info *info, int ndx)
2169{
2170 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
2171 struct mdp4_overlay_pipe *pipe;
2172 uint32 flags;
Liyuan Lid9736632011-11-11 13:47:59 -08002173 struct dpp_ctrl dpp;
2174 int i;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002175
2176 if (mfd == NULL)
2177 return -ENODEV;
2178
2179 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
2180 return -EINTR;
2181
2182 pipe = mdp4_overlay_ndx2pipe(ndx);
2183
2184 if (pipe == NULL) {
2185 mutex_unlock(&mfd->dma->ov_mutex);
2186 return -ENODEV;
2187 }
2188
2189 if (pipe->mixer_num == MDP4_MIXER1)
2190 ctrl->mixer1_played = 0;
2191 else {
2192 /* mixer 0 */
2193 ctrl->mixer0_played = 0;
2194#ifdef CONFIG_FB_MSM_MIPI_DSI
2195 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
2196 if (mfd->panel_power_on) {
2197 mdp4_dsi_blt_dmap_busy_wait(mfd);
2198 }
2199 }
2200#else
2201 if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
2202 if (mfd->panel_power_on)
2203 mdp4_mddi_dma_busy_wait(mfd);
2204 }
2205#endif
2206 }
2207
2208 mdp4_mixer_stage_down(pipe);
2209
2210 if (pipe->mixer_num == MDP4_MIXER0) {
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07002211
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002212#ifdef CONFIG_FB_MSM_MIPI_DSI
2213 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
2214 if (mfd->panel_power_on)
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07002215 mdp4_dsi_cmd_overlay_restore();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002216 } else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
kuogee hsiehebca0c72011-07-14 13:30:33 -07002217 mdp4_overlay_reg_flush(pipe, 1);
kuogee hsieh5c6cfbf2011-09-06 19:01:31 -07002218 if (mfd->panel_power_on) {
2219 flags = pipe->flags;
2220 pipe->flags &= ~MDP_OV_PLAY_NOWAIT;
2221 mdp4_overlay_dsi_video_vsync_push(mfd, pipe);
2222 pipe->flags = flags;
2223 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002224 }
2225#else
2226 if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
2227 if (mdp_hw_revision == MDP4_REVISION_V2_1)
2228 mdp4_overlay_status_write(
2229 MDP4_OVERLAY_TYPE_UNSET, true);
2230 if (mfd->panel_power_on)
2231 mdp4_mddi_overlay_restore();
2232 }
2233#endif
2234 else if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
kuogee hsiehebca0c72011-07-14 13:30:33 -07002235 mdp4_overlay_reg_flush(pipe, 1);
kuogee hsieh5c6cfbf2011-09-06 19:01:31 -07002236 if (mfd->panel_power_on) {
2237 flags = pipe->flags;
2238 pipe->flags &= ~MDP_OV_PLAY_NOWAIT;
2239 mdp4_overlay_lcdc_vsync_push(mfd, pipe);
2240 pipe->flags = flags;
2241 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002242 }
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07002243
2244 mfd->use_ov0_blt &= ~(1 << (pipe->pipe_ndx-1));
2245 mdp4_overlay_update_blt_mode(mfd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002246 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002247 else { /* mixer1, DTV, ATV */
Adrian Salido-Morenofc6be922011-10-04 15:22:39 -07002248 if (ctrl->panel_mode & MDP4_PANEL_DTV)
2249 mdp4_overlay_dtv_unset(mfd, pipe);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002250 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002251
Liyuan Lid9736632011-11-11 13:47:59 -08002252 /* Reset any HSIC settings to default */
2253 if (pipe->flags & MDP_DPP_HSIC) {
2254 for (i = 0; i < NUM_HSIC_PARAM; i++)
2255 dpp.hsic_params[i] = 0;
2256
2257 mdp4_hsic_set(pipe, &dpp);
2258 mdp4_hsic_update(pipe);
2259 }
2260
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002261 mdp4_stat.overlay_unset[pipe->mixer_num]++;
2262
2263 mdp4_overlay_pipe_free(pipe);
2264
Adrian Salido-Morenocb8fbbc2011-10-26 13:00:18 -07002265 if (!(ctrl->plist[OVERLAY_PIPE_VG1].pipe_used +
2266 ctrl->plist[OVERLAY_PIPE_VG2].pipe_used))
2267 mdp4_update_perf_level(OVERLAY_PERF_LEVEL4);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002268
2269 mutex_unlock(&mfd->dma->ov_mutex);
2270
2271#ifdef CONFIG_MSM_BUS_SCALING
2272 if (pipe->mixer_num == MDP4_MIXER0)
2273 if (mfd->panel_power_on)
2274 mdp_bus_scale_update_request(2);
2275#endif
2276 return 0;
2277}
2278
2279struct tile_desc {
2280 uint32 width; /* tile's width */
2281 uint32 height; /* tile's height */
2282 uint32 row_tile_w; /* tiles per row's width */
2283 uint32 row_tile_h; /* tiles per row's height */
2284};
2285
2286void tile_samsung(struct tile_desc *tp)
2287{
2288 /*
2289 * each row of samsung tile consists of two tiles in height
2290 * and two tiles in width which means width should align to
2291 * 64 x 2 bytes and height should align to 32 x 2 bytes.
2292 * video decoder generate two tiles in width and one tile
2293 * in height which ends up height align to 32 X 1 bytes.
2294 */
2295 tp->width = 64; /* 64 bytes */
2296 tp->row_tile_w = 2; /* 2 tiles per row's width */
2297 tp->height = 32; /* 32 bytes */
2298 tp->row_tile_h = 1; /* 1 tiles per row's height */
2299}
2300
2301uint32 tile_mem_size(struct mdp4_overlay_pipe *pipe, struct tile_desc *tp)
2302{
2303 uint32 tile_w, tile_h;
2304 uint32 row_num_w, row_num_h;
2305
2306
2307 tile_w = tp->width * tp->row_tile_w;
2308 tile_h = tp->height * tp->row_tile_h;
2309
2310 row_num_w = (pipe->src_width + tile_w - 1) / tile_w;
2311 row_num_h = (pipe->src_height + tile_h - 1) / tile_h;
2312 return ((row_num_w * row_num_h * tile_w * tile_h) + 8191) & ~8191;
2313}
2314
Nagamalleswararao Ganji0737d652011-10-14 02:02:33 -07002315int mdp4_overlay_play_wait(struct fb_info *info, struct msmfb_overlay_data *req)
2316{
2317 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
2318 struct mdp4_overlay_pipe *pipe;
2319
2320 if (mfd == NULL)
2321 return -ENODEV;
2322
2323 if (!mfd->panel_power_on) /* suspended */
2324 return -EPERM;
2325
2326 pipe = mdp4_overlay_ndx2pipe(req->id);
2327
2328 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
2329 return -EINTR;
2330
2331 mdp4_overlay_dtv_wait_for_ov(mfd, pipe);
2332
2333 mutex_unlock(&mfd->dma->ov_mutex);
2334
2335 return 0;
2336}
2337
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002338int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002339{
2340 struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
2341 struct msmfb_data *img;
2342 struct mdp4_overlay_pipe *pipe;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002343 ulong start, addr;
2344 ulong len = 0;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002345 struct file *srcp0_file = NULL;
2346 struct file *srcp1_file = NULL, *srcp2_file = NULL;
2347 struct ion_handle *srcp0_ihdl = NULL;
2348 struct ion_handle *srcp1_ihdl = NULL, *srcp2_ihdl = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002349 uint32_t overlay_version = 0;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002350 int ret = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002351
2352 if (mfd == NULL)
2353 return -ENODEV;
2354
2355 if (!mfd->panel_power_on) /* suspended */
2356 return -EPERM;
2357
2358 pipe = mdp4_overlay_ndx2pipe(req->id);
2359 if (pipe == NULL) {
2360 pr_err("%s: req_id=%d Error\n", __func__, req->id);
2361 return -ENODEV;
2362 }
2363
2364 if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
2365 return -EINTR;
2366
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002367 img = &req->data;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002368 get_img(img, info, &start, &len, &srcp0_file, &srcp0_ihdl);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002369 if (len == 0) {
2370 mutex_unlock(&mfd->dma->ov_mutex);
2371 pr_err("%s: pmem Error\n", __func__);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002372 ret = -1;
2373 goto end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002374 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002375
2376 addr = start + img->offset;
2377 pipe->srcp0_addr = addr;
2378 pipe->srcp0_ystride = pipe->src_width * pipe->bpp;
2379
2380 if ((req->version_key & VERSION_KEY_MASK) == 0xF9E8D700)
2381 overlay_version = (req->version_key & ~VERSION_KEY_MASK);
2382
2383 if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR) {
2384 if (overlay_version > 0) {
2385 img = &req->plane1_data;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002386 get_img(img, info, &start, &len, &srcp1_file,
2387 &srcp1_ihdl);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002388 if (len == 0) {
2389 mutex_unlock(&mfd->dma->ov_mutex);
2390 pr_err("%s: Error to get plane1\n", __func__);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002391 ret = -EINVAL;
2392 goto end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002393 }
2394 pipe->srcp1_addr = start + img->offset;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002395 } else if (pipe->frame_format ==
2396 MDP4_FRAME_FORMAT_VIDEO_SUPERTILE) {
2397 struct tile_desc tile;
2398
2399 tile_samsung(&tile);
2400 pipe->srcp1_addr = addr + tile_mem_size(pipe, &tile);
2401 } else {
2402 pipe->srcp1_addr = addr + (pipe->src_width *
2403 pipe->src_height);
2404 }
2405 pipe->srcp0_ystride = pipe->src_width;
2406 if ((pipe->src_format == MDP_Y_CRCB_H1V1) ||
2407 (pipe->src_format == MDP_Y_CBCR_H1V1)) {
2408 if (pipe->src_width > YUV_444_MAX_WIDTH)
2409 pipe->srcp1_ystride = pipe->src_width << 2;
2410 else
2411 pipe->srcp1_ystride = pipe->src_width << 1;
2412 } else
2413 pipe->srcp1_ystride = pipe->src_width;
2414
2415 } else if (pipe->fetch_plane == OVERLAY_PLANE_PLANAR) {
2416 if (overlay_version > 0) {
2417 img = &req->plane1_data;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002418 get_img(img, info, &start, &len, &srcp1_file,
2419 &srcp1_ihdl);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002420 if (len == 0) {
2421 mutex_unlock(&mfd->dma->ov_mutex);
2422 pr_err("%s: Error to get plane1\n", __func__);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002423 ret = -EINVAL;
2424 goto end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002425 }
2426 pipe->srcp1_addr = start + img->offset;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002427
2428 img = &req->plane2_data;
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002429 get_img(img, info, &start, &len, &srcp2_file,
2430 &srcp2_ihdl);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002431 if (len == 0) {
2432 mutex_unlock(&mfd->dma->ov_mutex);
2433 pr_err("%s: Error to get plane2\n", __func__);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002434 ret = -EINVAL;
2435 goto end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002436 }
2437 pipe->srcp2_addr = start + img->offset;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002438 } else {
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +05302439 if (pipe->src_format == MDP_Y_CR_CB_GH2V2) {
2440 addr += (ALIGN(pipe->src_width, 16) *
2441 pipe->src_height);
2442 pipe->srcp1_addr = addr;
2443 addr += ((ALIGN((pipe->src_width / 2), 16)) *
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002444 (pipe->src_height / 2));
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +05302445 pipe->srcp2_addr = addr;
2446 } else {
2447 addr += (pipe->src_width * pipe->src_height);
2448 pipe->srcp1_addr = addr;
2449 addr += ((pipe->src_width / 2) *
2450 (pipe->src_height / 2));
2451 pipe->srcp2_addr = addr;
2452 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002453 }
Adrian Salido-Moreno33dc7b92011-08-18 16:16:12 -07002454 /* mdp planar format expects Cb in srcp1 and Cr in p2 */
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +05302455 if ((pipe->src_format == MDP_Y_CR_CB_H2V2) ||
2456 (pipe->src_format == MDP_Y_CR_CB_GH2V2))
Adrian Salido-Moreno33dc7b92011-08-18 16:16:12 -07002457 swap(pipe->srcp1_addr, pipe->srcp2_addr);
Pradeep Jilagam959fd6f2011-10-05 21:19:46 +05302458
2459 if (pipe->src_format == MDP_Y_CR_CB_GH2V2) {
2460 pipe->srcp0_ystride = ALIGN(pipe->src_width, 16);
2461 pipe->srcp1_ystride = ALIGN(pipe->src_width / 2, 16);
2462 pipe->srcp2_ystride = ALIGN(pipe->src_width / 2, 16);
2463 } else {
2464 pipe->srcp0_ystride = pipe->src_width;
2465 pipe->srcp1_ystride = pipe->src_width / 2;
2466 pipe->srcp2_ystride = pipe->src_width / 2;
2467 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002468 }
2469
Adrian Salido-Moreno6a601cd2011-12-13 18:16:25 -08002470 if (mfd->use_ov0_blt)
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07002471 mdp4_overlay_update_blt_mode(mfd);
Nagamalleswararao Ganjie8943492011-11-01 13:04:10 -07002472
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002473 if (pipe->pipe_num >= OVERLAY_PIPE_VG1)
2474 mdp4_overlay_vg_setup(pipe); /* video/graphic pipe */
2475 else {
2476 if (pipe->flags & MDP_SHARPENING) {
2477 pr_warn(
2478 "%s: Sharpening/Smoothing not supported on RGB pipe\n",
2479 __func__);
2480 pipe->flags &= ~MDP_SHARPENING;
2481 }
2482 mdp4_overlay_rgb_setup(pipe); /* rgb pipe */
2483 }
2484
2485 mdp4_mixer_blend_setup(pipe);
2486 mdp4_mixer_stage_up(pipe);
2487
2488 if (pipe->mixer_num == MDP4_MIXER1) {
2489 ctrl->mixer1_played++;
2490 /* enternal interface */
2491 if (ctrl->panel_mode & MDP4_PANEL_DTV)
2492#ifdef CONFIG_FB_MSM_DTV
2493 mdp4_overlay_dtv_ov_done_push(mfd, pipe);
2494#else
2495 mdp4_overlay_reg_flush(pipe, 1);
2496#endif
2497 else if (ctrl->panel_mode & MDP4_PANEL_ATV)
2498 mdp4_overlay_reg_flush(pipe, 1);
Vinay Kalia27020d12011-10-14 17:50:29 -07002499#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
2500 else if (ctrl->panel_mode & MDP4_PANEL_WRITEBACK) {
2501 mdp4_writeback_dma_busy_wait(mfd);
2502 mdp4_writeback_kickoff_video(mfd, pipe);
2503 }
2504#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002505 } else {
Adrian Salido-Moreno6a601cd2011-12-13 18:16:25 -08002506
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002507 /* primary interface */
2508 ctrl->mixer0_played++;
kuogee hsieh3de11f32011-07-08 14:09:11 -07002509 if (ctrl->panel_mode & MDP4_PANEL_LCDC) {
2510 mdp4_overlay_reg_flush(pipe, 1);
Adrian Salido-Moreno6a601cd2011-12-13 18:16:25 -08002511 if (!mfd->use_ov0_blt)
2512 mdp4_overlay_update_blt_mode(mfd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002513 mdp4_overlay_lcdc_vsync_push(mfd, pipe);
kuogee hsieh3de11f32011-07-08 14:09:11 -07002514 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002515#ifdef CONFIG_FB_MSM_MIPI_DSI
kuogee hsieh3de11f32011-07-08 14:09:11 -07002516 else if (ctrl->panel_mode & MDP4_PANEL_DSI_VIDEO) {
2517 mdp4_overlay_reg_flush(pipe, 1);
Adrian Salido-Moreno6a601cd2011-12-13 18:16:25 -08002518 if (!mfd->use_ov0_blt)
2519 mdp4_overlay_update_blt_mode(mfd);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002520 mdp4_overlay_dsi_video_vsync_push(mfd, pipe);
kuogee hsieh3de11f32011-07-08 14:09:11 -07002521 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002522#endif
2523 else {
2524 /* mddi & mipi dsi cmd mode */
2525 if (pipe->flags & MDP_OV_PLAY_NOWAIT) {
2526 mdp4_stat.overlay_play[pipe->mixer_num]++;
2527 mutex_unlock(&mfd->dma->ov_mutex);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002528 goto end;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002529 }
2530#ifdef CONFIG_FB_MSM_MIPI_DSI
2531 if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
2532 mdp4_dsi_cmd_dma_busy_wait(mfd);
2533 mdp4_dsi_cmd_kickoff_video(mfd, pipe);
2534 }
2535#else
2536 if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
2537 mdp4_mddi_dma_busy_wait(mfd);
2538 mdp4_mddi_kickoff_video(mfd, pipe);
2539 }
2540#endif
2541 }
2542 }
2543
Liyuan Lid9736632011-11-11 13:47:59 -08002544 /* write out DPP HSIC registers */
2545 if (pipe->flags & MDP_DPP_HSIC)
2546 mdp4_hsic_update(pipe);
2547
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002548 mdp4_stat.overlay_play[pipe->mixer_num]++;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002549 mutex_unlock(&mfd->dma->ov_mutex);
Nagamalleswararao Ganjie69bed82011-10-17 16:21:42 -07002550end:
2551#ifdef CONFIG_ANDROID_PMEM
2552 if (srcp0_file)
2553 put_pmem_file(srcp0_file);
2554 if (srcp1_file)
2555 put_pmem_file(srcp1_file);
2556 if (srcp2_file)
2557 put_pmem_file(srcp2_file);
2558#endif
2559#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
2560 if (!IS_ERR_OR_NULL(srcp0_ihdl))
2561 ion_free(mfd->client, srcp0_ihdl);
2562 if (!IS_ERR_OR_NULL(srcp1_ihdl))
2563 ion_free(mfd->client, srcp1_ihdl);
2564 if (!IS_ERR_OR_NULL(srcp2_ihdl))
2565 ion_free(mfd->client, srcp2_ihdl);
2566#endif
2567 return ret;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002568}