• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * g2d_scal.c
3  *
4  * Copyright (c) 2007-2019 Allwinnertech Co., Ltd.
5  * Author: zhengxiaobin <zhengxiaobin@allwinnertech.com>
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17 #include "g2d_scal.h"
18 
19 static __s32 linearcoefftab32[32] = {
20 	0x00004000, 0x00023e00, 0x00043c00, 0x00063a00, 0x00083800,
21 	0x000a3600, 0x000c3400, 0x000e3200, 0x00103000, 0x00122e00,
22 	0x00142c00, 0x00162a00, 0x00182800, 0x001a2600, 0x001c2400,
23 	0x001e2200, 0x00202000, 0x00221e00, 0x00241c00, 0x00261a00,
24 	0x00281800, 0x002a1600, 0x002c1400, 0x002e1200, 0x00301000,
25 	0x00320e00, 0x00340c00, 0x00360a00, 0x00380800, 0x003a0600,
26 	0x003c0400, 0x003e0200, };
27 
28 static __s32 lan2coefftab32_full[512] = {
29 	0x00004000, 0x000140ff, 0x00033ffe, 0x00043ffd, 0x00063efc, 0xff083dfc,
30 	0x000a3bfb, 0xff0d39fb, 0xff0f37fb, 0xff1136fa, 0xfe1433fb,
31 	0xfe1631fb, 0xfd192ffb, 0xfd1c2cfb, 0xfd1f29fb, 0xfc2127fc,
32 	0xfc2424fc, 0xfc2721fc, 0xfb291ffd, 0xfb2c1cfd, 0xfb2f19fd,
33 	0xfb3116fe, 0xfb3314fe, 0xfa3611ff, 0xfb370fff, 0xfb390dff,
34 	0xfb3b0a00, 0xfc3d08ff, 0xfc3e0600, 0xfd3f0400, 0xfe3f0300,
35 	0xff400100,
36 	/* counter = 1 */
37 	0x00004000, 0x000140ff, 0x00033ffe, 0x00043ffd, 0x00063efc,
38 	0xff083dfc, 0x000a3bfb, 0xff0d39fb, 0xff0f37fb, 0xff1136fa,
39 	0xfe1433fb, 0xfe1631fb, 0xfd192ffb, 0xfd1c2cfb, 0xfd1f29fb,
40 	0xfc2127fc, 0xfc2424fc, 0xfc2721fc, 0xfb291ffd, 0xfb2c1cfd,
41 	0xfb2f19fd, 0xfb3116fe, 0xfb3314fe, 0xfa3611ff, 0xfb370fff,
42 	0xfb390dff, 0xfb3b0a00, 0xfc3d08ff, 0xfc3e0600, 0xfd3f0400,
43 	0xfe3f0300, 0xff400100,
44 	/* counter = 2 */
45 	0xff053804, 0xff063803, 0xff083801, 0xff093701, 0xff0a3700,
46 	0xff0c3500, 0xff0e34ff, 0xff1033fe, 0xff1232fd, 0xfe1431fd,
47 	0xfe162ffd, 0xfe182dfd, 0xfd1b2cfc, 0xfd1d2afc, 0xfd1f28fc,
48 	0xfd2126fc, 0xfd2323fd, 0xfc2621fd, 0xfc281ffd, 0xfc2a1dfd,
49 	0xfc2c1bfd, 0xfd2d18fe, 0xfd2f16fe, 0xfd3114fe, 0xfd3212ff,
50 	0xfe3310ff, 0xff340eff, 0x00350cff, 0x00360a00, 0x01360900,
51 	0x02370700, 0x03370600,
52 	/* counter = 3 */
53 	0xff083207, 0xff093206, 0xff0a3205, 0xff0c3203, 0xff0d3103,
54 	0xff0e3102, 0xfe113001, 0xfe132f00, 0xfe142e00, 0xfe162dff,
55 	0xfe182bff, 0xfe192aff, 0xfe1b29fe, 0xfe1d27fe, 0xfe1f25fe,
56 	0xfd2124fe, 0xfe2222fe, 0xfe2421fd, 0xfe251ffe, 0xfe271dfe,
57 	0xfe291bfe, 0xff2a19fe, 0xff2b18fe, 0xff2d16fe, 0x002e14fe,
58 	0x002f12ff, 0x013010ff, 0x02300fff, 0x03310dff, 0x04310cff,
59 	0x05310a00, 0x06310900,
60 	/* counter = 4 */
61 	0xff0a2e09, 0xff0b2e08, 0xff0c2e07, 0xff0e2d06, 0xff0f2d05,
62 	0xff102d04, 0xff122c03, 0xfe142c02, 0xfe152b02, 0xfe172a01,
63 	0xfe182901, 0xfe1a2800, 0xfe1b2700, 0xfe1d2500, 0xff1e24ff,
64 	0xfe2023ff, 0xff2121ff, 0xff2320fe, 0xff241eff, 0x00251dfe,
65 	0x00261bff, 0x00281afe, 0x012818ff, 0x012a16ff, 0x022a15ff,
66 	0x032b13ff, 0x032c12ff, 0x052c10ff, 0x052d0fff, 0x062d0d00,
67 	0x072d0c00, 0x082d0b00,
68 	/* counter = 5 */
69 	0xff0c2a0b, 0xff0d2a0a, 0xff0e2a09, 0xff0f2a08, 0xff102a07,
70 	0xff112a06, 0xff132905, 0xff142904, 0xff162803, 0xff172703,
71 	0xff182702, 0xff1a2601, 0xff1b2501, 0xff1c2401, 0xff1e2300,
72 	0xff1f2200, 0x00202000, 0x00211f00, 0x01221d00, 0x01231c00,
73 	0x01251bff, 0x02251aff, 0x032618ff, 0x032717ff, 0x042815ff,
74 	0x052814ff, 0x052913ff, 0x06291100, 0x072a10ff, 0x082a0e00,
75 	0x092a0d00, 0x0a2a0c00,
76 	/* counter = 6 */
77 	0xff0d280c, 0xff0e280b, 0xff0f280a, 0xff102809, 0xff112808,
78 	0xff122708, 0xff142706, 0xff152705, 0xff162605, 0xff172604,
79 	0xff192503, 0xff1a2403, 0x001b2302, 0x001c2202, 0x001d2201,
80 	0x001e2101, 0x011f1f01, 0x01211e00, 0x01221d00, 0x02221c00,
81 	0x02231b00, 0x03241900, 0x04241800, 0x04251700, 0x052616ff,
82 	0x06261400, 0x072713ff, 0x08271100, 0x08271100, 0x09271000,
83 	0x0a280e00, 0x0b280d00,
84 	/* counter = 7 */
85 	0xff0e260d, 0xff0f260c, 0xff10260b, 0xff11260a, 0xff122609,
86 	0xff132608, 0xff142508, 0xff152507, 0x00152506, 0x00172405,
87 	0x00182305, 0x00192304, 0x001b2203, 0x001c2103, 0x011d2002,
88 	0x011d2002, 0x011f1f01, 0x021f1e01, 0x02201d01, 0x03211c00,
89 	0x03221b00, 0x04221a00, 0x04231801, 0x05241700, 0x06241600,
90 	0x07241500, 0x08251300, 0x09251200, 0x09261100, 0x0a261000,
91 	0x0b260f00, 0x0c260e00,
92 	/* counter = 8 */
93 	0xff0e250e, 0xff0f250d, 0xff10250c, 0xff11250b, 0x0011250a,
94 	0x00132409, 0x00142408, 0x00152407, 0x00162307, 0x00172306,
95 	0x00182206, 0x00192205, 0x011a2104, 0x011b2004, 0x011c2003,
96 	0x021c1f03, 0x021e1e02, 0x031e1d02, 0x03201c01, 0x04201b01,
97 	0x04211a01, 0x05221900, 0x05221801, 0x06231700, 0x07231600,
98 	0x07241500, 0x08241400, 0x09241300, 0x0a241200, 0x0b241100,
99 	0x0c241000, 0x0d240f00,
100 	/* counter = 9 */
101 	0x000e240e, 0x000f240d, 0x0010240c, 0x0011240b, 0x0013230a,
102 	0x0013230a, 0x00142309, 0x00152308, 0x00162208, 0x00172207,
103 	0x01182106, 0x01192105, 0x011a2005, 0x021b1f04, 0x021b1f04,
104 	0x021d1e03, 0x031d1d03, 0x031e1d02, 0x041e1c02, 0x041f1b02,
105 	0x05201a01, 0x05211901, 0x06211801, 0x07221700, 0x07221601,
106 	0x08231500, 0x09231400, 0x0a231300, 0x0a231300, 0x0b231200,
107 	0x0c231100, 0x0d231000,
108 	/* counter = 10 */
109 	0x000f220f, 0x0010220e, 0x0011220d, 0x0012220c, 0x0013220b,
110 	0x0013220b, 0x0015210a, 0x0015210a, 0x01162108, 0x01172008,
111 	0x01182007, 0x02191f06, 0x02191f06, 0x021a1e06, 0x031a1e05,
112 	0x031c1d04, 0x041c1c04, 0x041d1c03, 0x051d1b03, 0x051e1a03,
113 	0x061f1902, 0x061f1902, 0x07201801, 0x08201701, 0x08211601,
114 	0x09211501, 0x0a211500, 0x0b211400, 0x0b221300, 0x0c221200,
115 	0x0d221100, 0x0e221000,
116 	/* counter = 11 */
117 	0x0010210f, 0x0011210e, 0x0011210e, 0x0012210d, 0x0013210c,
118 	0x0014200c, 0x0114200b, 0x0115200a, 0x01161f0a, 0x01171f09,
119 	0x02171f08, 0x02181e08, 0x03181e07, 0x031a1d06, 0x031a1d06,
120 	0x041b1c05, 0x041c1c04, 0x051c1b04, 0x051d1a04, 0x061d1a03,
121 	0x071d1903, 0x071e1803, 0x081e1802, 0x081f1702, 0x091f1602,
122 	0x0a201501, 0x0b1f1501, 0x0b201401, 0x0c211300, 0x0d211200,
123 	0x0e201200, 0x0e211100,
124 	/* counter = 12 */
125 	0x00102010, 0x0011200f, 0x0012200e, 0x0013200d, 0x0013200d,
126 	0x01141f0c, 0x01151f0b, 0x01151f0b, 0x01161f0a, 0x02171e09,
127 	0x02171e09, 0x03181d08, 0x03191d07, 0x03191d07, 0x041a1c06,
128 	0x041b1c05, 0x051b1b05, 0x051c1b04, 0x061c1a04, 0x071d1903,
129 	0x071d1903, 0x081d1803, 0x081e1703, 0x091e1702, 0x0a1f1601,
130 	0x0a1f1502, 0x0b1f1501, 0x0c1f1401, 0x0d201300, 0x0d201300,
131 	0x0e201200, 0x0f201100,
132 	/* counter = 13 */
133 	0x00102010, 0x0011200f, 0x00121f0f, 0x00131f0e, 0x00141f0d,
134 	0x01141f0c, 0x01141f0c, 0x01151e0c, 0x02161e0a, 0x02171e09,
135 	0x03171d09, 0x03181d08, 0x03181d08, 0x04191c07, 0x041a1c06,
136 	0x051a1b06, 0x051b1b05, 0x061b1a05, 0x061c1a04, 0x071c1904,
137 	0x081c1903, 0x081d1803, 0x091d1703, 0x091e1702, 0x0a1e1602,
138 	0x0b1e1502, 0x0c1e1501, 0x0c1f1401, 0x0d1f1400, 0x0e1f1300,
139 	0x0e1f1201, 0x0f1f1200,
140 	/* counter = 14 */
141 	0x00111e11, 0x00121e10, 0x00131e0f, 0x00131e0f, 0x01131e0e,
142 	0x01141d0e, 0x02151d0c, 0x02151d0c, 0x02161d0b, 0x03161c0b,
143 	0x03171c0a, 0x04171c09, 0x04181b09, 0x05181b08, 0x05191b07,
144 	0x06191a07, 0x061a1a06, 0x071a1906, 0x071b1905, 0x081b1805,
145 	0x091b1804, 0x091c1704, 0x0a1c1703, 0x0a1c1604, 0x0b1d1602,
146 	0x0c1d1502, 0x0c1d1502, 0x0d1d1402, 0x0e1d1401, 0x0e1e1301,
147 	0x0f1e1300, 0x101e1200,
148 	/* counter = 15 */
149 	0x00111e11, 0x00121e10, 0x00131d10, 0x01131d0f, 0x01141d0e,
150 	0x01141d0e, 0x02151c0d, 0x02151c0d, 0x03161c0b, 0x03161c0b,
151 	0x04171b0a, 0x04171b0a, 0x05171b09, 0x05181a09, 0x06181a08,
152 	0x06191a07, 0x07191907, 0x071a1906, 0x081a1806, 0x081a1806,
153 	0x091a1805, 0x0a1b1704, 0x0a1b1704, 0x0b1c1603, 0x0b1c1603,
154 	0x0c1c1503, 0x0d1c1502, 0x0d1d1402, 0x0e1d1401, 0x0f1d1301,
155 	0x0f1d1301, 0x101e1200,
156 	/* counter = 16 */
157 };
158 
scal_rcq_setup(struct scaler_submodule * p_scal,u8 __iomem * base,struct g2d_rcq_mem_info * p_rcq_info)159 static int scal_rcq_setup(struct scaler_submodule *p_scal, u8 __iomem *base,
160 			  struct g2d_rcq_mem_info *p_rcq_info)
161 {
162 	u8 __iomem *reg_base = base + G2D_VSU;
163 	int ret = -1;
164 
165 	if (!p_scal) {
166 		G2D_ERR_MSG("Null pointer!\n");
167 		goto OUT;
168 	}
169 
170 	p_scal->reg_info->size = sizeof(struct g2d_mixer_video_scaler_reg);
171 	p_scal->reg_info->vir_addr = (u8 *)g2d_top_reg_memory_alloc(
172 	    p_scal->reg_info->size, (void *)&(p_scal->reg_info->phy_addr),
173 	    p_rcq_info);
174 
175 	if (!p_scal->reg_info->vir_addr) {
176 		G2D_ERR_MSG("Malloc scaler reg rcq memory fail!\n");
177 		goto OUT;
178 	}
179 
180 	p_scal->reg_blks->vir_addr = p_scal->reg_info->vir_addr;
181 	p_scal->reg_blks->phy_addr = p_scal->reg_info->phy_addr;
182 	p_scal->reg_blks->size = p_scal->reg_info->size;
183 	p_scal->reg_blks->reg_addr = reg_base;
184 	ret = 0;
185 
186 OUT:
187 	return ret;
188 }
189 
scal_get_reg_block_num(struct scaler_submodule * p_scal)190 static __u32 scal_get_reg_block_num(struct scaler_submodule *p_scal)
191 {
192 	if (p_scal)
193 		return p_scal->reg_blk_num;
194 	return 0;
195 }
196 
scal_get_reg_block(struct scaler_submodule * p_scal,struct g2d_reg_block ** blks)197 static __s32 scal_get_reg_block(struct scaler_submodule *p_scal,
198 			    struct g2d_reg_block **blks)
199 {
200 	__s32 i = 0, ret = -1;
201 	if (p_scal) {
202 		for (i = 0; i < p_scal->reg_blk_num; ++i)
203 			blks[i] = p_scal->reg_blks + i;
204 		ret = 0;
205 	}
206 
207 	return ret;
208 }
209 
scal_get_reg(struct scaler_submodule * p_scal)210 static struct g2d_mixer_video_scaler_reg *scal_get_reg(struct scaler_submodule *p_scal)
211 {
212 
213 #if G2D_MIXER_RCQ_USED == 1
214 	return (struct g2d_mixer_video_scaler_reg *)(p_scal->reg_blks
215 						     ->vir_addr);
216 #else
217 	return (struct g2d_mixer_video_scaler_reg *)(p_scal->reg_blks
218 						     ->reg_addr);
219 #endif
220 
221 	return NULL;
222 }
223 
scal_set_block_dirty(struct scaler_submodule * p_scal,__u32 blk_id,__u32 dirty)224 static void scal_set_block_dirty(struct scaler_submodule *p_scal, __u32 blk_id, __u32 dirty)
225 {
226 #if G2D_MIXER_RCQ_USED == 1
227 	if (p_scal && p_scal->reg_blks->rcq_hd)
228 		p_scal->reg_blks->rcq_hd->dirty.bits.dirty = dirty;
229 	else
230 		G2D_ERR_MSG("Null pointer!\n");
231 #else
232 
233 	if (p_scal)
234 		p_scal->reg_blks->dirty = dirty;
235 	else
236 		G2D_ERR_MSG("Null pointer!\n");
237 #endif
238 }
239 
240 /**
241  * function       : g2d_vsu_calc_fir_coef(unsigned int step)
242  * description    : set fir coefficients
243  * parameters     :
244  *                  step		<horizontal scale ratio of vsu>
245  * return         :
246  *                  offset (in word) of coefficient table
247  */
g2d_vsu_calc_fir_coef(__u32 step)248 static __u32 g2d_vsu_calc_fir_coef(__u32 step)
249 {
250 	__u32 pt_coef;
251 	__u32 scale_ratio, int_part, float_part, fir_coef_ofst;
252 
253 	scale_ratio = step >> (VSU_PHASE_FRAC_BITWIDTH - 3);
254 	int_part = scale_ratio >> 3;
255 	float_part = scale_ratio & 0x7;
256 	fir_coef_ofst = (int_part == 0) ? VSU_ZOOM0_SIZE :
257 	    (int_part == 1) ? VSU_ZOOM0_SIZE + float_part :
258 	    (int_part ==
259 	     2) ? VSU_ZOOM0_SIZE + VSU_ZOOM1_SIZE +
260 	    (float_part >> 1) : (int_part ==
261 				  3) ? VSU_ZOOM0_SIZE + VSU_ZOOM1_SIZE +
262 	    VSU_ZOOM2_SIZE : (int_part ==
263 			       4) ? VSU_ZOOM0_SIZE + VSU_ZOOM1_SIZE +
264 	    VSU_ZOOM2_SIZE + VSU_ZOOM3_SIZE : VSU_ZOOM0_SIZE +
265 	    VSU_ZOOM1_SIZE + VSU_ZOOM2_SIZE + VSU_ZOOM3_SIZE + VSU_ZOOM4_SIZE;
266 	pt_coef = fir_coef_ofst * VSU_PHASE_NUM;
267 	return pt_coef;
268 }
269 
g2d_vsu_para_set(struct scaler_submodule * p_scal,__u32 fmt,__u32 in_w,__u32 in_h,__u32 out_w,__u32 out_h,__u8 alpha)270 __s32 g2d_vsu_para_set(struct scaler_submodule *p_scal, __u32 fmt, __u32 in_w,
271 		       __u32 in_h, __u32 out_w, __u32 out_h, __u8 alpha)
272 {
273 	__u64 temp;
274 	__u32 yhstep, yvstep;
275 	__u32 incw, inch;
276 	__u32 yhcoef_offset, yvcoef_offset, chcoef_offset;
277 	__u32 format;
278 	__s32 ret = -1;
279 
280 	struct g2d_mixer_video_scaler_reg *p_reg = NULL;
281 	p_reg = p_scal->get_reg(p_scal);
282 	if (!p_reg)
283 		goto OUT;
284 
285 	p_reg->vs_ctrl.bits.coef_access_sel = 1;
286 	p_reg->vs_ctrl.bits.en = 1;
287 	if (fmt > G2D_FORMAT_IYUV422_Y1U0Y0V0)
288 		p_reg->vs_ctrl.bits.filter_type = 1;
289 	else
290 		p_reg->vs_ctrl.bits.filter_type = 0;
291 
292 	p_reg->out_size.bits.out_width = out_w - 1;
293 	p_reg->out_size.bits.out_height = out_h - 1;
294 	p_reg->glb_alpha.bits.glb_alpha = alpha;
295 
296 	p_reg->y_ch_size.bits.y_width = in_w - 1;
297 	p_reg->y_ch_size.bits.y_height = in_h - 1;
298 
299 	temp = in_w << VSU_PHASE_FRAC_BITWIDTH;
300 	if (out_w)
301 		do_div(temp, out_w);
302 	else
303 		temp = 0;
304 
305 	yhstep = temp;
306 	p_reg->y_hor_step.dwval = yhstep << 1;
307 	temp = in_h << VSU_PHASE_FRAC_BITWIDTH;
308 	if (out_h)
309 		do_div(temp, out_h);
310 	else
311 		temp = 0;
312 	yvstep = temp;
313 	p_reg->y_ver_step.dwval = yvstep << 1;
314 
315 	yhcoef_offset = g2d_vsu_calc_fir_coef(yhstep);
316 	memcpy(&p_reg->vs_y_ch_hor_filter_coef[0],
317 	       &lan2coefftab32_full[yhcoef_offset], VSU_PHASE_NUM * sizeof(unsigned int));
318 
319 	yvcoef_offset = g2d_vsu_calc_fir_coef(yvstep);
320 	switch (fmt) {
321 	case G2D_FORMAT_Y8:
322 		format = VSU_FORMAT_RGB;
323 		incw = (in_w + 1) >> 1;
324 		inch = in_h;
325 		p_reg->c_ch_size.bits.y_width = 0;
326 		p_reg->c_ch_size.bits.y_height = 0;
327 		p_reg->c_hor_step.dwval = 0;
328 		p_reg->c_ver_step.dwval = 0;
329 		memcpy(&p_reg->vs_y_ch_ver_filter_coef[0],
330 		       &linearcoefftab32[0],
331 		       VSU_PHASE_NUM * sizeof(unsigned int));
332 		p_reg->y_hor_phase.dwval = 0;
333 		p_reg->y_ver_phase.dwval = 0x0;
334 		p_reg->y_ver_phase.bits.integer =
335 		    ((in_h / out_h) < 3) ? 0 : (in_h / out_h - 3);
336 		p_reg->c_hor_phase.dwval = 0;
337 		p_reg->c_ver_phase.dwval = 0;
338 		break;
339 	case G2D_FORMAT_IYUV422_V0Y1U0Y0:
340 	case G2D_FORMAT_IYUV422_Y1V0Y0U0:
341 	case G2D_FORMAT_IYUV422_U0Y1V0Y0:
342 	case G2D_FORMAT_IYUV422_Y1U0Y0V0:{
343 			incw = (in_w + 1) >> 1;
344 			inch = in_h;
345 			format = VSU_FORMAT_YUV422;
346 			p_reg->c_ch_size.bits.y_width = incw - 1;
347 			p_reg->c_ch_size.bits.y_height = inch - 1;
348 
349 			    /* chstep = yhstep>>1 cvstep = yvstep */
350 			p_reg->c_hor_step.dwval = yhstep;
351 			p_reg->c_ver_step.dwval = yvstep << 1;
352 			chcoef_offset = g2d_vsu_calc_fir_coef(yhstep >> 1);
353 			memcpy(&p_reg->vs_c_ch_hor_filter_coef[0],
354 			       &lan2coefftab32_full[chcoef_offset],
355 			       VSU_PHASE_NUM * sizeof(unsigned int));
356 			memcpy(&p_reg->vs_y_ch_ver_filter_coef[0],
357 			       &linearcoefftab32[0],
358 			       VSU_PHASE_NUM * sizeof(unsigned int));
359 			break;
360 		}
361 	case G2D_FORMAT_YUV422UVC_V1U1V0U0:
362 	case G2D_FORMAT_YUV422UVC_U1V1U0V0:
363 	case G2D_FORMAT_YUV422_PLANAR:{
364 			incw = (in_w + 1) >> 1;
365 			inch = in_h;
366 			format = VSU_FORMAT_YUV422;
367 			p_reg->c_ch_size.bits.y_width = incw - 1;
368 			p_reg->c_ch_size.bits.y_height = inch - 1;
369 
370 			    /* chstep = yhstep>>1 cvstep = yvstep>>1 */
371 			p_reg->c_hor_step.dwval = yhstep;
372 			p_reg->c_ver_step.dwval = yvstep << 1;
373 			chcoef_offset = g2d_vsu_calc_fir_coef(yhstep >> 1);
374 
375 			memcpy(&p_reg->vs_c_ch_hor_filter_coef[0],
376 			       &lan2coefftab32_full[chcoef_offset],
377 			       VSU_PHASE_NUM * sizeof(unsigned int));
378 
379 			memcpy(&p_reg->vs_y_ch_ver_filter_coef[0],
380 			       &lan2coefftab32_full[yvcoef_offset],
381 			       VSU_PHASE_NUM * sizeof(unsigned int));
382 			break;
383 		}
384 	case G2D_FORMAT_YUV420_PLANAR:
385 	case G2D_FORMAT_YUV420UVC_V1U1V0U0:
386 	case G2D_FORMAT_YUV420UVC_U1V1U0V0:{
387 			incw = (in_w + 1) >> 1;
388 			inch = (in_h + 1) >> 1;
389 			format = VSU_FORMAT_YUV420;
390 			p_reg->c_ch_size.bits.y_width = incw - 1;
391 			p_reg->c_ch_size.bits.y_height = inch - 1;
392 
393 			    /* chstep = yhstep>>1 cvstep = yvstep>>1 */
394 			p_reg->c_hor_step.dwval = yhstep;
395 			p_reg->c_ver_step.dwval = yvstep;
396 
397 			chcoef_offset = g2d_vsu_calc_fir_coef(yhstep >> 1);
398 
399 			memcpy(&p_reg->vs_c_ch_hor_filter_coef[0],
400 			       &lan2coefftab32_full[chcoef_offset],
401 			       VSU_PHASE_NUM * sizeof(unsigned int));
402 			memcpy(&p_reg->vs_y_ch_ver_filter_coef[0],
403 			       &lan2coefftab32_full[yvcoef_offset],
404 			       VSU_PHASE_NUM * sizeof(unsigned int));
405 			break;
406 		}
407 	case G2D_FORMAT_YUV411_PLANAR:
408 	case G2D_FORMAT_YUV411UVC_V1U1V0U0:
409 	case G2D_FORMAT_YUV411UVC_U1V1U0V0:{
410 			incw = (in_w + 3) >> 2;
411 			inch = in_h;
412 			format = VSU_FORMAT_YUV411;
413 			p_reg->c_ch_size.bits.y_width = incw - 1;
414 			p_reg->c_ch_size.bits.y_height = inch - 1;
415 
416 			    /* chstep = yhstep>>2 cvstep = yvstep */
417 			p_reg->c_hor_step.dwval = yhstep >> 1;
418 			p_reg->c_ver_step.dwval = yvstep << 1;
419 
420 			chcoef_offset = g2d_vsu_calc_fir_coef(yhstep >> 2);
421 			memcpy(&p_reg->vs_c_ch_hor_filter_coef[0],
422 			       &lan2coefftab32_full[chcoef_offset],
423 			       VSU_PHASE_NUM * sizeof(unsigned int));
424 
425 			memcpy(&p_reg->vs_y_ch_ver_filter_coef[0],
426 			       &lan2coefftab32_full[yvcoef_offset],
427 			       VSU_PHASE_NUM * sizeof(unsigned int));
428 
429 			break;
430 		}
431 	default:
432 		format = VSU_FORMAT_RGB;
433 		incw = in_w;
434 		inch = in_h;
435 		p_reg->c_ch_size.bits.y_width = incw - 1;
436 		p_reg->c_ch_size.bits.y_height = inch - 1;
437 
438 		p_reg->c_hor_step.dwval = yhstep << 1;
439 		p_reg->c_ver_step.dwval = yvstep << 1;
440 		    /* chstep = yhstep cvstep = yvstep */
441 		chcoef_offset = g2d_vsu_calc_fir_coef(yhstep);
442 
443 		memcpy(&p_reg->vs_c_ch_hor_filter_coef[0],
444 		       &lan2coefftab32_full[chcoef_offset],
445 		       VSU_PHASE_NUM * sizeof(unsigned int));
446 
447 		memcpy(&p_reg->vs_y_ch_ver_filter_coef[0],
448 		       &linearcoefftab32[0],
449 		       VSU_PHASE_NUM * sizeof(unsigned int));
450 
451 		break;
452 	}
453 	if (format == VSU_FORMAT_YUV420) {
454 		/**
455 		 * yhphase = 0;
456 		 * yvphase = 0;
457 		 * chphase = 0xFFFE0000;
458 		 * cvphase = 0xFFFE0000;
459 		 */
460 		p_reg->y_hor_phase.dwval = 0;
461 		p_reg->y_ver_phase.dwval = 0;
462 		p_reg->c_hor_phase.dwval = 0xFFFc0000;
463 		p_reg->c_ver_phase.dwval = 0xFFFc0000;
464 	} else if (fmt != G2D_FORMAT_Y8) {
465 		p_reg->y_hor_phase.dwval = 0;
466 		p_reg->y_ver_phase.dwval = 0;
467 		p_reg->c_hor_phase.dwval = 0;
468 		p_reg->c_ver_phase.dwval = 0;
469 	}
470 
471 	ret = 0;
472 	p_scal->set_block_dirty(p_scal, 0, 1);
473 OUT:
474 	return ret;
475 }
476 
scal_get_rcq_mem_size(struct scaler_submodule * p_scal)477 static __u32 scal_get_rcq_mem_size(struct scaler_submodule *p_scal)
478 {
479 	return G2D_RCQ_BYTE_ALIGN(sizeof(struct g2d_mixer_video_scaler_reg));
480 }
481 
scal_destory(struct scaler_submodule * p_scal)482 static __s32 scal_destory(struct scaler_submodule *p_scal)
483 {
484 	__s32 ret = -1;
485 
486 	if (p_scal) {
487 		kfree(p_scal->reg_blks);
488 		p_scal->reg_blks = NULL;
489 
490 		kfree(p_scal->reg_info);
491 		p_scal->reg_info = NULL;
492 		kfree(p_scal);
493 		ret = 0;
494 	}
495 
496 	return ret;
497 }
498 
g2d_scaler_submodule_setup(struct g2d_mixer_frame * p_frame)499 struct scaler_submodule *g2d_scaler_submodule_setup(struct g2d_mixer_frame *p_frame)
500 {
501 	struct scaler_submodule *p_scal = NULL;
502 
503 	p_scal = kmalloc(sizeof(struct scaler_submodule), GFP_KERNEL | __GFP_ZERO);
504 
505 	if (!p_scal) {
506 		G2D_ERR_MSG("Kmalloc wb submodule fail!\n");
507 		return NULL;
508 	}
509 
510 	p_scal->rcq_setup = scal_rcq_setup;
511 	p_scal->reg_blk_num = 1;
512 	p_scal->get_reg_block_num = scal_get_reg_block_num;
513 	p_scal->get_reg_block = scal_get_reg_block;
514 	p_scal->get_reg = scal_get_reg;
515 	p_scal->set_block_dirty = scal_set_block_dirty;
516 	p_scal->get_rcq_mem_size = scal_get_rcq_mem_size;
517 	p_scal->destory = scal_destory;
518 
519 	p_scal->reg_blks =
520 	    kmalloc(sizeof(struct g2d_reg_block) * p_scal->reg_blk_num,
521 		    GFP_KERNEL | __GFP_ZERO);
522 	p_scal->reg_info =
523 	    kmalloc(sizeof(struct g2d_reg_mem_info), GFP_KERNEL | __GFP_ZERO);
524 
525 	if (!p_scal->reg_blks || !p_scal->reg_info) {
526 		G2D_ERR_MSG("Kmalloc wb reg info fail!\n");
527 		goto FREE_WB;
528 	}
529 
530 
531 	return p_scal;
532 FREE_WB:
533 	kfree(p_scal->reg_blks);
534 	kfree(p_scal->reg_info);
535 	kfree(p_scal);
536 
537 	return NULL;
538 }
539