Archived
14
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
linux-2.6/drivers/staging/msm/mdp_ppp_v31.c
Stepan Moskovchenko 9d20015391 Staging: add MSM framebuffer driver
Qualcomm development of the MSM SOC framebuffer driver has
diverged significantly from the driver used by Android. This
is a snapshot of our current driver, in all it's agony. We are
putting this in staging to help with the process of converging
the two drivers.

At this point, the driver has been tested only in dumb
framebuffer mode.

Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
Signed-off-by: David Brown <davidb@codeaurora.org>
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
[dwalker@codeaurora.org: added a small compile fix and TODO.]
Signed-off-by: Daniel Walker <dwalker@codeaurora.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2010-06-04 13:38:54 -07:00

829 lines
24 KiB
C

/* Copyright (c) 2008-2010, 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]);
MDP_OUTP(MDP_PPP_SCALE_COEFF_LSBn(index), val);
val =
((MDP_SCALE_COEFF_MASK & c3[i]) << 16) |
(MDP_SCALE_COEFF_MASK & c2[i]);
MDP_OUTP(MDP_PPP_SCALE_COEFF_MSBn(index), val);
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;
}
}