Logo Search packages:      
Sourcecode: linux-qcm-msm version File versions  Download package

mdp_ppp_v31.c

/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/fb.h>
#include "linux/proc_fs.h"

#include <mach/hardware.h>
#include <linux/io.h>

#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <asm/div64.h>

#include "mdp.h"
#include "msm_fb.h"

#define MDP_SCALE_COEFF_NUM      32
#define MDP_SCALE_0P2_TO_0P4_INDEX 0
#define MDP_SCALE_0P4_TO_0P6_INDEX 32
#define MDP_SCALE_0P6_TO_0P8_INDEX 64
#define MDP_SCALE_0P8_TO_8P0_INDEX 96
#define MDP_SCALE_COEFF_MASK 0x3ff

#define MDP_SCALE_PR  0
#define MDP_SCALE_FIR 1

static uint32 mdp_scale_0p8_to_8p0_mode;
static uint32 mdp_scale_0p6_to_0p8_mode;
static uint32 mdp_scale_0p4_to_0p6_mode;
static uint32 mdp_scale_0p2_to_0p4_mode;

/* -------- All scaling range, "pixel repeat" -------- */
static int16 mdp_scale_pixel_repeat_C0[MDP_SCALE_COEFF_NUM] = {
      0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0
};

static int16 mdp_scale_pixel_repeat_C1[MDP_SCALE_COEFF_NUM] = {
      511, 511, 511, 511, 511, 511, 511, 511,
      511, 511, 511, 511, 511, 511, 511, 511,
      511, 511, 511, 511, 511, 511, 511, 511,
      511, 511, 511, 511, 511, 511, 511, 511
};

static int16 mdp_scale_pixel_repeat_C2[MDP_SCALE_COEFF_NUM] = {
      0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0
};

static int16 mdp_scale_pixel_repeat_C3[MDP_SCALE_COEFF_NUM] = {
      0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0
};

/* --------------------------- FIR ------------------------------------- */
/* -------- Downscale, ranging from 0.8x to 8.0x of original size -------- */

static int16 mdp_scale_0p8_to_8p0_C0[MDP_SCALE_COEFF_NUM] = {
      0, -7, -13, -19, -24, -28, -32, -34, -37, -39,
      -40, -41, -41, -41, -40, -40, -38, -37, -35, -33,
      -31, -29, -26, -24, -21, -18, -15, -13, -10, -7,
      -5, -2
};

static int16 mdp_scale_0p8_to_8p0_C1[MDP_SCALE_COEFF_NUM] = {
      511, 507, 501, 494, 485, 475, 463, 450, 436, 422,
      405, 388, 370, 352, 333, 314, 293, 274, 253, 233,
      213, 193, 172, 152, 133, 113, 95, 77, 60, 43,
      28, 13
};

static int16 mdp_scale_0p8_to_8p0_C2[MDP_SCALE_COEFF_NUM] = {
      0, 13, 28, 43, 60, 77, 95, 113, 133, 152,
      172, 193, 213, 233, 253, 274, 294, 314, 333, 352,
      370, 388, 405, 422, 436, 450, 463, 475, 485, 494,
      501, 507,
};

static int16 mdp_scale_0p8_to_8p0_C3[MDP_SCALE_COEFF_NUM] = {
      0, -2, -5, -7, -10, -13, -15, -18, -21, -24,
      -26, -29, -31, -33, -35, -37, -38, -40, -40, -41,
      -41, -41, -40, -39, -37, -34, -32, -28, -24, -19,
      -13, -7
};

/* -------- Downscale, ranging from 0.6x to 0.8x of original size -------- */

static int16 mdp_scale_0p6_to_0p8_C0[MDP_SCALE_COEFF_NUM] = {
      104, 96, 89, 82, 75, 68, 61, 55, 49, 43,
      38, 33, 28, 24, 20, 16, 12, 9, 6, 4,
      2, 0, -2, -4, -5, -6, -7, -7, -8, -8,
      -8, -8
};

static int16 mdp_scale_0p6_to_0p8_C1[MDP_SCALE_COEFF_NUM] = {
      303, 303, 302, 300, 298, 296, 293, 289, 286, 281,
      276, 270, 265, 258, 252, 245, 238, 230, 223, 214,
      206, 197, 189, 180, 172, 163, 154, 145, 137, 128,
      120, 112
};

