linux/drivers/staging/msm/mdp_ppp_v31.c
<<
>>
Prefs
   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}
 829