]>
Commit | Line | Data |
---|---|---|
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 | ||
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 | } |