static int16 mdp_scale_0p6_to_0p8_C2[MDP_SCALE_COEFF_NUM] = {
      112, 120, 128, 137, 145, 154, 163, 172, 180, 189,
      197, 206, 214, 223, 230, 238, 245, 252, 258, 265,
      270, 276, 281, 286, 289, 293, 296, 298, 300, 302,
      303, 303
};

static int16 mdp_scale_0p6_to_0p8_C3[MDP_SCALE_COEFF_NUM] = {
      -8, -8, -8, -8, -7, -7, -6, -5, -4, -2,
      0, 2, 4, 6, 9, 12, 16, 20, 24, 28,
      33, 38, 43, 49, 55, 61, 68, 75, 82, 89,
      96, 104
};

/* -------- Downscale, ranging from 0.4x to 0.6x of original size -------- */

static int16 mdp_scale_0p4_to_0p6_C0[MDP_SCALE_COEFF_NUM] = {
      136, 132, 128, 123, 119, 115, 111, 107, 103, 98,
      95, 91, 87, 84, 80, 76, 73, 69, 66, 62,
      59, 57, 54, 50, 47, 44, 41, 39, 36, 33,
      32, 29
};

static int16 mdp_scale_0p4_to_0p6_C1[MDP_SCALE_COEFF_NUM] = {
      206, 205, 204, 204, 201, 200, 199, 197, 196, 194,
      191, 191, 189, 185, 184, 182, 180, 178, 176, 173,
      170, 168, 165, 162, 160, 157, 155, 152, 148, 146,
      142, 140
};

static int16 mdp_scale_0p4_to_0p6_C2[MDP_SCALE_COEFF_NUM] = {
      140, 142, 146, 148, 152, 155, 157, 160, 162, 165,
      168, 170, 173, 176, 178, 180, 182, 184, 185, 189,
      191, 191, 194, 196, 197, 199, 200, 201, 204, 204,
      205, 206
};

static int16 mdp_scale_0p4_to_0p6_C3[MDP_SCALE_COEFF_NUM] = {
      29, 32, 33, 36, 39, 41, 44, 47, 50, 54,
      57, 59, 62, 66, 69, 73, 76, 80, 84, 87,
      91, 95, 98, 103, 107, 111, 115, 119, 123, 128,
      132, 136
};

/* -------- Downscale, ranging from 0.2x to 0.4x of original size -------- */

static int16 mdp_scale_0p2_to_0p4_C0[MDP_SCALE_COEFF_NUM] = {
      131, 131, 130, 129, 128, 127, 127, 126, 125, 125,
      124, 123, 123, 121, 120, 119, 119, 118, 117, 117,
      116, 115, 115, 114, 113, 112, 111, 110, 109, 109,
      108, 107
};

static int16 mdp_scale_0p2_to_0p4_C1[MDP_SCALE_COEFF_NUM] = {
      141, 140, 140, 140, 140, 139, 138, 138, 138, 137,
      137, 137, 136, 137, 137, 137, 136, 136, 136, 135,
      135, 135, 134, 134, 134, 134, 134, 133, 133, 132,
      132, 132
};

static int16 mdp_scale_0p2_to_0p4_C2[MDP_SCALE_COEFF_NUM] = {
      132, 132, 132, 133, 133, 134, 134, 134, 134, 134,
      135, 135, 135, 136, 136, 136, 137, 137, 137, 136,
      137, 137, 137, 138, 138, 138, 139, 140, 140, 140,
      140, 141
};

static int16 mdp_scale_0p2_to_0p4_C3[MDP_SCALE_COEFF_NUM] = {
      107, 108, 109, 109, 110, 111, 112, 113, 114, 115,
      115, 116, 117, 117, 118, 119, 119, 120, 121, 123,
      123, 124, 125, 125, 126, 127, 127, 128, 129, 130,
      131, 131
};

static void mdp_update_scale_table(int index, int16 *c0, int16 *c1,
                           int16 *c2, int16 *c3)
{
      int i, val;

      for (i = 0; i < MDP_SCALE_COEFF_NUM; i++) {
            val =
                ((MDP_SCALE_COEFF_MASK & c1[i]) << 16) |
                (MDP_SCALE_COEFF_MASK & c0[i]);
            writel(val, MDP_PPP_SCALE_COEFF_LSBn(index));
            val =
                ((MDP_SCALE_COEFF_MASK & c3[i]) << 16) |
                (MDP_SCALE_COEFF_MASK & c2[i]);
            writel(val, MDP_PPP_SCALE_COEFF_MSBn(index));
            index++;
      }
}

