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