]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/staging/msm/mdp_ppp_v31.c
Merge branch 'x86-security-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[mirror_ubuntu-artful-kernel.git] / drivers / staging / msm / mdp_ppp_v31.c
CommitLineData
9d200153
SM
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
48static uint32 mdp_scale_0p8_to_8p0_mode;
49static uint32 mdp_scale_0p6_to_0p8_mode;
50static uint32 mdp_scale_0p4_to_0p6_mode;
51static uint32 mdp_scale_0p2_to_0p4_mode;
52
53/* -------- All scaling range, "pixel repeat" -------- */
54static 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
61static 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
68static 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
75static 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
85static 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
92static 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
99static 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
106static 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
115static 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
122static 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
129static 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
136static 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
145static 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
152static 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
159static 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
166static 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
175static 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
182static 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
189static 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
196static 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
203static 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
221void 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
252static 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
263struct phase_val {
264 int phase_init_x;
265 int phase_init_y;
266 int phase_step_x;
267 int phase_step_y;
268};
269
270static 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
456void 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
746void 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
782void 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}