void mdp_init_scale_table(void)
{
      mdp_scale_0p2_to_0p4_mode = MDP_SCALE_FIR;
      mdp_update_scale_table(MDP_SCALE_0P2_TO_0P4_INDEX,
                         mdp_scale_0p2_to_0p4_C0,
                         mdp_scale_0p2_to_0p4_C1,
                         mdp_scale_0p2_to_0p4_C2,
                         mdp_scale_0p2_to_0p4_C3);

      mdp_scale_0p4_to_0p6_mode = MDP_SCALE_FIR;
      mdp_update_scale_table(MDP_SCALE_0P4_TO_0P6_INDEX,
                         mdp_scale_0p4_to_0p6_C0,
                         mdp_scale_0p4_to_0p6_C1,
                         mdp_scale_0p4_to_0p6_C2,
                         mdp_scale_0p4_to_0p6_C3);

      mdp_scale_0p6_to_0p8_mode = MDP_SCALE_FIR;
      mdp_update_scale_table(MDP_SCALE_0P6_TO_0P8_INDEX,
                         mdp_scale_0p6_to_0p8_C0,
                         mdp_scale_0p6_to_0p8_C1,
                         mdp_scale_0p6_to_0p8_C2,
                         mdp_scale_0p6_to_0p8_C3);

      mdp_scale_0p8_to_8p0_mode = MDP_SCALE_FIR;
      mdp_update_scale_table(MDP_SCALE_0P8_TO_8P0_INDEX,
                         mdp_scale_0p8_to_8p0_C0,
                         mdp_scale_0p8_to_8p0_C1,
                         mdp_scale_0p8_to_8p0_C2,
                         mdp_scale_0p8_to_8p0_C3);
}

static long long mdp_do_div(long long num, long long den)
{
      do_div(num, den);
      return num;
}

#define SCALER_PHASE_BITS 29
#define HAL_MDP_PHASE_STEP_2P50    0x50000000
#define HAL_MDP_PHASE_STEP_1P66    0x35555555
#define HAL_MDP_PHASE_STEP_1P25    0x28000000

struct phase_val {
      int phase_init_x;
      int phase_init_y;
      int phase_step_x;
      int phase_step_y;
};

