block: fix warning with calling smp_processor_id() in preemptible section
[pandora-kernel.git] / drivers / staging / msm / mdp_ppp_v31.c
1 /* Copyright (c) 2008-2010, 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/fb.h>
25 #include "linux/proc_fs.h"
26
27 #include <mach/hardware.h>
28 #include <linux/io.h>
29
30 #include <asm/system.h>
31 #include <asm/mach-types.h>
32 #include <linux/semaphore.h>
33 #include <asm/div64.h>
34
35 #include "mdp.h"
36 #include "msm_fb.h"
37
38 #define MDP_SCALE_COEFF_NUM      32
39 #define MDP_SCALE_0P2_TO_0P4_INDEX 0
40 #define MDP_SCALE_0P4_TO_0P6_INDEX 32
41 #define MDP_SCALE_0P6_TO_0P8_INDEX 64
42 #define MDP_SCALE_0P8_TO_8P0_INDEX 96
43 #define MDP_SCALE_COEFF_MASK 0x3ff
44
45 #define MDP_SCALE_PR  0
46 #define MDP_SCALE_FIR 1
47
48 static uint32 mdp_scale_0p8_to_8p0_mode;
49 static uint32 mdp_scale_0p6_to_0p8_mode;
50 static uint32 mdp_scale_0p4_to_0p6_mode;
51 static uint32 mdp_scale_0p2_to_0p4_mode;
52
53 /* -------- All scaling range, "pixel repeat" -------- */
54 static int16 mdp_scale_pixel_repeat_C0[MDP_SCALE_COEFF_NUM] = {
55         0, 0, 0, 0, 0, 0, 0, 0,
56         0, 0, 0, 0, 0, 0, 0, 0,
57         0, 0, 0, 0, 0, 0, 0, 0,
58         0, 0, 0, 0, 0, 0, 0, 0
59 };
60
61 static int16 mdp_scale_pixel_repeat_C1[MDP_SCALE_COEFF_NUM] = {
62         511, 511, 511, 511, 511, 511, 511, 511,
63         511, 511, 511, 511, 511, 511, 511, 511,
64         511, 511, 511, 511, 511, 511, 511, 511,
65         511, 511, 511, 511, 511, 511, 511, 511
66 };
67
68 static int16 mdp_scale_pixel_repeat_C2[MDP_SCALE_COEFF_NUM] = {
69         0, 0, 0, 0, 0, 0, 0, 0,
70         0, 0, 0, 0, 0, 0, 0, 0,
71         0, 0, 0, 0, 0, 0, 0, 0,
72         0, 0, 0, 0, 0, 0, 0, 0
73 };
74
75 static int16 mdp_scale_pixel_repeat_C3[MDP_SCALE_COEFF_NUM] = {
76         0, 0, 0, 0, 0, 0, 0, 0,
77         0, 0, 0, 0, 0, 0, 0, 0,
78         0, 0, 0, 0, 0, 0, 0, 0,
79         0, 0, 0, 0, 0, 0, 0, 0
80 };
81
82 /* --------------------------- FIR ------------------------------------- */
83 /* -------- Downscale, ranging from 0.8x to 8.0x of original size -------- */
84
85 static int16 mdp_scale_0p8_to_8p0_C0[MDP_SCALE_COEFF_NUM] = {
86         0, -7, -13, -19, -24, -28, -32, -34, -37, -39,
87         -40, -41, -41, -41, -40, -40, -38, -37, -35, -33,
88         -31, -29, -26, -24, -21, -18, -15, -13, -10, -7,
89         -5, -2
90 };
91
92 static int16 mdp_scale_0p8_to_8p0_C1[MDP_SCALE_COEFF_NUM] = {
93         511, 507, 501, 494, 485, 475, 463, 450, 436, 422,
94         405, 388, 370, 352, 333, 314, 293, 274, 253, 233,
95         213, 193, 172, 152, 133, 113, 95, 77, 60, 43,
96         28, 13
97 };
98
99 static int16 mdp_scale_0p8_to_8p0_C2[MDP_SCALE_COEFF_NUM] = {
100         0, 13, 28, 43, 60, 77, 95, 113, 133, 152,
101         172, 193, 213, 233, 253, 274, 294, 314, 333, 352,
102         370, 388, 405, 422, 436, 450, 463, 475, 485, 494,
103         501, 507,
104 };
105
106 static int16 mdp_scale_0p8_to_8p0_C3[MDP_SCALE_COEFF_NUM] = {
107         0, -2, -5, -7, -10, -13, -15, -18, -21, -24,
108         -26, -29, -31, -33, -35, -37, -38, -40, -40, -41,
109         -41, -41, -40, -39, -37, -34, -32, -28, -24, -19,
110         -13, -7
111 };
112
113 /* -------- Downscale, ranging from 0.6x to 0.8x of original size -------- */
114
115 static int16 mdp_scale_0p6_to_0p8_C0[MDP_SCALE_COEFF_NUM] = {
116         104, 96, 89, 82, 75, 68, 61, 55, 49, 43,
117         38, 33, 28, 24, 20, 16, 12, 9, 6, 4,
118         2, 0, -2, -4, -5, -6, -7, -7, -8, -8,
119         -8, -8
120 };
121
122 static int16 mdp_scale_0p6_to_0p8_C1[MDP_SCALE_COEFF_NUM] = {
123         303, 303, 302, 300, 298, 296, 293, 289, 286, 281,
124         276, 270, 265, 258, 252, 245, 238, 230, 223, 214,
125         206, 197, 189, 180, 172, 163, 154, 145, 137, 128,
126         120, 112
127 };
128
129 static int16 mdp_scale_0p6_to_0p8_C2[MDP_SCALE_COEFF_NUM] = {
130         112, 120, 128, 137, 145, 154, 163, 172, 180, 189,
131         197, 206, 214, 223, 230, 238, 245, 252, 258, 265,
132         270, 276, 281, 286, 289, 293, 296, 298, 300, 302,
133         303, 303
134 };
135
136 static int16 mdp_scale_0p6_to_0p8_C3[MDP_SCALE_COEFF_NUM] = {
137         -8, -8, -8, -8, -7, -7, -6, -5, -4, -2,
138         0, 2, 4, 6, 9, 12, 16, 20, 24, 28,
139         33, 38, 43, 49, 55, 61, 68, 75, 82, 89,
140         96, 104
141 };
142
143 /* -------- Downscale, ranging from 0.4x to 0.6x of original size -------- */
144
145 static int16 mdp_scale_0p4_to_0p6_C0[MDP_SCALE_COEFF_NUM] = {
146         136, 132, 128, 123, 119, 115, 111, 107, 103, 98,
147         95, 91, 87, 84, 80, 76, 73, 69, 66, 62,
148         59, 57, 54, 50, 47, 44, 41, 39, 36, 33,
149         32, 29
150 };
151
152 static int16 mdp_scale_0p4_to_0p6_C1[MDP_SCALE_COEFF_NUM] = {
153         206, 205, 204, 204, 201, 200, 199, 197, 196, 194,
154         191, 191, 189, 185, 184, 182, 180, 178, 176, 173,
155         170, 168, 165, 162, 160, 157, 155, 152, 148, 146,
156         142, 140
157 };
158
159 static int16 mdp_scale_0p4_to_0p6_C2[MDP_SCALE_COEFF_NUM] = {
160         140, 142, 146, 148, 152, 155, 157, 160, 162, 165,
161         168, 170, 173, 176, 178, 180, 182, 184, 185, 189,
162         191, 191, 194, 196, 197, 199, 200, 201, 204, 204,
163         205, 206
164 };
165
166 static int16 mdp_scale_0p4_to_0p6_C3[MDP_SCALE_COEFF_NUM] = {
167         29, 32, 33, 36, 39, 41, 44, 47, 50, 54,
168         57, 59, 62, 66, 69, 73, 76, 80, 84, 87,
169         91, 95, 98, 103, 107, 111, 115, 119, 123, 128,
170         132, 136
171 };
172
173 /* -------- Downscale, ranging from 0.2x to 0.4x of original size -------- */
174
175 static int16 mdp_scale_0p2_to_0p4_C0[MDP_SCALE_COEFF_NUM] = {
176         131, 131, 130, 129, 128, 127, 127, 126, 125, 125,
177         124, 123, 123, 121, 120, 119, 119, 118, 117, 117,
178         116, 115, 115, 114, 113, 112, 111, 110, 109, 109,
179         108, 107
180 };
181
182 static int16 mdp_scale_0p2_to_0p4_C1[MDP_SCALE_COEFF_NUM] = {
183         141, 140, 140, 140, 140, 139, 138, 138, 138, 137,
184         137, 137, 136, 137, 137, 137, 136, 136, 136, 135,
185         135, 135, 134, 134, 134, 134, 134, 133, 133, 132,
186         132, 132
187 };
188
189 static int16 mdp_scale_0p2_to_0p4_C2[MDP_SCALE_COEFF_NUM] = {
190         132, 132, 132, 133, 133, 134, 134, 134, 134, 134,
191         135, 135, 135, 136, 136, 136, 137, 137, 137, 136,
192         137, 137, 137, 138, 138, 138, 139, 140, 140, 140,
193         140, 141
194 };
195
196 static int16 mdp_scale_0p2_to_0p4_C3[MDP_SCALE_COEFF_NUM] = {
197         107, 108, 109, 109, 110, 111, 112, 113, 114, 115,
198         115, 116, 117, 117, 118, 119, 119, 120, 121, 123,
199         123, 124, 125, 125, 126, 127, 127, 128, 129, 130,
200         131, 131
201 };
202
203 static void mdp_update_scale_table(int index, int16 *c0, int16 *c1,
204                                    int16 *c2, int16 *c3)
205 {
206         int i, val;
207
208         for (i = 0; i < MDP_SCALE_COEFF_NUM; i++) {
209                 val =
210                     ((MDP_SCALE_COEFF_MASK & c1[i]) << 16) |
211                     (MDP_SCALE_COEFF_MASK & c0[i]);
212                 MDP_OUTP(MDP_PPP_SCALE_COEFF_LSBn(index), val);
213                 val =
214                     ((MDP_SCALE_COEFF_MASK & c3[i]) << 16) |
215                     (MDP_SCALE_COEFF_MASK & c2[i]);
216                 MDP_OUTP(MDP_PPP_SCALE_COEFF_MSBn(index), val);
217                 index++;
218         }
219 }
220
221 void mdp_init_scale_table(void)
222 {
223         mdp_scale_0p2_to_0p4_mode = MDP_SCALE_FIR;
224         mdp_update_scale_table(MDP_SCALE_0P2_TO_0P4_INDEX,
225                                mdp_scale_0p2_to_0p4_C0,
226                                mdp_scale_0p2_to_0p4_C1,
227                                mdp_scale_0p2_to_0p4_C2,
228                                mdp_scale_0p2_to_0p4_C3);
229
230         mdp_scale_0p4_to_0p6_mode = MDP_SCALE_FIR;
231         mdp_update_scale_table(MDP_SCALE_0P4_TO_0P6_INDEX,
232                                mdp_scale_0p4_to_0p6_C0,
233                                mdp_scale_0p4_to_0p6_C1,
234                                mdp_scale_0p4_to_0p6_C2,
235                                mdp_scale_0p4_to_0p6_C3);
236
237         mdp_scale_0p6_to_0p8_mode = MDP_SCALE_FIR;
238         mdp_update_scale_table(MDP_SCALE_0P6_TO_0P8_INDEX,
239                                mdp_scale_0p6_to_0p8_C0,
240                                mdp_scale_0p6_to_0p8_C1,
241                                mdp_scale_0p6_to_0p8_C2,
242                                mdp_scale_0p6_to_0p8_C3);
243
244         mdp_scale_0p8_to_8p0_mode = MDP_SCALE_FIR;
245         mdp_update_scale_table(MDP_SCALE_0P8_TO_8P0_INDEX,
246                                mdp_scale_0p8_to_8p0_C0,
247                                mdp_scale_0p8_to_8p0_C1,
248                                mdp_scale_0p8_to_8p0_C2,
249                                mdp_scale_0p8_to_8p0_C3);
250 }
251
252 static long long mdp_do_div(long long num, long long den)
253 {
254         do_div(num, den);
255         return num;
256 }
257
258 #define SCALER_PHASE_BITS 29
259 #define HAL_MDP_PHASE_STEP_2P50    0x50000000
260 #define HAL_MDP_PHASE_STEP_1P66    0x35555555
261 #define HAL_MDP_PHASE_STEP_1P25    0x28000000
262
263 struct phase_val {
264         int phase_init_x;
265         int phase_init_y;
266         int phase_step_x;
267         int phase_step_y;
268 };
269
270 static void mdp_calc_scaleInitPhase_3p1(uint32 in_w,
271                                         uint32 in_h,
272                                         uint32 out_w,
273                                         uint32 out_h,
274                                         boolean is_rotate,
275                                         boolean is_pp_x,
276                                         boolean is_pp_y, struct phase_val *pval)
277 {
278         uint64 dst_ROI_width;
279         uint64 dst_ROI_height;
280         uint64 src_ROI_width;
281         uint64 src_ROI_height;
282
283         /*
284          * phase_step_x, phase_step_y, phase_init_x and phase_init_y
285          * are represented in fixed-point, unsigned 3.29 format
286          */
287         uint32 phase_step_x = 0;
288         uint32 phase_step_y = 0;
289         uint32 phase_init_x = 0;
290         uint32 phase_init_y = 0;
291         uint32 yscale_filter_sel, xscale_filter_sel;
292         uint32 scale_unit_sel_x, scale_unit_sel_y;
293
294         uint64 numerator, denominator;
295         uint64 temp_dim;
296
297         src_ROI_width = in_w;
298         src_ROI_height = in_h;
299         dst_ROI_width = out_w;
300         dst_ROI_height = out_h;
301
302         /* if there is a 90 degree rotation */
303         if (is_rotate) {
304                 /* decide whether to use FIR or M/N for scaling */
305
306                 /* if down-scaling by a factor smaller than 1/4 */
307                 if (src_ROI_width > (4 * dst_ROI_height))
308                         scale_unit_sel_x = 1;   /* use M/N scalar */
309                 else
310                         scale_unit_sel_x = 0;   /* use FIR scalar */
311
312                 /* if down-scaling by a factor smaller than 1/4 */
313                 if (src_ROI_height > (4 * dst_ROI_width))
314                         scale_unit_sel_y = 1;   /* use M/N scalar */
315                 else
316                         scale_unit_sel_y = 0;   /* use FIR scalar */
317         } else {
318                 /* decide whether to use FIR or M/N for scaling */
319
320                 if (src_ROI_width > (4 * dst_ROI_width))
321                         scale_unit_sel_x = 1;   /* use M/N scalar */
322                 else
323                         scale_unit_sel_x = 0;   /* use FIR scalar */
324
325                 if (src_ROI_height > (4 * dst_ROI_height))
326                         scale_unit_sel_y = 1;   /* use M/N scalar */
327                 else
328                         scale_unit_sel_y = 0;   /* use FIR scalar */
329
330         }
331
332         /* if there is a 90 degree rotation */
333         if (is_rotate) {
334                 /* swap the width and height of dst ROI */
335                 temp_dim = dst_ROI_width;
336                 dst_ROI_width = dst_ROI_height;
337                 dst_ROI_height = temp_dim;
338         }
339
340         /* calculate phase step for the x direction */
341
342         /* if destination is only 1 pixel wide, the value of phase_step_x
343            is unimportant. Assigning phase_step_x to src ROI width
344            as an arbitrary value. */
345         if (dst_ROI_width == 1)
346                 phase_step_x = (uint32) ((src_ROI_width) << SCALER_PHASE_BITS);
347
348         /* if using FIR scalar */
349         else if (scale_unit_sel_x == 0) {
350
351                 /* Calculate the quotient ( src_ROI_width - 1 ) / ( dst_ROI_width - 1)
352                    with u3.29 precision. Quotient is rounded up to the larger
353                    29th decimal point. */
354                 numerator = (src_ROI_width - 1) << SCALER_PHASE_BITS;
355                 denominator = (dst_ROI_width - 1);      /* never equals to 0 because of the "( dst_ROI_width == 1 ) case" */
356                 phase_step_x = (uint32) mdp_do_div((numerator + denominator - 1), denominator); /* divide and round up to the larger 29th decimal point. */
357
358         }
359
360         /* if M/N scalar */
361         else if (scale_unit_sel_x == 1) {
362                 /* Calculate the quotient ( src_ROI_width ) / ( dst_ROI_width)
363                    with u3.29 precision. Quotient is rounded down to the
364                    smaller 29th decimal point. */
365                 numerator = (src_ROI_width) << SCALER_PHASE_BITS;
366                 denominator = (dst_ROI_width);
367                 phase_step_x = (uint32) mdp_do_div(numerator, denominator);
368         }
369         /* calculate phase step for the y direction */
370
371         /* if destination is only 1 pixel wide, the value of
372            phase_step_x is unimportant. Assigning phase_step_x
373            to src ROI width as an arbitrary value. */
374         if (dst_ROI_height == 1)
375                 phase_step_y = (uint32) ((src_ROI_height) << SCALER_PHASE_BITS);
376
377         /* if FIR scalar */
378         else if (scale_unit_sel_y == 0) {
379                 /* Calculate the quotient ( src_ROI_height - 1 ) / ( dst_ROI_height - 1)
380                    with u3.29 precision. Quotient is rounded up to the larger
381                    29th decimal point. */
382                 numerator = (src_ROI_height - 1) << SCALER_PHASE_BITS;
383                 denominator = (dst_ROI_height - 1);     /* never equals to 0 because of the "( dst_ROI_height == 1 )" case */
384                 phase_step_y = (uint32) mdp_do_div((numerator + denominator - 1), denominator); /* Quotient is rounded up to the larger 29th decimal point. */
385
386         }
387
388         /* if M/N scalar */
389         else if (scale_unit_sel_y == 1) {
390                 /* Calculate the quotient ( src_ROI_height ) / ( dst_ROI_height)
391                    with u3.29 precision. Quotient is rounded down to the smaller
392                    29th decimal point. */
393                 numerator = (src_ROI_height) << SCALER_PHASE_BITS;
394                 denominator = (dst_ROI_height);
395                 phase_step_y = (uint32) mdp_do_div(numerator, denominator);
396         }
397
398         /* decide which set of FIR coefficients to use */
399         if (phase_step_x > HAL_MDP_PHASE_STEP_2P50)
400                 xscale_filter_sel = 0;
401         else if (phase_step_x > HAL_MDP_PHASE_STEP_1P66)
402                 xscale_filter_sel = 1;
403         else if (phase_step_x > HAL_MDP_PHASE_STEP_1P25)
404                 xscale_filter_sel = 2;
405         else
406                 xscale_filter_sel = 3;
407
408         if (phase_step_y > HAL_MDP_PHASE_STEP_2P50)
409                 yscale_filter_sel = 0;
410         else if (phase_step_y > HAL_MDP_PHASE_STEP_1P66)
411                 yscale_filter_sel = 1;
412         else if (phase_step_y > HAL_MDP_PHASE_STEP_1P25)
413                 yscale_filter_sel = 2;
414         else
415                 yscale_filter_sel = 3;
416
417         /* calculate phase init for the x direction */
418
419         /* if using FIR scalar */
420         if (scale_unit_sel_x == 0) {
421                 if (dst_ROI_width == 1)
422                         phase_init_x =
423                             (uint32) ((src_ROI_width - 1) << SCALER_PHASE_BITS);
424                 else
425                         phase_init_x = 0;
426
427         }
428         /* M over N scalar  */
429         else if (scale_unit_sel_x == 1)
430                 phase_init_x = 0;
431
432         /* calculate phase init for the y direction
433            if using FIR scalar */
434         if (scale_unit_sel_y == 0) {
435                 if (dst_ROI_height == 1)
436                         phase_init_y =
437                             (uint32) ((src_ROI_height -
438                                        1) << SCALER_PHASE_BITS);
439                 else
440                         phase_init_y = 0;
441
442         }
443         /* M over N scalar   */
444         else if (scale_unit_sel_y == 1)
445                 phase_init_y = 0;
446
447         /* write registers */
448         pval->phase_step_x = (uint32) phase_step_x;
449         pval->phase_step_y = (uint32) phase_step_y;
450         pval->phase_init_x = (uint32) phase_init_x;
451         pval->phase_init_y = (uint32) phase_init_y;
452
453         return;
454 }
455
456 void mdp_set_scale(MDPIBUF *iBuf,
457                    uint32 dst_roi_width,
458                    uint32 dst_roi_height,
459                    boolean inputRGB, boolean outputRGB, uint32 *pppop_reg_ptr)
460 {
461         uint32 dst_roi_width_scale;
462         uint32 dst_roi_height_scale;
463         struct phase_val pval;
464         boolean use_pr;
465         uint32 ppp_scale_config = 0;
466
467         if (!inputRGB)
468                 ppp_scale_config |= BIT(6);
469
470         if (iBuf->mdpImg.mdpOp & MDPOP_ASCALE) {
471                 if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) {
472                         dst_roi_width_scale = dst_roi_height;
473                         dst_roi_height_scale = dst_roi_width;
474                 } else {
475                         dst_roi_width_scale = dst_roi_width;
476                         dst_roi_height_scale = dst_roi_height;
477                 }
478
479                 if ((dst_roi_width_scale != iBuf->roi.width) ||
480                     (dst_roi_height_scale != iBuf->roi.height) ||
481                         (iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
482                         *pppop_reg_ptr |=
483                             (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
484
485                         mdp_calc_scaleInitPhase_3p1(iBuf->roi.width,
486                                                     iBuf->roi.height,
487                                                     dst_roi_width,
488                                                     dst_roi_height,
489                                                     iBuf->mdpImg.
490                                                     mdpOp & MDPOP_ROT90, 1, 1,
491                                                     &pval);
492
493                         MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x013c,
494                                  pval.phase_init_x);
495                         MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0140,
496                                  pval.phase_init_y);
497                         MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0144,
498                                  pval.phase_step_x);
499                         MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0148,
500                                  pval.phase_step_y);
501
502                         use_pr = (inputRGB) && (outputRGB);
503
504                         /* x-direction */
505                         if ((dst_roi_width_scale == iBuf->roi.width) &&
506                                 !(iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
507                                 *pppop_reg_ptr &= ~PPP_OP_SCALE_X_ON;
508                         } else
509                             if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
510                                 8) {
511                                 if ((use_pr)
512                                     && (mdp_scale_0p8_to_8p0_mode !=
513                                         MDP_SCALE_PR)) {
514                                         mdp_scale_0p8_to_8p0_mode =
515                                             MDP_SCALE_PR;
516                                         mdp_update_scale_table
517                                             (MDP_SCALE_0P8_TO_8P0_INDEX,
518                                              mdp_scale_pixel_repeat_C0,
519                                              mdp_scale_pixel_repeat_C1,
520                                              mdp_scale_pixel_repeat_C2,
521                                              mdp_scale_pixel_repeat_C3);
522                                 } else if ((!use_pr)
523                                            && (mdp_scale_0p8_to_8p0_mode !=
524                                                MDP_SCALE_FIR)) {
525                                         mdp_scale_0p8_to_8p0_mode =
526                                             MDP_SCALE_FIR;
527                                         mdp_update_scale_table
528                                             (MDP_SCALE_0P8_TO_8P0_INDEX,
529                                              mdp_scale_0p8_to_8p0_C0,
530                                              mdp_scale_0p8_to_8p0_C1,
531                                              mdp_scale_0p8_to_8p0_C2,
532                                              mdp_scale_0p8_to_8p0_C3);
533                                 }
534                                 ppp_scale_config |= (SCALE_U1_SET << 2);
535                         } else
536                             if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
537                                 6) {
538                                 if ((use_pr)
539                                     && (mdp_scale_0p6_to_0p8_mode !=
540                                         MDP_SCALE_PR)) {
541                                         mdp_scale_0p6_to_0p8_mode =
542                                             MDP_SCALE_PR;
543                                         mdp_update_scale_table
544                                             (MDP_SCALE_0P6_TO_0P8_INDEX,
545                                              mdp_scale_pixel_repeat_C0,
546                                              mdp_scale_pixel_repeat_C1,
547                                              mdp_scale_pixel_repeat_C2,
548                                              mdp_scale_pixel_repeat_C3);
549                                 } else if ((!use_pr)
550                                            && (mdp_scale_0p6_to_0p8_mode !=
551                                                MDP_SCALE_FIR)) {
552                                         mdp_scale_0p6_to_0p8_mode =
553                                             MDP_SCALE_FIR;
554                                         mdp_update_scale_table
555                                             (MDP_SCALE_0P6_TO_0P8_INDEX,
556                                              mdp_scale_0p6_to_0p8_C0,
557                                              mdp_scale_0p6_to_0p8_C1,
558                                              mdp_scale_0p6_to_0p8_C2,
559                                              mdp_scale_0p6_to_0p8_C3);
560                                 }
561                                 ppp_scale_config |= (SCALE_D2_SET << 2);
562                         } else
563                             if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
564                                 4) {
565                                 if ((use_pr)
566                                     && (mdp_scale_0p4_to_0p6_mode !=
567                                         MDP_SCALE_PR)) {
568                                         mdp_scale_0p4_to_0p6_mode =
569                                             MDP_SCALE_PR;
570                                         mdp_update_scale_table
571                                             (MDP_SCALE_0P4_TO_0P6_INDEX,
572                                              mdp_scale_pixel_repeat_C0,
573                                              mdp_scale_pixel_repeat_C1,
574                                              mdp_scale_pixel_repeat_C2,
575                                              mdp_scale_pixel_repeat_C3);
576                                 } else if ((!use_pr)
577                                            && (mdp_scale_0p4_to_0p6_mode !=
578                                                MDP_SCALE_FIR)) {
579                                         mdp_scale_0p4_to_0p6_mode =
580                                             MDP_SCALE_FIR;
581                                         mdp_update_scale_table
582                                             (MDP_SCALE_0P4_TO_0P6_INDEX,
583                                              mdp_scale_0p4_to_0p6_C0,
584                                              mdp_scale_0p4_to_0p6_C1,
585                                              mdp_scale_0p4_to_0p6_C2,
586                                              mdp_scale_0p4_to_0p6_C3);
587                                 }
588                                 ppp_scale_config |= (SCALE_D1_SET << 2);
589                         } else
590                             if (((dst_roi_width_scale * 4) / iBuf->roi.width) >=
591                                 1) {
592                                 if ((use_pr)
593                                     && (mdp_scale_0p2_to_0p4_mode !=
594                                         MDP_SCALE_PR)) {
595                                         mdp_scale_0p2_to_0p4_mode =
596                                             MDP_SCALE_PR;
597                                         mdp_update_scale_table
598                                             (MDP_SCALE_0P2_TO_0P4_INDEX,
599                                              mdp_scale_pixel_repeat_C0,
600                                              mdp_scale_pixel_repeat_C1,
601                                              mdp_scale_pixel_repeat_C2,
602                                              mdp_scale_pixel_repeat_C3);
603                                 } else if ((!use_pr)
604                                            && (mdp_scale_0p2_to_0p4_mode !=
605                                                MDP_SCALE_FIR)) {
606                                         mdp_scale_0p2_to_0p4_mode =
607                                             MDP_SCALE_FIR;
608                                         mdp_update_scale_table
609                                             (MDP_SCALE_0P2_TO_0P4_INDEX,
610                                              mdp_scale_0p2_to_0p4_C0,
611                                              mdp_scale_0p2_to_0p4_C1,
612                                              mdp_scale_0p2_to_0p4_C2,
613                                              mdp_scale_0p2_to_0p4_C3);
614                                 }
615                                 ppp_scale_config |= (SCALE_D0_SET << 2);
616                         } else
617                                 ppp_scale_config |= BIT(0);
618
619                         /* y-direction */
620                         if ((dst_roi_height_scale == iBuf->roi.height) &&
621                                 !(iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
622                                 *pppop_reg_ptr &= ~PPP_OP_SCALE_Y_ON;
623                         } else if (((dst_roi_height_scale * 10) /
624                                         iBuf->roi.height) > 8) {
625                                 if ((use_pr)
626                                     && (mdp_scale_0p8_to_8p0_mode !=
627                                         MDP_SCALE_PR)) {
628                                         mdp_scale_0p8_to_8p0_mode =
629                                             MDP_SCALE_PR;
630                                         mdp_update_scale_table
631                                             (MDP_SCALE_0P8_TO_8P0_INDEX,
632                                              mdp_scale_pixel_repeat_C0,
633                                              mdp_scale_pixel_repeat_C1,
634                                              mdp_scale_pixel_repeat_C2,
635                                              mdp_scale_pixel_repeat_C3);
636                                 } else if ((!use_pr)
637                                            && (mdp_scale_0p8_to_8p0_mode !=
638                                                MDP_SCALE_FIR)) {
639                                         mdp_scale_0p8_to_8p0_mode =
640                                             MDP_SCALE_FIR;
641                                         mdp_update_scale_table
642                                             (MDP_SCALE_0P8_TO_8P0_INDEX,
643                                              mdp_scale_0p8_to_8p0_C0,
644                                              mdp_scale_0p8_to_8p0_C1,
645                                              mdp_scale_0p8_to_8p0_C2,
646                                              mdp_scale_0p8_to_8p0_C3);
647                                 }
648                                 ppp_scale_config |= (SCALE_U1_SET << 4);
649                         } else
650                             if (((dst_roi_height_scale * 10) /
651                                  iBuf->roi.height) > 6) {
652                                 if ((use_pr)
653                                     && (mdp_scale_0p6_to_0p8_mode !=
654                                         MDP_SCALE_PR)) {
655                                         mdp_scale_0p6_to_0p8_mode =
656                                             MDP_SCALE_PR;
657                                         mdp_update_scale_table
658                                             (MDP_SCALE_0P6_TO_0P8_INDEX,
659                                              mdp_scale_pixel_repeat_C0,
660                                              mdp_scale_pixel_repeat_C1,
661                                              mdp_scale_pixel_repeat_C2,
662                                              mdp_scale_pixel_repeat_C3);
663                                 } else if ((!use_pr)
664                                            && (mdp_scale_0p6_to_0p8_mode !=
665                                                MDP_SCALE_FIR)) {
666                                         mdp_scale_0p6_to_0p8_mode =
667                                             MDP_SCALE_FIR;
668                                         mdp_update_scale_table
669                                             (MDP_SCALE_0P6_TO_0P8_INDEX,
670                                              mdp_scale_0p6_to_0p8_C0,
671                                              mdp_scale_0p6_to_0p8_C1,
672                                              mdp_scale_0p6_to_0p8_C2,
673                                              mdp_scale_0p6_to_0p8_C3);
674                                 }
675                                 ppp_scale_config |= (SCALE_D2_SET << 4);
676                         } else
677                             if (((dst_roi_height_scale * 10) /
678                                  iBuf->roi.height) > 4) {
679                                 if ((use_pr)
680                                     && (mdp_scale_0p4_to_0p6_mode !=
681                                         MDP_SCALE_PR)) {
682                                         mdp_scale_0p4_to_0p6_mode =
683                                             MDP_SCALE_PR;
684                                         mdp_update_scale_table
685                                             (MDP_SCALE_0P4_TO_0P6_INDEX,
686                                              mdp_scale_pixel_repeat_C0,
687                                              mdp_scale_pixel_repeat_C1,
688                                              mdp_scale_pixel_repeat_C2,
689                                              mdp_scale_pixel_repeat_C3);
690                                 } else if ((!use_pr)
691                                            && (mdp_scale_0p4_to_0p6_mode !=
692                                                MDP_SCALE_FIR)) {
693                                         mdp_scale_0p4_to_0p6_mode =
694                                             MDP_SCALE_FIR;
695                                         mdp_update_scale_table
696                                             (MDP_SCALE_0P4_TO_0P6_INDEX,
697                                              mdp_scale_0p4_to_0p6_C0,
698                                              mdp_scale_0p4_to_0p6_C1,
699                                              mdp_scale_0p4_to_0p6_C2,
700                                              mdp_scale_0p4_to_0p6_C3);
701                                 }
702                                 ppp_scale_config |= (SCALE_D1_SET << 4);
703                         } else
704                             if (((dst_roi_height_scale * 4) /
705                                  iBuf->roi.height) >= 1) {
706                                 if ((use_pr)
707                                     && (mdp_scale_0p2_to_0p4_mode !=
708                                         MDP_SCALE_PR)) {
709                                         mdp_scale_0p2_to_0p4_mode =
710                                             MDP_SCALE_PR;
711                                         mdp_update_scale_table
712                                             (MDP_SCALE_0P2_TO_0P4_INDEX,
713                                              mdp_scale_pixel_repeat_C0,
714                                              mdp_scale_pixel_repeat_C1,
715                                              mdp_scale_pixel_repeat_C2,
716                                              mdp_scale_pixel_repeat_C3);
717                                 } else if ((!use_pr)
718                                            && (mdp_scale_0p2_to_0p4_mode !=
719                                                MDP_SCALE_FIR)) {
720                                         mdp_scale_0p2_to_0p4_mode =
721                                             MDP_SCALE_FIR;
722                                         mdp_update_scale_table
723                                             (MDP_SCALE_0P2_TO_0P4_INDEX,
724                                              mdp_scale_0p2_to_0p4_C0,
725                                              mdp_scale_0p2_to_0p4_C1,
726                                              mdp_scale_0p2_to_0p4_C2,
727                                              mdp_scale_0p2_to_0p4_C3);
728                                 }
729                                 ppp_scale_config |= (SCALE_D0_SET << 4);
730                         } else
731                                 ppp_scale_config |= BIT(1);
732
733                         if (iBuf->mdpImg.mdpOp & MDPOP_SHARPENING) {
734                                 ppp_scale_config |= BIT(7);
735                                 MDP_OUTP(MDP_BASE + 0x50020,
736                                                 iBuf->mdpImg.sp_value);
737                         }
738
739                         MDP_OUTP(MDP_BASE + 0x10230, ppp_scale_config);
740                 } else {
741                         iBuf->mdpImg.mdpOp &= ~(MDPOP_ASCALE);
742                 }
743         }
744 }
745
746 void mdp_adjust_start_addr(uint8 **src0,
747                            uint8 **src1,
748                            int v_slice,
749                            int h_slice,
750                            int x,
751                            int y,
752                            uint32 width,
753                            uint32 height, int bpp, MDPIBUF *iBuf, int layer)
754 {
755         switch (layer) {
756         case 0:
757                 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0200, (y << 16) | (x));
758                 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0208,
759                          (height << 16) | (width));
760                 break;
761
762         case 1:
763                 /* MDP 3.1 HW bug workaround */
764                 if (iBuf->ibuf_type == MDP_YCRYCB_H2V1) {
765                         *src0 += (x + y * width) * bpp;
766                         x = y = 0;
767                         width = iBuf->roi.dst_width;
768                         height = iBuf->roi.dst_height;
769                 }
770
771                 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0204, (y << 16) | (x));
772                 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x020c,
773                          (height << 16) | (width));
774                 break;
775
776         case 2:
777                 MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x019c, (y << 16) | (x));
778                 break;
779         }
780 }
781
782 void mdp_set_blend_attr(MDPIBUF *iBuf,
783                         uint32 *alpha,
784                         uint32 *tpVal,
785                         uint32 perPixelAlpha, uint32 *pppop_reg_ptr)
786 {
787         int bg_alpha;
788
789         *alpha = iBuf->mdpImg.alpha;
790         *tpVal = iBuf->mdpImg.tpVal;
791
792         if (iBuf->mdpImg.mdpOp & MDPOP_FG_PM_ALPHA) {
793                 *pppop_reg_ptr |= PPP_OP_ROT_ON |
794                     PPP_OP_BLEND_ON | PPP_OP_BLEND_CONSTANT_ALPHA;
795
796                 bg_alpha = PPP_BLEND_BG_USE_ALPHA_SEL |
797                                 PPP_BLEND_BG_ALPHA_REVERSE;
798
799                 if (perPixelAlpha)
800                         bg_alpha |= PPP_BLEND_BG_SRCPIXEL_ALPHA;
801                 else
802                         bg_alpha |= PPP_BLEND_BG_CONSTANT_ALPHA;
803
804                 outpdw(MDP_BASE + 0x70010, bg_alpha);
805
806                 if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
807                         *pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
808         } else if (perPixelAlpha) {
809                 *pppop_reg_ptr |= PPP_OP_ROT_ON |
810                     PPP_OP_BLEND_ON | PPP_OP_BLEND_SRCPIXEL_ALPHA;
811         } else {
812                 if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
813                     && (iBuf->mdpImg.alpha == 0xff)) {
814                         iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB);
815                 }
816
817                 if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
818                     || (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
819                         *pppop_reg_ptr |=
820                             PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
821                             PPP_OP_BLEND_CONSTANT_ALPHA |
822                             PPP_OP_BLEND_ALPHA_BLEND_NORMAL;
823                 }
824
825                 if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
826                         *pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
827         }
828 }