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