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, ¶m);
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