static void mdp_calc_scaleInitPhase_3p1(uint32 in_w,
                              uint32 in_h,
                              uint32 out_w,
                              uint32 out_h,
                              boolean is_rotate,
                              boolean is_pp_x,
                              boolean is_pp_y, struct phase_val *pval)
{
      uint64 dst_ROI_width;
      uint64 dst_ROI_height;
      uint64 src_ROI_width;
      uint64 src_ROI_height;

      /*
       * phase_step_x, phase_step_y, phase_init_x and phase_init_y
       * are represented in fixed-point, unsigned 3.29 format
       */
      uint32 phase_step_x = 0;
      uint32 phase_step_y = 0;
      uint32 phase_init_x = 0;
      uint32 phase_init_y = 0;
      uint32 yscale_filter_sel, xscale_filter_sel;
      uint32 scale_unit_sel_x, scale_unit_sel_y;

      uint64 numerator, denominator;
      uint64 temp_dim;

      src_ROI_width = in_w;
      src_ROI_height = in_h;
      dst_ROI_width = out_w;
      dst_ROI_height = out_h;

      /* if there is a 90 degree rotation */
      if (is_rotate) {
            /* decide whether to use FIR or M/N for scaling */

            /* if down-scaling by a factor smaller than 1/4 */
            if (src_ROI_width > (4 * dst_ROI_height))
                  scale_unit_sel_x = 1;   /* use M/N scalar */
            else
                  scale_unit_sel_x = 0;   /* use FIR scalar */

            /* if down-scaling by a factor smaller than 1/4 */
            if (src_ROI_height > (4 * dst_ROI_width))
                  scale_unit_sel_y = 1;   /* use M/N scalar */
            else
                  scale_unit_sel_y = 0;   /* use FIR scalar */
      } else {
            /* decide whether to use FIR or M/N for scaling */

            if (src_ROI_width > (4 * dst_ROI_width))
                  scale_unit_sel_x = 1;   /* use M/N scalar */
            else
                  scale_unit_sel_x = 0;   /* use FIR scalar */

            if (src_ROI_height > (4 * dst_ROI_height))
                  scale_unit_sel_y = 1;   /* use M/N scalar */
            else
                  scale_unit_sel_y = 0;   /* use FIR scalar */

      }

      /* if there is a 90 degree rotation */
      if (is_rotate) {
            /* swap the width and height of dst ROI */
            temp_dim = dst_ROI_width;
            dst_ROI_width = dst_ROI_height;
            dst_ROI_height = temp_dim;
      }

      /* calculate phase step for the x direction */

      /* if destination is only 1 pixel wide, the value of phase_step_x
         is unimportant. Assigning phase_step_x to src ROI width
         as an arbitrary value. */
      if (dst_ROI_width == 1)
            phase_step_x = (uint32) ((src_ROI_width) << SCALER_PHASE_BITS);

      /* if using FIR scalar */
      else if (scale_unit_sel_x == 0) {

            /* Calculate the quotient ( src_ROI_width - 1 ) / ( dst_ROI_width - 1)
               with u3.29 precision. Quotient is rounded up to the larger
               29th decimal point. */
            numerator = (src_ROI_width - 1) << SCALER_PHASE_BITS;
            denominator = (dst_ROI_width - 1);  /* never equals to 0 because of the "( dst_ROI_width == 1 ) case" */
            phase_step_x = (uint32) mdp_do_div((numerator + denominator - 1), denominator);     /* divide and round up to the larger 29th decimal point. */

      }

      /* if M/N scalar */
      else if (scale_unit_sel_x == 1) {
            /* Calculate the quotient ( src_ROI_width ) / ( dst_ROI_width)
               with u3.29 precision. Quotient is rounded down to the
               smaller 29th decimal point. */
            numerator = (src_ROI_width) << SCALER_PHASE_BITS;
            denominator = (dst_ROI_width);
            phase_step_x = (uint32) mdp_do_div(numerator, denominator);
      }
      /* calculate phase step for the y direction */

      /* if destination is only 1 pixel wide, the value of
         phase_step_x is unimportant. Assigning phase_step_x
         to src ROI width as an arbitrary value. */
      if (dst_ROI_height == 1)
            phase_step_y = (uint32) ((src_ROI_height) << SCALER_PHASE_BITS);

      /* if FIR scalar */
      else if (scale_unit_sel_y == 0) {
            /* Calculate the quotient ( src_ROI_height - 1 ) / ( dst_ROI_height - 1)
               with u3.29 precision. Quotient is rounded up to the larger
               29th decimal point. */
            numerator = (src_ROI_height - 1) << SCALER_PHASE_BITS;
            denominator = (dst_ROI_height - 1); /* never equals to 0 because of the "( dst_ROI_height == 1 )" case */
            phase_step_y = (uint32) mdp_do_div((numerator + denominator - 1), denominator);     /* Quotient is rounded up to the larger 29th decimal point. */

      }

      /* if M/N scalar */
      else if (scale_unit_sel_y == 1) {
            /* Calculate the quotient ( src_ROI_height ) / ( dst_ROI_height)
               with u3.29 precision. Quotient is rounded down to the smaller
               29th decimal point. */
            numerator = (src_ROI_height) << SCALER_PHASE_BITS;
            denominator = (dst_ROI_height);
            phase_step_y = (uint32) mdp_do_div(numerator, denominator);
      }

      /* decide which set of FIR coefficients to use */
      if (phase_step_x > HAL_MDP_PHASE_STEP_2P50)
            xscale_filter_sel = 0;
      else if (phase_step_x > HAL_MDP_PHASE_STEP_1P66)
            xscale_filter_sel = 1;
      else if (phase_step_x > HAL_MDP_PHASE_STEP_1P25)
            xscale_filter_sel = 2;
      else
            xscale_filter_sel = 3;

      if (phase_step_y > HAL_MDP_PHASE_STEP_2P50)
            yscale_filter_sel = 0;
      else if (phase_step_y > HAL_MDP_PHASE_STEP_1P66)
            yscale_filter_sel = 1;
      else if (phase_step_y > HAL_MDP_PHASE_STEP_1P25)
            yscale_filter_sel = 2;
      else
            yscale_filter_sel = 3;

      /* calculate phase init for the x direction */

      /* if using FIR scalar */
      if (scale_unit_sel_x == 0) {
            if (dst_ROI_width == 1)
                  phase_init_x =
                      (uint32) ((src_ROI_width - 1) << SCALER_PHASE_BITS);
            else
                  phase_init_x = 0;

      }
      /* M over N scalar  */
      else if (scale_unit_sel_x == 1)
            phase_init_x = 0;

      /* calculate phase init for the y direction
         if using FIR scalar */
      if (scale_unit_sel_y == 0) {
            if (dst_ROI_height == 1)
                  phase_init_y =
                      (uint32) ((src_ROI_height -
                               1) << SCALER_PHASE_BITS);
            else
                  phase_init_y = 0;

      }
      /* M over N scalar   */
      else if (scale_unit_sel_y == 1)
            phase_init_y = 0;

      /* write registers */
      pval->phase_step_x = (uint32) phase_step_x;
      pval->phase_step_y = (uint32) phase_step_y;
      pval->phase_init_x = (uint32) phase_init_x;
      pval->phase_init_y = (uint32) phase_init_y;

      return;
}

