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