• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/staging/msm/
1/* Copyright (c) 2008-2009, 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 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/time.h>
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/spinlock.h>
25#include <linux/hrtimer.h>
26#include <linux/clk.h>
27#include <mach/hardware.h>
28#include <linux/io.h>
29#include <linux/debugfs.h>
30#include <linux/fb.h>
31#include <msm_mdp.h>
32#include <linux/file.h>
33#include "android_pmem.h"
34#include <linux/major.h>
35#include <asm/system.h>
36#include <asm/mach-types.h>
37#include <linux/semaphore.h>
38#include <linux/uaccess.h>
39#include <linux/mutex.h>
40
41#include "mdp.h"
42#include "msm_fb.h"
43#include "mdp4.h"
44
45
46struct mdp4_overlay_ctrl {
47	struct mdp4_overlay_pipe plist[MDP4_MAX_OVERLAY_PIPE];
48	struct mdp4_overlay_pipe *stage[MDP4_MAX_MIXER][MDP4_MAX_STAGE];
49} mdp4_overlay_db;
50
51static struct mdp4_overlay_ctrl *ctrl = &mdp4_overlay_db;
52
53
54void mdp4_overlay_dmap_cfg(struct msm_fb_data_type *mfd, int lcdc)
55{
56	uint32	dma2_cfg_reg;
57
58	dma2_cfg_reg = DMA_DITHER_EN;
59
60	if (mfd->fb_imgType == MDP_BGR_565)
61		dma2_cfg_reg |= DMA_PACK_PATTERN_BGR;
62	else
63		dma2_cfg_reg |= DMA_PACK_PATTERN_RGB;
64
65
66	if (mfd->panel_info.bpp == 18) {
67		dma2_cfg_reg |= DMA_DSTC0G_6BITS |	/* 666 18BPP */
68		    DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
69	} else if (mfd->panel_info.bpp == 16) {
70		dma2_cfg_reg |= DMA_DSTC0G_6BITS |	/* 565 16BPP */
71		    DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
72	} else {
73		dma2_cfg_reg |= DMA_DSTC0G_8BITS |	/* 888 16BPP */
74		    DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;
75	}
76
77	if (lcdc)
78		dma2_cfg_reg |= DMA_PACK_ALIGN_MSB;
79
80	/* dma2 config register */
81	MDP_OUTP(MDP_BASE + 0x90000, dma2_cfg_reg);
82
83}
84
85void mdp4_overlay_dmap_xy(struct mdp4_overlay_pipe *pipe)
86{
87
88	/* dma_p source */
89	MDP_OUTP(MDP_BASE + 0x90004,
90			(pipe->src_height << 16 | pipe->src_width));
91	MDP_OUTP(MDP_BASE + 0x90008, pipe->srcp0_addr);
92	MDP_OUTP(MDP_BASE + 0x9000c, pipe->srcp0_ystride);
93
94	/* dma_p dest */
95	MDP_OUTP(MDP_BASE + 0x90010, (pipe->dst_y << 16 | pipe->dst_x));
96}
97
98#define MDP4_VG_PHASE_STEP_DEFAULT	0x20000000
99#define MDP4_VG_PHASE_STEP_SHIFT	29
100
101static int mdp4_leading_0(uint32 num)
102{
103	uint32 bit = 0x80000000;
104	int i;
105
106	for (i = 0; i < 32; i++) {
107		if (bit & num)
108			return i;
109		bit >>= 1;
110	}
111
112	return i;
113}
114
115static uint32 mdp4_scale_phase_step(int f_num, uint32 src, uint32 dst)
116{
117	uint32 val;
118	int	n;
119
120	n = mdp4_leading_0(src);
121	if (n > f_num)
122		n = f_num;
123	val = src << n;	/* maximum to reduce lose of resolution */
124	val /= dst;
125	if (n < f_num) {
126		n = f_num - n;
127		val <<= n;
128	}
129
130	return val;
131}
132
133static void mdp4_scale_setup(struct mdp4_overlay_pipe *pipe)
134{
135
136	pipe->phasex_step = MDP4_VG_PHASE_STEP_DEFAULT;
137	pipe->phasey_step = MDP4_VG_PHASE_STEP_DEFAULT;
138
139	if (pipe->dst_h && pipe->src_h != pipe->dst_h) {
140		if (pipe->dst_h >= pipe->src_h * 8)	/* too much */
141			return;
142		pipe->op_mode |= MDP4_OP_SCALEY_EN;
143
144		if (pipe->pipe_type == OVERLAY_TYPE_VG) {
145			if (pipe->dst_h <= (pipe->src_h / 4))
146				pipe->op_mode |= MDP4_OP_SCALEY_MN_PHASE;
147			else
148				pipe->op_mode |= MDP4_OP_SCALEY_FIR;
149		}
150
151		pipe->phasey_step = mdp4_scale_phase_step(29,
152					pipe->src_h, pipe->dst_h);
153	}
154
155	if (pipe->dst_w && pipe->src_w != pipe->dst_w) {
156		if (pipe->dst_w >= pipe->src_w * 8)	/* too much */
157			return;
158		pipe->op_mode |= MDP4_OP_SCALEX_EN;
159
160		if (pipe->pipe_type == OVERLAY_TYPE_VG) {
161			if (pipe->dst_w <= (pipe->src_w / 4))
162				pipe->op_mode |= MDP4_OP_SCALEY_MN_PHASE;
163			else
164				pipe->op_mode |= MDP4_OP_SCALEY_FIR;
165		}
166
167		pipe->phasex_step = mdp4_scale_phase_step(29,
168					pipe->src_w, pipe->dst_w);
169	}
170}
171
172void mdp4_overlay_rgb_setup(struct mdp4_overlay_pipe *pipe)
173{
174	char *rgb_base;
175	uint32 src_size, src_xy, dst_size, dst_xy;
176	uint32 format, pattern;
177
178	rgb_base = MDP_BASE + MDP4_RGB_BASE;
179	rgb_base += (MDP4_RGB_OFF * pipe->pipe_num);
180
181	src_size = ((pipe->src_h << 16) | pipe->src_w);
182	src_xy = ((pipe->src_y << 16) | pipe->src_x);
183	dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
184	dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
185
186	format = mdp4_overlay_format(pipe);
187	pattern = mdp4_overlay_unpack_pattern(pipe);
188
189	pipe->op_mode |= MDP4_OP_IGC_LUT_EN;
190
191	mdp4_scale_setup(pipe);
192
193	outpdw(rgb_base + 0x0000, src_size);	/* MDP_RGB_SRC_SIZE */
194	outpdw(rgb_base + 0x0004, src_xy);	/* MDP_RGB_SRC_XY */
195	outpdw(rgb_base + 0x0008, dst_size);	/* MDP_RGB_DST_SIZE */
196	outpdw(rgb_base + 0x000c, dst_xy);	/* MDP_RGB_DST_XY */
197
198	outpdw(rgb_base + 0x0010, pipe->srcp0_addr);
199	outpdw(rgb_base + 0x0040, pipe->srcp0_ystride);
200
201	outpdw(rgb_base + 0x0050, format);/* MDP_RGB_SRC_FORMAT */
202	outpdw(rgb_base + 0x0054, pattern);/* MDP_RGB_SRC_UNPACK_PATTERN */
203	outpdw(rgb_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */
204	outpdw(rgb_base + 0x005c, pipe->phasex_step);
205	outpdw(rgb_base + 0x0060, pipe->phasey_step);
206
207	/* 16 bytes-burst x 3 req <= 48 bytes */
208	outpdw(rgb_base + 0x1004, 0xc2);	/* MDP_RGB_FETCH_CFG */
209}
210
211void mdp4_overlay_vg_setup(struct mdp4_overlay_pipe *pipe)
212{
213	char *vg_base;
214	uint32 frame_size, src_size, src_xy, dst_size, dst_xy;
215	uint32 format, pattern;
216
217	vg_base = MDP_BASE + MDP4_VIDEO_BASE;
218	vg_base += (MDP4_VIDEO_OFF * pipe->pipe_num);
219
220	frame_size = ((pipe->src_height << 16) | pipe->src_width);
221	src_size = ((pipe->src_h << 16) | pipe->src_w);
222	src_xy = ((pipe->src_y << 16) | pipe->src_x);
223	dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
224	dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
225
226	format = mdp4_overlay_format(pipe);
227	pattern = mdp4_overlay_unpack_pattern(pipe);
228
229	pipe->op_mode |= (MDP4_OP_CSC_EN | MDP4_OP_SRC_DATA_YCBCR |
230				MDP4_OP_IGC_LUT_EN);
231
232	mdp4_scale_setup(pipe);
233
234	outpdw(vg_base + 0x0000, src_size);	/* MDP_RGB_SRC_SIZE */
235	outpdw(vg_base + 0x0004, src_xy);	/* MDP_RGB_SRC_XY */
236	outpdw(vg_base + 0x0008, dst_size);	/* MDP_RGB_DST_SIZE */
237	outpdw(vg_base + 0x000c, dst_xy);	/* MDP_RGB_DST_XY */
238	outpdw(vg_base + 0x0048, frame_size);	/* TILE frame size */
239
240	/* luma component plane */
241	outpdw(vg_base + 0x0010, pipe->srcp0_addr);
242
243	/* chroma component plane */
244	outpdw(vg_base + 0x0014, pipe->srcp1_addr);
245
246	outpdw(vg_base + 0x0040,
247			pipe->srcp1_ystride << 16 | pipe->srcp0_ystride);
248
249	outpdw(vg_base + 0x0050, format);	/* MDP_RGB_SRC_FORMAT */
250	outpdw(vg_base + 0x0054, pattern);	/* MDP_RGB_SRC_UNPACK_PATTERN */
251	outpdw(vg_base + 0x0058, pipe->op_mode);/* MDP_RGB_OP_MODE */
252	outpdw(vg_base + 0x005c, pipe->phasex_step);
253	outpdw(vg_base + 0x0060, pipe->phasey_step);
254
255	if (pipe->op_mode & MDP4_OP_DITHER_EN) {
256		outpdw(vg_base + 0x0068,
257			pipe->r_bit << 4 | pipe->b_bit << 2 | pipe->g_bit);
258	}
259
260	/* 16 bytes-burst x 3 req <= 48 bytes */
261	outpdw(vg_base + 0x1004, 0xc2);	/* MDP_VG_FETCH_CFG */
262}
263
264int mdp4_overlay_format2type(uint32 format)
265{
266	switch (format) {
267	case MDP_RGB_565:
268	case MDP_RGB_888:
269	case MDP_BGR_565:
270	case MDP_ARGB_8888:
271	case MDP_RGBA_8888:
272	case MDP_BGRA_8888:
273		return OVERLAY_TYPE_RGB;
274	case MDP_YCRYCB_H2V1:
275	case MDP_Y_CRCB_H2V1:
276	case MDP_Y_CBCR_H2V1:
277	case MDP_Y_CRCB_H2V2:
278	case MDP_Y_CBCR_H2V2:
279	case MDP_Y_CBCR_H2V2_TILE:
280	case MDP_Y_CRCB_H2V2_TILE:
281		return OVERLAY_TYPE_VG;
282	default:
283		return -ERANGE;
284	}
285
286}
287
288#define C3_ALPHA	3	/* alpha */
289#define C2_R_Cr		2	/* R/Cr */
290#define C1_B_Cb		1	/* B/Cb */
291#define C0_G_Y		0	/* G/luma */
292
293int mdp4_overlay_format2pipe(struct mdp4_overlay_pipe *pipe)
294{
295	switch (pipe->src_format) {
296	case MDP_RGB_565:
297		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
298		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
299		pipe->a_bit = 0;
300		pipe->r_bit = 1;	/* R, 5 bits */
301		pipe->b_bit = 1;	/* B, 5 bits */
302		pipe->g_bit = 2;	/* G, 6 bits */
303		pipe->alpha_enable = 0;
304		pipe->unpack_tight = 1;
305		pipe->unpack_align_msb = 0;
306		pipe->unpack_count = 2;
307		pipe->element2 = C2_R_Cr;	/* R */
308		pipe->element1 = C0_G_Y;	/* G */
309		pipe->element0 = C1_B_Cb;	/* B */
310		pipe->bpp = 2;	/* 2 bpp */
311		break;
312	case MDP_RGB_888:
313		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
314		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
315		pipe->a_bit = 0;
316		pipe->r_bit = 3;	/* R, 8 bits */
317		pipe->b_bit = 3;	/* B, 8 bits */
318		pipe->g_bit = 3;	/* G, 8 bits */
319		pipe->alpha_enable = 0;
320		pipe->unpack_tight = 1;
321		pipe->unpack_align_msb = 0;
322		pipe->unpack_count = 2;
323		pipe->element2 = C2_R_Cr;	/* R */
324		pipe->element1 = C0_G_Y;	/* G */
325		pipe->element0 = C1_B_Cb;	/* B */
326		pipe->bpp = 3;	/* 3 bpp */
327		break;
328	case MDP_BGR_565:
329		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
330		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
331		pipe->a_bit = 0;
332		pipe->r_bit = 1;	/* R, 5 bits */
333		pipe->b_bit = 1;	/* B, 5 bits */
334		pipe->g_bit = 2;	/* G, 6 bits */
335		pipe->alpha_enable = 0;
336		pipe->unpack_tight = 1;
337		pipe->unpack_align_msb = 0;
338		pipe->unpack_count = 2;
339		pipe->element2 = C1_B_Cb;	/* B */
340		pipe->element1 = C0_G_Y;	/* G */
341		pipe->element0 = C2_R_Cr;	/* R */
342		pipe->bpp = 2;	/* 2 bpp */
343		break;
344	case MDP_ARGB_8888:
345		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
346		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
347		pipe->a_bit = 3;	/* alpha, 4 bits */
348		pipe->r_bit = 3;	/* R, 8 bits */
349		pipe->b_bit = 3;	/* B, 8 bits */
350		pipe->g_bit = 3;	/* G, 8 bits */
351		pipe->alpha_enable = 1;
352		pipe->unpack_tight = 1;
353		pipe->unpack_align_msb = 0;
354		pipe->unpack_count = 3;
355		pipe->element3 = C3_ALPHA;	/* alpha */
356		pipe->element2 = C2_R_Cr;	/* R */
357		pipe->element1 = C0_G_Y;	/* G */
358		pipe->element0 = C1_B_Cb;	/* B */
359		pipe->bpp = 4;		/* 4 bpp */
360		break;
361	case MDP_RGBA_8888:
362		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
363		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
364		pipe->a_bit = 3;	/* alpha, 4 bits */
365		pipe->r_bit = 3;	/* R, 8 bits */
366		pipe->b_bit = 3;	/* B, 8 bits */
367		pipe->g_bit = 3;	/* G, 8 bits */
368		pipe->alpha_enable = 1;
369		pipe->unpack_tight = 1;
370		pipe->unpack_align_msb = 0;
371		pipe->unpack_count = 3;
372		pipe->element3 = C2_R_Cr;	/* R */
373		pipe->element2 = C0_G_Y;	/* G */
374		pipe->element1 = C1_B_Cb;	/* B */
375		pipe->element0 = C3_ALPHA;	/* alpha */
376		pipe->bpp = 4;		/* 4 bpp */
377		break;
378	case MDP_BGRA_8888:
379		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
380		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
381		pipe->a_bit = 3;	/* alpha, 4 bits */
382		pipe->r_bit = 3;	/* R, 8 bits */
383		pipe->b_bit = 3;	/* B, 8 bits */
384		pipe->g_bit = 3;	/* G, 8 bits */
385		pipe->alpha_enable = 1;
386		pipe->unpack_tight = 1;
387		pipe->unpack_align_msb = 0;
388		pipe->unpack_count = 3;
389		pipe->element3 = C1_B_Cb;	/* B */
390		pipe->element2 = C0_G_Y;	/* G */
391		pipe->element1 = C2_R_Cr;	/* R */
392		pipe->element0 = C3_ALPHA;	/* alpha */
393		pipe->bpp = 4;		/* 4 bpp */
394		break;
395	case MDP_YCRYCB_H2V1:
396		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
397		pipe->fetch_plane = OVERLAY_PLANE_INTERLEAVED;
398		pipe->a_bit = 0;	/* alpha, 4 bits */
399		pipe->r_bit = 3;	/* R, 8 bits */
400		pipe->b_bit = 3;	/* B, 8 bits */
401		pipe->g_bit = 3;	/* G, 8 bits */
402		pipe->alpha_enable = 0;
403		pipe->unpack_tight = 1;
404		pipe->unpack_align_msb = 0;
405		pipe->unpack_count = 3;
406		pipe->element3 = C0_G_Y;	/* G */
407		pipe->element2 = C2_R_Cr;	/* R */
408		pipe->element1 = C0_G_Y;	/* G */
409		pipe->element0 = C1_B_Cb;	/* B */
410		pipe->bpp = 2;		/* 2 bpp */
411		pipe->chroma_sample = MDP4_CHROMA_H2V1;
412		break;
413	case MDP_Y_CRCB_H2V1:
414	case MDP_Y_CBCR_H2V1:
415	case MDP_Y_CRCB_H2V2:
416	case MDP_Y_CBCR_H2V2:
417		pipe->frame_format = MDP4_FRAME_FORMAT_LINEAR;
418		pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_PLANAR;
419		pipe->a_bit = 0;
420		pipe->r_bit = 3;	/* R, 8 bits */
421		pipe->b_bit = 3;	/* B, 8 bits */
422		pipe->g_bit = 3;	/* G, 8 bits */
423		pipe->alpha_enable = 0;
424		pipe->unpack_tight = 1;
425		pipe->unpack_align_msb = 0;
426		pipe->unpack_count = 1;		/* 2 */
427		pipe->element3 = C0_G_Y;	/* not used */
428		pipe->element2 = C0_G_Y;	/* not used */
429		if (pipe->src_format == MDP_Y_CRCB_H2V1) {
430			pipe->element1 = C2_R_Cr;	/* R */
431			pipe->element0 = C1_B_Cb;	/* B */
432			pipe->chroma_sample = MDP4_CHROMA_H2V1;
433		} else if (pipe->src_format == MDP_Y_CBCR_H2V1) {
434			pipe->element1 = C1_B_Cb;	/* B */
435			pipe->element0 = C2_R_Cr;	/* R */
436			pipe->chroma_sample = MDP4_CHROMA_H2V1;
437		} else if (pipe->src_format == MDP_Y_CRCB_H2V2) {
438			pipe->element1 = C2_R_Cr;	/* R */
439			pipe->element0 = C1_B_Cb;	/* B */
440			pipe->chroma_sample = MDP4_CHROMA_420;
441		} else if (pipe->src_format == MDP_Y_CBCR_H2V2) {
442			pipe->element1 = C1_B_Cb;	/* B */
443			pipe->element0 = C2_R_Cr;	/* R */
444			pipe->chroma_sample = MDP4_CHROMA_420;
445		}
446		pipe->bpp = 2;	/* 2 bpp */
447		break;
448	case MDP_Y_CBCR_H2V2_TILE:
449	case MDP_Y_CRCB_H2V2_TILE:
450		pipe->frame_format = MDP4_FRAME_FORMAT_VIDEO_SUPERTILE;
451		pipe->fetch_plane = OVERLAY_PLANE_PSEUDO_PLANAR;
452		pipe->a_bit = 0;
453		pipe->r_bit = 3;	/* R, 8 bits */
454		pipe->b_bit = 3;	/* B, 8 bits */
455		pipe->g_bit = 3;	/* G, 8 bits */
456		pipe->alpha_enable = 0;
457		pipe->unpack_tight = 1;
458		pipe->unpack_align_msb = 0;
459		pipe->unpack_count = 1;		/* 2 */
460		pipe->element3 = C0_G_Y;	/* not used */
461		pipe->element2 = C0_G_Y;	/* not used */
462		if (pipe->src_format == MDP_Y_CRCB_H2V2_TILE) {
463			pipe->element1 = C2_R_Cr;	/* R */
464			pipe->element0 = C1_B_Cb;	/* B */
465			pipe->chroma_sample = MDP4_CHROMA_420;
466		} else if (pipe->src_format == MDP_Y_CBCR_H2V2_TILE) {
467			pipe->element1 = C1_B_Cb;	/* B */
468			pipe->element0 = C2_R_Cr;	/* R */
469			pipe->chroma_sample = MDP4_CHROMA_420;
470		}
471		pipe->bpp = 2;	/* 2 bpp */
472		break;
473	default:
474		/* not likely */
475		return -ERANGE;
476	}
477
478	return 0;
479}
480
481/*
482 * color_key_convert: output with 12 bits color key
483 */
484static uint32 color_key_convert(int start, int num, uint32 color)
485{
486
487	uint32 data;
488
489	data = (color >> start) & ((1 << num) - 1);
490
491	if (num == 5)
492		data = (data << 7) + (data << 2) + (data >> 3);
493	else if (num == 6)
494		data = (data << 6) + data;
495	else	/* 8 bits */
496		data = (data << 4) + (data >> 4);
497
498	return data;
499
500}
501
502void transp_color_key(int format, uint32 transp,
503			uint32 *c0, uint32 *c1, uint32 *c2)
504{
505	int b_start, g_start, r_start;
506	int b_num, g_num, r_num;
507
508	switch (format) {
509	case MDP_RGB_565:
510		b_start = 0;
511		g_start = 5;
512		r_start = 11;
513		r_num = 5;
514		g_num = 6;
515		b_num = 5;
516		break;
517	case MDP_RGB_888:
518	case MDP_XRGB_8888:
519	case MDP_ARGB_8888:
520		b_start = 0;
521		g_start = 8;
522		r_start = 16;
523		r_num = 8;
524		g_num = 8;
525		b_num = 8;
526		break;
527	case MDP_BGR_565:
528		b_start = 11;
529		g_start = 5;
530		r_start = 0;
531		r_num = 5;
532		g_num = 6;
533		b_num = 5;
534		break;
535	case MDP_Y_CBCR_H2V2:
536	case MDP_Y_CBCR_H2V1:
537		b_start = 8;
538		g_start = 16;
539		r_start = 0;
540		r_num = 8;
541		g_num = 8;
542		b_num = 8;
543		break;
544	case MDP_Y_CRCB_H2V2:
545	case MDP_Y_CRCB_H2V1:
546		b_start = 0;
547		g_start = 16;
548		r_start = 8;
549		r_num = 8;
550		g_num = 8;
551		b_num = 8;
552		break;
553	default:
554		b_start = 0;
555		g_start = 8;
556		r_start = 16;
557		r_num = 8;
558		g_num = 8;
559		b_num = 8;
560		break;
561	}
562
563	*c0 = color_key_convert(g_start, g_num, transp);
564	*c1 = color_key_convert(b_start, b_num, transp);
565	*c2 = color_key_convert(r_start, r_num, transp);
566}
567
568uint32 mdp4_overlay_format(struct mdp4_overlay_pipe *pipe)
569{
570	uint32	format;
571
572	format = 0;
573
574	if (pipe->solid_fill)
575		format |= MDP4_FORMAT_SOLID_FILL;
576
577	if (pipe->unpack_align_msb)
578		format |= MDP4_FORMAT_UNPACK_ALIGN_MSB;
579
580	if (pipe->unpack_tight)
581		format |= MDP4_FORMAT_UNPACK_TIGHT;
582
583	if (pipe->alpha_enable)
584		format |= MDP4_FORMAT_ALPHA_ENABLE;
585
586	format |= (pipe->unpack_count << 13);
587	format |= ((pipe->bpp - 1) << 9);
588	format |= (pipe->a_bit << 6);
589	format |= (pipe->r_bit << 4);
590	format |= (pipe->b_bit << 2);
591	format |= pipe->g_bit;
592
593	format |= (pipe->frame_format << 29);
594
595	if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR) {
596		/* video/graphic */
597		format |= (pipe->fetch_plane << 19);
598		format |= (pipe->chroma_site << 28);
599		format |= (pipe->chroma_sample << 26);
600	}
601
602	return format;
603}
604
605uint32 mdp4_overlay_unpack_pattern(struct mdp4_overlay_pipe *pipe)
606{
607	return (pipe->element3 << 24) | (pipe->element2 << 16) |
608			(pipe->element1 << 8) | pipe->element0;
609}
610
611void mdp4_overlayproc_cfg(struct mdp4_overlay_pipe *pipe)
612{
613	uint32 data;
614	char *overlay_base;
615
616	if (pipe->mixer_num == MDP4_MIXER1)
617		overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
618	else
619		overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
620
621	/* MDP_OVERLAYPROC_CFG */
622	outpdw(overlay_base + 0x0004, 0x01); /* directout */
623	data = pipe->src_height;
624	data <<= 16;
625	data |= pipe->src_width;
626	outpdw(overlay_base + 0x0008, data); /* ROI, height + width */
627	outpdw(overlay_base + 0x000c, pipe->srcp0_addr);
628	outpdw(overlay_base + 0x0010, pipe->srcp0_ystride);
629	outpdw(overlay_base + 0x0014, 0x4);	/* GC_LUT_EN, 888 */
630}
631
632int mdp4_overlay_active(int mixer)
633{
634	uint32 data, mask, i;
635	int p1, p2;
636
637	data = inpdw(MDP_BASE + 0x10100);
638	p1 = 0;
639	p2 = 0;
640	for (i = 0; i < 8; i++) {
641		mask = data & 0x0f;
642		if (mask) {
643			if (mask <= 4)
644				p1++;
645			else
646				p2++;
647		}
648		data >>= 4;
649	}
650
651	if (mixer)
652		return p2;
653	else
654		return p1;
655}
656
657void mdp4_mixer_stage_up(struct mdp4_overlay_pipe *pipe)
658{
659	uint32 data, mask, snum, stage, mixer;
660
661	stage = pipe->mixer_stage;
662	mixer = pipe->mixer_num;
663
664	/* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1  */
665	data = inpdw(MDP_BASE + 0x10100);
666
667	if (mixer == MDP4_MIXER1)
668		stage += 8;
669
670	if (pipe->pipe_type == OVERLAY_TYPE_VG) {/* VG1 and VG2 */
671		snum = 0;
672		snum += (4 * pipe->pipe_num);
673	} else {
674		snum = 8;
675		snum += (4 * pipe->pipe_num);	/* RGB1 and RGB2 */
676	}
677
678	mask = 0x0f;
679	mask <<= snum;
680	stage <<= snum;
681	data &= ~mask;	/* clear old bits */
682
683	data |= stage;
684
685	outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
686
687	data = inpdw(MDP_BASE + 0x10100);
688
689	ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = pipe;	/* keep it */
690}
691
692void mdp4_mixer_stage_down(struct mdp4_overlay_pipe *pipe)
693{
694	uint32 data, mask, snum, stage, mixer;
695
696	stage = pipe->mixer_stage;
697	mixer = pipe->mixer_num;
698
699	if (pipe != ctrl->stage[mixer][stage])	/* not runing */
700		return;
701
702	/* MDP_LAYERMIXER_IN_CFG, shard by both mixer 0 and 1  */
703	data = inpdw(MDP_BASE + 0x10100);
704
705	if (mixer == MDP4_MIXER1)
706		stage += 8;
707
708	if (pipe->pipe_type == OVERLAY_TYPE_VG) {/* VG1 and VG2 */
709		snum = 0;
710		snum += (4 * pipe->pipe_num);
711	} else {
712		snum = 8;
713		snum += (4 * pipe->pipe_num);	/* RGB1 and RGB2 */
714	}
715
716	mask = 0x0f;
717	mask <<= snum;
718	data &= ~mask;	/* clear old bits */
719
720	outpdw(MDP_BASE + 0x10100, data); /* MDP_LAYERMIXER_IN_CFG */
721
722	data = inpdw(MDP_BASE + 0x10100);
723
724	ctrl->stage[pipe->mixer_num][pipe->mixer_stage] = NULL;	/* clear it */
725}
726
727void mdp4_mixer_blend_setup(struct mdp4_overlay_pipe *pipe)
728{
729	unsigned char *overlay_base;
730	uint32 c0, c1, c2, blend_op;
731	int off;
732
733	if (pipe->mixer_num) 	/* mixer number, /dev/fb0, /dev/fb1 */
734		overlay_base = MDP_BASE + MDP4_OVERLAYPROC1_BASE;/* 0x18000 */
735	else
736		overlay_base = MDP_BASE + MDP4_OVERLAYPROC0_BASE;/* 0x10000 */
737
738	/* stage 0 to stage 2 */
739	off = 0x20 * (pipe->mixer_stage - MDP4_MIXER_STAGE0);
740
741	blend_op = 0;
742	if (pipe->alpha_enable) 	/* ARGB */
743		blend_op = MDP4_BLEND_FG_ALPHA_FG_PIXEL |
744				MDP4_BLEND_BG_ALPHA_FG_PIXEL;
745	else
746		blend_op = (MDP4_BLEND_BG_ALPHA_BG_CONST |
747				MDP4_BLEND_FG_ALPHA_FG_CONST);
748
749
750	if (pipe->alpha_enable == 0) { 	/* not ARGB */
751		if (pipe->is_fg) {
752			outpdw(overlay_base + off + 0x108, pipe->alpha);
753			outpdw(overlay_base + off + 0x10c, 0xff - pipe->alpha);
754		} else {
755			outpdw(overlay_base + off + 0x108, 0xff - pipe->alpha);
756			outpdw(overlay_base + off + 0x10c, pipe->alpha);
757		}
758	}
759
760	if (pipe->transp != MDP_TRANSP_NOP) {
761		transp_color_key(pipe->src_format, pipe->transp, &c0, &c1, &c2);
762		if (pipe->is_fg) {
763			blend_op |= MDP4_BLEND_FG_TRANSP_EN; /* Fg blocked */
764			/* lower limit */
765			if (c0 > 0x10)
766				c0 -= 0x10;
767			if (c1 > 0x10)
768				c1 -= 0x10;
769			if (c2 > 0x10)
770				c2 -= 0x10;
771			outpdw(overlay_base + off + 0x110,
772						(c1 << 16 | c0));/* low */
773			outpdw(overlay_base + off + 0x114, c2);/* low */
774			/* upper limit */
775			if ((c0 + 0x20) < 0x0fff)
776				c0 += 0x20;
777			else
778				c0 = 0x0fff;
779			if ((c1 + 0x20) < 0x0fff)
780				c1 += 0x20;
781			else
782				c1 = 0x0fff;
783			if ((c2 + 0x20) < 0x0fff)
784				c2 += 0x20;
785			else
786				c2 = 0x0fff;
787			outpdw(overlay_base + off + 0x118,
788					(c1 << 16 | c0));/* high */
789			outpdw(overlay_base + off + 0x11c, c2);/* high */
790		} else {
791			blend_op |= MDP4_BLEND_BG_TRANSP_EN; /* bg blocked */
792			/* lower limit */
793			if (c0 > 0x10)
794				c0 -= 0x10;
795			if (c1 > 0x10)
796				c1 -= 0x10;
797			if (c2 > 0x10)
798				c2 -= 0x10;
799			outpdw(overlay_base + 0x180,
800						(c1 << 16 | c0));/* low */
801			outpdw(overlay_base + 0x184, c2);/* low */
802			/* upper limit */
803			if ((c0 + 0x20) < 0x0fff)
804				c0 += 0x20;
805			else
806				c0 = 0x0fff;
807			if ((c1 + 0x20) < 0x0fff)
808				c1 += 0x20;
809			else
810				c1 = 0x0fff;
811			if ((c2 + 0x20) < 0x0fff)
812				c2 += 0x20;
813			else
814				c2 = 0x0fff;
815			outpdw(overlay_base + 0x188,
816						(c1 << 16 | c0));/* high */
817			outpdw(overlay_base + 0x18c, c2);/* high */
818		}
819	}
820	outpdw(overlay_base + off + 0x104, blend_op);
821}
822
823void mdp4_overlay_reg_flush(struct mdp4_overlay_pipe *pipe, int all)
824{
825	uint32 bits = 0;
826
827	if (pipe->mixer_num == MDP4_MIXER1)
828		bits |= 0x02;
829	else
830		bits |= 0x01;
831
832	if (all) {
833		if (pipe->pipe_type == OVERLAY_TYPE_RGB) {
834			if (pipe->pipe_num == OVERLAY_PIPE_RGB2)
835				bits |= 0x20;
836			else
837				bits |= 0x10;
838		} else {
839			if (pipe->pipe_num == OVERLAY_PIPE_VG2)
840				bits |= 0x08;
841			else
842				bits |= 0x04;
843		}
844	}
845
846	outpdw(MDP_BASE + 0x18000, bits);	/* MDP_OVERLAY_REG_FLUSH */
847
848	while (inpdw(MDP_BASE + 0x18000) & bits) /* self clear when complete */
849		;
850}
851
852struct mdp4_overlay_pipe *mdp4_overlay_ndx2pipe(int ndx)
853{
854	struct mdp4_overlay_pipe *pipe;
855
856	if (ndx == 0 || ndx >= MDP4_MAX_OVERLAY_PIPE)
857		return NULL;
858
859	pipe = &ctrl->plist[ndx - 1];	/* ndx start from 1 */
860
861	if (pipe->pipe_ndx == 0)
862		return NULL;
863
864	return pipe;
865}
866
867struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(void)
868{
869	int i;
870	struct mdp4_overlay_pipe *pipe;
871
872	pipe = &ctrl->plist[0];
873	for (i = 0; i < MDP4_MAX_OVERLAY_PIPE; i++) {
874		if (pipe->pipe_ndx == 0) {
875			pipe->pipe_ndx = i + 1;	/* start from 1 */
876			init_completion(&pipe->comp);
877	printk(KERN_INFO "mdp4_overlay_pipe_alloc: pipe=%p ndx=%d\n",
878					pipe, pipe->pipe_ndx);
879			return pipe;
880		}
881		pipe++;
882	}
883
884	return NULL;
885}
886
887
888void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe)
889{
890	printk(KERN_INFO "mdp4_overlay_pipe_free: pipe=%p ndx=%d\n",
891					pipe, pipe->pipe_ndx);
892	memset(pipe, 0, sizeof(*pipe));
893}
894
895static int get_pipe_num(int ptype, int stage)
896{
897	if (ptype == OVERLAY_TYPE_RGB) {
898		if (stage == MDP4_MIXER_STAGE_BASE)
899			return OVERLAY_PIPE_RGB1;
900		else
901			return OVERLAY_PIPE_RGB2;
902	} else {
903		if (stage == MDP4_MIXER_STAGE0)
904			return OVERLAY_PIPE_VG1;
905		else
906			return OVERLAY_PIPE_VG2;
907	}
908}
909
910int mdp4_overlay_req_check(uint32 id, uint32 z_order, uint32 mixer)
911{
912	struct mdp4_overlay_pipe *pipe;
913
914	pipe = ctrl->stage[mixer][z_order];
915
916	if (pipe == NULL)
917		return 0;
918
919	if (pipe->pipe_ndx == id)	/* same req, recycle */
920		return 0;
921
922	return -EPERM;
923}
924
925static int mdp4_overlay_req2pipe(struct mdp_overlay *req, int mixer,
926			struct mdp4_overlay_pipe **ppipe)
927{
928	struct mdp4_overlay_pipe *pipe;
929	int ret, ptype;
930
931	if (mixer >= MDP4_MAX_MIXER) {
932		printk(KERN_ERR "mpd_overlay_req2pipe: mixer out of range!\n");
933		return -ERANGE;
934	}
935
936	if (req->z_order < 0 || req->z_order > 2) {
937		printk(KERN_ERR "mpd_overlay_req2pipe: z_order=%d out of range!\n",
938				req->z_order);
939		return -ERANGE;
940	}
941
942	if (req->src_rect.h == 0 || req->src_rect.w == 0) {
943		printk(KERN_ERR "mpd_overlay_req2pipe: src img of zero size!\n");
944		return -EINVAL;
945	}
946
947	ret = mdp4_overlay_req_check(req->id, req->z_order, mixer);
948	if (ret < 0)
949		return ret;
950
951	ptype = mdp4_overlay_format2type(req->src.format);
952	if (ptype < 0)
953		return ptype;
954
955	if (req->id == MSMFB_NEW_REQUEST)  /* new request */
956		pipe = mdp4_overlay_pipe_alloc();
957	else
958		pipe = mdp4_overlay_ndx2pipe(req->id);
959
960	if (pipe == NULL)
961		return -ENOMEM;
962
963	pipe->src_format = req->src.format;
964	ret = mdp4_overlay_format2pipe(pipe);
965
966	if (ret < 0)
967		return ret;
968
969	/*
970	 * base layer == 1, reserved for frame buffer
971	 * zorder 0 == stage 0 == 2
972	 * zorder 1 == stage 1 == 3
973	 * zorder 2 == stage 2 == 4
974	 */
975	if (req->id == MSMFB_NEW_REQUEST) {  /* new request */
976		pipe->mixer_stage = req->z_order + MDP4_MIXER_STAGE0;
977		pipe->pipe_type = ptype;
978		pipe->pipe_num = get_pipe_num(ptype, pipe->mixer_stage);
979		printk(KERN_INFO "mpd4_overlay_req2pipe: zorder=%d pipe_num=%d\n",
980				req->z_order, pipe->pipe_num);
981	}
982
983	pipe->src_width = req->src.width & 0x07ff;	/* source img width */
984	pipe->src_height = req->src.height & 0x07ff;	/* source img height */
985	pipe->src_h = req->src_rect.h & 0x07ff;
986	pipe->src_w = req->src_rect.w & 0x07ff;
987	pipe->src_y = req->src_rect.y & 0x07ff;
988	pipe->src_x = req->src_rect.x & 0x07ff;
989	pipe->dst_h = req->dst_rect.h & 0x07ff;
990	pipe->dst_w = req->dst_rect.w & 0x07ff;
991	pipe->dst_y = req->dst_rect.y & 0x07ff;
992	pipe->dst_x = req->dst_rect.x & 0x07ff;
993
994	if (req->flags & MDP_FLIP_LR)
995		pipe->op_mode |= MDP4_OP_FLIP_LR;
996
997	if (req->flags & MDP_FLIP_UD)
998		pipe->op_mode |= MDP4_OP_FLIP_UD;
999
1000	if (req->flags & MDP_DITHER)
1001		pipe->op_mode |= MDP4_OP_DITHER_EN;
1002
1003	if (req->flags & MDP_DEINTERLACE)
1004		pipe->op_mode |= MDP4_OP_DEINT_ODD_REF;
1005
1006	pipe->is_fg = req->is_fg;/* control alpha and color key */
1007
1008	pipe->alpha = req->alpha & 0x0ff;
1009
1010	pipe->transp = req->transp_mask;
1011
1012	*ppipe = pipe;
1013
1014	return 0;
1015}
1016
1017int get_img(struct msmfb_data *img, struct fb_info *info,
1018	unsigned long *start, unsigned long *len, struct file **pp_file)
1019{
1020	int put_needed, ret = 0;
1021	struct file *file;
1022#ifdef CONFIG_ANDROID_PMEM
1023	unsigned long vstart;
1024#endif
1025
1026#ifdef CONFIG_ANDROID_PMEM
1027	if (!get_pmem_file(img->memory_id, start, &vstart, len, pp_file))
1028		return 0;
1029#endif
1030	file = fget_light(img->memory_id, &put_needed);
1031	if (file == NULL)
1032		return -1;
1033
1034	if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
1035		*start = info->fix.smem_start;
1036		*len = info->fix.smem_len;
1037		*pp_file = file;
1038	} else {
1039		ret = -1;
1040		fput_light(file, put_needed);
1041	}
1042	return ret;
1043}
1044int mdp4_overlay_get(struct fb_info *info, struct mdp_overlay *req)
1045{
1046	struct mdp4_overlay_pipe *pipe;
1047
1048	pipe = mdp4_overlay_ndx2pipe(req->id);
1049	if (pipe == NULL)
1050		return -ENODEV;
1051
1052	*req = pipe->req_data;
1053
1054	return 0;
1055}
1056
1057int mdp4_overlay_set(struct fb_info *info, struct mdp_overlay *req)
1058{
1059	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1060	int ret, mixer;
1061	struct mdp4_overlay_pipe *pipe;
1062	int lcdc;
1063
1064	if (mfd == NULL)
1065		return -ENODEV;
1066
1067	if (req->src.format == MDP_FB_FORMAT)
1068		req->src.format = mfd->fb_imgType;
1069
1070	if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
1071		return -EINTR;
1072
1073	mixer = info->node; /* minor number of char device */
1074
1075	ret = mdp4_overlay_req2pipe(req, mixer, &pipe);
1076	if (ret < 0) {
1077		mutex_unlock(&mfd->dma->ov_mutex);
1078		return ret;
1079	}
1080
1081	lcdc = inpdw(MDP_BASE + 0xc0000);
1082
1083	if (lcdc == 0) { /* mddi */
1084		/* MDP cmd block enable */
1085		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
1086	}
1087
1088	/* return id back to user */
1089	req->id = pipe->pipe_ndx;	/* pipe_ndx start from 1 */
1090	pipe->req_data = *req;		/* keep original req */
1091
1092	mutex_unlock(&mfd->dma->ov_mutex);
1093
1094	return 0;
1095}
1096
1097int mdp4_overlay_unset(struct fb_info *info, int ndx)
1098{
1099	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1100	struct mdp4_overlay_pipe *pipe;
1101	int lcdc;
1102
1103	if (mfd == NULL)
1104		return -ENODEV;
1105
1106	if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
1107		return -EINTR;
1108
1109	pipe = mdp4_overlay_ndx2pipe(ndx);
1110
1111	if (pipe == NULL) {
1112		mutex_unlock(&mfd->dma->ov_mutex);
1113		return -ENODEV;
1114	}
1115
1116	lcdc = inpdw(MDP_BASE + 0xc0000);
1117
1118	mdp4_mixer_stage_down(pipe);
1119
1120	if (lcdc == 0) { /* mddi */
1121		/* MDP cmd block disable */
1122		mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
1123	}
1124
1125	if (lcdc) /* LCDC mode */
1126		mdp4_overlay_reg_flush(pipe, 0);
1127
1128	mdp4_overlay_pipe_free(pipe);
1129
1130	if (lcdc == 0) { /* mddi */
1131		mdp4_mddi_overlay_restore();
1132	}
1133
1134	mutex_unlock(&mfd->dma->ov_mutex);
1135
1136	return 0;
1137}
1138
1139struct tile_desc {
1140	uint32 width;  /* tile's width */
1141	uint32 height; /* tile's height */
1142	uint32 row_tile_w; /* tiles per row's width */
1143	uint32 row_tile_h; /* tiles per row's height */
1144};
1145
1146void tile_samsung(struct tile_desc *tp)
1147{
1148	/*
1149	 * each row of samsung tile consists of two tiles in height
1150	 * and two tiles in width which means width should align to
1151	 * 64 x 2 bytes and height should align to 32 x 2 bytes.
1152	 * video decoder generate two tiles in width and one tile
1153	 * in height which ends up height align to 32 X 1 bytes.
1154	 */
1155	tp->width = 64;		/* 64 bytes */
1156	tp->row_tile_w = 2;	/* 2 tiles per row's width */
1157	tp->height = 32;	/* 32 bytes */
1158	tp->row_tile_h = 1;	/* 1 tiles per row's height */
1159}
1160
1161uint32 tile_mem_size(struct mdp4_overlay_pipe *pipe, struct tile_desc *tp)
1162{
1163	uint32 tile_w, tile_h;
1164	uint32 row_num_w, row_num_h;
1165
1166
1167	tile_w = tp->width * tp->row_tile_w;
1168	tile_h = tp->height * tp->row_tile_h;
1169
1170	row_num_w = (pipe->src_width + tile_w - 1) / tile_w;
1171	row_num_h = (pipe->src_height + tile_h - 1) / tile_h;
1172
1173	return row_num_w * row_num_h * tile_w * tile_h;
1174}
1175
1176int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req,
1177		struct file **pp_src_file)
1178{
1179	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
1180	struct msmfb_data *img;
1181	struct mdp4_overlay_pipe *pipe;
1182	ulong start, addr;
1183	ulong len = 0;
1184	struct file *p_src_file = 0;
1185	int lcdc;
1186
1187	if (mfd == NULL)
1188		return -ENODEV;
1189
1190	pipe = mdp4_overlay_ndx2pipe(req->id);
1191	if (pipe == NULL)
1192		return -ENODEV;
1193
1194	if (mutex_lock_interruptible(&mfd->dma->ov_mutex))
1195		return -EINTR;
1196
1197	img = &req->data;
1198	get_img(img, info, &start, &len, &p_src_file);
1199	if (len == 0) {
1200		mutex_unlock(&mfd->dma->ov_mutex);
1201		printk(KERN_ERR "mdp_overlay_play: could not retrieve"
1202				       " image from memory\n");
1203		return -1;
1204	}
1205	*pp_src_file = p_src_file;
1206
1207	addr = start + img->offset;
1208	pipe->srcp0_addr = addr;
1209	pipe->srcp0_ystride = pipe->src_width * pipe->bpp;
1210
1211	if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR) {
1212		if (pipe->frame_format == MDP4_FRAME_FORMAT_VIDEO_SUPERTILE) {
1213			struct tile_desc tile;
1214
1215			tile_samsung(&tile);
1216			pipe->srcp1_addr = addr + tile_mem_size(pipe, &tile);
1217		} else
1218			pipe->srcp1_addr = addr +
1219					pipe->src_width * pipe->src_height;
1220
1221		pipe->srcp0_ystride = pipe->src_width;
1222		pipe->srcp1_ystride = pipe->src_width;
1223	}
1224
1225	lcdc = inpdw(MDP_BASE + 0xc0000);
1226	lcdc &= 0x01; /* LCDC mode */
1227
1228	if (pipe->pipe_type == OVERLAY_TYPE_VG)
1229		mdp4_overlay_vg_setup(pipe);	/* video/graphic pipe */
1230	else
1231		mdp4_overlay_rgb_setup(pipe);	/* rgb pipe */
1232
1233	mdp4_mixer_blend_setup(pipe);
1234	mdp4_mixer_stage_up(pipe);
1235
1236	if (lcdc) { /* LCDC mode */
1237		mdp4_overlay_reg_flush(pipe, 1);
1238	}
1239
1240	if (lcdc) { /* LCDC mode */
1241		if (pipe->mixer_stage != MDP4_MIXER_STAGE_BASE) { /* done */
1242			mutex_unlock(&mfd->dma->ov_mutex);
1243			return 0;
1244		}
1245	}
1246
1247	if (lcdc == 0) { /* MDDI mode */
1248#ifdef MDP4_NONBLOCKING
1249		if (mfd->panel_power_on)
1250#else
1251		if (!mfd->dma->busy && mfd->panel_power_on)
1252#endif
1253			mdp4_mddi_overlay_kickoff(mfd, pipe);
1254	}
1255
1256	mutex_unlock(&mfd->dma->ov_mutex);
1257
1258	return 0;
1259}
1260