void mdp_set_scale(MDPIBUF *iBuf,
               uint32 dst_roi_width,
               uint32 dst_roi_height,
               boolean inputRGB, boolean outputRGB, uint32 *pppop_reg_ptr)
{
      uint32 dst_roi_width_scale;
      uint32 dst_roi_height_scale;
      struct phase_val pval;
      boolean use_pr;
      uint32 ppp_scale_config = 0;

      if (!inputRGB)
            ppp_scale_config |= BIT(6);

      if (iBuf->mdpImg.mdpOp & MDPOP_ASCALE) {
            if (iBuf->mdpImg.mdpOp & MDPOP_ROT90) {
                  dst_roi_width_scale = dst_roi_height;
                  dst_roi_height_scale = dst_roi_width;
            } else {
                  dst_roi_width_scale = dst_roi_width;
                  dst_roi_height_scale = dst_roi_height;
            }

            if ((dst_roi_width_scale != iBuf->roi.width) ||
                (dst_roi_height_scale != iBuf->roi.height) ||
                  (iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
                  *pppop_reg_ptr |=
                      (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);

                  mdp_calc_scaleInitPhase_3p1(iBuf->roi.width,
                                        iBuf->roi.height,
                                        dst_roi_width,
                                        dst_roi_height,
                                        iBuf->mdpImg.
                                        mdpOp & MDPOP_ROT90, 1, 1,
                                        &pval);

                  MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x013c,
                         pval.phase_init_x);
                  MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0140,
                         pval.phase_init_y);
                  MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0144,
                         pval.phase_step_x);
                  MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0148,
                         pval.phase_step_y);

                  use_pr = (inputRGB) && (outputRGB);

                  /* x-direction */
                  if ((dst_roi_width_scale == iBuf->roi.width) &&
                        !(iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
                        *pppop_reg_ptr &= ~PPP_OP_SCALE_X_ON;
                  } else
                      if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
                        8) {
                        if ((use_pr)
                            && (mdp_scale_0p8_to_8p0_mode !=
                              MDP_SCALE_PR)) {
                              mdp_scale_0p8_to_8p0_mode =
                                  MDP_SCALE_PR;
                              mdp_update_scale_table
                                  (MDP_SCALE_0P8_TO_8P0_INDEX,
                                   mdp_scale_pixel_repeat_C0,
                                   mdp_scale_pixel_repeat_C1,
                                   mdp_scale_pixel_repeat_C2,
                                   mdp_scale_pixel_repeat_C3);
                        } else if ((!use_pr)
                                 && (mdp_scale_0p8_to_8p0_mode !=
                                     MDP_SCALE_FIR)) {
                              mdp_scale_0p8_to_8p0_mode =
                                  MDP_SCALE_FIR;
                              mdp_update_scale_table
                                  (MDP_SCALE_0P8_TO_8P0_INDEX,
                                   mdp_scale_0p8_to_8p0_C0,
                                   mdp_scale_0p8_to_8p0_C1,
                                   mdp_scale_0p8_to_8p0_C2,
                                   mdp_scale_0p8_to_8p0_C3);
                        }
                        ppp_scale_config |= (SCALE_U1_SET << 2);
                  } else
                      if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
                        6) {
                        if ((use_pr)
                            && (mdp_scale_0p6_to_0p8_mode !=
                              MDP_SCALE_PR)) {
                              mdp_scale_0p6_to_0p8_mode =
                                  MDP_SCALE_PR;
                              mdp_update_scale_table
                                  (MDP_SCALE_0P6_TO_0P8_INDEX,
                                   mdp_scale_pixel_repeat_C0,
                                   mdp_scale_pixel_repeat_C1,
                                   mdp_scale_pixel_repeat_C2,
                                   mdp_scale_pixel_repeat_C3);
                        } else if ((!use_pr)
                                 && (mdp_scale_0p6_to_0p8_mode !=
                                     MDP_SCALE_FIR)) {
                              mdp_scale_0p6_to_0p8_mode =
                                  MDP_SCALE_FIR;
                              mdp_update_scale_table
                                  (MDP_SCALE_0P6_TO_0P8_INDEX,
                                   mdp_scale_0p6_to_0p8_C0,
                                   mdp_scale_0p6_to_0p8_C1,
                                   mdp_scale_0p6_to_0p8_C2,
                                   mdp_scale_0p6_to_0p8_C3);
                        }
                        ppp_scale_config |= (SCALE_D2_SET << 2);
                  } else
                      if (((dst_roi_width_scale * 10) / iBuf->roi.width) >
                        4) {
                        if ((use_pr)
                            && (mdp_scale_0p4_to_0p6_mode !=
                              MDP_SCALE_PR)) {
                              mdp_scale_0p4_to_0p6_mode =
                                  MDP_SCALE_PR;
                              mdp_update_scale_table
                                  (MDP_SCALE_0P4_TO_0P6_INDEX,
                                   mdp_scale_pixel_repeat_C0,
                                   mdp_scale_pixel_repeat_C1,
                                   mdp_scale_pixel_repeat_C2,
                                   mdp_scale_pixel_repeat_C3);
                        } else if ((!use_pr)
                                 && (mdp_scale_0p4_to_0p6_mode !=
                                     MDP_SCALE_FIR)) {
                              mdp_scale_0p4_to_0p6_mode =
                                  MDP_SCALE_FIR;
                              mdp_update_scale_table
                                  (MDP_SCALE_0P4_TO_0P6_INDEX,
                                   mdp_scale_0p4_to_0p6_C0,
                                   mdp_scale_0p4_to_0p6_C1,
                                   mdp_scale_0p4_to_0p6_C2,
                                   mdp_scale_0p4_to_0p6_C3);
                        }
                        ppp_scale_config |= (SCALE_D1_SET << 2);
                  } else
                      if (((dst_roi_width_scale * 4) / iBuf->roi.width) >=
                        1) {
                        if ((use_pr)
                            && (mdp_scale_0p2_to_0p4_mode !=
                              MDP_SCALE_PR)) {
                              mdp_scale_0p2_to_0p4_mode =
                                  MDP_SCALE_PR;
                              mdp_update_scale_table
                                  (MDP_SCALE_0P2_TO_0P4_INDEX,
                                   mdp_scale_pixel_repeat_C0,
                                   mdp_scale_pixel_repeat_C1,
                                   mdp_scale_pixel_repeat_C2,
                                   mdp_scale_pixel_repeat_C3);
                        } else if ((!use_pr)
                                 && (mdp_scale_0p2_to_0p4_mode !=
                                     MDP_SCALE_FIR)) {
                              mdp_scale_0p2_to_0p4_mode =
                                  MDP_SCALE_FIR;
                              mdp_update_scale_table
                                  (MDP_SCALE_0P2_TO_0P4_INDEX,
                                   mdp_scale_0p2_to_0p4_C0,
                                   mdp_scale_0p2_to_0p4_C1,
                                   mdp_scale_0p2_to_0p4_C2,
                                   mdp_scale_0p2_to_0p4_C3);
                        }
                        ppp_scale_config |= (SCALE_D0_SET << 2);
                  } else
                        ppp_scale_config |= BIT(0);

                  /* y-direction */
                  if ((dst_roi_height_scale == iBuf->roi.height) &&
                        !(iBuf->mdpImg.mdpOp & MDPOP_SHARPENING)) {
                        *pppop_reg_ptr &= ~PPP_OP_SCALE_Y_ON;
                  } else if (((dst_roi_height_scale * 10) /
                              iBuf->roi.height) > 8) {
                        if ((use_pr)
                            && (mdp_scale_0p8_to_8p0_mode !=
                              MDP_SCALE_PR)) {
                              mdp_scale_0p8_to_8p0_mode =
                                  MDP_SCALE_PR;
                              mdp_update_scale_table
                                  (MDP_SCALE_0P8_TO_8P0_INDEX,
                                   mdp_scale_pixel_repeat_C0,
                                   mdp_scale_pixel_repeat_C1,
                                   mdp_scale_pixel_repeat_C2,
                                   mdp_scale_pixel_repeat_C3);
                        } else if ((!use_pr)
                                 && (mdp_scale_0p8_to_8p0_mode !=
                                     MDP_SCALE_FIR)) {
                              mdp_scale_0p8_to_8p0_mode =
                                  MDP_SCALE_FIR;
                              mdp_update_scale_table
                                  (MDP_SCALE_0P8_TO_8P0_INDEX,
                                   mdp_scale_0p8_to_8p0_C0,
                                   mdp_scale_0p8_to_8p0_C1,
                                   mdp_scale_0p8_to_8p0_C2,
                                   mdp_scale_0p8_to_8p0_C3);
                        }
                        ppp_scale_config |= (SCALE_U1_SET << 4);
                  } else
                      if (((dst_roi_height_scale * 10) /
                         iBuf->roi.height) > 6) {
                        if ((use_pr)
                            && (mdp_scale_0p6_to_0p8_mode !=
                              MDP_SCALE_PR)) {
                              mdp_scale_0p6_to_0p8_mode =
                                  MDP_SCALE_PR;
                              mdp_update_scale_table
                                  (MDP_SCALE_0P6_TO_0P8_INDEX,
                                   mdp_scale_pixel_repeat_C0,
                                   mdp_scale_pixel_repeat_C1,
                                   mdp_scale_pixel_repeat_C2,
                                   mdp_scale_pixel_repeat_C3);
                        } else if ((!use_pr)
                                 && (mdp_scale_0p6_to_0p8_mode !=
                                     MDP_SCALE_FIR)) {
                              mdp_scale_0p6_to_0p8_mode =
                                  MDP_SCALE_FIR;
                              mdp_update_scale_table
                                  (MDP_SCALE_0P6_TO_0P8_INDEX,
                                   mdp_scale_0p6_to_0p8_C0,
                                   mdp_scale_0p6_to_0p8_C1,
                                   mdp_scale_0p6_to_0p8_C2,
                                   mdp_scale_0p6_to_0p8_C3);
                        }
                        ppp_scale_config |= (SCALE_D2_SET << 4);
                  } else
                      if (((dst_roi_height_scale * 10) /
                         iBuf->roi.height) > 4) {
                        if ((use_pr)
                            && (mdp_scale_0p4_to_0p6_mode !=
                              MDP_SCALE_PR)) {
                              mdp_scale_0p4_to_0p6_mode =
                                  MDP_SCALE_PR;
                              mdp_update_scale_table
                                  (MDP_SCALE_0P4_TO_0P6_INDEX,
                                   mdp_scale_pixel_repeat_C0,
                                   mdp_scale_pixel_repeat_C1,
                                   mdp_scale_pixel_repeat_C2,
                                   mdp_scale_pixel_repeat_C3);
                        } else if ((!use_pr)
                                 && (mdp_scale_0p4_to_0p6_mode !=
                                     MDP_SCALE_FIR)) {
                              mdp_scale_0p4_to_0p6_mode =
                                  MDP_SCALE_FIR;
                              mdp_update_scale_table
                                  (MDP_SCALE_0P4_TO_0P6_INDEX,
                                   mdp_scale_0p4_to_0p6_C0,
                                   mdp_scale_0p4_to_0p6_C1,
                                   mdp_scale_0p4_to_0p6_C2,
                                   mdp_scale_0p4_to_0p6_C3);
                        }
                        ppp_scale_config |= (SCALE_D1_SET << 4);
                  } else
                      if (((dst_roi_height_scale * 4) /
                         iBuf->roi.height) >= 1) {
                        if ((use_pr)
                            && (mdp_scale_0p2_to_0p4_mode !=
                              MDP_SCALE_PR)) {
                              mdp_scale_0p2_to_0p4_mode =
                                  MDP_SCALE_PR;
                              mdp_update_scale_table
                                  (MDP_SCALE_0P2_TO_0P4_INDEX,
                                   mdp_scale_pixel_repeat_C0,
                                   mdp_scale_pixel_repeat_C1,
                                   mdp_scale_pixel_repeat_C2,
                                   mdp_scale_pixel_repeat_C3);
                        } else if ((!use_pr)
                                 && (mdp_scale_0p2_to_0p4_mode !=
                                     MDP_SCALE_FIR)) {
                              mdp_scale_0p2_to_0p4_mode =
                                  MDP_SCALE_FIR;
                              mdp_update_scale_table
                                  (MDP_SCALE_0P2_TO_0P4_INDEX,
                                   mdp_scale_0p2_to_0p4_C0,
                                   mdp_scale_0p2_to_0p4_C1,
                                   mdp_scale_0p2_to_0p4_C2,
                                   mdp_scale_0p2_to_0p4_C3);
                        }
                        ppp_scale_config |= (SCALE_D0_SET << 4);
                  } else
                        ppp_scale_config |= BIT(1);

                  if (iBuf->mdpImg.mdpOp & MDPOP_SHARPENING) {
                        ppp_scale_config |= BIT(7);
                        MDP_OUTP(MDP_BASE + 0x50020,
                                    iBuf->mdpImg.sp_value);
                  }

                  MDP_OUTP(MDP_BASE + 0x10230, ppp_scale_config);
            } else {
                  iBuf->mdpImg.mdpOp &= ~(MDPOP_ASCALE);
            }
      }
}

