• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/staging/msm/
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		if (iBuf->ibuf_type == MDP_YCRYCB_H2V1) {
764			*src0 += (x + y * width) * bpp;
765			x = y = 0;
766			width = iBuf->roi.dst_width;
767			height = iBuf->roi.dst_height;
768		}
769
770		MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0204, (y << 16) | (x));
771		MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x020c,
772			 (height << 16) | (width));
773		break;
774
775	case 2:
776		MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x019c, (y << 16) | (x));
777		break;
778	}
779}
780
781void mdp_set_blend_attr(MDPIBUF *iBuf,
782			uint32 *alpha,
783			uint32 *tpVal,
784			uint32 perPixelAlpha, uint32 *pppop_reg_ptr)
785{
786	int bg_alpha;
787
788	*alpha = iBuf->mdpImg.alpha;
789	*tpVal = iBuf->mdpImg.tpVal;
790
791	if (iBuf->mdpImg.mdpOp & MDPOP_FG_PM_ALPHA) {
792		*pppop_reg_ptr |= PPP_OP_ROT_ON |
793		    PPP_OP_BLEND_ON | PPP_OP_BLEND_CONSTANT_ALPHA;
794
795		bg_alpha = PPP_BLEND_BG_USE_ALPHA_SEL |
796				PPP_BLEND_BG_ALPHA_REVERSE;
797
798		if (perPixelAlpha)
799			bg_alpha |= PPP_BLEND_BG_SRCPIXEL_ALPHA;
800		else
801			bg_alpha |= PPP_BLEND_BG_CONSTANT_ALPHA;
802
803		outpdw(MDP_BASE + 0x70010, bg_alpha);
804
805		if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
806			*pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
807	} else if (perPixelAlpha) {
808		*pppop_reg_ptr |= PPP_OP_ROT_ON |
809		    PPP_OP_BLEND_ON | PPP_OP_BLEND_SRCPIXEL_ALPHA;
810	} else {
811		if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
812		    && (iBuf->mdpImg.alpha == 0xff)) {
813			iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB);
814		}
815
816		if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
817		    || (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
818			*pppop_reg_ptr |=
819			    PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
820			    PPP_OP_BLEND_CONSTANT_ALPHA |
821			    PPP_OP_BLEND_ALPHA_BLEND_NORMAL;
822		}
823
824		if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
825			*pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
826	}
827}
828