• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * drivers/amlogic/amports/encoder.c
3  *
4  * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16 */
17 
18 #include <linux/kernel.h>
19 #include <linux/types.h>
20 #include <linux/errno.h>
21 #include <linux/interrupt.h>
22 #include <linux/timer.h>
23 #include <linux/fs.h>
24 #include <linux/sched.h>
25 #include <linux/slab.h>
26 #include <linux/dma-mapping.h>
27 #include <linux/platform_device.h>
28 #include <linux/spinlock.h>
29 #include <linux/ctype.h>
30 #include <uapi/linux/sched/types.h>
31 
32 #include <linux/amlogic/media/frame_sync/ptsserv.h>
33 #include <linux/amlogic/media/utils/amstream.h>
34 #include <linux/amlogic/media/canvas/canvas.h>
35 #include <linux/amlogic/media/canvas/canvas_mgr.h>
36 #include <linux/amlogic/media/codec_mm/codec_mm.h>
37 
38 #include <linux/amlogic/media/utils/vdec_reg.h>
39 #include "../../../frame_provider/decoder/utils/vdec.h"
40 #include <linux/delay.h>
41 #include <linux/poll.h>
42 #include <linux/of.h>
43 #include <linux/of_fdt.h>
44 #include <linux/dma-map-ops.h>
45 #include <linux/kthread.h>
46 #include <linux/sched/rt.h>
47 #include <linux/amlogic/media/utils/amports_config.h>
48 #include "encoder.h"
49 #include "../../../frame_provider/decoder/utils/amvdec.h"
50 #include <linux/amlogic/media/utils/amlog.h>
51 #include "../../../stream_input/amports/amports_priv.h"
52 #include "../../../frame_provider/decoder/utils/firmware.h"
53 #include <linux/of_reserved_mem.h>
54 
55 
56 #ifdef CONFIG_AM_JPEG_ENCODER
57 #include "jpegenc.h"
58 #endif
59 
60 #define ENCODE_NAME "encoder"
61 #define AMVENC_CANVAS_INDEX 0xE4
62 #define AMVENC_CANVAS_MAX_INDEX 0xEF
63 
64 #define MIN_SIZE amvenc_buffspec[0].min_buffsize
65 #define DUMP_INFO_BYTES_PER_MB 80
66 
67 #define ADJUSTED_QP_FLAG 64
68 
69 static s32 avc_device_major;
70 static struct device *amvenc_avc_dev;
71 #define DRIVER_NAME "amvenc_avc"
72 #define CLASS_NAME "amvenc_avc"
73 #define DEVICE_NAME "amvenc_avc"
74 
75 static struct encode_manager_s encode_manager;
76 
77 #define MULTI_SLICE_MC
78 #define H264_ENC_CBR
79 /* #define MORE_MODULE_PARAM */
80 
81 #define ENC_CANVAS_OFFSET  AMVENC_CANVAS_INDEX
82 
83 #define UCODE_MODE_FULL 0
84 
85 /* #define ENABLE_IGNORE_FUNCTION */
86 
87 static u32 ie_me_mb_type;
88 static u32 ie_me_mode;
89 static u32 ie_pippeline_block = 3;
90 static u32 ie_cur_ref_sel;
91 /* static u32 avc_endian = 6; */
92 static u32 clock_level = 5;
93 
94 static u32 encode_print_level = LOG_DEBUG;
95 static u32 no_timeout;
96 static int nr_mode = -1;
97 static u32 qp_table_debug;
98 
99 #ifdef H264_ENC_SVC
100 static u32 svc_enable = 0; /* Enable sac feature or not */
101 static u32 svc_ref_conf = 0; /* Continuous no reference numbers */
102 #endif
103 
104 static u32 me_mv_merge_ctl =
105 	(0x1 << 31)  |  /* [31] me_merge_mv_en_16 */
106 	(0x1 << 30)  |  /* [30] me_merge_small_mv_en_16 */
107 	(0x1 << 29)  |  /* [29] me_merge_flex_en_16 */
108 	(0x1 << 28)  |  /* [28] me_merge_sad_en_16 */
109 	(0x1 << 27)  |  /* [27] me_merge_mv_en_8 */
110 	(0x1 << 26)  |  /* [26] me_merge_small_mv_en_8 */
111 	(0x1 << 25)  |  /* [25] me_merge_flex_en_8 */
112 	(0x1 << 24)  |  /* [24] me_merge_sad_en_8 */
113 	/* [23:18] me_merge_mv_diff_16 - MV diff <= n pixel can be merged */
114 	(0x12 << 18) |
115 	/* [17:12] me_merge_mv_diff_8 - MV diff <= n pixel can be merged */
116 	(0x2b << 12) |
117 	/* [11:0] me_merge_min_sad - SAD >= 0x180 can be merged with other MV */
118 	(0x80 << 0);
119 	/* ( 0x4 << 18)  |
120 	 * // [23:18] me_merge_mv_diff_16 - MV diff <= n pixel can be merged
121 	 */
122 	/* ( 0x3f << 12)  |
123 	 * // [17:12] me_merge_mv_diff_8 - MV diff <= n pixel can be merged
124 	 */
125 	/* ( 0xc0 << 0);
126 	 * // [11:0] me_merge_min_sad - SAD >= 0x180 can be merged with other MV
127 	 */
128 
129 static u32 me_mv_weight_01 = (0x40 << 24) | (0x30 << 16) | (0x20 << 8) | 0x30;
130 static u32 me_mv_weight_23 = (0x40 << 8) | 0x30;
131 static u32 me_sad_range_inc = 0x03030303;
132 static u32 me_step0_close_mv = 0x003ffc21;
133 static u32 me_f_skip_sad;
134 static u32 me_f_skip_weight;
135 static u32 me_sad_enough_01;/* 0x00018010; */
136 static u32 me_sad_enough_23;/* 0x00000020; */
137 
138 /* [31:0] NUM_ROWS_PER_SLICE_P */
139 /* [15:0] NUM_ROWS_PER_SLICE_I */
140 static u32 fixed_slice_cfg;
141 
142 /* y tnr */
143 static unsigned int y_tnr_mc_en = 1;
144 static unsigned int y_tnr_txt_mode;
145 static unsigned int y_tnr_mot_sad_margin = 1;
146 static unsigned int y_tnr_mot_cortxt_rate = 1;
147 static unsigned int y_tnr_mot_distxt_ofst = 5;
148 static unsigned int y_tnr_mot_distxt_rate = 4;
149 static unsigned int y_tnr_mot_dismot_ofst = 4;
150 static unsigned int y_tnr_mot_frcsad_lock = 8;
151 static unsigned int y_tnr_mot2alp_frc_gain = 10;
152 static unsigned int y_tnr_mot2alp_nrm_gain = 216;
153 static unsigned int y_tnr_mot2alp_dis_gain = 128;
154 static unsigned int y_tnr_mot2alp_dis_ofst = 32;
155 static unsigned int y_tnr_alpha_min = 32;
156 static unsigned int y_tnr_alpha_max = 63;
157 static unsigned int y_tnr_deghost_os;
158 /* c tnr */
159 static unsigned int c_tnr_mc_en = 1;
160 static unsigned int c_tnr_txt_mode;
161 static unsigned int c_tnr_mot_sad_margin = 1;
162 static unsigned int c_tnr_mot_cortxt_rate = 1;
163 static unsigned int c_tnr_mot_distxt_ofst = 5;
164 static unsigned int c_tnr_mot_distxt_rate = 4;
165 static unsigned int c_tnr_mot_dismot_ofst = 4;
166 static unsigned int c_tnr_mot_frcsad_lock = 8;
167 static unsigned int c_tnr_mot2alp_frc_gain = 10;
168 static unsigned int c_tnr_mot2alp_nrm_gain = 216;
169 static unsigned int c_tnr_mot2alp_dis_gain = 128;
170 static unsigned int c_tnr_mot2alp_dis_ofst = 32;
171 static unsigned int c_tnr_alpha_min = 32;
172 static unsigned int c_tnr_alpha_max = 63;
173 static unsigned int c_tnr_deghost_os;
174 /* y snr */
175 static unsigned int y_snr_err_norm = 1;
176 static unsigned int y_snr_gau_bld_core = 1;
177 static int y_snr_gau_bld_ofst = -1;
178 static unsigned int y_snr_gau_bld_rate = 48;
179 static unsigned int y_snr_gau_alp0_min;
180 static unsigned int y_snr_gau_alp0_max = 63;
181 static unsigned int y_bld_beta2alp_rate = 16;
182 static unsigned int y_bld_beta_min;
183 static unsigned int y_bld_beta_max = 63;
184 /* c snr */
185 static unsigned int c_snr_err_norm = 1;
186 static unsigned int c_snr_gau_bld_core = 1;
187 static int c_snr_gau_bld_ofst = -1;
188 static unsigned int c_snr_gau_bld_rate = 48;
189 static unsigned int c_snr_gau_alp0_min;
190 static unsigned int c_snr_gau_alp0_max = 63;
191 static unsigned int c_bld_beta2alp_rate = 16;
192 static unsigned int c_bld_beta_min;
193 static unsigned int c_bld_beta_max = 63;
194 static unsigned int qp_mode;
195 
196 static DEFINE_SPINLOCK(lock);
197 
198 #define ADV_MV_LARGE_16x8 1
199 #define ADV_MV_LARGE_8x16 1
200 #define ADV_MV_LARGE_16x16 1
201 
202 /* me weight offset should not very small, it used by v1 me module. */
203 /* the min real sad for me is 16 by hardware. */
204 #define ME_WEIGHT_OFFSET 0x520
205 #define I4MB_WEIGHT_OFFSET 0x655
206 #define I16MB_WEIGHT_OFFSET 0x560
207 
208 #define ADV_MV_16x16_WEIGHT 0x080
209 #define ADV_MV_16_8_WEIGHT 0x0e0
210 #define ADV_MV_8x8_WEIGHT 0x240
211 #define ADV_MV_4x4x4_WEIGHT 0x3000
212 
213 #define IE_SAD_SHIFT_I16 0x001
214 #define IE_SAD_SHIFT_I4 0x001
215 #define ME_SAD_SHIFT_INTER 0x001
216 
217 #define STEP_2_SKIP_SAD 0
218 #define STEP_1_SKIP_SAD 0
219 #define STEP_0_SKIP_SAD 0
220 #define STEP_2_SKIP_WEIGHT 0
221 #define STEP_1_SKIP_WEIGHT 0
222 #define STEP_0_SKIP_WEIGHT 0
223 
224 #define ME_SAD_RANGE_0 0x1 /* 0x0 */
225 #define ME_SAD_RANGE_1 0x0
226 #define ME_SAD_RANGE_2 0x0
227 #define ME_SAD_RANGE_3 0x0
228 
229 /* use 0 for v3, 0x18 for v2 */
230 #define ME_MV_PRE_WEIGHT_0 0x18
231 /* use 0 for v3, 0x18 for v2 */
232 #define ME_MV_PRE_WEIGHT_1 0x18
233 #define ME_MV_PRE_WEIGHT_2 0x0
234 #define ME_MV_PRE_WEIGHT_3 0x0
235 
236 /* use 0 for v3, 0x18 for v2 */
237 #define ME_MV_STEP_WEIGHT_0 0x18
238 /* use 0 for v3, 0x18 for v2 */
239 #define ME_MV_STEP_WEIGHT_1 0x18
240 #define ME_MV_STEP_WEIGHT_2 0x0
241 #define ME_MV_STEP_WEIGHT_3 0x0
242 
243 #define ME_SAD_ENOUGH_0_DATA 0x00
244 #define ME_SAD_ENOUGH_1_DATA 0x04
245 #define ME_SAD_ENOUGH_2_DATA 0x11
246 #define ADV_MV_8x8_ENOUGH_DATA 0x20
247 
248 /* V4_COLOR_BLOCK_FIX */
249 #define V3_FORCE_SKIP_SAD_0 0x10
250 /* 4 Blocks */
251 #define V3_FORCE_SKIP_SAD_1 0x60
252 /* 16 Blocks + V3_SKIP_WEIGHT_2 */
253 #define V3_FORCE_SKIP_SAD_2 0x250
254 /* almost disable it -- use t_lac_coeff_2 output to F_ZERO is better */
255 #define V3_ME_F_ZERO_SAD (ME_WEIGHT_OFFSET + 0x10)
256 
257 #define V3_IE_F_ZERO_SAD_I16 (I16MB_WEIGHT_OFFSET + 0x10)
258 #define V3_IE_F_ZERO_SAD_I4 (I4MB_WEIGHT_OFFSET + 0x20)
259 
260 #define V3_SKIP_WEIGHT_0 0x10
261 /* 4 Blocks  8 separate search sad can be very low */
262 #define V3_SKIP_WEIGHT_1 0x8 /* (4 * ME_MV_STEP_WEIGHT_1 + 0x100) */
263 #define V3_SKIP_WEIGHT_2 0x3
264 
265 #define V3_LEVEL_1_F_SKIP_MAX_SAD 0x0
266 #define V3_LEVEL_1_SKIP_MAX_SAD 0x6
267 
268 #define I4_ipred_weight_most   0x18
269 #define I4_ipred_weight_else   0x28
270 
271 #define C_ipred_weight_V       0x04
272 #define C_ipred_weight_H       0x08
273 #define C_ipred_weight_DC      0x0c
274 
275 #define I16_ipred_weight_V       0x04
276 #define I16_ipred_weight_H       0x08
277 #define I16_ipred_weight_DC      0x0c
278 
279 /* 0x00 same as disable */
280 #define v3_left_small_max_ie_sad 0x00
281 #define v3_left_small_max_me_sad 0x40
282 
283 #define v5_use_small_diff_cnt 0
284 #define v5_simple_mb_inter_all_en 1
285 #define v5_simple_mb_inter_8x8_en 1
286 #define v5_simple_mb_inter_16_8_en 1
287 #define v5_simple_mb_inter_16x16_en 1
288 #define v5_simple_mb_intra_en 1
289 #define v5_simple_mb_C_en 0
290 #define v5_simple_mb_Y_en 1
291 #define v5_small_diff_Y 0x10
292 #define v5_small_diff_C 0x18
293 /* shift 8-bits, 2, 1, 0, -1, -2, -3, -4 */
294 #define v5_simple_dq_setting 0x43210fed
295 #define v5_simple_me_weight_setting 0
296 
297 #ifdef H264_ENC_CBR
298 #define CBR_TABLE_SIZE  0x800
299 #define CBR_SHORT_SHIFT 12 /* same as disable */
300 #define CBR_LONG_MB_NUM 2
301 #define START_TABLE_ID 8
302 #define CBR_LONG_THRESH 4
303 #endif
304 
305 static u32 v3_mv_sad[64] = {
306 	/* For step0 */
307 	0x00000004,
308 	0x00010008,
309 	0x00020010,
310 	0x00030018,
311 	0x00040020,
312 	0x00050028,
313 	0x00060038,
314 	0x00070048,
315 	0x00080058,
316 	0x00090068,
317 	0x000a0080,
318 	0x000b0098,
319 	0x000c00b0,
320 	0x000d00c8,
321 	0x000e00e8,
322 	0x000f0110,
323 	/* For step1 */
324 	0x00100002,
325 	0x00110004,
326 	0x00120008,
327 	0x0013000c,
328 	0x00140010,
329 	0x00150014,
330 	0x0016001c,
331 	0x00170024,
332 	0x0018002c,
333 	0x00190034,
334 	0x001a0044,
335 	0x001b0054,
336 	0x001c0064,
337 	0x001d0074,
338 	0x001e0094,
339 	0x001f00b4,
340 	/* For step2 */
341 	0x00200006,
342 	0x0021000c,
343 	0x0022000c,
344 	0x00230018,
345 	0x00240018,
346 	0x00250018,
347 	0x00260018,
348 	0x00270030,
349 	0x00280030,
350 	0x00290030,
351 	0x002a0030,
352 	0x002b0030,
353 	0x002c0030,
354 	0x002d0030,
355 	0x002e0030,
356 	0x002f0050,
357 	/* For step2 4x4-8x8 */
358 	0x00300001,
359 	0x00310002,
360 	0x00320002,
361 	0x00330004,
362 	0x00340004,
363 	0x00350004,
364 	0x00360004,
365 	0x00370006,
366 	0x00380006,
367 	0x00390006,
368 	0x003a0006,
369 	0x003b0006,
370 	0x003c0006,
371 	0x003d0006,
372 	0x003e0006,
373 	0x003f0006
374 };
375 
376 static struct BuffInfo_s amvenc_buffspec[] = {
377 	{
378 		.lev_id = 0,
379 		.max_width = 1920,
380 		.max_height = 1088,
381 		.min_buffsize = 0x1400000,
382 		.dct = {
383 			.buf_start = 0,
384 			.buf_size = 0x800000, /* 1920x1088x4 */
385 		},
386 		.dec0_y = {
387 			.buf_start = 0x800000,
388 			.buf_size = 0x300000,
389 		},
390 		.dec1_y = {
391 			.buf_start = 0xb00000,
392 			.buf_size = 0x300000,
393 		},
394 		.assit = {
395 			.buf_start = 0xe10000,
396 			.buf_size = 0xc0000,
397 		},
398 		.bitstream = {
399 			.buf_start = 0xf00000,
400 			.buf_size = 0x100000,
401 		},
402 		.scale_buff = {
403 			.buf_start = 0x1000000,
404 			.buf_size = 0x300000,
405 		},
406 		.dump_info = {
407 			.buf_start = 0x1300000,
408 			.buf_size = 0xa0000, /* (1920x1088/256)x80 */
409 		},
410 		.cbr_info = {
411 			.buf_start = 0x13b0000,
412 			.buf_size = 0x2000,
413 		}
414 	}
415 };
416 
417 enum ucode_type_e {
418 	UCODE_GXL,
419 	UCODE_TXL,
420 	UCODE_G12A,
421 	UCODE_MAX
422 };
423 
424 const char *ucode_name[] = {
425 	"gxl_h264_enc",
426 	"txl_h264_enc_cavlc",
427 	"ga_h264_enc_cabac",
428 };
429 
430 static void dma_flush(u32 buf_start, u32 buf_size);
431 static void cache_flush(u32 buf_start, u32 buf_size);
432 static int enc_dma_buf_get_phys(struct enc_dma_cfg *cfg, unsigned long *addr);
433 static void enc_dma_buf_unmap(struct enc_dma_cfg *cfg);
434 
select_ucode(u32 ucode_index)435 static const char *select_ucode(u32 ucode_index)
436 {
437 	enum ucode_type_e ucode = UCODE_GXL;
438 
439 	switch (ucode_index) {
440 	case UCODE_MODE_FULL:
441 		if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A)
442 			ucode = UCODE_G12A;
443 		else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL)
444 			ucode = UCODE_TXL;
445 		else /* (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) */
446 			ucode = UCODE_GXL;
447 		break;
448 		break;
449 	default:
450 		break;
451 	}
452 	return (const char *)ucode_name[ucode];
453 }
454 
hcodec_prog_qtbl(struct encode_wq_s * wq)455 static void hcodec_prog_qtbl(struct encode_wq_s *wq)
456 {
457 	WRITE_HREG(HCODEC_Q_QUANT_CONTROL,
458 		(0 << 23) |  /* quant_table_addr */
459 		(1 << 22));  /* quant_table_addr_update */
460 
461 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
462 		wq->quant_tbl_i4[0]);
463 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
464 		wq->quant_tbl_i4[1]);
465 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
466 		wq->quant_tbl_i4[2]);
467 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
468 		wq->quant_tbl_i4[3]);
469 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
470 		wq->quant_tbl_i4[4]);
471 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
472 		wq->quant_tbl_i4[5]);
473 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
474 		wq->quant_tbl_i4[6]);
475 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
476 		wq->quant_tbl_i4[7]);
477 
478 	WRITE_HREG(HCODEC_Q_QUANT_CONTROL,
479 		(8 << 23) |  /* quant_table_addr */
480 		(1 << 22));  /* quant_table_addr_update */
481 
482 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
483 		wq->quant_tbl_i16[0]);
484 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
485 		wq->quant_tbl_i16[1]);
486 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
487 		wq->quant_tbl_i16[2]);
488 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
489 		wq->quant_tbl_i16[3]);
490 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
491 		wq->quant_tbl_i16[4]);
492 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
493 		wq->quant_tbl_i16[5]);
494 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
495 		wq->quant_tbl_i16[6]);
496 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
497 		wq->quant_tbl_i16[7]);
498 
499 	WRITE_HREG(HCODEC_Q_QUANT_CONTROL,
500 		(16 << 23) | /* quant_table_addr */
501 		(1 << 22));  /* quant_table_addr_update */
502 
503 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
504 		wq->quant_tbl_me[0]);
505 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
506 		wq->quant_tbl_me[1]);
507 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
508 		wq->quant_tbl_me[2]);
509 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
510 		wq->quant_tbl_me[3]);
511 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
512 		wq->quant_tbl_me[4]);
513 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
514 		wq->quant_tbl_me[5]);
515 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
516 		wq->quant_tbl_me[6]);
517 	WRITE_HREG(HCODEC_QUANT_TABLE_DATA,
518 		wq->quant_tbl_me[7]);
519 }
520 
InitEncodeWeight(void)521 static void InitEncodeWeight(void)
522 {
523 	me_mv_merge_ctl =
524 		(0x1 << 31)  |  /* [31] me_merge_mv_en_16 */
525 		(0x1 << 30)  |  /* [30] me_merge_small_mv_en_16 */
526 		(0x1 << 29)  |  /* [29] me_merge_flex_en_16 */
527 		(0x1 << 28)  |  /* [28] me_merge_sad_en_16 */
528 		(0x1 << 27)  |  /* [27] me_merge_mv_en_8 */
529 		(0x1 << 26)  |  /* [26] me_merge_small_mv_en_8 */
530 		(0x1 << 25)  |  /* [25] me_merge_flex_en_8 */
531 		(0x1 << 24)  |  /* [24] me_merge_sad_en_8 */
532 		(0x12 << 18) |
533 		/* [23:18] me_merge_mv_diff_16 - MV diff
534 		 *	<= n pixel can be merged
535 		 */
536 		(0x2b << 12) |
537 		/* [17:12] me_merge_mv_diff_8 - MV diff
538 		 *	<= n pixel can be merged
539 		 */
540 		(0x80 << 0);
541 		/* [11:0] me_merge_min_sad - SAD
542 		 *	>= 0x180 can be merged with other MV
543 		 */
544 
545 	me_mv_weight_01 = (ME_MV_STEP_WEIGHT_1 << 24) |
546 		(ME_MV_PRE_WEIGHT_1 << 16) |
547 		(ME_MV_STEP_WEIGHT_0 << 8) |
548 		(ME_MV_PRE_WEIGHT_0 << 0);
549 
550 	me_mv_weight_23 = (ME_MV_STEP_WEIGHT_3 << 24) |
551 		(ME_MV_PRE_WEIGHT_3  << 16) |
552 		(ME_MV_STEP_WEIGHT_2 << 8) |
553 		(ME_MV_PRE_WEIGHT_2  << 0);
554 
555 	me_sad_range_inc = (ME_SAD_RANGE_3 << 24) |
556 		(ME_SAD_RANGE_2 << 16) |
557 		(ME_SAD_RANGE_1 << 8) |
558 		(ME_SAD_RANGE_0 << 0);
559 
560 	me_step0_close_mv = (0x100 << 10) |
561 		/* me_step0_big_sad -- two MV sad
562 		 *  diff bigger will use use 1
563 		 */
564 		(2 << 5) | /* me_step0_close_mv_y */
565 		(2 << 0); /* me_step0_close_mv_x */
566 
567 	me_f_skip_sad = (0x00 << 24) | /* force_skip_sad_3 */
568 		(STEP_2_SKIP_SAD << 16) | /* force_skip_sad_2 */
569 		(STEP_1_SKIP_SAD << 8) | /* force_skip_sad_1 */
570 		(STEP_0_SKIP_SAD << 0); /* force_skip_sad_0 */
571 
572 	me_f_skip_weight = (0x00 << 24) | /* force_skip_weight_3 */
573 		/* force_skip_weight_2 */
574 		(STEP_2_SKIP_WEIGHT << 16) |
575 		/* force_skip_weight_1 */
576 		(STEP_1_SKIP_WEIGHT << 8) |
577 		/* force_skip_weight_0 */
578 		(STEP_0_SKIP_WEIGHT << 0);
579 
580 	if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) {
581 		me_f_skip_sad = 0;
582 		me_f_skip_weight = 0;
583 		me_mv_weight_01 = 0;
584 		me_mv_weight_23 = 0;
585 	}
586 
587 	me_sad_enough_01 = (ME_SAD_ENOUGH_1_DATA << 12) |
588 		/* me_sad_enough_1 */
589 		(ME_SAD_ENOUGH_0_DATA << 0) |
590 		/* me_sad_enough_0 */
591 		(0 << 12) | /* me_sad_enough_1 */
592 		(0 << 0); /* me_sad_enough_0 */
593 
594 	me_sad_enough_23 = (ADV_MV_8x8_ENOUGH_DATA << 12) |
595 		/* adv_mv_8x8_enough */
596 		(ME_SAD_ENOUGH_2_DATA << 0) |
597 		/* me_sad_enough_2 */
598 		(0 << 12) | /* me_sad_enough_3 */
599 		(0 << 0); /* me_sad_enough_2 */
600 }
601 
602 /*output stream buffer setting*/
avc_init_output_buffer(struct encode_wq_s * wq)603 static void avc_init_output_buffer(struct encode_wq_s *wq)
604 {
605 	WRITE_HREG(HCODEC_VLC_VB_MEM_CTL,
606 		((1 << 31) | (0x3f << 24) |
607 		(0x20 << 16) | (2 << 0)));
608 	WRITE_HREG(HCODEC_VLC_VB_START_PTR,
609 		wq->mem.BitstreamStart);
610 	WRITE_HREG(HCODEC_VLC_VB_WR_PTR,
611 		wq->mem.BitstreamStart);
612 	WRITE_HREG(HCODEC_VLC_VB_SW_RD_PTR,
613 		wq->mem.BitstreamStart);
614 	WRITE_HREG(HCODEC_VLC_VB_END_PTR,
615 		wq->mem.BitstreamEnd);
616 	WRITE_HREG(HCODEC_VLC_VB_CONTROL, 1);
617 	WRITE_HREG(HCODEC_VLC_VB_CONTROL,
618 		((0 << 14) | (7 << 3) |
619 		(1 << 1) | (0 << 0)));
620 }
621 
622 /*input dct buffer setting*/
avc_init_input_buffer(struct encode_wq_s * wq)623 static void avc_init_input_buffer(struct encode_wq_s *wq)
624 {
625 	WRITE_HREG(HCODEC_QDCT_MB_START_PTR,
626 		wq->mem.dct_buff_start_addr);
627 	WRITE_HREG(HCODEC_QDCT_MB_END_PTR,
628 		wq->mem.dct_buff_end_addr);
629 	WRITE_HREG(HCODEC_QDCT_MB_WR_PTR,
630 		wq->mem.dct_buff_start_addr);
631 	WRITE_HREG(HCODEC_QDCT_MB_RD_PTR,
632 		wq->mem.dct_buff_start_addr);
633 	WRITE_HREG(HCODEC_QDCT_MB_BUFF, 0);
634 }
635 
636 /*input reference buffer setting*/
avc_init_reference_buffer(s32 canvas)637 static void avc_init_reference_buffer(s32 canvas)
638 {
639 	WRITE_HREG(HCODEC_ANC0_CANVAS_ADDR, canvas);
640 	WRITE_HREG(HCODEC_VLC_HCMD_CONFIG, 0);
641 }
642 
avc_init_assit_buffer(struct encode_wq_s * wq)643 static void avc_init_assit_buffer(struct encode_wq_s *wq)
644 {
645 	WRITE_HREG(MEM_OFFSET_REG, wq->mem.assit_buffer_offset);
646 }
647 
648 /*deblock buffer setting, same as INI_CANVAS*/
avc_init_dblk_buffer(s32 canvas)649 static void avc_init_dblk_buffer(s32 canvas)
650 {
651 	WRITE_HREG(HCODEC_REC_CANVAS_ADDR, canvas);
652 	WRITE_HREG(HCODEC_DBKR_CANVAS_ADDR, canvas);
653 	WRITE_HREG(HCODEC_DBKW_CANVAS_ADDR, canvas);
654 }
655 
avc_init_encoder(struct encode_wq_s * wq,bool idr)656 static void avc_init_encoder(struct encode_wq_s *wq, bool idr)
657 {
658 	WRITE_HREG(HCODEC_VLC_TOTAL_BYTES, 0);
659 	WRITE_HREG(HCODEC_VLC_CONFIG, 0x07);
660 	WRITE_HREG(HCODEC_VLC_INT_CONTROL, 0);
661 
662 	WRITE_HREG(HCODEC_ASSIST_AMR1_INT0, 0x15);
663 	WRITE_HREG(HCODEC_ASSIST_AMR1_INT1, 0x8);
664 	WRITE_HREG(HCODEC_ASSIST_AMR1_INT3, 0x14);
665 
666 	WRITE_HREG(IDR_PIC_ID, wq->pic.idr_pic_id);
667 	WRITE_HREG(FRAME_NUMBER,
668 		(idr == true) ? 0 : wq->pic.frame_number);
669 	WRITE_HREG(PIC_ORDER_CNT_LSB,
670 		(idr == true) ? 0 : wq->pic.pic_order_cnt_lsb);
671 
672 	WRITE_HREG(LOG2_MAX_PIC_ORDER_CNT_LSB,
673 		wq->pic.log2_max_pic_order_cnt_lsb);
674 	WRITE_HREG(LOG2_MAX_FRAME_NUM,
675 		wq->pic.log2_max_frame_num);
676 	WRITE_HREG(ANC0_BUFFER_ID, 0);
677 	WRITE_HREG(QPPICTURE, wq->pic.init_qppicture);
678 }
679 
avc_canvas_init(struct encode_wq_s * wq)680 static void avc_canvas_init(struct encode_wq_s *wq)
681 {
682 	u32 canvas_width, canvas_height;
683 	u32 start_addr = wq->mem.buf_start;
684 
685 	canvas_width = ((wq->pic.encoder_width + 31) >> 5) << 5;
686 	canvas_height = ((wq->pic.encoder_height + 15) >> 4) << 4;
687 
688 	canvas_config(ENC_CANVAS_OFFSET,
689 	      start_addr + wq->mem.bufspec.dec0_y.buf_start,
690 	      canvas_width, canvas_height,
691 	      CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
692 	canvas_config(1 + ENC_CANVAS_OFFSET,
693 	      start_addr + wq->mem.bufspec.dec0_uv.buf_start,
694 	      canvas_width, canvas_height / 2,
695 	      CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
696 	/*here the third plane use the same address as the second plane*/
697 	canvas_config(2 + ENC_CANVAS_OFFSET,
698 	      start_addr + wq->mem.bufspec.dec0_uv.buf_start,
699 	      canvas_width, canvas_height / 2,
700 	      CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
701 
702 	canvas_config(3 + ENC_CANVAS_OFFSET,
703 	      start_addr + wq->mem.bufspec.dec1_y.buf_start,
704 	      canvas_width, canvas_height,
705 	      CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
706 	canvas_config(4 + ENC_CANVAS_OFFSET,
707 	      start_addr + wq->mem.bufspec.dec1_uv.buf_start,
708 	      canvas_width, canvas_height / 2,
709 	      CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
710 	/*here the third plane use the same address as the second plane*/
711 	canvas_config(5 + ENC_CANVAS_OFFSET,
712 	      start_addr + wq->mem.bufspec.dec1_uv.buf_start,
713 	      canvas_width, canvas_height / 2,
714 	      CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
715 }
716 
avc_buffspec_init(struct encode_wq_s * wq)717 static void avc_buffspec_init(struct encode_wq_s *wq)
718 {
719 	u32 canvas_width, canvas_height;
720 	u32 start_addr = wq->mem.buf_start;
721 	u32 mb_w = (wq->pic.encoder_width + 15) >> 4;
722 	u32 mb_h = (wq->pic.encoder_height + 15) >> 4;
723 	u32 mbs = mb_w * mb_h;
724 
725 	canvas_width = ((wq->pic.encoder_width + 31) >> 5) << 5;
726 	canvas_height = ((wq->pic.encoder_height + 15) >> 4) << 4;
727 
728 	wq->mem.dct_buff_start_addr = start_addr +
729 		wq->mem.bufspec.dct.buf_start;
730 	wq->mem.dct_buff_end_addr =
731 		wq->mem.dct_buff_start_addr +
732 		wq->mem.bufspec.dct.buf_size - 1;
733 	enc_pr(LOG_INFO, "dct_buff_start_addr is 0x%x, wq:%p.\n",
734 		wq->mem.dct_buff_start_addr, (void *)wq);
735 
736 	wq->mem.bufspec.dec0_uv.buf_start =
737 		wq->mem.bufspec.dec0_y.buf_start +
738 		canvas_width * canvas_height;
739 	wq->mem.bufspec.dec0_uv.buf_size = canvas_width * canvas_height / 2;
740 	wq->mem.bufspec.dec1_uv.buf_start =
741 		wq->mem.bufspec.dec1_y.buf_start +
742 		canvas_width * canvas_height;
743 	wq->mem.bufspec.dec1_uv.buf_size = canvas_width * canvas_height / 2;
744 	wq->mem.assit_buffer_offset = start_addr +
745 		wq->mem.bufspec.assit.buf_start;
746 	enc_pr(LOG_INFO, "assit_buffer_offset is 0x%x, wq: %p.\n",
747 		wq->mem.assit_buffer_offset, (void *)wq);
748 	/*output stream buffer config*/
749 	wq->mem.BitstreamStart = start_addr +
750 		wq->mem.bufspec.bitstream.buf_start;
751 	wq->mem.BitstreamEnd =
752 		wq->mem.BitstreamStart +
753 		wq->mem.bufspec.bitstream.buf_size - 1;
754 	enc_pr(LOG_INFO, "BitstreamStart is 0x%x, wq: %p.\n",
755 		wq->mem.BitstreamStart, (void *)wq);
756 
757 	wq->mem.scaler_buff_start_addr =
758 		wq->mem.buf_start + wq->mem.bufspec.scale_buff.buf_start;
759 	wq->mem.dump_info_ddr_start_addr =
760 		wq->mem.buf_start + wq->mem.bufspec.dump_info.buf_start;
761 	enc_pr(LOG_INFO,
762 		"CBR: dump_info_ddr_start_addr:%x.\n",
763 		wq->mem.dump_info_ddr_start_addr);
764 	enc_pr(LOG_INFO, "CBR: buf_start :%d.\n",
765 		wq->mem.buf_start);
766 	enc_pr(LOG_INFO, "CBR: dump_info.buf_start :%d.\n",
767 		wq->mem.bufspec.dump_info.buf_start);
768 	wq->mem.dump_info_ddr_size =
769 		DUMP_INFO_BYTES_PER_MB * mbs;
770 	wq->mem.dump_info_ddr_size =
771 		(wq->mem.dump_info_ddr_size + PAGE_SIZE - 1)
772 		& ~(PAGE_SIZE - 1);
773 	wq->mem.cbr_info_ddr_start_addr =
774 		wq->mem.buf_start + wq->mem.bufspec.cbr_info.buf_start;
775 	wq->mem.cbr_info_ddr_size =
776 		wq->mem.bufspec.cbr_info.buf_size;
777 	wq->mem.cbr_info_ddr_virt_addr =
778 		codec_mm_vmap(wq->mem.cbr_info_ddr_start_addr,
779 		            wq->mem.bufspec.cbr_info.buf_size);
780 
781 	wq->mem.dblk_buf_canvas =
782 		((ENC_CANVAS_OFFSET + 2) << 16) |
783 		((ENC_CANVAS_OFFSET + 1) << 8) |
784 		(ENC_CANVAS_OFFSET);
785 	wq->mem.ref_buf_canvas =
786 		((ENC_CANVAS_OFFSET + 5) << 16) |
787 		((ENC_CANVAS_OFFSET + 4) << 8) |
788 		(ENC_CANVAS_OFFSET + 3);
789 }
790 
avc_init_ie_me_parameter(struct encode_wq_s * wq,u32 quant)791 static void avc_init_ie_me_parameter(struct encode_wq_s *wq, u32 quant)
792 {
793 	ie_cur_ref_sel = 0;
794 	ie_pippeline_block = 12;
795 	/* currently disable half and sub pixel */
796 	ie_me_mode =
797 		(ie_pippeline_block & IE_PIPPELINE_BLOCK_MASK) <<
798 	      IE_PIPPELINE_BLOCK_SHIFT;
799 
800 	WRITE_HREG(IE_ME_MODE, ie_me_mode);
801 	WRITE_HREG(IE_REF_SEL, ie_cur_ref_sel);
802 	WRITE_HREG(IE_ME_MB_TYPE, ie_me_mb_type);
803 #ifdef MULTI_SLICE_MC
804 	if (fixed_slice_cfg)
805 		WRITE_HREG(FIXED_SLICE_CFG, fixed_slice_cfg);
806 	else if (wq->pic.rows_per_slice !=
807 			(wq->pic.encoder_height + 15) >> 4) {
808 		u32 mb_per_slice = (wq->pic.encoder_height + 15) >> 4;
809 
810 		mb_per_slice = mb_per_slice * wq->pic.rows_per_slice;
811 		WRITE_HREG(FIXED_SLICE_CFG, mb_per_slice);
812 	} else
813 		WRITE_HREG(FIXED_SLICE_CFG, 0);
814 #else
815 	WRITE_HREG(FIXED_SLICE_CFG, 0);
816 #endif
817 }
818 
819 /* for temp */
820 #define HCODEC_MFDIN_REGC_MBLP		(HCODEC_MFDIN_REGB_AMPC + 0x1)
821 #define HCODEC_MFDIN_REG0D			(HCODEC_MFDIN_REGB_AMPC + 0x2)
822 #define HCODEC_MFDIN_REG0E			(HCODEC_MFDIN_REGB_AMPC + 0x3)
823 #define HCODEC_MFDIN_REG0F			(HCODEC_MFDIN_REGB_AMPC + 0x4)
824 #define HCODEC_MFDIN_REG10			(HCODEC_MFDIN_REGB_AMPC + 0x5)
825 #define HCODEC_MFDIN_REG11			(HCODEC_MFDIN_REGB_AMPC + 0x6)
826 #define HCODEC_MFDIN_REG12			(HCODEC_MFDIN_REGB_AMPC + 0x7)
827 #define HCODEC_MFDIN_REG13			(HCODEC_MFDIN_REGB_AMPC + 0x8)
828 #define HCODEC_MFDIN_REG14			(HCODEC_MFDIN_REGB_AMPC + 0x9)
829 #define HCODEC_MFDIN_REG15			(HCODEC_MFDIN_REGB_AMPC + 0xa)
830 #define HCODEC_MFDIN_REG16			(HCODEC_MFDIN_REGB_AMPC + 0xb)
831 
mfdin_basic(u32 input,u8 iformat,u8 oformat,u32 picsize_x,u32 picsize_y,u8 r2y_en,u8 nr,u8 ifmt_extra)832 static void mfdin_basic(u32 input, u8 iformat,
833 	u8 oformat, u32 picsize_x, u32 picsize_y,
834 	u8 r2y_en, u8 nr, u8 ifmt_extra)
835 {
836 	u8 dsample_en; /* Downsample Enable */
837 	u8 interp_en;  /* Interpolation Enable */
838 	u8 y_size;     /* 0:16 Pixels for y direction pickup; 1:8 pixels */
839 	u8 r2y_mode;   /* RGB2YUV Mode, range(0~3) */
840 	/* mfdin_reg3_canv[25:24];
841 	 *  // bytes per pixel in x direction for index0, 0:half 1:1 2:2 3:3
842 	 */
843 	u8 canv_idx0_bppx;
844 	/* mfdin_reg3_canv[27:26];
845 	 *  // bytes per pixel in x direction for index1-2, 0:half 1:1 2:2 3:3
846 	 */
847 	u8 canv_idx1_bppx;
848 	/* mfdin_reg3_canv[29:28];
849 	 *  // bytes per pixel in y direction for index0, 0:half 1:1 2:2 3:3
850 	 */
851 	u8 canv_idx0_bppy;
852 	/* mfdin_reg3_canv[31:30];
853 	 *  // bytes per pixel in y direction for index1-2, 0:half 1:1 2:2 3:3
854 	 */
855 	u8 canv_idx1_bppy;
856 	u8 ifmt444, ifmt422, ifmt420, linear_bytes4p;
857 	u8 nr_enable;
858 	u8 cfg_y_snr_en;
859 	u8 cfg_y_tnr_en;
860 	u8 cfg_c_snr_en;
861 	u8 cfg_c_tnr_en;
862 	u32 linear_bytesperline;
863 	s32 reg_offset;
864 	bool linear_enable = false;
865 	bool format_err = false;
866 
867 	if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL) {
868 		if ((iformat == 7) && (ifmt_extra > 2))
869 			format_err = true;
870 	} else if (iformat == 7)
871 		format_err = true;
872 
873 	if (format_err) {
874 		enc_pr(LOG_ERROR,
875 			"mfdin format err, iformat:%d, ifmt_extra:%d\n",
876 			iformat, ifmt_extra);
877 		return;
878 	}
879 	if (iformat != 7)
880 		ifmt_extra = 0;
881 
882 	ifmt444 = ((iformat == 1) || (iformat == 5) || (iformat == 8) ||
883 		(iformat == 9) || (iformat == 12)) ? 1 : 0;
884 	if (iformat == 7 && ifmt_extra == 1)
885 		ifmt444 = 1;
886 	ifmt422 = ((iformat == 0) || (iformat == 10)) ? 1 : 0;
887 	if (iformat == 7 && ifmt_extra != 1)
888 		ifmt422 = 1;
889 	ifmt420 = ((iformat == 2) || (iformat == 3) || (iformat == 4) ||
890 		(iformat == 11)) ? 1 : 0;
891 	dsample_en = ((ifmt444 && (oformat != 2)) ||
892 		(ifmt422 && (oformat == 0))) ? 1 : 0;
893 	interp_en = ((ifmt422 && (oformat == 2)) ||
894 		(ifmt420 && (oformat != 0))) ? 1 : 0;
895 	y_size = (oformat != 0) ? 1 : 0;
896 	if (iformat == 12)
897 		y_size = 0;
898 	r2y_mode = (r2y_en == 1) ? 1 : 0; /* Fixed to 1 (TODO) */
899 	canv_idx0_bppx = (iformat == 1) ? 3 : (iformat == 0) ? 2 : 1;
900 	canv_idx1_bppx = (iformat == 4) ? 0 : 1;
901 	canv_idx0_bppy = 1;
902 	canv_idx1_bppy = (iformat == 5) ? 1 : 0;
903 
904 	if ((iformat == 8) || (iformat == 9) || (iformat == 12))
905 		linear_bytes4p = 3;
906 	else if (iformat == 10)
907 		linear_bytes4p = 2;
908 	else if (iformat == 11)
909 		linear_bytes4p = 1;
910 	else
911 		linear_bytes4p = 0;
912 	if (iformat == 12)
913 		linear_bytesperline = picsize_x * 4;
914 	else
915 		linear_bytesperline = picsize_x * linear_bytes4p;
916 
917 	if (iformat < 8)
918 		linear_enable = false;
919 	else
920 		linear_enable = true;
921 
922 	if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) {
923 		reg_offset = -8;
924 		/* nr_mode: 0:Disabled 1:SNR Only 2:TNR Only 3:3DNR */
925 		nr_enable = (nr) ? 1 : 0;
926 		cfg_y_snr_en = ((nr == 1) || (nr == 3)) ? 1 : 0;
927 		cfg_y_tnr_en = ((nr == 2) || (nr == 3)) ? 1 : 0;
928 		cfg_c_snr_en = cfg_y_snr_en;
929 		/* cfg_c_tnr_en = cfg_y_tnr_en; */
930 		cfg_c_tnr_en = 0;
931 
932 		/* NR For Y */
933 		WRITE_HREG((HCODEC_MFDIN_REG0D + reg_offset),
934 			((cfg_y_snr_en << 0) |
935 			(y_snr_err_norm << 1) |
936 			(y_snr_gau_bld_core << 2) |
937 			(((y_snr_gau_bld_ofst) & 0xff) << 6) |
938 			(y_snr_gau_bld_rate << 14) |
939 			(y_snr_gau_alp0_min << 20) |
940 			(y_snr_gau_alp0_max << 26)));
941 		WRITE_HREG((HCODEC_MFDIN_REG0E + reg_offset),
942 			((cfg_y_tnr_en << 0) |
943 			(y_tnr_mc_en << 1) |
944 			(y_tnr_txt_mode << 2) |
945 			(y_tnr_mot_sad_margin << 3) |
946 			(y_tnr_alpha_min << 7) |
947 			(y_tnr_alpha_max << 13) |
948 			(y_tnr_deghost_os << 19)));
949 		WRITE_HREG((HCODEC_MFDIN_REG0F + reg_offset),
950 			((y_tnr_mot_cortxt_rate << 0) |
951 			(y_tnr_mot_distxt_ofst << 8) |
952 			(y_tnr_mot_distxt_rate << 4) |
953 			(y_tnr_mot_dismot_ofst << 16) |
954 			(y_tnr_mot_frcsad_lock << 24)));
955 		WRITE_HREG((HCODEC_MFDIN_REG10 + reg_offset),
956 			((y_tnr_mot2alp_frc_gain << 0) |
957 			(y_tnr_mot2alp_nrm_gain << 8) |
958 			(y_tnr_mot2alp_dis_gain << 16) |
959 			(y_tnr_mot2alp_dis_ofst << 24)));
960 		WRITE_HREG((HCODEC_MFDIN_REG11 + reg_offset),
961 			((y_bld_beta2alp_rate << 0) |
962 			(y_bld_beta_min << 8) |
963 			(y_bld_beta_max << 14)));
964 
965 		/* NR For C */
966 		WRITE_HREG((HCODEC_MFDIN_REG12 + reg_offset),
967 			((cfg_y_snr_en << 0) |
968 			(c_snr_err_norm << 1) |
969 			(c_snr_gau_bld_core << 2) |
970 			(((c_snr_gau_bld_ofst) & 0xff) << 6) |
971 			(c_snr_gau_bld_rate << 14) |
972 			(c_snr_gau_alp0_min << 20) |
973 			(c_snr_gau_alp0_max << 26)));
974 
975 		WRITE_HREG((HCODEC_MFDIN_REG13 + reg_offset),
976 			((cfg_c_tnr_en << 0) |
977 			(c_tnr_mc_en << 1) |
978 			(c_tnr_txt_mode << 2) |
979 			(c_tnr_mot_sad_margin << 3) |
980 			(c_tnr_alpha_min << 7) |
981 			(c_tnr_alpha_max << 13) |
982 			(c_tnr_deghost_os << 19)));
983 		WRITE_HREG((HCODEC_MFDIN_REG14 + reg_offset),
984 			((c_tnr_mot_cortxt_rate << 0) |
985 			(c_tnr_mot_distxt_ofst << 8) |
986 			(c_tnr_mot_distxt_rate << 4) |
987 			(c_tnr_mot_dismot_ofst << 16) |
988 			(c_tnr_mot_frcsad_lock << 24)));
989 		WRITE_HREG((HCODEC_MFDIN_REG15 + reg_offset),
990 			((c_tnr_mot2alp_frc_gain << 0) |
991 			(c_tnr_mot2alp_nrm_gain << 8) |
992 			(c_tnr_mot2alp_dis_gain << 16) |
993 			(c_tnr_mot2alp_dis_ofst << 24)));
994 
995 		WRITE_HREG((HCODEC_MFDIN_REG16 + reg_offset),
996 			((c_bld_beta2alp_rate << 0) |
997 			(c_bld_beta_min << 8) |
998 			(c_bld_beta_max << 14)));
999 
1000 		WRITE_HREG((HCODEC_MFDIN_REG1_CTRL + reg_offset),
1001 			(iformat << 0) | (oformat << 4) |
1002 			(dsample_en << 6) | (y_size << 8) |
1003 			(interp_en << 9) | (r2y_en << 12) |
1004 			(r2y_mode << 13) | (ifmt_extra << 16) |
1005 			(nr_enable << 19));
1006 		WRITE_HREG((HCODEC_MFDIN_REG8_DMBL + reg_offset),
1007 			(picsize_x << 14) | (picsize_y << 0));
1008 	} else {
1009 		reg_offset = 0;
1010 		WRITE_HREG((HCODEC_MFDIN_REG1_CTRL + reg_offset),
1011 			(iformat << 0) | (oformat << 4) |
1012 			(dsample_en << 6) | (y_size << 8) |
1013 			(interp_en << 9) | (r2y_en << 12) |
1014 			(r2y_mode << 13));
1015 		WRITE_HREG((HCODEC_MFDIN_REG8_DMBL + reg_offset),
1016 			(picsize_x << 12) | (picsize_y << 0));
1017 	}
1018 
1019 	if (linear_enable == false) {
1020 		WRITE_HREG((HCODEC_MFDIN_REG3_CANV + reg_offset),
1021 			(input & 0xffffff) |
1022 			(canv_idx1_bppy << 30) |
1023 			(canv_idx0_bppy << 28) |
1024 			(canv_idx1_bppx << 26) |
1025 			(canv_idx0_bppx << 24));
1026 		WRITE_HREG((HCODEC_MFDIN_REG4_LNR0 + reg_offset),
1027 			(0 << 16) | (0 << 0));
1028 		WRITE_HREG((HCODEC_MFDIN_REG5_LNR1 + reg_offset), 0);
1029 	} else {
1030 		WRITE_HREG((HCODEC_MFDIN_REG3_CANV + reg_offset),
1031 			(canv_idx1_bppy << 30) |
1032 			(canv_idx0_bppy << 28) |
1033 			(canv_idx1_bppx << 26) |
1034 			(canv_idx0_bppx << 24));
1035 		WRITE_HREG((HCODEC_MFDIN_REG4_LNR0 + reg_offset),
1036 			(linear_bytes4p << 16) | (linear_bytesperline << 0));
1037 		WRITE_HREG((HCODEC_MFDIN_REG5_LNR1 + reg_offset), input);
1038 	}
1039 
1040 	if (iformat == 12)
1041 		WRITE_HREG((HCODEC_MFDIN_REG9_ENDN + reg_offset),
1042 			(2 << 0) | (1 << 3) | (0 << 6) |
1043 			(3 << 9) | (6 << 12) | (5 << 15) |
1044 			(4 << 18) | (7 << 21));
1045 	else
1046 		WRITE_HREG((HCODEC_MFDIN_REG9_ENDN + reg_offset),
1047 			(7 << 0) | (6 << 3) | (5 << 6) |
1048 			(4 << 9) | (3 << 12) | (2 << 15) |
1049 			(1 << 18) | (0 << 21));
1050 }
1051 
1052 #ifdef CONFIG_AMLOGIC_MEDIA_GE2D
scale_frame(struct encode_wq_s * wq,struct encode_request_s * request,struct config_para_ex_s * ge2d_config,u32 src_addr,bool canvas)1053 static int scale_frame(struct encode_wq_s *wq,
1054 	struct encode_request_s *request,
1055 	struct config_para_ex_s *ge2d_config,
1056 	u32 src_addr, bool canvas)
1057 {
1058 	struct ge2d_context_s *context = encode_manager.context;
1059 	int src_top, src_left, src_width, src_height;
1060 	struct canvas_s cs0, cs1, cs2, cd;
1061 	u32 src_canvas, dst_canvas;
1062 	u32 src_canvas_w, dst_canvas_w;
1063 	u32 src_h = request->src_h;
1064 	u32 dst_w = ((wq->pic.encoder_width + 15) >> 4) << 4;
1065 	u32 dst_h = ((wq->pic.encoder_height + 15) >> 4) << 4;
1066 	int input_format = GE2D_FORMAT_M24_NV21;
1067 
1068 	src_top = request->crop_top;
1069 	src_left = request->crop_left;
1070 	src_width = request->src_w - src_left - request->crop_right;
1071 	src_height = request->src_h - src_top - request->crop_bottom;
1072 	pr_err("request->fmt=%d, %d %d, canvas=%d\n", request->fmt, FMT_NV21, FMT_BGR888, canvas);
1073 
1074 	if (canvas) {
1075 		if ((request->fmt == FMT_NV21)
1076 			|| (request->fmt == FMT_NV12)) {
1077 			src_canvas = src_addr & 0xffff;
1078 			input_format = GE2D_FORMAT_M24_NV21;
1079 		} else if (request->fmt == FMT_BGR888) {
1080 			src_canvas = src_addr & 0xffffff;
1081 			input_format = GE2D_FORMAT_S24_RGB; //Opposite color after ge2d
1082 		} else if (request->fmt == FMT_RGBA8888) {
1083 			src_canvas = src_addr & 0xffffff;
1084 			input_format = GE2D_FORMAT_S32_ABGR;
1085 		} else {
1086 			src_canvas = src_addr & 0xffffff;
1087 			input_format = GE2D_FORMAT_M24_YUV420;
1088 		}
1089 	} else {
1090 		if ((request->fmt == FMT_NV21)
1091 			|| (request->fmt == FMT_NV12)) {
1092 			src_canvas_w =
1093 				((request->src_w + 31) >> 5) << 5;
1094 			canvas_config(ENC_CANVAS_OFFSET + 9,
1095 				src_addr,
1096 				src_canvas_w, src_h,
1097 				CANVAS_ADDR_NOWRAP,
1098 				CANVAS_BLKMODE_LINEAR);
1099 			canvas_config(ENC_CANVAS_OFFSET + 10,
1100 				src_addr + src_canvas_w * src_h,
1101 				src_canvas_w, src_h / 2,
1102 				CANVAS_ADDR_NOWRAP,
1103 				CANVAS_BLKMODE_LINEAR);
1104 			src_canvas =
1105 				((ENC_CANVAS_OFFSET + 10) << 8)
1106 				| (ENC_CANVAS_OFFSET + 9);
1107 			input_format = GE2D_FORMAT_M24_NV21;
1108 		} else if (request->fmt == FMT_BGR888) {
1109 			src_canvas_w =
1110 				((request->src_w + 31) >> 5) << 5;
1111 
1112 			canvas_config(ENC_CANVAS_OFFSET + 9,
1113 				src_addr,
1114 				src_canvas_w * 3, src_h,
1115 				CANVAS_ADDR_NOWRAP,
1116 				CANVAS_BLKMODE_LINEAR);
1117 			src_canvas = ENC_CANVAS_OFFSET + 9;
1118 			input_format = GE2D_FORMAT_S24_RGB; //Opposite color after ge2d
1119 		} else if (request->fmt == FMT_RGBA8888) {
1120 			src_canvas_w =
1121 				((request->src_w + 31) >> 5) << 5;
1122 			canvas_config(
1123 				ENC_CANVAS_OFFSET + 9,
1124 				src_addr,
1125 				src_canvas_w * 4,
1126 				src_h,
1127 				CANVAS_ADDR_NOWRAP,
1128 				CANVAS_BLKMODE_LINEAR);
1129 			src_canvas = ENC_CANVAS_OFFSET + 9;
1130 			input_format = GE2D_FORMAT_S32_ABGR; //Opposite color after ge2d
1131 		} else {
1132 			src_canvas_w =
1133 				((request->src_w + 63) >> 6) << 6;
1134 			canvas_config(ENC_CANVAS_OFFSET + 9,
1135 				src_addr,
1136 				src_canvas_w, src_h,
1137 				CANVAS_ADDR_NOWRAP,
1138 				CANVAS_BLKMODE_LINEAR);
1139 			canvas_config(ENC_CANVAS_OFFSET + 10,
1140 				src_addr + src_canvas_w * src_h,
1141 				src_canvas_w / 2, src_h / 2,
1142 				CANVAS_ADDR_NOWRAP,
1143 				CANVAS_BLKMODE_LINEAR);
1144 			canvas_config(ENC_CANVAS_OFFSET + 11,
1145 				src_addr + src_canvas_w * src_h * 5 / 4,
1146 				src_canvas_w / 2, src_h / 2,
1147 				CANVAS_ADDR_NOWRAP,
1148 				CANVAS_BLKMODE_LINEAR);
1149 			src_canvas =
1150 				((ENC_CANVAS_OFFSET + 11) << 16) |
1151 				((ENC_CANVAS_OFFSET + 10) << 8) |
1152 				(ENC_CANVAS_OFFSET + 9);
1153 			input_format = GE2D_FORMAT_M24_YUV420;
1154 		}
1155 	}
1156 
1157 	dst_canvas_w =  ((dst_w + 31) >> 5) << 5;
1158 
1159 	canvas_config(ENC_CANVAS_OFFSET + 6,
1160 		wq->mem.scaler_buff_start_addr,
1161 		dst_canvas_w, dst_h,
1162 		CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
1163 
1164 	canvas_config(ENC_CANVAS_OFFSET + 7,
1165 		wq->mem.scaler_buff_start_addr + dst_canvas_w * dst_h,
1166 		dst_canvas_w, dst_h / 2,
1167 		CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR);
1168 
1169 	dst_canvas = ((ENC_CANVAS_OFFSET + 7) << 8) |
1170 		(ENC_CANVAS_OFFSET + 6);
1171 
1172 	ge2d_config->alu_const_color = 0;
1173 	ge2d_config->bitmask_en  = 0;
1174 	ge2d_config->src1_gb_alpha = 0;
1175 	ge2d_config->dst_xy_swap = 0;
1176 	canvas_read(src_canvas & 0xff, &cs0);
1177 	canvas_read((src_canvas >> 8) & 0xff, &cs1);
1178 	canvas_read((src_canvas >> 16) & 0xff, &cs2);
1179 	ge2d_config->src_planes[0].addr = cs0.addr;
1180 	ge2d_config->src_planes[0].w = dst_w * 4;//cs0.width;
1181 	ge2d_config->src_planes[0].h = dst_h;//cs0.height;
1182 	ge2d_config->src_planes[1].addr = cs1.addr;
1183 	ge2d_config->src_planes[1].w = cs1.width;
1184 	ge2d_config->src_planes[1].h = cs1.height;
1185 	ge2d_config->src_planes[2].addr = cs2.addr;
1186 	ge2d_config->src_planes[2].w = cs2.width;
1187 	ge2d_config->src_planes[2].h = cs2.height;
1188 
1189 	canvas_read(dst_canvas & 0xff, &cd);
1190 
1191 	ge2d_config->dst_planes[0].addr = cd.addr;
1192 	ge2d_config->dst_planes[0].w = dst_w * 4;//cd.width;
1193 	ge2d_config->dst_planes[0].h = dst_h;//cd.height;
1194 	ge2d_config->src_key.key_enable = 0;
1195 	ge2d_config->src_key.key_mask = 0;
1196 	ge2d_config->src_key.key_mode = 0;
1197 	ge2d_config->src_para.canvas_index = src_canvas;
1198 	ge2d_config->src_para.mem_type = CANVAS_TYPE_INVALID;
1199 	ge2d_config->src_para.format = input_format | GE2D_LITTLE_ENDIAN;
1200 	ge2d_config->src_para.fill_color_en = 0;
1201 	ge2d_config->src_para.fill_mode = 0;
1202 	ge2d_config->src_para.x_rev = 0;
1203 	ge2d_config->src_para.y_rev = 0;
1204 	ge2d_config->src_para.color = 0xffffffff;
1205 	ge2d_config->src_para.top = 0;
1206 	ge2d_config->src_para.left = 0;
1207 	ge2d_config->src_para.width = dst_w;//request->src_w;
1208 	ge2d_config->src_para.height = dst_h;//request->src_h;
1209 	ge2d_config->src2_para.mem_type = CANVAS_TYPE_INVALID;
1210 	ge2d_config->dst_para.canvas_index = dst_canvas;
1211 	ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID;
1212 	ge2d_config->dst_para.format =
1213 		GE2D_FORMAT_M24_NV21 | GE2D_LITTLE_ENDIAN;
1214 
1215 	if (wq->pic.encoder_width >= 1280 && wq->pic.encoder_height >= 720) {
1216 		ge2d_config->dst_para.format |= wq->pic.color_space;
1217 	}
1218 
1219 	ge2d_config->dst_para.fill_color_en = 0;
1220 	ge2d_config->dst_para.fill_mode = 0;
1221 	ge2d_config->dst_para.x_rev = 0;
1222 	ge2d_config->dst_para.y_rev = 0;
1223 	ge2d_config->dst_para.color = 0;
1224 	ge2d_config->dst_para.top = 0;
1225 	ge2d_config->dst_para.left = 0;
1226 	ge2d_config->dst_para.width = dst_w;
1227 	ge2d_config->dst_para.height = dst_h;
1228 	ge2d_config->dst_para.x_rev = 0;
1229 	ge2d_config->dst_para.y_rev = 0;
1230 
1231 
1232 	if (ge2d_context_config_ex(context, ge2d_config) < 0) {
1233 		pr_err("++ge2d configing error.\n");
1234 		return -1;
1235 	}
1236 	stretchblt_noalpha(context, src_left, src_top, src_width, src_height,
1237 		0, 0, wq->pic.encoder_width, wq->pic.encoder_height);
1238 	return dst_canvas_w*dst_h * 3 / 2;
1239 }
1240 #endif
1241 
set_input_format(struct encode_wq_s * wq,struct encode_request_s * request)1242 static s32 set_input_format(struct encode_wq_s *wq,
1243 			    struct encode_request_s *request)
1244 {
1245 	s32 ret = 0;
1246 	u8 iformat = MAX_FRAME_FMT, oformat = MAX_FRAME_FMT, r2y_en = 0;
1247 	u32 picsize_x, picsize_y, src_addr;
1248 	u32 canvas_w = 0;
1249 	u32 input = request->src;
1250 	u32 input_y = 0;
1251 	u32 input_u = 0;
1252 	u32 input_v = 0;
1253 	u8 ifmt_extra = 0;
1254 
1255 	if ((request->fmt == FMT_RGB565) || (request->fmt >= MAX_FRAME_FMT))
1256 		return -1;
1257 
1258 	picsize_x = ((wq->pic.encoder_width + 15) >> 4) << 4;
1259 	picsize_y = ((wq->pic.encoder_height + 15) >> 4) << 4;
1260 	oformat = 0;
1261 
1262 	if ((request->type == LOCAL_BUFF)
1263 		|| (request->type == PHYSICAL_BUFF)
1264 		|| (request->type == DMA_BUFF)) {
1265 		if ((request->type == LOCAL_BUFF) &&
1266 			(request->flush_flag & AMVENC_FLUSH_FLAG_INPUT))
1267 			dma_flush(wq->mem.dct_buff_start_addr,
1268 				request->framesize);
1269 		if (request->type == LOCAL_BUFF) {
1270 			input = wq->mem.dct_buff_start_addr;
1271 			src_addr =
1272 				wq->mem.dct_buff_start_addr;
1273 		} else if (request->type == DMA_BUFF) {
1274 			if (request->plane_num == 3) {
1275 				input_y = (unsigned long)request->dma_cfg[0].paddr;
1276 				input_u = (unsigned long)request->dma_cfg[1].paddr;
1277 				input_v = (unsigned long)request->dma_cfg[2].paddr;
1278 			} else if (request->plane_num == 2) {
1279 				input_y = (unsigned long)request->dma_cfg[0].paddr;
1280 				input_u = (unsigned long)request->dma_cfg[1].paddr;
1281 				input_v = input_u;
1282 			} else if (request->plane_num == 1) {
1283 				input_y = (unsigned long)request->dma_cfg[0].paddr;
1284 				if (request->fmt == FMT_NV21
1285 					|| request->fmt == FMT_NV12) {
1286 					input_u = input_y + picsize_x * picsize_y;
1287 					input_v = input_u;
1288 				}
1289 				if (request->fmt == FMT_YUV420) {
1290 					input_u = input_y + picsize_x * picsize_y;
1291 					input_v = input_u + picsize_x * picsize_y  / 4;
1292 				}
1293 			}
1294 			src_addr = input_y;
1295 			picsize_y = wq->pic.encoder_height;
1296 			enc_pr(LOG_INFO, "dma addr[0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx]\n",
1297 				(unsigned long)request->dma_cfg[0].vaddr,
1298 				(unsigned long)request->dma_cfg[0].paddr,
1299 				(unsigned long)request->dma_cfg[1].vaddr,
1300 				(unsigned long)request->dma_cfg[1].paddr,
1301 				(unsigned long)request->dma_cfg[2].vaddr,
1302 				(unsigned long)request->dma_cfg[2].paddr);
1303 		} else {
1304 			src_addr = input;
1305 			picsize_y = wq->pic.encoder_height;
1306 		}
1307 		if (request->scale_enable) {
1308 #ifdef CONFIG_AMLOGIC_MEDIA_GE2D
1309 			struct config_para_ex_s ge2d_config;
1310 
1311 			memset(&ge2d_config, 0,
1312 				sizeof(struct config_para_ex_s));
1313 			scale_frame(
1314 				wq, request,
1315 				&ge2d_config,
1316 				src_addr,
1317 				false);
1318 			iformat = 2;
1319 			r2y_en = 0;
1320 			input = ((ENC_CANVAS_OFFSET + 7) << 8) |
1321 				(ENC_CANVAS_OFFSET + 6);
1322 			ret = 0;
1323 			goto MFDIN;
1324 #else
1325 			enc_pr(LOG_ERROR,
1326 				"Warning: need enable ge2d for scale frame!\n");
1327 			return -1;
1328 #endif
1329 		}
1330 		if ((request->fmt <= FMT_YUV444_PLANE) ||
1331 			(request->fmt >= FMT_YUV422_12BIT))
1332 			r2y_en = 0;
1333 		else
1334 			r2y_en = 1;
1335 
1336 		if (request->fmt >= FMT_YUV422_12BIT) {
1337 			iformat = 7;
1338 			ifmt_extra = request->fmt - FMT_YUV422_12BIT;
1339 			if (request->fmt == FMT_YUV422_12BIT)
1340 				canvas_w = picsize_x * 24 / 8;
1341 			else if (request->fmt == FMT_YUV444_10BIT)
1342 				canvas_w = picsize_x * 32 / 8;
1343 			else
1344 				canvas_w = (picsize_x * 20 + 7) / 8;
1345 			canvas_w = ((canvas_w + 31) >> 5) << 5;
1346 			canvas_config(ENC_CANVAS_OFFSET + 6,
1347 				input,
1348 				canvas_w, picsize_y,
1349 				CANVAS_ADDR_NOWRAP,
1350 				CANVAS_BLKMODE_LINEAR);
1351 			input = ENC_CANVAS_OFFSET + 6;
1352 			input = input & 0xff;
1353 		} else if (request->fmt == FMT_YUV422_SINGLE)
1354 			iformat = 10;
1355 		else if ((request->fmt == FMT_YUV444_SINGLE)
1356 			|| (request->fmt == FMT_RGB888)) {
1357 			iformat = 1;
1358 			if (request->fmt == FMT_RGB888)
1359 				r2y_en = 1;
1360 			canvas_w =  picsize_x * 3;
1361 			canvas_w = ((canvas_w + 31) >> 5) << 5;
1362 			canvas_config(ENC_CANVAS_OFFSET + 6,
1363 				input,
1364 				canvas_w, picsize_y,
1365 				CANVAS_ADDR_NOWRAP,
1366 				CANVAS_BLKMODE_LINEAR);
1367 			input = ENC_CANVAS_OFFSET + 6;
1368 		} else if ((request->fmt == FMT_NV21)
1369 			|| (request->fmt == FMT_NV12)) {
1370 			canvas_w = ((wq->pic.encoder_width + 31) >> 5) << 5;
1371 			iformat = (request->fmt == FMT_NV21) ? 2 : 3;
1372 			if (request->type == DMA_BUFF) {
1373 				canvas_config(ENC_CANVAS_OFFSET + 6,
1374 					input_y,
1375 					canvas_w, picsize_y,
1376 					CANVAS_ADDR_NOWRAP,
1377 					CANVAS_BLKMODE_LINEAR);
1378 				canvas_config(ENC_CANVAS_OFFSET + 7,
1379 					input_u,
1380 					canvas_w, picsize_y / 2,
1381 					CANVAS_ADDR_NOWRAP,
1382 					CANVAS_BLKMODE_LINEAR);
1383 			} else {
1384 				canvas_config(ENC_CANVAS_OFFSET + 6,
1385 					input,
1386 					canvas_w, picsize_y,
1387 					CANVAS_ADDR_NOWRAP,
1388 					CANVAS_BLKMODE_LINEAR);
1389 				canvas_config(ENC_CANVAS_OFFSET + 7,
1390 					input + canvas_w * picsize_y,
1391 					canvas_w, picsize_y / 2,
1392 					CANVAS_ADDR_NOWRAP,
1393 					CANVAS_BLKMODE_LINEAR);
1394 			}
1395 			input = ((ENC_CANVAS_OFFSET + 7) << 8) |
1396 				(ENC_CANVAS_OFFSET + 6);
1397 		} else if (request->fmt == FMT_YUV420) {
1398 			iformat = 4;
1399 			canvas_w = ((wq->pic.encoder_width + 63) >> 6) << 6;
1400 			if (request->type == DMA_BUFF) {
1401 				canvas_config(ENC_CANVAS_OFFSET + 6,
1402 					input_y,
1403 					canvas_w, picsize_y,
1404 					CANVAS_ADDR_NOWRAP,
1405 					CANVAS_BLKMODE_LINEAR);
1406 				canvas_config(ENC_CANVAS_OFFSET + 7,
1407 					input_u,
1408 					canvas_w / 2, picsize_y / 2,
1409 					CANVAS_ADDR_NOWRAP,
1410 					CANVAS_BLKMODE_LINEAR);
1411 				canvas_config(ENC_CANVAS_OFFSET + 8,
1412 					input_v,
1413 					canvas_w / 2, picsize_y / 2,
1414 					CANVAS_ADDR_NOWRAP,
1415 					CANVAS_BLKMODE_LINEAR);
1416 			} else {
1417 				canvas_config(ENC_CANVAS_OFFSET + 6,
1418 					input,
1419 					canvas_w, picsize_y,
1420 					CANVAS_ADDR_NOWRAP,
1421 					CANVAS_BLKMODE_LINEAR);
1422 				canvas_config(ENC_CANVAS_OFFSET + 7,
1423 					input + canvas_w * picsize_y,
1424 					canvas_w / 2, picsize_y / 2,
1425 					CANVAS_ADDR_NOWRAP,
1426 					CANVAS_BLKMODE_LINEAR);
1427 				canvas_config(ENC_CANVAS_OFFSET + 8,
1428 					input + canvas_w * picsize_y * 5 / 4,
1429 					canvas_w / 2, picsize_y / 2,
1430 					CANVAS_ADDR_NOWRAP,
1431 					CANVAS_BLKMODE_LINEAR);
1432 
1433 			}
1434 			input = ((ENC_CANVAS_OFFSET + 8) << 16) |
1435 				((ENC_CANVAS_OFFSET + 7) << 8) |
1436 				(ENC_CANVAS_OFFSET + 6);
1437 		} else if ((request->fmt == FMT_YUV444_PLANE)
1438 			|| (request->fmt == FMT_RGB888_PLANE)) {
1439 			if (request->fmt == FMT_RGB888_PLANE)
1440 				r2y_en = 1;
1441 			iformat = 5;
1442 			canvas_w = ((wq->pic.encoder_width + 31) >> 5) << 5;
1443 			canvas_config(ENC_CANVAS_OFFSET + 6,
1444 				input,
1445 				canvas_w, picsize_y,
1446 				CANVAS_ADDR_NOWRAP,
1447 				CANVAS_BLKMODE_LINEAR);
1448 			canvas_config(ENC_CANVAS_OFFSET + 7,
1449 				input + canvas_w * picsize_y,
1450 				canvas_w, picsize_y,
1451 				CANVAS_ADDR_NOWRAP,
1452 				CANVAS_BLKMODE_LINEAR);
1453 			canvas_config(ENC_CANVAS_OFFSET + 8,
1454 				input + canvas_w * picsize_y * 2,
1455 				canvas_w, picsize_y,
1456 				CANVAS_ADDR_NOWRAP,
1457 				CANVAS_BLKMODE_LINEAR);
1458 			input = ((ENC_CANVAS_OFFSET + 8) << 16) |
1459 				((ENC_CANVAS_OFFSET + 7) << 8) |
1460 				(ENC_CANVAS_OFFSET + 6);
1461 		} else if (request->fmt == FMT_RGBA8888) {
1462 			r2y_en = 1;
1463 			iformat = 12;
1464 		}
1465 		ret = 0;
1466 	} else if (request->type == CANVAS_BUFF) {
1467 		r2y_en = 0;
1468 		if (request->scale_enable) {
1469 #ifdef CONFIG_AMLOGIC_MEDIA_GE2D
1470 			struct config_para_ex_s ge2d_config;
1471 			memset(&ge2d_config, 0,
1472 				sizeof(struct config_para_ex_s));
1473 			scale_frame(
1474 				wq, request,
1475 				&ge2d_config,
1476 				input, true);
1477 			iformat = 2;
1478 			r2y_en = 0;
1479 			input = ((ENC_CANVAS_OFFSET + 7) << 8) |
1480 				(ENC_CANVAS_OFFSET + 6);
1481 			ret = 0;
1482 			goto MFDIN;
1483 #else
1484 			enc_pr(LOG_ERROR,
1485 				"Warning: need enable ge2d for scale frame!\n");
1486 			return -1;
1487 #endif
1488 		}
1489 		if (request->fmt == FMT_YUV422_SINGLE) {
1490 			iformat = 0;
1491 			input = input & 0xff;
1492 		} else if (request->fmt == FMT_YUV444_SINGLE) {
1493 			iformat = 1;
1494 			input = input & 0xff;
1495 		} else if ((request->fmt == FMT_NV21)
1496 			|| (request->fmt == FMT_NV12)) {
1497 			iformat = (request->fmt == FMT_NV21) ? 2 : 3;
1498 			input = input & 0xffff;
1499 		} else if (request->fmt == FMT_YUV420) {
1500 			iformat = 4;
1501 			input = input & 0xffffff;
1502 		} else if ((request->fmt == FMT_YUV444_PLANE)
1503 			|| (request->fmt == FMT_RGB888_PLANE)) {
1504 			if (request->fmt == FMT_RGB888_PLANE)
1505 				r2y_en = 1;
1506 			iformat = 5;
1507 			input = input & 0xffffff;
1508 		} else if ((request->fmt == FMT_YUV422_12BIT)
1509 			|| (request->fmt == FMT_YUV444_10BIT)
1510 			|| (request->fmt == FMT_YUV422_10BIT)) {
1511 			iformat = 7;
1512 			ifmt_extra = request->fmt - FMT_YUV422_12BIT;
1513 			input = input & 0xff;
1514 		} else
1515 			ret = -1;
1516 	}
1517 #ifdef CONFIG_AMLOGIC_MEDIA_GE2D
1518 MFDIN:
1519 #endif
1520 	if (ret == 0)
1521 		mfdin_basic(input, iformat, oformat,
1522 			picsize_x, picsize_y, r2y_en,
1523 			request->nr_mode, ifmt_extra);
1524 	return ret;
1525 }
1526 
1527 #ifdef H264_ENC_CBR
ConvertTable2Risc(void * table,u32 len)1528 static void ConvertTable2Risc(void *table, u32 len)
1529 {
1530 	u32 i, j;
1531 	u16 temp;
1532 	u16 *tbl = (u16 *)table;
1533 
1534 	if ((len < 8) || (len % 8) || (!table)) {
1535 		enc_pr(LOG_ERROR, "ConvertTable2Risc tbl %p, len %d error\n",
1536 			table, len);
1537 		return;
1538 	}
1539 	for (i = 0; i < len / 8; i++) {
1540 		j = i << 2;
1541 		temp = tbl[j];
1542 		tbl[j] = tbl[j + 3];
1543 		tbl[j + 3] = temp;
1544 
1545 		temp = tbl[j + 1];
1546 		tbl[j + 1] = tbl[j + 2];
1547 		tbl[j + 2] = temp;
1548 	}
1549 
1550 }
1551 #endif
1552 
avc_prot_init(struct encode_wq_s * wq,struct encode_request_s * request,u32 quant,bool IDR)1553 static void avc_prot_init(struct encode_wq_s *wq,
1554 	struct encode_request_s *request, u32 quant, bool IDR)
1555 {
1556 	u32 data32;
1557 	u32 pic_width, pic_height;
1558 	u32 pic_mb_nr;
1559 	u32 pic_mbx, pic_mby;
1560 	u32 i_pic_qp, p_pic_qp;
1561 	u32 i_pic_qp_c, p_pic_qp_c;
1562 	u32 pic_width_in_mb;
1563 	u32 slice_qp;
1564 
1565 	pic_width  = wq->pic.encoder_width;
1566 	pic_height = wq->pic.encoder_height;
1567 	pic_mb_nr  = 0;
1568 	pic_mbx    = 0;
1569 	pic_mby    = 0;
1570 	i_pic_qp   = quant;
1571 	p_pic_qp   = quant;
1572 
1573 	pic_width_in_mb = (pic_width + 15) / 16;
1574 	WRITE_HREG(HCODEC_HDEC_MC_OMEM_AUTO,
1575 		(1 << 31) | /* use_omem_mb_xy */
1576 		((pic_width_in_mb - 1) << 16)); /* omem_max_mb_x */
1577 
1578 	WRITE_HREG(HCODEC_VLC_ADV_CONFIG,
1579 		/* early_mix_mc_hcmd -- will enable in P Picture */
1580 		(0 << 10) |
1581 		(1 << 9) | /* update_top_left_mix */
1582 		(1 << 8) | /* p_top_left_mix */
1583 		/* mv_cal_mixed_type -- will enable in P Picture */
1584 		(0 << 7) |
1585 		/* mc_hcmd_mixed_type -- will enable in P Picture */
1586 		(0 << 6) |
1587 		(1 << 5) | /* use_separate_int_control */
1588 		(1 << 4) | /* hcmd_intra_use_q_info */
1589 		(1 << 3) | /* hcmd_left_use_prev_info */
1590 		(1 << 2) | /* hcmd_use_q_info */
1591 		(1 << 1) | /* use_q_delta_quant */
1592 		/* detect_I16_from_I4 use qdct detected mb_type */
1593 		(0 << 0));
1594 
1595 	WRITE_HREG(HCODEC_QDCT_ADV_CONFIG,
1596 		(1 << 29) | /* mb_info_latch_no_I16_pred_mode */
1597 		(1 << 28) | /* ie_dma_mbxy_use_i_pred */
1598 		(1 << 27) | /* ie_dma_read_write_use_ip_idx */
1599 		(1 << 26) | /* ie_start_use_top_dma_count */
1600 		(1 << 25) | /* i_pred_top_dma_rd_mbbot */
1601 		(1 << 24) | /* i_pred_top_dma_wr_disable */
1602 		/* i_pred_mix -- will enable in P Picture */
1603 		(0 << 23) |
1604 		(1 << 22) | /* me_ab_rd_when_intra_in_p */
1605 		(1 << 21) | /* force_mb_skip_run_when_intra */
1606 		/* mc_out_mixed_type -- will enable in P Picture */
1607 		(0 << 20) |
1608 		(1 << 19) | /* ie_start_when_quant_not_full */
1609 		(1 << 18) | /* mb_info_state_mix */
1610 		/* mb_type_use_mix_result -- will enable in P Picture */
1611 		(0 << 17) |
1612 		/* me_cb_ie_read_enable -- will enable in P Picture */
1613 		(0 << 16) |
1614 		/* ie_cur_data_from_me -- will enable in P Picture */
1615 		(0 << 15) |
1616 		(1 << 14) | /* rem_per_use_table */
1617 		(0 << 13) | /* q_latch_int_enable */
1618 		(1 << 12) | /* q_use_table */
1619 		(0 << 11) | /* q_start_wait */
1620 		(1 << 10) | /* LUMA_16_LEFT_use_cur */
1621 		(1 << 9) | /* DC_16_LEFT_SUM_use_cur */
1622 		(1 << 8) | /* c_ref_ie_sel_cur */
1623 		(0 << 7) | /* c_ipred_perfect_mode */
1624 		(1 << 6) | /* ref_ie_ul_sel */
1625 		(1 << 5) | /* mb_type_use_ie_result */
1626 		(1 << 4) | /* detect_I16_from_I4 */
1627 		(1 << 3) | /* ie_not_wait_ref_busy */
1628 		(1 << 2) | /* ie_I16_enable */
1629 		(3 << 0)); /* ie_done_sel  // fastest when waiting */
1630 
1631 	if (request != NULL) {
1632 		WRITE_HREG(HCODEC_IE_WEIGHT,
1633 			(request->i16_weight << 16) |
1634 			(request->i4_weight << 0));
1635 		WRITE_HREG(HCODEC_ME_WEIGHT,
1636 			(request->me_weight << 0));
1637 		WRITE_HREG(HCODEC_SAD_CONTROL_0,
1638 			/* ie_sad_offset_I16 */
1639 			(request->i16_weight << 16) |
1640 			/* ie_sad_offset_I4 */
1641 			(request->i4_weight << 0));
1642 		WRITE_HREG(HCODEC_SAD_CONTROL_1,
1643 			/* ie_sad_shift_I16 */
1644 			(IE_SAD_SHIFT_I16 << 24) |
1645 			/* ie_sad_shift_I4 */
1646 			(IE_SAD_SHIFT_I4 << 20) |
1647 			/* me_sad_shift_INTER */
1648 			(ME_SAD_SHIFT_INTER << 16) |
1649 			/* me_sad_offset_INTER */
1650 			(request->me_weight << 0));
1651 		wq->me_weight = request->me_weight;
1652 		wq->i4_weight = request->i4_weight;
1653 		wq->i16_weight = request->i16_weight;
1654 	} else {
1655 		WRITE_HREG(HCODEC_IE_WEIGHT,
1656 			(I16MB_WEIGHT_OFFSET << 16) |
1657 			(I4MB_WEIGHT_OFFSET << 0));
1658 		WRITE_HREG(HCODEC_ME_WEIGHT,
1659 			(ME_WEIGHT_OFFSET << 0));
1660 		WRITE_HREG(HCODEC_SAD_CONTROL_0,
1661 			/* ie_sad_offset_I16 */
1662 			(I16MB_WEIGHT_OFFSET << 16) |
1663 			/* ie_sad_offset_I4 */
1664 			(I4MB_WEIGHT_OFFSET << 0));
1665 		WRITE_HREG(HCODEC_SAD_CONTROL_1,
1666 			/* ie_sad_shift_I16 */
1667 			(IE_SAD_SHIFT_I16 << 24) |
1668 			/* ie_sad_shift_I4 */
1669 			(IE_SAD_SHIFT_I4 << 20) |
1670 			/* me_sad_shift_INTER */
1671 			(ME_SAD_SHIFT_INTER << 16) |
1672 			/* me_sad_offset_INTER */
1673 			(ME_WEIGHT_OFFSET << 0));
1674 	}
1675 
1676 	WRITE_HREG(HCODEC_ADV_MV_CTL0,
1677 		(ADV_MV_LARGE_16x8 << 31) |
1678 		(ADV_MV_LARGE_8x16 << 30) |
1679 		(ADV_MV_8x8_WEIGHT << 16) |   /* adv_mv_8x8_weight */
1680 		/* adv_mv_4x4x4_weight should be set bigger */
1681 		(ADV_MV_4x4x4_WEIGHT << 0));
1682 	WRITE_HREG(HCODEC_ADV_MV_CTL1,
1683 		/* adv_mv_16x16_weight */
1684 		(ADV_MV_16x16_WEIGHT << 16) |
1685 		(ADV_MV_LARGE_16x16 << 15) |
1686 		(ADV_MV_16_8_WEIGHT << 0));  /* adv_mv_16_8_weight */
1687 
1688 	hcodec_prog_qtbl(wq);
1689 	if (IDR) {
1690 		i_pic_qp =
1691 			wq->quant_tbl_i4[0] & 0xff;
1692 		i_pic_qp +=
1693 			wq->quant_tbl_i16[0] & 0xff;
1694 		i_pic_qp /= 2;
1695 		p_pic_qp = i_pic_qp;
1696 	} else {
1697 		i_pic_qp =
1698 			wq->quant_tbl_i4[0] & 0xff;
1699 		i_pic_qp +=
1700 			wq->quant_tbl_i16[0] & 0xff;
1701 		p_pic_qp = wq->quant_tbl_me[0] & 0xff;
1702 		slice_qp = (i_pic_qp + p_pic_qp) / 3;
1703 		i_pic_qp = slice_qp;
1704 		p_pic_qp = i_pic_qp;
1705 	}
1706 #ifdef H264_ENC_CBR
1707 	if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) {
1708 		data32 = READ_HREG(HCODEC_SAD_CONTROL_1);
1709 		data32 = data32 & 0xffff; /* remove sad shift */
1710 		WRITE_HREG(HCODEC_SAD_CONTROL_1, data32);
1711 		WRITE_HREG(H264_ENC_CBR_TABLE_ADDR,
1712 			wq->mem.cbr_info_ddr_start_addr);
1713 		WRITE_HREG(H264_ENC_CBR_MB_SIZE_ADDR,
1714 			wq->mem.cbr_info_ddr_start_addr
1715 			+ CBR_TABLE_SIZE);
1716 		WRITE_HREG(H264_ENC_CBR_CTL,
1717 			(wq->cbr_info.start_tbl_id << 28) |
1718 			(wq->cbr_info.short_shift << 24) |
1719 			(wq->cbr_info.long_mb_num << 16) |
1720 			(wq->cbr_info.long_th << 0));
1721 		WRITE_HREG(H264_ENC_CBR_REGION_SIZE,
1722 			(wq->cbr_info.block_w << 16) |
1723 			(wq->cbr_info.block_h << 0));
1724 	}
1725 #endif
1726 	WRITE_HREG(HCODEC_QDCT_VLC_QUANT_CTL_0,
1727 		(0 << 19) | /* vlc_delta_quant_1 */
1728 		(i_pic_qp << 13) | /* vlc_quant_1 */
1729 		(0 << 6) | /* vlc_delta_quant_0 */
1730 		(i_pic_qp << 0)); /* vlc_quant_0 */
1731 	WRITE_HREG(HCODEC_QDCT_VLC_QUANT_CTL_1,
1732 		(14 << 6) | /* vlc_max_delta_q_neg */
1733 		(13 << 0)); /* vlc_max_delta_q_pos */
1734 	WRITE_HREG(HCODEC_VLC_PIC_SIZE,
1735 		pic_width | (pic_height << 16));
1736 	WRITE_HREG(HCODEC_VLC_PIC_POSITION,
1737 		(pic_mb_nr << 16) |
1738 		(pic_mby << 8) |
1739 		(pic_mbx << 0));
1740 
1741 	/* synopsys parallel_case full_case */
1742 	switch (i_pic_qp) {
1743 	case 0:
1744 		i_pic_qp_c = 0;
1745 		break;
1746 	case 1:
1747 		i_pic_qp_c = 1;
1748 		break;
1749 	case 2:
1750 		i_pic_qp_c = 2;
1751 		break;
1752 	case 3:
1753 		i_pic_qp_c = 3;
1754 		break;
1755 	case 4:
1756 		i_pic_qp_c = 4;
1757 		break;
1758 	case 5:
1759 		i_pic_qp_c = 5;
1760 		break;
1761 	case 6:
1762 		i_pic_qp_c = 6;
1763 		break;
1764 	case 7:
1765 		i_pic_qp_c = 7;
1766 		break;
1767 	case 8:
1768 		i_pic_qp_c = 8;
1769 		break;
1770 	case 9:
1771 		i_pic_qp_c = 9;
1772 		break;
1773 	case 10:
1774 		i_pic_qp_c = 10;
1775 		break;
1776 	case 11:
1777 		i_pic_qp_c = 11;
1778 		break;
1779 	case 12:
1780 		i_pic_qp_c = 12;
1781 		break;
1782 	case 13:
1783 		i_pic_qp_c = 13;
1784 		break;
1785 	case 14:
1786 		i_pic_qp_c = 14;
1787 		break;
1788 	case 15:
1789 		i_pic_qp_c = 15;
1790 		break;
1791 	case 16:
1792 		i_pic_qp_c = 16;
1793 		break;
1794 	case 17:
1795 		i_pic_qp_c = 17;
1796 		break;
1797 	case 18:
1798 		i_pic_qp_c = 18;
1799 		break;
1800 	case 19:
1801 		i_pic_qp_c = 19;
1802 		break;
1803 	case 20:
1804 		i_pic_qp_c = 20;
1805 		break;
1806 	case 21:
1807 		i_pic_qp_c = 21;
1808 		break;
1809 	case 22:
1810 		i_pic_qp_c = 22;
1811 		break;
1812 	case 23:
1813 		i_pic_qp_c = 23;
1814 		break;
1815 	case 24:
1816 		i_pic_qp_c = 24;
1817 		break;
1818 	case 25:
1819 		i_pic_qp_c = 25;
1820 		break;
1821 	case 26:
1822 		i_pic_qp_c = 26;
1823 		break;
1824 	case 27:
1825 		i_pic_qp_c = 27;
1826 		break;
1827 	case 28:
1828 		i_pic_qp_c = 28;
1829 		break;
1830 	case 29:
1831 		i_pic_qp_c = 29;
1832 		break;
1833 	case 30:
1834 		i_pic_qp_c = 29;
1835 		break;
1836 	case 31:
1837 		i_pic_qp_c = 30;
1838 		break;
1839 	case 32:
1840 		i_pic_qp_c = 31;
1841 		break;
1842 	case 33:
1843 		i_pic_qp_c = 32;
1844 		break;
1845 	case 34:
1846 		i_pic_qp_c = 32;
1847 		break;
1848 	case 35:
1849 		i_pic_qp_c = 33;
1850 		break;
1851 	case 36:
1852 		i_pic_qp_c = 34;
1853 		break;
1854 	case 37:
1855 		i_pic_qp_c = 34;
1856 		break;
1857 	case 38:
1858 		i_pic_qp_c = 35;
1859 		break;
1860 	case 39:
1861 		i_pic_qp_c = 35;
1862 		break;
1863 	case 40:
1864 		i_pic_qp_c = 36;
1865 		break;
1866 	case 41:
1867 		i_pic_qp_c = 36;
1868 		break;
1869 	case 42:
1870 		i_pic_qp_c = 37;
1871 		break;
1872 	case 43:
1873 		i_pic_qp_c = 37;
1874 		break;
1875 	case 44:
1876 		i_pic_qp_c = 37;
1877 		break;
1878 	case 45:
1879 		i_pic_qp_c = 38;
1880 		break;
1881 	case 46:
1882 		i_pic_qp_c = 38;
1883 		break;
1884 	case 47:
1885 		i_pic_qp_c = 38;
1886 		break;
1887 	case 48:
1888 		i_pic_qp_c = 39;
1889 		break;
1890 	case 49:
1891 		i_pic_qp_c = 39;
1892 		break;
1893 	case 50:
1894 		i_pic_qp_c = 39;
1895 		break;
1896 	default:
1897 		i_pic_qp_c = 39;
1898 		break;
1899 	}
1900 
1901 	/* synopsys parallel_case full_case */
1902 	switch (p_pic_qp) {
1903 	case 0:
1904 		p_pic_qp_c = 0;
1905 		break;
1906 	case 1:
1907 		p_pic_qp_c = 1;
1908 		break;
1909 	case 2:
1910 		p_pic_qp_c = 2;
1911 		break;
1912 	case 3:
1913 		p_pic_qp_c = 3;
1914 		break;
1915 	case 4:
1916 		p_pic_qp_c = 4;
1917 		break;
1918 	case 5:
1919 		p_pic_qp_c = 5;
1920 		break;
1921 	case 6:
1922 		p_pic_qp_c = 6;
1923 		break;
1924 	case 7:
1925 		p_pic_qp_c = 7;
1926 		break;
1927 	case 8:
1928 		p_pic_qp_c = 8;
1929 		break;
1930 	case 9:
1931 		p_pic_qp_c = 9;
1932 		break;
1933 	case 10:
1934 		p_pic_qp_c = 10;
1935 		break;
1936 	case 11:
1937 		p_pic_qp_c = 11;
1938 		break;
1939 	case 12:
1940 		p_pic_qp_c = 12;
1941 		break;
1942 	case 13:
1943 		p_pic_qp_c = 13;
1944 		break;
1945 	case 14:
1946 		p_pic_qp_c = 14;
1947 		break;
1948 	case 15:
1949 		p_pic_qp_c = 15;
1950 		break;
1951 	case 16:
1952 		p_pic_qp_c = 16;
1953 		break;
1954 	case 17:
1955 		p_pic_qp_c = 17;
1956 		break;
1957 	case 18:
1958 		p_pic_qp_c = 18;
1959 		break;
1960 	case 19:
1961 		p_pic_qp_c = 19;
1962 		break;
1963 	case 20:
1964 		p_pic_qp_c = 20;
1965 		break;
1966 	case 21:
1967 		p_pic_qp_c = 21;
1968 		break;
1969 	case 22:
1970 		p_pic_qp_c = 22;
1971 		break;
1972 	case 23:
1973 		p_pic_qp_c = 23;
1974 		break;
1975 	case 24:
1976 		p_pic_qp_c = 24;
1977 		break;
1978 	case 25:
1979 		p_pic_qp_c = 25;
1980 		break;
1981 	case 26:
1982 		p_pic_qp_c = 26;
1983 		break;
1984 	case 27:
1985 		p_pic_qp_c = 27;
1986 		break;
1987 	case 28:
1988 		p_pic_qp_c = 28;
1989 		break;
1990 	case 29:
1991 		p_pic_qp_c = 29;
1992 		break;
1993 	case 30:
1994 		p_pic_qp_c = 29;
1995 		break;
1996 	case 31:
1997 		p_pic_qp_c = 30;
1998 		break;
1999 	case 32:
2000 		p_pic_qp_c = 31;
2001 		break;
2002 	case 33:
2003 		p_pic_qp_c = 32;
2004 		break;
2005 	case 34:
2006 		p_pic_qp_c = 32;
2007 		break;
2008 	case 35:
2009 		p_pic_qp_c = 33;
2010 		break;
2011 	case 36:
2012 		p_pic_qp_c = 34;
2013 		break;
2014 	case 37:
2015 		p_pic_qp_c = 34;
2016 		break;
2017 	case 38:
2018 		p_pic_qp_c = 35;
2019 		break;
2020 	case 39:
2021 		p_pic_qp_c = 35;
2022 		break;
2023 	case 40:
2024 		p_pic_qp_c = 36;
2025 		break;
2026 	case 41:
2027 		p_pic_qp_c = 36;
2028 		break;
2029 	case 42:
2030 		p_pic_qp_c = 37;
2031 		break;
2032 	case 43:
2033 		p_pic_qp_c = 37;
2034 		break;
2035 	case 44:
2036 		p_pic_qp_c = 37;
2037 		break;
2038 	case 45:
2039 		p_pic_qp_c = 38;
2040 		break;
2041 	case 46:
2042 		p_pic_qp_c = 38;
2043 		break;
2044 	case 47:
2045 		p_pic_qp_c = 38;
2046 		break;
2047 	case 48:
2048 		p_pic_qp_c = 39;
2049 		break;
2050 	case 49:
2051 		p_pic_qp_c = 39;
2052 		break;
2053 	case 50:
2054 		p_pic_qp_c = 39;
2055 		break;
2056 	default:
2057 		p_pic_qp_c = 39;
2058 		break;
2059 	}
2060 	WRITE_HREG(HCODEC_QDCT_Q_QUANT_I,
2061 		(i_pic_qp_c << 22) |
2062 		(i_pic_qp << 16) |
2063 		((i_pic_qp_c % 6) << 12) |
2064 		((i_pic_qp_c / 6) << 8) |
2065 		((i_pic_qp % 6) << 4) |
2066 		((i_pic_qp / 6) << 0));
2067 
2068 	WRITE_HREG(HCODEC_QDCT_Q_QUANT_P,
2069 		(p_pic_qp_c << 22) |
2070 		(p_pic_qp << 16) |
2071 		((p_pic_qp_c % 6) << 12) |
2072 		((p_pic_qp_c / 6) << 8) |
2073 		((p_pic_qp % 6) << 4) |
2074 		((p_pic_qp / 6) << 0));
2075 
2076 #ifdef ENABLE_IGNORE_FUNCTION
2077 	WRITE_HREG(HCODEC_IGNORE_CONFIG,
2078 		(1 << 31) | /* ignore_lac_coeff_en */
2079 		(1 << 26) | /* ignore_lac_coeff_else (<1) */
2080 		(1 << 21) | /* ignore_lac_coeff_2 (<1) */
2081 		(2 << 16) | /* ignore_lac_coeff_1 (<2) */
2082 		(1 << 15) | /* ignore_cac_coeff_en */
2083 		(1 << 10) | /* ignore_cac_coeff_else (<1) */
2084 		(1 << 5)  | /* ignore_cac_coeff_2 (<1) */
2085 		(3 << 0));  /* ignore_cac_coeff_1 (<2) */
2086 
2087 	if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB)
2088 		WRITE_HREG(HCODEC_IGNORE_CONFIG_2,
2089 			(1 << 31) | /* ignore_t_lac_coeff_en */
2090 			(1 << 26) | /* ignore_t_lac_coeff_else (<1) */
2091 			(2 << 21) | /* ignore_t_lac_coeff_2 (<2) */
2092 			(6 << 16) | /* ignore_t_lac_coeff_1 (<6) */
2093 			(1<<15) | /* ignore_cdc_coeff_en */
2094 			(0<<14) | /* ignore_t_lac_coeff_else_le_3 */
2095 			(1<<13) | /* ignore_t_lac_coeff_else_le_4 */
2096 			(1<<12) | /* ignore_cdc_only_when_empty_cac_inter */
2097 			(1<<11) | /* ignore_cdc_only_when_one_empty_inter */
2098 			/* ignore_cdc_range_max_inter 0-0, 1-1, 2-2, 3-3 */
2099 			(2<<9) |
2100 			/* ignore_cdc_abs_max_inter 0-1, 1-2, 2-3, 3-4 */
2101 			(0<<7) |
2102 			/* ignore_cdc_only_when_empty_cac_intra */
2103 			(1<<5) |
2104 			/* ignore_cdc_only_when_one_empty_intra */
2105 			(1<<4) |
2106 			/* ignore_cdc_range_max_intra 0-0, 1-1, 2-2, 3-3 */
2107 			(1<<2) |
2108 			/* ignore_cdc_abs_max_intra 0-1, 1-2, 2-3, 3-4 */
2109 			(0<<0));
2110 	else
2111 		WRITE_HREG(HCODEC_IGNORE_CONFIG_2,
2112 			(1 << 31) | /* ignore_t_lac_coeff_en */
2113 			(1 << 26) | /* ignore_t_lac_coeff_else (<1) */
2114 			(1 << 21) | /* ignore_t_lac_coeff_2 (<1) */
2115 			(5 << 16) | /* ignore_t_lac_coeff_1 (<5) */
2116 			(0 << 0));
2117 #else
2118 	WRITE_HREG(HCODEC_IGNORE_CONFIG, 0);
2119 	WRITE_HREG(HCODEC_IGNORE_CONFIG_2, 0);
2120 #endif
2121 
2122 	WRITE_HREG(HCODEC_QDCT_MB_CONTROL,
2123 		(1 << 9) | /* mb_info_soft_reset */
2124 		(1 << 0)); /* mb read buffer soft reset */
2125 
2126 	WRITE_HREG(HCODEC_QDCT_MB_CONTROL,
2127 		(1 << 28) | /* ignore_t_p8x8 */
2128 		(0 << 27) | /* zero_mc_out_null_non_skipped_mb */
2129 		(0 << 26) | /* no_mc_out_null_non_skipped_mb */
2130 		(0 << 25) | /* mc_out_even_skipped_mb */
2131 		(0 << 24) | /* mc_out_wait_cbp_ready */
2132 		(0 << 23) | /* mc_out_wait_mb_type_ready */
2133 		(1 << 29) | /* ie_start_int_enable */
2134 		(1 << 19) | /* i_pred_enable */
2135 		(1 << 20) | /* ie_sub_enable */
2136 		(1 << 18) | /* iq_enable */
2137 		(1 << 17) | /* idct_enable */
2138 		(1 << 14) | /* mb_pause_enable */
2139 		(1 << 13) | /* q_enable */
2140 		(1 << 12) | /* dct_enable */
2141 		(1 << 10) | /* mb_info_en */
2142 		(0 << 3) | /* endian */
2143 		(0 << 1) | /* mb_read_en */
2144 		(0 << 0)); /* soft reset */
2145 
2146 	WRITE_HREG(HCODEC_SAD_CONTROL,
2147 		(0 << 3) | /* ie_result_buff_enable */
2148 		(1 << 2) | /* ie_result_buff_soft_reset */
2149 		(0 << 1) | /* sad_enable */
2150 		(1 << 0)); /* sad soft reset */
2151 	WRITE_HREG(HCODEC_IE_RESULT_BUFFER, 0);
2152 
2153 	WRITE_HREG(HCODEC_SAD_CONTROL,
2154 		(1 << 3) | /* ie_result_buff_enable */
2155 		(0 << 2) | /* ie_result_buff_soft_reset */
2156 		(1 << 1) | /* sad_enable */
2157 		(0 << 0)); /* sad soft reset */
2158 
2159 	WRITE_HREG(HCODEC_IE_CONTROL,
2160 		(1 << 30) | /* active_ul_block */
2161 		(0 << 1) | /* ie_enable */
2162 		(1 << 0)); /* ie soft reset */
2163 
2164 	WRITE_HREG(HCODEC_IE_CONTROL,
2165 		(1 << 30) | /* active_ul_block */
2166 		(0 << 1) | /* ie_enable */
2167 		(0 << 0)); /* ie soft reset */
2168 
2169 	WRITE_HREG(HCODEC_ME_SKIP_LINE,
2170 		(8 << 24) | /* step_3_skip_line */
2171 		(8 << 18) | /* step_2_skip_line */
2172 		(2 << 12) | /* step_1_skip_line */
2173 		(0 << 6) | /* step_0_skip_line */
2174 		(0 << 0));
2175 
2176 	WRITE_HREG(HCODEC_ME_MV_MERGE_CTL, me_mv_merge_ctl);
2177 	WRITE_HREG(HCODEC_ME_STEP0_CLOSE_MV, me_step0_close_mv);
2178 	WRITE_HREG(HCODEC_ME_SAD_ENOUGH_01, me_sad_enough_01);
2179 	WRITE_HREG(HCODEC_ME_SAD_ENOUGH_23, me_sad_enough_23);
2180 	WRITE_HREG(HCODEC_ME_F_SKIP_SAD, me_f_skip_sad);
2181 	WRITE_HREG(HCODEC_ME_F_SKIP_WEIGHT, me_f_skip_weight);
2182 	WRITE_HREG(HCODEC_ME_MV_WEIGHT_01, me_mv_weight_01);
2183 	WRITE_HREG(HCODEC_ME_MV_WEIGHT_23, me_mv_weight_23);
2184 	WRITE_HREG(HCODEC_ME_SAD_RANGE_INC, me_sad_range_inc);
2185 
2186 	if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL) {
2187 		WRITE_HREG(HCODEC_V5_SIMPLE_MB_CTL, 0);
2188 		WRITE_HREG(HCODEC_V5_SIMPLE_MB_CTL,
2189 			(v5_use_small_diff_cnt << 7) |
2190 			(v5_simple_mb_inter_all_en << 6) |
2191 			(v5_simple_mb_inter_8x8_en << 5) |
2192 			(v5_simple_mb_inter_16_8_en << 4) |
2193 			(v5_simple_mb_inter_16x16_en << 3) |
2194 			(v5_simple_mb_intra_en << 2) |
2195 			(v5_simple_mb_C_en << 1) |
2196 			(v5_simple_mb_Y_en << 0));
2197 		WRITE_HREG(HCODEC_V5_MB_DIFF_SUM, 0);
2198 		WRITE_HREG(HCODEC_V5_SMALL_DIFF_CNT,
2199 			(v5_small_diff_C<<16) |
2200 			(v5_small_diff_Y<<0));
2201 		if (qp_mode == 1) {
2202 			WRITE_HREG(HCODEC_V5_SIMPLE_MB_DQUANT,
2203 				0);
2204 		} else {
2205 			WRITE_HREG(HCODEC_V5_SIMPLE_MB_DQUANT,
2206 				v5_simple_dq_setting);
2207 		}
2208 		WRITE_HREG(HCODEC_V5_SIMPLE_MB_ME_WEIGHT,
2209 			v5_simple_me_weight_setting);
2210 		/* txlx can remove it */
2211 		WRITE_HREG(HCODEC_QDCT_CONFIG, 1 << 0);
2212 	}
2213 
2214 	if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) {
2215 		WRITE_HREG(HCODEC_V4_FORCE_SKIP_CFG,
2216 			(i_pic_qp << 26) | /* v4_force_q_r_intra */
2217 			(i_pic_qp << 20) | /* v4_force_q_r_inter */
2218 			(0 << 19) | /* v4_force_q_y_enable */
2219 			(5 << 16) | /* v4_force_qr_y */
2220 			(6 << 12) | /* v4_force_qp_y */
2221 			(0 << 0)); /* v4_force_skip_sad */
2222 
2223 		/* V3 Force skip */
2224 		WRITE_HREG(HCODEC_V3_SKIP_CONTROL,
2225 			(1 << 31) | /* v3_skip_enable */
2226 			(0 << 30) | /* v3_step_1_weight_enable */
2227 			(1 << 28) | /* v3_mv_sad_weight_enable */
2228 			(1 << 27) | /* v3_ipred_type_enable */
2229 			(V3_FORCE_SKIP_SAD_1 << 12) |
2230 			(V3_FORCE_SKIP_SAD_0 << 0));
2231 		WRITE_HREG(HCODEC_V3_SKIP_WEIGHT,
2232 			(V3_SKIP_WEIGHT_1 << 16) |
2233 			(V3_SKIP_WEIGHT_0 << 0));
2234 		WRITE_HREG(HCODEC_V3_L1_SKIP_MAX_SAD,
2235 			(V3_LEVEL_1_F_SKIP_MAX_SAD << 16) |
2236 			(V3_LEVEL_1_SKIP_MAX_SAD << 0));
2237 		WRITE_HREG(HCODEC_V3_L2_SKIP_WEIGHT,
2238 			(V3_FORCE_SKIP_SAD_2 << 16) |
2239 			(V3_SKIP_WEIGHT_2 << 0));
2240 		if (request != NULL) {
2241 			unsigned int off1, off2;
2242 
2243 			off1 = V3_IE_F_ZERO_SAD_I4 - I4MB_WEIGHT_OFFSET;
2244 			off2 = V3_IE_F_ZERO_SAD_I16
2245 				- I16MB_WEIGHT_OFFSET;
2246 			WRITE_HREG(HCODEC_V3_F_ZERO_CTL_0,
2247 				((request->i16_weight + off2) << 16) |
2248 				((request->i4_weight + off1) << 0));
2249 			off1 = V3_ME_F_ZERO_SAD - ME_WEIGHT_OFFSET;
2250 			WRITE_HREG(HCODEC_V3_F_ZERO_CTL_1,
2251 				(0 << 25) |
2252 				/* v3_no_ver_when_top_zero_en */
2253 				(0 << 24) |
2254 				/* v3_no_hor_when_left_zero_en */
2255 				(3 << 16) |  /* type_hor break */
2256 				((request->me_weight + off1) << 0));
2257 		} else {
2258 			WRITE_HREG(HCODEC_V3_F_ZERO_CTL_0,
2259 				(V3_IE_F_ZERO_SAD_I16 << 16) |
2260 				(V3_IE_F_ZERO_SAD_I4 << 0));
2261 			WRITE_HREG(HCODEC_V3_F_ZERO_CTL_1,
2262 				(0 << 25) |
2263 				/* v3_no_ver_when_top_zero_en */
2264 				(0 << 24) |
2265 				/* v3_no_hor_when_left_zero_en */
2266 				(3 << 16) |  /* type_hor break */
2267 				(V3_ME_F_ZERO_SAD << 0));
2268 		}
2269 	} else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) {
2270 		/* V3 Force skip */
2271 		WRITE_HREG(HCODEC_V3_SKIP_CONTROL,
2272 			(1 << 31) | /* v3_skip_enable */
2273 			(0 << 30) | /* v3_step_1_weight_enable */
2274 			(1 << 28) | /* v3_mv_sad_weight_enable */
2275 			(1 << 27) | /* v3_ipred_type_enable */
2276 			(0 << 12) | /* V3_FORCE_SKIP_SAD_1 */
2277 			(0 << 0)); /* V3_FORCE_SKIP_SAD_0 */
2278 		WRITE_HREG(HCODEC_V3_SKIP_WEIGHT,
2279 			(V3_SKIP_WEIGHT_1 << 16) |
2280 			(V3_SKIP_WEIGHT_0 << 0));
2281 		WRITE_HREG(HCODEC_V3_L1_SKIP_MAX_SAD,
2282 			(V3_LEVEL_1_F_SKIP_MAX_SAD << 16) |
2283 			(V3_LEVEL_1_SKIP_MAX_SAD << 0));
2284 		WRITE_HREG(HCODEC_V3_L2_SKIP_WEIGHT,
2285 			(0 << 16) | /* V3_FORCE_SKIP_SAD_2 */
2286 			(V3_SKIP_WEIGHT_2 << 0));
2287 		WRITE_HREG(HCODEC_V3_F_ZERO_CTL_0,
2288 			(0 << 16) | /* V3_IE_F_ZERO_SAD_I16 */
2289 			(0 << 0)); /* V3_IE_F_ZERO_SAD_I4 */
2290 		WRITE_HREG(HCODEC_V3_F_ZERO_CTL_1,
2291 			(0 << 25) | /* v3_no_ver_when_top_zero_en */
2292 			(0 << 24) | /* v3_no_hor_when_left_zero_en */
2293 			(3 << 16) |  /* type_hor break */
2294 			(0 << 0)); /* V3_ME_F_ZERO_SAD */
2295 	}
2296 	if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) {
2297 		int i;
2298 		/* MV SAD Table */
2299 		for (i = 0; i < 64; i++)
2300 			WRITE_HREG(HCODEC_V3_MV_SAD_TABLE,
2301 				v3_mv_sad[i]);
2302 
2303 		/* IE PRED SAD Table*/
2304 		WRITE_HREG(HCODEC_V3_IPRED_TYPE_WEIGHT_0,
2305 			(C_ipred_weight_H << 24) |
2306 			(C_ipred_weight_V << 16) |
2307 			(I4_ipred_weight_else << 8) |
2308 			(I4_ipred_weight_most << 0));
2309 		WRITE_HREG(HCODEC_V3_IPRED_TYPE_WEIGHT_1,
2310 			(I16_ipred_weight_DC << 24) |
2311 			(I16_ipred_weight_H << 16) |
2312 			(I16_ipred_weight_V << 8) |
2313 			(C_ipred_weight_DC << 0));
2314 		WRITE_HREG(HCODEC_V3_LEFT_SMALL_MAX_SAD,
2315 			(v3_left_small_max_me_sad << 16) |
2316 			(v3_left_small_max_ie_sad << 0));
2317 	}
2318 	WRITE_HREG(HCODEC_IE_DATA_FEED_BUFF_INFO, 0);
2319 	WRITE_HREG(HCODEC_CURR_CANVAS_CTRL, 0);
2320 	data32 = READ_HREG(HCODEC_VLC_CONFIG);
2321 	data32 = data32 | (1 << 0); /* set pop_coeff_even_all_zero */
2322 	WRITE_HREG(HCODEC_VLC_CONFIG, data32);
2323 
2324 	WRITE_HREG(INFO_DUMP_START_ADDR,
2325 		wq->mem.dump_info_ddr_start_addr);
2326 
2327 	/* clear mailbox interrupt */
2328 	WRITE_HREG(HCODEC_IRQ_MBOX_CLR, 1);
2329 
2330 	/* enable mailbox interrupt */
2331 	WRITE_HREG(HCODEC_IRQ_MBOX_MASK, 1);
2332 }
2333 
amvenc_reset(void)2334 void amvenc_reset(void)
2335 {
2336 	READ_VREG(DOS_SW_RESET1);
2337 	READ_VREG(DOS_SW_RESET1);
2338 	READ_VREG(DOS_SW_RESET1);
2339 	WRITE_VREG(DOS_SW_RESET1,
2340 		(1 << 2) | (1 << 6) |
2341 		(1 << 7) | (1 << 8) |
2342 		(1 << 14) | (1 << 16) |
2343 		(1 << 17));
2344 	WRITE_VREG(DOS_SW_RESET1, 0);
2345 	READ_VREG(DOS_SW_RESET1);
2346 	READ_VREG(DOS_SW_RESET1);
2347 	READ_VREG(DOS_SW_RESET1);
2348 }
2349 
amvenc_start(void)2350 void amvenc_start(void)
2351 {
2352 	READ_VREG(DOS_SW_RESET1);
2353 	READ_VREG(DOS_SW_RESET1);
2354 	READ_VREG(DOS_SW_RESET1);
2355 	WRITE_VREG(DOS_SW_RESET1,
2356 		(1 << 12) | (1 << 11));
2357 	WRITE_VREG(DOS_SW_RESET1, 0);
2358 
2359 	READ_VREG(DOS_SW_RESET1);
2360 	READ_VREG(DOS_SW_RESET1);
2361 	READ_VREG(DOS_SW_RESET1);
2362 
2363 	WRITE_HREG(HCODEC_MPSR, 0x0001);
2364 }
2365 
amvenc_stop(void)2366 void amvenc_stop(void)
2367 {
2368 	ulong timeout = jiffies + HZ;
2369 
2370 	WRITE_HREG(HCODEC_MPSR, 0);
2371 	WRITE_HREG(HCODEC_CPSR, 0);
2372 	while (READ_HREG(HCODEC_IMEM_DMA_CTRL) & 0x8000) {
2373 		if (time_after(jiffies, timeout))
2374 			break;
2375 	}
2376 	READ_VREG(DOS_SW_RESET1);
2377 	READ_VREG(DOS_SW_RESET1);
2378 	READ_VREG(DOS_SW_RESET1);
2379 
2380 	WRITE_VREG(DOS_SW_RESET1,
2381 		(1 << 12) | (1 << 11) |
2382 		(1 << 2) | (1 << 6) |
2383 		(1 << 7) | (1 << 8) |
2384 		(1 << 14) | (1 << 16) |
2385 		(1 << 17));
2386 
2387 	WRITE_VREG(DOS_SW_RESET1, 0);
2388 
2389 	READ_VREG(DOS_SW_RESET1);
2390 	READ_VREG(DOS_SW_RESET1);
2391 	READ_VREG(DOS_SW_RESET1);
2392 }
2393 
2394 static void __iomem *mc_addr;
2395 static u32 mc_addr_map;
2396 #define MC_SIZE (4096 * 8)
amvenc_loadmc(const char * p,struct encode_wq_s * wq)2397 s32 amvenc_loadmc(const char *p, struct encode_wq_s *wq)
2398 {
2399 	ulong timeout;
2400 	s32 ret = 0;
2401 
2402 	/* use static mempry*/
2403 	if (mc_addr == NULL) {
2404 		mc_addr = kmalloc(MC_SIZE, GFP_KERNEL);
2405 		if (!mc_addr) {
2406 			enc_pr(LOG_ERROR, "avc loadmc iomap mc addr error.\n");
2407 			return -ENOMEM;
2408 		}
2409 	}
2410 
2411 	enc_pr(LOG_ALL, "avc encode ucode name is %s\n", p);
2412 	ret = get_data_from_name(p, (u8 *)mc_addr);
2413 	if (ret < 0) {
2414 		enc_pr(LOG_ERROR,
2415 			"avc microcode fail ret=%d, name: %s, wq:%p.\n",
2416 			ret, p, (void *)wq);
2417 	}
2418 
2419 	mc_addr_map = dma_map_single(
2420 		&encode_manager.this_pdev->dev,
2421 		mc_addr, MC_SIZE, DMA_TO_DEVICE);
2422 
2423 	/* mc_addr_map = wq->mem.assit_buffer_offset; */
2424 	/* mc_addr = ioremap_wc(mc_addr_map, MC_SIZE); */
2425 	/* memcpy(mc_addr, p, MC_SIZE); */
2426 	enc_pr(LOG_ALL, "address 0 is 0x%x\n", *((u32 *)mc_addr));
2427 	enc_pr(LOG_ALL, "address 1 is 0x%x\n", *((u32 *)mc_addr + 1));
2428 	enc_pr(LOG_ALL, "address 2 is 0x%x\n", *((u32 *)mc_addr + 2));
2429 	enc_pr(LOG_ALL, "address 3 is 0x%x\n", *((u32 *)mc_addr + 3));
2430 	WRITE_HREG(HCODEC_MPSR, 0);
2431 	WRITE_HREG(HCODEC_CPSR, 0);
2432 
2433 	/* Read CBUS register for timing */
2434 	timeout = READ_HREG(HCODEC_MPSR);
2435 	timeout = READ_HREG(HCODEC_MPSR);
2436 
2437 	timeout = jiffies + HZ;
2438 
2439 	WRITE_HREG(HCODEC_IMEM_DMA_ADR, mc_addr_map);
2440 	WRITE_HREG(HCODEC_IMEM_DMA_COUNT, 0x1000);
2441 	WRITE_HREG(HCODEC_IMEM_DMA_CTRL, (0x8000 | (7 << 16)));
2442 
2443 	while (READ_HREG(HCODEC_IMEM_DMA_CTRL) & 0x8000) {
2444 		if (time_before(jiffies, timeout))
2445 			schedule();
2446 		else {
2447 			enc_pr(LOG_ERROR, "hcodec load mc error\n");
2448 			ret = -EBUSY;
2449 			break;
2450 		}
2451 	}
2452 	dma_unmap_single(
2453 		&encode_manager.this_pdev->dev,
2454 		mc_addr_map, MC_SIZE, DMA_TO_DEVICE);
2455 	return ret;
2456 }
2457 
2458 const u32 fix_mc[] __aligned(8) = {
2459 	0x0809c05a, 0x06696000, 0x0c780000, 0x00000000
2460 };
2461 
2462 
2463 /*
2464  * DOS top level register access fix.
2465  * When hcodec is running, a protocol register HCODEC_CCPU_INTR_MSK
2466  * is set to make hcodec access one CBUS out of DOS domain once
2467  * to work around a HW bug for 4k2k dual decoder implementation.
2468  * If hcodec is not running, then a ucode is loaded and executed
2469  * instead.
2470  */
amvenc_dos_top_reg_fix(void)2471 void amvenc_dos_top_reg_fix(void)
2472 {
2473 	bool hcodec_on;
2474 	ulong flags;
2475 
2476 	spin_lock_irqsave(&lock, flags);
2477 
2478 	hcodec_on = vdec_on(VDEC_HCODEC);
2479 
2480 	if ((hcodec_on) && (READ_VREG(HCODEC_MPSR) & 1)) {
2481 		WRITE_HREG(HCODEC_CCPU_INTR_MSK, 1);
2482 		spin_unlock_irqrestore(&lock, flags);
2483 		return;
2484 	}
2485 
2486 	if (!hcodec_on)
2487 		vdec_poweron(VDEC_HCODEC);
2488 
2489 	amhcodec_loadmc(fix_mc);
2490 
2491 	amhcodec_start();
2492 
2493 	udelay(1000);
2494 
2495 	amhcodec_stop();
2496 
2497 	if (!hcodec_on)
2498 		vdec_poweroff(VDEC_HCODEC);
2499 
2500 	spin_unlock_irqrestore(&lock, flags);
2501 }
2502 
amvenc_avc_on(void)2503 bool amvenc_avc_on(void)
2504 {
2505 	bool hcodec_on;
2506 	ulong flags;
2507 
2508 	spin_lock_irqsave(&lock, flags);
2509 
2510 	hcodec_on = vdec_on(VDEC_HCODEC);
2511 	hcodec_on &= (encode_manager.wq_count > 0);
2512 
2513 	spin_unlock_irqrestore(&lock, flags);
2514 	return hcodec_on;
2515 }
2516 
avc_poweron(u32 clock)2517 static s32 avc_poweron(u32 clock)
2518 {
2519 	ulong flags;
2520 	u32 data32;
2521 
2522 	data32 = 0;
2523 
2524 	amports_switch_gate("clk_hcodec_mux", 1);
2525 
2526 	spin_lock_irqsave(&lock, flags);
2527 
2528 	WRITE_AOREG(AO_RTI_PWR_CNTL_REG0,
2529 		(READ_AOREG(AO_RTI_PWR_CNTL_REG0) & (~0x18)));
2530 	udelay(10);
2531 	/* Powerup HCODEC */
2532 	/* [1:0] HCODEC */
2533 	WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
2534 			READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) &
2535 			((get_cpu_type() == MESON_CPU_MAJOR_ID_SM1 ||
2536 			 get_cpu_type() >= MESON_CPU_MAJOR_ID_TM2)
2537 			? ~0x1 : ~0x3));
2538 
2539 	udelay(10);
2540 
2541 	WRITE_VREG(DOS_SW_RESET1, 0xffffffff);
2542 	WRITE_VREG(DOS_SW_RESET1, 0);
2543 
2544 	/* Enable Dos internal clock gating */
2545 	hvdec_clock_enable(clock);
2546 
2547 	/* Powerup HCODEC memories */
2548 	WRITE_VREG(DOS_MEM_PD_HCODEC, 0x0);
2549 
2550 	/* Remove HCODEC ISO */
2551 	WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
2552 			READ_AOREG(AO_RTI_GEN_PWR_ISO0) &
2553 			((get_cpu_type() == MESON_CPU_MAJOR_ID_SM1 ||
2554 			  get_cpu_type() >= MESON_CPU_MAJOR_ID_TM2)
2555 			? ~0x1 : ~0x30));
2556 
2557 	udelay(10);
2558 	/* Disable auto-clock gate */
2559 	WRITE_VREG(DOS_GEN_CTRL0,
2560 		(READ_VREG(DOS_GEN_CTRL0) | 0x1));
2561 	WRITE_VREG(DOS_GEN_CTRL0,
2562 		(READ_VREG(DOS_GEN_CTRL0) & 0xFFFFFFFE));
2563 
2564 	spin_unlock_irqrestore(&lock, flags);
2565 
2566 	mdelay(10);
2567 	return 0;
2568 }
2569 
avc_poweroff(void)2570 static s32 avc_poweroff(void)
2571 {
2572 	ulong flags;
2573 
2574 	spin_lock_irqsave(&lock, flags);
2575 
2576 	/* enable HCODEC isolation */
2577 	WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
2578 			READ_AOREG(AO_RTI_GEN_PWR_ISO0) |
2579 			((get_cpu_type() == MESON_CPU_MAJOR_ID_SM1 ||
2580 			  get_cpu_type() >= MESON_CPU_MAJOR_ID_TM2)
2581 			? 0x1 : 0x30));
2582 
2583 	/* power off HCODEC memories */
2584 	WRITE_VREG(DOS_MEM_PD_HCODEC, 0xffffffffUL);
2585 
2586 	/* disable HCODEC clock */
2587 	hvdec_clock_disable();
2588 
2589 	/* HCODEC power off */
2590 	WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
2591 			READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) |
2592 			((get_cpu_type() == MESON_CPU_MAJOR_ID_SM1 ||
2593 			  get_cpu_type() >= MESON_CPU_MAJOR_ID_TM2)
2594 			? 0x1 : 0x3));
2595 
2596 	spin_unlock_irqrestore(&lock, flags);
2597 
2598 	/* release DOS clk81 clock gating */
2599 	amports_switch_gate("clk_hcodec_mux", 0);
2600 	return 0;
2601 }
2602 
reload_mc(struct encode_wq_s * wq)2603 static s32 reload_mc(struct encode_wq_s *wq)
2604 {
2605 	const char *p = select_ucode(encode_manager.ucode_index);
2606 
2607 	amvenc_stop();
2608 
2609 	WRITE_VREG(DOS_SW_RESET1, 0xffffffff);
2610 	WRITE_VREG(DOS_SW_RESET1, 0);
2611 
2612 	udelay(10);
2613 
2614 	WRITE_HREG(HCODEC_ASSIST_MMC_CTRL1, 0x32);
2615 	enc_pr(LOG_INFO, "reload microcode\n");
2616 
2617 	if (amvenc_loadmc(p, wq) < 0)
2618 		return -EBUSY;
2619 	return 0;
2620 }
2621 
encode_isr_tasklet(ulong data)2622 static void encode_isr_tasklet(ulong data)
2623 {
2624 	struct encode_manager_s *manager = (struct encode_manager_s *)data;
2625 
2626 	enc_pr(LOG_INFO, "encoder is done %d\n", manager->encode_hw_status);
2627 	if (((manager->encode_hw_status == ENCODER_IDR_DONE)
2628 		|| (manager->encode_hw_status == ENCODER_NON_IDR_DONE)
2629 		|| (manager->encode_hw_status == ENCODER_SEQUENCE_DONE)
2630 		|| (manager->encode_hw_status == ENCODER_PICTURE_DONE))
2631 		&& (manager->process_irq)) {
2632 		wake_up_interruptible(&manager->event.hw_complete);
2633 	}
2634 }
2635 
2636 /* irq function */
enc_isr(s32 irq_number,void * para)2637 static irqreturn_t enc_isr(s32 irq_number, void *para)
2638 {
2639 	struct encode_manager_s *manager = (struct encode_manager_s *)para;
2640 
2641 	WRITE_HREG(HCODEC_IRQ_MBOX_CLR, 1);
2642 
2643 	manager->encode_hw_status  = READ_HREG(ENCODER_STATUS);
2644 	if ((manager->encode_hw_status == ENCODER_IDR_DONE)
2645 		|| (manager->encode_hw_status == ENCODER_NON_IDR_DONE)
2646 		|| (manager->encode_hw_status == ENCODER_SEQUENCE_DONE)
2647 		|| (manager->encode_hw_status == ENCODER_PICTURE_DONE)) {
2648 		enc_pr(LOG_ALL, "encoder stage is %d\n",
2649 			manager->encode_hw_status);
2650 	}
2651 
2652 	if (((manager->encode_hw_status == ENCODER_IDR_DONE)
2653 		|| (manager->encode_hw_status == ENCODER_NON_IDR_DONE)
2654 		|| (manager->encode_hw_status == ENCODER_SEQUENCE_DONE)
2655 		|| (manager->encode_hw_status == ENCODER_PICTURE_DONE))
2656 		&& (!manager->process_irq)) {
2657 		manager->process_irq = true;
2658 		if (manager->encode_hw_status != ENCODER_SEQUENCE_DONE)
2659 			manager->need_reset = true;
2660 		tasklet_schedule(&manager->encode_tasklet);
2661 	}
2662 	return IRQ_HANDLED;
2663 }
2664 
convert_request(struct encode_wq_s * wq,u32 * cmd_info)2665 static s32 convert_request(struct encode_wq_s *wq, u32 *cmd_info)
2666 {
2667 	int i = 0;
2668 	u8 *ptr;
2669 	u32 data_offset;
2670 	u32 cmd = cmd_info[0];
2671 	unsigned long paddr = 0;
2672 	struct enc_dma_cfg *cfg = NULL;
2673 	s32 ret = 0;
2674 	struct platform_device *pdev;
2675 
2676 	if (!wq)
2677 		return -1;
2678 	memset(&wq->request, 0, sizeof(struct encode_request_s));
2679 	wq->request.me_weight = ME_WEIGHT_OFFSET;
2680 	wq->request.i4_weight = I4MB_WEIGHT_OFFSET;
2681 	wq->request.i16_weight = I16MB_WEIGHT_OFFSET;
2682 
2683 	if (cmd == ENCODER_SEQUENCE) {
2684 		wq->request.cmd = cmd;
2685 		wq->request.ucode_mode = cmd_info[1];
2686 		wq->request.quant = cmd_info[2];
2687 		wq->request.flush_flag = cmd_info[3];
2688 		wq->request.timeout = cmd_info[4];
2689 		wq->request.timeout = 5000; /* 5000 ms */
2690 	} else if ((cmd == ENCODER_IDR) || (cmd == ENCODER_NON_IDR)) {
2691 		wq->request.cmd = cmd;
2692 		wq->request.ucode_mode = cmd_info[1];
2693 		wq->request.type = cmd_info[2];
2694 		wq->request.fmt = cmd_info[3];
2695 		wq->request.src = cmd_info[4];
2696 		wq->request.framesize = cmd_info[5];
2697 		wq->request.quant = cmd_info[6];
2698 		wq->request.flush_flag = cmd_info[7];
2699 		wq->request.timeout = cmd_info[8];
2700 		wq->request.crop_top = cmd_info[9];
2701 		wq->request.crop_bottom = cmd_info[10];
2702 		wq->request.crop_left = cmd_info[11];
2703 		wq->request.crop_right = cmd_info[12];
2704 		wq->request.src_w = cmd_info[13];
2705 		wq->request.src_h = cmd_info[14];
2706 		wq->request.scale_enable = cmd_info[15];
2707 
2708 		enc_pr(LOG_INFO, "hwenc: wq->pic.encoder_width %d, ",
2709 		      wq->pic.encoder_width);
2710 		enc_pr(LOG_INFO, "wq->pic.encoder_height:%d, request fmt=%d\n",
2711 		      wq->pic.encoder_height, wq->request.fmt);
2712 
2713 		if (wq->pic.encoder_width >= 1280 && wq->pic.encoder_height >= 720
2714 			&& wq->request.fmt == FMT_RGBA8888 && wq->pic.color_space != GE2D_FORMAT_BT601) {
2715 			wq->request.scale_enable = 1;
2716 			wq->request.src_w = wq->pic.encoder_width;
2717 			wq->request.src_h = wq->pic.encoder_height;
2718 			enc_pr(LOG_DEBUG, "hwenc: force wq->request.scale_enable=%d\n", wq->request.scale_enable);
2719 		}
2720 
2721 		wq->request.nr_mode =
2722 			(nr_mode > 0) ? nr_mode : cmd_info[16];
2723 		if (cmd == ENCODER_IDR)
2724 			wq->request.nr_mode = 0;
2725 
2726 		data_offset = 17 +
2727 			(sizeof(wq->quant_tbl_i4)
2728 			+ sizeof(wq->quant_tbl_i16)
2729 			+ sizeof(wq->quant_tbl_me)) / 4;
2730 
2731 		if (wq->request.quant == ADJUSTED_QP_FLAG) {
2732 			ptr = (u8 *) &cmd_info[17];
2733 			memcpy(wq->quant_tbl_i4, ptr,
2734 				sizeof(wq->quant_tbl_i4));
2735 			ptr += sizeof(wq->quant_tbl_i4);
2736 			memcpy(wq->quant_tbl_i16, ptr,
2737 				sizeof(wq->quant_tbl_i16));
2738 			ptr += sizeof(wq->quant_tbl_i16);
2739 			memcpy(wq->quant_tbl_me, ptr,
2740 				sizeof(wq->quant_tbl_me));
2741 			wq->request.i4_weight -=
2742 				cmd_info[data_offset++];
2743 			wq->request.i16_weight -=
2744 				cmd_info[data_offset++];
2745 			wq->request.me_weight -=
2746 				cmd_info[data_offset++];
2747 			if (qp_table_debug) {
2748 				u8 *qp_tb = (u8 *)(&wq->quant_tbl_i4[0]);
2749 
2750 				for (i = 0; i < 32; i++) {
2751 					enc_pr(LOG_INFO, "%d ", *qp_tb);
2752 					qp_tb++;
2753 				}
2754 				enc_pr(LOG_INFO, "\n");
2755 
2756 				qp_tb = (u8 *)(&wq->quant_tbl_i16[0]);
2757 				for (i = 0; i < 32; i++) {
2758 					enc_pr(LOG_INFO, "%d ", *qp_tb);
2759 					qp_tb++;
2760 				}
2761 				enc_pr(LOG_INFO, "\n");
2762 
2763 				qp_tb = (u8 *)(&wq->quant_tbl_me[0]);
2764 				for (i = 0; i < 32; i++) {
2765 					enc_pr(LOG_INFO, "%d ", *qp_tb);
2766 					qp_tb++;
2767 				}
2768 				enc_pr(LOG_INFO, "\n");
2769 			}
2770 		} else {
2771 			memset(wq->quant_tbl_me, wq->request.quant,
2772 				sizeof(wq->quant_tbl_me));
2773 			memset(wq->quant_tbl_i4, wq->request.quant,
2774 				sizeof(wq->quant_tbl_i4));
2775 			memset(wq->quant_tbl_i16, wq->request.quant,
2776 				sizeof(wq->quant_tbl_i16));
2777 			data_offset += 3;
2778 		}
2779 #ifdef H264_ENC_CBR
2780 		wq->cbr_info.block_w = cmd_info[data_offset++];
2781 		wq->cbr_info.block_h = cmd_info[data_offset++];
2782 		wq->cbr_info.long_th = cmd_info[data_offset++];
2783 		wq->cbr_info.start_tbl_id = cmd_info[data_offset++];
2784 		wq->cbr_info.short_shift = CBR_SHORT_SHIFT;
2785 		wq->cbr_info.long_mb_num = CBR_LONG_MB_NUM;
2786 #endif
2787 		data_offset = 17 +
2788 				(sizeof(wq->quant_tbl_i4)
2789 				+ sizeof(wq->quant_tbl_i16)
2790 				+ sizeof(wq->quant_tbl_me)) / 4 + 7;
2791 
2792 		if (wq->request.type == DMA_BUFF) {
2793 			wq->request.plane_num = cmd_info[data_offset++];
2794 			enc_pr(LOG_INFO, "wq->request.plane_num %d\n",
2795 				wq->request.plane_num);
2796 			if (wq->request.fmt == FMT_NV12 ||
2797 				wq->request.fmt == FMT_NV21 ||
2798 				wq->request.fmt == FMT_YUV420) {
2799 				for (i = 0; i < wq->request.plane_num; i++) {
2800 					cfg = &wq->request.dma_cfg[i];
2801 					cfg->dir = DMA_TO_DEVICE;
2802 					cfg->fd = cmd_info[data_offset++];
2803 					pdev = encode_manager.this_pdev;
2804 					cfg->dev = &(pdev->dev);
2805 
2806 					ret = enc_dma_buf_get_phys(cfg, &paddr);
2807 					if (ret < 0) {
2808 						enc_pr(LOG_ERROR,
2809 							"import fd %d failed\n",
2810 							cfg->fd);
2811 						cfg->paddr = NULL;
2812 						cfg->vaddr = NULL;
2813 						return -1;
2814 					}
2815 					cfg->paddr = (void *)paddr;
2816 					enc_pr(LOG_INFO, "vaddr %p\n",
2817 						cfg->vaddr);
2818 				}
2819 			} else {
2820 				enc_pr(LOG_ERROR, "error fmt = %d\n",
2821 					wq->request.fmt);
2822 			}
2823 		}
2824 
2825 	} else {
2826 		enc_pr(LOG_ERROR, "error cmd = %d, wq: %p.\n",
2827 			cmd, (void *)wq);
2828 		return -1;
2829 	}
2830 	wq->request.parent = wq;
2831 	return 0;
2832 }
2833 
amvenc_avc_start_cmd(struct encode_wq_s * wq,struct encode_request_s * request)2834 void amvenc_avc_start_cmd(struct encode_wq_s *wq,
2835 			  struct encode_request_s *request)
2836 {
2837 	u32 reload_flag = 0;
2838 
2839 	if (request->ucode_mode != encode_manager.ucode_index) {
2840 		encode_manager.ucode_index = request->ucode_mode;
2841 		if (reload_mc(wq)) {
2842 			enc_pr(LOG_ERROR,
2843 				"reload mc fail, wq:%p\n", (void *)wq);
2844 			return;
2845 		}
2846 		reload_flag = 1;
2847 		encode_manager.need_reset = true;
2848 	}
2849 
2850 	wq->hw_status = 0;
2851 	wq->output_size = 0;
2852 	wq->ucode_index = encode_manager.ucode_index;
2853 
2854 	ie_me_mode = (0 & ME_PIXEL_MODE_MASK) << ME_PIXEL_MODE_SHIFT;
2855 	if (encode_manager.need_reset) {
2856 		amvenc_stop();
2857 		reload_flag = 1;
2858 		encode_manager.need_reset = false;
2859 		encode_manager.encode_hw_status = ENCODER_IDLE;
2860 		amvenc_reset();
2861 		avc_canvas_init(wq);
2862 		avc_init_encoder(wq,
2863 			(request->cmd == ENCODER_IDR) ? true : false);
2864 		avc_init_input_buffer(wq);
2865 		avc_init_output_buffer(wq);
2866 		avc_prot_init(wq, request, request->quant,
2867 			(request->cmd == ENCODER_IDR) ? true : false);
2868 		avc_init_assit_buffer(wq);
2869 		enc_pr(LOG_INFO,
2870 			"begin to new frame, request->cmd: %d, ucode mode: %d, wq:%p\n",
2871 			request->cmd, request->ucode_mode, (void *)wq);
2872 	}
2873 	if ((request->cmd == ENCODER_IDR) ||
2874 		(request->cmd == ENCODER_NON_IDR)) {
2875 #ifdef H264_ENC_SVC
2876 		/* encode non reference frame or not */
2877 		if (request->cmd == ENCODER_IDR)
2878 			wq->pic.non_ref_cnt = 0; //IDR reset counter
2879 		if (wq->pic.enable_svc && wq->pic.non_ref_cnt) {
2880 			enc_pr(LOG_INFO,
2881 				"PIC is NON REF cmd %d cnt %d value 0x%x\n",
2882 				request->cmd, wq->pic.non_ref_cnt,
2883 				ENC_SLC_NON_REF);
2884 			WRITE_HREG(H264_ENC_SVC_PIC_TYPE, ENC_SLC_NON_REF);
2885 		} else {
2886 			enc_pr(LOG_INFO,
2887 				"PIC is REF cmd %d cnt %d val 0x%x\n",
2888 				request->cmd, wq->pic.non_ref_cnt,
2889 				ENC_SLC_REF);
2890 			WRITE_HREG(H264_ENC_SVC_PIC_TYPE, ENC_SLC_REF);
2891 		}
2892 #else
2893 		/* if FW defined but not defined SVC in driver here*/
2894 		WRITE_HREG(H264_ENC_SVC_PIC_TYPE, ENC_SLC_REF);
2895 #endif
2896 		avc_init_dblk_buffer(wq->mem.dblk_buf_canvas);
2897 		avc_init_reference_buffer(wq->mem.ref_buf_canvas);
2898 	}
2899 	if ((request->cmd == ENCODER_IDR) ||
2900 		(request->cmd == ENCODER_NON_IDR))
2901 		set_input_format(wq, request);
2902 
2903 	if (request->cmd == ENCODER_IDR)
2904 		ie_me_mb_type = HENC_MB_Type_I4MB;
2905 	else if (request->cmd == ENCODER_NON_IDR)
2906 		ie_me_mb_type =
2907 			(HENC_SKIP_RUN_AUTO << 16) |
2908 			(HENC_MB_Type_AUTO << 4) |
2909 			(HENC_MB_Type_AUTO << 0);
2910 	else
2911 		ie_me_mb_type = 0;
2912 	avc_init_ie_me_parameter(wq, request->quant);
2913 
2914 #ifdef MULTI_SLICE_MC
2915 	if (fixed_slice_cfg)
2916 		WRITE_HREG(FIXED_SLICE_CFG, fixed_slice_cfg);
2917 	else if (wq->pic.rows_per_slice !=
2918 		(wq->pic.encoder_height + 15) >> 4) {
2919 		u32 mb_per_slice = (wq->pic.encoder_height + 15) >> 4;
2920 
2921 		mb_per_slice = mb_per_slice * wq->pic.rows_per_slice;
2922 		WRITE_HREG(FIXED_SLICE_CFG, mb_per_slice);
2923 	} else
2924 		WRITE_HREG(FIXED_SLICE_CFG, 0);
2925 #else
2926 	WRITE_HREG(FIXED_SLICE_CFG, 0);
2927 #endif
2928 
2929 	encode_manager.encode_hw_status = request->cmd;
2930 	wq->hw_status = request->cmd;
2931 	WRITE_HREG(ENCODER_STATUS, request->cmd);
2932 	if ((request->cmd == ENCODER_IDR)
2933 		|| (request->cmd == ENCODER_NON_IDR)
2934 		|| (request->cmd == ENCODER_SEQUENCE)
2935 		|| (request->cmd == ENCODER_PICTURE))
2936 		encode_manager.process_irq = false;
2937 
2938 	if (reload_flag)
2939 		amvenc_start();
2940 	enc_pr(LOG_ALL, "amvenc_avc_start cmd out, request:%p.\n", (void*)request);
2941 }
2942 
dma_flush(u32 buf_start,u32 buf_size)2943 static void dma_flush(u32 buf_start, u32 buf_size)
2944 {
2945 	if ((buf_start == 0) || (buf_size == 0))
2946 		return;
2947 	dma_sync_single_for_device(
2948 		&encode_manager.this_pdev->dev, buf_start,
2949 		buf_size, DMA_TO_DEVICE);
2950 }
2951 
cache_flush(u32 buf_start,u32 buf_size)2952 static void cache_flush(u32 buf_start, u32 buf_size)
2953 {
2954 	if ((buf_start == 0) || (buf_size == 0))
2955 		return;
2956 	dma_sync_single_for_cpu(
2957 		&encode_manager.this_pdev->dev, buf_start,
2958 		buf_size, DMA_FROM_DEVICE);
2959 }
2960 
getbuffer(struct encode_wq_s * wq,u32 type)2961 static u32 getbuffer(struct encode_wq_s *wq, u32 type)
2962 {
2963 	u32 ret = 0;
2964 
2965 	switch (type) {
2966 	case ENCODER_BUFFER_INPUT:
2967 		ret = wq->mem.dct_buff_start_addr;
2968 		break;
2969 	case ENCODER_BUFFER_REF0:
2970 		ret = wq->mem.dct_buff_start_addr +
2971 			wq->mem.bufspec.dec0_y.buf_start;
2972 		break;
2973 	case ENCODER_BUFFER_REF1:
2974 		ret = wq->mem.dct_buff_start_addr +
2975 			wq->mem.bufspec.dec1_y.buf_start;
2976 		break;
2977 	case ENCODER_BUFFER_OUTPUT:
2978 		ret = wq->mem.BitstreamStart;
2979 		break;
2980 	case ENCODER_BUFFER_DUMP:
2981 		ret = wq->mem.dump_info_ddr_start_addr;
2982 		break;
2983 	case ENCODER_BUFFER_CBR:
2984 		ret = wq->mem.cbr_info_ddr_start_addr;
2985 		break;
2986 	default:
2987 		break;
2988 	}
2989 	return ret;
2990 }
2991 
amvenc_avc_start(struct encode_wq_s * wq,u32 clock)2992 s32 amvenc_avc_start(struct encode_wq_s *wq, u32 clock)
2993 {
2994 	const char *p = select_ucode(encode_manager.ucode_index);
2995 
2996 	avc_poweron(clock);
2997 	avc_canvas_init(wq);
2998 
2999 	WRITE_HREG(HCODEC_ASSIST_MMC_CTRL1, 0x32);
3000 
3001 	if (amvenc_loadmc(p, wq) < 0)
3002 		return -EBUSY;
3003 
3004 	encode_manager.need_reset = true;
3005 	encode_manager.process_irq = false;
3006 	encode_manager.encode_hw_status = ENCODER_IDLE;
3007 	amvenc_reset();
3008 	avc_init_encoder(wq, true);
3009 	avc_init_input_buffer(wq);  /* dct buffer setting */
3010 	avc_init_output_buffer(wq);  /* output stream buffer */
3011 
3012 	ie_me_mode = (0 & ME_PIXEL_MODE_MASK) << ME_PIXEL_MODE_SHIFT;
3013 	avc_prot_init(wq, NULL, wq->pic.init_qppicture, true);
3014 	if (request_irq(encode_manager.irq_num, enc_isr, IRQF_SHARED,
3015 		"enc-irq", (void *)&encode_manager) == 0)
3016 		encode_manager.irq_requested = true;
3017 	else
3018 		encode_manager.irq_requested = false;
3019 
3020 	/* decoder buffer , need set before each frame start */
3021 	avc_init_dblk_buffer(wq->mem.dblk_buf_canvas);
3022 	/* reference  buffer , need set before each frame start */
3023 	avc_init_reference_buffer(wq->mem.ref_buf_canvas);
3024 	avc_init_assit_buffer(wq); /* assitant buffer for microcode */
3025 	ie_me_mb_type = 0;
3026 	avc_init_ie_me_parameter(wq, wq->pic.init_qppicture);
3027 	WRITE_HREG(ENCODER_STATUS, ENCODER_IDLE);
3028 
3029 #ifdef MULTI_SLICE_MC
3030 	if (fixed_slice_cfg)
3031 		WRITE_HREG(FIXED_SLICE_CFG, fixed_slice_cfg);
3032 	else if (wq->pic.rows_per_slice !=
3033 		(wq->pic.encoder_height + 15) >> 4) {
3034 		u32 mb_per_slice = (wq->pic.encoder_height + 15) >> 4;
3035 
3036 		mb_per_slice = mb_per_slice * wq->pic.rows_per_slice;
3037 		WRITE_HREG(FIXED_SLICE_CFG, mb_per_slice);
3038 	} else
3039 		WRITE_HREG(FIXED_SLICE_CFG, 0);
3040 #else
3041 	WRITE_HREG(FIXED_SLICE_CFG, 0);
3042 #endif
3043 	amvenc_start();
3044 	return 0;
3045 }
3046 
amvenc_avc_stop(void)3047 void amvenc_avc_stop(void)
3048 {
3049 	if ((encode_manager.irq_num >= 0) &&
3050 		(encode_manager.irq_requested == true)) {
3051 		free_irq(encode_manager.irq_num, &encode_manager);
3052 		encode_manager.irq_requested = false;
3053 	}
3054 	amvenc_stop();
3055 	avc_poweroff();
3056 }
3057 
avc_init(struct encode_wq_s * wq)3058 static s32 avc_init(struct encode_wq_s *wq)
3059 {
3060 	s32 r = 0;
3061 
3062 	encode_manager.ucode_index = wq->ucode_index;
3063 	r = amvenc_avc_start(wq, clock_level);
3064 
3065 	enc_pr(LOG_DEBUG,
3066 		"init avc encode. microcode %d, ret=%d, wq:%p.\n",
3067 		encode_manager.ucode_index, r, (void *)wq);
3068 	return 0;
3069 }
3070 
amvenc_avc_light_reset(struct encode_wq_s * wq,u32 value)3071 static s32 amvenc_avc_light_reset(struct encode_wq_s *wq, u32 value)
3072 {
3073 	s32 r = 0;
3074 
3075 	amvenc_avc_stop();
3076 
3077 	mdelay(value);
3078 
3079 	encode_manager.ucode_index = UCODE_MODE_FULL;
3080 	r = amvenc_avc_start(wq, clock_level);
3081 
3082 	enc_pr(LOG_DEBUG,
3083 		"amvenc_avc_light_reset finish, wq:%p. ret=%d\n",
3084 		 (void *)wq, r);
3085 	return r;
3086 }
3087 
3088 #ifdef CONFIG_CMA
checkCMA(void)3089 static u32 checkCMA(void)
3090 {
3091 	u32 ret;
3092 
3093 	if (encode_manager.cma_pool_size > 0) {
3094 		ret = encode_manager.cma_pool_size;
3095 		ret = ret / MIN_SIZE;
3096 	} else
3097 		ret = 0;
3098 	return ret;
3099 }
3100 #endif
3101 
3102 /* file operation */
amvenc_avc_open(struct inode * inode,struct file * file)3103 static s32 amvenc_avc_open(struct inode *inode, struct file *file)
3104 {
3105 	s32 r = 0;
3106 	struct encode_wq_s *wq = NULL;
3107 
3108 	file->private_data = NULL;
3109 	enc_pr(LOG_DEBUG, "avc open\n");
3110 #ifdef CONFIG_AM_JPEG_ENCODER
3111 	if (jpegenc_on() == true) {
3112 		enc_pr(LOG_ERROR,
3113 			"hcodec in use for JPEG Encode now.\n");
3114 		return -EBUSY;
3115 	}
3116 #endif
3117 
3118 #ifdef CONFIG_CMA
3119 	if ((encode_manager.use_reserve == false) &&
3120 	    (encode_manager.check_cma == false)) {
3121 		encode_manager.max_instance = checkCMA();
3122 		if (encode_manager.max_instance > 0) {
3123 			enc_pr(LOG_DEBUG,
3124 				"amvenc_avc  check CMA pool success, max instance: %d.\n",
3125 				encode_manager.max_instance);
3126 		} else {
3127 			enc_pr(LOG_ERROR,
3128 				"amvenc_avc CMA pool too small.\n");
3129 		}
3130 		encode_manager.check_cma = true;
3131 	}
3132 #endif
3133 
3134 	wq = create_encode_work_queue();
3135 	if (wq == NULL) {
3136 		enc_pr(LOG_ERROR, "amvenc_avc create instance fail.\n");
3137 		return -EBUSY;
3138 	}
3139 
3140 #ifdef CONFIG_CMA
3141 	if (encode_manager.use_reserve == false) {
3142 		wq->mem.buf_start = codec_mm_alloc_for_dma(ENCODE_NAME,
3143 			MIN_SIZE  >> PAGE_SHIFT, 0,
3144 			CODEC_MM_FLAGS_CPU);
3145 		if (wq->mem.buf_start) {
3146 			wq->mem.buf_size = MIN_SIZE;
3147 			enc_pr(LOG_DEBUG,
3148 				"allocating phys 0x%x, size %dk, wq:%p.\n",
3149 				wq->mem.buf_start,
3150 				wq->mem.buf_size >> 10, (void *)wq);
3151 		} else {
3152 			enc_pr(LOG_ERROR,
3153 				"CMA failed to allocate dma buffer for %s, wq:%p.\n",
3154 				encode_manager.this_pdev->name,
3155 				(void *)wq);
3156 			destroy_encode_work_queue(wq);
3157 			return -ENOMEM;
3158 		}
3159 	}
3160 #endif
3161 
3162 	if (wq->mem.buf_start == 0 ||
3163 		wq->mem.buf_size < MIN_SIZE) {
3164 		enc_pr(LOG_ERROR,
3165 			"alloc mem failed, start: 0x%x, size:0x%x, wq:%p.\n",
3166 			wq->mem.buf_start,
3167 			wq->mem.buf_size, (void *)wq);
3168 		destroy_encode_work_queue(wq);
3169 		return -ENOMEM;
3170 	}
3171 
3172 	memcpy(&wq->mem.bufspec, &amvenc_buffspec[0],
3173 		sizeof(struct BuffInfo_s));
3174 
3175 	enc_pr(LOG_DEBUG,
3176 		"amvenc_avc  memory config success, buff start:0x%x, size is 0x%x, wq:%p.\n",
3177 		wq->mem.buf_start, wq->mem.buf_size, (void *)wq);
3178 
3179 	file->private_data = (void *) wq;
3180 	return r;
3181 }
3182 
amvenc_avc_release(struct inode * inode,struct file * file)3183 static s32 amvenc_avc_release(struct inode *inode, struct file *file)
3184 {
3185 	struct encode_wq_s *wq = (struct encode_wq_s *)file->private_data;
3186 
3187 	if (wq) {
3188 		enc_pr(LOG_DEBUG, "avc release, wq:%p\n", (void *)wq);
3189 		destroy_encode_work_queue(wq);
3190 	}
3191 	return 0;
3192 }
3193 
amvenc_avc_ioctl(struct file * file,u32 cmd,ulong arg)3194 static long amvenc_avc_ioctl(struct file *file, u32 cmd, ulong arg)
3195 {
3196 	long r = 0;
3197 	u32 amrisc_cmd = 0;
3198 	struct encode_wq_s *wq = (struct encode_wq_s *)file->private_data;
3199 #define MAX_ADDR_INFO_SIZE 52
3200 	u32 addr_info[MAX_ADDR_INFO_SIZE + 4];
3201 	ulong argV;
3202 	u32 buf_start;
3203 	s32 canvas = -1;
3204 	struct canvas_s dst;
3205 
3206 	switch (cmd) {
3207 	case AMVENC_AVC_IOC_GET_ADDR:
3208 		if ((wq->mem.ref_buf_canvas & 0xff) == (ENC_CANVAS_OFFSET))
3209 			put_user(1, (u32 *)arg);
3210 		else
3211 			put_user(2, (u32 *)arg);
3212 		break;
3213 	case AMVENC_AVC_IOC_INPUT_UPDATE:
3214 		break;
3215 	case AMVENC_AVC_IOC_NEW_CMD:
3216 		if (copy_from_user(addr_info, (void *)arg,
3217 			MAX_ADDR_INFO_SIZE * sizeof(u32))) {
3218 			enc_pr(LOG_ERROR,
3219 				"avc get new cmd error, wq:%p.\n", (void *)wq);
3220 			return -1;
3221 		}
3222 		r = convert_request(wq, addr_info);
3223 		if (r == 0)
3224 			r = encode_wq_add_request(wq);
3225 		if (r) {
3226 			enc_pr(LOG_ERROR,
3227 				"avc add new request error, wq:%p.\n",
3228 				(void *)wq);
3229 		}
3230 		break;
3231 	case AMVENC_AVC_IOC_GET_STAGE:
3232 		put_user(wq->hw_status, (u32 *)arg);
3233 		break;
3234 	case AMVENC_AVC_IOC_GET_OUTPUT_SIZE:
3235 		addr_info[0] = wq->output_size;
3236 		addr_info[1] = wq->me_weight;
3237 		addr_info[2] = wq->i4_weight;
3238 		addr_info[3] = wq->i16_weight;
3239 		r = copy_to_user((u32 *)arg,
3240 			addr_info, 4 * sizeof(u32));
3241 		break;
3242 	case AMVENC_AVC_IOC_CONFIG_INIT:
3243 		if (copy_from_user(addr_info, (void *)arg,
3244 			MAX_ADDR_INFO_SIZE * sizeof(u32))) {
3245 			enc_pr(LOG_ERROR,
3246 				"avc config init error, wq:%p.\n", (void *)wq);
3247 			return -1;
3248 		}
3249 		wq->ucode_index = UCODE_MODE_FULL;
3250 #ifdef MULTI_SLICE_MC
3251 		wq->pic.rows_per_slice = addr_info[1];
3252 		enc_pr(LOG_DEBUG,
3253 			"avc init -- rows_per_slice: %d, wq: %p.\n",
3254 			wq->pic.rows_per_slice, (void *)wq);
3255 #endif
3256 		enc_pr(LOG_DEBUG,
3257 			"avc init as mode %d, wq: %p.\n",
3258 			wq->ucode_index, (void *)wq);
3259 
3260 		if (addr_info[2] > wq->mem.bufspec.max_width ||
3261 		    addr_info[3] > wq->mem.bufspec.max_height) {
3262 			enc_pr(LOG_ERROR,
3263 				"avc config init- encode size %dx%d is larger than supported (%dx%d).  wq:%p.\n",
3264 				addr_info[2], addr_info[3],
3265 				wq->mem.bufspec.max_width,
3266 				wq->mem.bufspec.max_height, (void *)wq);
3267 			return -1;
3268 		}
3269 		pr_err("hwenc: AMVENC_AVC_IOC_CONFIG_INIT: w:%d, h:%d\n", wq->pic.encoder_width, wq->pic.encoder_height);
3270 		wq->pic.encoder_width = addr_info[2];
3271 		wq->pic.encoder_height = addr_info[3];
3272 
3273 		wq->pic.color_space = addr_info[4];
3274 		pr_err("hwenc: AMVENC_AVC_IOC_CONFIG_INIT, wq->pic.color_space=%#x\n", wq->pic.color_space);
3275 		if (wq->pic.encoder_width *
3276 			wq->pic.encoder_height >= 1280 * 720)
3277 			clock_level = 6;
3278 		else
3279 			clock_level = 5;
3280 		avc_buffspec_init(wq);
3281 		complete(&encode_manager.event.request_in_com);
3282 		addr_info[1] = wq->mem.bufspec.dct.buf_start;
3283 		addr_info[2] = wq->mem.bufspec.dct.buf_size;
3284 		addr_info[3] = wq->mem.bufspec.bitstream.buf_start;
3285 		addr_info[4] = wq->mem.bufspec.bitstream.buf_size;
3286 		addr_info[5] = wq->mem.bufspec.scale_buff.buf_start;
3287 		addr_info[6] = wq->mem.bufspec.scale_buff.buf_size;
3288 		addr_info[7] = wq->mem.bufspec.dump_info.buf_start;
3289 		addr_info[8] = wq->mem.bufspec.dump_info.buf_size;
3290 		addr_info[9] = wq->mem.bufspec.cbr_info.buf_start;
3291 		addr_info[10] = wq->mem.bufspec.cbr_info.buf_size;
3292 		r = copy_to_user((u32 *)arg, addr_info, 11*sizeof(u32));
3293 		break;
3294 	case AMVENC_AVC_IOC_FLUSH_CACHE:
3295 		if (copy_from_user(addr_info, (void *)arg,
3296 				   MAX_ADDR_INFO_SIZE * sizeof(u32))) {
3297 			enc_pr(LOG_ERROR,
3298 				"avc flush cache error, wq: %p.\n", (void *)wq);
3299 			return -1;
3300 		}
3301 		buf_start = getbuffer(wq, addr_info[0]);
3302 		dma_flush(buf_start + addr_info[1],
3303 			addr_info[2] - addr_info[1]);
3304 		break;
3305 	case AMVENC_AVC_IOC_FLUSH_DMA:
3306 		if (copy_from_user(addr_info, (void *)arg,
3307 				MAX_ADDR_INFO_SIZE * sizeof(u32))) {
3308 			enc_pr(LOG_ERROR,
3309 				"avc flush dma error, wq:%p.\n", (void *)wq);
3310 			return -1;
3311 		}
3312 		buf_start = getbuffer(wq, addr_info[0]);
3313 		cache_flush(buf_start + addr_info[1],
3314 			addr_info[2] - addr_info[1]);
3315 		break;
3316 	case AMVENC_AVC_IOC_GET_BUFFINFO:
3317 		put_user(wq->mem.buf_size, (u32 *)arg);
3318 		break;
3319 	case AMVENC_AVC_IOC_GET_DEVINFO:
3320 		if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) {
3321 			/* send the same id as GXTVBB to upper*/
3322 			r = copy_to_user((s8 *)arg, AMVENC_DEVINFO_GXTVBB,
3323 				strlen(AMVENC_DEVINFO_GXTVBB));
3324 		} else if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) {
3325 			r = copy_to_user((s8 *)arg, AMVENC_DEVINFO_GXTVBB,
3326 				strlen(AMVENC_DEVINFO_GXTVBB));
3327 		} else if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXBB) {
3328 			r = copy_to_user((s8 *)arg, AMVENC_DEVINFO_GXBB,
3329 				strlen(AMVENC_DEVINFO_GXBB));
3330 		} else if (get_cpu_type() == MESON_CPU_MAJOR_ID_MG9TV) {
3331 			r = copy_to_user((s8 *)arg, AMVENC_DEVINFO_G9,
3332 				strlen(AMVENC_DEVINFO_G9));
3333 		} else {
3334 			r = copy_to_user((s8 *)arg, AMVENC_DEVINFO_M8,
3335 				strlen(AMVENC_DEVINFO_M8));
3336 		}
3337 		break;
3338 	case AMVENC_AVC_IOC_SUBMIT:
3339 		get_user(amrisc_cmd, ((u32 *)arg));
3340 		if (amrisc_cmd == ENCODER_IDR) {
3341 			wq->pic.idr_pic_id++;
3342 			if (wq->pic.idr_pic_id > 65535)
3343 				wq->pic.idr_pic_id = 0;
3344 			wq->pic.pic_order_cnt_lsb = 2;
3345 			wq->pic.frame_number = 1;
3346 		} else if (amrisc_cmd == ENCODER_NON_IDR) {
3347 #ifdef H264_ENC_SVC
3348 			/* only update when there is reference frame */
3349 			if (wq->pic.enable_svc == 0 || wq->pic.non_ref_cnt == 0) {
3350 				wq->pic.frame_number++;
3351 				enc_pr(LOG_INFO, "Increase frame_num to %d\n",
3352 					wq->pic.frame_number);
3353 			}
3354 #else
3355 			wq->pic.frame_number++;
3356 #endif
3357 
3358 			wq->pic.pic_order_cnt_lsb += 2;
3359 			if (wq->pic.frame_number > 65535)
3360 				wq->pic.frame_number = 0;
3361 		}
3362 #ifdef H264_ENC_SVC
3363 		/* only update when there is reference frame */
3364 		if (wq->pic.enable_svc == 0 || wq->pic.non_ref_cnt == 0) {
3365 			amrisc_cmd = wq->mem.dblk_buf_canvas;
3366 			wq->mem.dblk_buf_canvas = wq->mem.ref_buf_canvas;
3367 			/* current dblk buffer as next reference buffer */
3368 			wq->mem.ref_buf_canvas = amrisc_cmd;
3369 			enc_pr(LOG_INFO,
3370 				"switch buffer enable %d  cnt %d\n",
3371 				wq->pic.enable_svc, wq->pic.non_ref_cnt);
3372 		}
3373 		if (wq->pic.enable_svc) {
3374 			wq->pic.non_ref_cnt ++;
3375 			if (wq->pic.non_ref_cnt > wq->pic.non_ref_limit) {
3376 				enc_pr(LOG_INFO, "Svc clear cnt %d conf %d\n",
3377 					wq->pic.non_ref_cnt,
3378 					wq->pic.non_ref_limit);
3379 				wq->pic.non_ref_cnt = 0;
3380 			} else
3381 			enc_pr(LOG_INFO,"Svc increase non ref counter to %d\n",
3382 				wq->pic.non_ref_cnt );
3383 		}
3384 #else
3385 		amrisc_cmd = wq->mem.dblk_buf_canvas;
3386 		wq->mem.dblk_buf_canvas = wq->mem.ref_buf_canvas;
3387 		/* current dblk buffer as next reference buffer */
3388 		wq->mem.ref_buf_canvas = amrisc_cmd;
3389 #endif
3390 		break;
3391 	case AMVENC_AVC_IOC_READ_CANVAS:
3392 		get_user(argV, ((u32 *)arg));
3393 		canvas = argV;
3394 		if (canvas & 0xff) {
3395 			canvas_read(canvas & 0xff, &dst);
3396 			addr_info[0] = dst.addr;
3397 			if ((canvas & 0xff00) >> 8)
3398 				canvas_read((canvas & 0xff00) >> 8, &dst);
3399 			if ((canvas & 0xff0000) >> 16)
3400 				canvas_read((canvas & 0xff0000) >> 16, &dst);
3401 			addr_info[1] = dst.addr - addr_info[0] +
3402 				dst.width * dst.height;
3403 		} else {
3404 			addr_info[0] = 0;
3405 			addr_info[1] = 0;
3406 		}
3407 		dma_flush(dst.addr, dst.width * dst.height * 3 / 2);
3408 		r = copy_to_user((u32 *)arg, addr_info, 2 * sizeof(u32));
3409 		break;
3410 	case AMVENC_AVC_IOC_MAX_INSTANCE:
3411 		put_user(encode_manager.max_instance, (u32 *)arg);
3412 		break;
3413 	case AMVENC_AVC_IOC_QP_MODE:
3414 		get_user(qp_mode, ((u32 *)arg));
3415 		pr_info("qp_mode %d\n", qp_mode);
3416 		break;
3417 	default:
3418 		r = -1;
3419 		break;
3420 	}
3421 	return r;
3422 }
3423 
3424 #ifdef CONFIG_COMPAT
amvenc_avc_compat_ioctl(struct file * filp,unsigned int cmd,unsigned long args)3425 static long amvenc_avc_compat_ioctl(struct file *filp,
3426 	unsigned int cmd, unsigned long args)
3427 {
3428 	unsigned long ret;
3429 
3430 	args = (unsigned long)compat_ptr(args);
3431 	ret = amvenc_avc_ioctl(filp, cmd, args);
3432 	return ret;
3433 }
3434 #endif
3435 
avc_mmap(struct file * filp,struct vm_area_struct * vma)3436 static s32 avc_mmap(struct file *filp, struct vm_area_struct *vma)
3437 {
3438 	struct encode_wq_s *wq = (struct encode_wq_s *)filp->private_data;
3439 	ulong off = vma->vm_pgoff << PAGE_SHIFT;
3440 	ulong vma_size = vma->vm_end - vma->vm_start;
3441 
3442 	if (vma_size == 0) {
3443 		enc_pr(LOG_ERROR, "vma_size is 0, wq:%p.\n", (void *)wq);
3444 		return -EAGAIN;
3445 	}
3446 	if (!off)
3447 		off += wq->mem.buf_start;
3448 	enc_pr(LOG_ALL,
3449 		"vma_size is %ld , off is %ld, wq:%p.\n",
3450 		vma_size, off, (void *)wq);
3451 	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_IO;
3452 	/* vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); */
3453 	if (remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
3454 		vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
3455 		enc_pr(LOG_ERROR,
3456 			"set_cached: failed remap_pfn_range, wq:%p.\n",
3457 			(void *)wq);
3458 		return -EAGAIN;
3459 	}
3460 	return 0;
3461 }
3462 
amvenc_avc_poll(struct file * file,poll_table * wait_table)3463 static u32 amvenc_avc_poll(struct file *file, poll_table *wait_table)
3464 {
3465 	struct encode_wq_s *wq = (struct encode_wq_s *)file->private_data;
3466 
3467 	poll_wait(file, &wq->request_complete, wait_table);
3468 
3469 	if (atomic_read(&wq->request_ready)) {
3470 		atomic_dec(&wq->request_ready);
3471 		return POLLIN | POLLRDNORM;
3472 	}
3473 	return 0;
3474 }
3475 
3476 static const struct file_operations amvenc_avc_fops = {
3477 	.owner = THIS_MODULE,
3478 	.open = amvenc_avc_open,
3479 	.mmap = avc_mmap,
3480 	.release = amvenc_avc_release,
3481 	.unlocked_ioctl = amvenc_avc_ioctl,
3482 #ifdef CONFIG_COMPAT
3483 	.compat_ioctl = amvenc_avc_compat_ioctl,
3484 #endif
3485 	.poll = amvenc_avc_poll,
3486 };
3487 
3488 /* work queue function */
encode_process_request(struct encode_manager_s * manager,struct encode_queue_item_s * pitem)3489 static s32 encode_process_request(struct encode_manager_s *manager,
3490 	struct encode_queue_item_s *pitem)
3491 {
3492 	s32 ret = 0;
3493 	struct encode_wq_s *wq = pitem->request.parent;
3494 	struct encode_request_s *request = &pitem->request;
3495 	u32 timeout = (request->timeout == 0) ?
3496 		1 : msecs_to_jiffies(request->timeout);
3497 	u32 buf_start = 0;
3498 	u32 size = 0;
3499 	u32 flush_size = ((wq->pic.encoder_width + 31) >> 5 << 5) *
3500 		((wq->pic.encoder_height + 15) >> 4 << 4) * 3 / 2;
3501 
3502 	struct enc_dma_cfg *cfg = NULL;
3503 	int i = 0;
3504 
3505 #ifdef H264_ENC_CBR
3506 	if (request->cmd == ENCODER_IDR || request->cmd == ENCODER_NON_IDR) {
3507 		if (request->flush_flag & AMVENC_FLUSH_FLAG_CBR
3508 			&& get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) {
3509 			void *vaddr = wq->mem.cbr_info_ddr_virt_addr;
3510 			ConvertTable2Risc(vaddr, 0xa00);
3511 			buf_start = getbuffer(wq, ENCODER_BUFFER_CBR);
3512 			codec_mm_dma_flush(vaddr, wq->mem.cbr_info_ddr_size, DMA_TO_DEVICE);
3513 		}
3514 	}
3515 #endif
3516 
3517 Again:
3518 	amvenc_avc_start_cmd(wq, request);
3519 
3520 	if (no_timeout) {
3521 		wait_event_interruptible(manager->event.hw_complete,
3522 			(manager->encode_hw_status == ENCODER_IDR_DONE
3523 			|| manager->encode_hw_status == ENCODER_NON_IDR_DONE
3524 			|| manager->encode_hw_status == ENCODER_SEQUENCE_DONE
3525 			|| manager->encode_hw_status == ENCODER_PICTURE_DONE));
3526 	} else {
3527 		wait_event_interruptible_timeout(manager->event.hw_complete,
3528 			((manager->encode_hw_status == ENCODER_IDR_DONE)
3529 			|| (manager->encode_hw_status == ENCODER_NON_IDR_DONE)
3530 			|| (manager->encode_hw_status == ENCODER_SEQUENCE_DONE)
3531 			|| (manager->encode_hw_status == ENCODER_PICTURE_DONE)),
3532 			timeout);
3533 	}
3534 
3535 	if ((request->cmd == ENCODER_SEQUENCE) &&
3536 	    (manager->encode_hw_status == ENCODER_SEQUENCE_DONE)) {
3537 		wq->sps_size = READ_HREG(HCODEC_VLC_TOTAL_BYTES);
3538 		wq->hw_status = manager->encode_hw_status;
3539 		request->cmd = ENCODER_PICTURE;
3540 		goto Again;
3541 	} else if ((request->cmd == ENCODER_PICTURE) &&
3542 		   (manager->encode_hw_status == ENCODER_PICTURE_DONE)) {
3543 		wq->pps_size =
3544 			READ_HREG(HCODEC_VLC_TOTAL_BYTES) - wq->sps_size;
3545 		wq->hw_status = manager->encode_hw_status;
3546 		if (request->flush_flag & AMVENC_FLUSH_FLAG_OUTPUT) {
3547 			buf_start = getbuffer(wq, ENCODER_BUFFER_OUTPUT);
3548 			cache_flush(buf_start,
3549 				wq->sps_size + wq->pps_size);
3550 		}
3551 		wq->output_size = (wq->sps_size << 16) | wq->pps_size;
3552 	} else {
3553 		wq->hw_status = manager->encode_hw_status;
3554 		if ((manager->encode_hw_status == ENCODER_IDR_DONE) ||
3555 		    (manager->encode_hw_status == ENCODER_NON_IDR_DONE)) {
3556 			wq->output_size = READ_HREG(HCODEC_VLC_TOTAL_BYTES);
3557 			if (request->flush_flag & AMVENC_FLUSH_FLAG_OUTPUT) {
3558 				buf_start = getbuffer(wq,
3559 					ENCODER_BUFFER_OUTPUT);
3560 				cache_flush(buf_start, wq->output_size);
3561 			}
3562 			if (request->flush_flag &
3563 				AMVENC_FLUSH_FLAG_DUMP) {
3564 				buf_start = getbuffer(wq,
3565 					ENCODER_BUFFER_DUMP);
3566 				size = wq->mem.dump_info_ddr_size;
3567 				cache_flush(buf_start, size);
3568 			//enc_pr(LOG_DEBUG, "CBR flush dump_info done");
3569 			}
3570 			if (request->flush_flag &
3571 				AMVENC_FLUSH_FLAG_REFERENCE) {
3572 				u32 ref_id = ENCODER_BUFFER_REF0;
3573 
3574 				if ((wq->mem.ref_buf_canvas & 0xff) ==
3575 					(ENC_CANVAS_OFFSET))
3576 					ref_id = ENCODER_BUFFER_REF0;
3577 				else
3578 					ref_id = ENCODER_BUFFER_REF1;
3579 				buf_start = getbuffer(wq, ref_id);
3580 				cache_flush(buf_start, flush_size);
3581 			}
3582 		} else {
3583 			manager->encode_hw_status = ENCODER_ERROR;
3584 			enc_pr(LOG_DEBUG, "avc encode light reset --- ");
3585 			enc_pr(LOG_DEBUG,
3586 				"frame type: %s, size: %dx%d, wq: %p\n",
3587 				(request->cmd == ENCODER_IDR) ? "IDR" : "P",
3588 				wq->pic.encoder_width,
3589 				wq->pic.encoder_height, (void *)wq);
3590 			enc_pr(LOG_DEBUG,
3591 				"mb info: 0x%x, encode status: 0x%x, dct status: 0x%x ",
3592 				READ_HREG(HCODEC_VLC_MB_INFO),
3593 				READ_HREG(ENCODER_STATUS),
3594 				READ_HREG(HCODEC_QDCT_STATUS_CTRL));
3595 			enc_pr(LOG_DEBUG,
3596 				"vlc status: 0x%x, me status: 0x%x, risc pc:0x%x, debug:0x%x\n",
3597 				READ_HREG(HCODEC_VLC_STATUS_CTRL),
3598 				READ_HREG(HCODEC_ME_STATUS),
3599 				READ_HREG(HCODEC_MPC_E),
3600 				READ_HREG(DEBUG_REG));
3601 			amvenc_avc_light_reset(wq, 30);
3602 		}
3603 		for (i = 0; i < request->plane_num; i++) {
3604 			cfg = &request->dma_cfg[i];
3605 			enc_pr(LOG_INFO, "request vaddr %p, paddr %p\n",
3606 				cfg->vaddr, cfg->paddr);
3607 			if (cfg->fd >= 0 && cfg->vaddr != NULL)
3608 				enc_dma_buf_unmap(cfg);
3609 		}
3610 	}
3611 	atomic_inc(&wq->request_ready);
3612 	wake_up_interruptible(&wq->request_complete);
3613 	return ret;
3614 }
3615 
encode_wq_add_request(struct encode_wq_s * wq)3616 s32 encode_wq_add_request(struct encode_wq_s *wq)
3617 {
3618 	struct encode_queue_item_s *pitem = NULL;
3619 	struct list_head *head = NULL;
3620 	struct encode_wq_s *tmp = NULL;
3621 	bool find = false;
3622 
3623 	spin_lock(&encode_manager.event.sem_lock);
3624 
3625 	head =  &encode_manager.wq;
3626 	list_for_each_entry(tmp, head, list) {
3627 		if ((wq == tmp) && (wq != NULL)) {
3628 			find = true;
3629 			break;
3630 		}
3631 	}
3632 
3633 	if (find == false) {
3634 		enc_pr(LOG_ERROR, "current wq (%p) doesn't register.\n",
3635 			(void *)wq);
3636 		goto error;
3637 	}
3638 
3639 	if (list_empty(&encode_manager.free_queue)) {
3640 		enc_pr(LOG_ERROR, "work queue no space, wq:%p.\n",
3641 			(void *)wq);
3642 		goto error;
3643 	}
3644 
3645 	pitem = list_entry(encode_manager.free_queue.next,
3646 		struct encode_queue_item_s, list);
3647 	if (IS_ERR(pitem))
3648 		goto error;
3649 
3650 	memcpy(&pitem->request, &wq->request, sizeof(struct encode_request_s));
3651 
3652 	enc_pr(LOG_INFO, "new work request %p, vaddr %p, paddr %p\n", &pitem->request,
3653 		pitem->request.dma_cfg[0].vaddr,pitem->request.dma_cfg[0].paddr);
3654 
3655 	memset(&wq->request, 0, sizeof(struct encode_request_s));
3656 	wq->request.dma_cfg[0].fd = -1;
3657 	wq->request.dma_cfg[1].fd = -1;
3658 	wq->request.dma_cfg[2].fd = -1;
3659 	wq->hw_status = 0;
3660 	wq->output_size = 0;
3661 	pitem->request.parent = wq;
3662 	list_move_tail(&pitem->list, &encode_manager.process_queue);
3663 	spin_unlock(&encode_manager.event.sem_lock);
3664 
3665 	enc_pr(LOG_INFO,
3666 		"add new work ok, cmd:%d, ucode mode: %d, wq:%p.\n",
3667 		pitem->request.cmd, pitem->request.ucode_mode,
3668 		(void *)wq);
3669 	complete(&encode_manager.event.request_in_com);/* new cmd come in */
3670 	return 0;
3671 error:
3672 	spin_unlock(&encode_manager.event.sem_lock);
3673 	return -1;
3674 }
3675 
create_encode_work_queue(void)3676 struct encode_wq_s *create_encode_work_queue(void)
3677 {
3678 	struct encode_wq_s *encode_work_queue = NULL;
3679 	bool done = false;
3680 	u32 i, max_instance;
3681 	struct Buff_s *reserve_buff;
3682 
3683 	encode_work_queue = kzalloc(sizeof(struct encode_wq_s), GFP_KERNEL);
3684 	if (IS_ERR(encode_work_queue)) {
3685 		enc_pr(LOG_ERROR, "can't create work queue\n");
3686 		return NULL;
3687 	}
3688 	max_instance = encode_manager.max_instance;
3689 	encode_work_queue->pic.init_qppicture = 26;
3690 	encode_work_queue->pic.log2_max_frame_num = 4;
3691 	encode_work_queue->pic.log2_max_pic_order_cnt_lsb = 4;
3692 	encode_work_queue->pic.idr_pic_id = 0;
3693 	encode_work_queue->pic.frame_number = 0;
3694 	encode_work_queue->pic.pic_order_cnt_lsb = 0;
3695 #ifdef H264_ENC_SVC
3696 	/* Get settings from the global*/
3697 	encode_work_queue->pic.enable_svc = svc_enable;
3698 	encode_work_queue->pic.non_ref_limit = svc_ref_conf;
3699 	encode_work_queue->pic.non_ref_cnt = 0;
3700 	enc_pr(LOG_INFO, "svc conf enable %d, duration %d\n",
3701 		encode_work_queue->pic.enable_svc,
3702 		encode_work_queue->pic.non_ref_limit);
3703 #endif
3704 	encode_work_queue->ucode_index = UCODE_MODE_FULL;
3705 
3706 #ifdef H264_ENC_CBR
3707 	encode_work_queue->cbr_info.block_w = 16;
3708 	encode_work_queue->cbr_info.block_h = 9;
3709 	encode_work_queue->cbr_info.long_th = CBR_LONG_THRESH;
3710 	encode_work_queue->cbr_info.start_tbl_id = START_TABLE_ID;
3711 	encode_work_queue->cbr_info.short_shift = CBR_SHORT_SHIFT;
3712 	encode_work_queue->cbr_info.long_mb_num = CBR_LONG_MB_NUM;
3713 #endif
3714 	init_waitqueue_head(&encode_work_queue->request_complete);
3715 	atomic_set(&encode_work_queue->request_ready, 0);
3716 	spin_lock(&encode_manager.event.sem_lock);
3717 	if (encode_manager.wq_count < encode_manager.max_instance) {
3718 		list_add_tail(&encode_work_queue->list, &encode_manager.wq);
3719 		encode_manager.wq_count++;
3720 		if (encode_manager.use_reserve == true) {
3721 			for (i = 0; i < max_instance; i++) {
3722 				reserve_buff = &encode_manager.reserve_buff[i];
3723 				if (reserve_buff->used == false) {
3724 					encode_work_queue->mem.buf_start =
3725 						reserve_buff->buf_start;
3726 					encode_work_queue->mem.buf_size =
3727 						reserve_buff->buf_size;
3728 					reserve_buff->used = true;
3729 					done = true;
3730 					break;
3731 				}
3732 			}
3733 		} else
3734 			done = true;
3735 	}
3736 	spin_unlock(&encode_manager.event.sem_lock);
3737 	if (done == false) {
3738 		kfree(encode_work_queue);
3739 		encode_work_queue = NULL;
3740 		enc_pr(LOG_ERROR, "too many work queue!\n");
3741 	}
3742 	return encode_work_queue; /* find it */
3743 }
3744 
_destroy_encode_work_queue(struct encode_manager_s * manager,struct encode_wq_s ** wq,struct encode_wq_s * encode_work_queue,bool * find)3745 static void _destroy_encode_work_queue(struct encode_manager_s *manager,
3746 	struct encode_wq_s **wq,
3747 	struct encode_wq_s *encode_work_queue,
3748 	bool *find)
3749 {
3750 	struct list_head *head;
3751 	struct encode_wq_s *wp_tmp = NULL;
3752 	u32 i, max_instance;
3753 	struct Buff_s *reserve_buff;
3754 	u32 buf_start = encode_work_queue->mem.buf_start;
3755 
3756 	max_instance = manager->max_instance;
3757 	head =  &manager->wq;
3758 	list_for_each_entry_safe((*wq), wp_tmp, head, list) {
3759 		if ((*wq) && (*wq == encode_work_queue)) {
3760 			list_del(&(*wq)->list);
3761 			if (manager->use_reserve == true) {
3762 				for (i = 0; i < max_instance; i++) {
3763 					reserve_buff =
3764 						&manager->reserve_buff[i];
3765 					if (reserve_buff->used	== true &&
3766 						buf_start ==
3767 						reserve_buff->buf_start) {
3768 						reserve_buff->used = false;
3769 						break;
3770 					}
3771 				}
3772 			}
3773 			*find = true;
3774 			manager->wq_count--;
3775 			enc_pr(LOG_DEBUG,
3776 				"remove  encode_work_queue %p success, %s line %d.\n",
3777 				(void *)encode_work_queue,
3778 				__func__, __LINE__);
3779 			break;
3780 		}
3781 	}
3782 }
3783 
destroy_encode_work_queue(struct encode_wq_s * encode_work_queue)3784 s32 destroy_encode_work_queue(struct encode_wq_s *encode_work_queue)
3785 {
3786 	struct encode_queue_item_s *pitem, *tmp;
3787 	struct encode_wq_s *wq = NULL;
3788 	bool find = false;
3789 
3790 	struct list_head *head;
3791 
3792 	if (encode_work_queue) {
3793 		spin_lock(&encode_manager.event.sem_lock);
3794 		if (encode_manager.current_wq == encode_work_queue) {
3795 			encode_manager.remove_flag = true;
3796 			spin_unlock(&encode_manager.event.sem_lock);
3797 			enc_pr(LOG_DEBUG,
3798 				"warning--Destroy the running queue, should not be here.\n");
3799 			wait_for_completion(
3800 				&encode_manager.event.process_complete);
3801 			spin_lock(&encode_manager.event.sem_lock);
3802 		} /* else we can delete it safely. */
3803 
3804 		head =  &encode_manager.process_queue;
3805 		list_for_each_entry_safe(pitem, tmp, head, list) {
3806 			if (pitem && pitem->request.parent ==
3807 				encode_work_queue) {
3808 				pitem->request.parent = NULL;
3809 				enc_pr(LOG_DEBUG,
3810 					"warning--remove not process request, should not be here.\n");
3811 				list_move_tail(&pitem->list,
3812 					&encode_manager.free_queue);
3813 			}
3814 		}
3815 
3816 		_destroy_encode_work_queue(&encode_manager, &wq,
3817 			encode_work_queue, &find);
3818 		spin_unlock(&encode_manager.event.sem_lock);
3819 #ifdef CONFIG_CMA
3820 		if (encode_work_queue->mem.buf_start) {
3821 			if (wq->mem.cbr_info_ddr_virt_addr != NULL) {
3822 				codec_mm_unmap_phyaddr(wq->mem.cbr_info_ddr_virt_addr);
3823 				wq->mem.cbr_info_ddr_virt_addr = NULL;
3824 			}
3825 			codec_mm_free_for_dma(
3826 				ENCODE_NAME,
3827 				encode_work_queue->mem.buf_start);
3828 			encode_work_queue->mem.buf_start = 0;
3829 
3830 		}
3831 #endif
3832 		kfree(encode_work_queue);
3833 		complete(&encode_manager.event.request_in_com);
3834 	}
3835 	return  0;
3836 }
3837 
encode_monitor_thread(void * data)3838 static s32 encode_monitor_thread(void *data)
3839 {
3840 	struct encode_manager_s *manager = (struct encode_manager_s *)data;
3841 	struct encode_queue_item_s *pitem = NULL;
3842 	struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3843 	s32 ret = 0;
3844 
3845 	enc_pr(LOG_DEBUG, "encode workqueue monitor start.\n");
3846 	//sched_setscheduler(current, SCHED_FIFO, &param);
3847 	allow_signal(SIGTERM);
3848 	/* setup current_wq here. */
3849 	while (manager->process_queue_state != ENCODE_PROCESS_QUEUE_STOP) {
3850 		if (kthread_should_stop())
3851 			break;
3852 
3853 		ret = wait_for_completion_interruptible(
3854 				&manager->event.request_in_com);
3855 
3856 		if (ret == -ERESTARTSYS)
3857 			break;
3858 
3859 		if (kthread_should_stop())
3860 			break;
3861 		if (manager->inited == false) {
3862 			spin_lock(&manager->event.sem_lock);
3863 			if (!list_empty(&manager->wq)) {
3864 				struct encode_wq_s *first_wq =
3865 					list_entry(manager->wq.next,
3866 					struct encode_wq_s, list);
3867 				manager->current_wq = first_wq;
3868 				spin_unlock(&manager->event.sem_lock);
3869 				if (first_wq) {
3870 #ifdef CONFIG_AMLOGIC_MEDIA_GE2D
3871 					if (!manager->context)
3872 						manager->context =
3873 						create_ge2d_work_queue();
3874 #endif
3875 					avc_init(first_wq);
3876 					manager->inited = true;
3877 				}
3878 				spin_lock(&manager->event.sem_lock);
3879 				manager->current_wq = NULL;
3880 				spin_unlock(&manager->event.sem_lock);
3881 				if (manager->remove_flag) {
3882 					complete(
3883 						&manager
3884 						->event.process_complete);
3885 					manager->remove_flag = false;
3886 				}
3887 			} else
3888 				spin_unlock(&manager->event.sem_lock);
3889 			continue;
3890 		}
3891 
3892 		spin_lock(&manager->event.sem_lock);
3893 		pitem = NULL;
3894 		if (list_empty(&manager->wq)) {
3895 			spin_unlock(&manager->event.sem_lock);
3896 			manager->inited = false;
3897 			amvenc_avc_stop();
3898 #ifdef CONFIG_AMLOGIC_MEDIA_GE2D
3899 			if (manager->context) {
3900 				destroy_ge2d_work_queue(manager->context);
3901 				manager->context = NULL;
3902 			}
3903 #endif
3904 			enc_pr(LOG_DEBUG, "power off encode.\n");
3905 			continue;
3906 		} else if (!list_empty(&manager->process_queue)) {
3907 			pitem = list_entry(manager->process_queue.next,
3908 				struct encode_queue_item_s, list);
3909 			list_del(&pitem->list);
3910 			manager->current_item = pitem;
3911 			manager->current_wq = pitem->request.parent;
3912 		}
3913 		spin_unlock(&manager->event.sem_lock);
3914 
3915 		if (pitem) {
3916 			encode_process_request(manager, pitem);
3917 			spin_lock(&manager->event.sem_lock);
3918 			list_add_tail(&pitem->list, &manager->free_queue);
3919 			manager->current_item = NULL;
3920 			manager->last_wq = manager->current_wq;
3921 			manager->current_wq = NULL;
3922 			spin_unlock(&manager->event.sem_lock);
3923 		}
3924 		if (manager->remove_flag) {
3925 			complete(&manager->event.process_complete);
3926 			manager->remove_flag = false;
3927 		}
3928 	}
3929 	while (!kthread_should_stop())
3930 		msleep(20);
3931 
3932 	enc_pr(LOG_DEBUG, "exit encode_monitor_thread.\n");
3933 	return 0;
3934 }
3935 
encode_start_monitor(void)3936 static s32 encode_start_monitor(void)
3937 {
3938 	s32 ret = 0;
3939 
3940 	if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) {
3941 		y_tnr_mot2alp_nrm_gain = 216;
3942 		y_tnr_mot2alp_dis_gain = 144;
3943 		c_tnr_mot2alp_nrm_gain = 216;
3944 		c_tnr_mot2alp_dis_gain = 144;
3945 	} else {
3946 		/* more tnr */
3947 		y_tnr_mot2alp_nrm_gain = 144;
3948 		y_tnr_mot2alp_dis_gain = 96;
3949 		c_tnr_mot2alp_nrm_gain = 144;
3950 		c_tnr_mot2alp_dis_gain = 96;
3951 	}
3952 
3953 	enc_pr(LOG_DEBUG, "encode start monitor.\n");
3954 	encode_manager.process_queue_state = ENCODE_PROCESS_QUEUE_START;
3955 	encode_manager.encode_thread = kthread_run(encode_monitor_thread,
3956 		&encode_manager, "encode_monitor");
3957 	if (IS_ERR(encode_manager.encode_thread)) {
3958 		ret = PTR_ERR(encode_manager.encode_thread);
3959 		encode_manager.process_queue_state = ENCODE_PROCESS_QUEUE_STOP;
3960 		enc_pr(LOG_ERROR,
3961 			"encode monitor : failed to start kthread (%d)\n", ret);
3962 	}
3963 	return ret;
3964 }
3965 
encode_stop_monitor(void)3966 static s32  encode_stop_monitor(void)
3967 {
3968 	enc_pr(LOG_DEBUG, "stop encode monitor thread\n");
3969 	if (encode_manager.encode_thread) {
3970 		spin_lock(&encode_manager.event.sem_lock);
3971 		if (!list_empty(&encode_manager.wq)) {
3972 			u32 count = encode_manager.wq_count;
3973 
3974 			spin_unlock(&encode_manager.event.sem_lock);
3975 			enc_pr(LOG_ERROR,
3976 				"stop encode monitor thread error, active wq (%d) is not 0.\n",
3977 				 count);
3978 			return -1;
3979 		}
3980 		spin_unlock(&encode_manager.event.sem_lock);
3981 		encode_manager.process_queue_state = ENCODE_PROCESS_QUEUE_STOP;
3982 		send_sig(SIGTERM, encode_manager.encode_thread, 1);
3983 		complete(&encode_manager.event.request_in_com);
3984 		kthread_stop(encode_manager.encode_thread);
3985 		encode_manager.encode_thread = NULL;
3986 		kfree(mc_addr);
3987 		mc_addr = NULL;
3988 	}
3989 	return  0;
3990 }
3991 
encode_wq_init(void)3992 static s32 encode_wq_init(void)
3993 {
3994 	u32 i = 0;
3995 	struct encode_queue_item_s *pitem = NULL;
3996 
3997 	enc_pr(LOG_DEBUG, "encode_wq_init.\n");
3998 	encode_manager.irq_requested = false;
3999 
4000 	spin_lock_init(&encode_manager.event.sem_lock);
4001 	init_completion(&encode_manager.event.request_in_com);
4002 	init_waitqueue_head(&encode_manager.event.hw_complete);
4003 	init_completion(&encode_manager.event.process_complete);
4004 	INIT_LIST_HEAD(&encode_manager.process_queue);
4005 	INIT_LIST_HEAD(&encode_manager.free_queue);
4006 	INIT_LIST_HEAD(&encode_manager.wq);
4007 
4008 	tasklet_init(&encode_manager.encode_tasklet,
4009 		encode_isr_tasklet,
4010 		(ulong)&encode_manager);
4011 
4012 	for (i = 0; i < MAX_ENCODE_REQUEST; i++) {
4013 		pitem = kcalloc(1,
4014 			sizeof(struct encode_queue_item_s),
4015 			GFP_KERNEL);
4016 		if (IS_ERR(pitem)) {
4017 			enc_pr(LOG_ERROR, "can't request queue item memory.\n");
4018 			return -1;
4019 		}
4020 		pitem->request.parent = NULL;
4021 		list_add_tail(&pitem->list, &encode_manager.free_queue);
4022 	}
4023 	encode_manager.current_wq = NULL;
4024 	encode_manager.last_wq = NULL;
4025 	encode_manager.encode_thread = NULL;
4026 	encode_manager.current_item = NULL;
4027 	encode_manager.wq_count = 0;
4028 	encode_manager.remove_flag = false;
4029 	InitEncodeWeight();
4030 	if (encode_start_monitor()) {
4031 		enc_pr(LOG_ERROR, "encode create thread error.\n");
4032 		return -1;
4033 	}
4034 	return 0;
4035 }
4036 
encode_wq_uninit(void)4037 static s32 encode_wq_uninit(void)
4038 {
4039 	struct encode_queue_item_s *pitem, *tmp;
4040 	struct list_head *head;
4041 	u32 count = 0;
4042 	s32 r = -1;
4043 
4044 	enc_pr(LOG_DEBUG, "uninit encode wq.\n");
4045 	if (encode_stop_monitor() == 0) {
4046 		if ((encode_manager.irq_num >= 0) &&
4047 			(encode_manager.irq_requested == true)) {
4048 			free_irq(encode_manager.irq_num, &encode_manager);
4049 			encode_manager.irq_requested = false;
4050 		}
4051 		spin_lock(&encode_manager.event.sem_lock);
4052 		head =  &encode_manager.process_queue;
4053 		list_for_each_entry_safe(pitem, tmp, head, list) {
4054 			if (pitem) {
4055 				list_del(&pitem->list);
4056 				kfree(pitem);
4057 				count++;
4058 			}
4059 		}
4060 		head =  &encode_manager.free_queue;
4061 		list_for_each_entry_safe(pitem, tmp, head, list) {
4062 			if (pitem) {
4063 				list_del(&pitem->list);
4064 				kfree(pitem);
4065 				count++;
4066 			}
4067 		}
4068 		spin_unlock(&encode_manager.event.sem_lock);
4069 		if (count == MAX_ENCODE_REQUEST)
4070 			r = 0;
4071 		else {
4072 			enc_pr(LOG_ERROR, "lost some request item %d.\n",
4073 				MAX_ENCODE_REQUEST - count);
4074 		}
4075 	}
4076 	return  r;
4077 }
4078 
encode_status_show(struct class * cla,struct class_attribute * attr,char * buf)4079 static ssize_t encode_status_show(struct class *cla,
4080 				  struct class_attribute *attr, char *buf)
4081 {
4082 	u32 process_count = 0;
4083 	u32 free_count = 0;
4084 	struct encode_queue_item_s *pitem = NULL;
4085 	struct encode_wq_s *current_wq = NULL;
4086 	struct encode_wq_s *last_wq = NULL;
4087 	struct list_head *head = NULL;
4088 	s32 irq_num = 0;
4089 	u32 hw_status = 0;
4090 	u32 process_queue_state = 0;
4091 	u32 wq_count = 0;
4092 	u32 ucode_index;
4093 	bool need_reset;
4094 	bool process_irq;
4095 	bool inited;
4096 	bool use_reserve;
4097 	struct Buff_s reserve_mem;
4098 	u32 max_instance;
4099 #ifdef CONFIG_CMA
4100 	bool check_cma = false;
4101 #endif
4102 
4103 	spin_lock(&encode_manager.event.sem_lock);
4104 	head = &encode_manager.free_queue;
4105 	list_for_each_entry(pitem, head, list) {
4106 		free_count++;
4107 		if (free_count > MAX_ENCODE_REQUEST)
4108 			break;
4109 	}
4110 
4111 	head = &encode_manager.process_queue;
4112 	list_for_each_entry(pitem, head, list) {
4113 		process_count++;
4114 		if (free_count > MAX_ENCODE_REQUEST)
4115 			break;
4116 	}
4117 
4118 	current_wq = encode_manager.current_wq;
4119 	last_wq = encode_manager.last_wq;
4120 	pitem = encode_manager.current_item;
4121 	irq_num = encode_manager.irq_num;
4122 	hw_status = encode_manager.encode_hw_status;
4123 	process_queue_state = encode_manager.process_queue_state;
4124 	wq_count = encode_manager.wq_count;
4125 	ucode_index = encode_manager.ucode_index;
4126 	need_reset = encode_manager.need_reset;
4127 	process_irq = encode_manager.process_irq;
4128 	inited = encode_manager.inited;
4129 	use_reserve = encode_manager.use_reserve;
4130 	reserve_mem.buf_start = encode_manager.reserve_mem.buf_start;
4131 	reserve_mem.buf_size = encode_manager.reserve_mem.buf_size;
4132 
4133 	max_instance = encode_manager.max_instance;
4134 #ifdef CONFIG_CMA
4135 	check_cma = encode_manager.check_cma;
4136 #endif
4137 
4138 	spin_unlock(&encode_manager.event.sem_lock);
4139 
4140 	enc_pr(LOG_DEBUG,
4141 		"encode process queue count: %d, free queue count: %d.\n",
4142 		process_count, free_count);
4143 	enc_pr(LOG_DEBUG,
4144 		"encode curent wq: %p, last wq: %p, wq count: %d, max_instance: %d.\n",
4145 		current_wq, last_wq, wq_count, max_instance);
4146 	if (current_wq)
4147 		enc_pr(LOG_DEBUG,
4148 			"encode curent wq -- encode width: %d, encode height: %d.\n",
4149 			current_wq->pic.encoder_width,
4150 			current_wq->pic.encoder_height);
4151 	enc_pr(LOG_DEBUG,
4152 		"encode curent pitem: %p, ucode_index: %d, hw_status: %d, need_reset: %s, process_irq: %s.\n",
4153 		pitem, ucode_index, hw_status, need_reset ? "true" : "false",
4154 		process_irq ? "true" : "false");
4155 	enc_pr(LOG_DEBUG,
4156 		"encode irq num: %d,  inited: %s, process_queue_state: %d.\n",
4157 		irq_num, inited ? "true" : "false",  process_queue_state);
4158 	if (use_reserve) {
4159 		enc_pr(LOG_DEBUG,
4160 			"encode use reserve memory, buffer start: 0x%x, size: %d MB.\n",
4161 			 reserve_mem.buf_start,
4162 			 reserve_mem.buf_size / SZ_1M);
4163 	} else {
4164 #ifdef CONFIG_CMA
4165 		enc_pr(LOG_DEBUG, "encode check cma: %s.\n",
4166 			check_cma ? "true" : "false");
4167 #endif
4168 	}
4169 	return snprintf(buf, 40, "encode max instance: %d\n", max_instance);
4170 }
4171 
4172 static CLASS_ATTR_RO(encode_status);
4173 
4174 static struct attribute *amvenc_class_attrs[] = {
4175 	&class_attr_encode_status.attr,
4176 	NULL
4177 };
4178 
4179 ATTRIBUTE_GROUPS(amvenc_class);
4180 
4181 static struct class amvenc_avc_class = {
4182 	.name = CLASS_NAME,
4183 	.class_groups = amvenc_class_groups,
4184 };
4185 
init_avc_device(void)4186 s32 init_avc_device(void)
4187 {
4188 	s32  r = 0;
4189 
4190 	r = register_chrdev(0, DEVICE_NAME, &amvenc_avc_fops);
4191 	if (r <= 0) {
4192 		enc_pr(LOG_ERROR, "register amvenc_avc device error.\n");
4193 		return  r;
4194 	}
4195 	avc_device_major = r;
4196 
4197 	r = class_register(&amvenc_avc_class);
4198 	if (r < 0) {
4199 		enc_pr(LOG_ERROR, "error create amvenc_avc class.\n");
4200 		return r;
4201 	}
4202 
4203 	amvenc_avc_dev = device_create(&amvenc_avc_class, NULL,
4204 		MKDEV(avc_device_major, 0), NULL,
4205 		DEVICE_NAME);
4206 
4207 	if (IS_ERR(amvenc_avc_dev)) {
4208 		enc_pr(LOG_ERROR, "create amvenc_avc device error.\n");
4209 		class_unregister(&amvenc_avc_class);
4210 		return -1;
4211 	}
4212 	return r;
4213 }
4214 
uninit_avc_device(void)4215 s32 uninit_avc_device(void)
4216 {
4217 	if (amvenc_avc_dev)
4218 		device_destroy(&amvenc_avc_class, MKDEV(avc_device_major, 0));
4219 
4220 	class_destroy(&amvenc_avc_class);
4221 
4222 	unregister_chrdev(avc_device_major, DEVICE_NAME);
4223 	return 0;
4224 }
4225 
avc_mem_device_init(struct reserved_mem * rmem,struct device * dev)4226 static s32 avc_mem_device_init(struct reserved_mem *rmem, struct device *dev)
4227 {
4228 	s32 r;
4229 	struct resource res;
4230 
4231 	if (!rmem) {
4232 		enc_pr(LOG_ERROR,
4233 			"Can not obtain I/O memory, and will allocate avc buffer!\n");
4234 		r = -EFAULT;
4235 		return r;
4236 	}
4237 	res.start = (phys_addr_t)rmem->base;
4238 	res.end = res.start + (phys_addr_t)rmem->size - 1;
4239 	encode_manager.reserve_mem.buf_start = res.start;
4240 	encode_manager.reserve_mem.buf_size = res.end - res.start + 1;
4241 
4242 	if (encode_manager.reserve_mem.buf_size >=
4243 		amvenc_buffspec[0].min_buffsize) {
4244 		encode_manager.max_instance =
4245 			encode_manager.reserve_mem.buf_size /
4246 			amvenc_buffspec[0].min_buffsize;
4247 		if (encode_manager.max_instance > MAX_ENCODE_INSTANCE)
4248 			encode_manager.max_instance = MAX_ENCODE_INSTANCE;
4249 		encode_manager.reserve_buff = kzalloc(
4250 			encode_manager.max_instance *
4251 			sizeof(struct Buff_s), GFP_KERNEL);
4252 		if (encode_manager.reserve_buff) {
4253 			u32 i;
4254 			struct Buff_s *reserve_buff;
4255 			u32 max_instance = encode_manager.max_instance;
4256 
4257 			for (i = 0; i < max_instance; i++) {
4258 				reserve_buff = &encode_manager.reserve_buff[i];
4259 				reserve_buff->buf_start =
4260 					i *
4261 					amvenc_buffspec[0]
4262 					.min_buffsize +
4263 					encode_manager.reserve_mem.buf_start;
4264 				reserve_buff->buf_size =
4265 					encode_manager.reserve_mem.buf_start;
4266 				reserve_buff->used = false;
4267 			}
4268 			encode_manager.use_reserve = true;
4269 			r = 0;
4270 			enc_pr(LOG_DEBUG,
4271 				"amvenc_avc  use reserve memory, buff start: 0x%x, size: 0x%x, max instance is %d\n",
4272 				encode_manager.reserve_mem.buf_start,
4273 				encode_manager.reserve_mem.buf_size,
4274 				encode_manager.max_instance);
4275 		} else {
4276 			enc_pr(LOG_ERROR,
4277 				"amvenc_avc alloc reserve buffer pointer fail. max instance is %d.\n",
4278 				encode_manager.max_instance);
4279 			encode_manager.max_instance = 0;
4280 			encode_manager.reserve_mem.buf_start = 0;
4281 			encode_manager.reserve_mem.buf_size = 0;
4282 			r = -ENOMEM;
4283 		}
4284 	} else {
4285 		enc_pr(LOG_ERROR,
4286 			"amvenc_avc memory resource too small, size is 0x%x. Need 0x%x bytes at least.\n",
4287 			encode_manager.reserve_mem.buf_size,
4288 			amvenc_buffspec[0]
4289 			.min_buffsize);
4290 		encode_manager.reserve_mem.buf_start = 0;
4291 		encode_manager.reserve_mem.buf_size = 0;
4292 		r = -ENOMEM;
4293 	}
4294 	return r;
4295 }
4296 
amvenc_avc_probe(struct platform_device * pdev)4297 static s32 amvenc_avc_probe(struct platform_device *pdev)
4298 {
4299 	/* struct resource mem; */
4300 	s32 res_irq;
4301 	s32 idx;
4302 	s32 r;
4303 
4304 	enc_pr(LOG_INFO, "amvenc_avc probe start.\n");
4305 
4306 	encode_manager.this_pdev = pdev;
4307 #ifdef CONFIG_CMA
4308 	encode_manager.check_cma = false;
4309 #endif
4310 	encode_manager.reserve_mem.buf_start = 0;
4311 	encode_manager.reserve_mem.buf_size = 0;
4312 	encode_manager.use_reserve = false;
4313 	encode_manager.max_instance = 0;
4314 	encode_manager.reserve_buff = NULL;
4315 
4316 	idx = of_reserved_mem_device_init(&pdev->dev);
4317 	if (idx != 0) {
4318 		enc_pr(LOG_DEBUG,
4319 			"amvenc_avc_probe -- reserved memory config fail.\n");
4320 	}
4321 
4322 	if (encode_manager.use_reserve == false) {
4323 #ifndef CONFIG_CMA
4324 		enc_pr(LOG_ERROR,
4325 			"amvenc_avc memory is invaild, probe fail!\n");
4326 		return -EFAULT;
4327 #else
4328 		encode_manager.cma_pool_size =
4329 			(codec_mm_get_total_size() > (MIN_SIZE * 3)) ?
4330 			(MIN_SIZE * 3) : codec_mm_get_total_size();
4331 		enc_pr(LOG_DEBUG,
4332 			"amvenc_avc - cma memory pool size: %d MB\n",
4333 			(u32)encode_manager.cma_pool_size / SZ_1M);
4334 #endif
4335 	}
4336 
4337 	res_irq = platform_get_irq(pdev, 0);
4338 	if (res_irq < 0) {
4339 		enc_pr(LOG_ERROR, "[%s] get irq error!", __func__);
4340 		return -EINVAL;
4341 	}
4342 
4343 	encode_manager.irq_num = res_irq;
4344 	if (encode_wq_init()) {
4345 		kfree(encode_manager.reserve_buff);
4346 		encode_manager.reserve_buff = NULL;
4347 		enc_pr(LOG_ERROR, "encode work queue init error.\n");
4348 		return -EFAULT;
4349 	}
4350 
4351 	r = init_avc_device();
4352 	enc_pr(LOG_INFO, "amvenc_avc probe end.\n");
4353 	return r;
4354 }
4355 
amvenc_avc_remove(struct platform_device * pdev)4356 static s32 amvenc_avc_remove(struct platform_device *pdev)
4357 {
4358 	kfree(encode_manager.reserve_buff);
4359 	encode_manager.reserve_buff = NULL;
4360 	if (encode_wq_uninit())
4361 		enc_pr(LOG_ERROR, "encode work queue uninit error.\n");
4362 	uninit_avc_device();
4363 	enc_pr(LOG_INFO, "amvenc_avc remove.\n");
4364 	return 0;
4365 }
4366 
4367 static const struct of_device_id amlogic_avcenc_dt_match[] = {
4368 	{
4369 		.compatible = "amlogic, amvenc_avc",
4370 	},
4371 	{},
4372 };
4373 
4374 static struct platform_driver amvenc_avc_driver = {
4375 	.probe = amvenc_avc_probe,
4376 	.remove = amvenc_avc_remove,
4377 	.driver = {
4378 		.name = DRIVER_NAME,
4379 		.of_match_table = amlogic_avcenc_dt_match,
4380 	}
4381 };
4382 
4383 static struct codec_profile_t amvenc_avc_profile = {
4384 	.name = "avc",
4385 	.profile = ""
4386 };
4387 
amvenc_avc_driver_init_module(void)4388 static s32 __init amvenc_avc_driver_init_module(void)
4389 {
4390 	enc_pr(LOG_INFO, "amvenc_avc module init\n");
4391 
4392 	if (platform_driver_register(&amvenc_avc_driver)) {
4393 		enc_pr(LOG_ERROR,
4394 			"failed to register amvenc_avc driver\n");
4395 		return -ENODEV;
4396 	}
4397 	vcodec_profile_register(&amvenc_avc_profile);
4398 	return 0;
4399 }
4400 
amvenc_avc_driver_remove_module(void)4401 static void __exit amvenc_avc_driver_remove_module(void)
4402 {
4403 	enc_pr(LOG_INFO, "amvenc_avc module remove.\n");
4404 
4405 	platform_driver_unregister(&amvenc_avc_driver);
4406 }
4407 
4408 static const struct reserved_mem_ops rmem_avc_ops = {
4409 	.device_init = avc_mem_device_init,
4410 };
4411 
avc_mem_setup(struct reserved_mem * rmem)4412 static s32 __init avc_mem_setup(struct reserved_mem *rmem)
4413 {
4414 	rmem->ops = &rmem_avc_ops;
4415 	enc_pr(LOG_DEBUG, "amvenc_avc reserved mem setup.\n");
4416 	return 0;
4417 }
4418 
enc_dma_buf_map(struct enc_dma_cfg * cfg)4419 static int enc_dma_buf_map(struct enc_dma_cfg *cfg)
4420 {
4421 	long ret = -1;
4422 	int fd = -1;
4423 	struct dma_buf *dbuf = NULL;
4424 	struct dma_buf_attachment *d_att = NULL;
4425 	struct sg_table *sg = NULL;
4426 	void *vaddr = NULL;
4427 	struct device *dev = NULL;
4428 	enum dma_data_direction dir;
4429 
4430 	if (cfg == NULL || (cfg->fd < 0) || cfg->dev == NULL) {
4431 		enc_pr(LOG_ERROR, "error input param\n");
4432 		return -EINVAL;
4433 	}
4434 	enc_pr(LOG_INFO, "enc_dma_buf_map, fd %d\n", cfg->fd);
4435 
4436 	fd = cfg->fd;
4437 	dev = cfg->dev;
4438 	dir = cfg->dir;
4439 	enc_pr(LOG_INFO, "enc_dma_buffer_map fd %d\n", fd);
4440 
4441 	dbuf = dma_buf_get(fd);
4442 	if (dbuf == NULL) {
4443 		enc_pr(LOG_ERROR, "failed to get dma buffer,fd %d\n",fd);
4444 		return -EINVAL;
4445 	}
4446 
4447 	d_att = dma_buf_attach(dbuf, dev);
4448 	if (d_att == NULL) {
4449 		enc_pr(LOG_ERROR, "failed to set dma attach\n");
4450 		goto attach_err;
4451 	}
4452 
4453 	sg = dma_buf_map_attachment(d_att, dir);
4454 	if (sg == NULL) {
4455 		enc_pr(LOG_ERROR, "failed to get dma sg\n");
4456 		goto map_attach_err;
4457 	}
4458 
4459 	ret = dma_buf_begin_cpu_access(dbuf, dir);
4460 	if (ret != 0) {
4461 		enc_pr(LOG_ERROR, "failed to access dma buff\n");
4462 		goto access_err;
4463 	}
4464 
4465 	vaddr = dma_buf_vmap(dbuf);
4466 	if (vaddr == NULL) {
4467 		enc_pr(LOG_ERROR, "failed to vmap dma buf\n");
4468 		goto vmap_err;
4469 	}
4470 	cfg->dbuf = dbuf;
4471 	cfg->attach = d_att;
4472 	cfg->vaddr = vaddr;
4473 	cfg->sg = sg;
4474 
4475 	return ret;
4476 
4477 vmap_err:
4478 	dma_buf_end_cpu_access(dbuf, dir);
4479 
4480 access_err:
4481 	dma_buf_unmap_attachment(d_att, sg, dir);
4482 
4483 map_attach_err:
4484 	dma_buf_detach(dbuf, d_att);
4485 
4486 attach_err:
4487 	dma_buf_put(dbuf);
4488 
4489 	return ret;
4490 }
4491 
enc_dma_buf_get_phys(struct enc_dma_cfg * cfg,unsigned long * addr)4492 static int enc_dma_buf_get_phys(struct enc_dma_cfg *cfg, unsigned long *addr)
4493 {
4494 	struct sg_table *sg_table;
4495 	struct page *page;
4496 	int ret;
4497 	enc_pr(LOG_INFO, "enc_dma_buf_get_phys in\n");
4498 
4499 	ret = enc_dma_buf_map(cfg);
4500 	if (ret < 0) {
4501 		enc_pr(LOG_ERROR, "gdc_dma_buf_map failed\n");
4502 		return ret;
4503 	}
4504 	if (cfg->sg) {
4505 		sg_table = cfg->sg;
4506 		page = sg_page(sg_table->sgl);
4507 		*addr = PFN_PHYS(page_to_pfn(page));
4508 		ret = 0;
4509 	}
4510 	enc_pr(LOG_INFO, "enc_dma_buf_get_phys 0x%lx\n", *addr);
4511 	return ret;
4512 }
4513 
enc_dma_buf_unmap(struct enc_dma_cfg * cfg)4514 static void enc_dma_buf_unmap(struct enc_dma_cfg *cfg)
4515 {
4516 	int fd = -1;
4517 	struct dma_buf *dbuf = NULL;
4518 	struct dma_buf_attachment *d_att = NULL;
4519 	struct sg_table *sg = NULL;
4520 	void *vaddr = NULL;
4521 	struct device *dev = NULL;
4522 	enum dma_data_direction dir;
4523 
4524 	if (cfg == NULL || (cfg->fd < 0) || cfg->dev == NULL
4525 			|| cfg->dbuf == NULL || cfg->vaddr == NULL
4526 			|| cfg->attach == NULL || cfg->sg == NULL) {
4527 		enc_pr(LOG_ERROR, "Error input param\n");
4528 		return;
4529 	}
4530 
4531 	fd = cfg->fd;
4532 	dev = cfg->dev;
4533 	dir = cfg->dir;
4534 	dbuf = cfg->dbuf;
4535 	vaddr = cfg->vaddr;
4536 	d_att = cfg->attach;
4537 	sg = cfg->sg;
4538 
4539 	dma_buf_vunmap(dbuf, vaddr);
4540 
4541 	dma_buf_end_cpu_access(dbuf, dir);
4542 
4543 	dma_buf_unmap_attachment(d_att, sg, dir);
4544 
4545 	dma_buf_detach(dbuf, d_att);
4546 
4547 	dma_buf_put(dbuf);
4548 	enc_pr(LOG_DEBUG, "enc_dma_buffer_unmap vaddr %p\n",(unsigned *)vaddr);
4549 }
4550 
4551 
4552 module_param(fixed_slice_cfg, uint, 0664);
4553 MODULE_PARM_DESC(fixed_slice_cfg, "\n fixed_slice_cfg\n");
4554 
4555 module_param(clock_level, uint, 0664);
4556 MODULE_PARM_DESC(clock_level, "\n clock_level\n");
4557 
4558 module_param(encode_print_level, uint, 0664);
4559 MODULE_PARM_DESC(encode_print_level, "\n encode_print_level\n");
4560 
4561 module_param(no_timeout, uint, 0664);
4562 MODULE_PARM_DESC(no_timeout, "\n no_timeout flag for process request\n");
4563 
4564 module_param(nr_mode, int, 0664);
4565 MODULE_PARM_DESC(nr_mode, "\n nr_mode option\n");
4566 
4567 module_param(qp_table_debug, uint, 0664);
4568 MODULE_PARM_DESC(qp_table_debug, "\n print qp table\n");
4569 
4570 #ifdef H264_ENC_SVC
4571 module_param(svc_enable, uint, 0664);
4572 MODULE_PARM_DESC(svc_enable, "\n svc enable\n");
4573 module_param(svc_ref_conf, uint, 0664);
4574 MODULE_PARM_DESC(svc_ref_conf, "\n svc reference duration config\n");
4575 #endif
4576 
4577 #ifdef MORE_MODULE_PARAM
4578 module_param(me_mv_merge_ctl, uint, 0664);
4579 MODULE_PARM_DESC(me_mv_merge_ctl, "\n me_mv_merge_ctl\n");
4580 
4581 module_param(me_step0_close_mv, uint, 0664);
4582 MODULE_PARM_DESC(me_step0_close_mv, "\n me_step0_close_mv\n");
4583 
4584 module_param(me_f_skip_sad, uint, 0664);
4585 MODULE_PARM_DESC(me_f_skip_sad, "\n me_f_skip_sad\n");
4586 
4587 module_param(me_f_skip_weight, uint, 0664);
4588 MODULE_PARM_DESC(me_f_skip_weight, "\n me_f_skip_weight\n");
4589 
4590 module_param(me_mv_weight_01, uint, 0664);
4591 MODULE_PARM_DESC(me_mv_weight_01, "\n me_mv_weight_01\n");
4592 
4593 module_param(me_mv_weight_23, uint, 0664);
4594 MODULE_PARM_DESC(me_mv_weight_23, "\n me_mv_weight_23\n");
4595 
4596 module_param(me_sad_range_inc, uint, 0664);
4597 MODULE_PARM_DESC(me_sad_range_inc, "\n me_sad_range_inc\n");
4598 
4599 module_param(me_sad_enough_01, uint, 0664);
4600 MODULE_PARM_DESC(me_sad_enough_01, "\n me_sad_enough_01\n");
4601 
4602 module_param(me_sad_enough_23, uint, 0664);
4603 MODULE_PARM_DESC(me_sad_enough_23, "\n me_sad_enough_23\n");
4604 
4605 module_param(y_tnr_mc_en, uint, 0664);
4606 MODULE_PARM_DESC(y_tnr_mc_en, "\n y_tnr_mc_en option\n");
4607 module_param(y_tnr_txt_mode, uint, 0664);
4608 MODULE_PARM_DESC(y_tnr_txt_mode, "\n y_tnr_txt_mode option\n");
4609 module_param(y_tnr_mot_sad_margin, uint, 0664);
4610 MODULE_PARM_DESC(y_tnr_mot_sad_margin, "\n y_tnr_mot_sad_margin option\n");
4611 module_param(y_tnr_mot_cortxt_rate, uint, 0664);
4612 MODULE_PARM_DESC(y_tnr_mot_cortxt_rate, "\n y_tnr_mot_cortxt_rate option\n");
4613 module_param(y_tnr_mot_distxt_ofst, uint, 0664);
4614 MODULE_PARM_DESC(y_tnr_mot_distxt_ofst, "\n y_tnr_mot_distxt_ofst option\n");
4615 module_param(y_tnr_mot_distxt_rate, uint, 0664);
4616 MODULE_PARM_DESC(y_tnr_mot_distxt_rate, "\n y_tnr_mot_distxt_rate option\n");
4617 module_param(y_tnr_mot_dismot_ofst, uint, 0664);
4618 MODULE_PARM_DESC(y_tnr_mot_dismot_ofst, "\n y_tnr_mot_dismot_ofst option\n");
4619 module_param(y_tnr_mot_frcsad_lock, uint, 0664);
4620 MODULE_PARM_DESC(y_tnr_mot_frcsad_lock, "\n y_tnr_mot_frcsad_lock option\n");
4621 module_param(y_tnr_mot2alp_frc_gain, uint, 0664);
4622 MODULE_PARM_DESC(y_tnr_mot2alp_frc_gain, "\n y_tnr_mot2alp_frc_gain option\n");
4623 module_param(y_tnr_mot2alp_nrm_gain, uint, 0664);
4624 MODULE_PARM_DESC(y_tnr_mot2alp_nrm_gain, "\n y_tnr_mot2alp_nrm_gain option\n");
4625 module_param(y_tnr_mot2alp_dis_gain, uint, 0664);
4626 MODULE_PARM_DESC(y_tnr_mot2alp_dis_gain, "\n y_tnr_mot2alp_dis_gain option\n");
4627 module_param(y_tnr_mot2alp_dis_ofst, uint, 0664);
4628 MODULE_PARM_DESC(y_tnr_mot2alp_dis_ofst, "\n y_tnr_mot2alp_dis_ofst option\n");
4629 module_param(y_tnr_alpha_min, uint, 0664);
4630 MODULE_PARM_DESC(y_tnr_alpha_min, "\n y_tnr_alpha_min option\n");
4631 module_param(y_tnr_alpha_max, uint, 0664);
4632 MODULE_PARM_DESC(y_tnr_alpha_max, "\n y_tnr_alpha_max option\n");
4633 module_param(y_tnr_deghost_os, uint, 0664);
4634 MODULE_PARM_DESC(y_tnr_deghost_os, "\n y_tnr_deghost_os option\n");
4635 
4636 module_param(c_tnr_mc_en, uint, 0664);
4637 MODULE_PARM_DESC(c_tnr_mc_en, "\n c_tnr_mc_en option\n");
4638 module_param(c_tnr_txt_mode, uint, 0664);
4639 MODULE_PARM_DESC(c_tnr_txt_mode, "\n c_tnr_txt_mode option\n");
4640 module_param(c_tnr_mot_sad_margin, uint, 0664);
4641 MODULE_PARM_DESC(c_tnr_mot_sad_margin, "\n c_tnr_mot_sad_margin option\n");
4642 module_param(c_tnr_mot_cortxt_rate, uint, 0664);
4643 MODULE_PARM_DESC(c_tnr_mot_cortxt_rate, "\n c_tnr_mot_cortxt_rate option\n");
4644 module_param(c_tnr_mot_distxt_ofst, uint, 0664);
4645 MODULE_PARM_DESC(c_tnr_mot_distxt_ofst, "\n c_tnr_mot_distxt_ofst option\n");
4646 module_param(c_tnr_mot_distxt_rate, uint, 0664);
4647 MODULE_PARM_DESC(c_tnr_mot_distxt_rate, "\n c_tnr_mot_distxt_rate option\n");
4648 module_param(c_tnr_mot_dismot_ofst, uint, 0664);
4649 MODULE_PARM_DESC(c_tnr_mot_dismot_ofst, "\n c_tnr_mot_dismot_ofst option\n");
4650 module_param(c_tnr_mot_frcsad_lock, uint, 0664);
4651 MODULE_PARM_DESC(c_tnr_mot_frcsad_lock, "\n c_tnr_mot_frcsad_lock option\n");
4652 module_param(c_tnr_mot2alp_frc_gain, uint, 0664);
4653 MODULE_PARM_DESC(c_tnr_mot2alp_frc_gain, "\n c_tnr_mot2alp_frc_gain option\n");
4654 module_param(c_tnr_mot2alp_nrm_gain, uint, 0664);
4655 MODULE_PARM_DESC(c_tnr_mot2alp_nrm_gain, "\n c_tnr_mot2alp_nrm_gain option\n");
4656 module_param(c_tnr_mot2alp_dis_gain, uint, 0664);
4657 MODULE_PARM_DESC(c_tnr_mot2alp_dis_gain, "\n c_tnr_mot2alp_dis_gain option\n");
4658 module_param(c_tnr_mot2alp_dis_ofst, uint, 0664);
4659 MODULE_PARM_DESC(c_tnr_mot2alp_dis_ofst, "\n c_tnr_mot2alp_dis_ofst option\n");
4660 module_param(c_tnr_alpha_min, uint, 0664);
4661 MODULE_PARM_DESC(c_tnr_alpha_min, "\n c_tnr_alpha_min option\n");
4662 module_param(c_tnr_alpha_max, uint, 0664);
4663 MODULE_PARM_DESC(c_tnr_alpha_max, "\n c_tnr_alpha_max option\n");
4664 module_param(c_tnr_deghost_os, uint, 0664);
4665 MODULE_PARM_DESC(c_tnr_deghost_os, "\n c_tnr_deghost_os option\n");
4666 
4667 module_param(y_snr_err_norm, uint, 0664);
4668 MODULE_PARM_DESC(y_snr_err_norm, "\n y_snr_err_norm option\n");
4669 module_param(y_snr_gau_bld_core, uint, 0664);
4670 MODULE_PARM_DESC(y_snr_gau_bld_core, "\n y_snr_gau_bld_core option\n");
4671 module_param(y_snr_gau_bld_ofst, int, 0664);
4672 MODULE_PARM_DESC(y_snr_gau_bld_ofst, "\n y_snr_gau_bld_ofst option\n");
4673 module_param(y_snr_gau_bld_rate, uint, 0664);
4674 MODULE_PARM_DESC(y_snr_gau_bld_rate, "\n y_snr_gau_bld_rate option\n");
4675 module_param(y_snr_gau_alp0_min, uint, 0664);
4676 MODULE_PARM_DESC(y_snr_gau_alp0_min, "\n y_snr_gau_alp0_min option\n");
4677 module_param(y_snr_gau_alp0_max, uint, 0664);
4678 MODULE_PARM_DESC(y_snr_gau_alp0_max, "\n y_snr_gau_alp0_max option\n");
4679 module_param(y_bld_beta2alp_rate, uint, 0664);
4680 MODULE_PARM_DESC(y_bld_beta2alp_rate, "\n y_bld_beta2alp_rate option\n");
4681 module_param(y_bld_beta_min, uint, 0664);
4682 MODULE_PARM_DESC(y_bld_beta_min, "\n y_bld_beta_min option\n");
4683 module_param(y_bld_beta_max, uint, 0664);
4684 MODULE_PARM_DESC(y_bld_beta_max, "\n y_bld_beta_max option\n");
4685 
4686 module_param(c_snr_err_norm, uint, 0664);
4687 MODULE_PARM_DESC(c_snr_err_norm, "\n c_snr_err_norm option\n");
4688 module_param(c_snr_gau_bld_core, uint, 0664);
4689 MODULE_PARM_DESC(c_snr_gau_bld_core, "\n c_snr_gau_bld_core option\n");
4690 module_param(c_snr_gau_bld_ofst, int, 0664);
4691 MODULE_PARM_DESC(c_snr_gau_bld_ofst, "\n c_snr_gau_bld_ofst option\n");
4692 module_param(c_snr_gau_bld_rate, uint, 0664);
4693 MODULE_PARM_DESC(c_snr_gau_bld_rate, "\n c_snr_gau_bld_rate option\n");
4694 module_param(c_snr_gau_alp0_min, uint, 0664);
4695 MODULE_PARM_DESC(c_snr_gau_alp0_min, "\n c_snr_gau_alp0_min option\n");
4696 module_param(c_snr_gau_alp0_max, uint, 0664);
4697 MODULE_PARM_DESC(c_snr_gau_alp0_max, "\n c_snr_gau_alp0_max option\n");
4698 module_param(c_bld_beta2alp_rate, uint, 0664);
4699 MODULE_PARM_DESC(c_bld_beta2alp_rate, "\n c_bld_beta2alp_rate option\n");
4700 module_param(c_bld_beta_min, uint, 0664);
4701 MODULE_PARM_DESC(c_bld_beta_min, "\n c_bld_beta_min option\n");
4702 module_param(c_bld_beta_max, uint, 0664);
4703 MODULE_PARM_DESC(c_bld_beta_max, "\n c_bld_beta_max option\n");
4704 #endif
4705 
4706 module_init(amvenc_avc_driver_init_module);
4707 module_exit(amvenc_avc_driver_remove_module);
4708 RESERVEDMEM_OF_DECLARE(amvenc_avc, "amlogic, amvenc-memory", avc_mem_setup);
4709 
4710 MODULE_DESCRIPTION("AMLOGIC AVC Video Encoder Driver");
4711 MODULE_LICENSE("GPL");
4712 MODULE_AUTHOR("simon.zheng <simon.zheng@amlogic.com>");
4713