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