blob: f041bf7e92fa06ec44df8d60bd742499d5421cb9
1 | /* |
2 | * drivers/amlogic/amports/vavs.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 | #include <linux/kernel.h> |
18 | #include <linux/types.h> |
19 | #include <linux/errno.h> |
20 | #include <linux/interrupt.h> |
21 | #include <linux/semaphore.h> |
22 | #include <linux/timer.h> |
23 | #include <linux/kfifo.h> |
24 | #include <linux/delay.h> |
25 | #include <linux/platform_device.h> |
26 | #include <linux/amlogic/media/utils/amstream.h> |
27 | #include <linux/amlogic/media/frame_sync/ptsserv.h> |
28 | #include <linux/amlogic/media/canvas/canvas.h> |
29 | #include <linux/amlogic/media/vfm/vframe_provider.h> |
30 | #include <linux/amlogic/media/vfm/vframe_receiver.h> |
31 | #include <linux/amlogic/media/vfm/vframe.h> |
32 | #include <linux/amlogic/media/utils/vdec_reg.h> |
33 | #include "../../../stream_input/parser/streambuf_reg.h" |
34 | #include "../utils/amvdec.h" |
35 | #include <linux/amlogic/media/registers/register.h> |
36 | #include "../../../stream_input/amports/amports_priv.h" |
37 | #include <linux/dma-mapping.h> |
38 | #include <linux/amlogic/media/codec_mm/codec_mm.h> |
39 | #include <linux/slab.h> |
40 | #include "avs_multi.h" |
41 | #include <linux/amlogic/media/codec_mm/configs.h> |
42 | #include "../utils/decoder_mmu_box.h" |
43 | #include "../utils/decoder_bmmu_box.h" |
44 | #include "../utils/firmware.h" |
45 | #include "../../../common/chips/decoder_cpu_ver_info.h" |
46 | #include <linux/amlogic/tee.h> |
47 | |
48 | #define DEBUG_MULTI_FLAG 0 |
49 | /* |
50 | #define DEBUG_WITH_SINGLE_MODE |
51 | #define DEBUG_MULTI_WITH_AUTOMODE |
52 | #define DEBUG_MULTI_FRAME_INS |
53 | */ |
54 | |
55 | |
56 | #define USE_DYNAMIC_BUF_NUM |
57 | |
58 | #ifdef DEBUG_WITH_SINGLE_MODE |
59 | #define DRIVER_NAME "amvdec_avs" |
60 | #define MODULE_NAME "amvdec_avs" |
61 | #else |
62 | #define DRIVER_NAME "ammvdec_avs" |
63 | #define MODULE_NAME "ammvdec_avs" |
64 | #endif |
65 | |
66 | #define MULTI_DRIVER_NAME "ammvdec_avs" |
67 | |
68 | #define ENABLE_USER_DATA |
69 | |
70 | #if 1/* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ |
71 | #define NV21 |
72 | #endif |
73 | |
74 | #define USE_AVS_SEQ_INFO |
75 | #define HANDLE_AVS_IRQ |
76 | #define DEBUG_PTS |
77 | |
78 | #define CHECK_INTERVAL (HZ/100) |
79 | |
80 | #define I_PICTURE 0 |
81 | #define P_PICTURE 1 |
82 | #define B_PICTURE 2 |
83 | |
84 | #define LMEM_BUF_SIZE (0x500 * 2) |
85 | |
86 | /* #define ORI_BUFFER_START_ADDR 0x81000000 */ |
87 | #define ORI_BUFFER_START_ADDR 0x80000000 |
88 | |
89 | #define INTERLACE_FLAG 0x80 |
90 | #define TOP_FIELD_FIRST_FLAG 0x40 |
91 | |
92 | /* protocol registers */ |
93 | #define AVS_PIC_RATIO AV_SCRATCH_0 |
94 | #define AVS_PIC_WIDTH AV_SCRATCH_1 |
95 | #define AVS_PIC_HEIGHT AV_SCRATCH_2 |
96 | #define AVS_FRAME_RATE AV_SCRATCH_3 |
97 | |
98 | /*#define AVS_ERROR_COUNT AV_SCRATCH_6*/ |
99 | #define AVS_SOS_COUNT AV_SCRATCH_7 |
100 | #define AVS_BUFFERIN AV_SCRATCH_8 |
101 | #define AVS_BUFFEROUT AV_SCRATCH_9 |
102 | #define AVS_REPEAT_COUNT AV_SCRATCH_A |
103 | #define AVS_TIME_STAMP AV_SCRATCH_B |
104 | #define AVS_OFFSET_REG AV_SCRATCH_C |
105 | #define MEM_OFFSET_REG AV_SCRATCH_F |
106 | #define AVS_ERROR_RECOVERY_MODE AV_SCRATCH_G |
107 | #define DECODE_PIC_COUNT AV_SCRATCH_G |
108 | |
109 | #define DECODE_MODE AV_SCRATCH_6 |
110 | #define DECODE_MODE_SINGLE 0x0 |
111 | #define DECODE_MODE_MULTI_FRAMEBASE 0x1 |
112 | #define DECODE_MODE_MULTI_STREAMBASE 0x2 |
113 | #define DECODE_MODE_MULTI_STREAMBASE_CONT 0x3 |
114 | |
115 | #define DECODE_STATUS AV_SCRATCH_H |
116 | #define DECODE_STATUS_PIC_DONE 0x1 |
117 | #define DECODE_STATUS_DECODE_BUF_EMPTY 0x2 |
118 | #define DECODE_STATUS_SEARCH_BUF_EMPTY 0x3 |
119 | #define DECODE_STATUS_SKIP_PIC_DONE 0x4 |
120 | #define DECODE_SEARCH_HEAD 0xff |
121 | |
122 | #define DECODE_STOP_POS AV_SCRATCH_J |
123 | |
124 | #define DECODE_LMEM_BUF_ADR AV_SCRATCH_I |
125 | |
126 | #define DECODE_CFG AV_SCRATCH_K |
127 | |
128 | #define VF_POOL_SIZE 64 |
129 | #define PUT_INTERVAL (HZ/100) |
130 | |
131 | #if 1 /*MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8*/ |
132 | #define INT_AMVENCODER INT_DOS_MAILBOX_1 |
133 | #else |
134 | /* #define AMVENC_DEV_VERSION "AML-MT" */ |
135 | #define INT_AMVENCODER INT_MAILBOX_1A |
136 | #endif |
137 | |
138 | #ifdef USE_DYNAMIC_BUF_NUM |
139 | static unsigned int buf_spec_reg[] = { |
140 | AV_SCRATCH_0, |
141 | AV_SCRATCH_1, |
142 | AV_SCRATCH_2, |
143 | AV_SCRATCH_3, |
144 | AV_SCRATCH_7, /*AVS_SOS_COUNT*/ |
145 | AV_SCRATCH_D, /*DEBUG_REG2*/ |
146 | AV_SCRATCH_E, /*DEBUG_REG1*/ |
147 | AV_SCRATCH_N /*user_data_flags*/ |
148 | }; |
149 | #endif |
150 | |
151 | static void check_timer_func(unsigned long arg); |
152 | static void vavs_work(struct work_struct *work); |
153 | |
154 | #define DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE 0x0001 |
155 | static u32 dec_control = DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE; |
156 | |
157 | |
158 | #define VPP_VD1_POSTBLEND (1 << 10) |
159 | |
160 | static int debug; |
161 | static unsigned int debug_mask = 0xff; |
162 | |
163 | /*for debug*/ |
164 | /* |
165 | udebug_flag: |
166 | bit 0, enable ucode print |
167 | bit 1, enable ucode more print |
168 | bit 3, enable ucdode detail print |
169 | bit [31:16] not 0, pos to dump lmem |
170 | bit 2, pop bits to lmem |
171 | bit [11:8], pre-pop bits for alignment (when bit 2 is 1) |
172 | |
173 | avs only: |
174 | bit [8], disable empty muitl-instance handling |
175 | bit [9], enable writting of VC1_CONTROL_REG in ucode |
176 | */ |
177 | static u32 udebug_flag; |
178 | /* |
179 | when udebug_flag[1:0] is not 0 |
180 | udebug_pause_pos not 0, |
181 | pause position |
182 | */ |
183 | static u32 udebug_pause_pos; |
184 | /* |
185 | when udebug_flag[1:0] is not 0 |
186 | and udebug_pause_pos is not 0, |
187 | pause only when DEBUG_REG2 is equal to this val |
188 | */ |
189 | static u32 udebug_pause_val; |
190 | |
191 | static u32 udebug_pause_decode_idx; |
192 | |
193 | static u32 udebug_pause_ins_id; |
194 | |
195 | static u32 force_fps; |
196 | |
197 | #ifdef DEBUG_MULTI_FRAME_INS |
198 | static u32 delay; |
199 | #endif |
200 | |
201 | static u32 step; |
202 | |
203 | static u32 start_decoding_delay; |
204 | |
205 | #define AVS_DEV_NUM 9 |
206 | static unsigned int max_decode_instance_num = AVS_DEV_NUM; |
207 | static unsigned int max_process_time[AVS_DEV_NUM]; |
208 | static unsigned int max_get_frame_interval[AVS_DEV_NUM]; |
209 | static unsigned int run_count[AVS_DEV_NUM]; |
210 | static unsigned int ins_udebug_flag[AVS_DEV_NUM]; |
211 | #ifdef DEBUG_MULTI_FRAME_INS |
212 | static unsigned int max_run_count[AVS_DEV_NUM]; |
213 | #endif |
214 | /* |
215 | error_handle_policy: |
216 | */ |
217 | static unsigned int error_handle_policy = 3; |
218 | |
219 | static u32 again_threshold = 0; /*0x40;*/ |
220 | |
221 | static unsigned int decode_timeout_val = 200; |
222 | static unsigned int start_decode_buf_level = 0x8000; |
223 | |
224 | /******************************** |
225 | firmware_sel |
226 | 0: use avsp_trans long cabac ucode; |
227 | 1: not use avsp_trans long cabac ucode |
228 | in ucode: |
229 | #define USE_EXT_BUFFER_ASSIGNMENT |
230 | #undef USE_DYNAMIC_BUF_NUM |
231 | ********************************/ |
232 | static int firmware_sel; |
233 | static int disable_longcabac_trans = 1; |
234 | |
235 | |
236 | static struct vframe_s *vavs_vf_peek(void *); |
237 | static struct vframe_s *vavs_vf_get(void *); |
238 | static void vavs_vf_put(struct vframe_s *, void *); |
239 | static int vavs_vf_states(struct vframe_states *states, void *); |
240 | static int vavs_event_cb(int type, void *data, void *private_data); |
241 | |
242 | static const char vavs_dec_id[] = "vavs-dev"; |
243 | |
244 | #define PROVIDER_NAME "decoder.avs" |
245 | static DEFINE_SPINLOCK(lock); |
246 | static DEFINE_MUTEX(vavs_mutex); |
247 | |
248 | static const struct vframe_operations_s vavs_vf_provider = { |
249 | .peek = vavs_vf_peek, |
250 | .get = vavs_vf_get, |
251 | .put = vavs_vf_put, |
252 | .event_cb = vavs_event_cb, |
253 | .vf_states = vavs_vf_states, |
254 | }; |
255 | /* |
256 | static void *mm_blk_handle; |
257 | */ |
258 | static struct vframe_provider_s vavs_vf_prov; |
259 | |
260 | #define VF_BUF_NUM_MAX 16 |
261 | #ifdef DEBUG_MULTI_FRAME_INS |
262 | #define WORKSPACE_SIZE (16 * SZ_1M) |
263 | #else |
264 | #define WORKSPACE_SIZE (4 * SZ_1M) |
265 | #endif |
266 | #ifdef AVSP_LONG_CABAC |
267 | #define MAX_BMMU_BUFFER_NUM (VF_BUF_NUM_MAX + 2) |
268 | #define WORKSPACE_SIZE_A (MAX_CODED_FRAME_SIZE + LOCAL_HEAP_SIZE) |
269 | #else |
270 | #define MAX_BMMU_BUFFER_NUM (VF_BUF_NUM_MAX + 1) |
271 | #endif |
272 | |
273 | #define RV_AI_BUFF_START_ADDR 0x01a00000 |
274 | #define LONG_CABAC_RV_AI_BUFF_START_ADDR 0x00000000 |
275 | |
276 | /* 4 buffers not enough for multi inc*/ |
277 | static u32 vf_buf_num = 8; |
278 | /*static u32 vf_buf_num_used;*/ |
279 | static u32 canvas_base = 128; |
280 | #ifdef NV21 |
281 | int canvas_num = 2; /*NV21*/ |
282 | #else |
283 | int canvas_num = 3; |
284 | #endif |
285 | |
286 | #if 0 |
287 | static struct vframe_s vfpool[VF_POOL_SIZE]; |
288 | /*static struct vframe_s vfpool2[VF_POOL_SIZE];*/ |
289 | static struct vframe_s *cur_vfpool; |
290 | static unsigned char recover_flag; |
291 | static s32 vfbuf_use[VF_BUF_NUM_MAX]; |
292 | static u32 saved_resolution; |
293 | static u32 frame_width, frame_height, frame_dur, frame_prog; |
294 | static struct timer_list recycle_timer; |
295 | static u32 stat; |
296 | #endif |
297 | static u32 buf_size = 32 * 1024 * 1024; |
298 | #if 0 |
299 | static u32 buf_offset; |
300 | static u32 avi_flag; |
301 | static u32 vavs_ratio; |
302 | static u32 pic_type; |
303 | #endif |
304 | static u32 pts_by_offset = 1; |
305 | #if 0 |
306 | static u32 total_frame; |
307 | static u32 next_pts; |
308 | static unsigned char throw_pb_flag; |
309 | #ifdef DEBUG_PTS |
310 | static u32 pts_hit, pts_missed, pts_i_hit, pts_i_missed; |
311 | #endif |
312 | #endif |
313 | static u32 radr, rval; |
314 | static u32 dbg_cmd; |
315 | #if 0 |
316 | static struct dec_sysinfo vavs_amstream_dec_info; |
317 | static struct vdec_info *gvs; |
318 | static u32 fr_hint_status; |
319 | static struct work_struct notify_work; |
320 | static struct work_struct set_clk_work; |
321 | static bool is_reset; |
322 | #endif |
323 | /*static struct vdec_s *vdec;*/ |
324 | |
325 | #ifdef AVSP_LONG_CABAC |
326 | static struct work_struct long_cabac_wd_work; |
327 | void *es_write_addr_virt; |
328 | dma_addr_t es_write_addr_phy; |
329 | |
330 | void *bitstream_read_tmp; |
331 | dma_addr_t bitstream_read_tmp_phy; |
332 | void *avsp_heap_adr; |
333 | static uint long_cabac_busy; |
334 | #endif |
335 | |
336 | #if 0 |
337 | #ifdef ENABLE_USER_DATA |
338 | static void *user_data_buffer; |
339 | static dma_addr_t user_data_buffer_phys; |
340 | #endif |
341 | static DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE); |
342 | static DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); |
343 | static DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE); |
344 | #endif |
345 | static inline u32 index2canvas(u32 index) |
346 | { |
347 | const u32 canvas_tab[VF_BUF_NUM_MAX] = { |
348 | 0x010100, 0x030302, 0x050504, 0x070706, |
349 | 0x090908, 0x0b0b0a, 0x0d0d0c, 0x0f0f0e, |
350 | 0x111110, 0x131312, 0x151514, 0x171716, |
351 | 0x191918, 0x1b1b1a, 0x1d1d1c, 0x1f1f1e, |
352 | }; |
353 | const u32 canvas_tab_3[4] = { |
354 | 0x010100, 0x040403, 0x070706, 0x0a0a09 |
355 | }; |
356 | |
357 | if (canvas_num == 2) |
358 | return canvas_tab[index] + (canvas_base << 16) |
359 | + (canvas_base << 8) + canvas_base; |
360 | |
361 | return canvas_tab_3[index] + (canvas_base << 16) |
362 | + (canvas_base << 8) + canvas_base; |
363 | } |
364 | |
365 | static const u32 frame_rate_tab[16] = { |
366 | 96000 / 30, /* forbidden */ |
367 | 96000000 / 23976, /* 24000/1001 (23.967) */ |
368 | 96000 / 24, |
369 | 96000 / 25, |
370 | 9600000 / 2997, /* 30000/1001 (29.97) */ |
371 | 96000 / 30, |
372 | 96000 / 50, |
373 | 9600000 / 5994, /* 60000/1001 (59.94) */ |
374 | 96000 / 60, |
375 | /* > 8 reserved, use 24 */ |
376 | 96000 / 24, 96000 / 24, 96000 / 24, 96000 / 24, |
377 | 96000 / 24, 96000 / 24, 96000 / 24 |
378 | }; |
379 | |
380 | #define DECODE_BUFFER_NUM_MAX VF_BUF_NUM_MAX |
381 | #define PIC_PTS_NUM 64 |
382 | struct buf_pool_s { |
383 | unsigned detached; |
384 | struct vframe_s vf; |
385 | }; |
386 | |
387 | #define buf_of_vf(vf) container_of(vf, struct buf_pool_s, vf) |
388 | |
389 | struct pic_pts_s { |
390 | u32 pts; |
391 | u64 pts64; |
392 | u64 timestamp; |
393 | unsigned short decode_pic_count; |
394 | }; |
395 | |
396 | struct vdec_avs_hw_s { |
397 | spinlock_t lock; |
398 | unsigned char m_ins_flag; |
399 | struct platform_device *platform_dev; |
400 | DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE); |
401 | DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); |
402 | DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE); |
403 | struct buf_pool_s vfpool[VF_POOL_SIZE]; |
404 | s32 vfbuf_use[VF_BUF_NUM_MAX]; |
405 | unsigned char again_flag; |
406 | unsigned char recover_flag; |
407 | u32 frame_width; |
408 | u32 frame_height; |
409 | u32 frame_dur; |
410 | u32 frame_prog; |
411 | u32 saved_resolution; |
412 | u32 avi_flag; |
413 | u32 vavs_ratio; |
414 | u32 pic_type; |
415 | |
416 | u32 vf_buf_num_used; |
417 | u32 total_frame; |
418 | u32 next_pts; |
419 | unsigned char throw_pb_flag; |
420 | struct pic_pts_s pic_pts[PIC_PTS_NUM]; |
421 | int pic_pts_wr_pos; |
422 | |
423 | #ifdef DEBUG_PTS |
424 | u32 pts_hit; |
425 | u32 pts_missed; |
426 | u32 pts_i_hit; |
427 | u32 pts_i_missed; |
428 | #endif |
429 | #ifdef ENABLE_USER_DATA |
430 | struct work_struct userdata_push_work; |
431 | void *user_data_buffer; |
432 | dma_addr_t user_data_buffer_phys; |
433 | #endif |
434 | void *lmem_addr; |
435 | dma_addr_t lmem_phy_addr; |
436 | |
437 | u32 buf_offset; |
438 | |
439 | struct dec_sysinfo vavs_amstream_dec_info; |
440 | struct vdec_info *gvs; |
441 | u32 fr_hint_status; |
442 | struct work_struct set_clk_work; |
443 | bool is_reset; |
444 | |
445 | /*debug*/ |
446 | u32 ucode_pause_pos; |
447 | /**/ |
448 | u32 decode_pic_count; |
449 | u8 reset_decode_flag; |
450 | u32 display_frame_count; |
451 | u32 buf_status; |
452 | u32 pre_parser_wr_ptr; |
453 | /* |
454 | buffer_status &= ~buf_recycle_status |
455 | */ |
456 | u32 buf_recycle_status; |
457 | u32 seqinfo; |
458 | u32 ctx_valid; |
459 | u32 dec_control; |
460 | void *mm_blk_handle; |
461 | struct vframe_chunk_s *chunk; |
462 | u32 stat; |
463 | u8 init_flag; |
464 | unsigned long buf_start; |
465 | u32 buf_size; |
466 | |
467 | u32 reg_scratch_0; |
468 | u32 reg_scratch_1; |
469 | u32 reg_scratch_2; |
470 | u32 reg_scratch_3; |
471 | u32 reg_scratch_4; |
472 | u32 reg_scratch_5; |
473 | u32 reg_scratch_6; |
474 | u32 reg_scratch_7; |
475 | u32 reg_scratch_8; |
476 | u32 reg_scratch_9; |
477 | u32 reg_scratch_A; |
478 | u32 reg_scratch_B; |
479 | u32 reg_scratch_C; |
480 | u32 reg_scratch_D; |
481 | u32 reg_scratch_E; |
482 | u32 reg_scratch_F; |
483 | u32 reg_scratch_G; |
484 | u32 reg_scratch_H; |
485 | u32 reg_scratch_I; |
486 | u32 reg_mb_width; |
487 | u32 reg_viff_bit_cnt; |
488 | u32 reg_canvas_addr; |
489 | u32 reg_dbkr_canvas_addr; |
490 | u32 reg_dbkw_canvas_addr; |
491 | u32 reg_anc2_canvas_addr; |
492 | u32 reg_anc0_canvas_addr; |
493 | u32 reg_anc1_canvas_addr; |
494 | u32 reg_anc3_canvas_addr; |
495 | u32 reg_anc4_canvas_addr; |
496 | u32 reg_anc5_canvas_addr; |
497 | u32 slice_ver_pos_pic_type; |
498 | u32 vc1_control_reg; |
499 | u32 avs_co_mb_wr_addr; |
500 | u32 slice_start_byte_01; |
501 | u32 slice_start_byte_23; |
502 | u32 vcop_ctrl_reg; |
503 | u32 iqidct_control; |
504 | u32 rv_ai_mb_count; |
505 | u32 slice_qp; |
506 | u32 dc_scaler; |
507 | u32 avsp_iq_wq_param_01; |
508 | u32 avsp_iq_wq_param_23; |
509 | u32 avsp_iq_wq_param_45; |
510 | u32 avs_co_mb_rd_addr; |
511 | u32 dblk_mb_wid_height; |
512 | u32 mc_pic_w_h; |
513 | u32 avs_co_mb_rw_ctl; |
514 | u32 vld_decode_control; |
515 | |
516 | struct timer_list check_timer; |
517 | u32 decode_timeout_count; |
518 | unsigned long int start_process_time; |
519 | u32 last_vld_level; |
520 | u32 eos; |
521 | u32 canvas_spec[DECODE_BUFFER_NUM_MAX]; |
522 | struct canvas_config_s canvas_config[DECODE_BUFFER_NUM_MAX][2]; |
523 | |
524 | s32 refs[2]; |
525 | int dec_result; |
526 | struct timer_list recycle_timer; |
527 | struct work_struct work; |
528 | struct work_struct notify_work; |
529 | atomic_t error_handler_run; |
530 | struct work_struct fatal_error_wd_work; |
531 | void (*vdec_cb)(struct vdec_s *, void *); |
532 | void *vdec_cb_arg; |
533 | /* for error handling */ |
534 | u32 run_count; |
535 | u32 not_run_ready; |
536 | u32 input_empty; |
537 | u32 prepare_num; |
538 | u32 put_num; |
539 | u32 peek_num; |
540 | u32 get_num; |
541 | u32 drop_frame_count; |
542 | u32 buffer_not_ready; |
543 | int frameinfo_enable; |
544 | struct firmware_s *fw; |
545 | u32 old_udebug_flag; |
546 | u32 decode_status_skip_pic_done_flag; |
547 | u32 decode_decode_cont_start_code; |
548 | }; |
549 | |
550 | static void reset_process_time(struct vdec_avs_hw_s *hw); |
551 | static void start_process_time(struct vdec_avs_hw_s *hw); |
552 | static void vavs_save_regs(struct vdec_avs_hw_s *hw); |
553 | |
554 | struct vdec_avs_hw_s *ghw; |
555 | |
556 | #define MULTI_INSTANCE_PROVIDER_NAME "vdec.avs" |
557 | |
558 | #define DEC_RESULT_NONE 0 |
559 | #define DEC_RESULT_DONE 1 |
560 | #define DEC_RESULT_AGAIN 2 |
561 | #define DEC_RESULT_ERROR 3 |
562 | #define DEC_RESULT_FORCE_EXIT 4 |
563 | #define DEC_RESULT_EOS 5 |
564 | #define DEC_RESULT_GET_DATA 6 |
565 | #define DEC_RESULT_GET_DATA_RETRY 7 |
566 | #define DEC_RESULT_USERDATA 8 |
567 | |
568 | #define DECODE_ID(hw) (hw->m_ins_flag? hw_to_vdec(hw)->id : 0) |
569 | |
570 | #define PRINT_FLAG_ERROR 0x0 |
571 | #define PRINT_FLAG_RUN_FLOW 0X0001 |
572 | #define PRINT_FLAG_DECODING 0x0002 |
573 | #define PRINT_FLAG_PTS 0x0004 |
574 | #define PRINT_FLAG_VFRAME_DETAIL 0x0010 |
575 | #define PRINT_FLAG_VLD_DETAIL 0x0020 |
576 | #define PRINT_FLAG_DEC_DETAIL 0x0040 |
577 | #define PRINT_FLAG_BUFFER_DETAIL 0x0080 |
578 | #define PRINT_FLAG_FORCE_DONE 0x0100 |
579 | #define PRINT_FLAG_COUNTER 0X0200 |
580 | #define PRINT_FRAMEBASE_DATA 0x0400 |
581 | #define PRINT_FLAG_PARA_DATA 0x1000 |
582 | #define DEBUG_FLAG_PREPARE_MORE_INPUT 0x2000 |
583 | #define DEBUG_FLAG_PRINT_REG 0x4000 |
584 | #define DEBUG_FLAG_DISABLE_TIMEOUT 0x10000 |
585 | #define DEBUG_WAIT_DECODE_DONE_WHEN_STOP 0x20000 |
586 | #define DEBUG_PIC_DONE_WHEN_UCODE_PAUSE 0x40000 |
587 | |
588 | |
589 | #undef DEBUG_REG |
590 | #ifdef DEBUG_REG |
591 | static void WRITE_VREG_DBG2(unsigned adr, unsigned val) |
592 | { |
593 | if (debug & DEBUG_FLAG_PRINT_REG) |
594 | pr_info("%s(%x, %x)\n", __func__, adr, val); |
595 | if (adr != 0) |
596 | WRITE_VREG(adr, val); |
597 | } |
598 | |
599 | #undef WRITE_VREG |
600 | #define WRITE_VREG WRITE_VREG_DBG2 |
601 | #endif |
602 | |
603 | #undef pr_info |
604 | #define pr_info printk |
605 | static int debug_print(struct vdec_avs_hw_s *hw, |
606 | int flag, const char *fmt, ...) |
607 | { |
608 | #define AVS_PRINT_BUF 256 |
609 | unsigned char buf[AVS_PRINT_BUF]; |
610 | int len = 0; |
611 | int index = 0; |
612 | if (hw) |
613 | index = hw->m_ins_flag ? DECODE_ID(hw) : 0; |
614 | if (hw == NULL || |
615 | (flag == 0) || |
616 | ((debug_mask & |
617 | (1 << index)) |
618 | && (debug & flag))) { |
619 | va_list args; |
620 | |
621 | va_start(args, fmt); |
622 | if (hw) |
623 | len = sprintf(buf, "[%d]", index); |
624 | vsnprintf(buf + len, AVS_PRINT_BUF - len, fmt, args); |
625 | pr_info("%s", buf); |
626 | va_end(args); |
627 | } |
628 | return 0; |
629 | } |
630 | |
631 | static int debug_print_cont(struct vdec_avs_hw_s *hw, |
632 | int flag, const char *fmt, ...) |
633 | { |
634 | unsigned char buf[AVS_PRINT_BUF]; |
635 | int len = 0; |
636 | int index = 0; |
637 | if (hw) |
638 | index = hw->m_ins_flag ? DECODE_ID(hw) : 0; |
639 | if (hw == NULL || |
640 | (flag == 0) || |
641 | ((debug_mask & |
642 | (1 << index)) |
643 | && (debug & flag))) { |
644 | va_list args; |
645 | |
646 | va_start(args, fmt); |
647 | vsnprintf(buf + len, AVS_PRINT_BUF - len, fmt, args); |
648 | pr_info("%s", buf); |
649 | va_end(args); |
650 | } |
651 | return 0; |
652 | } |
653 | |
654 | static void avs_pts_check_in(struct vdec_avs_hw_s *hw, |
655 | unsigned short decode_pic_count, struct vframe_chunk_s *chunk) |
656 | { |
657 | if (chunk) |
658 | debug_print(hw, PRINT_FLAG_PTS, |
659 | "%s %d (wr pos %d), pts %d pts64 %ld timestamp %ld\n", |
660 | __func__, decode_pic_count, hw->pic_pts_wr_pos, |
661 | chunk->pts, (u64)(chunk->pts64), (u64)(chunk->timestamp)); |
662 | else |
663 | debug_print(hw, PRINT_FLAG_PTS, |
664 | "%s %d, chunk is null\n", |
665 | __func__, decode_pic_count); |
666 | |
667 | if (chunk) { |
668 | hw->pic_pts[hw->pic_pts_wr_pos].pts = chunk->pts; |
669 | hw->pic_pts[hw->pic_pts_wr_pos].pts64 = chunk->pts64; |
670 | hw->pic_pts[hw->pic_pts_wr_pos].timestamp = chunk->timestamp; |
671 | } else { |
672 | hw->pic_pts[hw->pic_pts_wr_pos].pts = 0; |
673 | hw->pic_pts[hw->pic_pts_wr_pos].pts64 = 0; |
674 | hw->pic_pts[hw->pic_pts_wr_pos].timestamp = 0; |
675 | } |
676 | hw->pic_pts[hw->pic_pts_wr_pos].decode_pic_count |
677 | = decode_pic_count; |
678 | hw->pic_pts_wr_pos++; |
679 | if (hw->pic_pts_wr_pos >= PIC_PTS_NUM) |
680 | hw->pic_pts_wr_pos = 0; |
681 | return; |
682 | } |
683 | |
684 | static void clear_pts_buf(struct vdec_avs_hw_s *hw) |
685 | { |
686 | int i; |
687 | debug_print(hw, PRINT_FLAG_PTS, |
688 | "%s\n", __func__); |
689 | hw->pic_pts_wr_pos = 0; |
690 | for (i = 0; i < PIC_PTS_NUM; i++) { |
691 | hw->pic_pts[hw->pic_pts_wr_pos].pts = 0; |
692 | hw->pic_pts[hw->pic_pts_wr_pos].pts64 = 0; |
693 | hw->pic_pts[hw->pic_pts_wr_pos].timestamp = 0; |
694 | hw->pic_pts[hw->pic_pts_wr_pos].decode_pic_count = 0; |
695 | } |
696 | } |
697 | |
698 | static int set_vframe_pts(struct vdec_avs_hw_s *hw, |
699 | unsigned short decode_pic_count, struct vframe_s *vf) |
700 | { |
701 | int i; |
702 | int ret = -1; |
703 | for (i = 0; i < PIC_PTS_NUM; i++) { |
704 | if (hw->pic_pts[i].decode_pic_count == decode_pic_count) { |
705 | vf->pts = hw->pic_pts[i].pts; |
706 | vf->pts_us64 = hw->pic_pts[i].pts64; |
707 | vf->timestamp = hw->pic_pts[i].timestamp; |
708 | ret = 0; |
709 | debug_print(hw, PRINT_FLAG_PTS, |
710 | "%s %d (rd pos %d), pts %d pts64 %ld timestamp %ld\n", |
711 | __func__, decode_pic_count, i, |
712 | vf->pts, vf->pts_us64, vf->timestamp); |
713 | |
714 | break; |
715 | } |
716 | } |
717 | return ret; |
718 | } |
719 | |
720 | static void avs_vf_notify_receiver(struct vdec_avs_hw_s *hw, |
721 | const char *provider_name, int event_type, void *data) |
722 | { |
723 | if (hw->m_ins_flag) |
724 | vf_notify_receiver(hw_to_vdec(hw)->vf_provider_name, |
725 | event_type, data); |
726 | else |
727 | vf_notify_receiver(provider_name, event_type, data); |
728 | } |
729 | |
730 | static void set_frame_info(struct vdec_avs_hw_s *hw, struct vframe_s *vf, |
731 | unsigned int *duration) |
732 | { |
733 | int ar = 0; |
734 | |
735 | unsigned int pixel_ratio = READ_VREG(AVS_PIC_RATIO); |
736 | hw->prepare_num++; |
737 | #ifndef USE_AVS_SEQ_INFO |
738 | if (hw->vavs_amstream_dec_info.width > 0 |
739 | && hw->vavs_amstream_dec_info.height > 0) { |
740 | vf->width = hw->vavs_amstream_dec_info.width; |
741 | vf->height = hw->vavs_amstream_dec_info.height; |
742 | } else |
743 | #endif |
744 | { |
745 | vf->width = READ_VREG(AVS_PIC_WIDTH); |
746 | vf->height = READ_VREG(AVS_PIC_HEIGHT); |
747 | hw->frame_width = vf->width; |
748 | hw->frame_height = vf->height; |
749 | /* pr_info("%s: (%d,%d)\n", __func__,vf->width, vf->height);*/ |
750 | } |
751 | |
752 | #ifndef USE_AVS_SEQ_INFO |
753 | if (hw->vavs_amstream_dec_info.rate > 0) |
754 | *duration = hw->vavs_amstream_dec_info.rate; |
755 | else |
756 | #endif |
757 | { |
758 | *duration = frame_rate_tab[READ_VREG(AVS_FRAME_RATE) & 0xf]; |
759 | /* pr_info("%s: duration = %d\n", __func__, *duration); */ |
760 | hw->frame_dur = *duration; |
761 | schedule_work(&hw->notify_work); |
762 | } |
763 | |
764 | if (hw->vavs_ratio == 0) { |
765 | /* always stretch to 16:9 */ |
766 | vf->ratio_control |= (0x90 << |
767 | DISP_RATIO_ASPECT_RATIO_BIT); |
768 | } else { |
769 | switch (pixel_ratio) { |
770 | case 1: |
771 | ar = (vf->height * hw->vavs_ratio) / vf->width; |
772 | break; |
773 | case 2: |
774 | ar = (vf->height * 3 * hw->vavs_ratio) / (vf->width * 4); |
775 | break; |
776 | case 3: |
777 | ar = (vf->height * 9 * hw->vavs_ratio) / (vf->width * 16); |
778 | break; |
779 | case 4: |
780 | ar = (vf->height * 100 * hw->vavs_ratio) / (vf->width * |
781 | 221); |
782 | break; |
783 | default: |
784 | ar = (vf->height * hw->vavs_ratio) / vf->width; |
785 | break; |
786 | } |
787 | } |
788 | |
789 | ar = min(ar, DISP_RATIO_ASPECT_RATIO_MAX); |
790 | |
791 | vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT); |
792 | /*vf->ratio_control |= DISP_RATIO_FORCECONFIG | DISP_RATIO_KEEPRATIO; */ |
793 | |
794 | vf->flag = 0; |
795 | buf_of_vf(vf)->detached = 0; |
796 | |
797 | } |
798 | |
799 | #ifdef ENABLE_USER_DATA |
800 | |
801 | /*static struct work_struct userdata_push_work;*/ |
802 | /* |
803 | #define DUMP_LAST_REPORTED_USER_DATA |
804 | */ |
805 | static void userdata_push_process(struct vdec_avs_hw_s *hw) |
806 | { |
807 | unsigned int user_data_flags; |
808 | unsigned int user_data_wp; |
809 | unsigned int user_data_length; |
810 | struct userdata_poc_info_t user_data_poc; |
811 | #ifdef DUMP_LAST_REPORTED_USER_DATA |
812 | int user_data_len; |
813 | int wp_start; |
814 | unsigned char *pdata; |
815 | int nLeft; |
816 | #endif |
817 | |
818 | user_data_flags = READ_VREG(AV_SCRATCH_N); |
819 | user_data_wp = (user_data_flags >> 16) & 0xffff; |
820 | user_data_length = user_data_flags & 0x7fff; |
821 | |
822 | #ifdef DUMP_LAST_REPORTED_USER_DATA |
823 | dma_sync_single_for_cpu(amports_get_dma_device(), |
824 | hw->user_data_buffer_phys, USER_DATA_SIZE, |
825 | DMA_FROM_DEVICE); |
826 | |
827 | if (user_data_length & 0x07) |
828 | user_data_len = (user_data_length + 8) & 0xFFFFFFF8; |
829 | else |
830 | user_data_len = user_data_length; |
831 | |
832 | if (user_data_wp >= user_data_len) { |
833 | wp_start = user_data_wp - user_data_len; |
834 | |
835 | pdata = (unsigned char *)hw->user_data_buffer; |
836 | pdata += wp_start; |
837 | nLeft = user_data_len; |
838 | while (nLeft >= 8) { |
839 | pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n", |
840 | pdata[0], pdata[1], pdata[2], pdata[3], |
841 | pdata[4], pdata[5], pdata[6], pdata[7]); |
842 | nLeft -= 8; |
843 | pdata += 8; |
844 | } |
845 | } else { |
846 | wp_start = user_data_wp + |
847 | USER_DATA_SIZE - user_data_len; |
848 | |
849 | pdata = (unsigned char *)hw->user_data_buffer; |
850 | pdata += wp_start; |
851 | nLeft = USER_DATA_SIZE - wp_start; |
852 | |
853 | while (nLeft >= 8) { |
854 | pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n", |
855 | pdata[0], pdata[1], pdata[2], pdata[3], |
856 | pdata[4], pdata[5], pdata[6], pdata[7]); |
857 | nLeft -= 8; |
858 | pdata += 8; |
859 | } |
860 | |
861 | pdata = (unsigned char *)hw->user_data_buffer; |
862 | nLeft = user_data_wp; |
863 | while (nLeft >= 8) { |
864 | pr_info("%02x %02x %02x %02x %02x %02x %02x %02x\n", |
865 | pdata[0], pdata[1], pdata[2], pdata[3], |
866 | pdata[4], pdata[5], pdata[6], pdata[7]); |
867 | nLeft -= 8; |
868 | pdata += 8; |
869 | } |
870 | } |
871 | #endif |
872 | |
873 | /* |
874 | pr_info("pocinfo 0x%x, poc %d, wp 0x%x, len %d\n", |
875 | READ_VREG(AV_SCRATCH_L), READ_VREG(AV_SCRATCH_M), |
876 | user_data_wp, user_data_length); |
877 | */ |
878 | user_data_poc.poc_info = READ_VREG(AV_SCRATCH_L); |
879 | user_data_poc.poc_number = READ_VREG(AV_SCRATCH_M); |
880 | |
881 | WRITE_VREG(AV_SCRATCH_N, 0); |
882 | /* |
883 | wakeup_userdata_poll(user_data_poc, user_data_wp, |
884 | (unsigned long)hw->user_data_buffer, |
885 | USER_DATA_SIZE, user_data_length); |
886 | */ |
887 | } |
888 | |
889 | static void userdata_push_do_work(struct work_struct *work) |
890 | { |
891 | struct vdec_avs_hw_s *hw = |
892 | container_of(work, struct vdec_avs_hw_s, userdata_push_work); |
893 | userdata_push_process(hw); |
894 | } |
895 | |
896 | static u8 UserDataHandler(struct vdec_avs_hw_s *hw) |
897 | { |
898 | unsigned int user_data_flags; |
899 | |
900 | user_data_flags = READ_VREG(AV_SCRATCH_N); |
901 | if (user_data_flags & (1 << 15)) { /* data ready */ |
902 | if (hw->m_ins_flag) { |
903 | hw->dec_result = DEC_RESULT_USERDATA; |
904 | vdec_schedule_work(&hw->work); |
905 | return 1; |
906 | } else |
907 | schedule_work(&hw->userdata_push_work); |
908 | } |
909 | return 0; |
910 | } |
911 | #endif |
912 | |
913 | |
914 | static inline void avs_update_gvs(struct vdec_avs_hw_s *hw) |
915 | { |
916 | if (hw->gvs->frame_height != hw->frame_height) { |
917 | hw->gvs->frame_width = hw->frame_width; |
918 | hw->gvs->frame_height = hw->frame_height; |
919 | } |
920 | if (hw->gvs->frame_dur != hw->frame_dur) { |
921 | hw->gvs->frame_dur = hw->frame_dur; |
922 | if (hw->frame_dur != 0) |
923 | hw->gvs->frame_rate = 96000 / hw->frame_dur; |
924 | else |
925 | hw->gvs->frame_rate = -1; |
926 | } |
927 | |
928 | hw->gvs->status = hw->stat; |
929 | hw->gvs->error_count = READ_VREG(AV_SCRATCH_C); |
930 | hw->gvs->drop_frame_count = hw->drop_frame_count; |
931 | |
932 | } |
933 | |
934 | #ifdef HANDLE_AVS_IRQ |
935 | static irqreturn_t vavs_isr(int irq, void *dev_id) |
936 | #else |
937 | static void vavs_isr(void) |
938 | #endif |
939 | { |
940 | u32 reg; |
941 | struct vframe_s *vf = NULL; |
942 | u32 dur; |
943 | u32 repeat_count; |
944 | u32 picture_type; |
945 | u32 buffer_index; |
946 | u32 frame_size; |
947 | bool force_interlaced_frame = false; |
948 | unsigned int pts, pts_valid = 0, offset = 0; |
949 | u64 pts_us64; |
950 | u32 debug_tag; |
951 | u32 buffer_status_debug; |
952 | struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)dev_id; |
953 | |
954 | /*if (debug & AVS_DEBUG_UCODE) { |
955 | if (READ_VREG(AV_SCRATCH_E) != 0) { |
956 | pr_info("dbg%x: %x\n", READ_VREG(AV_SCRATCH_E), |
957 | READ_VREG(AV_SCRATCH_D)); |
958 | WRITE_VREG(AV_SCRATCH_E, 0); |
959 | } |
960 | }*/ |
961 | #define DEBUG_REG1 AV_SCRATCH_E |
962 | #define DEBUG_REG2 AV_SCRATCH_D |
963 | |
964 | debug_tag = READ_VREG(DEBUG_REG1); |
965 | buffer_status_debug = debug_tag >> 16; |
966 | debug_tag &= 0xffff; |
967 | /* if (debug_tag & 0x10000) { |
968 | int i; |
969 | dma_sync_single_for_cpu( |
970 | amports_get_dma_device(), |
971 | hw->lmem_phy_addr, |
972 | LMEM_BUF_SIZE, |
973 | DMA_FROM_DEVICE); |
974 | |
975 | debug_print(hw, 0, |
976 | "LMEM<tag %x>:\n", debug_tag); |
977 | |
978 | for (i = 0; i < 0x400; i += 4) { |
979 | int ii; |
980 | unsigned short *lmem_ptr = hw->lmem_addr; |
981 | if ((i & 0xf) == 0) |
982 | debug_print_cont(hw, 0, "%03x: ", i); |
983 | for (ii = 0; ii < 4; ii++) { |
984 | debug_print_cont(hw, 0, "%04x ", |
985 | lmem_ptr[i + 3 - ii]); |
986 | } |
987 | if (((i + ii) & 0xf) == 0) |
988 | debug_print_cont(hw, 0, "\n"); |
989 | } |
990 | |
991 | if (((udebug_pause_pos & 0xffff) |
992 | == (debug_tag & 0xffff)) && |
993 | (udebug_pause_decode_idx == 0 || |
994 | udebug_pause_decode_idx == hw->decode_pic_count) && |
995 | (udebug_pause_val == 0 || |
996 | udebug_pause_val == READ_VREG(DEBUG_REG2))) { |
997 | udebug_pause_pos &= 0xffff; |
998 | hw->ucode_pause_pos = udebug_pause_pos; |
999 | } |
1000 | else if (debug_tag & 0x20000) |
1001 | hw->ucode_pause_pos = 0xffffffff; |
1002 | if (hw->ucode_pause_pos) |
1003 | reset_process_time(hw); |
1004 | else |
1005 | WRITE_VREG(DEBUG_REG1, 0); |
1006 | } else*/ if (debug_tag != 0) { |
1007 | debug_print(hw, 0, |
1008 | "dbg%x: %x buffer_status 0x%x l/w/r %x %x %x bitcnt %x AVAIL %x\n", |
1009 | debug_tag, |
1010 | READ_VREG(DEBUG_REG2), |
1011 | buffer_status_debug, |
1012 | READ_VREG(VLD_MEM_VIFIFO_LEVEL), |
1013 | READ_VREG(VLD_MEM_VIFIFO_WP), |
1014 | READ_VREG(VLD_MEM_VIFIFO_RP), |
1015 | READ_VREG(VIFF_BIT_CNT), |
1016 | READ_VREG(VLD_MEM_VIFIFO_BYTES_AVAIL)); |
1017 | |
1018 | if (((udebug_pause_pos & 0xffff) |
1019 | == (debug_tag & 0xffff)) && |
1020 | (udebug_pause_decode_idx == 0 || |
1021 | udebug_pause_decode_idx == hw->decode_pic_count) && |
1022 | (udebug_pause_val == 0 || |
1023 | udebug_pause_val == READ_VREG(DEBUG_REG2)) && |
1024 | (udebug_pause_ins_id == 0 || |
1025 | DECODE_ID(hw) == (udebug_pause_ins_id -1))) { |
1026 | udebug_pause_pos &= 0xffff; |
1027 | hw->ucode_pause_pos = udebug_pause_pos; |
1028 | if (debug & DEBUG_PIC_DONE_WHEN_UCODE_PAUSE) { |
1029 | hw->decode_pic_count++; |
1030 | if ((hw->decode_pic_count & 0xffff) == 0) { |
1031 | /*make ucode do not handle it as first picture*/ |
1032 | hw->decode_pic_count++; |
1033 | } |
1034 | reset_process_time(hw); |
1035 | hw->dec_result = DEC_RESULT_DONE; |
1036 | amvdec_stop(); |
1037 | vavs_save_regs(hw); |
1038 | debug_print(hw, PRINT_FLAG_DECODING, |
1039 | "%s ucode pause, force done, decode_pic_count = %d, bit_cnt=0x%x\n", |
1040 | __func__, |
1041 | hw->decode_pic_count, |
1042 | READ_VREG(VIFF_BIT_CNT)); |
1043 | vdec_schedule_work(&hw->work); |
1044 | return IRQ_HANDLED; |
1045 | } |
1046 | } |
1047 | if (hw->ucode_pause_pos) |
1048 | reset_process_time(hw); |
1049 | else |
1050 | WRITE_VREG(DEBUG_REG1, 0); |
1051 | //return IRQ_HANDLED; |
1052 | } else { |
1053 | debug_print(hw, PRINT_FLAG_DECODING, |
1054 | "%s decode_status 0x%x, buffer_status 0x%x\n", |
1055 | __func__, |
1056 | READ_VREG(DECODE_STATUS), |
1057 | buffer_status_debug); |
1058 | } |
1059 | |
1060 | #ifdef AVSP_LONG_CABAC |
1061 | if (firmware_sel == 0 && READ_VREG(LONG_CABAC_REQ)) { |
1062 | #ifdef PERFORMANCE_DEBUG |
1063 | pr_info("%s:schedule long_cabac_wd_work\r\n", __func__); |
1064 | #endif |
1065 | pr_info("schedule long_cabac_wd_work and requested from %d\n", |
1066 | (READ_VREG(LONG_CABAC_REQ) >> 8)&0xFF); |
1067 | schedule_work(&long_cabac_wd_work); |
1068 | } |
1069 | #endif |
1070 | |
1071 | #ifdef ENABLE_USER_DATA |
1072 | if (UserDataHandler(hw)) |
1073 | return IRQ_HANDLED; |
1074 | #endif |
1075 | reg = READ_VREG(AVS_BUFFEROUT); |
1076 | if (reg) { |
1077 | unsigned short decode_pic_count |
1078 | = READ_VREG(DECODE_PIC_COUNT); |
1079 | debug_print(hw, PRINT_FLAG_DECODING, "AVS_BUFFEROUT=0x%x decode_pic_count %d\n", |
1080 | reg, decode_pic_count); |
1081 | if (pts_by_offset) { |
1082 | offset = READ_VREG(AVS_OFFSET_REG); |
1083 | debug_print(hw, PRINT_FLAG_DECODING, "AVS OFFSET=%x\n", offset); |
1084 | if (pts_lookup_offset_us64(PTS_TYPE_VIDEO, offset, &pts, |
1085 | &frame_size, |
1086 | 0, &pts_us64) == 0) { |
1087 | pts_valid = 1; |
1088 | #ifdef DEBUG_PTS |
1089 | hw->pts_hit++; |
1090 | #endif |
1091 | } else { |
1092 | #ifdef DEBUG_PTS |
1093 | hw->pts_missed++; |
1094 | #endif |
1095 | } |
1096 | } |
1097 | |
1098 | repeat_count = READ_VREG(AVS_REPEAT_COUNT); |
1099 | #ifdef USE_DYNAMIC_BUF_NUM |
1100 | buffer_index = |
1101 | ((reg & 0x7) + |
1102 | (((reg >> 8) & 0x3) << 3) - 1) & 0x1f; |
1103 | #else |
1104 | if (firmware_sel == 0) |
1105 | buffer_index = |
1106 | ((reg & 0x7) + |
1107 | (((reg >> 8) & 0x3) << 3) - 1) & 0x1f; |
1108 | else |
1109 | buffer_index = |
1110 | ((reg & 0x7) - 1) & 3; |
1111 | #endif |
1112 | picture_type = (reg >> 3) & 7; |
1113 | #ifdef DEBUG_PTS |
1114 | if (picture_type == I_PICTURE) { |
1115 | /* pr_info("I offset 0x%x, pts_valid %d\n", |
1116 | * offset, pts_valid); |
1117 | */ |
1118 | if (!pts_valid) |
1119 | hw->pts_i_missed++; |
1120 | else |
1121 | hw->pts_i_hit++; |
1122 | } |
1123 | #endif |
1124 | |
1125 | if ((dec_control & DEC_CONTROL_FLAG_FORCE_2500_1080P_INTERLACE) |
1126 | && hw->frame_width == 1920 && hw->frame_height == 1080) { |
1127 | force_interlaced_frame = true; |
1128 | } |
1129 | |
1130 | if (hw->throw_pb_flag && picture_type != I_PICTURE) { |
1131 | |
1132 | debug_print(hw, PRINT_FLAG_DECODING, |
1133 | "%s WRITE_VREG(AVS_BUFFERIN, 0x%x) for throwing picture with type of %d\n", |
1134 | __func__, |
1135 | ~(1 << buffer_index), picture_type); |
1136 | |
1137 | WRITE_VREG(AVS_BUFFERIN, ~(1 << buffer_index)); |
1138 | } else if (reg & INTERLACE_FLAG || force_interlaced_frame) { /* interlace */ |
1139 | hw->throw_pb_flag = 0; |
1140 | |
1141 | debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, |
1142 | "interlace, picture type %d\n", |
1143 | picture_type); |
1144 | |
1145 | if (kfifo_get(&hw->newframe_q, &vf) == 0) { |
1146 | pr_info |
1147 | ("fatal error, no available buffer slot."); |
1148 | return IRQ_HANDLED; |
1149 | } |
1150 | set_frame_info(hw, vf, &dur); |
1151 | vf->bufWidth = 1920; |
1152 | hw->pic_type = 2; |
1153 | if ((picture_type == I_PICTURE) && pts_valid) { |
1154 | vf->pts = pts; |
1155 | if ((repeat_count > 1) && hw->avi_flag) { |
1156 | /* hw->next_pts = pts + |
1157 | * (hw->vavs_amstream_dec_info.rate * |
1158 | * repeat_count >> 1)*15/16; |
1159 | */ |
1160 | hw->next_pts = |
1161 | pts + |
1162 | (dur * repeat_count >> 1) * |
1163 | 15 / 16; |
1164 | } else |
1165 | hw->next_pts = 0; |
1166 | } else { |
1167 | vf->pts = hw->next_pts; |
1168 | if ((repeat_count > 1) && hw->avi_flag) { |
1169 | /* vf->duration = |
1170 | * hw->vavs_amstream_dec_info.rate * |
1171 | * repeat_count >> 1; |
1172 | */ |
1173 | vf->duration = dur * repeat_count >> 1; |
1174 | if (hw->next_pts != 0) { |
1175 | hw->next_pts += |
1176 | ((vf->duration) - |
1177 | ((vf->duration) >> 4)); |
1178 | } |
1179 | } else { |
1180 | /* vf->duration = |
1181 | * hw->vavs_amstream_dec_info.rate >> 1; |
1182 | */ |
1183 | vf->duration = dur >> 1; |
1184 | hw->next_pts = 0; |
1185 | } |
1186 | } |
1187 | vf->signal_type = 0; |
1188 | vf->index = buffer_index; |
1189 | vf->duration_pulldown = 0; |
1190 | if (force_interlaced_frame) { |
1191 | vf->type = VIDTYPE_INTERLACE_TOP; |
1192 | }else{ |
1193 | vf->type = |
1194 | (reg & TOP_FIELD_FIRST_FLAG) |
1195 | ? VIDTYPE_INTERLACE_TOP |
1196 | : VIDTYPE_INTERLACE_BOTTOM; |
1197 | } |
1198 | #ifdef NV21 |
1199 | vf->type |= VIDTYPE_VIU_NV21; |
1200 | #endif |
1201 | if (hw->m_ins_flag) { |
1202 | vf->canvas0Addr = vf->canvas1Addr = -1; |
1203 | vf->plane_num = 2; |
1204 | |
1205 | vf->canvas0_config[0] = hw->canvas_config[buffer_index][0]; |
1206 | vf->canvas0_config[1] = hw->canvas_config[buffer_index][1]; |
1207 | |
1208 | vf->canvas1_config[0] = hw->canvas_config[buffer_index][0]; |
1209 | vf->canvas1_config[1] = hw->canvas_config[buffer_index][1]; |
1210 | } else |
1211 | vf->canvas0Addr = vf->canvas1Addr = |
1212 | index2canvas(buffer_index); |
1213 | vf->type_original = vf->type; |
1214 | |
1215 | debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, |
1216 | "buffer_index %d, canvas addr %x\n", |
1217 | buffer_index, vf->canvas0Addr); |
1218 | vf->pts_us64 = (pts_valid) ? pts_us64 : 0; |
1219 | hw->vfbuf_use[buffer_index]++; |
1220 | vf->mem_handle = |
1221 | decoder_bmmu_box_get_mem_handle( |
1222 | hw->mm_blk_handle, |
1223 | buffer_index); |
1224 | |
1225 | if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw))) |
1226 | set_vframe_pts(hw, decode_pic_count, vf); |
1227 | |
1228 | kfifo_put(&hw->display_q, |
1229 | (const struct vframe_s *)vf); |
1230 | avs_vf_notify_receiver(hw, PROVIDER_NAME, |
1231 | VFRAME_EVENT_PROVIDER_VFRAME_READY, |
1232 | NULL); |
1233 | |
1234 | if (kfifo_get(&hw->newframe_q, &vf) == 0) { |
1235 | pr_info("fatal error, no available buffer slot."); |
1236 | return IRQ_HANDLED; |
1237 | } |
1238 | set_frame_info(hw, vf, &dur); |
1239 | vf->bufWidth = 1920; |
1240 | if (force_interlaced_frame) |
1241 | vf->pts = 0; |
1242 | else |
1243 | vf->pts = hw->next_pts; |
1244 | |
1245 | if ((repeat_count > 1) && hw->avi_flag) { |
1246 | /* vf->duration = hw->vavs_amstream_dec_info.rate * |
1247 | * repeat_count >> 1; |
1248 | */ |
1249 | vf->duration = dur * repeat_count >> 1; |
1250 | if (hw->next_pts != 0) { |
1251 | hw->next_pts += |
1252 | ((vf->duration) - |
1253 | ((vf->duration) >> 4)); |
1254 | } |
1255 | } else { |
1256 | /* vf->duration = hw->vavs_amstream_dec_info.rate |
1257 | * >> 1; |
1258 | */ |
1259 | vf->duration = dur >> 1; |
1260 | hw->next_pts = 0; |
1261 | } |
1262 | vf->signal_type = 0; |
1263 | vf->index = buffer_index; |
1264 | vf->duration_pulldown = 0; |
1265 | if (force_interlaced_frame) { |
1266 | vf->type = VIDTYPE_INTERLACE_BOTTOM; |
1267 | } else { |
1268 | vf->type = |
1269 | (reg & TOP_FIELD_FIRST_FLAG) ? |
1270 | VIDTYPE_INTERLACE_BOTTOM : |
1271 | VIDTYPE_INTERLACE_TOP; |
1272 | } |
1273 | #ifdef NV21 |
1274 | vf->type |= VIDTYPE_VIU_NV21; |
1275 | #endif |
1276 | if (hw->m_ins_flag) { |
1277 | vf->canvas0Addr = vf->canvas1Addr = -1; |
1278 | vf->plane_num = 2; |
1279 | |
1280 | vf->canvas0_config[0] = hw->canvas_config[buffer_index][0]; |
1281 | vf->canvas0_config[1] = hw->canvas_config[buffer_index][1]; |
1282 | |
1283 | vf->canvas1_config[0] = hw->canvas_config[buffer_index][0]; |
1284 | vf->canvas1_config[1] = hw->canvas_config[buffer_index][1]; |
1285 | } else |
1286 | vf->canvas0Addr = vf->canvas1Addr = |
1287 | index2canvas(buffer_index); |
1288 | vf->type_original = vf->type; |
1289 | vf->pts_us64 = 0; |
1290 | hw->vfbuf_use[buffer_index]++; |
1291 | vf->mem_handle = |
1292 | decoder_bmmu_box_get_mem_handle( |
1293 | hw->mm_blk_handle, |
1294 | buffer_index); |
1295 | |
1296 | if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw))) |
1297 | set_vframe_pts(hw, decode_pic_count, vf); |
1298 | |
1299 | kfifo_put(&hw->display_q, |
1300 | (const struct vframe_s *)vf); |
1301 | avs_vf_notify_receiver(hw, PROVIDER_NAME, |
1302 | VFRAME_EVENT_PROVIDER_VFRAME_READY, |
1303 | NULL); |
1304 | hw->total_frame++; |
1305 | } else { /* progressive */ |
1306 | hw->throw_pb_flag = 0; |
1307 | |
1308 | debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, |
1309 | "progressive picture type %d\n", |
1310 | picture_type); |
1311 | if (kfifo_get(&hw->newframe_q, &vf) == 0) { |
1312 | pr_info |
1313 | ("fatal error, no available buffer slot."); |
1314 | return IRQ_HANDLED; |
1315 | } |
1316 | set_frame_info(hw, vf, &dur); |
1317 | vf->bufWidth = 1920; |
1318 | hw->pic_type = 1; |
1319 | |
1320 | if ((picture_type == I_PICTURE) && pts_valid) { |
1321 | vf->pts = pts; |
1322 | if ((repeat_count > 1) && hw->avi_flag) { |
1323 | /* hw->next_pts = pts + |
1324 | * (hw->vavs_amstream_dec_info.rate * |
1325 | * repeat_count)*15/16; |
1326 | */ |
1327 | hw->next_pts = |
1328 | pts + |
1329 | (dur * repeat_count) * 15 / 16; |
1330 | } else |
1331 | hw->next_pts = 0; |
1332 | } else { |
1333 | vf->pts = hw->next_pts; |
1334 | if ((repeat_count > 1) && hw->avi_flag) { |
1335 | /* vf->duration = |
1336 | * hw->vavs_amstream_dec_info.rate * |
1337 | * repeat_count; |
1338 | */ |
1339 | vf->duration = dur * repeat_count; |
1340 | if (hw->next_pts != 0) { |
1341 | hw->next_pts += |
1342 | ((vf->duration) - |
1343 | ((vf->duration) >> 4)); |
1344 | } |
1345 | } else { |
1346 | /* vf->duration = |
1347 | * hw->vavs_amstream_dec_info.rate; |
1348 | */ |
1349 | vf->duration = dur; |
1350 | hw->next_pts = 0; |
1351 | } |
1352 | } |
1353 | vf->signal_type = 0; |
1354 | vf->index = buffer_index; |
1355 | vf->duration_pulldown = 0; |
1356 | vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD; |
1357 | #ifdef NV21 |
1358 | vf->type |= VIDTYPE_VIU_NV21; |
1359 | #endif |
1360 | if (hw->m_ins_flag) { |
1361 | vf->canvas0Addr = vf->canvas1Addr = -1; |
1362 | vf->plane_num = 2; |
1363 | |
1364 | vf->canvas0_config[0] = hw->canvas_config[buffer_index][0]; |
1365 | vf->canvas0_config[1] = hw->canvas_config[buffer_index][1]; |
1366 | |
1367 | vf->canvas1_config[0] = hw->canvas_config[buffer_index][0]; |
1368 | vf->canvas1_config[1] = hw->canvas_config[buffer_index][1]; |
1369 | } else |
1370 | vf->canvas0Addr = vf->canvas1Addr = |
1371 | index2canvas(buffer_index); |
1372 | vf->type_original = vf->type; |
1373 | |
1374 | vf->pts_us64 = (pts_valid) ? pts_us64 : 0; |
1375 | debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, |
1376 | "buffer_index %d, canvas addr %x\n", |
1377 | buffer_index, vf->canvas0Addr); |
1378 | |
1379 | hw->vfbuf_use[buffer_index]++; |
1380 | vf->mem_handle = |
1381 | decoder_bmmu_box_get_mem_handle( |
1382 | hw->mm_blk_handle, |
1383 | buffer_index); |
1384 | |
1385 | if (hw->m_ins_flag && vdec_frame_based(hw_to_vdec(hw))) |
1386 | set_vframe_pts(hw, decode_pic_count, vf); |
1387 | |
1388 | kfifo_put(&hw->display_q, |
1389 | (const struct vframe_s *)vf); |
1390 | avs_vf_notify_receiver(hw, PROVIDER_NAME, |
1391 | VFRAME_EVENT_PROVIDER_VFRAME_READY, |
1392 | NULL); |
1393 | hw->total_frame++; |
1394 | } |
1395 | |
1396 | /*count info*/ |
1397 | vdec_count_info(hw->gvs, 0, offset); |
1398 | avs_update_gvs(hw); |
1399 | vdec_fill_vdec_frame(hw_to_vdec(hw), NULL, hw->gvs, vf, 0); |
1400 | |
1401 | /* pr_info("PicType = %d, PTS = 0x%x\n", |
1402 | * picture_type, vf->pts); |
1403 | */ |
1404 | WRITE_VREG(AVS_BUFFEROUT, 0); |
1405 | } |
1406 | WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); |
1407 | |
1408 | |
1409 | if (hw->m_ins_flag) { |
1410 | u32 status_reg = READ_VREG(DECODE_STATUS); |
1411 | u32 decode_status = status_reg & 0xff; |
1412 | if (hw->dec_result == DEC_RESULT_DONE || |
1413 | hw->dec_result == DEC_RESULT_AGAIN) { |
1414 | debug_print(hw, PRINT_FLAG_DECODING, |
1415 | "%s !!! READ_VREG(DECODE_STATUS) = 0x%x, decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d bit_cnt=0x%x\n", |
1416 | __func__, status_reg, decode_status, |
1417 | hw->buf_status, |
1418 | hw->dec_result, hw->decode_pic_count, |
1419 | READ_VREG(VIFF_BIT_CNT)); |
1420 | return IRQ_HANDLED; |
1421 | } else if (decode_status == DECODE_STATUS_PIC_DONE || |
1422 | decode_status == DECODE_STATUS_SKIP_PIC_DONE) { |
1423 | hw->buf_status = (status_reg >> 16) & 0xffff; |
1424 | if (decode_status == DECODE_STATUS_SKIP_PIC_DONE) { |
1425 | hw->decode_status_skip_pic_done_flag = 1; |
1426 | hw->decode_decode_cont_start_code = (status_reg >> 8) & 0xff; |
1427 | } |
1428 | hw->decode_pic_count++; |
1429 | if ((hw->decode_pic_count & 0xffff) == 0) { |
1430 | /*make ucode do not handle it as first picture*/ |
1431 | hw->decode_pic_count++; |
1432 | } |
1433 | reset_process_time(hw); |
1434 | hw->dec_result = DEC_RESULT_DONE; |
1435 | #if DEBUG_MULTI_FLAG == 1 |
1436 | WRITE_VREG(DECODE_STATUS, 0); |
1437 | #else |
1438 | amvdec_stop(); |
1439 | #endif |
1440 | vavs_save_regs(hw); |
1441 | debug_print(hw, PRINT_FLAG_DECODING, |
1442 | "%s %s, READ_VREG(DECODE_STATUS) = 0x%x, decode_status 0x%x, buf_status 0x%x, dec_result = 0x%x, decode_pic_count = %d, bit_cnt=0x%x\n", |
1443 | __func__, |
1444 | (decode_status == DECODE_STATUS_PIC_DONE) ? |
1445 | "DECODE_STATUS_PIC_DONE" : "DECODE_STATUS_SKIP_PIC_DONE", |
1446 | status_reg, decode_status, |
1447 | hw->buf_status, |
1448 | hw->dec_result, hw->decode_pic_count, |
1449 | READ_VREG(VIFF_BIT_CNT)); |
1450 | vdec_schedule_work(&hw->work); |
1451 | return IRQ_HANDLED; |
1452 | } else if (decode_status == DECODE_STATUS_DECODE_BUF_EMPTY || |
1453 | decode_status == DECODE_STATUS_SEARCH_BUF_EMPTY) { |
1454 | hw->buf_status = (status_reg >> 16) & 0xffff; |
1455 | reset_process_time(hw); |
1456 | #if DEBUG_MULTI_FLAG == 1 |
1457 | WRITE_VREG(DECODE_STATUS, 0); |
1458 | #else |
1459 | amvdec_stop(); |
1460 | #endif |
1461 | if (vdec_frame_based(hw_to_vdec(hw))) { |
1462 | hw->dec_result = DEC_RESULT_DONE; |
1463 | if (hw->decode_pic_count == 0) { |
1464 | hw->decode_pic_count++; |
1465 | } |
1466 | vavs_save_regs(hw); |
1467 | } else |
1468 | hw->dec_result = DEC_RESULT_AGAIN; |
1469 | |
1470 | debug_print(hw, PRINT_FLAG_DECODING, |
1471 | "%s BUF_EMPTY, READ_VREG(DECODE_STATUS) = 0x%x, decode_status 0x%x, buf_status 0x%x, scratch_8 (AVS_BUFFERIN) 0x%x, dec_result = 0x%x, decode_pic_count = %d, bit_cnt=0x%x\n", |
1472 | __func__, status_reg, decode_status, |
1473 | hw->buf_status, |
1474 | hw->reg_scratch_8, |
1475 | hw->dec_result, hw->decode_pic_count, |
1476 | READ_VREG(VIFF_BIT_CNT)); |
1477 | vdec_schedule_work(&hw->work); |
1478 | return IRQ_HANDLED; |
1479 | } |
1480 | } |
1481 | |
1482 | |
1483 | #ifdef HANDLE_AVS_IRQ |
1484 | return IRQ_HANDLED; |
1485 | #else |
1486 | return; |
1487 | #endif |
1488 | } |
1489 | /* |
1490 | *static int run_flag = 1; |
1491 | *static int step_flag; |
1492 | */ |
1493 | static int error_recovery_mode; /*0: blocky 1: mosaic*/ |
1494 | /* |
1495 | *static uint error_watchdog_threshold=10; |
1496 | *static uint error_watchdog_count; |
1497 | *static uint error_watchdog_buf_threshold = 0x4000000; |
1498 | */ |
1499 | |
1500 | static struct vframe_s *vavs_vf_peek(void *op_arg) |
1501 | { |
1502 | struct vframe_s *vf; |
1503 | struct vdec_avs_hw_s *hw = |
1504 | (struct vdec_avs_hw_s *)op_arg; |
1505 | hw->peek_num++; |
1506 | if (step == 2) |
1507 | return NULL; |
1508 | if (hw->recover_flag) |
1509 | return NULL; |
1510 | |
1511 | if (kfifo_peek(&hw->display_q, &vf)) { |
1512 | if (vf) { |
1513 | if (force_fps & 0x100) { |
1514 | u32 rate = force_fps & 0xff; |
1515 | |
1516 | if (rate) |
1517 | vf->duration = 96000/rate; |
1518 | else |
1519 | vf->duration = 0; |
1520 | } |
1521 | |
1522 | } |
1523 | return vf; |
1524 | } |
1525 | |
1526 | return NULL; |
1527 | |
1528 | } |
1529 | |
1530 | static struct vframe_s *vavs_vf_get(void *op_arg) |
1531 | { |
1532 | struct vframe_s *vf; |
1533 | struct vdec_avs_hw_s *hw = |
1534 | (struct vdec_avs_hw_s *)op_arg; |
1535 | |
1536 | if (hw->recover_flag) |
1537 | return NULL; |
1538 | |
1539 | if (step == 2) |
1540 | return NULL; |
1541 | else if (step == 1) |
1542 | step = 2; |
1543 | |
1544 | if (kfifo_get(&hw->display_q, &vf)) { |
1545 | if (vf) { |
1546 | hw->get_num++; |
1547 | if (force_fps & 0x100) { |
1548 | u32 rate = force_fps & 0xff; |
1549 | |
1550 | if (rate) |
1551 | vf->duration = 96000/rate; |
1552 | else |
1553 | vf->duration = 0; |
1554 | } |
1555 | |
1556 | debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, |
1557 | "%s, index = %d, w %d h %d, type 0x%x detached %d\n", |
1558 | __func__, |
1559 | vf->index, |
1560 | vf->width, |
1561 | vf->height, |
1562 | vf->type, |
1563 | buf_of_vf(vf)->detached); |
1564 | } |
1565 | return vf; |
1566 | } |
1567 | |
1568 | return NULL; |
1569 | |
1570 | } |
1571 | |
1572 | static void vavs_vf_put(struct vframe_s *vf, void *op_arg) |
1573 | { |
1574 | int i; |
1575 | struct vdec_avs_hw_s *hw = |
1576 | (struct vdec_avs_hw_s *)op_arg; |
1577 | |
1578 | if (vf) { |
1579 | hw->put_num++; |
1580 | debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, |
1581 | "%s, index = %d, w %d h %d, type 0x%x detached 0x%x\n", |
1582 | __func__, |
1583 | vf->index, |
1584 | vf->width, |
1585 | vf->height, |
1586 | vf->type, |
1587 | buf_of_vf(vf)->detached); |
1588 | } |
1589 | if (hw->recover_flag) |
1590 | return; |
1591 | |
1592 | for (i = 0; i < VF_POOL_SIZE; i++) { |
1593 | if (vf == &hw->vfpool[i].vf) |
1594 | break; |
1595 | } |
1596 | if (i < VF_POOL_SIZE) |
1597 | |
1598 | kfifo_put(&hw->recycle_q, (const struct vframe_s *)vf); |
1599 | |
1600 | } |
1601 | |
1602 | static int vavs_event_cb(int type, void *data, void *private_data) |
1603 | { |
1604 | return 0; |
1605 | } |
1606 | |
1607 | int vavs_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus) |
1608 | { |
1609 | struct vdec_avs_hw_s *hw = |
1610 | (struct vdec_avs_hw_s *)vdec->private; |
1611 | /*if (!(hw->stat & STAT_VDEC_RUN)) |
1612 | return -1;*/ |
1613 | if (!hw) |
1614 | return -1; |
1615 | |
1616 | vstatus->frame_width = hw->frame_width; |
1617 | vstatus->frame_height = hw->frame_height; |
1618 | if (hw->frame_dur != 0) |
1619 | vstatus->frame_rate = 96000 / hw->frame_dur; |
1620 | else |
1621 | vstatus->frame_rate = -1; |
1622 | vstatus->error_count = READ_VREG(AV_SCRATCH_C); |
1623 | vstatus->status = hw->stat; |
1624 | vstatus->bit_rate = hw->gvs->bit_rate; |
1625 | vstatus->frame_dur = hw->frame_dur; |
1626 | vstatus->frame_data = hw->gvs->frame_data; |
1627 | vstatus->total_data = hw->gvs->total_data; |
1628 | vstatus->frame_count = hw->gvs->frame_count; |
1629 | vstatus->error_frame_count = hw->gvs->error_frame_count; |
1630 | vstatus->drop_frame_count = hw->gvs->drop_frame_count; |
1631 | vstatus->total_data = hw->gvs->total_data; |
1632 | vstatus->samp_cnt = hw->gvs->samp_cnt; |
1633 | vstatus->offset = hw->gvs->offset; |
1634 | snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name), |
1635 | "%s", DRIVER_NAME); |
1636 | |
1637 | return 0; |
1638 | } |
1639 | |
1640 | int vavs_set_isreset(struct vdec_s *vdec, int isreset) |
1641 | { |
1642 | struct vdec_avs_hw_s *hw = |
1643 | (struct vdec_avs_hw_s *)vdec->private; |
1644 | |
1645 | hw->is_reset = isreset; |
1646 | return 0; |
1647 | } |
1648 | |
1649 | static int vavs_vdec_info_init(struct vdec_avs_hw_s *hw) |
1650 | { |
1651 | |
1652 | hw->gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL); |
1653 | if (NULL == hw->gvs) { |
1654 | pr_info("the struct of vdec status malloc failed.\n"); |
1655 | return -ENOMEM; |
1656 | } |
1657 | |
1658 | return 0; |
1659 | } |
1660 | /****************************************/ |
1661 | static int vavs_canvas_init(struct vdec_avs_hw_s *hw) |
1662 | { |
1663 | int i, ret; |
1664 | u32 canvas_width, canvas_height; |
1665 | u32 decbuf_size, decbuf_y_size, decbuf_uv_size; |
1666 | unsigned long buf_start; |
1667 | int need_alloc_buf_num; |
1668 | struct vdec_s *vdec = NULL; |
1669 | |
1670 | if (hw->m_ins_flag) |
1671 | vdec = hw_to_vdec(hw); |
1672 | |
1673 | if (buf_size <= 0x00400000) { |
1674 | /* SD only */ |
1675 | canvas_width = 768; |
1676 | canvas_height = 576; |
1677 | decbuf_y_size = 0x80000; |
1678 | decbuf_uv_size = 0x20000; |
1679 | decbuf_size = 0x100000; |
1680 | } else { |
1681 | /* HD & SD */ |
1682 | canvas_width = 1920; |
1683 | canvas_height = 1088; |
1684 | decbuf_y_size = 0x200000; |
1685 | decbuf_uv_size = 0x80000; |
1686 | decbuf_size = 0x300000; |
1687 | } |
1688 | |
1689 | #ifdef AVSP_LONG_CABAC |
1690 | need_alloc_buf_num = hw->vf_buf_num_used + 2; |
1691 | #else |
1692 | need_alloc_buf_num = hw->vf_buf_num_used + 1; |
1693 | #endif |
1694 | for (i = 0; i < need_alloc_buf_num; i++) { |
1695 | |
1696 | if (i == (need_alloc_buf_num - 1)) |
1697 | decbuf_size = WORKSPACE_SIZE; |
1698 | #ifdef AVSP_LONG_CABAC |
1699 | else if (i == (need_alloc_buf_num - 2)) |
1700 | decbuf_size = WORKSPACE_SIZE_A; |
1701 | #endif |
1702 | ret = decoder_bmmu_box_alloc_buf_phy(hw->mm_blk_handle, i, |
1703 | decbuf_size, DRIVER_NAME, &buf_start); |
1704 | if (ret < 0) |
1705 | return ret; |
1706 | if (i == (need_alloc_buf_num - 1)) { |
1707 | if (firmware_sel == 1) |
1708 | hw->buf_offset = buf_start - |
1709 | RV_AI_BUFF_START_ADDR; |
1710 | else |
1711 | hw->buf_offset = buf_start - |
1712 | LONG_CABAC_RV_AI_BUFF_START_ADDR; |
1713 | continue; |
1714 | } |
1715 | #ifdef AVSP_LONG_CABAC |
1716 | else if (i == (need_alloc_buf_num - 2)) { |
1717 | avsp_heap_adr = codec_mm_phys_to_virt(buf_start); |
1718 | continue; |
1719 | } |
1720 | #endif |
1721 | if (hw->m_ins_flag) { |
1722 | unsigned canvas; |
1723 | |
1724 | if (vdec->parallel_dec == 1) { |
1725 | unsigned tmp; |
1726 | if (canvas_u(hw->canvas_spec[i]) == 0xff) { |
1727 | tmp = |
1728 | vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id); |
1729 | hw->canvas_spec[i] &= ~(0xffff << 8); |
1730 | hw->canvas_spec[i] |= tmp << 8; |
1731 | hw->canvas_spec[i] |= tmp << 16; |
1732 | } |
1733 | if (canvas_y(hw->canvas_spec[i]) == 0xff) { |
1734 | tmp = |
1735 | vdec->get_canvas_ex(CORE_MASK_VDEC_1, vdec->id); |
1736 | hw->canvas_spec[i] &= ~0xff; |
1737 | hw->canvas_spec[i] |= tmp; |
1738 | } |
1739 | canvas = hw->canvas_spec[i]; |
1740 | } else { |
1741 | canvas = vdec->get_canvas(i, 2); |
1742 | hw->canvas_spec[i] = canvas; |
1743 | } |
1744 | |
1745 | hw->canvas_config[i][0].phy_addr = |
1746 | buf_start; |
1747 | hw->canvas_config[i][0].width = |
1748 | canvas_width; |
1749 | hw->canvas_config[i][0].height = |
1750 | canvas_height; |
1751 | hw->canvas_config[i][0].block_mode = |
1752 | CANVAS_BLKMODE_32X32; |
1753 | |
1754 | hw->canvas_config[i][1].phy_addr = |
1755 | buf_start + decbuf_y_size; |
1756 | hw->canvas_config[i][1].width = |
1757 | canvas_width; |
1758 | hw->canvas_config[i][1].height = |
1759 | canvas_height / 2; |
1760 | hw->canvas_config[i][1].block_mode = |
1761 | CANVAS_BLKMODE_32X32; |
1762 | |
1763 | } else { |
1764 | #ifdef NV21 |
1765 | canvas_config(canvas_base + canvas_num * i + 0, |
1766 | buf_start, |
1767 | canvas_width, canvas_height, |
1768 | CANVAS_ADDR_NOWRAP, |
1769 | CANVAS_BLKMODE_32X32); |
1770 | canvas_config(canvas_base + canvas_num * i + 1, |
1771 | buf_start + |
1772 | decbuf_y_size, canvas_width, |
1773 | canvas_height / 2, |
1774 | CANVAS_ADDR_NOWRAP, |
1775 | CANVAS_BLKMODE_32X32); |
1776 | #else |
1777 | canvas_config(canvas_num * i + 0, |
1778 | buf_start, |
1779 | canvas_width, canvas_height, |
1780 | CANVAS_ADDR_NOWRAP, |
1781 | CANVAS_BLKMODE_32X32); |
1782 | canvas_config(canvas_num * i + 1, |
1783 | buf_start + |
1784 | decbuf_y_size, canvas_width / 2, |
1785 | canvas_height / 2, |
1786 | CANVAS_ADDR_NOWRAP, |
1787 | CANVAS_BLKMODE_32X32); |
1788 | canvas_config(canvas_num * i + 2, |
1789 | buf_start + |
1790 | decbuf_y_size + decbuf_uv_size, |
1791 | canvas_width / 2, canvas_height / 2, |
1792 | CANVAS_ADDR_NOWRAP, |
1793 | CANVAS_BLKMODE_32X32); |
1794 | #endif |
1795 | debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, |
1796 | "canvas config %d, addr %p\n", i, |
1797 | (void *)buf_start); |
1798 | } |
1799 | } |
1800 | return 0; |
1801 | } |
1802 | |
1803 | void vavs_recover(struct vdec_avs_hw_s *hw) |
1804 | { |
1805 | vavs_canvas_init(hw); |
1806 | |
1807 | WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4)); |
1808 | WRITE_VREG(DOS_SW_RESET0, 0); |
1809 | |
1810 | READ_VREG(DOS_SW_RESET0); |
1811 | |
1812 | WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4)); |
1813 | WRITE_VREG(DOS_SW_RESET0, 0); |
1814 | |
1815 | WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8)); |
1816 | WRITE_VREG(DOS_SW_RESET0, 0); |
1817 | |
1818 | if (firmware_sel == 1) { |
1819 | WRITE_VREG(POWER_CTL_VLD, 0x10); |
1820 | WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2, |
1821 | MEM_FIFO_CNT_BIT, 2); |
1822 | WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8, |
1823 | MEM_LEVEL_CNT_BIT, 6); |
1824 | } |
1825 | |
1826 | |
1827 | if (firmware_sel == 0) { |
1828 | /* fixed canvas index */ |
1829 | WRITE_VREG(AV_SCRATCH_0, canvas_base); |
1830 | WRITE_VREG(AV_SCRATCH_1, hw->vf_buf_num_used); |
1831 | } else { |
1832 | int ii; |
1833 | #ifndef USE_DYNAMIC_BUF_NUM |
1834 | for (ii = 0; ii < 4; ii++) { |
1835 | WRITE_VREG(AV_SCRATCH_0 + ii, |
1836 | (canvas_base + canvas_num * ii) | |
1837 | ((canvas_base + canvas_num * ii + 1) |
1838 | << 8) | |
1839 | ((canvas_base + canvas_num * ii + 1) |
1840 | << 16) |
1841 | ); |
1842 | } |
1843 | #else |
1844 | for (ii = 0; ii < hw->vf_buf_num_used; ii += 2) { |
1845 | WRITE_VREG(buf_spec_reg[ii >> 1], |
1846 | (canvas_base + canvas_num * ii) | |
1847 | ((canvas_base + canvas_num * ii + 1) |
1848 | << 8) | |
1849 | ((canvas_base + canvas_num * ii + 2) |
1850 | << 16) | |
1851 | ((canvas_base + canvas_num * ii + 3) |
1852 | << 24) |
1853 | ); |
1854 | } |
1855 | #endif |
1856 | } |
1857 | |
1858 | /* notify ucode the buffer offset */ |
1859 | WRITE_VREG(AV_SCRATCH_F, hw->buf_offset); |
1860 | |
1861 | /* disable PSCALE for hardware sharing */ |
1862 | WRITE_VREG(PSCALE_CTRL, 0); |
1863 | |
1864 | #ifndef USE_DYNAMIC_BUF_NUM |
1865 | WRITE_VREG(AVS_SOS_COUNT, 0); |
1866 | #endif |
1867 | WRITE_VREG(AVS_BUFFERIN, 0); |
1868 | WRITE_VREG(AVS_BUFFEROUT, 0); |
1869 | if (error_recovery_mode) |
1870 | WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 0); |
1871 | else |
1872 | WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 1); |
1873 | /* clear mailbox interrupt */ |
1874 | WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); |
1875 | |
1876 | /* enable mailbox interrupt */ |
1877 | WRITE_VREG(ASSIST_MBOX1_MASK, 1); |
1878 | #ifndef USE_DYNAMIC_BUF_NUM /* def DEBUG_UCODE */ |
1879 | WRITE_VREG(AV_SCRATCH_D, 0); |
1880 | #endif |
1881 | |
1882 | #ifdef NV21 |
1883 | SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); |
1884 | #endif |
1885 | |
1886 | #ifdef PIC_DC_NEED_CLEAR |
1887 | CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); |
1888 | #endif |
1889 | |
1890 | #ifdef AVSP_LONG_CABAC |
1891 | if (firmware_sel == 0) { |
1892 | WRITE_VREG(LONG_CABAC_DES_ADDR, es_write_addr_phy); |
1893 | WRITE_VREG(LONG_CABAC_REQ, 0); |
1894 | WRITE_VREG(LONG_CABAC_PIC_SIZE, 0); |
1895 | WRITE_VREG(LONG_CABAC_SRC_ADDR, 0); |
1896 | } |
1897 | #endif |
1898 | WRITE_VREG(AV_SCRATCH_5, 0); |
1899 | |
1900 | } |
1901 | |
1902 | #define MBY_MBX MB_MOTION_MODE /*0xc07*/ |
1903 | #define AVS_CO_MB_WR_ADDR 0xc38 |
1904 | #define AVS_CO_MB_RW_CTL 0xc3d |
1905 | #define AVS_CO_MB_RD_ADDR 0xc39 |
1906 | #define AVSP_IQ_WQ_PARAM_01 0x0e19 |
1907 | #define AVSP_IQ_WQ_PARAM_23 0x0e1a |
1908 | #define AVSP_IQ_WQ_PARAM_45 0x0e1b |
1909 | |
1910 | static void vavs_save_regs(struct vdec_avs_hw_s *hw) |
1911 | { |
1912 | hw->reg_scratch_0 = READ_VREG(AV_SCRATCH_0); |
1913 | hw->reg_scratch_1 = READ_VREG(AV_SCRATCH_1); |
1914 | hw->reg_scratch_2 = READ_VREG(AV_SCRATCH_2); |
1915 | hw->reg_scratch_3 = READ_VREG(AV_SCRATCH_3); |
1916 | hw->reg_scratch_4 = READ_VREG(AV_SCRATCH_4); |
1917 | hw->reg_scratch_5 = READ_VREG(AV_SCRATCH_5); |
1918 | hw->reg_scratch_6 = READ_VREG(AV_SCRATCH_6); |
1919 | hw->reg_scratch_7 = READ_VREG(AV_SCRATCH_7); |
1920 | hw->reg_scratch_8 = READ_VREG(AV_SCRATCH_8); |
1921 | hw->reg_scratch_9 = READ_VREG(AV_SCRATCH_9); |
1922 | hw->reg_scratch_A = READ_VREG(AV_SCRATCH_A); |
1923 | hw->reg_scratch_B = READ_VREG(AV_SCRATCH_B); |
1924 | hw->reg_scratch_C = READ_VREG(AV_SCRATCH_C); |
1925 | hw->reg_scratch_D = READ_VREG(AV_SCRATCH_D); |
1926 | hw->reg_scratch_E = READ_VREG(AV_SCRATCH_E); |
1927 | hw->reg_scratch_F = READ_VREG(AV_SCRATCH_F); |
1928 | hw->reg_scratch_G = READ_VREG(AV_SCRATCH_G); |
1929 | hw->reg_scratch_H = READ_VREG(AV_SCRATCH_H); |
1930 | hw->reg_scratch_I = READ_VREG(AV_SCRATCH_I); |
1931 | |
1932 | hw->reg_mb_width = READ_VREG(MB_WIDTH); |
1933 | hw->reg_viff_bit_cnt = READ_VREG(VIFF_BIT_CNT); |
1934 | |
1935 | hw->reg_canvas_addr = READ_VREG(REC_CANVAS_ADDR); |
1936 | hw->reg_dbkr_canvas_addr = READ_VREG(DBKR_CANVAS_ADDR); |
1937 | hw->reg_dbkw_canvas_addr = READ_VREG(DBKW_CANVAS_ADDR); |
1938 | hw->reg_anc2_canvas_addr = READ_VREG(ANC2_CANVAS_ADDR); |
1939 | hw->reg_anc0_canvas_addr = READ_VREG(ANC0_CANVAS_ADDR); |
1940 | hw->reg_anc1_canvas_addr = READ_VREG(ANC1_CANVAS_ADDR); |
1941 | hw->reg_anc3_canvas_addr = READ_VREG(ANC3_CANVAS_ADDR); |
1942 | hw->reg_anc4_canvas_addr = READ_VREG(ANC4_CANVAS_ADDR); |
1943 | hw->reg_anc5_canvas_addr = READ_VREG(ANC5_CANVAS_ADDR); |
1944 | |
1945 | hw->slice_ver_pos_pic_type = READ_VREG(SLICE_VER_POS_PIC_TYPE); |
1946 | |
1947 | hw->vc1_control_reg = READ_VREG(VC1_CONTROL_REG); |
1948 | hw->avs_co_mb_wr_addr = READ_VREG(AVS_CO_MB_WR_ADDR); |
1949 | hw->slice_start_byte_01 = READ_VREG(SLICE_START_BYTE_01); |
1950 | hw->slice_start_byte_23 = READ_VREG(SLICE_START_BYTE_23); |
1951 | hw->vcop_ctrl_reg = READ_VREG(VCOP_CTRL_REG); |
1952 | hw->iqidct_control = READ_VREG(IQIDCT_CONTROL); |
1953 | hw->rv_ai_mb_count = READ_VREG(RV_AI_MB_COUNT); |
1954 | hw->slice_qp = READ_VREG(SLICE_QP); |
1955 | |
1956 | hw->dc_scaler = READ_VREG(DC_SCALER); |
1957 | hw->avsp_iq_wq_param_01 = READ_VREG(AVSP_IQ_WQ_PARAM_01); |
1958 | hw->avsp_iq_wq_param_23 = READ_VREG(AVSP_IQ_WQ_PARAM_23); |
1959 | hw->avsp_iq_wq_param_45 = READ_VREG(AVSP_IQ_WQ_PARAM_45); |
1960 | hw->avs_co_mb_rd_addr = READ_VREG(AVS_CO_MB_RD_ADDR); |
1961 | hw->dblk_mb_wid_height = READ_VREG(DBLK_MB_WID_HEIGHT); |
1962 | hw->mc_pic_w_h = READ_VREG(MC_PIC_W_H); |
1963 | hw->avs_co_mb_rw_ctl = READ_VREG(AVS_CO_MB_RW_CTL); |
1964 | |
1965 | hw->vld_decode_control = READ_VREG(VLD_DECODE_CONTROL); |
1966 | } |
1967 | |
1968 | static void vavs_restore_regs(struct vdec_avs_hw_s *hw) |
1969 | { |
1970 | debug_print(hw, PRINT_FLAG_DECODING, |
1971 | "%s scratch_8 (AVS_BUFFERIN) 0x%x, decode_pic_count = %d\n", |
1972 | __func__, hw->reg_scratch_8, hw->decode_pic_count); |
1973 | |
1974 | WRITE_VREG(AV_SCRATCH_0, hw->reg_scratch_0); |
1975 | WRITE_VREG(AV_SCRATCH_1, hw->reg_scratch_1); |
1976 | WRITE_VREG(AV_SCRATCH_2, hw->reg_scratch_2); |
1977 | WRITE_VREG(AV_SCRATCH_3, hw->reg_scratch_3); |
1978 | WRITE_VREG(AV_SCRATCH_4, hw->reg_scratch_4); |
1979 | WRITE_VREG(AV_SCRATCH_5, hw->reg_scratch_5); |
1980 | WRITE_VREG(AV_SCRATCH_6, hw->reg_scratch_6); |
1981 | WRITE_VREG(AV_SCRATCH_7, hw->reg_scratch_7); |
1982 | WRITE_VREG(AV_SCRATCH_8, hw->reg_scratch_8); |
1983 | WRITE_VREG(AV_SCRATCH_9, hw->reg_scratch_9); |
1984 | WRITE_VREG(AV_SCRATCH_A, hw->reg_scratch_A); |
1985 | WRITE_VREG(AV_SCRATCH_B, hw->reg_scratch_B); |
1986 | WRITE_VREG(AV_SCRATCH_C, hw->reg_scratch_C); |
1987 | WRITE_VREG(AV_SCRATCH_D, hw->reg_scratch_D); |
1988 | WRITE_VREG(AV_SCRATCH_E, hw->reg_scratch_E); |
1989 | WRITE_VREG(AV_SCRATCH_F, hw->reg_scratch_F); |
1990 | WRITE_VREG(AV_SCRATCH_G, hw->reg_scratch_G); |
1991 | WRITE_VREG(AV_SCRATCH_H, hw->reg_scratch_H); |
1992 | WRITE_VREG(AV_SCRATCH_I, hw->reg_scratch_I); |
1993 | |
1994 | WRITE_VREG(MB_WIDTH, hw->reg_mb_width); |
1995 | WRITE_VREG(VIFF_BIT_CNT, hw->reg_viff_bit_cnt); |
1996 | |
1997 | WRITE_VREG(REC_CANVAS_ADDR, hw->reg_canvas_addr); |
1998 | WRITE_VREG(DBKR_CANVAS_ADDR, hw->reg_dbkr_canvas_addr); |
1999 | WRITE_VREG(DBKW_CANVAS_ADDR, hw->reg_dbkw_canvas_addr); |
2000 | WRITE_VREG(ANC2_CANVAS_ADDR, hw->reg_anc2_canvas_addr); |
2001 | WRITE_VREG(ANC0_CANVAS_ADDR, hw->reg_anc0_canvas_addr); |
2002 | WRITE_VREG(ANC1_CANVAS_ADDR, hw->reg_anc1_canvas_addr); |
2003 | WRITE_VREG(ANC3_CANVAS_ADDR, hw->reg_anc3_canvas_addr); |
2004 | WRITE_VREG(ANC4_CANVAS_ADDR, hw->reg_anc4_canvas_addr); |
2005 | WRITE_VREG(ANC5_CANVAS_ADDR, hw->reg_anc5_canvas_addr); |
2006 | |
2007 | WRITE_VREG(SLICE_VER_POS_PIC_TYPE, hw->slice_ver_pos_pic_type); |
2008 | |
2009 | WRITE_VREG(VC1_CONTROL_REG, hw->vc1_control_reg); |
2010 | WRITE_VREG(AVS_CO_MB_WR_ADDR, hw->avs_co_mb_wr_addr); |
2011 | WRITE_VREG(SLICE_START_BYTE_01, hw->slice_start_byte_01); |
2012 | WRITE_VREG(SLICE_START_BYTE_23, hw->slice_start_byte_23); |
2013 | WRITE_VREG(VCOP_CTRL_REG, hw->vcop_ctrl_reg); |
2014 | WRITE_VREG(IQIDCT_CONTROL, hw->iqidct_control); |
2015 | WRITE_VREG(RV_AI_MB_COUNT, hw->rv_ai_mb_count); |
2016 | WRITE_VREG(SLICE_QP, hw->slice_qp); |
2017 | |
2018 | WRITE_VREG(DC_SCALER, hw->dc_scaler); |
2019 | WRITE_VREG(AVSP_IQ_WQ_PARAM_01, hw->avsp_iq_wq_param_01); |
2020 | WRITE_VREG(AVSP_IQ_WQ_PARAM_23, hw->avsp_iq_wq_param_23); |
2021 | WRITE_VREG(AVSP_IQ_WQ_PARAM_45, hw->avsp_iq_wq_param_45); |
2022 | WRITE_VREG(AVS_CO_MB_RD_ADDR, hw->avs_co_mb_rd_addr); |
2023 | WRITE_VREG(DBLK_MB_WID_HEIGHT, hw->dblk_mb_wid_height); |
2024 | WRITE_VREG(MC_PIC_W_H, hw->mc_pic_w_h); |
2025 | WRITE_VREG(AVS_CO_MB_RW_CTL, hw->avs_co_mb_rw_ctl); |
2026 | |
2027 | WRITE_VREG(VLD_DECODE_CONTROL, hw->vld_decode_control); |
2028 | |
2029 | } |
2030 | |
2031 | static int vavs_prot_init(struct vdec_avs_hw_s *hw) |
2032 | { |
2033 | int r = 0; |
2034 | #if DEBUG_MULTI_FLAG > 0 |
2035 | if (hw->decode_pic_count == 0) { |
2036 | #endif |
2037 | #if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ |
2038 | WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4)); |
2039 | WRITE_VREG(DOS_SW_RESET0, 0); |
2040 | |
2041 | READ_VREG(DOS_SW_RESET0); |
2042 | |
2043 | WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4)); |
2044 | WRITE_VREG(DOS_SW_RESET0, 0); |
2045 | |
2046 | WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8)); |
2047 | WRITE_VREG(DOS_SW_RESET0, 0); |
2048 | |
2049 | #else |
2050 | WRITE_RESET_REG(RESET0_REGISTER, |
2051 | RESET_IQIDCT | RESET_MC | RESET_VLD_PART); |
2052 | READ_RESET_REG(RESET0_REGISTER); |
2053 | WRITE_RESET_REG(RESET0_REGISTER, |
2054 | RESET_IQIDCT | RESET_MC | RESET_VLD_PART); |
2055 | |
2056 | WRITE_RESET_REG(RESET2_REGISTER, RESET_PIC_DC | RESET_DBLK); |
2057 | #endif |
2058 | #if DEBUG_MULTI_FLAG > 0 |
2059 | } |
2060 | #endif |
2061 | /***************** reset vld **********************************/ |
2062 | WRITE_VREG(POWER_CTL_VLD, 0x10); |
2063 | WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2, MEM_FIFO_CNT_BIT, 2); |
2064 | WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8, MEM_LEVEL_CNT_BIT, 6); |
2065 | /*************************************************************/ |
2066 | if (hw->m_ins_flag) { |
2067 | int i; |
2068 | if (hw->decode_pic_count == 0) { |
2069 | r = vavs_canvas_init(hw); |
2070 | #ifndef USE_DYNAMIC_BUF_NUM |
2071 | for (i = 0; i < 4; i++) { |
2072 | WRITE_VREG(AV_SCRATCH_0 + i, |
2073 | hw->canvas_spec[i] |
2074 | ); |
2075 | } |
2076 | #else |
2077 | for (i = 0; i < hw->vf_buf_num_used; i += 2) { |
2078 | WRITE_VREG(buf_spec_reg[i >> 1], |
2079 | (hw->canvas_spec[i] & 0xffff) | |
2080 | ((hw->canvas_spec[i + 1] & 0xffff) |
2081 | << 16) |
2082 | ); |
2083 | debug_print(hw, PRINT_FLAG_DECODING, |
2084 | "%s WRITE_VREG(0x%x, 0x%x)\n", |
2085 | __func__, buf_spec_reg[i >> 1], READ_VREG(buf_spec_reg[i >> 1])); |
2086 | } |
2087 | #endif |
2088 | } else |
2089 | vavs_restore_regs(hw); |
2090 | |
2091 | for (i = 0; i < hw->vf_buf_num_used; i++) { |
2092 | canvas_config_ex(canvas_y(hw->canvas_spec[i]), |
2093 | hw->canvas_config[i][0].phy_addr, |
2094 | hw->canvas_config[i][0].width, |
2095 | hw->canvas_config[i][0].height, |
2096 | CANVAS_ADDR_NOWRAP, |
2097 | hw->canvas_config[i][0].block_mode, |
2098 | 0); |
2099 | |
2100 | canvas_config_ex(canvas_u(hw->canvas_spec[i]), |
2101 | hw->canvas_config[i][1].phy_addr, |
2102 | hw->canvas_config[i][1].width, |
2103 | hw->canvas_config[i][1].height, |
2104 | CANVAS_ADDR_NOWRAP, |
2105 | hw->canvas_config[i][1].block_mode, |
2106 | 0); |
2107 | } |
2108 | } else { |
2109 | r = vavs_canvas_init(hw); |
2110 | #ifdef NV21 |
2111 | if (firmware_sel == 0) { |
2112 | /* fixed canvas index */ |
2113 | WRITE_VREG(AV_SCRATCH_0, canvas_base); |
2114 | WRITE_VREG(AV_SCRATCH_1, hw->vf_buf_num_used); |
2115 | } else { |
2116 | int ii; |
2117 | #ifndef USE_DYNAMIC_BUF_NUM |
2118 | for (ii = 0; ii < 4; ii++) { |
2119 | WRITE_VREG(AV_SCRATCH_0 + ii, |
2120 | (canvas_base + canvas_num * ii) | |
2121 | ((canvas_base + canvas_num * ii + 1) |
2122 | << 8) | |
2123 | ((canvas_base + canvas_num * ii + 1) |
2124 | << 16) |
2125 | ); |
2126 | } |
2127 | #else |
2128 | for (ii = 0; ii < hw->vf_buf_num_used; ii += 2) { |
2129 | WRITE_VREG(buf_spec_reg[ii >> 1], |
2130 | (canvas_base + canvas_num * ii) | |
2131 | ((canvas_base + canvas_num * ii + 1) |
2132 | << 8) | |
2133 | ((canvas_base + canvas_num * ii + 2) |
2134 | << 16) | |
2135 | ((canvas_base + canvas_num * ii + 3) |
2136 | << 24) |
2137 | ); |
2138 | } |
2139 | #endif |
2140 | /* |
2141 | *WRITE_VREG(AV_SCRATCH_0, 0x010100); |
2142 | *WRITE_VREG(AV_SCRATCH_1, 0x040403); |
2143 | *WRITE_VREG(AV_SCRATCH_2, 0x070706); |
2144 | *WRITE_VREG(AV_SCRATCH_3, 0x0a0a09); |
2145 | */ |
2146 | } |
2147 | #else |
2148 | /* index v << 16 | u << 8 | y */ |
2149 | WRITE_VREG(AV_SCRATCH_0, 0x020100); |
2150 | WRITE_VREG(AV_SCRATCH_1, 0x050403); |
2151 | WRITE_VREG(AV_SCRATCH_2, 0x080706); |
2152 | WRITE_VREG(AV_SCRATCH_3, 0x0b0a09); |
2153 | #endif |
2154 | } |
2155 | /* notify ucode the buffer offset */ |
2156 | if (hw->decode_pic_count == 0) |
2157 | WRITE_VREG(AV_SCRATCH_F, hw->buf_offset); |
2158 | |
2159 | /* disable PSCALE for hardware sharing */ |
2160 | WRITE_VREG(PSCALE_CTRL, 0); |
2161 | |
2162 | if (hw->decode_pic_count == 0) { |
2163 | #ifndef USE_DYNAMIC_BUF_NUM |
2164 | WRITE_VREG(AVS_SOS_COUNT, 0); |
2165 | #endif |
2166 | WRITE_VREG(AVS_BUFFERIN, 0); |
2167 | WRITE_VREG(AVS_BUFFEROUT, 0); |
2168 | } |
2169 | if (error_recovery_mode) |
2170 | WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 0); |
2171 | else |
2172 | WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 1); |
2173 | /* clear mailbox interrupt */ |
2174 | WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); |
2175 | |
2176 | /* enable mailbox interrupt */ |
2177 | WRITE_VREG(ASSIST_MBOX1_MASK, 1); |
2178 | #ifndef USE_DYNAMIC_BUF_NUM /* def DEBUG_UCODE */ |
2179 | if (hw->decode_pic_count == 0) |
2180 | WRITE_VREG(AV_SCRATCH_D, 0); |
2181 | #endif |
2182 | |
2183 | #ifdef NV21 |
2184 | SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); |
2185 | #endif |
2186 | |
2187 | #ifdef PIC_DC_NEED_CLEAR |
2188 | CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); |
2189 | #endif |
2190 | if (hw->m_ins_flag && start_decoding_delay > 0) |
2191 | msleep(start_decoding_delay); |
2192 | |
2193 | //pr_info("+++++++++++++++++++++++++++++++\n"); |
2194 | //pr_info("+++++++++++++++++++++++++++++++\n"); |
2195 | //pr_info("+++++++++++++++++++++++++++++++\n"); |
2196 | #ifdef AVSP_LONG_CABAC |
2197 | if (firmware_sel == 0) { |
2198 | WRITE_VREG(LONG_CABAC_DES_ADDR, es_write_addr_phy); |
2199 | WRITE_VREG(LONG_CABAC_REQ, 0); |
2200 | WRITE_VREG(LONG_CABAC_PIC_SIZE, 0); |
2201 | WRITE_VREG(LONG_CABAC_SRC_ADDR, 0); |
2202 | } |
2203 | #endif |
2204 | |
2205 | #ifdef ENABLE_USER_DATA |
2206 | if (firmware_sel == 0) { |
2207 | WRITE_VREG(AV_SCRATCH_N, (u32)(hw->user_data_buffer_phys - hw->buf_offset)); |
2208 | pr_debug("AV_SCRATCH_N = 0x%x\n", READ_VREG(AV_SCRATCH_N)); |
2209 | } |
2210 | #endif |
2211 | if (hw->m_ins_flag) { |
2212 | if (vdec_frame_based(hw_to_vdec(hw))) |
2213 | WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_FRAMEBASE); |
2214 | else { |
2215 | if (hw->decode_status_skip_pic_done_flag) { |
2216 | WRITE_VREG(DECODE_CFG, hw->decode_decode_cont_start_code); |
2217 | WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE_CONT); |
2218 | } else |
2219 | WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE); |
2220 | } |
2221 | WRITE_VREG(DECODE_LMEM_BUF_ADR, hw->lmem_phy_addr); |
2222 | } else |
2223 | WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); |
2224 | |
2225 | if (ins_udebug_flag[DECODE_ID(hw)] && |
2226 | (ins_udebug_flag[DECODE_ID(hw)] >> 16) == hw->decode_pic_count) { |
2227 | WRITE_VREG(DECODE_STOP_POS, |
2228 | ins_udebug_flag[DECODE_ID(hw)] & 0xffff); |
2229 | } |
2230 | else |
2231 | WRITE_VREG(DECODE_STOP_POS, udebug_flag); |
2232 | hw->old_udebug_flag = udebug_flag; |
2233 | |
2234 | return r; |
2235 | } |
2236 | |
2237 | |
2238 | #ifdef AVSP_LONG_CABAC |
2239 | static unsigned char es_write_addr[MAX_CODED_FRAME_SIZE] __aligned(64); |
2240 | #endif |
2241 | static void vavs_local_init(struct vdec_avs_hw_s *hw) |
2242 | { |
2243 | int i; |
2244 | |
2245 | hw->vf_buf_num_used = vf_buf_num; |
2246 | |
2247 | hw->vavs_ratio = hw->vavs_amstream_dec_info.ratio; |
2248 | |
2249 | hw->avi_flag = (unsigned long) hw->vavs_amstream_dec_info.param; |
2250 | |
2251 | hw->frame_width = hw->frame_height = hw->frame_dur = hw->frame_prog = 0; |
2252 | |
2253 | hw->throw_pb_flag = 1; |
2254 | |
2255 | hw->total_frame = 0; |
2256 | hw->saved_resolution = 0; |
2257 | hw->next_pts = 0; |
2258 | |
2259 | #ifdef DEBUG_PTS |
2260 | hw->pts_hit = hw->pts_missed = hw->pts_i_hit = hw->pts_i_missed = 0; |
2261 | #endif |
2262 | INIT_KFIFO(hw->display_q); |
2263 | INIT_KFIFO(hw->recycle_q); |
2264 | INIT_KFIFO(hw->newframe_q); |
2265 | |
2266 | for (i = 0; i < VF_POOL_SIZE; i++) { |
2267 | const struct vframe_s *vf = &hw->vfpool[i].vf; |
2268 | |
2269 | hw->vfpool[i].vf.index = hw->vf_buf_num_used; |
2270 | hw->vfpool[i].vf.bufWidth = 1920; |
2271 | hw->vfpool[i].detached = 0; |
2272 | kfifo_put(&hw->newframe_q, vf); |
2273 | } |
2274 | for (i = 0; i < hw->vf_buf_num_used; i++) |
2275 | hw->vfbuf_use[i] = 0; |
2276 | |
2277 | /*cur_vfpool = vfpool;*/ |
2278 | |
2279 | if (hw->recover_flag == 1) |
2280 | return; |
2281 | |
2282 | if (hw->mm_blk_handle) { |
2283 | pr_info("decoder_bmmu_box_free\n"); |
2284 | decoder_bmmu_box_free(hw->mm_blk_handle); |
2285 | hw->mm_blk_handle = NULL; |
2286 | } |
2287 | |
2288 | hw->mm_blk_handle = decoder_bmmu_box_alloc_box( |
2289 | DRIVER_NAME, |
2290 | 0, |
2291 | MAX_BMMU_BUFFER_NUM, |
2292 | 4 + PAGE_SHIFT, |
2293 | CODEC_MM_FLAGS_CMA_CLEAR | |
2294 | CODEC_MM_FLAGS_FOR_VDECODER); |
2295 | if (hw->mm_blk_handle == NULL) |
2296 | pr_info("Error, decoder_bmmu_box_alloc_box fail\n"); |
2297 | |
2298 | } |
2299 | |
2300 | static int vavs_vf_states(struct vframe_states *states, void *op_arg) |
2301 | { |
2302 | unsigned long flags; |
2303 | struct vdec_avs_hw_s *hw = |
2304 | (struct vdec_avs_hw_s *)op_arg; |
2305 | |
2306 | |
2307 | spin_lock_irqsave(&lock, flags); |
2308 | states->vf_pool_size = VF_POOL_SIZE; |
2309 | states->buf_free_num = kfifo_len(&hw->newframe_q); |
2310 | states->buf_avail_num = kfifo_len(&hw->display_q); |
2311 | states->buf_recycle_num = kfifo_len(&hw->recycle_q); |
2312 | if (step == 2) |
2313 | states->buf_avail_num = 0; |
2314 | spin_unlock_irqrestore(&lock, flags); |
2315 | return 0; |
2316 | } |
2317 | |
2318 | #ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER |
2319 | static void vavs_ppmgr_reset(void) |
2320 | { |
2321 | vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); |
2322 | |
2323 | vavs_local_init(ghw); |
2324 | |
2325 | pr_info("vavs: vf_ppmgr_reset\n"); |
2326 | } |
2327 | #endif |
2328 | |
2329 | static void vavs_local_reset(struct vdec_avs_hw_s *hw) |
2330 | { |
2331 | mutex_lock(&vavs_mutex); |
2332 | hw->recover_flag = 1; |
2333 | pr_info("error, local reset\n"); |
2334 | amvdec_stop(); |
2335 | msleep(100); |
2336 | avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); |
2337 | vavs_local_init(hw); |
2338 | vavs_recover(hw); |
2339 | |
2340 | #ifdef ENABLE_USER_DATA |
2341 | reset_userdata_fifo(1); |
2342 | #endif |
2343 | |
2344 | amvdec_start(); |
2345 | hw->recover_flag = 0; |
2346 | #if 0 |
2347 | error_watchdog_count = 0; |
2348 | |
2349 | pr_info("pc %x stream buf wp %x rp %x level %x\n", |
2350 | READ_VREG(MPC_E), |
2351 | READ_VREG(VLD_MEM_VIFIFO_WP), |
2352 | READ_VREG(VLD_MEM_VIFIFO_RP), |
2353 | READ_VREG(VLD_MEM_VIFIFO_LEVEL)); |
2354 | #endif |
2355 | |
2356 | |
2357 | |
2358 | mutex_unlock(&vavs_mutex); |
2359 | } |
2360 | |
2361 | #if 0 |
2362 | static struct work_struct fatal_error_wd_work; |
2363 | static struct work_struct notify_work; |
2364 | static atomic_t error_handler_run = ATOMIC_INIT(0); |
2365 | #endif |
2366 | static void vavs_fatal_error_handler(struct work_struct *work) |
2367 | { |
2368 | struct vdec_avs_hw_s *hw = |
2369 | container_of(work, struct vdec_avs_hw_s, fatal_error_wd_work); |
2370 | if (debug & AVS_DEBUG_OLD_ERROR_HANDLE) { |
2371 | mutex_lock(&vavs_mutex); |
2372 | pr_info("vavs fatal error reset !\n"); |
2373 | amvdec_stop(); |
2374 | #ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER |
2375 | vavs_ppmgr_reset(); |
2376 | #else |
2377 | vf_light_unreg_provider(&vavs_vf_prov); |
2378 | vavs_local_init(hw); |
2379 | vf_reg_provider(&vavs_vf_prov); |
2380 | #endif |
2381 | vavs_recover(hw); |
2382 | amvdec_start(); |
2383 | mutex_unlock(&vavs_mutex); |
2384 | } else { |
2385 | pr_info("avs fatal_error_handler\n"); |
2386 | vavs_local_reset(hw); |
2387 | } |
2388 | atomic_set(&hw->error_handler_run, 0); |
2389 | } |
2390 | |
2391 | static void vavs_notify_work(struct work_struct *work) |
2392 | { |
2393 | struct vdec_avs_hw_s *hw = |
2394 | container_of(work, struct vdec_avs_hw_s, notify_work); |
2395 | if (hw->fr_hint_status == VDEC_NEED_HINT) { |
2396 | avs_vf_notify_receiver(hw, PROVIDER_NAME , |
2397 | VFRAME_EVENT_PROVIDER_FR_HINT , |
2398 | (void *)((unsigned long)hw->frame_dur)); |
2399 | hw->fr_hint_status = VDEC_HINTED; |
2400 | } |
2401 | return; |
2402 | } |
2403 | |
2404 | static void avs_set_clk(struct work_struct *work) |
2405 | { |
2406 | struct vdec_avs_hw_s *hw = |
2407 | container_of(work, struct vdec_avs_hw_s, set_clk_work); |
2408 | if (hw->frame_dur > 0 && hw->saved_resolution != |
2409 | hw->frame_width * hw->frame_height * (96000 / hw->frame_dur)) { |
2410 | int fps = 96000 / hw->frame_dur; |
2411 | |
2412 | hw->saved_resolution = hw->frame_width * hw->frame_height * fps; |
2413 | if (firmware_sel == 0 && |
2414 | (debug & AVS_DEBUG_USE_FULL_SPEED)) { |
2415 | vdec_source_changed(VFORMAT_AVS, |
2416 | 4096, 2048, 60); |
2417 | } else { |
2418 | vdec_source_changed(VFORMAT_AVS, |
2419 | hw->frame_width, hw->frame_height, fps); |
2420 | } |
2421 | |
2422 | } |
2423 | } |
2424 | |
2425 | #ifdef DEBUG_MULTI_WITH_AUTOMODE |
2426 | int delay_count = 0; |
2427 | #endif |
2428 | static void vavs_put_timer_func(unsigned long arg) |
2429 | { |
2430 | struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)arg; |
2431 | struct timer_list *timer = &hw->recycle_timer; |
2432 | |
2433 | #ifndef HANDLE_AVS_IRQ |
2434 | vavs_isr(); |
2435 | #endif |
2436 | #ifdef DEBUG_MULTI_WITH_AUTOMODE |
2437 | if (delay_count > 0) { |
2438 | if (delay_count == 1) |
2439 | amvdec_start(); |
2440 | delay_count--; |
2441 | } |
2442 | #endif |
2443 | if (READ_VREG(AVS_SOS_COUNT)) { |
2444 | if (!error_recovery_mode) { |
2445 | #if 0 |
2446 | if (debug & AVS_DEBUG_OLD_ERROR_HANDLE) { |
2447 | mutex_lock(&vavs_mutex); |
2448 | pr_info("vavs fatal error reset !\n"); |
2449 | amvdec_stop(); |
2450 | #ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER |
2451 | vavs_ppmgr_reset(); |
2452 | #else |
2453 | vf_light_unreg_provider(&vavs_vf_prov); |
2454 | vavs_local_init(); |
2455 | vf_reg_provider(&vavs_vf_prov); |
2456 | #endif |
2457 | vavs_recover(); |
2458 | amvdec_start(); |
2459 | mutex_unlock(&vavs_mutex); |
2460 | } else { |
2461 | vavs_local_reset(); |
2462 | } |
2463 | #else |
2464 | if (!atomic_read(&hw->error_handler_run)) { |
2465 | atomic_set(&hw->error_handler_run, 1); |
2466 | pr_info("AVS_SOS_COUNT = %d\n", |
2467 | READ_VREG(AVS_SOS_COUNT)); |
2468 | pr_info("WP = 0x%x, RP = 0x%x, LEVEL = 0x%x, AVAIL = 0x%x, CUR_PTR = 0x%x\n", |
2469 | READ_VREG(VLD_MEM_VIFIFO_WP), |
2470 | READ_VREG(VLD_MEM_VIFIFO_RP), |
2471 | READ_VREG(VLD_MEM_VIFIFO_LEVEL), |
2472 | READ_VREG(VLD_MEM_VIFIFO_BYTES_AVAIL), |
2473 | READ_VREG(VLD_MEM_VIFIFO_CURR_PTR)); |
2474 | schedule_work(&hw->fatal_error_wd_work); |
2475 | } |
2476 | #endif |
2477 | } |
2478 | } |
2479 | #if 0 |
2480 | if (long_cabac_busy == 0 && |
2481 | error_watchdog_threshold > 0 && |
2482 | kfifo_len(&hw->display_q) == 0 && |
2483 | READ_VREG(VLD_MEM_VIFIFO_LEVEL) > |
2484 | error_watchdog_buf_threshold) { |
2485 | pr_info("newq %d dispq %d recyq %d\r\n", |
2486 | kfifo_len(&hw->newframe_q), |
2487 | kfifo_len(&hw->display_q), |
2488 | kfifo_len(&hw->recycle_q)); |
2489 | pr_info("pc %x stream buf wp %x rp %x level %x\n", |
2490 | READ_VREG(MPC_E), |
2491 | READ_VREG(VLD_MEM_VIFIFO_WP), |
2492 | READ_VREG(VLD_MEM_VIFIFO_RP), |
2493 | READ_VREG(VLD_MEM_VIFIFO_LEVEL)); |
2494 | error_watchdog_count++; |
2495 | if (error_watchdog_count >= error_watchdog_threshold) |
2496 | vavs_local_reset(); |
2497 | } else |
2498 | error_watchdog_count = 0; |
2499 | #endif |
2500 | if (radr != 0) { |
2501 | if (rval != 0) { |
2502 | WRITE_VREG(radr, rval); |
2503 | pr_info("WRITE_VREG(%x,%x)\n", radr, rval); |
2504 | } else |
2505 | pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr)); |
2506 | rval = 0; |
2507 | radr = 0; |
2508 | } |
2509 | if ((hw->ucode_pause_pos != 0) && |
2510 | (hw->ucode_pause_pos != 0xffffffff) && |
2511 | udebug_pause_pos != hw->ucode_pause_pos) { |
2512 | hw->ucode_pause_pos = 0; |
2513 | WRITE_VREG(DEBUG_REG1, 0); |
2514 | } |
2515 | |
2516 | if (!kfifo_is_empty(&hw->recycle_q) && (READ_VREG(AVS_BUFFERIN) == 0)) { |
2517 | struct vframe_s *vf; |
2518 | |
2519 | if (kfifo_get(&hw->recycle_q, &vf)) { |
2520 | if ((vf->index < hw->vf_buf_num_used) && |
2521 | (--hw->vfbuf_use[vf->index] == 0)) { |
2522 | debug_print(hw, PRINT_FLAG_DECODING, |
2523 | "%s WRITE_VREG(AVS_BUFFERIN, 0x%x) for vf index of %d\n", |
2524 | __func__, |
2525 | ~(1 << vf->index), vf->index); |
2526 | WRITE_VREG(AVS_BUFFERIN, ~(1 << vf->index)); |
2527 | vf->index = hw->vf_buf_num_used; |
2528 | } |
2529 | kfifo_put(&hw->newframe_q, |
2530 | (const struct vframe_s *)vf); |
2531 | } |
2532 | |
2533 | } |
2534 | |
2535 | schedule_work(&hw->set_clk_work); |
2536 | |
2537 | timer->expires = jiffies + PUT_INTERVAL; |
2538 | |
2539 | add_timer(timer); |
2540 | } |
2541 | |
2542 | #ifdef AVSP_LONG_CABAC |
2543 | |
2544 | static void long_cabac_do_work(struct work_struct *work) |
2545 | { |
2546 | int status = 0; |
2547 | struct vdec_avs_hw_s *hw = gw; |
2548 | #ifdef PERFORMANCE_DEBUG |
2549 | pr_info("enter %s buf level (new %d, display %d, recycle %d)\r\n", |
2550 | __func__, |
2551 | kfifo_len(&hw->newframe_q), |
2552 | kfifo_len(&hw->display_q), |
2553 | kfifo_len(&hw->recycle_q) |
2554 | ); |
2555 | #endif |
2556 | mutex_lock(&vavs_mutex); |
2557 | long_cabac_busy = 1; |
2558 | while (READ_VREG(LONG_CABAC_REQ)) { |
2559 | if (process_long_cabac() < 0) { |
2560 | status = -1; |
2561 | break; |
2562 | } |
2563 | } |
2564 | long_cabac_busy = 0; |
2565 | mutex_unlock(&vavs_mutex); |
2566 | #ifdef PERFORMANCE_DEBUG |
2567 | pr_info("exit %s buf level (new %d, display %d, recycle %d)\r\n", |
2568 | __func__, |
2569 | kfifo_len(&hw->newframe_q), |
2570 | kfifo_len(&hw->display_q), |
2571 | kfifo_len(&hw->recycle_q) |
2572 | ); |
2573 | #endif |
2574 | if (status < 0) { |
2575 | pr_info("transcoding error, local reset\r\n"); |
2576 | vavs_local_reset(hw); |
2577 | } |
2578 | |
2579 | } |
2580 | #endif |
2581 | |
2582 | #ifdef AVSP_LONG_CABAC |
2583 | static void init_avsp_long_cabac_buf(void) |
2584 | { |
2585 | #if 0 |
2586 | es_write_addr_phy = (unsigned long)codec_mm_alloc_for_dma( |
2587 | "vavs", |
2588 | PAGE_ALIGN(MAX_CODED_FRAME_SIZE)/PAGE_SIZE, |
2589 | 0, CODEC_MM_FLAGS_DMA_CPU); |
2590 | es_write_addr_virt = codec_mm_phys_to_virt(es_write_addr_phy); |
2591 | |
2592 | #elif 0 |
2593 | es_write_addr_virt = |
2594 | (void *)dma_alloc_coherent(amports_get_dma_device(), |
2595 | MAX_CODED_FRAME_SIZE, &es_write_addr_phy, |
2596 | GFP_KERNEL); |
2597 | #else |
2598 | /*es_write_addr_virt = kmalloc(MAX_CODED_FRAME_SIZE, GFP_KERNEL); |
2599 | * es_write_addr_virt = (void *)__get_free_pages(GFP_KERNEL, |
2600 | * get_order(MAX_CODED_FRAME_SIZE)); |
2601 | */ |
2602 | es_write_addr_virt = &es_write_addr[0]; |
2603 | if (es_write_addr_virt == NULL) { |
2604 | pr_err("%s: failed to alloc es_write_addr_virt buffer\n", |
2605 | __func__); |
2606 | return; |
2607 | } |
2608 | |
2609 | es_write_addr_phy = dma_map_single(amports_get_dma_device(), |
2610 | es_write_addr_virt, |
2611 | MAX_CODED_FRAME_SIZE, DMA_BIDIRECTIONAL); |
2612 | if (dma_mapping_error(amports_get_dma_device(), |
2613 | es_write_addr_phy)) { |
2614 | pr_err("%s: failed to map es_write_addr_virt buffer\n", |
2615 | __func__); |
2616 | /*kfree(es_write_addr_virt);*/ |
2617 | es_write_addr_virt = NULL; |
2618 | return; |
2619 | } |
2620 | #endif |
2621 | |
2622 | |
2623 | #ifdef BITSTREAM_READ_TMP_NO_CACHE |
2624 | bitstream_read_tmp = |
2625 | (void *)dma_alloc_coherent(amports_get_dma_device(), |
2626 | SVA_STREAM_BUF_SIZE, &bitstream_read_tmp_phy, |
2627 | GFP_KERNEL); |
2628 | |
2629 | #else |
2630 | |
2631 | bitstream_read_tmp = kmalloc(SVA_STREAM_BUF_SIZE, GFP_KERNEL); |
2632 | /*bitstream_read_tmp = (void *)__get_free_pages(GFP_KERNEL, |
2633 | *get_order(MAX_CODED_FRAME_SIZE)); |
2634 | */ |
2635 | if (bitstream_read_tmp == NULL) { |
2636 | pr_err("%s: failed to alloc bitstream_read_tmp buffer\n", |
2637 | __func__); |
2638 | return; |
2639 | } |
2640 | |
2641 | bitstream_read_tmp_phy = dma_map_single(amports_get_dma_device(), |
2642 | bitstream_read_tmp, |
2643 | SVA_STREAM_BUF_SIZE, DMA_FROM_DEVICE); |
2644 | if (dma_mapping_error(amports_get_dma_device(), |
2645 | bitstream_read_tmp_phy)) { |
2646 | pr_err("%s: failed to map rpm buffer\n", __func__); |
2647 | kfree(bitstream_read_tmp); |
2648 | bitstream_read_tmp = NULL; |
2649 | return; |
2650 | } |
2651 | #endif |
2652 | } |
2653 | #endif |
2654 | |
2655 | |
2656 | static s32 vavs_init(struct vdec_avs_hw_s *hw) |
2657 | { |
2658 | int ret, size = -1; |
2659 | struct firmware_s *fw; |
2660 | u32 fw_size = 0x1000 * 16; |
2661 | /*char *buf = vmalloc(0x1000 * 16); |
2662 | |
2663 | if (IS_ERR_OR_NULL(buf)) |
2664 | return -ENOMEM; |
2665 | */ |
2666 | fw = vmalloc(sizeof(struct firmware_s) + fw_size); |
2667 | if (IS_ERR_OR_NULL(fw)) |
2668 | return -ENOMEM; |
2669 | |
2670 | pr_info("vavs_init\n"); |
2671 | //init_timer(&hw->recycle_timer); |
2672 | |
2673 | //hw->stat |= STAT_TIMER_INIT; |
2674 | |
2675 | amvdec_enable(); |
2676 | |
2677 | //vdec_enable_DMC(NULL); |
2678 | |
2679 | vavs_local_init(hw); |
2680 | |
2681 | if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM) |
2682 | size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data); |
2683 | else { |
2684 | if (firmware_sel == 1) |
2685 | size = get_firmware_data(VIDEO_DEC_AVS_NOCABAC, fw->data); |
2686 | #ifdef AVSP_LONG_CABAC |
2687 | else { |
2688 | init_avsp_long_cabac_buf(); |
2689 | size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data); |
2690 | } |
2691 | #endif |
2692 | } |
2693 | |
2694 | if (size < 0) { |
2695 | amvdec_disable(); |
2696 | pr_err("get firmware fail."); |
2697 | vfree(fw); |
2698 | return -1; |
2699 | } |
2700 | |
2701 | fw->len = size; |
2702 | hw->fw = fw; |
2703 | |
2704 | if (hw->m_ins_flag) { |
2705 | init_timer(&hw->check_timer); |
2706 | hw->check_timer.data = (ulong) hw; |
2707 | hw->check_timer.function = check_timer_func; |
2708 | hw->check_timer.expires = jiffies + CHECK_INTERVAL; |
2709 | |
2710 | |
2711 | //add_timer(&hw->check_timer); |
2712 | hw->stat |= STAT_TIMER_ARM; |
2713 | |
2714 | INIT_WORK(&hw->work, vavs_work); |
2715 | |
2716 | hw->fw = fw; |
2717 | return 0; |
2718 | } |
2719 | |
2720 | if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM) |
2721 | ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, fw->data); |
2722 | else if (firmware_sel == 1) |
2723 | ret = amvdec_loadmc_ex(VFORMAT_AVS, "avs_no_cabac", fw->data); |
2724 | else |
2725 | ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, fw->data); |
2726 | |
2727 | if (ret < 0) { |
2728 | amvdec_disable(); |
2729 | /*vfree(buf);*/ |
2730 | pr_err("AVS: the %s fw loading failed, err: %x\n", |
2731 | tee_enabled() ? "TEE" : "local", ret); |
2732 | return -EBUSY; |
2733 | } |
2734 | |
2735 | /*vfree(buf);*/ |
2736 | |
2737 | hw->stat |= STAT_MC_LOAD; |
2738 | |
2739 | |
2740 | /* enable AMRISC side protocol */ |
2741 | ret = vavs_prot_init(hw); |
2742 | if (ret < 0) |
2743 | return ret; |
2744 | |
2745 | #ifdef HANDLE_AVS_IRQ |
2746 | if (vdec_request_irq(VDEC_IRQ_1, vavs_isr, |
2747 | "vavs-irq", (void *)hw)) { |
2748 | amvdec_disable(); |
2749 | pr_info("vavs irq register error.\n"); |
2750 | return -ENOENT; |
2751 | } |
2752 | #endif |
2753 | |
2754 | hw->stat |= STAT_ISR_REG; |
2755 | |
2756 | #ifdef CONFIG_AMLOGIC_POST_PROCESS_MANAGER |
2757 | vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, hw); |
2758 | vf_reg_provider(&vavs_vf_prov); |
2759 | avs_vf_notify_receiver(hw, PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); |
2760 | #else |
2761 | vf_provider_init(&vavs_vf_prov, PROVIDER_NAME, &vavs_vf_provider, hw); |
2762 | vf_reg_provider(&vavs_vf_prov); |
2763 | #endif |
2764 | |
2765 | if (hw->vavs_amstream_dec_info.rate != 0) { |
2766 | if (!hw->is_reset) |
2767 | avs_vf_notify_receiver(hw, PROVIDER_NAME, |
2768 | VFRAME_EVENT_PROVIDER_FR_HINT, |
2769 | (void *)((unsigned long) |
2770 | hw->vavs_amstream_dec_info.rate)); |
2771 | hw->fr_hint_status = VDEC_HINTED; |
2772 | } else |
2773 | hw->fr_hint_status = VDEC_NEED_HINT; |
2774 | |
2775 | hw->stat |= STAT_VF_HOOK; |
2776 | |
2777 | hw->recycle_timer.data = (ulong)(hw); |
2778 | hw->recycle_timer.function = vavs_put_timer_func; |
2779 | hw->recycle_timer.expires = jiffies + PUT_INTERVAL; |
2780 | |
2781 | add_timer(&hw->recycle_timer); |
2782 | |
2783 | hw->stat |= STAT_TIMER_ARM; |
2784 | |
2785 | #ifdef AVSP_LONG_CABAC |
2786 | if (firmware_sel == 0) |
2787 | INIT_WORK(&long_cabac_wd_work, long_cabac_do_work); |
2788 | #endif |
2789 | vdec_source_changed(VFORMAT_AVS, |
2790 | 1920, 1080, 30); |
2791 | #ifdef DEBUG_MULTI_WITH_AUTOMODE |
2792 | if (start_decoding_delay == 0) |
2793 | amvdec_start(); |
2794 | else |
2795 | delay_count = start_decoding_delay/10; |
2796 | #else |
2797 | amvdec_start(); |
2798 | #endif |
2799 | hw->stat |= STAT_VDEC_RUN; |
2800 | return 0; |
2801 | } |
2802 | |
2803 | static int amvdec_avs_probe(struct platform_device *pdev) |
2804 | { |
2805 | struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; |
2806 | struct vdec_avs_hw_s *hw = NULL; |
2807 | |
2808 | if (pdata == NULL) { |
2809 | pr_info("amvdec_avs memory resource undefined.\n"); |
2810 | return -EFAULT; |
2811 | } |
2812 | |
2813 | hw = (struct vdec_avs_hw_s *)devm_kzalloc(&pdev->dev, |
2814 | sizeof(struct vdec_avs_hw_s), GFP_KERNEL); |
2815 | if (hw == NULL) { |
2816 | pr_info("\nammvdec_avs decoder driver alloc failed\n"); |
2817 | return -ENOMEM; |
2818 | } |
2819 | pdata->private = hw; |
2820 | ghw = hw; |
2821 | atomic_set(&hw->error_handler_run, 0); |
2822 | hw->m_ins_flag = 0; |
2823 | |
2824 | if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans) |
2825 | firmware_sel = 1; |
2826 | |
2827 | if (firmware_sel == 1) { |
2828 | #ifndef USE_DYNAMIC_BUF_NUM |
2829 | vf_buf_num = 4; |
2830 | #endif |
2831 | canvas_base = 0; |
2832 | canvas_num = 3; |
2833 | } else { |
2834 | |
2835 | canvas_base = 128; |
2836 | canvas_num = 2; /*NV21*/ |
2837 | } |
2838 | |
2839 | |
2840 | if (pdata->sys_info) |
2841 | hw->vavs_amstream_dec_info = *pdata->sys_info; |
2842 | |
2843 | pr_info("%s (%d,%d) %d\n", __func__, hw->vavs_amstream_dec_info.width, |
2844 | hw->vavs_amstream_dec_info.height, hw->vavs_amstream_dec_info.rate); |
2845 | |
2846 | pdata->dec_status = vavs_dec_status; |
2847 | pdata->set_isreset = vavs_set_isreset; |
2848 | hw->is_reset = 0; |
2849 | |
2850 | pdata->user_data_read = NULL; |
2851 | pdata->reset_userdata_fifo = NULL; |
2852 | |
2853 | vavs_vdec_info_init(hw); |
2854 | |
2855 | #ifdef ENABLE_USER_DATA |
2856 | if (NULL == hw->user_data_buffer) { |
2857 | hw->user_data_buffer = |
2858 | dma_alloc_coherent(amports_get_dma_device(), |
2859 | USER_DATA_SIZE, |
2860 | &hw->user_data_buffer_phys, GFP_KERNEL); |
2861 | if (!hw->user_data_buffer) { |
2862 | pr_info("%s: Can not allocate hw->user_data_buffer\n", |
2863 | __func__); |
2864 | return -ENOMEM; |
2865 | } |
2866 | pr_debug("hw->user_data_buffer = 0x%p, hw->user_data_buffer_phys = 0x%x\n", |
2867 | hw->user_data_buffer, (u32)hw->user_data_buffer_phys); |
2868 | } |
2869 | #endif |
2870 | INIT_WORK(&hw->set_clk_work, avs_set_clk); |
2871 | if (vavs_init(hw) < 0) { |
2872 | pr_info("amvdec_avs init failed.\n"); |
2873 | kfree(hw->gvs); |
2874 | hw->gvs = NULL; |
2875 | pdata->dec_status = NULL; |
2876 | if (hw->fw) |
2877 | vfree(hw->fw); |
2878 | hw->fw = NULL; |
2879 | return -ENODEV; |
2880 | } |
2881 | /*vdec = pdata;*/ |
2882 | |
2883 | INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler); |
2884 | atomic_set(&hw->error_handler_run, 0); |
2885 | #ifdef ENABLE_USER_DATA |
2886 | INIT_WORK(&hw->userdata_push_work, userdata_push_do_work); |
2887 | #endif |
2888 | INIT_WORK(&hw->notify_work, vavs_notify_work); |
2889 | |
2890 | return 0; |
2891 | } |
2892 | |
2893 | static int amvdec_avs_remove(struct platform_device *pdev) |
2894 | { |
2895 | struct vdec_avs_hw_s *hw = ghw; |
2896 | |
2897 | cancel_work_sync(&hw->fatal_error_wd_work); |
2898 | atomic_set(&hw->error_handler_run, 0); |
2899 | #ifdef ENABLE_USER_DATA |
2900 | cancel_work_sync(&hw->userdata_push_work); |
2901 | #endif |
2902 | cancel_work_sync(&hw->notify_work); |
2903 | cancel_work_sync(&hw->set_clk_work); |
2904 | if (hw->stat & STAT_VDEC_RUN) { |
2905 | amvdec_stop(); |
2906 | hw->stat &= ~STAT_VDEC_RUN; |
2907 | } |
2908 | |
2909 | if (hw->stat & STAT_ISR_REG) { |
2910 | vdec_free_irq(VDEC_IRQ_1, (void *)vavs_dec_id); |
2911 | hw->stat &= ~STAT_ISR_REG; |
2912 | } |
2913 | |
2914 | if (hw->stat & STAT_TIMER_ARM) { |
2915 | del_timer_sync(&hw->recycle_timer); |
2916 | hw->stat &= ~STAT_TIMER_ARM; |
2917 | } |
2918 | #ifdef AVSP_LONG_CABAC |
2919 | if (firmware_sel == 0) { |
2920 | mutex_lock(&vavs_mutex); |
2921 | cancel_work_sync(&long_cabac_wd_work); |
2922 | mutex_unlock(&vavs_mutex); |
2923 | |
2924 | if (es_write_addr_virt) { |
2925 | #if 0 |
2926 | codec_mm_free_for_dma("vavs", es_write_addr_phy); |
2927 | #else |
2928 | dma_unmap_single(amports_get_dma_device(), |
2929 | es_write_addr_phy, |
2930 | MAX_CODED_FRAME_SIZE, DMA_FROM_DEVICE); |
2931 | /*kfree(es_write_addr_virt);*/ |
2932 | es_write_addr_virt = NULL; |
2933 | #endif |
2934 | } |
2935 | |
2936 | #ifdef BITSTREAM_READ_TMP_NO_CACHE |
2937 | if (bitstream_read_tmp) { |
2938 | dma_free_coherent(amports_get_dma_device(), |
2939 | SVA_STREAM_BUF_SIZE, bitstream_read_tmp, |
2940 | bitstream_read_tmp_phy); |
2941 | bitstream_read_tmp = NULL; |
2942 | } |
2943 | #else |
2944 | if (bitstream_read_tmp) { |
2945 | dma_unmap_single(amports_get_dma_device(), |
2946 | bitstream_read_tmp_phy, |
2947 | SVA_STREAM_BUF_SIZE, DMA_FROM_DEVICE); |
2948 | kfree(bitstream_read_tmp); |
2949 | bitstream_read_tmp = NULL; |
2950 | } |
2951 | #endif |
2952 | } |
2953 | #endif |
2954 | if (hw->stat & STAT_VF_HOOK) { |
2955 | if (hw->fr_hint_status == VDEC_HINTED && !hw->is_reset) |
2956 | avs_vf_notify_receiver(hw, PROVIDER_NAME, |
2957 | VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); |
2958 | hw->fr_hint_status = VDEC_NO_NEED_HINT; |
2959 | vf_unreg_provider(&vavs_vf_prov); |
2960 | hw->stat &= ~STAT_VF_HOOK; |
2961 | } |
2962 | |
2963 | #ifdef ENABLE_USER_DATA |
2964 | if (hw->user_data_buffer != NULL) { |
2965 | dma_free_coherent( |
2966 | amports_get_dma_device(), |
2967 | USER_DATA_SIZE, |
2968 | hw->user_data_buffer, |
2969 | hw->user_data_buffer_phys); |
2970 | hw->user_data_buffer = NULL; |
2971 | hw->user_data_buffer_phys = 0; |
2972 | } |
2973 | #endif |
2974 | |
2975 | if (hw->fw) { |
2976 | vfree(hw->fw); |
2977 | hw->fw = NULL; |
2978 | } |
2979 | |
2980 | amvdec_disable(); |
2981 | //vdec_disable_DMC(NULL); |
2982 | |
2983 | hw->pic_type = 0; |
2984 | if (hw->mm_blk_handle) { |
2985 | decoder_bmmu_box_free(hw->mm_blk_handle); |
2986 | hw->mm_blk_handle = NULL; |
2987 | } |
2988 | #ifdef DEBUG_PTS |
2989 | pr_debug("pts hit %d, pts missed %d, i hit %d, missed %d\n", hw->pts_hit, |
2990 | hw->pts_missed, hw->pts_i_hit, hw->pts_i_missed); |
2991 | pr_debug("total frame %d, hw->avi_flag %d, rate %d\n", hw->total_frame, hw->avi_flag, |
2992 | hw->vavs_amstream_dec_info.rate); |
2993 | #endif |
2994 | kfree(hw->gvs); |
2995 | hw->gvs = NULL; |
2996 | |
2997 | return 0; |
2998 | } |
2999 | |
3000 | /****************************************/ |
3001 | |
3002 | static struct platform_driver amvdec_avs_driver = { |
3003 | .probe = amvdec_avs_probe, |
3004 | .remove = amvdec_avs_remove, |
3005 | .driver = { |
3006 | .name = DRIVER_NAME, |
3007 | } |
3008 | }; |
3009 | |
3010 | static void recycle_frames(struct vdec_avs_hw_s *hw); |
3011 | |
3012 | static unsigned long run_ready(struct vdec_s *vdec, unsigned long mask) |
3013 | { |
3014 | struct vdec_avs_hw_s *hw = |
3015 | (struct vdec_avs_hw_s *)vdec->private; |
3016 | int ret = 1; |
3017 | unsigned buf_busy_mask = (1 << hw->vf_buf_num_used) - 1; |
3018 | #ifdef DEBUG_MULTI_FRAME_INS |
3019 | if ((DECODE_ID(hw) == 0) && run_count[0] > run_count[1] && |
3020 | run_count[1] < max_run_count[1]) |
3021 | return 0; |
3022 | |
3023 | if ((DECODE_ID(hw) == 1) && run_count[1] >= run_count[0] && |
3024 | run_count[0] < max_run_count[0]) |
3025 | return 0; |
3026 | |
3027 | if (max_run_count[DECODE_ID(hw)] > 0 && |
3028 | run_count[DECODE_ID(hw)] >= max_run_count[DECODE_ID(hw)]) |
3029 | return 0; |
3030 | #endif |
3031 | |
3032 | if (hw->reset_decode_flag == 0 && |
3033 | hw->again_flag == 0 && |
3034 | (hw->buf_status & buf_busy_mask) == buf_busy_mask) { |
3035 | recycle_frames(hw); |
3036 | if (hw->buf_recycle_status == 0) |
3037 | ret = 0; |
3038 | } |
3039 | |
3040 | if (again_threshold > 0 && |
3041 | hw->pre_parser_wr_ptr != 0 && |
3042 | hw->again_flag && |
3043 | (!vdec_frame_based(vdec))) { |
3044 | u32 parser_wr_ptr = |
3045 | READ_PARSER_REG(PARSER_VIDEO_WP); |
3046 | if (parser_wr_ptr >= hw->pre_parser_wr_ptr && |
3047 | (parser_wr_ptr - hw->pre_parser_wr_ptr) < |
3048 | again_threshold) { |
3049 | int r = vdec_sync_input(vdec); |
3050 | debug_print(hw, PRINT_FLAG_VFRAME_DETAIL, |
3051 | "%s buf lelvel:%x\n", __func__, r); |
3052 | ret = 0; |
3053 | } |
3054 | } |
3055 | |
3056 | if (ret) |
3057 | hw->not_run_ready = 0; |
3058 | else |
3059 | hw->not_run_ready++; |
3060 | |
3061 | if (ret != 0) { |
3062 | if (vdec->parallel_dec == 1) |
3063 | return (unsigned long)(CORE_MASK_VDEC_1); |
3064 | else |
3065 | return (unsigned long)(CORE_MASK_VDEC_1 | CORE_MASK_HEVC); |
3066 | } else |
3067 | return 0; |
3068 | } |
3069 | |
3070 | static void vavs_work(struct work_struct *work) |
3071 | { |
3072 | struct vdec_avs_hw_s *hw = |
3073 | container_of(work, struct vdec_avs_hw_s, work); |
3074 | struct vdec_s *vdec = hw_to_vdec(hw); |
3075 | if (hw->dec_result != DEC_RESULT_AGAIN) |
3076 | debug_print(hw, PRINT_FLAG_RUN_FLOW, |
3077 | "ammvdec_avs: vavs_work,result=%d,status=%d\n", |
3078 | hw->dec_result, hw_to_vdec(hw)->next_status); |
3079 | hw->again_flag = 0; |
3080 | if (hw->dec_result == DEC_RESULT_USERDATA) { |
3081 | userdata_push_process(hw); |
3082 | return; |
3083 | } else if (hw->dec_result == DEC_RESULT_DONE) { |
3084 | hw->buf_recycle_status = 0; |
3085 | if (!hw->ctx_valid) |
3086 | hw->ctx_valid = 1; |
3087 | #ifdef DEBUG_MULTI_FRAME_INS |
3088 | msleep(delay); |
3089 | #endif |
3090 | vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); |
3091 | } else if (hw->dec_result == DEC_RESULT_AGAIN |
3092 | && (hw_to_vdec(hw)->next_status != |
3093 | VDEC_STATUS_DISCONNECTED)) { |
3094 | /* |
3095 | stream base: stream buf empty or timeout |
3096 | frame base: vdec_prepare_input fail |
3097 | */ |
3098 | hw->again_flag = 1; |
3099 | if (!vdec_has_more_input(hw_to_vdec(hw))) { |
3100 | hw->dec_result = DEC_RESULT_EOS; |
3101 | vdec_schedule_work(&hw->work); |
3102 | return; |
3103 | } |
3104 | } else if (hw->dec_result == DEC_RESULT_GET_DATA |
3105 | && (hw_to_vdec(hw)->next_status != |
3106 | VDEC_STATUS_DISCONNECTED)) { |
3107 | if (!vdec_has_more_input(hw_to_vdec(hw))) { |
3108 | hw->dec_result = DEC_RESULT_EOS; |
3109 | vdec_schedule_work(&hw->work); |
3110 | return; |
3111 | } |
3112 | debug_print(hw, PRINT_FLAG_VLD_DETAIL, |
3113 | "%s DEC_RESULT_GET_DATA %x %x %x\n", |
3114 | __func__, |
3115 | READ_VREG(VLD_MEM_VIFIFO_LEVEL), |
3116 | READ_VREG(VLD_MEM_VIFIFO_WP), |
3117 | READ_VREG(VLD_MEM_VIFIFO_RP)); |
3118 | vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); |
3119 | vdec_clean_input(hw_to_vdec(hw)); |
3120 | return; |
3121 | } else if (hw->dec_result == DEC_RESULT_FORCE_EXIT) { |
3122 | debug_print(hw, PRINT_FLAG_ERROR, |
3123 | "%s: force exit\n", __func__); |
3124 | if (hw->stat & STAT_ISR_REG) { |
3125 | amvdec_stop(); |
3126 | /*disable mbox interrupt */ |
3127 | WRITE_VREG(ASSIST_MBOX1_MASK, 0); |
3128 | vdec_free_irq(VDEC_IRQ_1, (void *)hw); |
3129 | hw->stat &= ~STAT_ISR_REG; |
3130 | } |
3131 | } else if (hw->dec_result == DEC_RESULT_EOS) { |
3132 | debug_print(hw, PRINT_FLAG_DECODING, |
3133 | "%s: end of stream\n", __func__); |
3134 | if (hw->stat & STAT_VDEC_RUN) { |
3135 | amvdec_stop(); |
3136 | hw->stat &= ~STAT_VDEC_RUN; |
3137 | } |
3138 | hw->eos = 1; |
3139 | vdec_vframe_dirty(hw_to_vdec(hw), hw->chunk); |
3140 | vdec_clean_input(hw_to_vdec(hw)); |
3141 | } |
3142 | if (hw->stat & STAT_VDEC_RUN) { |
3143 | #if DEBUG_MULTI_FLAG == 1 |
3144 | #else |
3145 | amvdec_stop(); |
3146 | #endif |
3147 | hw->stat &= ~STAT_VDEC_RUN; |
3148 | } |
3149 | /*wait_vmmpeg12_search_done(hw);*/ |
3150 | if (hw->stat & STAT_TIMER_ARM) { |
3151 | del_timer_sync(&hw->check_timer); |
3152 | hw->stat &= ~STAT_TIMER_ARM; |
3153 | } |
3154 | |
3155 | if (vdec->parallel_dec == 1) |
3156 | vdec_core_finish_run(hw_to_vdec(hw), CORE_MASK_VDEC_1); |
3157 | else |
3158 | vdec_core_finish_run(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC); |
3159 | |
3160 | if (hw->vdec_cb) { |
3161 | hw->vdec_cb(hw_to_vdec(hw), hw->vdec_cb_arg); |
3162 | debug_print(hw, 0x80000, |
3163 | "%s:\n", __func__); |
3164 | } |
3165 | } |
3166 | |
3167 | |
3168 | static void reset_process_time(struct vdec_avs_hw_s *hw) |
3169 | { |
3170 | if (!hw->m_ins_flag) |
3171 | return; |
3172 | if (hw->start_process_time) { |
3173 | unsigned process_time = |
3174 | 1000 * (jiffies - hw->start_process_time) / HZ; |
3175 | hw->start_process_time = 0; |
3176 | if (process_time > max_process_time[DECODE_ID(hw)]) |
3177 | max_process_time[DECODE_ID(hw)] = process_time; |
3178 | } |
3179 | } |
3180 | static void start_process_time(struct vdec_avs_hw_s *hw) |
3181 | { |
3182 | hw->decode_timeout_count = 2; |
3183 | hw->start_process_time = jiffies; |
3184 | } |
3185 | |
3186 | static void handle_decoding_error(struct vdec_avs_hw_s *hw) |
3187 | { |
3188 | int i; |
3189 | unsigned long flags; |
3190 | struct vframe_s *vf; |
3191 | spin_lock_irqsave(&lock, flags); |
3192 | for (i = 0; i < VF_POOL_SIZE; i++) { |
3193 | vf = &hw->vfpool[i].vf; |
3194 | if (vf->index < hw->vf_buf_num_used) { |
3195 | hw->vfpool[i].detached = 1; |
3196 | hw->vfbuf_use[vf->index] = 0; |
3197 | } |
3198 | } |
3199 | if (error_handle_policy & 0x2) { |
3200 | while (!kfifo_is_empty(&hw->display_q)) { |
3201 | if (kfifo_get(&hw->display_q, &vf)) { |
3202 | if (buf_of_vf(vf)->detached !=0) { |
3203 | debug_print(hw, PRINT_FLAG_DECODING, |
3204 | "%s recycle %d => newframe_q\n", |
3205 | __func__, |
3206 | vf->index); |
3207 | vf->index = hw->vf_buf_num_used; |
3208 | buf_of_vf(vf)->detached = 0; |
3209 | kfifo_put(&hw->newframe_q, |
3210 | (const struct vframe_s *)vf); |
3211 | } |
3212 | } |
3213 | |
3214 | } |
3215 | } |
3216 | clear_pts_buf(hw); |
3217 | hw->decode_pic_count = 0; |
3218 | hw->reset_decode_flag = 1; |
3219 | hw->pre_parser_wr_ptr = 0; |
3220 | hw->buf_status = 0; |
3221 | hw->throw_pb_flag = 1; |
3222 | spin_unlock_irqrestore(&lock, flags); |
3223 | } |
3224 | |
3225 | static void timeout_process(struct vdec_avs_hw_s *hw) |
3226 | { |
3227 | struct vdec_s *vdec = hw_to_vdec(hw); |
3228 | amvdec_stop(); |
3229 | if (error_handle_policy & 0x1) { |
3230 | handle_decoding_error(hw); |
3231 | } else { |
3232 | vavs_save_regs(hw); |
3233 | |
3234 | if (hw->decode_pic_count == 0) |
3235 | hw->decode_pic_count++; |
3236 | } |
3237 | hw->dec_result = DEC_RESULT_DONE; |
3238 | |
3239 | debug_print(hw, PRINT_FLAG_ERROR, |
3240 | "%s decoder timeout, status=%d, level=%d\n", |
3241 | __func__, vdec->status, READ_VREG(VLD_MEM_VIFIFO_LEVEL)); |
3242 | reset_process_time(hw); |
3243 | vdec_schedule_work(&hw->work); |
3244 | } |
3245 | |
3246 | |
3247 | static void recycle_frame_bufferin(struct vdec_avs_hw_s *hw) |
3248 | { |
3249 | if (!kfifo_is_empty(&hw->recycle_q) && (READ_VREG(AVS_BUFFERIN) == 0)) { |
3250 | struct vframe_s *vf; |
3251 | |
3252 | if (kfifo_get(&hw->recycle_q, &vf)) { |
3253 | if (buf_of_vf(vf)->detached) { |
3254 | debug_print(hw, 0, |
3255 | "%s recycle detached vf, index=%d detched %d used %d\n", |
3256 | __func__, vf->index, |
3257 | buf_of_vf(vf)->detached, |
3258 | hw->vfbuf_use[vf->index]); |
3259 | } |
3260 | if ((vf->index < hw->vf_buf_num_used) && |
3261 | (buf_of_vf(vf)->detached == 0) && |
3262 | (--hw->vfbuf_use[vf->index] == 0)) { |
3263 | hw->buf_recycle_status |= (1 << vf->index); |
3264 | WRITE_VREG(AVS_BUFFERIN, ~(1 << vf->index)); |
3265 | debug_print(hw, PRINT_FLAG_DECODING, |
3266 | "%s WRITE_VREG(AVS_BUFFERIN, 0x%x) for vf index of %d => buf_recycle_status 0x%x\n", |
3267 | __func__, |
3268 | READ_VREG(AVS_BUFFERIN), vf->index, |
3269 | hw->buf_recycle_status); |
3270 | } |
3271 | vf->index = hw->vf_buf_num_used; |
3272 | buf_of_vf(vf)->detached = 0; |
3273 | kfifo_put(&hw->newframe_q, |
3274 | (const struct vframe_s *)vf); |
3275 | } |
3276 | |
3277 | } |
3278 | |
3279 | } |
3280 | |
3281 | static void recycle_frames(struct vdec_avs_hw_s *hw) |
3282 | { |
3283 | while (!kfifo_is_empty(&hw->recycle_q)) { |
3284 | struct vframe_s *vf; |
3285 | |
3286 | if (kfifo_get(&hw->recycle_q, &vf)) { |
3287 | if (buf_of_vf(vf)->detached) { |
3288 | debug_print(hw, 0, |
3289 | "%s recycle detached vf, index=%d detched %d used %d\n", |
3290 | __func__, vf->index, |
3291 | buf_of_vf(vf)->detached, |
3292 | hw->vfbuf_use[vf->index]); |
3293 | } |
3294 | |
3295 | |
3296 | if ((vf->index < hw->vf_buf_num_used) && |
3297 | (buf_of_vf(vf)->detached == 0) && |
3298 | (--hw->vfbuf_use[vf->index] == 0)) { |
3299 | hw->buf_recycle_status |= (1 << vf->index); |
3300 | debug_print(hw, PRINT_FLAG_DECODING, |
3301 | "%s for vf index of %d => buf_recycle_status 0x%x\n", |
3302 | __func__, |
3303 | vf->index, |
3304 | hw->buf_recycle_status); |
3305 | } |
3306 | vf->index = hw->vf_buf_num_used; |
3307 | buf_of_vf(vf)->detached = 0; |
3308 | kfifo_put(&hw->newframe_q, |
3309 | (const struct vframe_s *)vf); |
3310 | } |
3311 | |
3312 | } |
3313 | |
3314 | } |
3315 | |
3316 | |
3317 | static void check_timer_func(unsigned long arg) |
3318 | { |
3319 | struct vdec_avs_hw_s *hw = (struct vdec_avs_hw_s *)arg; |
3320 | struct vdec_s *vdec = hw_to_vdec(hw); |
3321 | unsigned int timeout_val = decode_timeout_val; |
3322 | unsigned long flags; |
3323 | |
3324 | if (hw->m_ins_flag && |
3325 | (debug & |
3326 | DEBUG_WAIT_DECODE_DONE_WHEN_STOP) == 0 && |
3327 | vdec->next_status == |
3328 | VDEC_STATUS_DISCONNECTED) { |
3329 | hw->dec_result = DEC_RESULT_FORCE_EXIT; |
3330 | vdec_schedule_work(&hw->work); |
3331 | debug_print(hw, |
3332 | 0, "vdec requested to be disconnected\n"); |
3333 | return; |
3334 | } |
3335 | |
3336 | /*recycle*/ |
3337 | if (!hw->m_ins_flag || |
3338 | hw->dec_result == DEC_RESULT_NONE || |
3339 | hw->dec_result == DEC_RESULT_USERDATA) { |
3340 | spin_lock_irqsave(&lock, flags); |
3341 | recycle_frame_bufferin(hw); |
3342 | spin_unlock_irqrestore(&lock, flags); |
3343 | } |
3344 | |
3345 | if (hw->m_ins_flag) { |
3346 | if ((READ_VREG(AV_SCRATCH_5) & 0xf) != 0 && |
3347 | (READ_VREG(AV_SCRATCH_5) & 0xff00) != 0){ |
3348 | /*ucode buffer empty*/ |
3349 | if ((kfifo_len(&hw->recycle_q) == 0) && |
3350 | (kfifo_len(&hw->display_q) == 0)) { |
3351 | debug_print(hw, |
3352 | 0, "AV_SCRATCH_5=0x%x, recover ucode buffer_status\n", |
3353 | READ_VREG(AV_SCRATCH_5)); |
3354 | WRITE_VREG(AV_SCRATCH_5, 0x10); |
3355 | /*let ucode to recover buffer_status*/ |
3356 | } |
3357 | } |
3358 | } |
3359 | if (radr != 0) { |
3360 | if (rval != 0) { |
3361 | WRITE_VREG(radr, rval); |
3362 | pr_info("WRITE_VREG(%x,%x)\n", radr, rval); |
3363 | } else |
3364 | pr_info("READ_VREG(%x)=%x\n", radr, READ_VREG(radr)); |
3365 | rval = 0; |
3366 | radr = 0; |
3367 | } |
3368 | |
3369 | if (udebug_flag != hw->old_udebug_flag) { |
3370 | WRITE_VREG(DECODE_STOP_POS, udebug_flag); |
3371 | hw->old_udebug_flag = udebug_flag; |
3372 | } |
3373 | if (dbg_cmd != 0) { |
3374 | if (dbg_cmd == 1) { |
3375 | int r = vdec_sync_input(vdec); |
3376 | dbg_cmd = 0; |
3377 | pr_info( |
3378 | "vdec_sync_input=>0x%x, (lev %x, wp %x rp %x, prp %x, pwp %x)\n", |
3379 | r, |
3380 | READ_VREG(VLD_MEM_VIFIFO_LEVEL), |
3381 | READ_VREG(VLD_MEM_VIFIFO_WP), |
3382 | READ_VREG(VLD_MEM_VIFIFO_RP), |
3383 | READ_PARSER_REG(PARSER_VIDEO_RP), |
3384 | READ_PARSER_REG(PARSER_VIDEO_WP)); |
3385 | } |
3386 | } |
3387 | |
3388 | if ((debug & DEBUG_FLAG_DISABLE_TIMEOUT) == 0 && |
3389 | (timeout_val > 0) && |
3390 | (hw->start_process_time > 0) && |
3391 | ((1000 * (jiffies - hw->start_process_time) / HZ) |
3392 | > timeout_val)) { |
3393 | if (hw->last_vld_level == READ_VREG(VLD_MEM_VIFIFO_LEVEL)) { |
3394 | if (hw->decode_timeout_count > 0) |
3395 | hw->decode_timeout_count--; |
3396 | if (hw->decode_timeout_count == 0) |
3397 | timeout_process(hw); |
3398 | } |
3399 | hw->last_vld_level = READ_VREG(VLD_MEM_VIFIFO_LEVEL); |
3400 | } |
3401 | |
3402 | if (READ_VREG(AVS_SOS_COUNT)) { |
3403 | if (!error_recovery_mode) { |
3404 | amvdec_stop(); |
3405 | if (error_handle_policy & 0x1) { |
3406 | handle_decoding_error(hw); |
3407 | } else { |
3408 | vavs_save_regs(hw); |
3409 | |
3410 | if (hw->decode_pic_count == 0) |
3411 | hw->decode_pic_count++; |
3412 | } |
3413 | hw->dec_result = DEC_RESULT_DONE; |
3414 | |
3415 | debug_print(hw, PRINT_FLAG_ERROR, |
3416 | "%s decoder error, status=%d, level=%d, AVS_SOS_COUNT=0x%x\n", |
3417 | __func__, vdec->status, READ_VREG(VLD_MEM_VIFIFO_LEVEL), |
3418 | READ_VREG(AVS_SOS_COUNT)); |
3419 | reset_process_time(hw); |
3420 | vdec_schedule_work(&hw->work); |
3421 | } |
3422 | } |
3423 | |
3424 | if ((hw->ucode_pause_pos != 0) && |
3425 | (hw->ucode_pause_pos != 0xffffffff) && |
3426 | udebug_pause_pos != hw->ucode_pause_pos) { |
3427 | hw->ucode_pause_pos = 0; |
3428 | WRITE_VREG(DEBUG_REG1, 0); |
3429 | } |
3430 | |
3431 | if (vdec->next_status == VDEC_STATUS_DISCONNECTED) { |
3432 | hw->dec_result = DEC_RESULT_FORCE_EXIT; |
3433 | vdec_schedule_work(&hw->work); |
3434 | pr_info("vdec requested to be disconnected\n"); |
3435 | return; |
3436 | } |
3437 | |
3438 | mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL); |
3439 | } |
3440 | |
3441 | static int avs_hw_ctx_restore(struct vdec_avs_hw_s *hw) |
3442 | { |
3443 | /*int r = 0;*/ |
3444 | vavs_prot_init(hw); |
3445 | |
3446 | return 0; |
3447 | } |
3448 | |
3449 | static unsigned char get_data_check_sum |
3450 | (struct vdec_avs_hw_s *hw, int size) |
3451 | { |
3452 | int jj; |
3453 | int sum = 0; |
3454 | u8 *data = NULL; |
3455 | |
3456 | if (!hw->chunk->block->is_mapped) |
3457 | data = codec_mm_vmap(hw->chunk->block->start + |
3458 | hw->chunk->offset, size); |
3459 | else |
3460 | data = ((u8 *)hw->chunk->block->start_virt) + |
3461 | hw->chunk->offset; |
3462 | |
3463 | for (jj = 0; jj < size; jj++) |
3464 | sum += data[jj]; |
3465 | |
3466 | if (!hw->chunk->block->is_mapped) |
3467 | codec_mm_unmap_phyaddr(data); |
3468 | return sum; |
3469 | } |
3470 | |
3471 | static void run(struct vdec_s *vdec, unsigned long mask, |
3472 | void (*callback)(struct vdec_s *, void *), |
3473 | void *arg) |
3474 | { |
3475 | struct vdec_avs_hw_s *hw = |
3476 | (struct vdec_avs_hw_s *)vdec->private; |
3477 | int save_reg = READ_VREG(POWER_CTL_VLD); |
3478 | int size, ret; |
3479 | /* reset everything except DOS_TOP[1] and APB_CBUS[0]*/ |
3480 | |
3481 | hw->pre_parser_wr_ptr = |
3482 | READ_PARSER_REG(PARSER_VIDEO_WP); |
3483 | |
3484 | #if 1 |
3485 | #if DEBUG_MULTI_FLAG > 0 |
3486 | if (hw->decode_pic_count == 0) { |
3487 | #endif |
3488 | WRITE_VREG(DOS_SW_RESET0, 0xfffffff0); |
3489 | WRITE_VREG(DOS_SW_RESET0, 0); |
3490 | WRITE_VREG(POWER_CTL_VLD, save_reg); |
3491 | hw->run_count++; |
3492 | run_count[DECODE_ID(hw)] = hw->run_count; |
3493 | vdec_reset_core(vdec); |
3494 | #if DEBUG_MULTI_FLAG > 0 |
3495 | } |
3496 | #endif |
3497 | #else |
3498 | vdec_reset_core(vdec); |
3499 | #endif |
3500 | hw->vdec_cb_arg = arg; |
3501 | hw->vdec_cb = callback; |
3502 | |
3503 | size = vdec_prepare_input(vdec, &hw->chunk); |
3504 | if (debug & DEBUG_FLAG_PREPARE_MORE_INPUT) { |
3505 | if (size < start_decode_buf_level) { |
3506 | /*debug_print(hw, PRINT_FLAG_VLD_DETAIL, |
3507 | "DEC_RESULT_AGAIN %x %x %x\n", |
3508 | READ_VREG(VLD_MEM_VIFIFO_LEVEL), |
3509 | READ_VREG(VLD_MEM_VIFIFO_WP), |
3510 | READ_VREG(VLD_MEM_VIFIFO_RP));*/ |
3511 | |
3512 | hw->input_empty++; |
3513 | hw->dec_result = DEC_RESULT_AGAIN; |
3514 | vdec_schedule_work(&hw->work); |
3515 | return; |
3516 | } |
3517 | } else { |
3518 | if (size < 0) { |
3519 | hw->input_empty++; |
3520 | hw->dec_result = DEC_RESULT_AGAIN; |
3521 | vdec_schedule_work(&hw->work); |
3522 | return; |
3523 | } |
3524 | } |
3525 | if (input_frame_based(vdec)) { |
3526 | u8 *data = NULL; |
3527 | |
3528 | if (!hw->chunk->block->is_mapped) |
3529 | data = codec_mm_vmap(hw->chunk->block->start + |
3530 | hw->chunk->offset, size); |
3531 | else |
3532 | data = ((u8 *)hw->chunk->block->start_virt) + |
3533 | hw->chunk->offset; |
3534 | |
3535 | if (debug & PRINT_FLAG_RUN_FLOW |
3536 | ) { |
3537 | debug_print(hw, 0, |
3538 | "%s decode_pic_count %d buf_recycle_status 0x%x: size 0x%x sum 0x%x %02x %02x %02x %02x %02x %02x .. %02x %02x %02x %02x\n", |
3539 | __func__, hw->decode_pic_count, |
3540 | hw->buf_recycle_status, |
3541 | size, get_data_check_sum(hw, size), |
3542 | data[0], data[1], data[2], data[3], |
3543 | data[4], data[5], data[size - 4], |
3544 | data[size - 3], data[size - 2], |
3545 | data[size - 1]); |
3546 | } |
3547 | if (debug & PRINT_FRAMEBASE_DATA |
3548 | ) { |
3549 | int jj; |
3550 | |
3551 | for (jj = 0; jj < size; jj++) { |
3552 | if ((jj & 0xf) == 0) |
3553 | debug_print(hw, |
3554 | PRINT_FRAMEBASE_DATA, |
3555 | "%06x:", jj); |
3556 | debug_print(hw, |
3557 | PRINT_FRAMEBASE_DATA, |
3558 | "%02x ", data[jj]); |
3559 | if (((jj + 1) & 0xf) == 0) |
3560 | debug_print(hw, |
3561 | PRINT_FRAMEBASE_DATA, |
3562 | "\n"); |
3563 | } |
3564 | } |
3565 | |
3566 | if (!hw->chunk->block->is_mapped) |
3567 | codec_mm_unmap_phyaddr(data); |
3568 | } else |
3569 | debug_print(hw, PRINT_FLAG_RUN_FLOW, |
3570 | "%s decode_pic_count %d buf_recycle_status 0x%x: %x %x %x %x %x size 0x%x\n", |
3571 | __func__, |
3572 | hw->decode_pic_count, |
3573 | hw->buf_recycle_status, |
3574 | READ_VREG(VLD_MEM_VIFIFO_LEVEL), |
3575 | READ_VREG(VLD_MEM_VIFIFO_WP), |
3576 | READ_VREG(VLD_MEM_VIFIFO_RP), |
3577 | READ_PARSER_REG(PARSER_VIDEO_RP), |
3578 | READ_PARSER_REG(PARSER_VIDEO_WP), |
3579 | size); |
3580 | |
3581 | |
3582 | hw->input_empty = 0; |
3583 | debug_print(hw, PRINT_FLAG_RUN_FLOW, |
3584 | "%s,%d, size=%d\n", __func__, __LINE__, size); |
3585 | |
3586 | /*vdec_enable_input(vdec); |
3587 | need run after VC1_CONTROL_REG is configured |
3588 | */ |
3589 | hw->init_flag = 1; |
3590 | |
3591 | if (hw->chunk) |
3592 | debug_print(hw, PRINT_FLAG_RUN_FLOW, |
3593 | "input chunk offset %d, size %d\n", |
3594 | hw->chunk->offset, hw->chunk->size); |
3595 | |
3596 | hw->dec_result = DEC_RESULT_NONE; |
3597 | /*vdec->mc_loaded = 0;*/ |
3598 | if (vdec->mc_loaded) { |
3599 | /*firmware have load before, |
3600 | and not changes to another. |
3601 | ignore reload. |
3602 | */ |
3603 | } else { |
3604 | ret = amvdec_vdec_loadmc_buf_ex(VFORMAT_AVS, "avs_multi", vdec, |
3605 | hw->fw->data, hw->fw->len); |
3606 | if (ret < 0) { |
3607 | pr_err("[%d] %s: the %s fw loading failed, err: %x\n", vdec->id, |
3608 | hw->fw->name, tee_enabled() ? "TEE" : "local", ret); |
3609 | hw->dec_result = DEC_RESULT_FORCE_EXIT; |
3610 | vdec_schedule_work(&hw->work); |
3611 | return; |
3612 | } |
3613 | vdec->mc_loaded = 1; |
3614 | vdec->mc_type = VFORMAT_AVS; |
3615 | } |
3616 | if (avs_hw_ctx_restore(hw) < 0) { |
3617 | hw->dec_result = DEC_RESULT_ERROR; |
3618 | debug_print(hw, PRINT_FLAG_ERROR, |
3619 | "ammvdec_avs: error HW context restore\n"); |
3620 | vdec_schedule_work(&hw->work); |
3621 | return; |
3622 | } |
3623 | |
3624 | /* |
3625 | This configureation of VC1_CONTROL_REG will |
3626 | pop bits (even no data in the stream buffer) if input is enabled, |
3627 | so it can only be configured before vdec_enable_input() is called. |
3628 | So move this code from ucode to here |
3629 | */ |
3630 | #define DISABLE_DBLK_HCMD 0 |
3631 | #define DISABLE_MC_HCMD 0 |
3632 | WRITE_VREG(VC1_CONTROL_REG, (DISABLE_DBLK_HCMD<<6) | |
3633 | (DISABLE_MC_HCMD<<5) | (1 << 7) | (0xc <<8) | (1<<14)); |
3634 | vdec_enable_input(vdec); |
3635 | /**/ |
3636 | |
3637 | /*wmb();*/ |
3638 | hw->stat |= STAT_MC_LOAD; |
3639 | hw->last_vld_level = 0; |
3640 | |
3641 | debug_print(hw, PRINT_FLAG_DECODING, |
3642 | "%s READ_VREG(AVS_BUFFERIN)=0x%x, recycle_q num %d\n", |
3643 | __func__, READ_VREG(AVS_BUFFERIN), |
3644 | kfifo_len(&hw->recycle_q)); |
3645 | |
3646 | WRITE_VREG(VIFF_BIT_CNT, size * 8); |
3647 | if (hw->reset_decode_flag) |
3648 | WRITE_VREG(DECODE_STATUS, 0); |
3649 | else { |
3650 | recycle_frames(hw); |
3651 | avs_pts_check_in(hw, |
3652 | hw->decode_pic_count & 0xffff, |
3653 | hw->chunk); |
3654 | |
3655 | WRITE_VREG(DECODE_STATUS, |
3656 | (hw->decode_pic_count & 0xffff) | |
3657 | ((~hw->buf_recycle_status) << 16)); |
3658 | } |
3659 | if (hw->again_flag == 0) |
3660 | hw->buf_recycle_status = 0; |
3661 | hw->reset_decode_flag = 0; |
3662 | hw->decode_status_skip_pic_done_flag = 0; |
3663 | start_process_time(hw); |
3664 | #if DEBUG_MULTI_FLAG == 1 |
3665 | if (hw->decode_pic_count > 0) |
3666 | WRITE_VREG(DECODE_STATUS, 0xff); |
3667 | else |
3668 | #endif |
3669 | amvdec_start(); |
3670 | hw->stat |= STAT_VDEC_RUN; |
3671 | |
3672 | hw->stat |= STAT_TIMER_ARM; |
3673 | |
3674 | mod_timer(&hw->check_timer, jiffies + CHECK_INTERVAL); |
3675 | } |
3676 | |
3677 | static void reset(struct vdec_s *vdec) |
3678 | { |
3679 | } |
3680 | |
3681 | static irqreturn_t vmavs_isr_thread_fn(struct vdec_s *vdec, int irq) |
3682 | { |
3683 | return IRQ_HANDLED; |
3684 | } |
3685 | |
3686 | static irqreturn_t vmavs_isr(struct vdec_s *vdec, int irq) |
3687 | { |
3688 | struct vdec_avs_hw_s *hw = |
3689 | (struct vdec_avs_hw_s *)vdec->private; |
3690 | |
3691 | return vavs_isr(0, hw); |
3692 | |
3693 | } |
3694 | |
3695 | static void vmavs_dump_state(struct vdec_s *vdec) |
3696 | { |
3697 | struct vdec_avs_hw_s *hw = |
3698 | (struct vdec_avs_hw_s *)vdec->private; |
3699 | int i; |
3700 | debug_print(hw, 0, |
3701 | "====== %s\n", __func__); |
3702 | |
3703 | debug_print(hw, 0, |
3704 | "width/height (%d/%d), dur %d\n", |
3705 | hw->frame_width, |
3706 | hw->frame_height, |
3707 | hw->frame_dur |
3708 | ); |
3709 | |
3710 | debug_print(hw, 0, |
3711 | "is_framebase(%d), decode_status 0x%x, buf_status 0x%x, buf_recycle_status 0x%x, throw %d, eos %d, state 0x%x, dec_result 0x%x dec_frm %d disp_frm %d run %d not_run_ready %d input_empty %d\n", |
3712 | vdec_frame_based(vdec), |
3713 | READ_VREG(DECODE_STATUS) & 0xff, |
3714 | hw->buf_status, |
3715 | hw->buf_recycle_status, |
3716 | hw->throw_pb_flag, |
3717 | hw->eos, |
3718 | hw->stat, |
3719 | hw->dec_result, |
3720 | hw->decode_pic_count, |
3721 | hw->display_frame_count, |
3722 | hw->run_count, |
3723 | hw->not_run_ready, |
3724 | hw->input_empty |
3725 | ); |
3726 | |
3727 | if (vf_get_receiver(vdec->vf_provider_name)) { |
3728 | enum receviver_start_e state = |
3729 | vf_notify_receiver(vdec->vf_provider_name, |
3730 | VFRAME_EVENT_PROVIDER_QUREY_STATE, |
3731 | NULL); |
3732 | debug_print(hw, 0, |
3733 | "\nreceiver(%s) state %d\n", |
3734 | vdec->vf_provider_name, |
3735 | state); |
3736 | } |
3737 | |
3738 | debug_print(hw, 0, |
3739 | "%s, newq(%d/%d), dispq(%d/%d)recycleq(%d/%d) drop %d vf peek %d, prepare/get/put (%d/%d/%d)\n", |
3740 | __func__, |
3741 | kfifo_len(&hw->newframe_q), |
3742 | VF_POOL_SIZE, |
3743 | kfifo_len(&hw->display_q), |
3744 | VF_POOL_SIZE, |
3745 | kfifo_len(&hw->recycle_q), |
3746 | VF_POOL_SIZE, |
3747 | hw->drop_frame_count, |
3748 | hw->peek_num, |
3749 | hw->prepare_num, |
3750 | hw->get_num, |
3751 | hw->put_num |
3752 | ); |
3753 | |
3754 | debug_print(hw, 0, "vfbuf_use:\n"); |
3755 | for (i = 0; i < hw->vf_buf_num_used; i++) |
3756 | debug_print(hw, 0, "%d: vf_buf_use %d\n", |
3757 | i, hw->vfbuf_use[i]); |
3758 | |
3759 | debug_print(hw, 0, |
3760 | "DECODE_STATUS=0x%x\n", |
3761 | READ_VREG(DECODE_STATUS)); |
3762 | debug_print(hw, 0, |
3763 | "MPC_E=0x%x\n", |
3764 | READ_VREG(MPC_E)); |
3765 | debug_print(hw, 0, |
3766 | "DECODE_MODE=0x%x\n", |
3767 | READ_VREG(DECODE_MODE)); |
3768 | debug_print(hw, 0, |
3769 | "wait_buf_status, AV_SCRATCH_5=0x%x\n", |
3770 | READ_VREG(AV_SCRATCH_5)); |
3771 | debug_print(hw, 0, |
3772 | "MBY_MBX=0x%x\n", |
3773 | READ_VREG(MBY_MBX)); |
3774 | debug_print(hw, 0, |
3775 | "VIFF_BIT_CNT=0x%x\n", |
3776 | READ_VREG(VIFF_BIT_CNT)); |
3777 | debug_print(hw, 0, |
3778 | "VLD_MEM_VIFIFO_LEVEL=0x%x\n", |
3779 | READ_VREG(VLD_MEM_VIFIFO_LEVEL)); |
3780 | debug_print(hw, 0, |
3781 | "VLD_MEM_VIFIFO_WP=0x%x\n", |
3782 | READ_VREG(VLD_MEM_VIFIFO_WP)); |
3783 | debug_print(hw, 0, |
3784 | "VLD_MEM_VIFIFO_RP=0x%x\n", |
3785 | READ_VREG(VLD_MEM_VIFIFO_RP)); |
3786 | debug_print(hw, 0, |
3787 | "PARSER_VIDEO_RP=0x%x\n", |
3788 | READ_PARSER_REG(PARSER_VIDEO_RP)); |
3789 | debug_print(hw, 0, |
3790 | "PARSER_VIDEO_WP=0x%x\n", |
3791 | READ_PARSER_REG(PARSER_VIDEO_WP)); |
3792 | |
3793 | if (vdec_frame_based(vdec) && |
3794 | (debug & PRINT_FRAMEBASE_DATA) |
3795 | ) { |
3796 | int jj; |
3797 | if (hw->chunk && hw->chunk->block && |
3798 | hw->chunk->size > 0) { |
3799 | u8 *data = NULL; |
3800 | |
3801 | if (!hw->chunk->block->is_mapped) |
3802 | data = codec_mm_vmap(hw->chunk->block->start + |
3803 | hw->chunk->offset, hw->chunk->size); |
3804 | else |
3805 | data = ((u8 *)hw->chunk->block->start_virt) |
3806 | + hw->chunk->offset; |
3807 | |
3808 | debug_print(hw, 0, |
3809 | "frame data size 0x%x\n", |
3810 | hw->chunk->size); |
3811 | for (jj = 0; jj < hw->chunk->size; jj++) { |
3812 | if ((jj & 0xf) == 0) |
3813 | debug_print(hw, |
3814 | PRINT_FRAMEBASE_DATA, |
3815 | "%06x:", jj); |
3816 | debug_print_cont(hw, |
3817 | PRINT_FRAMEBASE_DATA, |
3818 | "%02x ", data[jj]); |
3819 | if (((jj + 1) & 0xf) == 0) |
3820 | debug_print_cont(hw, |
3821 | PRINT_FRAMEBASE_DATA, |
3822 | "\n"); |
3823 | } |
3824 | |
3825 | if (!hw->chunk->block->is_mapped) |
3826 | codec_mm_unmap_phyaddr(data); |
3827 | } |
3828 | } |
3829 | |
3830 | } |
3831 | |
3832 | int ammvdec_avs_probe(struct platform_device *pdev) |
3833 | { |
3834 | struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; |
3835 | struct vdec_avs_hw_s *hw = NULL; |
3836 | |
3837 | if (vdec_get_debug_flags() & 0x8) |
3838 | return amvdec_avs_probe(pdev); |
3839 | |
3840 | pr_info("ammvdec_avs probe start.\n"); |
3841 | |
3842 | if (pdata == NULL) { |
3843 | pr_info("ammvdec_avs platform data undefined.\n"); |
3844 | return -EFAULT; |
3845 | } |
3846 | |
3847 | hw = (struct vdec_avs_hw_s *)devm_kzalloc(&pdev->dev, |
3848 | sizeof(struct vdec_avs_hw_s), GFP_KERNEL); |
3849 | if (hw == NULL) { |
3850 | pr_info("\nammvdec_avs decoder driver alloc failed\n"); |
3851 | return -ENOMEM; |
3852 | } |
3853 | /*atomic_set(&hw->error_handler_run, 0);*/ |
3854 | hw->m_ins_flag = 1; |
3855 | |
3856 | if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans) |
3857 | firmware_sel = 1; |
3858 | |
3859 | if (firmware_sel == 1) { |
3860 | #ifndef USE_DYNAMIC_BUF_NUM |
3861 | vf_buf_num = 4; |
3862 | #endif |
3863 | canvas_base = 0; |
3864 | canvas_num = 3; |
3865 | } else { |
3866 | pr_info("Error, do not support longcabac work around!!!"); |
3867 | return -ENOMEM; |
3868 | } |
3869 | |
3870 | if (pdata->sys_info) |
3871 | hw->vavs_amstream_dec_info = *pdata->sys_info; |
3872 | |
3873 | hw->is_reset = 0; |
3874 | pdata->user_data_read = NULL; |
3875 | pdata->reset_userdata_fifo = NULL; |
3876 | |
3877 | pdata->private = hw; |
3878 | pdata->dec_status = vavs_dec_status; |
3879 | pdata->set_isreset = vavs_set_isreset; |
3880 | pdata->run_ready = run_ready; |
3881 | pdata->run = run; |
3882 | pdata->reset = reset; |
3883 | pdata->irq_handler = vmavs_isr; |
3884 | pdata->threaded_irq_handler = vmavs_isr_thread_fn; |
3885 | pdata->dump_state = vmavs_dump_state; |
3886 | |
3887 | vavs_vdec_info_init(hw); |
3888 | |
3889 | #ifdef ENABLE_USER_DATA |
3890 | if (NULL == hw->user_data_buffer) { |
3891 | hw->user_data_buffer = |
3892 | dma_alloc_coherent(amports_get_dma_device(), |
3893 | USER_DATA_SIZE, |
3894 | &hw->user_data_buffer_phys, GFP_KERNEL); |
3895 | if (!hw->user_data_buffer) { |
3896 | pr_info("%s: Can not allocate hw->user_data_buffer\n", |
3897 | __func__); |
3898 | return -ENOMEM; |
3899 | } |
3900 | pr_debug("hw->user_data_buffer = 0x%p, hw->user_data_buffer_phys = 0x%x\n", |
3901 | hw->user_data_buffer, (u32)hw->user_data_buffer_phys); |
3902 | } |
3903 | #endif |
3904 | hw->lmem_addr = kmalloc(LMEM_BUF_SIZE, GFP_KERNEL); |
3905 | if (hw->lmem_addr == NULL) { |
3906 | pr_err("%s: failed to alloc lmem buffer\n", __func__); |
3907 | return -1; |
3908 | } |
3909 | hw->lmem_phy_addr = dma_map_single(amports_get_dma_device(), |
3910 | hw->lmem_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE); |
3911 | if (dma_mapping_error(amports_get_dma_device(), |
3912 | hw->lmem_phy_addr)) { |
3913 | pr_err("%s: failed to map lmem buffer\n", __func__); |
3914 | kfree(hw->lmem_addr); |
3915 | hw->lmem_addr = NULL; |
3916 | return -1; |
3917 | } |
3918 | |
3919 | /*INIT_WORK(&hw->set_clk_work, avs_set_clk);*/ |
3920 | |
3921 | if (vavs_init(hw) < 0) { |
3922 | pr_info("amvdec_avs init failed.\n"); |
3923 | kfree(hw->gvs); |
3924 | hw->gvs = NULL; |
3925 | pdata->dec_status = NULL; |
3926 | return -ENODEV; |
3927 | } |
3928 | |
3929 | /*INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler); |
3930 | atomic_set(&hw->error_handler_run, 0);*/ |
3931 | #if 0 |
3932 | #ifdef ENABLE_USER_DATA |
3933 | INIT_WORK(&hw->userdata_push_work, userdata_push_do_work); |
3934 | #endif |
3935 | #endif |
3936 | INIT_WORK(&hw->notify_work, vavs_notify_work); |
3937 | |
3938 | if (pdata->use_vfm_path) { |
3939 | snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, |
3940 | VFM_DEC_PROVIDER_NAME); |
3941 | hw->frameinfo_enable = 1; |
3942 | } |
3943 | else |
3944 | snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, |
3945 | MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff); |
3946 | if (pdata->parallel_dec == 1) { |
3947 | int i; |
3948 | for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) |
3949 | hw->canvas_spec[i] = 0xffffff; |
3950 | } |
3951 | vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, |
3952 | &vavs_vf_provider, hw); |
3953 | |
3954 | platform_set_drvdata(pdev, pdata); |
3955 | |
3956 | hw->platform_dev = pdev; |
3957 | |
3958 | vdec_set_prepare_level(pdata, start_decode_buf_level); |
3959 | |
3960 | vdec_set_vframe_comm(pdata, DRIVER_NAME); |
3961 | |
3962 | if (pdata->parallel_dec == 1) |
3963 | vdec_core_request(pdata, CORE_MASK_VDEC_1); |
3964 | else { |
3965 | vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC |
3966 | | CORE_MASK_COMBINE); |
3967 | } |
3968 | |
3969 | /*INIT_WORK(&hw->userdata_push_work, userdata_push_do_work);*/ |
3970 | |
3971 | |
3972 | return 0; |
3973 | } |
3974 | |
3975 | int ammvdec_avs_remove(struct platform_device *pdev) |
3976 | { |
3977 | |
3978 | if (vdec_get_debug_flags() & 0x8) |
3979 | return amvdec_avs_remove(pdev); |
3980 | else { |
3981 | struct vdec_avs_hw_s *hw = |
3982 | (struct vdec_avs_hw_s *) |
3983 | (((struct vdec_s *)(platform_get_drvdata(pdev)))->private); |
3984 | struct vdec_s *vdec = hw_to_vdec(hw); |
3985 | int i; |
3986 | |
3987 | if (hw->stat & STAT_VDEC_RUN) { |
3988 | amvdec_stop(); |
3989 | hw->stat &= ~STAT_VDEC_RUN; |
3990 | } |
3991 | |
3992 | if (hw->stat & STAT_ISR_REG) { |
3993 | vdec_free_irq(VDEC_IRQ_1, (void *)hw); |
3994 | hw->stat &= ~STAT_ISR_REG; |
3995 | } |
3996 | |
3997 | if (hw->stat & STAT_TIMER_ARM) { |
3998 | del_timer_sync(&hw->check_timer); |
3999 | hw->stat &= ~STAT_TIMER_ARM; |
4000 | } |
4001 | |
4002 | cancel_work_sync(&hw->work); |
4003 | cancel_work_sync(&hw->notify_work); |
4004 | |
4005 | if (hw->mm_blk_handle) { |
4006 | decoder_bmmu_box_free(hw->mm_blk_handle); |
4007 | hw->mm_blk_handle = NULL; |
4008 | } |
4009 | if (vdec->parallel_dec == 1) |
4010 | vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1); |
4011 | else |
4012 | vdec_core_release(hw_to_vdec(hw), CORE_MASK_VDEC_1 | CORE_MASK_HEVC); |
4013 | vdec_set_status(hw_to_vdec(hw), VDEC_STATUS_DISCONNECTED); |
4014 | |
4015 | if (vdec->parallel_dec == 1) { |
4016 | for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) { |
4017 | vdec->free_canvas_ex(canvas_y(hw->canvas_spec[i]), vdec->id); |
4018 | vdec->free_canvas_ex(canvas_u(hw->canvas_spec[i]), vdec->id); |
4019 | } |
4020 | } |
4021 | #ifdef ENABLE_USER_DATA |
4022 | if (hw->user_data_buffer != NULL) { |
4023 | dma_free_coherent( |
4024 | amports_get_dma_device(), |
4025 | USER_DATA_SIZE, |
4026 | hw->user_data_buffer, |
4027 | hw->user_data_buffer_phys); |
4028 | hw->user_data_buffer = NULL; |
4029 | hw->user_data_buffer_phys = 0; |
4030 | } |
4031 | #endif |
4032 | if (hw->lmem_addr) { |
4033 | dma_unmap_single(amports_get_dma_device(), |
4034 | hw->lmem_phy_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE); |
4035 | kfree(hw->lmem_addr); |
4036 | hw->lmem_addr = NULL; |
4037 | } |
4038 | |
4039 | if (hw->fw) { |
4040 | vfree(hw->fw); |
4041 | hw->fw = NULL; |
4042 | } |
4043 | |
4044 | pr_info("ammvdec_avs removed.\n"); |
4045 | if (hw->gvs) { |
4046 | kfree(hw->gvs); |
4047 | hw->gvs = NULL; |
4048 | } |
4049 | |
4050 | return 0; |
4051 | } |
4052 | } |
4053 | |
4054 | |
4055 | #ifdef DEBUG_MULTI_WITH_AUTOMODE |
4056 | struct stream_buf_s *get_vbuf(void); |
4057 | s32 esparser_init(struct stream_buf_s *buf, struct vdec_s *vdec); |
4058 | |
4059 | |
4060 | static s32 vavs_init2(struct vdec_avs_hw_s *hw) |
4061 | { |
4062 | int size = -1; |
4063 | struct firmware_s *fw; |
4064 | u32 fw_size = 0x1000 * 16; |
4065 | |
4066 | fw = vmalloc(sizeof(struct firmware_s) + fw_size); |
4067 | if (IS_ERR_OR_NULL(fw)) |
4068 | return -ENOMEM; |
4069 | |
4070 | pr_info("vavs_init\n"); |
4071 | |
4072 | amvdec_enable(); |
4073 | |
4074 | |
4075 | vavs_local_init(hw); |
4076 | |
4077 | if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM) |
4078 | size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data); |
4079 | else { |
4080 | if (firmware_sel == 1) |
4081 | size = get_firmware_data(VIDEO_DEC_AVS_NOCABAC, fw->data); |
4082 | #ifdef AVSP_LONG_CABAC |
4083 | else { |
4084 | init_avsp_long_cabac_buf(); |
4085 | size = get_firmware_data(VIDEO_DEC_AVS_MULTI, fw->data); |
4086 | } |
4087 | #endif |
4088 | } |
4089 | |
4090 | if (size < 0) { |
4091 | amvdec_disable(); |
4092 | pr_err("get firmware fail."); |
4093 | /*vfree(buf);*/ |
4094 | return -1; |
4095 | } |
4096 | |
4097 | fw->len = size; |
4098 | hw->fw = fw; |
4099 | if (hw->m_ins_flag) { |
4100 | init_timer(&hw->check_timer); |
4101 | hw->check_timer.data = (ulong) hw; |
4102 | hw->check_timer.function = check_timer_func; |
4103 | hw->check_timer.expires = jiffies + CHECK_INTERVAL; |
4104 | |
4105 | |
4106 | //add_timer(&hw->check_timer); |
4107 | hw->stat |= STAT_TIMER_ARM; |
4108 | |
4109 | INIT_WORK(&hw->work, vavs_work); |
4110 | |
4111 | hw->fw = fw; |
4112 | } |
4113 | return 0; |
4114 | } |
4115 | |
4116 | unsigned int debug_flag2; |
4117 | static int vavs_prot_init2(struct vdec_avs_hw_s *hw, unsigned char post_flag) |
4118 | { |
4119 | int r = 0; |
4120 | /* |
4121 | * 2: assist |
4122 | * 3: vld_reset |
4123 | * 4: vld_part_reset |
4124 | * 5: vfifo reset |
4125 | * 6: iqidct |
4126 | * 7: mc |
4127 | * 8: dblk |
4128 | * 9: pic_dc |
4129 | * 10: psc |
4130 | * 11: mcpu |
4131 | * 12: ccpu |
4132 | * 13: ddr |
4133 | * 14: afifo |
4134 | */ |
4135 | unsigned char run_flag; |
4136 | #ifdef OOO |
4137 | WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) /*| (1 << 4)*/); |
4138 | WRITE_VREG(DOS_SW_RESET0, 0); |
4139 | |
4140 | READ_VREG(DOS_SW_RESET0); |
4141 | |
4142 | WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) /*| (1 << 4)*/); |
4143 | WRITE_VREG(DOS_SW_RESET0, 0); |
4144 | |
4145 | WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8)); |
4146 | WRITE_VREG(DOS_SW_RESET0, 0); |
4147 | #endif |
4148 | /***************** reset vld **********************************/ |
4149 | #ifdef OOO |
4150 | WRITE_VREG(POWER_CTL_VLD, 0x10); |
4151 | WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 2, MEM_FIFO_CNT_BIT, 2); |
4152 | WRITE_VREG_BITS(VLD_MEM_VIFIFO_CONTROL, 8, MEM_LEVEL_CNT_BIT, 6); |
4153 | #endif |
4154 | if (start_decoding_delay & 0x80000) |
4155 | msleep(start_decoding_delay&0xffff); |
4156 | |
4157 | if (debug_flag2 & 0x1) |
4158 | run_flag = post_flag; |
4159 | else |
4160 | run_flag = !post_flag; |
4161 | if (run_flag) { |
4162 | if (hw->m_ins_flag) { |
4163 | int i; |
4164 | if (hw->decode_pic_count == 0) { |
4165 | r = vavs_canvas_init(hw); |
4166 | #ifndef USE_DYNAMIC_BUF_NUM |
4167 | for (i = 0; i < 4; i++) { |
4168 | WRITE_VREG(AV_SCRATCH_0 + i, |
4169 | hw->canvas_spec[i] |
4170 | ); |
4171 | } |
4172 | #else |
4173 | for (i = 0; i < hw->vf_buf_num_used; i += 2) { |
4174 | WRITE_VREG(buf_spec_reg[i >> 1], |
4175 | (hw->canvas_spec[i] & 0xffff) | |
4176 | ((hw->canvas_spec[i + 1] & 0xffff) |
4177 | << 16) |
4178 | ); |
4179 | } |
4180 | #endif |
4181 | } else |
4182 | vavs_restore_regs(hw); |
4183 | |
4184 | for (i = 0; i < hw->vf_buf_num_used; i++) { |
4185 | canvas_config_ex(canvas_y(hw->canvas_spec[i]), |
4186 | hw->canvas_config[i][0].phy_addr, |
4187 | hw->canvas_config[i][0].width, |
4188 | hw->canvas_config[i][0].height, |
4189 | CANVAS_ADDR_NOWRAP, |
4190 | hw->canvas_config[i][0].block_mode, |
4191 | 0); |
4192 | |
4193 | canvas_config_ex(canvas_u(hw->canvas_spec[i]), |
4194 | hw->canvas_config[i][1].phy_addr, |
4195 | hw->canvas_config[i][1].width, |
4196 | hw->canvas_config[i][1].height, |
4197 | CANVAS_ADDR_NOWRAP, |
4198 | hw->canvas_config[i][1].block_mode, |
4199 | 0); |
4200 | } |
4201 | } |
4202 | } |
4203 | |
4204 | if (debug_flag2 & 0x2) |
4205 | run_flag = post_flag; |
4206 | else |
4207 | run_flag = !post_flag; |
4208 | if (run_flag) { |
4209 | |
4210 | /* notify ucode the buffer offset */ |
4211 | if (hw->decode_pic_count == 0) |
4212 | WRITE_VREG(AV_SCRATCH_F, hw->buf_offset); |
4213 | #ifdef OOO |
4214 | /* disable PSCALE for hardware sharing */ |
4215 | WRITE_VREG(PSCALE_CTRL, 0); |
4216 | #endif |
4217 | } |
4218 | if (start_decoding_delay & 0x40000) |
4219 | msleep(start_decoding_delay&0xffff); |
4220 | |
4221 | if (debug_flag2 & 0x4) |
4222 | run_flag = post_flag; |
4223 | else |
4224 | run_flag = !post_flag; |
4225 | if (run_flag) { |
4226 | if (hw->decode_pic_count == 0) { |
4227 | #ifndef USE_DYNAMIC_BUF_NUM |
4228 | WRITE_VREG(AVS_SOS_COUNT, 0); |
4229 | #endif |
4230 | WRITE_VREG(AVS_BUFFERIN, 0); |
4231 | WRITE_VREG(AVS_BUFFEROUT, 0); |
4232 | } |
4233 | if (error_recovery_mode) |
4234 | WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 0); |
4235 | else |
4236 | WRITE_VREG(AVS_ERROR_RECOVERY_MODE, 1); |
4237 | /* clear mailbox interrupt */ |
4238 | WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); |
4239 | |
4240 | /* enable mailbox interrupt */ |
4241 | WRITE_VREG(ASSIST_MBOX1_MASK, 1); |
4242 | } |
4243 | |
4244 | if (debug_flag2 & 0x8) |
4245 | run_flag = post_flag; |
4246 | else |
4247 | run_flag = !post_flag; |
4248 | if (run_flag) { |
4249 | |
4250 | #ifndef USE_DYNAMIC_BUF_NUM /* def DEBUG_UCODE */ |
4251 | if (hw->decode_pic_count == 0) |
4252 | WRITE_VREG(AV_SCRATCH_D, 0); |
4253 | #endif |
4254 | if (start_decoding_delay & 0x10000) |
4255 | msleep(start_decoding_delay&0xffff); |
4256 | #ifdef NV21 |
4257 | SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); |
4258 | #endif |
4259 | if (start_decoding_delay & 0x20000) |
4260 | msleep(start_decoding_delay&0xffff); |
4261 | |
4262 | |
4263 | #ifdef PIC_DC_NEED_CLEAR |
4264 | CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 31); |
4265 | #endif |
4266 | } |
4267 | if (debug_flag2 & 0x10) |
4268 | run_flag = post_flag; |
4269 | else |
4270 | run_flag = !post_flag; |
4271 | if (run_flag) { |
4272 | #ifdef ENABLE_USER_DATA |
4273 | if (firmware_sel == 0) { |
4274 | pr_info("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! firmware_sel is 0\n"); |
4275 | WRITE_VREG(AV_SCRATCH_N, (u32)(hw->user_data_buffer_phys - hw->buf_offset)); |
4276 | pr_debug("AV_SCRATCH_N = 0x%x\n", READ_VREG(AV_SCRATCH_N)); |
4277 | } |
4278 | #endif |
4279 | } |
4280 | |
4281 | if (debug_flag2 & 0x20) |
4282 | run_flag = post_flag; |
4283 | else |
4284 | run_flag = !post_flag; |
4285 | if (run_flag) { |
4286 | if (hw->m_ins_flag) { |
4287 | if (vdec_frame_based(hw_to_vdec(hw))) |
4288 | WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_FRAMEBASE); |
4289 | else |
4290 | WRITE_VREG(DECODE_MODE, DECODE_MODE_MULTI_STREAMBASE); |
4291 | WRITE_VREG(DECODE_LMEM_BUF_ADR, hw->lmem_phy_addr); |
4292 | } else |
4293 | WRITE_VREG(DECODE_MODE, DECODE_MODE_SINGLE); |
4294 | WRITE_VREG(DECODE_STOP_POS, udebug_flag); |
4295 | hw->old_udebug_flag = udebug_flag; |
4296 | } |
4297 | return r; |
4298 | } |
4299 | |
4300 | static void init_hw(struct vdec_s *vdec) |
4301 | { |
4302 | struct vdec_avs_hw_s *hw = |
4303 | (struct vdec_avs_hw_s *)vdec->private; |
4304 | int ret; |
4305 | pr_info("%s, %d\n", __func__, __LINE__); |
4306 | if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM) |
4307 | ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, hw->fw->data); |
4308 | else if (firmware_sel == 1) |
4309 | ret = amvdec_loadmc_ex(VFORMAT_AVS, "avs_no_cabac", hw->fw->data); |
4310 | else |
4311 | ret = amvdec_loadmc_ex(VFORMAT_AVS, NULL, hw->fw->data); |
4312 | |
4313 | if (ret < 0) { |
4314 | amvdec_disable(); |
4315 | /*vfree(buf);*/ |
4316 | pr_err("AVS: the %s fw loading failed, err: %x\n", |
4317 | tee_enabled() ? "TEE" : "local", ret); |
4318 | } |
4319 | pr_info("%s, %d\n", __func__, __LINE__); |
4320 | |
4321 | /*vfree(buf);*/ |
4322 | |
4323 | hw->stat |= STAT_MC_LOAD; |
4324 | |
4325 | /* enable AMRISC side protocol */ |
4326 | ret = vavs_prot_init2(hw, 0); |
4327 | if (ret < 0) |
4328 | return; |
4329 | pr_info("%s, %d\n", __func__, __LINE__); |
4330 | |
4331 | } |
4332 | |
4333 | |
4334 | static unsigned long run_ready2(struct vdec_s *vdec, unsigned long mask) |
4335 | { |
4336 | return 1; |
4337 | } |
4338 | |
4339 | static void run2(struct vdec_s *vdec, unsigned long mask, |
4340 | void (*callback)(struct vdec_s *, void *), |
4341 | void *arg) |
4342 | { |
4343 | struct vdec_avs_hw_s *hw = |
4344 | (struct vdec_avs_hw_s *)vdec->private; |
4345 | pr_info("%s, %d\n", __func__, __LINE__); |
4346 | |
4347 | vavs_prot_init2(hw, 1); |
4348 | |
4349 | vdec_source_changed(VFORMAT_AVS, |
4350 | 1920, 1080, 30); |
4351 | |
4352 | amvdec_start(); |
4353 | |
4354 | hw->stat |= STAT_VDEC_RUN; |
4355 | pr_info("%s %d\n", __func__, __LINE__); |
4356 | |
4357 | } |
4358 | |
4359 | static int ammvdec_avs_probe2(struct platform_device *pdev) |
4360 | { |
4361 | struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; |
4362 | struct vdec_avs_hw_s *hw = NULL; |
4363 | |
4364 | pr_info("ammvdec_avs probe start.\n"); |
4365 | |
4366 | if (pdata == NULL) { |
4367 | pr_info("ammvdec_avs platform data undefined.\n"); |
4368 | return -EFAULT; |
4369 | } |
4370 | pr_info("%s %d\n", __func__, __LINE__); |
4371 | |
4372 | hw = (struct vdec_avs_hw_s *)devm_kzalloc(&pdev->dev, |
4373 | sizeof(struct vdec_avs_hw_s), GFP_KERNEL); |
4374 | if (hw == NULL) { |
4375 | pr_info("\nammvdec_avs decoder driver alloc failed\n"); |
4376 | return -ENOMEM; |
4377 | } |
4378 | pr_info("%s %d\n", __func__, __LINE__); |
4379 | /*atomic_set(&hw->error_handler_run, 0);*/ |
4380 | hw->m_ins_flag = 1; |
4381 | pr_info("%s %d\n", __func__, __LINE__); |
4382 | |
4383 | if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXM || disable_longcabac_trans) |
4384 | firmware_sel = 1; |
4385 | pr_info("%s %d\n", __func__, __LINE__); |
4386 | |
4387 | if (firmware_sel == 1) { |
4388 | #ifndef USE_DYNAMIC_BUF_NUM |
4389 | vf_buf_num = 4; |
4390 | #endif |
4391 | canvas_base = 0; |
4392 | canvas_num = 3; |
4393 | } else { |
4394 | pr_info("Error, do not support longcabac work around!!!"); |
4395 | return -ENOMEM; |
4396 | } |
4397 | pr_info("%s %d\n", __func__, __LINE__); |
4398 | |
4399 | if (pdata->sys_info) |
4400 | hw->vavs_amstream_dec_info = *pdata->sys_info; |
4401 | pr_info("%s %d\n", __func__, __LINE__); |
4402 | |
4403 | hw->is_reset = 0; |
4404 | pdata->user_data_read = NULL; |
4405 | pdata->reset_userdata_fifo = NULL; |
4406 | |
4407 | pr_info("%s %d\n", __func__, __LINE__); |
4408 | |
4409 | pdata->private = hw; |
4410 | pdata->dec_status = vavs_dec_status; |
4411 | pdata->set_isreset = vavs_set_isreset; |
4412 | pdata->run_ready = run_ready2; |
4413 | pdata->run = run2; |
4414 | pdata->reset = reset; |
4415 | pdata->irq_handler = vmavs_isr; |
4416 | pdata->threaded_irq_handler = vmavs_isr_thread_fn; |
4417 | pdata->dump_state = vmavs_dump_state; |
4418 | |
4419 | pr_info("%s %d\n", __func__, __LINE__); |
4420 | |
4421 | vavs_vdec_info_init(hw); |
4422 | |
4423 | pr_info("%s %d\n", __func__, __LINE__); |
4424 | |
4425 | #ifdef ENABLE_USER_DATA |
4426 | if (NULL == hw->user_data_buffer) { |
4427 | hw->user_data_buffer = |
4428 | dma_alloc_coherent(amports_get_dma_device(), |
4429 | USER_DATA_SIZE, |
4430 | &hw->user_data_buffer_phys, GFP_KERNEL); |
4431 | if (!hw->user_data_buffer) { |
4432 | pr_info("%s: Can not allocate hw->user_data_buffer\n", |
4433 | __func__); |
4434 | return -ENOMEM; |
4435 | } |
4436 | pr_debug("hw->user_data_buffer = 0x%p, hw->user_data_buffer_phys = 0x%x\n", |
4437 | hw->user_data_buffer, (u32)hw->user_data_buffer_phys); |
4438 | } |
4439 | #endif |
4440 | hw->lmem_addr = kmalloc(LMEM_BUF_SIZE, GFP_KERNEL); |
4441 | if (hw->lmem_addr == NULL) { |
4442 | pr_err("%s: failed to alloc lmem buffer\n", __func__); |
4443 | return -1; |
4444 | } |
4445 | hw->lmem_phy_addr = dma_map_single(amports_get_dma_device(), |
4446 | hw->lmem_addr, LMEM_BUF_SIZE, DMA_FROM_DEVICE); |
4447 | if (dma_mapping_error(amports_get_dma_device(), |
4448 | hw->lmem_phy_addr)) { |
4449 | pr_err("%s: failed to map lmem buffer\n", __func__); |
4450 | kfree(hw->lmem_addr); |
4451 | hw->lmem_addr = NULL; |
4452 | return -1; |
4453 | } |
4454 | |
4455 | pr_info("%s %d\n", __func__, __LINE__); |
4456 | |
4457 | /*INIT_WORK(&hw->set_clk_work, avs_set_clk);*/ |
4458 | |
4459 | pr_info("%s %d\n", __func__, __LINE__); |
4460 | |
4461 | if (vavs_init2(hw) < 0) { |
4462 | pr_info("amvdec_avs init failed.\n"); |
4463 | kfree(hw->gvs); |
4464 | hw->gvs = NULL; |
4465 | pdata->dec_status = NULL; |
4466 | return -ENODEV; |
4467 | } |
4468 | /*vdec = pdata;*/ |
4469 | pr_info("%s, %d\n", __func__, __LINE__); |
4470 | |
4471 | if (hw->m_ins_flag) { |
4472 | INIT_WORK(&hw->notify_work, vavs_notify_work); |
4473 | #if 1 |
4474 | if (pdata->use_vfm_path) { |
4475 | snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, |
4476 | VFM_DEC_PROVIDER_NAME); |
4477 | hw->frameinfo_enable = 1; |
4478 | } |
4479 | else |
4480 | snprintf(pdata->vf_provider_name, VDEC_PROVIDER_NAME_SIZE, |
4481 | MULTI_INSTANCE_PROVIDER_NAME ".%02x", pdev->id & 0xff); |
4482 | if (pdata->parallel_dec == 1) { |
4483 | int i; |
4484 | for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) |
4485 | hw->canvas_spec[i] = 0xffffff; |
4486 | } |
4487 | vf_provider_init(&pdata->vframe_provider, pdata->vf_provider_name, |
4488 | &vavs_vf_provider, hw); |
4489 | |
4490 | platform_set_drvdata(pdev, pdata); |
4491 | |
4492 | hw->platform_dev = pdev; |
4493 | |
4494 | vdec_set_prepare_level(pdata, start_decode_buf_level); |
4495 | |
4496 | if (pdata->parallel_dec == 1) |
4497 | vdec_core_request(pdata, CORE_MASK_VDEC_1); |
4498 | else { |
4499 | vdec_core_request(pdata, CORE_MASK_VDEC_1 | CORE_MASK_HEVC |
4500 | | CORE_MASK_COMBINE); |
4501 | } |
4502 | pr_info("%s, %d\n", __func__, __LINE__); |
4503 | #endif |
4504 | }else{ |
4505 | /*INIT_WORK(&hw->fatal_error_wd_work, vavs_fatal_error_handler); |
4506 | atomic_set(&hw->error_handler_run, 0);*/ |
4507 | #ifdef ENABLE_USER_DATA |
4508 | INIT_WORK(&hw->userdata_push_work, userdata_push_do_work); |
4509 | #endif |
4510 | INIT_WORK(&hw->notify_work, vavs_notify_work); |
4511 | } |
4512 | |
4513 | init_hw(pdata); |
4514 | return 0; |
4515 | } |
4516 | |
4517 | static int ammvdec_avs_remove2(struct platform_device *pdev) |
4518 | { |
4519 | struct vdec_avs_hw_s *hw = ghw; |
4520 | |
4521 | cancel_work_sync(&hw->fatal_error_wd_work); |
4522 | atomic_set(&hw->error_handler_run, 0); |
4523 | #ifdef ENABLE_USER_DATA |
4524 | cancel_work_sync(&hw->userdata_push_work); |
4525 | #endif |
4526 | cancel_work_sync(&hw->notify_work); |
4527 | cancel_work_sync(&hw->set_clk_work); |
4528 | if (hw->stat & STAT_VDEC_RUN) { |
4529 | amvdec_stop(); |
4530 | hw->stat &= ~STAT_VDEC_RUN; |
4531 | } |
4532 | |
4533 | if (hw->stat & STAT_ISR_REG) { |
4534 | vdec_free_irq(VDEC_IRQ_1, (void *)vavs_dec_id); |
4535 | hw->stat &= ~STAT_ISR_REG; |
4536 | } |
4537 | |
4538 | if (hw->stat & STAT_TIMER_ARM) { |
4539 | del_timer_sync(&hw->recycle_timer); |
4540 | hw->stat &= ~STAT_TIMER_ARM; |
4541 | } |
4542 | #ifdef AVSP_LONG_CABAC |
4543 | if (firmware_sel == 0) { |
4544 | mutex_lock(&vavs_mutex); |
4545 | cancel_work_sync(&long_cabac_wd_work); |
4546 | mutex_unlock(&vavs_mutex); |
4547 | |
4548 | if (es_write_addr_virt) { |
4549 | #if 0 |
4550 | codec_mm_free_for_dma("vavs", es_write_addr_phy); |
4551 | #else |
4552 | dma_unmap_single(amports_get_dma_device(), |
4553 | es_write_addr_phy, |
4554 | MAX_CODED_FRAME_SIZE, DMA_FROM_DEVICE); |
4555 | /*kfree(es_write_addr_virt);*/ |
4556 | es_write_addr_virt = NULL; |
4557 | #endif |
4558 | } |
4559 | |
4560 | #ifdef BITSTREAM_READ_TMP_NO_CACHE |
4561 | if (bitstream_read_tmp) { |
4562 | dma_free_coherent(amports_get_dma_device(), |
4563 | SVA_STREAM_BUF_SIZE, bitstream_read_tmp, |
4564 | bitstream_read_tmp_phy); |
4565 | bitstream_read_tmp = NULL; |
4566 | } |
4567 | #else |
4568 | if (bitstream_read_tmp) { |
4569 | dma_unmap_single(amports_get_dma_device(), |
4570 | bitstream_read_tmp_phy, |
4571 | SVA_STREAM_BUF_SIZE, DMA_FROM_DEVICE); |
4572 | kfree(bitstream_read_tmp); |
4573 | bitstream_read_tmp = NULL; |
4574 | } |
4575 | #endif |
4576 | } |
4577 | #endif |
4578 | if (hw->stat & STAT_VF_HOOK) { |
4579 | if (hw->fr_hint_status == VDEC_HINTED && !hw->is_reset) |
4580 | avs_vf_notify_receiver(hw, PROVIDER_NAME, |
4581 | VFRAME_EVENT_PROVIDER_FR_END_HINT, NULL); |
4582 | hw->fr_hint_status = VDEC_NO_NEED_HINT; |
4583 | vf_unreg_provider(&vavs_vf_prov); |
4584 | hw->stat &= ~STAT_VF_HOOK; |
4585 | } |
4586 | |
4587 | #ifdef ENABLE_USER_DATA |
4588 | if (hw->user_data_buffer != NULL) { |
4589 | dma_free_coherent( |
4590 | amports_get_dma_device(), |
4591 | USER_DATA_SIZE, |
4592 | hw->user_data_buffer, |
4593 | hw->user_data_buffer_phys); |
4594 | hw->user_data_buffer = NULL; |
4595 | hw->user_data_buffer_phys = 0; |
4596 | } |
4597 | #endif |
4598 | |
4599 | if (hw->fw) { |
4600 | vfree(hw->fw); |
4601 | hw->fw = NULL; |
4602 | } |
4603 | |
4604 | amvdec_disable(); |
4605 | /*vdec_disable_DMC(NULL);*/ |
4606 | |
4607 | hw->pic_type = 0; |
4608 | if (hw->mm_blk_handle) { |
4609 | decoder_bmmu_box_free(hw->mm_blk_handle); |
4610 | hw->mm_blk_handle = NULL; |
4611 | } |
4612 | #ifdef DEBUG_PTS |
4613 | pr_debug("pts hit %d, pts missed %d, i hit %d, missed %d\n", hw->pts_hit, |
4614 | hw->pts_missed, hw->pts_i_hit, hw->pts_i_missed); |
4615 | pr_debug("total frame %d, hw->avi_flag %d, rate %d\n", hw->total_frame, hw->avi_flag, |
4616 | hw->vavs_amstream_dec_info.rate); |
4617 | #endif |
4618 | kfree(hw->gvs); |
4619 | hw->gvs = NULL; |
4620 | |
4621 | return 0; |
4622 | } |
4623 | #endif |
4624 | |
4625 | static struct platform_driver ammvdec_avs_driver = { |
4626 | #ifdef DEBUG_MULTI_WITH_AUTOMODE |
4627 | .probe = ammvdec_avs_probe2, |
4628 | .remove = ammvdec_avs_remove2, |
4629 | #else |
4630 | .probe = ammvdec_avs_probe, |
4631 | .remove = ammvdec_avs_remove, |
4632 | #endif |
4633 | #ifdef CONFIG_PM |
4634 | .suspend = amvdec_suspend, |
4635 | .resume = amvdec_resume, |
4636 | #endif |
4637 | .driver = { |
4638 | .name = MULTI_DRIVER_NAME, |
4639 | } |
4640 | }; |
4641 | |
4642 | static struct codec_profile_t ammvdec_avs_profile = { |
4643 | .name = "mavs", |
4644 | .profile = "" |
4645 | }; |
4646 | |
4647 | static struct mconfig mavs_configs[] = { |
4648 | /*MC_PU32("stat", &stat), |
4649 | MC_PU32("debug_flag", &debug_flag), |
4650 | MC_PU32("error_recovery_mode", &error_recovery_mode), |
4651 | MC_PU32("hw->pic_type", &hw->pic_type), |
4652 | MC_PU32("radr", &radr), |
4653 | MC_PU32("vf_buf_num", &vf_buf_num), |
4654 | MC_PU32("vf_buf_num_used", &vf_buf_num_used), |
4655 | MC_PU32("canvas_base", &canvas_base), |
4656 | MC_PU32("firmware_sel", &firmware_sel), |
4657 | */ |
4658 | }; |
4659 | static struct mconfig_node mavs_node; |
4660 | |
4661 | |
4662 | static int __init ammvdec_avs_driver_init_module(void) |
4663 | { |
4664 | pr_debug("ammvdec_avs module init\n"); |
4665 | |
4666 | if (platform_driver_register(&ammvdec_avs_driver)) |
4667 | pr_err("failed to register ammvdec_avs driver\n"); |
4668 | #ifdef DEBUG_WITH_SINGLE_MODE |
4669 | if (platform_driver_register(&amvdec_avs_driver)) { |
4670 | pr_info("failed to register amvdec_avs driver\n"); |
4671 | return -ENODEV; |
4672 | } |
4673 | #else |
4674 | amvdec_avs_driver = amvdec_avs_driver; |
4675 | #endif |
4676 | if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_GXBB) |
4677 | ammvdec_avs_profile.profile = "avs+"; |
4678 | |
4679 | //vcodec_profile_register(&ammvdec_avs_profile); |
4680 | INIT_REG_NODE_CONFIGS("media.decoder", &mavs_node, |
4681 | "mavs", mavs_configs, CONFIG_FOR_RW); |
4682 | return 0; |
4683 | } |
4684 | |
4685 | |
4686 | |
4687 | static void __exit ammvdec_avs_driver_remove_module(void) |
4688 | { |
4689 | pr_debug("ammvdec_avs module remove.\n"); |
4690 | |
4691 | platform_driver_unregister(&ammvdec_avs_driver); |
4692 | #ifdef DEBUG_WITH_SINGLE_MODE |
4693 | platform_driver_unregister(&amvdec_avs_driver); |
4694 | #endif |
4695 | } |
4696 | |
4697 | /****************************************/ |
4698 | /* |
4699 | module_param(stat, uint, 0664); |
4700 | MODULE_PARM_DESC(stat, "\n amvdec_avs stat\n"); |
4701 | */ |
4702 | /****************************************** |
4703 | *module_param(run_flag, uint, 0664); |
4704 | *MODULE_PARM_DESC(run_flag, "\n run_flag\n"); |
4705 | * |
4706 | *module_param(step_flag, uint, 0664); |
4707 | *MODULE_PARM_DESC(step_flag, "\n step_flag\n"); |
4708 | ******************************************* |
4709 | */ |
4710 | module_param(step, uint, 0664); |
4711 | MODULE_PARM_DESC(step, "\n step\n"); |
4712 | |
4713 | module_param(debug, uint, 0664); |
4714 | MODULE_PARM_DESC(debug, "\n debug\n"); |
4715 | |
4716 | module_param(debug_mask, uint, 0664); |
4717 | MODULE_PARM_DESC(debug_mask, "\n debug_mask\n"); |
4718 | |
4719 | module_param(error_recovery_mode, uint, 0664); |
4720 | MODULE_PARM_DESC(error_recovery_mode, "\n error_recovery_mode\n"); |
4721 | |
4722 | /****************************************** |
4723 | *module_param(error_watchdog_threshold, uint, 0664); |
4724 | *MODULE_PARM_DESC(error_watchdog_threshold, "\n error_watchdog_threshold\n"); |
4725 | * |
4726 | *module_param(error_watchdog_buf_threshold, uint, 0664); |
4727 | *MODULE_PARM_DESC(error_watchdog_buf_threshold, |
4728 | * "\n error_watchdog_buf_threshold\n"); |
4729 | ******************************************* |
4730 | */ |
4731 | /* |
4732 | module_param(pic_type, uint, 0444); |
4733 | MODULE_PARM_DESC(pic_type, "\n amdec_vas picture type\n"); |
4734 | */ |
4735 | module_param(radr, uint, 0664); |
4736 | MODULE_PARM_DESC(radr, "\nradr\n"); |
4737 | |
4738 | module_param(rval, uint, 0664); |
4739 | MODULE_PARM_DESC(rval, "\nrval\n"); |
4740 | |
4741 | module_param(dbg_cmd, uint, 0664); |
4742 | MODULE_PARM_DESC(dbg_cmd, "\n dbg_cmd\n"); |
4743 | |
4744 | module_param(vf_buf_num, uint, 0664); |
4745 | MODULE_PARM_DESC(vf_buf_num, "\nvf_buf_num\n"); |
4746 | |
4747 | /* |
4748 | module_param(vf_buf_num_used, uint, 0664); |
4749 | MODULE_PARM_DESC(vf_buf_num_used, "\nvf_buf_num_used\n"); |
4750 | */ |
4751 | module_param(canvas_base, uint, 0664); |
4752 | MODULE_PARM_DESC(canvas_base, "\ncanvas_base\n"); |
4753 | |
4754 | |
4755 | module_param(firmware_sel, uint, 0664); |
4756 | MODULE_PARM_DESC(firmware_sel, "\n firmware_sel\n"); |
4757 | |
4758 | module_param(disable_longcabac_trans, uint, 0664); |
4759 | MODULE_PARM_DESC(disable_longcabac_trans, "\n disable_longcabac_trans\n"); |
4760 | |
4761 | module_param(dec_control, uint, 0664); |
4762 | MODULE_PARM_DESC(dec_control, "\n amvdec_vavs decoder control\n"); |
4763 | |
4764 | module_param(start_decode_buf_level, int, 0664); |
4765 | MODULE_PARM_DESC(start_decode_buf_level, |
4766 | "\n avs start_decode_buf_level\n"); |
4767 | |
4768 | module_param(decode_timeout_val, uint, 0664); |
4769 | MODULE_PARM_DESC(decode_timeout_val, |
4770 | "\n avs decode_timeout_val\n"); |
4771 | |
4772 | module_param(error_handle_policy, uint, 0664); |
4773 | MODULE_PARM_DESC(error_handle_policy, |
4774 | "\n avs error_handle_policy\n"); |
4775 | |
4776 | module_param(again_threshold, uint, 0664); |
4777 | MODULE_PARM_DESC(again_threshold, "\n again_threshold\n"); |
4778 | |
4779 | module_param(udebug_flag, uint, 0664); |
4780 | MODULE_PARM_DESC(udebug_flag, "\n amvdec_h265 udebug_flag\n"); |
4781 | |
4782 | module_param(udebug_pause_pos, uint, 0664); |
4783 | MODULE_PARM_DESC(udebug_pause_pos, "\n udebug_pause_pos\n"); |
4784 | |
4785 | module_param(udebug_pause_val, uint, 0664); |
4786 | MODULE_PARM_DESC(udebug_pause_val, "\n udebug_pause_val\n"); |
4787 | |
4788 | module_param(udebug_pause_decode_idx, uint, 0664); |
4789 | MODULE_PARM_DESC(udebug_pause_decode_idx, "\n udebug_pause_decode_idx\n"); |
4790 | |
4791 | module_param(udebug_pause_ins_id, uint, 0664); |
4792 | MODULE_PARM_DESC(udebug_pause_ins_id, "\n udebug_pause_ins_id\n"); |
4793 | |
4794 | module_param(start_decoding_delay, uint, 0664); |
4795 | MODULE_PARM_DESC(start_decoding_delay, "\n start_decoding_delay\n"); |
4796 | |
4797 | #ifdef DEBUG_MULTI_WITH_AUTOMODE |
4798 | module_param(debug_flag2, uint, 0664); |
4799 | MODULE_PARM_DESC(debug_flag2, "\n debug_flag2\n"); |
4800 | #endif |
4801 | module_param(force_fps, uint, 0664); |
4802 | MODULE_PARM_DESC(force_fps, "\n force_fps\n"); |
4803 | |
4804 | #ifdef DEBUG_MULTI_FRAME_INS |
4805 | module_param(delay, uint, 0664); |
4806 | MODULE_PARM_DESC(delay, "\n delay\n"); |
4807 | |
4808 | module_param_array(max_run_count, uint, &max_decode_instance_num, 0664); |
4809 | |
4810 | #endif |
4811 | |
4812 | module_param_array(ins_udebug_flag, uint, &max_decode_instance_num, 0664); |
4813 | |
4814 | module_param_array(max_process_time, uint, &max_decode_instance_num, 0664); |
4815 | |
4816 | module_param_array(run_count, uint, &max_decode_instance_num, 0664); |
4817 | |
4818 | module_param_array(max_get_frame_interval, uint, |
4819 | &max_decode_instance_num, 0664); |
4820 | |
4821 | |
4822 | module_init(ammvdec_avs_driver_init_module); |
4823 | module_exit(ammvdec_avs_driver_remove_module); |
4824 | |
4825 | MODULE_DESCRIPTION("AMLOGIC AVS Video Decoder Driver"); |
4826 | MODULE_LICENSE("GPL"); |
4827 | MODULE_AUTHOR("Qi Wang <qi.wang@amlogic.com>"); |
4828 |