~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise-security

« back to all changes in this revision

Viewing changes to drivers/staging/msm/mdp4_overlay.c

  • Committer: Package Import Robot
  • Author(s): Paolo Pisati, Paolo Pisati
  • Date: 2011-12-06 15:56:07 UTC
  • Revision ID: package-import@ubuntu.com-20111206155607-pcf44kv5fmhk564f
Tags: 3.2.0-1401.1
[ Paolo Pisati ]

* Rebased on top of Ubuntu-3.2.0-3.8
* Tilt-tracking @ ef2487af4bb15bdd0689631774b5a5e3a59f74e2
* Delete debian.ti-omap4/control, it shoudln't be tracked
* Fix architecture spelling (s/armel/armhf/)
* [Config] Update configs following 3.2 import
* [Config] Fix compilation: disable CODA and ARCH_OMAP3
* [Config] Fix compilation: disable Ethernet Faraday
* Update series to precise

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
46
 
struct 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
 
 
51
 
static struct mdp4_overlay_ctrl *ctrl = &mdp4_overlay_db;
52
 
 
53
 
 
54
 
void 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
 
 
85
 
void 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
 
 
101
 
static 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
 
 
115
 
static 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
 
 
133
 
static 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
 
 
172
 
void 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
 
 
211
 
void 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
 
 
264
 
int 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
 
 
293
 
int 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
 
 */
484
 
static 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
 
 
502
 
void 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
 
 
568
 
uint32 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
 
 
605
 
uint32 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
 
 
611
 
void 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
 
 
632
 
int 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
 
 
657
 
void 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
 
 
692
 
void 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 running */
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
 
 
727
 
void 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
 
 
823
 
void 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
 
 
852
 
struct 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
 
 
867
 
struct 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
 
 
888
 
void 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
 
 
895
 
static 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
 
 
910
 
int 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
 
 
925
 
static 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
 
 
1017
 
int 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
 
}
1044
 
int 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
 
 
1057
 
int 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
 
 
1097
 
int 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
 
 
1139
 
struct 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
 
 
1146
 
void 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
 
 
1161
 
uint32 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
 
 
1176
 
int 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
 
}