12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223 |
- /* Copyright (c) 2007, 2012-2013 The Linux Foundation. All rights reserved.
- * Copyright (C) 2007 Google Incorporated
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- */
- #include <linux/file.h>
- #include <linux/io.h>
- #include <linux/kernel.h>
- #include <linux/major.h>
- #include <linux/slab.h>
- #include <linux/types.h>
- #include <linux/uaccess.h>
- #include "linux/proc_fs.h"
- #include "mdss_fb.h"
- #include "mdp3_ppp.h"
- #include "mdp3_hwio.h"
- /* SHIM Q Factor */
- #define PHI_Q_FACTOR 29
- #define PQF_PLUS_5 (PHI_Q_FACTOR + 5) /* due to 32 phases */
- #define PQF_PLUS_4 (PHI_Q_FACTOR + 4)
- #define PQF_PLUS_2 (PHI_Q_FACTOR + 2) /* to get 4.0 */
- #define PQF_MINUS_2 (PHI_Q_FACTOR - 2) /* to get 0.25 */
- #define PQF_PLUS_5_PLUS_2 (PQF_PLUS_5 + 2)
- #define PQF_PLUS_5_MINUS_2 (PQF_PLUS_5 - 2)
- static long long mdp_do_div(long long num, long long den)
- {
- do_div(num, den);
- return num;
- }
- static int mdp_calc_scale_params(uint32_t org, uint32_t dim_in,
- uint32_t dim_out, bool is_W, int32_t *phase_init_ptr,
- uint32_t *phase_step_ptr)
- {
- bool rpa_on = false;
- int init_phase = 0;
- uint64_t numer = 0;
- uint64_t denom = 0;
- int64_t point5 = 1;
- int64_t one = 1;
- int64_t k1, k2, k3, k4; /* linear equation coefficients */
- uint64_t int_mask;
- uint64_t fract_mask;
- uint64_t Os;
- int64_t Osprime;
- int64_t Od;
- int64_t Odprime;
- int64_t Oreq;
- int64_t init_phase_temp;
- int64_t delta;
- uint32_t mult;
- /*
- * The phase accumulator should really be rational for all cases in a
- * general purpose polyphase scaler for a tiled architecture with
- * non-zero * origin capability because there is no way to represent
- * certain scale factors in fixed point regardless of precision.
- * The error incurred in attempting to use fixed point is most
- * eggregious for SF where 1/SF is an integral multiple of 1/3.
- *
- * Set the RPA flag for this dimension.
- *
- * In order for 1/SF (dim_in/dim_out) to be an integral multiple of
- * 1/3, dim_out must be an integral multiple of 3.
- */
- if (!(dim_out % 3)) {
- mult = dim_out / 3;
- rpa_on = (!(dim_in % mult));
- }
- numer = dim_out;
- denom = dim_in;
- /*
- * convert to U30.34 before division
- *
- * The K vectors carry 4 extra bits of precision
- * and are rounded.
- *
- * We initially go 5 bits over then round by adding
- * 1 and right shifting by 1
- * so final result is U31.33
- */
- numer <<= PQF_PLUS_5;
- /* now calculate the scale factor (aka k3) */
- k3 = ((mdp_do_div(numer, denom) + 1) >> 1);
- /* check scale factor for legal range [0.25 - 4.0] */
- if (((k3 >> 4) < (1LL << PQF_MINUS_2)) ||
- ((k3 >> 4) > (1LL << PQF_PLUS_2))) {
- return -EINVAL;
- }
- /* calculate inverse scale factor (aka k1) for phase init */
- numer = dim_in;
- denom = dim_out;
- numer <<= PQF_PLUS_5;
- k1 = ((mdp_do_div(numer, denom) + 1) >> 1);
- /*
- * calculate initial phase and ROI overfetch
- */
- /* convert point5 & one to S39.24 (will always be positive) */
- point5 <<= (PQF_PLUS_4 - 1);
- one <<= PQF_PLUS_4;
- k2 = ((k1 - one) >> 1);
- init_phase = (int)(k2 >> 4);
- k4 = ((k3 - one) >> 1);
- if (k3 != one) {
- /* calculate the masks */
- fract_mask = one - 1;
- int_mask = ~fract_mask;
- if (!rpa_on) {
- /*
- * FIXED POINT IMPLEMENTATION
- */
- if (org) {
- /*
- * The complicated case; ROI origin != 0
- * init_phase needs to be adjusted
- * OF is also position dependent
- */
- /* map (org - .5) into destination space */
- Os = ((uint64_t) org << 1) - 1;
- Od = ((k3 * Os) >> 1) + k4;
- /* take the ceiling */
- Odprime = (Od & int_mask);
- if (Odprime != Od)
- Odprime += one;
- /* now map that back to source space */
- Osprime = (k1 * (Odprime >> PQF_PLUS_4)) + k2;
- /* then floor & decrement to calc the required
- starting coordinate */
- Oreq = (Osprime & int_mask) - one;
- /* calculate initial phase */
- init_phase_temp = Osprime - Oreq;
- delta = ((int64_t) (org) << PQF_PLUS_4) - Oreq;
- init_phase_temp -= delta;
- /* limit to valid range before the left shift */
- delta = (init_phase_temp & (1LL << 63)) ?
- 4 : -4;
- delta <<= PQF_PLUS_4;
- while (abs((int)(init_phase_temp >>
- PQF_PLUS_4)) > 4)
- init_phase_temp += delta;
- /*
- * right shift to account for extra bits of
- * precision
- */
- init_phase = (int)(init_phase_temp >> 4);
- }
- } else {
- /*
- * RPA IMPLEMENTATION
- *
- * init_phase needs to be calculated in all RPA_on cases
- * because it's a numerator, not a fixed point value.
- */
- /* map (org - .5) into destination space */
- Os = ((uint64_t) org << PQF_PLUS_4) - point5;
- Od = mdp_do_div((dim_out * (Os + point5)),
- dim_in);
- Od -= point5;
- /* take the ceiling */
- Odprime = (Od & int_mask);
- if (Odprime != Od)
- Odprime += one;
- /* now map that back to source space */
- Osprime =
- mdp_do_div((dim_in * (Odprime + point5)),
- dim_out);
- Osprime -= point5;
- /* then floor & decrement to calculate the required
- starting coordinate */
- Oreq = (Osprime & int_mask) - one;
- /* calculate initial phase */
- init_phase_temp = Osprime - Oreq;
- delta = ((int64_t) (org) << PQF_PLUS_4) - Oreq;
- init_phase_temp -= delta;
- /* limit to valid range before the left shift */
- delta = (init_phase_temp & (1LL << 63)) ? 4 : -4;
- delta <<= PQF_PLUS_4;
- while (abs((int)(init_phase_temp >> PQF_PLUS_4)) > 4)
- init_phase_temp += delta;
- /* right shift to account for extra bits of precision */
- init_phase = (int)(init_phase_temp >> 4);
- }
- }
- /* return the scale parameters */
- *phase_init_ptr = init_phase;
- *phase_step_ptr = (uint32_t) (k1 >> 4);
- return 0;
- }
- static int scale_idx(int factor)
- {
- int idx;
- if (factor > 80)
- idx = PPP_DOWNSCALE_PT8TOPT1;
- else if (factor > 60)
- idx = PPP_DOWNSCALE_PT6TOPT8;
- else if (factor > 40)
- idx = PPP_DOWNSCALE_PT4TOPT6;
- else
- idx = PPP_DOWNSCALE_PT2TOPT4;
- return idx;
- }
- inline int32_t comp_conv_rgb2yuv(int32_t comp, int32_t y_high,
- int32_t y_low, int32_t c_high, int32_t c_low)
- {
- if (comp < 0)
- comp = 0;
- if (comp > 255)
- comp = 255;
- /* clamp */
- if (comp < y_low)
- comp = y_low;
- if (comp > y_high)
- comp = y_high;
- return comp;
- }
- static uint32_t conv_rgb2yuv(uint32_t input_pixel,
- uint16_t *matrix_vector,
- uint16_t *bv,
- uint16_t *clamp_vector)
- {
- uint8_t input_C2, input_C0, input_C1;
- uint32_t output;
- int32_t comp_C2, comp_C1, comp_C0, temp;
- int32_t temp1, temp2, temp3;
- int32_t matrix[9];
- int32_t bias_vector[3];
- int32_t Y_low_limit, Y_high_limit, C_low_limit, C_high_limit;
- int32_t i;
- input_C2 = (input_pixel >> 16) & 0xFF;
- input_C1 = (input_pixel >> 8) & 0xFF;
- input_C0 = (input_pixel >> 0) & 0xFF;
- comp_C0 = input_C0;
- comp_C1 = input_C1;
- comp_C2 = input_C2;
- for (i = 0; i < MDP_CSC_SIZE; i++)
- matrix[i] =
- ((int32_t) (((int32_t) matrix_vector[i]) << 20)) >> 20;
- bias_vector[0] = (int32_t) (bv[0] & 0xFF);
- bias_vector[1] = (int32_t) (bv[1] & 0xFF);
- bias_vector[2] = (int32_t) (bv[2] & 0xFF);
- Y_low_limit = (int32_t) clamp_vector[0];
- Y_high_limit = (int32_t) clamp_vector[1];
- C_low_limit = (int32_t) clamp_vector[2];
- C_high_limit = (int32_t) clamp_vector[3];
- /*
- * Color Conversion
- * reorder input colors
- */
- temp = comp_C2;
- comp_C2 = comp_C1;
- comp_C1 = comp_C0;
- comp_C0 = temp;
- /* matrix multiplication */
- temp1 = comp_C0 * matrix[0] + comp_C1 * matrix[1] + comp_C2 * matrix[2];
- temp2 = comp_C0 * matrix[3] + comp_C1 * matrix[4] + comp_C2 * matrix[5];
- temp3 = comp_C0 * matrix[6] + comp_C1 * matrix[7] + comp_C2 * matrix[8];
- comp_C0 = temp1 + 0x100;
- comp_C1 = temp2 + 0x100;
- comp_C2 = temp3 + 0x100;
- /* take interger part */
- comp_C0 >>= 9;
- comp_C1 >>= 9;
- comp_C2 >>= 9;
- /* post bias (+) */
- comp_C0 += bias_vector[0];
- comp_C1 += bias_vector[1];
- comp_C2 += bias_vector[2];
- /* limit pixel to 8-bit */
- comp_C0 = comp_conv_rgb2yuv(comp_C0, Y_high_limit,
- Y_low_limit, C_high_limit, C_low_limit);
- comp_C1 = comp_conv_rgb2yuv(comp_C1, Y_high_limit,
- Y_low_limit, C_high_limit, C_low_limit);
- comp_C2 = comp_conv_rgb2yuv(comp_C2, Y_high_limit,
- Y_low_limit, C_high_limit, C_low_limit);
- output = (comp_C2 << 16) | (comp_C1 << 8) | comp_C0;
- return output;
- }
- inline void y_h_even_num(struct ppp_img_desc *img)
- {
- img->roi.y = (img->roi.y / 2) * 2;
- img->roi.height = (img->roi.height / 2) * 2;
- }
- inline void x_w_even_num(struct ppp_img_desc *img)
- {
- img->roi.x = (img->roi.x / 2) * 2;
- img->roi.width = (img->roi.width / 2) * 2;
- }
- bool check_if_rgb(int color)
- {
- bool rgb = false;
- switch (color) {
- case MDP_RGB_565:
- case MDP_BGR_565:
- case MDP_RGB_888:
- case MDP_BGR_888:
- case MDP_BGRA_8888:
- case MDP_RGBA_8888:
- case MDP_ARGB_8888:
- case MDP_XRGB_8888:
- case MDP_RGBX_8888:
- case MDP_BGRX_8888:
- rgb = true;
- default:
- break;
- }
- return rgb;
- }
- uint8_t *mdp_dst_adjust_rot_addr(struct ppp_blit_op *iBuf,
- uint8_t *addr, uint32_t bpp, uint32_t uv)
- {
- uint32_t dest_ystride = iBuf->dst.prop.width * bpp;
- uint32_t h_slice = 1;
- if (uv && ((iBuf->dst.color_fmt == MDP_Y_CBCR_H2V2) ||
- (iBuf->dst.color_fmt == MDP_Y_CRCB_H2V2)))
- h_slice = 2;
- if (((iBuf->mdp_op & MDPOP_ROT90) == MDPOP_ROT90) ^
- ((iBuf->mdp_op & MDPOP_LR) == MDPOP_LR)) {
- addr +=
- (iBuf->dst.roi.width -
- MIN(16, iBuf->dst.roi.width)) * bpp;
- }
- if ((iBuf->mdp_op & MDPOP_UD) == MDPOP_UD) {
- addr +=
- ((iBuf->dst.roi.height -
- MIN(16, iBuf->dst.roi.height))/h_slice) *
- dest_ystride;
- }
- return addr;
- }
- void mdp_adjust_start_addr(struct ppp_blit_op *blit_op,
- struct ppp_img_desc *img, int v_slice,
- int h_slice, int layer)
- {
- uint32_t bpp = ppp_bpp(img->color_fmt);
- int x = img->roi.x;
- int y = img->roi.y;
- uint32_t width = img->prop.width;
- if (img->color_fmt == MDP_Y_CBCR_H2V2_ADRENO && layer == 0)
- img->p0 += (x + y * ALIGN(width, 32)) * bpp;
- else if (img->color_fmt == MDP_Y_CBCR_H2V2_VENUS && layer == 0)
- img->p0 += (x + y * ALIGN(width, 128)) * bpp;
- else
- img->p0 += (x + y * width) * bpp;
- if (layer != 0)
- img->p0 = mdp_dst_adjust_rot_addr(blit_op, img->p0, bpp, 0);
- if (img->p1) {
- /*
- * MDP_Y_CBCR_H2V2/MDP_Y_CRCB_H2V2 cosite for now
- * we need to shift x direction same as y dir for offsite
- */
- if ((img->color_fmt == MDP_Y_CBCR_H2V2_ADRENO ||
- img->color_fmt == MDP_Y_CBCR_H2V2_VENUS)
- && layer == 0)
- img->p1 += ((x / h_slice) * h_slice + ((y == 0) ? 0 :
- (((y + 1) / v_slice - 1) * (ALIGN(width/2, 32) * 2))))
- * bpp;
- else
- img->p1 += ((x / h_slice) * h_slice +
- ((y == 0) ? 0 : ((y + 1) / v_slice - 1) * width)) * bpp;
- if (layer != 0)
- img->p0 = mdp_dst_adjust_rot_addr(blit_op,
- img->p0, bpp, 0);
- }
- }
- int load_ppp_lut(int tableType, uint32_t *lut)
- {
- int i;
- uint32_t base_addr;
- base_addr = tableType ? MDP3_PPP_POST_LUT : MDP3_PPP_PRE_LUT;
- for (i = 0; i < PPP_LUT_MAX; i++)
- PPP_WRITEL(lut[i], base_addr + MDP3_PPP_LUTn(i));
- return 0;
- }
- /* Configure Primary CSC Matrix */
- int load_primary_matrix(struct ppp_csc_table *csc)
- {
- int i;
- for (i = 0; i < MDP_CSC_SIZE; i++)
- PPP_WRITEL(csc->fwd_matrix[i], MDP3_PPP_CSC_PFMVn(i));
- for (i = 0; i < MDP_CSC_SIZE; i++)
- PPP_WRITEL(csc->rev_matrix[i], MDP3_PPP_CSC_PRMVn(i));
- for (i = 0; i < MDP_BV_SIZE; i++)
- PPP_WRITEL(csc->bv[i], MDP3_PPP_CSC_PBVn(i));
- for (i = 0; i < MDP_LV_SIZE; i++)
- PPP_WRITEL(csc->lv[i], MDP3_PPP_CSC_PLVn(i));
- return 0;
- }
- /* Load Secondary CSC Matrix */
- int load_secondary_matrix(struct ppp_csc_table *csc)
- {
- int i;
- for (i = 0; i < MDP_CSC_SIZE; i++)
- PPP_WRITEL(csc->fwd_matrix[i], MDP3_PPP_CSC_SFMVn(i));
- for (i = 0; i < MDP_CSC_SIZE; i++)
- PPP_WRITEL(csc->rev_matrix[i], MDP3_PPP_CSC_SRMVn(i));
- for (i = 0; i < MDP_BV_SIZE; i++)
- PPP_WRITEL(csc->bv[i], MDP3_PPP_CSC_SBVn(i));
- for (i = 0; i < MDP_LV_SIZE; i++)
- PPP_WRITEL(csc->lv[i], MDP3_PPP_CSC_SLVn(i));
- return 0;
- }
- int load_csc_matrix(int matrix_type, struct ppp_csc_table *csc)
- {
- if (matrix_type == CSC_PRIMARY_MATRIX)
- return load_primary_matrix(csc);
- return load_secondary_matrix(csc);
- }
- int config_ppp_src(struct ppp_img_desc *src, uint32_t yuv2rgb)
- {
- uint32_t val;
- val = ((src->roi.height & MDP3_PPP_XY_MASK) << MDP3_PPP_XY_OFFSET) |
- (src->roi.width & MDP3_PPP_XY_MASK);
- PPP_WRITEL(val, MDP3_PPP_SRC_SIZE);
- PPP_WRITEL(src->p0, MDP3_PPP_SRCP0_ADDR);
- PPP_WRITEL(src->p1, MDP3_PPP_SRCP1_ADDR);
- PPP_WRITEL(src->p3, MDP3_PPP_SRCP3_ADDR);
- val = (src->stride0 & MDP3_PPP_STRIDE_MASK) |
- ((src->stride1 & MDP3_PPP_STRIDE_MASK) <<
- MDP3_PPP_STRIDE1_OFFSET);
- PPP_WRITEL(val, MDP3_PPP_SRC_YSTRIDE1_ADDR);
- val = ((src->stride2 & MDP3_PPP_STRIDE_MASK) <<
- MDP3_PPP_STRIDE1_OFFSET);
- PPP_WRITEL(val, MDP3_PPP_SRC_YSTRIDE2_ADDR);
- val = ppp_src_config(src->color_fmt);
- val |= (src->roi.x % 2) ? PPP_SRC_BPP_ROI_ODD_X : 0;
- val |= (src->roi.y % 2) ? PPP_SRC_BPP_ROI_ODD_Y : 0;
- PPP_WRITEL(val, MDP3_PPP_SRC_FORMAT);
- PPP_WRITEL(ppp_pack_pattern(src->color_fmt, yuv2rgb),
- MDP3_PPP_SRC_UNPACK_PATTERN1);
- return 0;
- }
- int config_ppp_out(struct ppp_img_desc *dst, uint32_t yuv2rgb)
- {
- uint32_t val;
- bool pseudoplanr_output = false;
- switch (dst->color_fmt) {
- case MDP_Y_CBCR_H2V2:
- case MDP_Y_CRCB_H2V2:
- case MDP_Y_CBCR_H2V1:
- case MDP_Y_CRCB_H2V1:
- pseudoplanr_output = true;
- break;
- default:
- break;
- }
- val = ppp_out_config(dst->color_fmt);
- if (pseudoplanr_output)
- val |= PPP_DST_PLANE_PSEUDOPLN;
- PPP_WRITEL(val, MDP3_PPP_OUT_FORMAT);
- PPP_WRITEL(ppp_pack_pattern(dst->color_fmt, yuv2rgb),
- MDP3_PPP_OUT_PACK_PATTERN1);
- val = ((dst->roi.height & MDP3_PPP_XY_MASK) << MDP3_PPP_XY_OFFSET) |
- (dst->roi.width & MDP3_PPP_XY_MASK);
- PPP_WRITEL(val, MDP3_PPP_OUT_SIZE);
- PPP_WRITEL(dst->p0, MDP3_PPP_OUTP0_ADDR);
- PPP_WRITEL(dst->p1, MDP3_PPP_OUTP1_ADDR);
- PPP_WRITEL(dst->p3, MDP3_PPP_OUTP3_ADDR);
- val = (dst->stride0 & MDP3_PPP_STRIDE_MASK) |
- ((dst->stride1 & MDP3_PPP_STRIDE_MASK) <<
- MDP3_PPP_STRIDE1_OFFSET);
- PPP_WRITEL(val, MDP3_PPP_OUT_YSTRIDE1_ADDR);
- val = ((dst->stride2 & MDP3_PPP_STRIDE_MASK) <<
- MDP3_PPP_STRIDE1_OFFSET);
- PPP_WRITEL(val, MDP3_PPP_OUT_YSTRIDE2_ADDR);
- return 0;
- }
- int config_ppp_background(struct ppp_img_desc *bg)
- {
- uint32_t val;
- PPP_WRITEL(bg->p0, MDP3_PPP_BGP0_ADDR);
- PPP_WRITEL(bg->p1, MDP3_PPP_BGP1_ADDR);
- PPP_WRITEL(bg->p3, MDP3_PPP_BGP3_ADDR);
- val = (bg->stride0 & MDP3_PPP_STRIDE_MASK) |
- ((bg->stride1 & MDP3_PPP_STRIDE_MASK) <<
- MDP3_PPP_STRIDE1_OFFSET);
- PPP_WRITEL(val, MDP3_PPP_BG_YSTRIDE1_ADDR);
- val = ((bg->stride2 & MDP3_PPP_STRIDE_MASK) <<
- MDP3_PPP_STRIDE1_OFFSET);
- PPP_WRITEL(val, MDP3_PPP_BG_YSTRIDE2_ADDR);
- PPP_WRITEL(ppp_src_config(bg->color_fmt),
- MDP3_PPP_BG_FORMAT);
- PPP_WRITEL(ppp_pack_pattern(bg->color_fmt, 0),
- MDP3_PPP_BG_UNPACK_PATTERN1);
- return 0;
- }
- void ppp_edge_rep_luma_pixel(struct ppp_blit_op *blit_op,
- struct ppp_edge_rep *er)
- {
- if (blit_op->mdp_op & MDPOP_ASCALE) {
- er->is_scale_enabled = 1;
- if (blit_op->mdp_op & MDPOP_ROT90) {
- er->dst_roi_width = blit_op->dst.roi.height;
- er->dst_roi_height = blit_op->dst.roi.width;
- } else {
- er->dst_roi_width = blit_op->dst.roi.width;
- er->dst_roi_height = blit_op->dst.roi.height;
- }
- /*
- * Find out the luma pixels needed for scaling in the
- * x direction (LEFT and RIGHT). Locations of pixels are
- * relative to the ROI. Upper-left corner of ROI corresponds
- * to coordinates (0,0). Also set the number of luma pixel
- * to repeat.
- */
- if (blit_op->src.roi.width > 3 * er->dst_roi_width) {
- /* scale factor < 1/3 */
- er->luma_interp_point_right =
- (blit_op->src.roi.width - 1);
- } else if (blit_op->src.roi.width == 3 * er->dst_roi_width) {
- /* scale factor == 1/3 */
- er->luma_interp_point_right =
- (blit_op->src.roi.width - 1) + 1;
- er->luma_repeat_right = 1;
- } else if ((blit_op->src.roi.width > er->dst_roi_width) &&
- (blit_op->src.roi.width < 3 * er->dst_roi_width)) {
- /* 1/3 < scale factor < 1 */
- er->luma_interp_point_left = -1;
- er->luma_interp_point_right =
- (blit_op->src.roi.width - 1) + 1;
- er->luma_repeat_left = 1;
- er->luma_repeat_right = 1;
- } else if (blit_op->src.roi.width == er->dst_roi_width) {
- /* scale factor == 1 */
- er->luma_interp_point_left = -1;
- er->luma_interp_point_right =
- (blit_op->src.roi.width - 1) + 2;
- er->luma_repeat_left = 1;
- er->luma_repeat_right = 2;
- } else {
- /* scale factor > 1 */
- er->luma_interp_point_left = -2;
- er->luma_interp_point_right =
- (blit_op->src.roi.width - 1) + 2;
- er->luma_repeat_left = 2;
- er->luma_repeat_right = 2;
- }
- /*
- * Find out the number of pixels needed for scaling in the
- * y direction (TOP and BOTTOM). Locations of pixels are
- * relative to the ROI. Upper-left corner of ROI corresponds
- * to coordinates (0,0). Also set the number of luma pixel
- * to repeat.
- */
- if (blit_op->src.roi.height > 3 * er->dst_roi_height) {
- er->luma_interp_point_bottom =
- (blit_op->src.roi.height - 1);
- } else if (blit_op->src.roi.height == 3 * er->dst_roi_height) {
- er->luma_interp_point_bottom =
- (blit_op->src.roi.height - 1) + 1;
- er->luma_repeat_bottom = 1;
- } else if ((blit_op->src.roi.height > er->dst_roi_height) &&
- (blit_op->src.roi.height < 3 * er->dst_roi_height)) {
- er->luma_interp_point_top = -1;
- er->luma_interp_point_bottom =
- (blit_op->src.roi.height - 1) + 1;
- er->luma_repeat_top = 1;
- er->luma_repeat_bottom = 1;
- } else if (blit_op->src.roi.height == er->dst_roi_height) {
- er->luma_interp_point_top = -1;
- er->luma_interp_point_bottom =
- (blit_op->src.roi.height - 1) + 2;
- er->luma_repeat_top = 1;
- er->luma_repeat_bottom = 2;
- } else {
- er->luma_interp_point_top = -2;
- er->luma_interp_point_bottom =
- (blit_op->src.roi.height - 1) + 2;
- er->luma_repeat_top = 2;
- er->luma_repeat_bottom = 2;
- }
- } else {
- /*
- * Since no scaling needed, Tile Fetch does not require any
- * more luma pixel than what the ROI contains.
- */
- er->luma_interp_point_right =
- (int32_t) (blit_op->src.roi.width - 1);
- er->luma_interp_point_bottom =
- (int32_t) (blit_op->src.roi.height - 1);
- }
- /* After adding the ROI offsets, we have locations of
- * luma_interp_points relative to the image.
- */
- er->luma_interp_point_left += (int32_t) (blit_op->src.roi.x);
- er->luma_interp_point_right += (int32_t) (blit_op->src.roi.x);
- er->luma_interp_point_top += (int32_t) (blit_op->src.roi.y);
- er->luma_interp_point_bottom += (int32_t) (blit_op->src.roi.y);
- }
- void ppp_edge_rep_chroma_pixel(struct ppp_blit_op *blit_op,
- struct ppp_edge_rep *er)
- {
- bool chroma_edge_enable = true;
- uint32_t is_yuv_offsite_vertical = 0;
- /* find out which chroma pixels are needed for chroma upsampling. */
- switch (blit_op->src.color_fmt) {
- case MDP_Y_CBCR_H2V1:
- case MDP_Y_CRCB_H2V1:
- case MDP_YCRYCB_H2V1:
- er->chroma_interp_point_left = er->luma_interp_point_left >> 1;
- er->chroma_interp_point_right =
- (er->luma_interp_point_right + 1) >> 1;
- er->chroma_interp_point_top = er->luma_interp_point_top;
- er->chroma_interp_point_bottom = er->luma_interp_point_bottom;
- break;
- case MDP_Y_CBCR_H2V2:
- case MDP_Y_CBCR_H2V2_ADRENO:
- case MDP_Y_CBCR_H2V2_VENUS:
- case MDP_Y_CRCB_H2V2:
- er->chroma_interp_point_left = er->luma_interp_point_left >> 1;
- er->chroma_interp_point_right =
- (er->luma_interp_point_right + 1) >> 1;
- er->chroma_interp_point_top =
- (er->luma_interp_point_top - 1) >> 1;
- er->chroma_interp_point_bottom =
- (er->luma_interp_point_bottom + 1) >> 1;
- is_yuv_offsite_vertical = 1;
- break;
- default:
- chroma_edge_enable = false;
- er->chroma_interp_point_left = er->luma_interp_point_left;
- er->chroma_interp_point_right = er->luma_interp_point_right;
- er->chroma_interp_point_top = er->luma_interp_point_top;
- er->chroma_interp_point_bottom = er->luma_interp_point_bottom;
- break;
- }
- if (chroma_edge_enable) {
- /* Defines which chroma pixels belongs to the roi */
- switch (blit_op->src.color_fmt) {
- case MDP_Y_CBCR_H2V1:
- case MDP_Y_CRCB_H2V1:
- case MDP_YCRYCB_H2V1:
- er->chroma_bound_left = blit_op->src.roi.x / 2;
- /* there are half as many chroma pixel as luma pixels */
- er->chroma_bound_right =
- (blit_op->src.roi.width +
- blit_op->src.roi.x - 1) / 2;
- er->chroma_bound_top = blit_op->src.roi.y;
- er->chroma_bound_bottom =
- (blit_op->src.roi.height + blit_op->src.roi.y - 1);
- break;
- case MDP_Y_CBCR_H2V2:
- case MDP_Y_CBCR_H2V2_ADRENO:
- case MDP_Y_CBCR_H2V2_VENUS:
- case MDP_Y_CRCB_H2V2:
- /*
- * cosite in horizontal dir, and offsite in vertical dir
- * width of chroma ROI is 1/2 of size of luma ROI
- * height of chroma ROI is 1/2 of size of luma ROI
- */
- er->chroma_bound_left = blit_op->src.roi.x / 2;
- er->chroma_bound_right =
- (blit_op->src.roi.width +
- blit_op->src.roi.x - 1) / 2;
- er->chroma_bound_top = blit_op->src.roi.y / 2;
- er->chroma_bound_bottom =
- (blit_op->src.roi.height +
- blit_op->src.roi.y - 1) / 2;
- break;
- default:
- /*
- * If no valid chroma sub-sampling format specified,
- * assume 4:4:4 ( i.e. fully sampled).
- */
- er->chroma_bound_left = blit_op->src.roi.x;
- er->chroma_bound_right = blit_op->src.roi.width +
- blit_op->src.roi.x - 1;
- er->chroma_bound_top = blit_op->src.roi.y;
- er->chroma_bound_bottom =
- (blit_op->src.roi.height + blit_op->src.roi.y - 1);
- break;
- }
- /*
- * Knowing which chroma pixels are needed, and which chroma
- * pixels belong to the ROI (i.e. available for fetching ),
- * calculate how many chroma pixels Tile Fetch needs to
- * duplicate. If any required chroma pixels falls outside
- * of the ROI, Tile Fetch must obtain them by replicating
- * pixels.
- */
- if (er->chroma_bound_left > er->chroma_interp_point_left)
- er->chroma_repeat_left =
- er->chroma_bound_left -
- er->chroma_interp_point_left;
- else
- er->chroma_repeat_left = 0;
- if (er->chroma_interp_point_right > er->chroma_bound_right)
- er->chroma_repeat_right =
- er->chroma_interp_point_right -
- er->chroma_bound_right;
- else
- er->chroma_repeat_right = 0;
- if (er->chroma_bound_top > er->chroma_interp_point_top)
- er->chroma_repeat_top =
- er->chroma_bound_top -
- er->chroma_interp_point_top;
- else
- er->chroma_repeat_top = 0;
- if (er->chroma_interp_point_bottom > er->chroma_bound_bottom)
- er->chroma_repeat_bottom =
- er->chroma_interp_point_bottom -
- er->chroma_bound_bottom;
- else
- er->chroma_repeat_bottom = 0;
- if (er->is_scale_enabled && (blit_op->src.roi.height == 1)
- && is_yuv_offsite_vertical) {
- er->chroma_repeat_bottom = 3;
- er->chroma_repeat_top = 0;
- }
- }
- }
- int config_ppp_edge_rep(struct ppp_blit_op *blit_op)
- {
- uint32_t reg = 0;
- struct ppp_edge_rep er;
- memset(&er, 0, sizeof(er));
- ppp_edge_rep_luma_pixel(blit_op, &er);
- /*
- * After adding the ROI offsets, we have locations of
- * chroma_interp_points relative to the image.
- */
- er.chroma_interp_point_left = er.luma_interp_point_left;
- er.chroma_interp_point_right = er.luma_interp_point_right;
- er.chroma_interp_point_top = er.luma_interp_point_top;
- er.chroma_interp_point_bottom = er.luma_interp_point_bottom;
- ppp_edge_rep_chroma_pixel(blit_op, &er);
- /* ensure repeats are >=0 and no larger than 3 pixels */
- if ((er.chroma_repeat_left < 0) || (er.chroma_repeat_right < 0) ||
- (er.chroma_repeat_top < 0) || (er.chroma_repeat_bottom < 0))
- return -EINVAL;
- if ((er.chroma_repeat_left > 3) || (er.chroma_repeat_right > 3) ||
- (er.chroma_repeat_top > 3) || (er.chroma_repeat_bottom > 3))
- return -EINVAL;
- if ((er.luma_repeat_left < 0) || (er.luma_repeat_right < 0) ||
- (er.luma_repeat_top < 0) || (er.luma_repeat_bottom < 0))
- return -EINVAL;
- if ((er.luma_repeat_left > 3) || (er.luma_repeat_right > 3) ||
- (er.luma_repeat_top > 3) || (er.luma_repeat_bottom > 3))
- return -EINVAL;
- reg |= (er.chroma_repeat_left & 3) << MDP_LEFT_CHROMA;
- reg |= (er.chroma_repeat_right & 3) << MDP_RIGHT_CHROMA;
- reg |= (er.chroma_repeat_top & 3) << MDP_TOP_CHROMA;
- reg |= (er.chroma_repeat_bottom & 3) << MDP_BOTTOM_CHROMA;
- reg |= (er.luma_repeat_left & 3) << MDP_LEFT_LUMA;
- reg |= (er.luma_repeat_right & 3) << MDP_RIGHT_LUMA;
- reg |= (er.luma_repeat_top & 3) << MDP_TOP_LUMA;
- reg |= (er.luma_repeat_bottom & 3) << MDP_BOTTOM_LUMA;
- PPP_WRITEL(reg, MDP3_PPP_SRC_EDGE_REP);
- return 0;
- }
- int config_ppp_bg_edge_rep(struct ppp_blit_op *blit_op)
- {
- uint32_t reg = 0;
- switch (blit_op->dst.color_fmt) {
- case MDP_Y_CBCR_H2V2:
- case MDP_Y_CRCB_H2V2:
- if (blit_op->dst.roi.y == 0)
- reg |= BIT(MDP_TOP_CHROMA);
- if ((blit_op->dst.roi.y + blit_op->dst.roi.height) ==
- blit_op->dst.prop.height) {
- reg |= BIT(MDP_BOTTOM_CHROMA);
- }
- if (((blit_op->dst.roi.x + blit_op->dst.roi.width) ==
- blit_op->dst.prop.width) &&
- ((blit_op->dst.roi.width % 2) == 0))
- reg |= BIT(MDP_RIGHT_CHROMA);
- break;
- case MDP_Y_CBCR_H2V1:
- case MDP_Y_CRCB_H2V1:
- case MDP_YCRYCB_H2V1:
- if (((blit_op->dst.roi.x + blit_op->dst.roi.width) ==
- blit_op->dst.prop.width) &&
- ((blit_op->dst.roi.width % 2) == 0))
- reg |= BIT(MDP_RIGHT_CHROMA);
- break;
- default:
- break;
- }
- PPP_WRITEL(reg, MDP3_PPP_BG_EDGE_REP);
- return 0;
- }
- int config_ppp_lut(uint32_t *pppop_reg_ptr, int lut_c0_en,
- int lut_c1_en, int lut_c2_en)
- {
- if (lut_c0_en)
- *pppop_reg_ptr |= MDP_LUT_C0_EN;
- if (lut_c1_en)
- *pppop_reg_ptr |= MDP_LUT_C1_EN;
- if (lut_c2_en)
- *pppop_reg_ptr |= MDP_LUT_C2_EN;
- return 0;
- }
- int config_ppp_scale(struct ppp_blit_op *blit_op, uint32_t *pppop_reg_ptr)
- {
- struct ppp_img_desc *src = &blit_op->src;
- struct ppp_img_desc *dst = &blit_op->dst;
- uint32_t dstW, dstH;
- uint32_t x_fac, y_fac;
- uint32_t mdp_blur = 0;
- uint32_t phase_init_x, phase_init_y, phase_step_x, phase_step_y;
- int x_idx, y_idx;
- if (blit_op->mdp_op & MDPOP_ASCALE) {
- if (blit_op->mdp_op & MDPOP_ROT90) {
- dstW = dst->roi.height;
- dstH = dst->roi.width;
- } else {
- dstW = dst->roi.width;
- dstH = dst->roi.height;
- }
- *pppop_reg_ptr |=
- (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
- mdp_blur = blit_op->mdp_op & MDPOP_BLUR;
- if ((dstW != src->roi.width) ||
- (dstH != src->roi.height) || mdp_blur) {
- mdp_calc_scale_params(blit_op->src.roi.x,
- blit_op->src.roi.width,
- dstW, 1, &phase_init_x,
- &phase_step_x);
- mdp_calc_scale_params(blit_op->src.roi.y,
- blit_op->src.roi.height,
- dstH, 0, &phase_init_y,
- &phase_step_y);
- PPP_WRITEL(phase_init_x, MDP3_PPP_SCALE_PHASEX_INIT);
- PPP_WRITEL(phase_init_y, MDP3_PPP_SCALE_PHASEY_INIT);
- PPP_WRITEL(phase_step_x, MDP3_PPP_SCALE_PHASEX_STEP);
- PPP_WRITEL(phase_step_y, MDP3_PPP_SCALE_PHASEY_STEP);
- if (dstW > src->roi.width || dstH > src->roi.height)
- ppp_load_up_lut();
- if (mdp_blur)
- ppp_load_gaussian_lut();
- if (dstW <= src->roi.width) {
- x_fac = (dstW * 100) / src->roi.width;
- x_idx = scale_idx(x_fac);
- ppp_load_x_scale_table(x_idx);
- }
- if (dstH <= src->roi.height) {
- y_fac = (dstH * 100) / src->roi.height;
- y_idx = scale_idx(y_fac);
- ppp_load_y_scale_table(y_idx);
- }
- } else {
- blit_op->mdp_op &= ~(MDPOP_ASCALE);
- }
- }
- config_ppp_edge_rep(blit_op);
- config_ppp_bg_edge_rep(blit_op);
- return 0;
- }
- int config_ppp_csc(int src_color, int dst_color, uint32_t *pppop_reg_ptr)
- {
- bool inputRGB, outputRGB;
- inputRGB = check_if_rgb(src_color);
- outputRGB = check_if_rgb(dst_color);
- if ((!inputRGB) && (outputRGB))
- *pppop_reg_ptr |= PPP_OP_CONVERT_YCBCR2RGB |
- PPP_OP_CONVERT_ON;
- if ((inputRGB) && (!outputRGB))
- *pppop_reg_ptr |= PPP_OP_CONVERT_ON;
- return 0;
- }
- int config_ppp_blend(struct ppp_blit_op *blit_op,
- uint32_t *pppop_reg_ptr)
- {
- struct ppp_csc_table *csc;
- uint32_t alpha, trans_color;
- uint32_t val = 0;
- int c_fmt = blit_op->src.color_fmt;
- int bg_alpha;
- csc = ppp_csc_rgb2yuv();
- alpha = blit_op->blend.const_alpha;
- trans_color = blit_op->blend.trans_color;
- if (blit_op->mdp_op & MDPOP_FG_PM_ALPHA) {
- if (ppp_per_p_alpha(c_fmt)) {
- *pppop_reg_ptr |= PPP_OP_ROT_ON |
- PPP_OP_BLEND_ON |
- PPP_OP_BLEND_CONSTANT_ALPHA;
- } else {
- if ((blit_op->mdp_op & MDPOP_ALPHAB)
- && (blit_op->blend.const_alpha == 0xff)) {
- blit_op->mdp_op &= ~(MDPOP_ALPHAB);
- }
- if ((blit_op->mdp_op & MDPOP_ALPHAB)
- || (blit_op->mdp_op & MDPOP_TRANSP)) {
- *pppop_reg_ptr |= PPP_OP_ROT_ON |
- PPP_OP_BLEND_ON |
- PPP_OP_BLEND_CONSTANT_ALPHA |
- PPP_OP_BLEND_ALPHA_BLEND_NORMAL;
- }
- }
- bg_alpha = PPP_BLEND_BG_USE_ALPHA_SEL |
- PPP_BLEND_BG_ALPHA_REVERSE;
- if ((ppp_per_p_alpha(c_fmt)) && !(blit_op->mdp_op &
- MDPOP_LAYER_IS_FG)) {
- bg_alpha |= PPP_BLEND_BG_SRCPIXEL_ALPHA;
- } else {
- bg_alpha |= PPP_BLEND_BG_CONSTANT_ALPHA;
- bg_alpha |= blit_op->blend.const_alpha << 24;
- }
- PPP_WRITEL(bg_alpha, MDP3_PPP_BLEND_BG_ALPHA_SEL);
- if (blit_op->mdp_op & MDPOP_TRANSP)
- *pppop_reg_ptr |= PPP_BLEND_CALPHA_TRNASP;
- } else if (ppp_per_p_alpha(c_fmt)) {
- if (blit_op->mdp_op & MDPOP_LAYER_IS_FG)
- *pppop_reg_ptr |= PPP_OP_ROT_ON |
- PPP_OP_BLEND_ON |
- PPP_OP_BLEND_CONSTANT_ALPHA;
- else
- *pppop_reg_ptr |= PPP_OP_ROT_ON |
- PPP_OP_BLEND_ON |
- PPP_OP_BLEND_SRCPIXEL_ALPHA;
- PPP_WRITEL(0, MDP3_PPP_BLEND_BG_ALPHA_SEL);
- } else {
- if ((blit_op->mdp_op & MDPOP_ALPHAB)
- && (blit_op->blend.const_alpha == 0xff)) {
- blit_op->mdp_op &=
- ~(MDPOP_ALPHAB);
- }
- if ((blit_op->mdp_op & MDPOP_ALPHAB)
- || (blit_op->mdp_op & 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 (blit_op->mdp_op & MDPOP_TRANSP)
- *pppop_reg_ptr |=
- PPP_BLEND_CALPHA_TRNASP;
- PPP_WRITEL(0, MDP3_PPP_BLEND_BG_ALPHA_SEL);
- }
- if (*pppop_reg_ptr & PPP_OP_BLEND_ON) {
- config_ppp_background(&blit_op->bg);
- if (blit_op->dst.color_fmt == MDP_YCRYCB_H2V1) {
- *pppop_reg_ptr |= PPP_OP_BG_CHROMA_H2V1;
- if (blit_op->mdp_op & MDPOP_TRANSP) {
- trans_color = conv_rgb2yuv(trans_color,
- &csc->fwd_matrix[0],
- &csc->bv[0],
- &csc->lv[0]);
- }
- }
- }
- val = (alpha << MDP_BLEND_CONST_ALPHA);
- val |= (trans_color & MDP_BLEND_TRASP_COL_MASK);
- PPP_WRITEL(val, MDP3_PPP_BLEND_PARAM);
- return 0;
- }
- int config_ppp_rotation(uint32_t mdp_op, uint32_t *pppop_reg_ptr)
- {
- *pppop_reg_ptr |= PPP_OP_ROT_ON;
- if (mdp_op & MDPOP_ROT90)
- *pppop_reg_ptr |= PPP_OP_ROT_90;
- if (mdp_op & MDPOP_LR)
- *pppop_reg_ptr |= PPP_OP_FLIP_LR;
- if (mdp_op & MDPOP_UD)
- *pppop_reg_ptr |= PPP_OP_FLIP_UD;
- return 0;
- }
- int config_ppp_op_mode(struct ppp_blit_op *blit_op)
- {
- uint32_t yuv2rgb;
- uint32_t ppp_operation_reg = 0;
- int sv_slice, sh_slice;
- int dv_slice, dh_slice;
- sv_slice = sh_slice = dv_slice = dh_slice = 1;
- ppp_operation_reg |= ppp_dst_op_reg(blit_op->dst.color_fmt);
- switch (blit_op->dst.color_fmt) {
- case MDP_Y_CBCR_H2V2:
- case MDP_Y_CRCB_H2V2:
- y_h_even_num(&blit_op->dst);
- y_h_even_num(&blit_op->src);
- dv_slice = 2;
- case MDP_Y_CBCR_H2V1:
- case MDP_Y_CRCB_H2V1:
- case MDP_YCRYCB_H2V1:
- x_w_even_num(&blit_op->dst);
- x_w_even_num(&blit_op->src);
- dh_slice = 2;
- break;
- default:
- break;
- }
- ppp_operation_reg |= ppp_src_op_reg(blit_op->src.color_fmt);
- switch (blit_op->src.color_fmt) {
- case MDP_Y_CBCR_H2V2:
- case MDP_Y_CBCR_H2V2_ADRENO:
- case MDP_Y_CBCR_H2V2_VENUS:
- case MDP_Y_CRCB_H2V2:
- sh_slice = sv_slice = 2;
- break;
- case MDP_YCRYCB_H2V1:
- x_w_even_num(&blit_op->dst);
- x_w_even_num(&blit_op->src);
- case MDP_Y_CBCR_H2V1:
- case MDP_Y_CRCB_H2V1:
- sh_slice = 2;
- break;
- default:
- break;
- }
- config_ppp_csc(blit_op->src.color_fmt,
- blit_op->dst.color_fmt, &ppp_operation_reg);
- yuv2rgb = ppp_operation_reg & PPP_OP_CONVERT_YCBCR2RGB;
- if (blit_op->mdp_op & MDPOP_DITHER)
- ppp_operation_reg |= PPP_OP_DITHER_EN;
- if (blit_op->mdp_op & MDPOP_ROTATION)
- config_ppp_rotation(blit_op->mdp_op, &ppp_operation_reg);
- if (blit_op->src.color_fmt == MDP_Y_CBCR_H2V2_ADRENO) {
- blit_op->src.stride0 = ALIGN(blit_op->src.prop.width, 32) *
- ppp_bpp(blit_op->src.color_fmt);
- blit_op->src.stride1 = 2 * ALIGN(blit_op->src.prop.width/2, 32);
- } else if (blit_op->src.color_fmt == MDP_Y_CBCR_H2V2_VENUS) {
- blit_op->src.stride0 = ALIGN(blit_op->src.prop.width, 128) *
- ppp_bpp(blit_op->src.color_fmt);
- blit_op->src.stride1 = blit_op->src.stride0;
- } else {
- blit_op->src.stride0 = blit_op->src.prop.width *
- ppp_bpp(blit_op->src.color_fmt);
- blit_op->src.stride1 = blit_op->src.stride0;
- }
- blit_op->dst.stride0 = blit_op->dst.prop.width *
- ppp_bpp(blit_op->dst.color_fmt);
- if (ppp_multi_plane(blit_op->dst.color_fmt)) {
- blit_op->dst.p1 = blit_op->dst.p0;
- blit_op->dst.p1 += blit_op->dst.prop.width *
- blit_op->dst.prop.height *
- ppp_bpp(blit_op->dst.color_fmt);
- } else {
- blit_op->dst.p1 = NULL;
- }
- blit_op->bg = blit_op->dst;
- /* Jumping from Y-Plane to Chroma Plane */
- /* first pixel addr calculation */
- mdp_adjust_start_addr(blit_op, &blit_op->src, sv_slice, sh_slice, 0);
- mdp_adjust_start_addr(blit_op, &blit_op->bg, dv_slice, dh_slice, 1);
- mdp_adjust_start_addr(blit_op, &blit_op->dst, dv_slice, dh_slice, 2);
- config_ppp_scale(blit_op, &ppp_operation_reg);
- config_ppp_blend(blit_op, &ppp_operation_reg);
- config_ppp_src(&blit_op->src, yuv2rgb);
- config_ppp_out(&blit_op->dst, yuv2rgb);
- PPP_WRITEL(ppp_operation_reg, MDP3_PPP_OP_MODE);
- mb();
- return 0;
- }
- void ppp_enable(void)
- {
- PPP_WRITEL(0x1000, 0x30);
- mb();
- }
- int mdp3_ppp_init(void)
- {
- load_ppp_lut(LUT_PRE_TABLE, ppp_default_pre_lut());
- load_ppp_lut(LUT_POST_TABLE, ppp_default_post_lut());
- load_csc_matrix(CSC_PRIMARY_MATRIX, ppp_csc_rgb2yuv());
- load_csc_matrix(CSC_SECONDARY_MATRIX, ppp_csc_table2());
- return 0;
- }
|