void mdp_adjust_start_addr(uint8 **src0,
                     uint8 **src1,
                     int v_slice,
                     int h_slice,
                     int x,
                     int y,
                     uint32 width,
                     uint32 height, int bpp, MDPIBUF *iBuf, int layer)
{
      switch (layer) {
      case 0:
            MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0200, (y << 16) | (x));
            MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0208,
                   (height << 16) | (width));
            break;

      case 1:
            /* MDP 3.1 HW bug workaround */
            if (iBuf->ibuf_type == MDP_YCRYCB_H2V1) {
                  *src0 += (x + y * width) * bpp;
                  x = y = 0;
                  width = iBuf->roi.dst_width;
                  height = iBuf->roi.dst_height;
            }

            MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x0204, (y << 16) | (x));
            MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x020c,
                   (height << 16) | (width));
            break;

      case 2:
            MDP_OUTP(MDP_CMD_DEBUG_ACCESS_BASE + 0x019c, (y << 16) | (x));
            break;
      }
}

void mdp_set_blend_attr(MDPIBUF *iBuf,
                  uint32 *alpha,
                  uint32 *tpVal,
                  uint32 perPixelAlpha, uint32 *pppop_reg_ptr)
{
      int bg_alpha;

      *alpha = iBuf->mdpImg.alpha;
      *tpVal = iBuf->mdpImg.tpVal;

      if (iBuf->mdpImg.mdpOp & MDPOP_FG_PM_ALPHA) {
            *pppop_reg_ptr |= PPP_OP_ROT_ON |
                PPP_OP_BLEND_ON | PPP_OP_BLEND_CONSTANT_ALPHA;

            bg_alpha = PPP_BLEND_BG_USE_ALPHA_SEL |
                        PPP_BLEND_BG_ALPHA_REVERSE;

            if (perPixelAlpha)
                  bg_alpha |= PPP_BLEND_BG_SRCPIXEL_ALPHA;
            else
                  bg_alpha |= PPP_BLEND_BG_CONSTANT_ALPHA;

            outpdw(MDP_BASE + 0x70010, bg_alpha);

            if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
                  *pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
      } else if (perPixelAlpha) {
            *pppop_reg_ptr |= PPP_OP_ROT_ON |
                PPP_OP_BLEND_ON | PPP_OP_BLEND_SRCPIXEL_ALPHA;
      } else {
            if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
                && (iBuf->mdpImg.alpha == 0xff)) {
                  iBuf->mdpImg.mdpOp &= ~(MDPOP_ALPHAB);
            }

            if ((iBuf->mdpImg.mdpOp & MDPOP_ALPHAB)
                || (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)) {
                  *pppop_reg_ptr |=
                      PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
                      PPP_OP_BLEND_CONSTANT_ALPHA |
                      PPP_OP_BLEND_ALPHA_BLEND_NORMAL;
            }

            if (iBuf->mdpImg.mdpOp & MDPOP_TRANSP)
                  *pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
      }
}

Generated by  Doxygen 1.6.0   Back to index