blob: 9d554a049a662717ff3e3d4330cf9b54776b7f3c
1 | /* |
2 | * drivers/amlogic/media/frame_provider/decoder/h264/vh264.c |
3 | * |
4 | * Copyright (C) 2016 Amlogic, Inc. All rights reserved. |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, but WITHOUT |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
14 | * more details. |
15 | * |
16 | */ |
17 | |
18 | #include <linux/kernel.h> |
19 | #include <linux/types.h> |
20 | #include <linux/errno.h> |
21 | #include <linux/interrupt.h> |
22 | #include <linux/timer.h> |
23 | #include <linux/kfifo.h> |
24 | #include <linux/platform_device.h> |
25 | |
26 | #include <linux/amlogic/media/utils/amstream.h> |
27 | #include <linux/amlogic/media/frame_sync/ptsserv.h> |
28 | #include <linux/amlogic/media/vfm/vframe.h> |
29 | #include <linux/amlogic/media/vfm/vframe_provider.h> |
30 | #include <linux/amlogic/media/vfm/vframe_receiver.h> |
31 | #include <linux/amlogic/media/utils/vformat.h> |
32 | #include <linux/amlogic/media/frame_sync/tsync.h> |
33 | #include <linux/workqueue.h> |
34 | #include <linux/dma-mapping.h> |
35 | #include <linux/atomic.h> |
36 | #include <linux/module.h> |
37 | #include <linux/slab.h> |
38 | #include "../../../stream_input/amports/amports_priv.h" |
39 | #include <linux/amlogic/media/canvas/canvas.h> |
40 | #include <linux/amlogic/media/codec_mm/codec_mm.h> |
41 | |
42 | #include "../utils/vdec.h" |
43 | #include <linux/amlogic/media/utils/vdec_reg.h> |
44 | #include "../utils/amvdec.h" |
45 | #include "vh264.h" |
46 | #include "../../../stream_input/parser/streambuf.h" |
47 | #include <linux/delay.h> |
48 | |
49 | /*#include <linux/amlogic/ge2d/ge2d.h>*/ |
50 | |
51 | #define DRIVER_NAME "amvdec_h264" |
52 | #define MODULE_NAME "amvdec_h264" |
53 | #define MEM_NAME "codec_264" |
54 | #define HANDLE_H264_IRQ |
55 | /* #define DEBUG_PTS */ |
56 | #if 0 /* MESON_CPU_TYPE <= MESON_CPU_TYPE_MESON6TV */ |
57 | #define DROP_B_FRAME_FOR_1080P_50_60FPS |
58 | #endif |
59 | #define RATE_MEASURE_NUM 8 |
60 | #define RATE_CORRECTION_THRESHOLD 5 |
61 | #define RATE_24_FPS 4004 /* 23.97 */ |
62 | #define RATE_25_FPS 3840 /* 25 */ |
63 | #define DUR2PTS(x) ((x)*90/96) |
64 | #define PTS2DUR(x) ((x)*96/90) |
65 | #define DUR2PTS_REM(x) (x*90 - DUR2PTS(x)*96) |
66 | #define FIX_FRAME_RATE_CHECK_IDRFRAME_NUM 2 |
67 | #define VDEC_CLOCK_ADJUST_FRAME 50 |
68 | |
69 | static inline bool close_to(int a, int b, int m) |
70 | { |
71 | return (abs(a - b) < m) ? true : false; |
72 | } |
73 | |
74 | static DEFINE_MUTEX(vh264_mutex); |
75 | /* 12M for L41 */ |
76 | #define MAX_DPB_BUFF_SIZE (12*1024*1024) |
77 | #define DEFAULT_MEM_SIZE (32*1024*1024) |
78 | #define AVIL_DPB_BUFF_SIZE 0x01ec2000 |
79 | |
80 | #define DEF_BUF_START_ADDR 0x1000000 |
81 | #define V_BUF_ADDR_OFFSET_NEW (0x1ee000) |
82 | #define V_BUF_ADDR_OFFSET (0x13e000) |
83 | |
84 | #define PIC_SINGLE_FRAME 0 |
85 | #define PIC_TOP_BOT_TOP 1 |
86 | #define PIC_BOT_TOP_BOT 2 |
87 | #define PIC_DOUBLE_FRAME 3 |
88 | #define PIC_TRIPLE_FRAME 4 |
89 | #define PIC_TOP_BOT 5 |
90 | #define PIC_BOT_TOP 6 |
91 | #define PIC_INVALID 7 |
92 | |
93 | #define EXTEND_SAR 0xff |
94 | |
95 | #define VF_POOL_SIZE 64 |
96 | #define VF_BUF_NUM 24 |
97 | #define PUT_INTERVAL (HZ/100) |
98 | #define NO_DISP_WD_COUNT (3 * HZ / PUT_INTERVAL) |
99 | |
100 | #define SWITCHING_STATE_OFF 0 |
101 | #define SWITCHING_STATE_ON_CMD3 1 |
102 | #define SWITCHING_STATE_ON_CMD1 2 |
103 | #define SWITCHING_STATE_ON_CMD1_PENDING 3 |
104 | |
105 | |
106 | #define DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE 0x0001 |
107 | #define DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE 0x0002 |
108 | #define DEC_CONTROL_FLAG_DISABLE_FAST_POC 0x0004 |
109 | |
110 | #define INCPTR(p) ptr_atomic_wrap_inc(&p) |
111 | |
112 | #define SLICE_TYPE_I 2 |
113 | #define SLICE_TYPE_P 5 |
114 | #define SLICE_TYPE_B 6 |
115 | |
116 | struct buffer_spec_s { |
117 | unsigned int y_addr; |
118 | unsigned int u_addr; |
119 | unsigned int v_addr; |
120 | |
121 | int y_canvas_index; |
122 | int u_canvas_index; |
123 | int v_canvas_index; |
124 | |
125 | unsigned int y_canvas_width; |
126 | unsigned int u_canvas_width; |
127 | unsigned int v_canvas_width; |
128 | |
129 | unsigned int y_canvas_height; |
130 | unsigned int u_canvas_height; |
131 | unsigned int v_canvas_height; |
132 | |
133 | unsigned long phy_addr; |
134 | int alloc_count; |
135 | }; |
136 | |
137 | #define spec2canvas(x) \ |
138 | (((x)->v_canvas_index << 16) | \ |
139 | ((x)->u_canvas_index << 8) | \ |
140 | ((x)->y_canvas_index << 0)) |
141 | |
142 | static struct vframe_s *vh264_vf_peek(void *); |
143 | static struct vframe_s *vh264_vf_get(void *); |
144 | static void vh264_vf_put(struct vframe_s *, void *); |
145 | static int vh264_vf_states(struct vframe_states *states, void *); |
146 | static int vh264_event_cb(int type, void *data, void *private_data); |
147 | |
148 | static void vh264_prot_init(void); |
149 | static void vh264_local_init(void); |
150 | static void vh264_put_timer_func(unsigned long arg); |
151 | static void stream_switching_done(void); |
152 | |
153 | static const char vh264_dec_id[] = "vh264-dev"; |
154 | |
155 | #define PROVIDER_NAME "decoder.h264" |
156 | |
157 | static const struct vframe_operations_s vh264_vf_provider_ops = { |
158 | .peek = vh264_vf_peek, |
159 | .get = vh264_vf_get, |
160 | .put = vh264_vf_put, |
161 | .event_cb = vh264_event_cb, |
162 | .vf_states = vh264_vf_states, |
163 | }; |
164 | |
165 | static struct vframe_provider_s vh264_vf_prov; |
166 | /*TODO irq*/ |
167 | #if 1 |
168 | static u32 frame_buffer_size; |
169 | static u32 frame_width, frame_height, frame_dur, frame_prog, frame_packing_type, |
170 | last_duration; |
171 | static u32 saved_resolution; |
172 | static u32 last_mb_width, last_mb_height; |
173 | #else |
174 | static u32 frame_buffer_size; |
175 | static u32 frame_width, frame_height, frame_dur, frame_prog, last_duration; |
176 | static u32 last_mb_width, last_mb_height; |
177 | static u32 frame_packing_type; |
178 | #endif |
179 | static DECLARE_KFIFO(newframe_q, struct vframe_s *, VF_POOL_SIZE); |
180 | static DECLARE_KFIFO(display_q, struct vframe_s *, VF_POOL_SIZE); |
181 | static DECLARE_KFIFO(recycle_q, struct vframe_s *, VF_POOL_SIZE); |
182 | static DECLARE_KFIFO(delay_display_q, struct vframe_s *, VF_POOL_SIZE); |
183 | |
184 | static struct vframe_s vfpool[VF_POOL_SIZE]; |
185 | static s32 vfbuf_use[VF_BUF_NUM]; |
186 | static struct buffer_spec_s buffer_spec[VF_BUF_NUM]; |
187 | static struct buffer_spec_s fense_buffer_spec[2]; |
188 | static struct vframe_s fense_vf[2]; |
189 | |
190 | static struct timer_list recycle_timer; |
191 | static u32 stat; |
192 | static unsigned long buf_start, buf_end; |
193 | static u32 buf_size; |
194 | static s32 buf_offset; |
195 | static u32 ucode_map_start; |
196 | static u32 pts_outside; |
197 | static u32 sync_outside; |
198 | static u32 dec_control; |
199 | static u32 vh264_ratio; |
200 | static u32 vh264_rotation; |
201 | static u32 use_idr_framerate; |
202 | |
203 | static u32 seq_info; |
204 | static u32 timing_info_present_flag; |
205 | static u32 fixed_frame_rate_flag; |
206 | static u32 fixed_frame_rate_check_count; |
207 | static u32 aspect_ratio_info; |
208 | static u32 num_units_in_tick; |
209 | static u32 time_scale; |
210 | static u32 h264_ar; |
211 | static u32 decoder_debug_flag; |
212 | #ifdef DROP_B_FRAME_FOR_1080P_50_60FPS |
213 | static u32 last_interlaced; |
214 | #endif |
215 | static bool is_4k; |
216 | static unsigned char h264_first_pts_ready; |
217 | static bool h264_first_valid_pts_ready; |
218 | static u32 h264pts1, h264pts2; |
219 | static u32 h264_pts_count, duration_from_pts_done, duration_on_correcting; |
220 | static u32 vh264_error_count; |
221 | static u32 vh264_no_disp_count; |
222 | static u32 fatal_error_flag; |
223 | static u32 fatal_error_reset; |
224 | static u32 max_refer_buf = 1; |
225 | static u32 decoder_force_reset; |
226 | static unsigned int no_idr_error_count; |
227 | static unsigned int no_idr_error_max = 60; |
228 | |
229 | #if 0 |
230 | static u32 vh264_no_disp_wd_count; |
231 | #endif |
232 | static u32 vh264_running; |
233 | static s32 vh264_stream_switching_state; |
234 | static s32 vh264_eos; |
235 | static struct vframe_s *p_last_vf; |
236 | static s32 iponly_early_mode; |
237 | |
238 | /*TODO irq*/ |
239 | #if 1 |
240 | static u32 last_pts, last_pts_remainder; |
241 | #else |
242 | static u32 last_pts; |
243 | #endif |
244 | static bool check_pts_discontinue; |
245 | static u32 wait_buffer_counter; |
246 | static u32 video_signal_from_vui; |
247 | |
248 | static uint error_recovery_mode; |
249 | static uint error_recovery_mode_in = 3; |
250 | static uint error_recovery_mode_use = 3; |
251 | |
252 | static uint mb_total = 0, mb_width = 0, mb_height; |
253 | #define UCODE_IP_ONLY 2 |
254 | #define UCODE_IP_ONLY_PARAM 1 |
255 | static uint ucode_type; |
256 | |
257 | #ifdef DEBUG_PTS |
258 | static unsigned long pts_missed, pts_hit; |
259 | #endif |
260 | static uint debugfirmware; |
261 | |
262 | static atomic_t vh264_active = ATOMIC_INIT(0); |
263 | static int vh264_reset; |
264 | static struct work_struct error_wd_work; |
265 | static struct work_struct stream_switching_work; |
266 | static struct work_struct set_parameter_work; |
267 | |
268 | static struct dec_sysinfo vh264_amstream_dec_info; |
269 | static dma_addr_t mc_dma_handle; |
270 | static void *mc_cpu_addr; |
271 | static u32 first_offset; |
272 | static u32 first_pts; |
273 | static u64 first_pts64; |
274 | static bool first_pts_cached; |
275 | static void *sei_data_buffer; |
276 | static dma_addr_t sei_data_buffer_phys; |
277 | static int clk_adj_frame_count; |
278 | |
279 | #define MC_OFFSET_HEADER 0x0000 |
280 | #define MC_OFFSET_DATA 0x1000 |
281 | #define MC_OFFSET_MMCO 0x2000 |
282 | #define MC_OFFSET_LIST 0x3000 |
283 | #define MC_OFFSET_SLICE 0x4000 |
284 | |
285 | #define MC_TOTAL_SIZE (20*SZ_1K) |
286 | #define MC_SWAP_SIZE (4*SZ_1K) |
287 | |
288 | #define MODE_ERROR 0 |
289 | #define MODE_FULL 1 |
290 | |
291 | static DEFINE_SPINLOCK(lock); |
292 | static DEFINE_SPINLOCK(prepare_lock); |
293 | static DEFINE_SPINLOCK(recycle_lock); |
294 | |
295 | static bool block_display_q; |
296 | static int vh264_stop(int mode); |
297 | static s32 vh264_init(void); |
298 | |
299 | #define DFS_HIGH_THEASHOLD 3 |
300 | |
301 | static bool pts_discontinue; |
302 | #if 0 |
303 | |
304 | static struct ge2d_context_s *ge2d_videoh264_context; |
305 | |
306 | static int ge2d_videoh264task_init(void) |
307 | { |
308 | if (ge2d_videoh264_context == NULL) |
309 | ge2d_videoh264_context = create_ge2d_work_queue(); |
310 | |
311 | if (ge2d_videoh264_context == NULL) { |
312 | pr_info("create_ge2d_work_queue video task failed\n"); |
313 | return -1; |
314 | } |
315 | return 0; |
316 | } |
317 | |
318 | static int ge2d_videoh264task_release(void) |
319 | { |
320 | if (ge2d_videoh264_context) { |
321 | destroy_ge2d_work_queue(ge2d_videoh264_context); |
322 | ge2d_videoh264_context = NULL; |
323 | } |
324 | return 0; |
325 | } |
326 | |
327 | static int ge2d_canvas_dup(struct canvas_s *srcy, struct canvas_s *srcu, |
328 | struct canvas_s *des, int format, u32 srcindex, |
329 | u32 desindex) |
330 | { |
331 | |
332 | struct config_para_ex_s ge2d_config; |
333 | /* pr_info("[%s]h264 ADDR srcy[0x%lx] srcu[0x%lx] des[0x%lx]\n", |
334 | * __func__, srcy->addr, srcu->addr, des->addr); |
335 | */ |
336 | memset(&ge2d_config, 0, sizeof(struct config_para_ex_s)); |
337 | |
338 | ge2d_config.alu_const_color = 0; |
339 | ge2d_config.bitmask_en = 0; |
340 | ge2d_config.src1_gb_alpha = 0; |
341 | |
342 | ge2d_config.src_planes[0].addr = srcy->addr; |
343 | ge2d_config.src_planes[0].w = srcy->width; |
344 | ge2d_config.src_planes[0].h = srcy->height; |
345 | |
346 | ge2d_config.src_planes[1].addr = srcu->addr; |
347 | ge2d_config.src_planes[1].w = srcu->width; |
348 | ge2d_config.src_planes[1].h = srcu->height; |
349 | |
350 | ge2d_config.dst_planes[0].addr = des->addr; |
351 | ge2d_config.dst_planes[0].w = des->width; |
352 | ge2d_config.dst_planes[0].h = des->height; |
353 | |
354 | ge2d_config.src_para.canvas_index = srcindex; |
355 | ge2d_config.src_para.mem_type = CANVAS_TYPE_INVALID; |
356 | ge2d_config.src_para.format = format; |
357 | ge2d_config.src_para.fill_color_en = 0; |
358 | ge2d_config.src_para.fill_mode = 0; |
359 | ge2d_config.src_para.color = 0; |
360 | ge2d_config.src_para.top = 0; |
361 | ge2d_config.src_para.left = 0; |
362 | ge2d_config.src_para.width = srcy->width; |
363 | ge2d_config.src_para.height = srcy->height; |
364 | |
365 | ge2d_config.dst_para.canvas_index = desindex; |
366 | ge2d_config.dst_para.mem_type = CANVAS_TYPE_INVALID; |
367 | ge2d_config.dst_para.format = format; |
368 | ge2d_config.dst_para.fill_color_en = 0; |
369 | ge2d_config.dst_para.fill_mode = 0; |
370 | ge2d_config.dst_para.color = 0; |
371 | ge2d_config.dst_para.top = 0; |
372 | ge2d_config.dst_para.left = 0; |
373 | ge2d_config.dst_para.width = srcy->width; |
374 | ge2d_config.dst_para.height = srcy->height; |
375 | |
376 | if (ge2d_context_config_ex(ge2d_videoh264_context, &ge2d_config) < 0) { |
377 | pr_info("ge2d_context_config_ex failed\n"); |
378 | return -1; |
379 | } |
380 | |
381 | stretchblt_noalpha(ge2d_videoh264_context, 0, 0, srcy->width, |
382 | srcy->height, 0, 0, srcy->width, srcy->height); |
383 | |
384 | return 0; |
385 | } |
386 | #endif/*mask*/ |
387 | |
388 | static inline int fifo_level(void) |
389 | { |
390 | return VF_POOL_SIZE - kfifo_len(&newframe_q); |
391 | } |
392 | |
393 | |
394 | void spec_set_canvas(struct buffer_spec_s *spec, |
395 | unsigned width, unsigned height) |
396 | { |
397 | canvas_config(spec->y_canvas_index, |
398 | spec->y_addr, |
399 | width, height, |
400 | CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); |
401 | |
402 | canvas_config(spec->u_canvas_index, |
403 | spec->u_addr, |
404 | width, height / 2, |
405 | CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32); |
406 | } |
407 | |
408 | static void prepare_display_q(void) |
409 | { |
410 | unsigned long flags; |
411 | int count; |
412 | |
413 | spin_lock_irqsave(&prepare_lock, flags); |
414 | |
415 | if (block_display_q) { |
416 | spin_unlock_irqrestore(&prepare_lock, flags); |
417 | return; |
418 | } |
419 | |
420 | spin_unlock_irqrestore(&prepare_lock, flags); |
421 | |
422 | count = (int)VF_POOL_SIZE - |
423 | kfifo_len(&delay_display_q) - |
424 | kfifo_len(&display_q) - |
425 | kfifo_len(&recycle_q) - |
426 | kfifo_len(&newframe_q); |
427 | |
428 | if ((vh264_stream_switching_state != SWITCHING_STATE_OFF) |
429 | || is_4k) |
430 | count = 0; |
431 | else |
432 | count = (count < 2) ? 0 : 2; |
433 | |
434 | while (kfifo_len(&delay_display_q) > count) { |
435 | struct vframe_s *vf; |
436 | |
437 | if (kfifo_get(&delay_display_q, &vf)) { |
438 | kfifo_put(&display_q, |
439 | (const struct vframe_s *)vf); |
440 | vf_notify_receiver(PROVIDER_NAME, |
441 | VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); |
442 | } |
443 | } |
444 | } |
445 | |
446 | static struct vframe_s *vh264_vf_peek(void *op_arg) |
447 | { |
448 | struct vframe_s *vf; |
449 | |
450 | if (kfifo_peek(&display_q, &vf)) |
451 | return vf; |
452 | |
453 | return NULL; |
454 | } |
455 | |
456 | static struct vframe_s *vh264_vf_get(void *op_arg) |
457 | { |
458 | struct vframe_s *vf; |
459 | |
460 | if (kfifo_get(&display_q, &vf)) |
461 | return vf; |
462 | |
463 | return NULL; |
464 | } |
465 | |
466 | static void vh264_vf_put(struct vframe_s *vf, void *op_arg) |
467 | { |
468 | unsigned long flags; |
469 | |
470 | spin_lock_irqsave(&recycle_lock, flags); |
471 | |
472 | if ((vf != &fense_vf[0]) && (vf != &fense_vf[1])) |
473 | kfifo_put(&recycle_q, (const struct vframe_s *)vf); |
474 | |
475 | spin_unlock_irqrestore(&recycle_lock, flags); |
476 | } |
477 | |
478 | static int vh264_event_cb(int type, void *data, void *private_data) |
479 | { |
480 | if (type & VFRAME_EVENT_RECEIVER_RESET) { |
481 | unsigned long flags; |
482 | |
483 | amvdec_stop(); |
484 | #ifndef CONFIG_POST_PROCESS_MANAGER |
485 | vf_light_unreg_provider(&vh264_vf_prov); |
486 | #endif |
487 | spin_lock_irqsave(&lock, flags); |
488 | vh264_local_init(); |
489 | vh264_prot_init(); |
490 | spin_unlock_irqrestore(&lock, flags); |
491 | #ifndef CONFIG_POST_PROCESS_MANAGER |
492 | vf_reg_provider(&vh264_vf_prov); |
493 | #endif |
494 | amvdec_start(); |
495 | } |
496 | return 0; |
497 | } |
498 | |
499 | static int vh264_vf_states(struct vframe_states *states, void *op_arg) |
500 | { |
501 | unsigned long flags; |
502 | |
503 | spin_lock_irqsave(&lock, flags); |
504 | |
505 | states->vf_pool_size = VF_POOL_SIZE; |
506 | states->buf_free_num = kfifo_len(&newframe_q); |
507 | states->buf_avail_num = kfifo_len(&display_q) + |
508 | kfifo_len(&delay_display_q); |
509 | states->buf_recycle_num = kfifo_len(&recycle_q); |
510 | |
511 | spin_unlock_irqrestore(&lock, flags); |
512 | |
513 | return 0; |
514 | } |
515 | |
516 | #if 0 |
517 | static tvin_trans_fmt_t convert_3d_format(u32 type) |
518 | { |
519 | const tvin_trans_fmt_t conv_tab[] = { |
520 | 0, /* checkerboard */ |
521 | 0, /* column alternation */ |
522 | TVIN_TFMT_3D_LA, /* row alternation */ |
523 | TVIN_TFMT_3D_LRH_OLER, /* side by side */ |
524 | TVIN_TFMT_3D_FA /* top bottom */ |
525 | }; |
526 | |
527 | return (type <= 4) ? conv_tab[type] : 0; |
528 | } |
529 | #endif |
530 | |
531 | static void set_frame_info(struct vframe_s *vf) |
532 | { |
533 | vf->width = frame_width; |
534 | vf->height = frame_height; |
535 | vf->duration = frame_dur; |
536 | vf->ratio_control = |
537 | (min(h264_ar, (u32) DISP_RATIO_ASPECT_RATIO_MAX)) << |
538 | DISP_RATIO_ASPECT_RATIO_BIT; |
539 | vf->orientation = vh264_rotation; |
540 | vf->flag = 0; |
541 | |
542 | #ifdef CONFIG_POST_PROCESS_MANAGER_3D_PROCESS |
543 | vf->trans_fmt = 0; |
544 | if ((vf->trans_fmt == TVIN_TFMT_3D_LRF) || |
545 | (vf->trans_fmt == TVIN_TFMT_3D_LA)) { |
546 | vf->left_eye.start_x = 0; |
547 | vf->left_eye.start_y = 0; |
548 | vf->left_eye.width = frame_width / 2; |
549 | vf->left_eye.height = frame_height; |
550 | |
551 | vf->right_eye.start_x = 0; |
552 | vf->right_eye.start_y = 0; |
553 | vf->right_eye.width = frame_width / 2; |
554 | vf->right_eye.height = frame_height; |
555 | } else if ((vf->trans_fmt == TVIN_TFMT_3D_LRH_OLER) || |
556 | (vf->trans_fmt == TVIN_TFMT_3D_TB)) { |
557 | vf->left_eye.start_x = 0; |
558 | vf->left_eye.start_y = 0; |
559 | vf->left_eye.width = frame_width / 2; |
560 | vf->left_eye.height = frame_height; |
561 | |
562 | vf->right_eye.start_x = 0; |
563 | vf->right_eye.start_y = 0; |
564 | vf->right_eye.width = frame_width / 2; |
565 | vf->right_eye.height = frame_height; |
566 | } |
567 | #endif |
568 | |
569 | } |
570 | |
571 | #ifdef CONFIG_POST_PROCESS_MANAGER |
572 | static void vh264_ppmgr_reset(void) |
573 | { |
574 | vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_RESET, NULL); |
575 | |
576 | vh264_local_init(); |
577 | |
578 | pr_info("vh264dec: vf_ppmgr_reset\n"); |
579 | } |
580 | #endif |
581 | |
582 | static int get_max_dpb_size(int level_idc, int mb_width, int mb_height) |
583 | { |
584 | int size, r; |
585 | |
586 | switch (level_idc) { |
587 | case 10: |
588 | r = 1485; |
589 | break; |
590 | case 11: |
591 | r = 3375; |
592 | break; |
593 | case 12: |
594 | case 13: |
595 | case 20: |
596 | r = 8910; |
597 | break; |
598 | case 21: |
599 | r = 17820; |
600 | break; |
601 | case 22: |
602 | case 30: |
603 | r = 30375; |
604 | break; |
605 | case 31: |
606 | r = 67500; |
607 | break; |
608 | case 32: |
609 | r = 76800; |
610 | break; |
611 | case 40: |
612 | case 41: |
613 | case 42: |
614 | r = 122880; |
615 | break; |
616 | case 50: |
617 | r = 414000; |
618 | break; |
619 | case 51: |
620 | case 52: |
621 | r = 691200; |
622 | break; |
623 | default: |
624 | return 0; |
625 | } |
626 | size = (mb_width * mb_height + |
627 | (mb_width * mb_height / 2)) * 256 * 10; |
628 | r = (r * 1024 + size-1) / size; |
629 | r = min(r, 16); |
630 | /*pr_info("max_dpb %d size:%d\n", r, size);*/ |
631 | return r; |
632 | } |
633 | static void vh264_set_params(struct work_struct *work) |
634 | { |
635 | int aspect_ratio_info_present_flag, aspect_ratio_idc; |
636 | int max_dpb_size, actual_dpb_size, max_reference_size; |
637 | int i, mb_mv_byte, start_addr; |
638 | unsigned long addr; |
639 | unsigned int post_canvas; |
640 | unsigned int frame_mbs_only_flag; |
641 | unsigned int chroma_format_idc, chroma444, video_signal; |
642 | unsigned int crop_infor, crop_bottom, crop_right, level_idc; |
643 | u32 disp_addr = 0xffffffff; |
644 | //struct canvas_s cur_canvas; |
645 | |
646 | if (!atomic_read(&vh264_active)) |
647 | return; |
648 | mutex_lock(&vh264_mutex); |
649 | if (vh264_stream_switching_state == SWITCHING_STATE_ON_CMD1) |
650 | vh264_stream_switching_state = SWITCHING_STATE_ON_CMD1_PENDING; |
651 | post_canvas = get_post_canvas(); |
652 | clk_adj_frame_count = 0; |
653 | /* set to max decoder clock rate at the beginning */ |
654 | vdec_source_changed(VFORMAT_H264, 3840, 2160, 60); |
655 | timing_info_present_flag = 0; |
656 | mb_width = READ_VREG(AV_SCRATCH_1); |
657 | seq_info = READ_VREG(AV_SCRATCH_2); |
658 | aspect_ratio_info = READ_VREG(AV_SCRATCH_3); |
659 | num_units_in_tick = READ_VREG(AV_SCRATCH_4); |
660 | time_scale = READ_VREG(AV_SCRATCH_5); |
661 | level_idc = READ_VREG(AV_SCRATCH_A); |
662 | video_signal = READ_VREG(AV_SCRATCH_H); |
663 | video_signal_from_vui = |
664 | ((video_signal & 0xffff) << 8) | |
665 | ((video_signal & 0xff0000) >> 16) | |
666 | ((video_signal & 0x3f000000)); |
667 | /* |
668 | * pr_info("video_signal_type_present_flag 0x%x\n", |
669 | * (video_signal_from_vui >> 29) & 1); |
670 | * pr_info("video_format 0x%x\n", |
671 | * (video_signal_from_vui >> 26) & 7); |
672 | * pr_info("video_full_range_flag 0x%x\n", |
673 | * (video_signal_from_vui >> 25) & 1); |
674 | * pr_info("color_description_present_flag 0x%x\n", |
675 | * (video_signal_from_vui >> 24) & 1); |
676 | * pr_info("color_primaries 0x%x\n", |
677 | * (video_signal_from_vui >> 16) & 0xff); |
678 | * pr_info("transfer_characteristic 0x%x\n", |
679 | * (video_signal_from_vui >> 8) & 0xff); |
680 | * pr_info("matrix_coefficient 0x%x\n", |
681 | * video_signal_from_vui & 0xff); |
682 | */ |
683 | |
684 | mb_total = (mb_width >> 8) & 0xffff; |
685 | max_reference_size = (mb_width >> 24) & 0x7f; |
686 | mb_mv_byte = (mb_width & 0x80000000) ? 24 : 96; |
687 | if (ucode_type == UCODE_IP_ONLY_PARAM) |
688 | mb_mv_byte = 96; |
689 | mb_width = mb_width & 0xff; |
690 | if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) { |
691 | if (!mb_width && mb_total) |
692 | mb_width = 256; |
693 | } |
694 | mb_height = mb_total / mb_width; |
695 | last_duration = 0; |
696 | /* AV_SCRATCH_2 |
697 | * bit 15: frame_mbs_only_flag |
698 | *bit 13-14: chroma_format_idc |
699 | */ |
700 | frame_mbs_only_flag = (seq_info >> 15) & 0x01; |
701 | chroma_format_idc = (seq_info >> 13) & 0x03; |
702 | chroma444 = (chroma_format_idc == 3) ? 1 : 0; |
703 | |
704 | /* @AV_SCRATCH_6.31-16 = (left << 8 | right ) << 1 |
705 | * @AV_SCRATCH_6.15-0 = (top << 8 | bottom ) << |
706 | * (2 - frame_mbs_only_flag) |
707 | */ |
708 | crop_infor = READ_VREG(AV_SCRATCH_6); |
709 | crop_bottom = (crop_infor & 0xff) >> (2 - frame_mbs_only_flag); |
710 | crop_right = ((crop_infor >> 16) & 0xff) >> (2 - frame_mbs_only_flag); |
711 | |
712 | /* if width or height from outside is not equal to mb, then use mb */ |
713 | /* add: for seeking stream with other resolution */ |
714 | if ((last_mb_width && (last_mb_width != mb_width)) |
715 | || (mb_width != ((frame_width + 15) >> 4))) |
716 | frame_width = 0; |
717 | if ((last_mb_height && (last_mb_height != mb_height)) |
718 | || (mb_height != ((frame_height + 15) >> 4))) |
719 | frame_height = 0; |
720 | last_mb_width = mb_width; |
721 | last_mb_height = mb_height; |
722 | |
723 | if ((frame_width == 0) || (frame_height == 0) || crop_infor) { |
724 | frame_width = mb_width << 4; |
725 | frame_height = mb_height << 4; |
726 | if (frame_mbs_only_flag) { |
727 | frame_height = |
728 | frame_height - (2 >> chroma444) * |
729 | min(crop_bottom, |
730 | (unsigned int)((8 << chroma444) - 1)); |
731 | frame_width = |
732 | frame_width - (2 >> chroma444) * min(crop_right, |
733 | (unsigned |
734 | int)((8 << chroma444) - 1)); |
735 | } else { |
736 | frame_height = |
737 | frame_height - (4 >> chroma444) * |
738 | min(crop_bottom, |
739 | (unsigned int)((8 << chroma444) |
740 | - 1)); |
741 | frame_width = |
742 | frame_width - (4 >> chroma444) * min(crop_right, |
743 | (unsigned |
744 | int)((8 << |
745 | chroma444) |
746 | - 1)); |
747 | } |
748 | #if 0 |
749 | pr_info |
750 | ("frame_mbs_only_flag %d, crop_bottom %d, frame_height %d, ", |
751 | frame_mbs_only_flag, crop_bottom, frame_height); |
752 | pr_info |
753 | ("mb_height %d,crop_right %d, frame_width %d, mb_width %d\n", |
754 | mb_height, crop_right, frame_width, mb_width); |
755 | #endif |
756 | if (frame_height == 1088) |
757 | frame_height = 1080; |
758 | } |
759 | |
760 | mb_width = (mb_width + 3) & 0xfffffffc; |
761 | mb_height = (mb_height + 3) & 0xfffffffc; |
762 | mb_total = mb_width * mb_height; |
763 | |
764 | /*max_reference_size <= max_dpb_size <= actual_dpb_size*/ |
765 | is_4k = (mb_total > 8160) ? true:false; |
766 | if (is_4k) { |
767 | /*4k2k*/ |
768 | if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) { |
769 | max_dpb_size = get_max_dpb_size( |
770 | level_idc, mb_width, mb_height); |
771 | actual_dpb_size = max_dpb_size + 4; |
772 | if (actual_dpb_size > VF_BUF_NUM) |
773 | actual_dpb_size = VF_BUF_NUM; |
774 | } else { |
775 | vh264_running = 0; |
776 | fatal_error_flag = |
777 | DECODER_FATAL_ERROR_SIZE_OVERFLOW; |
778 | mutex_unlock(&vh264_mutex); |
779 | pr_err("oversize ! mb_total %d,\n", mb_total); |
780 | return; |
781 | } |
782 | } else { |
783 | actual_dpb_size = (frame_buffer_size - mb_total * mb_mv_byte * |
784 | max_reference_size) / (mb_total * 384); |
785 | actual_dpb_size = min(actual_dpb_size, VF_BUF_NUM); |
786 | max_dpb_size = get_max_dpb_size(level_idc, mb_width, mb_height); |
787 | if (max_reference_size > 1) |
788 | max_dpb_size = max_reference_size - 1; |
789 | else |
790 | max_dpb_size = max_reference_size; |
791 | if (actual_dpb_size < (max_dpb_size + 4)) { |
792 | actual_dpb_size = max_dpb_size + 4; |
793 | if (actual_dpb_size > VF_BUF_NUM) |
794 | actual_dpb_size = VF_BUF_NUM; |
795 | } |
796 | pr_info("actual_dpb_size %d max_dpb_size %d\n", |
797 | actual_dpb_size, max_dpb_size); |
798 | } |
799 | if (max_dpb_size == 0) |
800 | max_dpb_size = actual_dpb_size; |
801 | else |
802 | max_dpb_size = min(max_dpb_size, actual_dpb_size); |
803 | max_reference_size = min(max_reference_size, actual_dpb_size-1); |
804 | max_dpb_size = max(max_reference_size, max_dpb_size); |
805 | max_reference_size++; |
806 | |
807 | start_addr = addr = buf_start; |
808 | if (is_4k) |
809 | addr += ((mb_total << 8) + (mb_total << 7));/*keep last frame */ |
810 | WRITE_VREG(AV_SCRATCH_1, addr); |
811 | WRITE_VREG(AV_SCRATCH_3, post_canvas); /* should be modified later */ |
812 | /*canvas_read((READ_VCBUS_REG(VD1_IF0_CANVAS0) & 0xff), &cur_canvas); |
813 | disp_addr = (cur_canvas.addr + 7) >> 3;*//*mask*/ |
814 | if ((addr + mb_total * mb_mv_byte * max_reference_size) |
815 | >= buf_end) { |
816 | fatal_error_flag = |
817 | DECODER_FATAL_ERROR_NO_MEM; |
818 | vh264_running = 0; |
819 | mutex_unlock(&vh264_mutex); |
820 | pr_err("mv buf not enough!\n"); |
821 | return; |
822 | } |
823 | addr += mb_total * mb_mv_byte * max_reference_size; |
824 | WRITE_VREG(AV_SCRATCH_4, addr); |
825 | if (!(READ_VREG(AV_SCRATCH_F) & 0x1)) { |
826 | bool use_alloc = is_4k ? true:false; |
827 | int alloc_count = 0; |
828 | |
829 | for (i = 0; i < actual_dpb_size; i++) { |
830 | if (((addr + (mb_total << 8) + (mb_total << 7)) |
831 | >= buf_end) && (!use_alloc)) { |
832 | pr_info("start alloc for %d\n", i); |
833 | use_alloc = true; |
834 | } |
835 | if (use_alloc) { |
836 | #ifdef DOUBLE_WRITE |
837 | int page_count = |
838 | PAGE_ALIGN((mb_total << 8) + (mb_total |
839 | << 7) + (mb_total << 6) + |
840 | (mb_total << 5)) / PAGE_SIZE; |
841 | #else |
842 | int page_count = |
843 | PAGE_ALIGN((mb_total << 8) + |
844 | (mb_total << 7)) / PAGE_SIZE; |
845 | #endif |
846 | if (buffer_spec[i].phy_addr) { |
847 | if (page_count != |
848 | buffer_spec[i].alloc_count) { |
849 | pr_info("Delay release cma buf %d\n", |
850 | i); |
851 | codec_mm_free_for_dma(MEM_NAME, |
852 | buffer_spec[i].phy_addr); |
853 | buffer_spec[i].phy_addr = 0; |
854 | buffer_spec[i].alloc_count = 0; |
855 | } else |
856 | pr_info("Re-use CMA buffer %d\n", i); |
857 | } |
858 | if (!buffer_spec[i].phy_addr) { |
859 | if (!codec_mm_enough_for_size( |
860 | page_count * PAGE_SIZE, 1)) { |
861 | buffer_spec[i].alloc_count = 0; |
862 | fatal_error_flag = |
863 | DECODER_FATAL_ERROR_NO_MEM; |
864 | vh264_running = 0; |
865 | mutex_unlock(&vh264_mutex); |
866 | pr_err("CMA not enough mem! %d\n", |
867 | i); |
868 | return; |
869 | } |
870 | buffer_spec[i].alloc_count = page_count; |
871 | buffer_spec[i].phy_addr = |
872 | codec_mm_alloc_for_dma(MEM_NAME, |
873 | buffer_spec[i].alloc_count, |
874 | 4 + PAGE_SHIFT, |
875 | CODEC_MM_FLAGS_CMA_CLEAR | |
876 | CODEC_MM_FLAGS_FOR_VDECODER); |
877 | pr_info("CMA malloc ok %d\n", i); |
878 | } |
879 | alloc_count++; |
880 | if (!buffer_spec[i].phy_addr) { |
881 | buffer_spec[i].alloc_count = 0; |
882 | pr_err("264-4k mem alloc failed %d\n", |
883 | i); |
884 | vh264_running = 0; |
885 | mutex_unlock(&vh264_mutex); |
886 | return; |
887 | } |
888 | addr = buffer_spec[i].phy_addr; |
889 | } else { |
890 | if (buffer_spec[i].phy_addr) { |
891 | codec_mm_free_for_dma(MEM_NAME, |
892 | buffer_spec[i].phy_addr); |
893 | buffer_spec[i].phy_addr = 0; |
894 | buffer_spec[i].alloc_count = 0; |
895 | } |
896 | } |
897 | /*4k keep last frame */ |
898 | if (is_4k && ((addr + 7) >> 3) == disp_addr) |
899 | addr = start_addr; |
900 | if (i <= 21) { |
901 | buffer_spec[i].y_addr = addr; |
902 | addr += mb_total << 8; |
903 | buffer_spec[i].u_addr = addr; |
904 | buffer_spec[i].v_addr = addr; |
905 | addr += mb_total << 7; |
906 | vfbuf_use[i] = 0; |
907 | |
908 | buffer_spec[i].y_canvas_index = 128 + i * 2; |
909 | buffer_spec[i].u_canvas_index = 128 + i * 2 + 1; |
910 | buffer_spec[i].v_canvas_index = 128 + i * 2 + 1; |
911 | |
912 | buffer_spec[i].y_canvas_width = mb_width << 4; |
913 | buffer_spec[i].y_canvas_height = mb_height << 4; |
914 | buffer_spec[i].u_canvas_width = mb_width << 4; |
915 | buffer_spec[i].u_canvas_height = mb_height << 4; |
916 | buffer_spec[i].v_canvas_width = mb_width << 4; |
917 | buffer_spec[i].v_canvas_height = mb_height << 4; |
918 | |
919 | canvas_config(128 + i * 2, |
920 | buffer_spec[i].y_addr, |
921 | mb_width << 4, mb_height << 4, |
922 | CANVAS_ADDR_NOWRAP, |
923 | CANVAS_BLKMODE_32X32); |
924 | canvas_config(128 + i * 2 + 1, |
925 | buffer_spec[i].u_addr, |
926 | mb_width << 4, mb_height << 3, |
927 | CANVAS_ADDR_NOWRAP, |
928 | CANVAS_BLKMODE_32X32); |
929 | WRITE_VREG(ANC0_CANVAS_ADDR + i, |
930 | spec2canvas(&buffer_spec[i])); |
931 | } else { |
932 | buffer_spec[i].y_canvas_index = |
933 | 2 * (i - 21) + 4; |
934 | buffer_spec[i].y_addr = addr; |
935 | addr += mb_total << 8; |
936 | buffer_spec[i].u_canvas_index = |
937 | 2 * (i - 21) + 5; |
938 | buffer_spec[i].v_canvas_index = |
939 | 2 * (i - 21) + 5; |
940 | buffer_spec[i].u_addr = addr; |
941 | addr += mb_total << 7; |
942 | vfbuf_use[i] = 0; |
943 | |
944 | buffer_spec[i].y_canvas_width = mb_width << 4; |
945 | buffer_spec[i].y_canvas_height = mb_height << 4; |
946 | buffer_spec[i].u_canvas_width = mb_width << 4; |
947 | buffer_spec[i].u_canvas_height = mb_height << 4; |
948 | buffer_spec[i].v_canvas_width = mb_width << 4; |
949 | buffer_spec[i].v_canvas_height = mb_height << 4; |
950 | |
951 | spec_set_canvas(&buffer_spec[i] |
952 | , mb_width << 4, mb_height << 4); |
953 | WRITE_VREG(ANC0_CANVAS_ADDR + i |
954 | , spec2canvas(&buffer_spec[i])); |
955 | } |
956 | } |
957 | } else |
958 | addr = buf_start + mb_total * 384 * actual_dpb_size; |
959 | |
960 | timing_info_present_flag = seq_info & 0x2; |
961 | fixed_frame_rate_flag = 0; |
962 | aspect_ratio_info_present_flag = seq_info & 0x1; |
963 | aspect_ratio_idc = (seq_info >> 16) & 0xff; |
964 | |
965 | if (timing_info_present_flag) { |
966 | fixed_frame_rate_flag = seq_info & 0x40; |
967 | |
968 | if (((num_units_in_tick * 120) >= time_scale |
969 | && ((!sync_outside) || (!frame_dur))) && |
970 | num_units_in_tick |
971 | && time_scale) { |
972 | if (use_idr_framerate || !frame_dur |
973 | || !duration_from_pts_done || vh264_running) { |
974 | u32 frame_dur_es = |
975 | div_u64(96000ULL * 2 * |
976 | num_units_in_tick, |
977 | time_scale); |
978 | |
979 | /* hack to avoid use ES frame duration |
980 | * when it's half of the rate from |
981 | * system info |
982 | */ |
983 | /* sometimes the encoder is given a wrong |
984 | * frame rate but the system side information |
985 | *is more reliable |
986 | */ |
987 | if ((frame_dur * 2) != frame_dur_es) |
988 | frame_dur = frame_dur_es; |
989 | } |
990 | } |
991 | } else |
992 | pr_info("H.264: timing_info not present\n"); |
993 | |
994 | if (aspect_ratio_info_present_flag) { |
995 | if (aspect_ratio_idc == EXTEND_SAR) { |
996 | h264_ar = |
997 | div_u64(256ULL * (aspect_ratio_info >> 16) * |
998 | frame_height, |
999 | (aspect_ratio_info & 0xffff) * |
1000 | frame_width); |
1001 | } else { |
1002 | /* pr_info("v264dec: aspect_ratio_idc = %d\n", |
1003 | * aspect_ratio_idc); |
1004 | */ |
1005 | |
1006 | switch (aspect_ratio_idc) { |
1007 | case 1: |
1008 | h264_ar = 0x100 * frame_height / frame_width; |
1009 | break; |
1010 | case 2: |
1011 | h264_ar = 0x100 * frame_height * 11 / |
1012 | (frame_width * 12); |
1013 | break; |
1014 | case 3: |
1015 | h264_ar = 0x100 * frame_height * 11 / |
1016 | (frame_width * 10); |
1017 | break; |
1018 | case 4: |
1019 | h264_ar = 0x100 * frame_height * 11 / |
1020 | (frame_width * 16); |
1021 | break; |
1022 | case 5: |
1023 | h264_ar = 0x100 * frame_height * 33 / |
1024 | (frame_width * 40); |
1025 | break; |
1026 | case 6: |
1027 | h264_ar = 0x100 * frame_height * 11 / |
1028 | (frame_width * 24); |
1029 | break; |
1030 | case 7: |
1031 | h264_ar = 0x100 * frame_height * 11 / |
1032 | (frame_width * 20); |
1033 | break; |
1034 | case 8: |
1035 | h264_ar = 0x100 * frame_height * 11 / |
1036 | (frame_width * 32); |
1037 | break; |
1038 | case 9: |
1039 | h264_ar = 0x100 * frame_height * 33 / |
1040 | (frame_width * 80); |
1041 | break; |
1042 | case 10: |
1043 | h264_ar = 0x100 * frame_height * 11 / |
1044 | (frame_width * 18); |
1045 | break; |
1046 | case 11: |
1047 | h264_ar = 0x100 * frame_height * 11 / |
1048 | (frame_width * 15); |
1049 | break; |
1050 | case 12: |
1051 | h264_ar = 0x100 * frame_height * 33 / |
1052 | (frame_width * 64); |
1053 | break; |
1054 | case 13: |
1055 | h264_ar = 0x100 * frame_height * 99 / |
1056 | (frame_width * 160); |
1057 | break; |
1058 | case 14: |
1059 | h264_ar = 0x100 * frame_height * 3 / |
1060 | (frame_width * 4); |
1061 | break; |
1062 | case 15: |
1063 | h264_ar = 0x100 * frame_height * 2 / |
1064 | (frame_width * 3); |
1065 | break; |
1066 | case 16: |
1067 | h264_ar = 0x100 * frame_height * 1 / |
1068 | (frame_width * 2); |
1069 | break; |
1070 | default: |
1071 | if (vh264_ratio >> 16) { |
1072 | h264_ar = (frame_height * |
1073 | (vh264_ratio & 0xffff) * |
1074 | 0x100 + |
1075 | ((vh264_ratio >> 16) * |
1076 | frame_width / 2)) / |
1077 | ((vh264_ratio >> 16) * |
1078 | frame_width); |
1079 | } else { |
1080 | h264_ar = frame_height * 0x100 / |
1081 | frame_width; |
1082 | } |
1083 | break; |
1084 | } |
1085 | } |
1086 | } else { |
1087 | pr_info("v264dec: aspect_ratio not available from source\n"); |
1088 | if (vh264_ratio >> 16) { |
1089 | /* high 16 bit is width, low 16 bit is height */ |
1090 | h264_ar = |
1091 | ((vh264_ratio & 0xffff) * frame_height * 0x100 + |
1092 | (vh264_ratio >> 16) * frame_width / 2) / |
1093 | ((vh264_ratio >> 16) * frame_width); |
1094 | } else |
1095 | h264_ar = frame_height * 0x100 / frame_width; |
1096 | } |
1097 | |
1098 | WRITE_VREG(AV_SCRATCH_0, |
1099 | (max_reference_size << 24) | (actual_dpb_size << 16) | |
1100 | (max_dpb_size << 8)); |
1101 | if (vh264_stream_switching_state != SWITCHING_STATE_OFF) { |
1102 | vh264_stream_switching_state = SWITCHING_STATE_OFF; |
1103 | pr_info("Leaving switching mode.\n"); |
1104 | } |
1105 | mutex_unlock(&vh264_mutex); |
1106 | } |
1107 | |
1108 | static unsigned pts_inc_by_duration(unsigned *new_pts, unsigned *new_pts_rem) |
1109 | { |
1110 | unsigned r, rem; |
1111 | |
1112 | r = last_pts + DUR2PTS(frame_dur); |
1113 | rem = last_pts_remainder + DUR2PTS_REM(frame_dur); |
1114 | |
1115 | if (rem >= 96) { |
1116 | r++; |
1117 | rem -= 96; |
1118 | } |
1119 | |
1120 | if (new_pts) |
1121 | *new_pts = r; |
1122 | if (new_pts_rem) |
1123 | *new_pts_rem = rem; |
1124 | |
1125 | return r; |
1126 | } |
1127 | static inline bool vh264_isr_parser(struct vframe_s *vf, |
1128 | unsigned int pts_valid, unsigned int buffer_index, |
1129 | unsigned int pts) |
1130 | { |
1131 | unsigned int pts_duration = 0; |
1132 | |
1133 | if (h264_first_pts_ready == 0) { |
1134 | if (pts_valid == 0) { |
1135 | vfbuf_use[buffer_index]++; |
1136 | vf->index = buffer_index; |
1137 | kfifo_put(&recycle_q, |
1138 | (const struct vframe_s *)vf); |
1139 | return false; |
1140 | } |
1141 | |
1142 | h264pts1 = pts; |
1143 | h264_pts_count = 0; |
1144 | h264_first_pts_ready = 1; |
1145 | } else { |
1146 | |
1147 | if (pts_valid && (pts > h264pts1) && (h264_pts_count > 24) |
1148 | && (duration_from_pts_done == 0)) { |
1149 | unsigned int |
1150 | old_duration = frame_dur; |
1151 | h264pts2 = pts; |
1152 | |
1153 | pts_duration = (h264pts2 - h264pts1) * 16 / |
1154 | (h264_pts_count * 15); |
1155 | |
1156 | if ((pts_duration != frame_dur) |
1157 | && (!pts_outside)) { |
1158 | if (use_idr_framerate) { |
1159 | bool pts_c_24 = close_to(pts_duration, |
1160 | RATE_24_FPS, |
1161 | RATE_CORRECTION_THRESHOLD); |
1162 | bool frm_c_25 = close_to(frame_dur, |
1163 | RATE_25_FPS, |
1164 | RATE_CORRECTION_THRESHOLD); |
1165 | bool pts_c_25 = close_to(pts_duration, |
1166 | RATE_25_FPS, |
1167 | RATE_CORRECTION_THRESHOLD); |
1168 | bool frm_c_24 = close_to(frame_dur, |
1169 | RATE_24_FPS, |
1170 | RATE_CORRECTION_THRESHOLD); |
1171 | if ((pts_c_24 && frm_c_25) |
1172 | || (pts_c_25 && frm_c_24)) { |
1173 | pr_info |
1174 | ("H.264:Correct frame dur "); |
1175 | pr_info |
1176 | (" from %d to duration based ", |
1177 | frame_dur); |
1178 | pr_info |
1179 | ("on PTS %d ---\n", |
1180 | pts_duration); |
1181 | frame_dur = pts_duration; |
1182 | duration_from_pts_done = 1; |
1183 | } else if (((frame_dur < 96000 / 240) |
1184 | && (pts_duration > 96000 / 240)) |
1185 | || (!duration_on_correcting && |
1186 | !frm_c_25 && !frm_c_24)) { |
1187 | /* fft: if the frame rate is |
1188 | * not regular, use the |
1189 | * calculate rate insteadof. |
1190 | */ |
1191 | pr_info |
1192 | ("H.264:Correct frame dur "); |
1193 | pr_info |
1194 | (" from %d to duration based ", |
1195 | frame_dur); |
1196 | pr_info |
1197 | ("on PTS %d ---\n", |
1198 | pts_duration); |
1199 | frame_dur = pts_duration; |
1200 | duration_on_correcting = 1; |
1201 | } |
1202 | } else { |
1203 | if (close_to(pts_duration, |
1204 | frame_dur, 2000)) { |
1205 | frame_dur = pts_duration; |
1206 | pr_info |
1207 | ("used calculate frame rate,"); |
1208 | pr_info("on duration =%d\n", |
1209 | frame_dur); |
1210 | } else { |
1211 | pr_info |
1212 | ("don't use calculate frame "); |
1213 | pr_info |
1214 | ("rate pts_duration =%d\n", |
1215 | pts_duration); |
1216 | } |
1217 | } |
1218 | } |
1219 | |
1220 | if (duration_from_pts_done == 0) { |
1221 | if (close_to |
1222 | (pts_duration, |
1223 | old_duration, |
1224 | RATE_CORRECTION_THRESHOLD)) { |
1225 | pr_info |
1226 | ("finished correct frame dur"); |
1227 | pr_info |
1228 | (" new=%d,old_duration=%d,cnt=%d\n", |
1229 | pts_duration, |
1230 | old_duration, |
1231 | h264_pts_count); |
1232 | duration_from_pts_done = 1; |
1233 | } else { /*not the same,redo it. */ |
1234 | if (!close_to(pts_duration, |
1235 | old_duration, 1000) && |
1236 | !close_to(pts_duration, |
1237 | frame_dur, 1000) && |
1238 | close_to(pts_duration, |
1239 | last_duration, 200)) { |
1240 | /* yangle: frame_dur must |
1241 | * wrong,recover it. |
1242 | */ |
1243 | frame_dur = pts_duration; |
1244 | } |
1245 | |
1246 | pr_info |
1247 | ("restart correct frame duration "); |
1248 | pr_info |
1249 | ("new=%d,old_duration=%d,cnt=%d\n", |
1250 | pts_duration, |
1251 | old_duration, |
1252 | h264_pts_count); |
1253 | h264pts1 = h264pts2; |
1254 | h264_pts_count = 0; |
1255 | duration_from_pts_done = 0; |
1256 | } |
1257 | } |
1258 | last_duration = pts_duration; |
1259 | } |
1260 | } |
1261 | return true; |
1262 | } |
1263 | #ifdef HANDLE_H264_IRQ |
1264 | static irqreturn_t vh264_isr(int irq, void *dev_id) |
1265 | #else |
1266 | static void vh264_isr(void) |
1267 | #endif |
1268 | { |
1269 | unsigned int buffer_index; |
1270 | struct vframe_s *vf; |
1271 | unsigned int cpu_cmd; |
1272 | unsigned int pts, pts_lookup_save, pts_valid_save, pts_valid = 0; |
1273 | unsigned int pts_us64_valid = 0; |
1274 | u64 pts_us64; |
1275 | bool force_interlaced_frame = false; |
1276 | unsigned int sei_itu35_flags; |
1277 | static const unsigned int idr_num = |
1278 | FIX_FRAME_RATE_CHECK_IDRFRAME_NUM; |
1279 | static const unsigned int flg_1080_itl = |
1280 | DEC_CONTROL_FLAG_FORCE_2997_1080P_INTERLACE; |
1281 | static const unsigned int flg_576_itl = |
1282 | DEC_CONTROL_FLAG_FORCE_2500_576P_INTERLACE; |
1283 | |
1284 | WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); |
1285 | |
1286 | if (0 == (stat & STAT_VDEC_RUN)) { |
1287 | pr_info("decoder is not running\n"); |
1288 | #ifdef HANDLE_H264_IRQ |
1289 | return IRQ_HANDLED; |
1290 | #else |
1291 | return; |
1292 | #endif |
1293 | } |
1294 | |
1295 | cpu_cmd = READ_VREG(AV_SCRATCH_0); |
1296 | |
1297 | #ifdef DROP_B_FRAME_FOR_1080P_50_60FPS |
1298 | if ((frame_dur < 2004) && |
1299 | (frame_width >= 1400) && |
1300 | (frame_height >= 1000) && (last_interlaced == 0)) |
1301 | SET_VREG_MASK(AV_SCRATCH_F, 0x8); |
1302 | #endif |
1303 | if ((decoder_force_reset == 1) |
1304 | || ((error_recovery_mode != 1) |
1305 | && (no_idr_error_count >= no_idr_error_max) |
1306 | && (ucode_type != UCODE_IP_ONLY_PARAM))) { |
1307 | vh264_running = 0; |
1308 | pr_info("force reset decoder %d!!!\n", no_idr_error_count); |
1309 | schedule_work(&error_wd_work); |
1310 | decoder_force_reset = 0; |
1311 | no_idr_error_count = 0; |
1312 | } else if ((cpu_cmd & 0xff) == 1) { |
1313 | if (unlikely |
1314 | (vh264_running |
1315 | && (kfifo_len(&newframe_q) != VF_POOL_SIZE))) { |
1316 | /* a cmd 1 sent during decoding w/o getting a cmd 3. */ |
1317 | /* should not happen but the original code has such |
1318 | * case, do the same process |
1319 | */ |
1320 | if ((READ_VREG(AV_SCRATCH_1) & 0xff) |
1321 | == 1) {/*invalid mb_width*/ |
1322 | vh264_running = 0; |
1323 | fatal_error_flag = DECODER_FATAL_ERROR_UNKNOWN; |
1324 | /* this is fatal error, need restart */ |
1325 | pr_info("cmd 1 fatal error happened\n"); |
1326 | schedule_work(&error_wd_work); |
1327 | } else { |
1328 | vh264_stream_switching_state = SWITCHING_STATE_ON_CMD1; |
1329 | pr_info("Enter switching mode cmd1.\n"); |
1330 | schedule_work(&stream_switching_work); |
1331 | } |
1332 | return IRQ_HANDLED; |
1333 | } |
1334 | pr_info("Enter set parameter cmd1.\n"); |
1335 | schedule_work(&set_parameter_work); |
1336 | return IRQ_HANDLED; |
1337 | } else if ((cpu_cmd & 0xff) == 2) { |
1338 | int frame_mb_only, pic_struct_present, pic_struct, prog_frame, |
1339 | poc_sel, idr_flag, eos, error; |
1340 | int i, status, num_frame, b_offset; |
1341 | int current_error_count, slice_type; |
1342 | |
1343 | vh264_running = 1; |
1344 | vh264_no_disp_count = 0; |
1345 | num_frame = (cpu_cmd >> 8) & 0xff; |
1346 | frame_mb_only = seq_info & 0x8000; |
1347 | pic_struct_present = seq_info & 0x10; |
1348 | |
1349 | current_error_count = READ_VREG(AV_SCRATCH_D); |
1350 | if (vh264_error_count != current_error_count) { |
1351 | /* pr_info("decoder error happened, count %d\n", |
1352 | * current_error_count); |
1353 | */ |
1354 | vh264_error_count = current_error_count; |
1355 | } |
1356 | |
1357 | for (i = 0; (i < num_frame) && (!vh264_eos); i++) { |
1358 | status = READ_VREG(AV_SCRATCH_1 + i); |
1359 | buffer_index = status & 0x1f; |
1360 | error = status & 0x200; |
1361 | slice_type = (READ_VREG(AV_SCRATCH_H) >> (i * 4)) & 0xf; |
1362 | |
1363 | if ((error_recovery_mode_use & 2) && error) |
1364 | check_pts_discontinue = true; |
1365 | if (ucode_type == UCODE_IP_ONLY_PARAM |
1366 | && iponly_early_mode) |
1367 | continue; |
1368 | if ((p_last_vf != NULL) |
1369 | && (p_last_vf->index == buffer_index)) |
1370 | continue; |
1371 | |
1372 | if (buffer_index >= VF_BUF_NUM) |
1373 | continue; |
1374 | |
1375 | pic_struct = (status >> 5) & 0x7; |
1376 | prog_frame = status & 0x100; |
1377 | poc_sel = status & 0x200; |
1378 | idr_flag = status & 0x400; |
1379 | frame_packing_type = (status >> 12) & 0x7; |
1380 | eos = (status >> 15) & 1; |
1381 | |
1382 | if (eos) |
1383 | vh264_eos = 1; |
1384 | |
1385 | b_offset = (status >> 16) & 0xffff; |
1386 | |
1387 | if (error) |
1388 | no_idr_error_count++; |
1389 | if (idr_flag || |
1390 | (!error && (slice_type != SLICE_TYPE_I))) |
1391 | no_idr_error_count = 0; |
1392 | |
1393 | if (decoder_debug_flag) { |
1394 | pr_info |
1395 | ("slice_type %x idr %x error %x count %d", |
1396 | slice_type, idr_flag, error, |
1397 | no_idr_error_count); |
1398 | pr_info(" prog %x pic_struct %x offset %x\n", |
1399 | prog_frame, pic_struct, b_offset); |
1400 | } |
1401 | #ifdef DROP_B_FRAME_FOR_1080P_50_60FPS |
1402 | last_interlaced = prog_frame ? 0 : 1; |
1403 | #endif |
1404 | if (kfifo_get(&newframe_q, &vf) == 0) { |
1405 | pr_info |
1406 | ("fatal error, no available buffer slot."); |
1407 | return IRQ_HANDLED; |
1408 | } |
1409 | |
1410 | if (clk_adj_frame_count < VDEC_CLOCK_ADJUST_FRAME) |
1411 | clk_adj_frame_count++; |
1412 | |
1413 | set_frame_info(vf); |
1414 | |
1415 | switch (i) { |
1416 | case 0: |
1417 | b_offset |= |
1418 | (READ_VREG(AV_SCRATCH_A) & 0xffff) |
1419 | << 16; |
1420 | break; |
1421 | case 1: |
1422 | b_offset |= |
1423 | READ_VREG(AV_SCRATCH_A) & 0xffff0000; |
1424 | break; |
1425 | case 2: |
1426 | b_offset |= |
1427 | (READ_VREG(AV_SCRATCH_B) & 0xffff) |
1428 | << 16; |
1429 | break; |
1430 | case 3: |
1431 | b_offset |= |
1432 | READ_VREG(AV_SCRATCH_B) & 0xffff0000; |
1433 | break; |
1434 | case 4: |
1435 | b_offset |= |
1436 | (READ_VREG(AV_SCRATCH_C) & 0xffff) |
1437 | << 16; |
1438 | break; |
1439 | case 5: |
1440 | b_offset |= |
1441 | READ_VREG(AV_SCRATCH_C) & 0xffff0000; |
1442 | break; |
1443 | default: |
1444 | break; |
1445 | } |
1446 | |
1447 | /* add 64bit pts us ; */ |
1448 | if (unlikely |
1449 | ((b_offset == first_offset) |
1450 | && (first_pts_cached))) { |
1451 | pts = first_pts; |
1452 | pts_us64 = first_pts64; |
1453 | first_pts_cached = false; |
1454 | pts_valid = 1; |
1455 | pts_us64_valid = 1; |
1456 | #ifdef DEBUG_PTS |
1457 | pts_hit++; |
1458 | #endif |
1459 | } else if (pts_lookup_offset_us64 |
1460 | (PTS_TYPE_VIDEO, b_offset, &pts, 0, |
1461 | &pts_us64) == 0) { |
1462 | pts_valid = 1; |
1463 | pts_us64_valid = 1; |
1464 | #ifdef DEBUG_PTS |
1465 | pts_hit++; |
1466 | #endif |
1467 | } else { |
1468 | pts_valid = 0; |
1469 | pts_us64_valid = 0; |
1470 | #ifdef DEBUG_PTS |
1471 | pts_missed++; |
1472 | #endif |
1473 | } |
1474 | |
1475 | /* on second IDR frame,check the diff between pts |
1476 | * compute from duration and pts from lookup , |
1477 | * if large than frame_dur,we think it is uncorrect. |
1478 | */ |
1479 | pts_lookup_save = pts; |
1480 | pts_valid_save = pts_valid; |
1481 | if (fixed_frame_rate_flag |
1482 | && (fixed_frame_rate_check_count <= |
1483 | idr_num)) { |
1484 | if (idr_flag && pts_valid) { |
1485 | fixed_frame_rate_check_count++; |
1486 | /* pr_info("diff:%d\n", |
1487 | * last_pts - pts_lookup_save); |
1488 | */ |
1489 | if ((fixed_frame_rate_check_count == |
1490 | idr_num) && |
1491 | (abs(pts - (last_pts + |
1492 | DUR2PTS(frame_dur))) > |
1493 | DUR2PTS(frame_dur))) { |
1494 | fixed_frame_rate_flag = 0; |
1495 | pr_info("pts sync mode play\n"); |
1496 | } |
1497 | |
1498 | if (fixed_frame_rate_flag |
1499 | && (fixed_frame_rate_check_count |
1500 | > idr_num)) { |
1501 | pr_info |
1502 | ("fix_frame_rate mode play\n"); |
1503 | } |
1504 | } |
1505 | } |
1506 | |
1507 | if (READ_VREG(AV_SCRATCH_F) & 2) { |
1508 | /* for I only mode, ignore the PTS information |
1509 | * and only uses frame duration for each I |
1510 | * frame decoded |
1511 | */ |
1512 | if (p_last_vf) |
1513 | pts_valid = 0; |
1514 | /* also skip frame duration calculation |
1515 | * based on PTS |
1516 | */ |
1517 | duration_from_pts_done = 1; |
1518 | /* and add a default duration for 1/30 second |
1519 | * if there is no valid frame |
1520 | * duration available |
1521 | */ |
1522 | if (frame_dur == 0) |
1523 | frame_dur = 96000 / 30; |
1524 | } |
1525 | |
1526 | if (sync_outside == 0) { |
1527 | if (!vh264_isr_parser(vf, |
1528 | pts_valid, buffer_index, pts)) |
1529 | continue; |
1530 | |
1531 | h264_pts_count++; |
1532 | } else { |
1533 | if (!idr_flag) |
1534 | pts_valid = 0; |
1535 | } |
1536 | |
1537 | if (pts_valid && !pts_discontinue) { |
1538 | pts_discontinue = |
1539 | (abs(last_pts - pts) >= |
1540 | tsync_vpts_discontinuity_margin()); |
1541 | } |
1542 | /* if use_idr_framerate or fixed frame rate, only |
1543 | * use PTS for IDR frames except for pts discontinue |
1544 | */ |
1545 | if (timing_info_present_flag && |
1546 | frame_dur && |
1547 | (use_idr_framerate || |
1548 | (fixed_frame_rate_flag != 0)) |
1549 | && pts_valid && h264_first_valid_pts_ready |
1550 | && (!pts_discontinue)) { |
1551 | pts_valid = |
1552 | (slice_type == SLICE_TYPE_I) ? 1 : 0; |
1553 | } |
1554 | |
1555 | if (!h264_first_valid_pts_ready && pts_valid) { |
1556 | h264_first_valid_pts_ready = true; |
1557 | last_pts = pts - DUR2PTS(frame_dur); |
1558 | last_pts_remainder = 0; |
1559 | } |
1560 | /* calculate PTS of next frame and smooth |
1561 | * PTS for fixed rate source |
1562 | */ |
1563 | if (pts_valid) { |
1564 | if ((fixed_frame_rate_flag) && |
1565 | (!pts_discontinue) && |
1566 | (abs(pts_inc_by_duration(NULL, NULL) |
1567 | - pts) |
1568 | < DUR2PTS(frame_dur))) { |
1569 | pts = pts_inc_by_duration(&pts, |
1570 | &last_pts_remainder); |
1571 | } else |
1572 | last_pts_remainder = 0; |
1573 | |
1574 | } else { |
1575 | if (fixed_frame_rate_flag && !pts_discontinue && |
1576 | (fixed_frame_rate_check_count > idr_num) && |
1577 | pts_valid_save && (sync_outside == 0) && |
1578 | (abs(pts_inc_by_duration(NULL, NULL) - pts) |
1579 | > DUR2PTS(frame_dur))) { |
1580 | duration_from_pts_done = 0; |
1581 | pr_info("recalc frame_dur\n"); |
1582 | } else |
1583 | pts = pts_inc_by_duration(&pts, |
1584 | &last_pts_remainder); |
1585 | pts_valid = 1; |
1586 | } |
1587 | |
1588 | if ((dec_control & |
1589 | flg_1080_itl) |
1590 | && (frame_width == 1920) |
1591 | && (frame_height >= 1080) |
1592 | && (vf->duration == 3203)) |
1593 | force_interlaced_frame = true; |
1594 | else if ((dec_control & |
1595 | flg_576_itl) |
1596 | && (frame_width == 720) |
1597 | && (frame_height == 576) |
1598 | && (vf->duration == 3840)) |
1599 | force_interlaced_frame = true; |
1600 | |
1601 | /* for frames with PTS, check if there is PTS |
1602 | * discontinue based on previous frames |
1603 | * (including error frames), |
1604 | * force no VPTS discontinue reporting if we saw |
1605 | *errors earlier but only once. |
1606 | */ |
1607 | if ((pts_valid) && (check_pts_discontinue) |
1608 | && (!error)) { |
1609 | if (pts_discontinue) { |
1610 | vf->flag = 0; |
1611 | check_pts_discontinue = false; |
1612 | } else if ((pts - last_pts) < 90000) { |
1613 | vf->flag = VFRAME_FLAG_NO_DISCONTINUE; |
1614 | check_pts_discontinue = false; |
1615 | } |
1616 | } |
1617 | |
1618 | last_pts = pts; |
1619 | |
1620 | if (fixed_frame_rate_flag |
1621 | && (fixed_frame_rate_check_count <= |
1622 | idr_num) |
1623 | && (sync_outside == 0) |
1624 | && pts_valid_save) |
1625 | pts = pts_lookup_save; |
1626 | |
1627 | if (pic_struct_present) { |
1628 | if ((pic_struct == PIC_TOP_BOT) |
1629 | || (pic_struct == PIC_BOT_TOP)) |
1630 | prog_frame = 0; |
1631 | } |
1632 | |
1633 | if ((!force_interlaced_frame) |
1634 | && (prog_frame |
1635 | || (pic_struct_present |
1636 | && pic_struct |
1637 | <= PIC_TRIPLE_FRAME))) { |
1638 | if (pic_struct_present) { |
1639 | if (pic_struct == PIC_TOP_BOT_TOP |
1640 | || pic_struct |
1641 | == PIC_BOT_TOP_BOT) { |
1642 | vf->duration += |
1643 | vf->duration >> 1; |
1644 | } else if (pic_struct == |
1645 | PIC_DOUBLE_FRAME) |
1646 | vf->duration += vf->duration; |
1647 | else if (pic_struct == |
1648 | PIC_TRIPLE_FRAME) { |
1649 | vf->duration += |
1650 | vf->duration << 1; |
1651 | } |
1652 | } |
1653 | |
1654 | last_pts = |
1655 | last_pts + DUR2PTS(vf->duration - |
1656 | frame_dur); |
1657 | |
1658 | vf->index = buffer_index; |
1659 | vf->type = |
1660 | VIDTYPE_PROGRESSIVE | |
1661 | VIDTYPE_VIU_FIELD | |
1662 | VIDTYPE_VIU_NV21; |
1663 | vf->duration_pulldown = 0; |
1664 | vf->signal_type = video_signal_from_vui; |
1665 | vf->index = buffer_index; |
1666 | vf->pts = (pts_valid) ? pts : 0; |
1667 | if (pts_us64_valid == 1) |
1668 | vf->pts_us64 = pts_us64; |
1669 | else |
1670 | vf->pts_us64 = div64_u64(((u64)vf->pts)*100, 9); |
1671 | vf->canvas0Addr = vf->canvas1Addr = |
1672 | spec2canvas(&buffer_spec[buffer_index]); |
1673 | vf->type_original = vf->type; |
1674 | vfbuf_use[buffer_index]++; |
1675 | |
1676 | if ((error_recovery_mode_use & 2) && error) { |
1677 | kfifo_put(&recycle_q, |
1678 | (const struct vframe_s *)vf); |
1679 | } else { |
1680 | p_last_vf = vf; |
1681 | pts_discontinue = false; |
1682 | kfifo_put(&delay_display_q, |
1683 | (const struct vframe_s *)vf); |
1684 | } |
1685 | } else { |
1686 | if (pic_struct_present |
1687 | && pic_struct == PIC_TOP_BOT) |
1688 | vf->type = VIDTYPE_INTERLACE_TOP; |
1689 | else if (pic_struct_present |
1690 | && pic_struct == PIC_BOT_TOP) |
1691 | vf->type = VIDTYPE_INTERLACE_BOTTOM; |
1692 | else { |
1693 | vf->type = |
1694 | poc_sel ? |
1695 | VIDTYPE_INTERLACE_BOTTOM : |
1696 | VIDTYPE_INTERLACE_TOP; |
1697 | } |
1698 | vf->type |= VIDTYPE_VIU_NV21; |
1699 | vf->type |= VIDTYPE_INTERLACE_FIRST; |
1700 | |
1701 | vf->duration >>= 1; |
1702 | vf->duration_pulldown = 0; |
1703 | vf->signal_type = video_signal_from_vui; |
1704 | vf->index = buffer_index; |
1705 | vf->pts = (pts_valid) ? pts : 0; |
1706 | if (pts_us64_valid == 1) |
1707 | vf->pts_us64 = pts_us64; |
1708 | else |
1709 | vf->pts_us64 = div64_u64(((u64)vf->pts)*100, 9); |
1710 | vf->canvas0Addr = vf->canvas1Addr = |
1711 | spec2canvas(&buffer_spec[buffer_index]); |
1712 | vf->type_original = vf->type; |
1713 | vfbuf_use[buffer_index]++; |
1714 | vf->ready_jiffies64 = jiffies_64; |
1715 | |
1716 | if ((error_recovery_mode_use & 2) && error) { |
1717 | kfifo_put(&recycle_q, |
1718 | (const struct vframe_s *)vf); |
1719 | continue; |
1720 | } else { |
1721 | pts_discontinue = false; |
1722 | kfifo_put(&delay_display_q, |
1723 | (const struct vframe_s *)vf); |
1724 | } |
1725 | |
1726 | if (READ_VREG(AV_SCRATCH_F) & 2) |
1727 | continue; |
1728 | |
1729 | if (kfifo_get(&newframe_q, &vf) == 0) { |
1730 | pr_info |
1731 | ("fatal error, no avail buffer slot."); |
1732 | return IRQ_HANDLED; |
1733 | } |
1734 | |
1735 | set_frame_info(vf); |
1736 | |
1737 | if (pic_struct_present |
1738 | && pic_struct == PIC_TOP_BOT) |
1739 | vf->type = VIDTYPE_INTERLACE_BOTTOM; |
1740 | else if (pic_struct_present |
1741 | && pic_struct == PIC_BOT_TOP) |
1742 | vf->type = VIDTYPE_INTERLACE_TOP; |
1743 | else { |
1744 | vf->type = |
1745 | poc_sel ? |
1746 | VIDTYPE_INTERLACE_TOP : |
1747 | VIDTYPE_INTERLACE_BOTTOM; |
1748 | } |
1749 | |
1750 | vf->type |= VIDTYPE_VIU_NV21; |
1751 | vf->duration >>= 1; |
1752 | vf->duration_pulldown = 0; |
1753 | vf->signal_type = video_signal_from_vui; |
1754 | vf->index = buffer_index; |
1755 | vf->pts = 0; |
1756 | vf->pts_us64 = 0; |
1757 | vf->canvas0Addr = vf->canvas1Addr = |
1758 | spec2canvas(&buffer_spec[buffer_index]); |
1759 | vf->type_original = vf->type; |
1760 | vfbuf_use[buffer_index]++; |
1761 | |
1762 | p_last_vf = vf; |
1763 | vf->ready_jiffies64 = jiffies_64; |
1764 | |
1765 | kfifo_put(&delay_display_q, |
1766 | (const struct vframe_s *)vf); |
1767 | } |
1768 | } |
1769 | |
1770 | WRITE_VREG(AV_SCRATCH_0, 0); |
1771 | } else if ((cpu_cmd & 0xff) == 3) { |
1772 | vh264_running = 1; |
1773 | vh264_stream_switching_state = SWITCHING_STATE_ON_CMD3; |
1774 | |
1775 | pr_info("Enter switching mode cmd3.\n"); |
1776 | schedule_work(&stream_switching_work); |
1777 | |
1778 | } else if ((cpu_cmd & 0xff) == 4) { |
1779 | vh264_running = 1; |
1780 | /* reserved for slice group */ |
1781 | WRITE_VREG(AV_SCRATCH_0, 0); |
1782 | } else if ((cpu_cmd & 0xff) == 5) { |
1783 | vh264_running = 1; |
1784 | /* reserved for slice group */ |
1785 | WRITE_VREG(AV_SCRATCH_0, 0); |
1786 | } else if ((cpu_cmd & 0xff) == 6) { |
1787 | vh264_running = 0; |
1788 | fatal_error_flag = DECODER_FATAL_ERROR_UNKNOWN; |
1789 | /* this is fatal error, need restart */ |
1790 | pr_info("fatal error happened\n"); |
1791 | if (!fatal_error_reset) |
1792 | schedule_work(&error_wd_work); |
1793 | } else if ((cpu_cmd & 0xff) == 7) { |
1794 | vh264_running = 0; |
1795 | frame_width = (READ_VREG(AV_SCRATCH_1) + 1) * 16; |
1796 | pr_info("Over decoder supported size, width = %d\n", |
1797 | frame_width); |
1798 | fatal_error_flag = DECODER_FATAL_ERROR_SIZE_OVERFLOW; |
1799 | } else if ((cpu_cmd & 0xff) == 8) { |
1800 | vh264_running = 0; |
1801 | frame_height = (READ_VREG(AV_SCRATCH_1) + 1) * 16; |
1802 | pr_info("Over decoder supported size, height = %d\n", |
1803 | frame_height); |
1804 | fatal_error_flag = DECODER_FATAL_ERROR_SIZE_OVERFLOW; |
1805 | } else if ((cpu_cmd & 0xff) == 9) { |
1806 | first_offset = READ_VREG(AV_SCRATCH_1); |
1807 | if (pts_lookup_offset_us64 |
1808 | (PTS_TYPE_VIDEO, first_offset, &first_pts, 0, |
1809 | &first_pts64) == 0) |
1810 | first_pts_cached = true; |
1811 | WRITE_VREG(AV_SCRATCH_0, 0); |
1812 | |
1813 | } else if ((cpu_cmd & 0xff) == 0xa) { |
1814 | int b_offset = READ_VREG(AV_SCRATCH_2); |
1815 | |
1816 | buffer_index = READ_VREG(AV_SCRATCH_1); |
1817 | /*pr_info("iponly output %d b_offset %x\n", |
1818 | * buffer_index,b_offset); |
1819 | */ |
1820 | if (kfifo_get(&newframe_q, &vf) == 0) { |
1821 | WRITE_VREG(AV_SCRATCH_0, 0); |
1822 | pr_info |
1823 | ("fatal error, no available buffer slot."); |
1824 | return IRQ_HANDLED; |
1825 | } |
1826 | if (pts_lookup_offset_us64 (PTS_TYPE_VIDEO, b_offset, |
1827 | &pts, 0, &pts_us64) != 0) |
1828 | vf->pts_us64 = vf->pts = 0; |
1829 | else { |
1830 | vf->pts_us64 = pts_us64; |
1831 | vf->pts = pts; |
1832 | } |
1833 | |
1834 | set_frame_info(vf); |
1835 | vf->type = VIDTYPE_PROGRESSIVE | |
1836 | VIDTYPE_VIU_FIELD | |
1837 | VIDTYPE_VIU_NV21; |
1838 | vf->duration_pulldown = 0; |
1839 | vf->signal_type = video_signal_from_vui; |
1840 | vf->index = buffer_index; |
1841 | vf->canvas0Addr = vf->canvas1Addr = |
1842 | spec2canvas(&buffer_spec[buffer_index]); |
1843 | vf->type_original = vf->type; |
1844 | vfbuf_use[buffer_index]++; |
1845 | p_last_vf = vf; |
1846 | pts_discontinue = false; |
1847 | iponly_early_mode = 1; |
1848 | kfifo_put(&delay_display_q, |
1849 | (const struct vframe_s *)vf); |
1850 | WRITE_VREG(AV_SCRATCH_0, 0); |
1851 | } |
1852 | |
1853 | sei_itu35_flags = READ_VREG(AV_SCRATCH_J); |
1854 | if (sei_itu35_flags & (1 << 15)) { /* data ready */ |
1855 | /* int ltemp; */ |
1856 | /* unsigned char *daddr; */ |
1857 | unsigned int sei_itu35_wp = (sei_itu35_flags >> 16) & 0xffff; |
1858 | unsigned int sei_itu35_data_length = sei_itu35_flags & 0x7fff; |
1859 | struct userdata_poc_info_t user_data_poc; |
1860 | |
1861 | #if 0 |
1862 | /* dump lmem for debug */ |
1863 | WRITE_VREG(0x301, 0x8000); |
1864 | WRITE_VREG(0x31d, 0x2); |
1865 | for (ltemp = 0; ltemp < 64; ltemp++) { |
1866 | laddr = 0x20 + ltemp; |
1867 | WRITE_VREG(0x31b, laddr); |
1868 | pr_info("mem 0x%x data 0x%x\n", laddr, |
1869 | READ_VREG(0x31c) & 0xffff); |
1870 | } |
1871 | #endif |
1872 | #if 0 |
1873 | for (ltemp = 0; ltemp < sei_itu35_wp; ltemp++) { |
1874 | daddr = |
1875 | (unsigned char *)phys_to_virt( |
1876 | sei_data_buffer_phys + |
1877 | ltemp); |
1878 | /* daddr = (unsigned char *)(sei_data_buffer + |
1879 | * ltemp); |
1880 | */ |
1881 | pr_info("0x%x\n", *daddr); |
1882 | } |
1883 | #endif |
1884 | /* pr_info("pocinfo 0x%x, top poc %d, wp 0x%x, length %d\n", |
1885 | * READ_VREG(AV_SCRATCH_L), READ_VREG(AV_SCRATCH_M), |
1886 | * sei_itu35_wp, sei_itu35_data_length); |
1887 | */ |
1888 | user_data_poc.poc_info = READ_VREG(AV_SCRATCH_L); |
1889 | user_data_poc.poc_number = READ_VREG(AV_SCRATCH_M); |
1890 | set_userdata_poc(user_data_poc); |
1891 | WRITE_VREG(AV_SCRATCH_J, 0); |
1892 | wakeup_userdata_poll(sei_itu35_wp, |
1893 | (unsigned long)sei_data_buffer, |
1894 | USER_DATA_SIZE, sei_itu35_data_length); |
1895 | } |
1896 | #ifdef HANDLE_H264_IRQ |
1897 | return IRQ_HANDLED; |
1898 | #else |
1899 | return; |
1900 | #endif |
1901 | } |
1902 | |
1903 | static void vh264_put_timer_func(unsigned long arg) |
1904 | { |
1905 | struct timer_list *timer = (struct timer_list *)arg; |
1906 | unsigned int wait_buffer_status; |
1907 | unsigned int wait_i_pass_frames; |
1908 | unsigned int reg_val; |
1909 | |
1910 | enum receviver_start_e state = RECEIVER_INACTIVE; |
1911 | |
1912 | if (vh264_reset) { |
1913 | pr_info("operation forbidden in timer !\n"); |
1914 | goto exit; |
1915 | } |
1916 | |
1917 | prepare_display_q(); |
1918 | |
1919 | if (vf_get_receiver(PROVIDER_NAME)) { |
1920 | state = |
1921 | vf_notify_receiver(PROVIDER_NAME, |
1922 | VFRAME_EVENT_PROVIDER_QUREY_STATE, |
1923 | NULL); |
1924 | if ((state == RECEIVER_STATE_NULL) |
1925 | || (state == RECEIVER_STATE_NONE)) { |
1926 | /* receiver has no event_cb or receiver's |
1927 | * event_cb does not process this event |
1928 | */ |
1929 | state = RECEIVER_INACTIVE; |
1930 | } |
1931 | } else |
1932 | state = RECEIVER_INACTIVE; |
1933 | #ifndef HANDLE_H264_IRQ |
1934 | vh264_isr(); |
1935 | #endif |
1936 | |
1937 | if (vh264_stream_switching_state != SWITCHING_STATE_OFF) |
1938 | wait_buffer_counter = 0; |
1939 | else { |
1940 | reg_val = READ_VREG(AV_SCRATCH_9); |
1941 | wait_buffer_status = reg_val & (1 << 31); |
1942 | wait_i_pass_frames = reg_val & 0xff; |
1943 | if (wait_buffer_status) { |
1944 | if (kfifo_is_empty(&display_q) && |
1945 | kfifo_is_empty(&delay_display_q) && |
1946 | kfifo_is_empty(&recycle_q) && |
1947 | (state == RECEIVER_INACTIVE)) { |
1948 | pr_info("$$$$decoder is waiting for buffer\n"); |
1949 | if (++wait_buffer_counter > 4) { |
1950 | amvdec_stop(); |
1951 | |
1952 | #ifdef CONFIG_POST_PROCESS_MANAGER |
1953 | vh264_ppmgr_reset(); |
1954 | #else |
1955 | vf_light_unreg_provider(&vh264_vf_prov); |
1956 | vh264_local_init(); |
1957 | vf_reg_provider(&vh264_vf_prov); |
1958 | #endif |
1959 | vh264_prot_init(); |
1960 | amvdec_start(); |
1961 | } |
1962 | } else |
1963 | wait_buffer_counter = 0; |
1964 | } else if (wait_i_pass_frames > 1000) { |
1965 | pr_info("i passed frames > 1000\n"); |
1966 | amvdec_stop(); |
1967 | #ifdef CONFIG_POST_PROCESS_MANAGER |
1968 | vh264_ppmgr_reset(); |
1969 | #else |
1970 | vf_light_unreg_provider(&vh264_vf_prov); |
1971 | vh264_local_init(); |
1972 | vf_reg_provider(&vh264_vf_prov); |
1973 | #endif |
1974 | vh264_prot_init(); |
1975 | amvdec_start(); |
1976 | } |
1977 | } |
1978 | |
1979 | #if 0 |
1980 | if (!wait_buffer_status) { |
1981 | if (vh264_no_disp_count++ > NO_DISP_WD_COUNT) { |
1982 | pr_info("$$$decoder did not send frame out\n"); |
1983 | amvdec_stop(); |
1984 | #ifdef CONFIG_POST_PROCESS_MANAGER |
1985 | vh264_ppmgr_reset(); |
1986 | #else |
1987 | vf_light_unreg_provider(PROVIDER_NAME); |
1988 | vh264_local_init(); |
1989 | vf_reg_provider(vh264_vf_prov); |
1990 | #endif |
1991 | vh264_prot_init(); |
1992 | amvdec_start(); |
1993 | |
1994 | vh264_no_disp_count = 0; |
1995 | vh264_no_disp_wd_count++; |
1996 | } |
1997 | } |
1998 | #endif |
1999 | |
2000 | while (!kfifo_is_empty(&recycle_q) && |
2001 | ((READ_VREG(AV_SCRATCH_7) == 0) |
2002 | || (READ_VREG(AV_SCRATCH_8) == 0)) |
2003 | && (vh264_stream_switching_state == SWITCHING_STATE_OFF)) { |
2004 | struct vframe_s *vf; |
2005 | |
2006 | if (kfifo_get(&recycle_q, &vf)) { |
2007 | if ((vf->index >= 0) && (vf->index < VF_BUF_NUM)) { |
2008 | if (--vfbuf_use[vf->index] == 0) { |
2009 | if (READ_VREG(AV_SCRATCH_7) == 0) { |
2010 | WRITE_VREG(AV_SCRATCH_7, |
2011 | vf->index + 1); |
2012 | } else { |
2013 | WRITE_VREG(AV_SCRATCH_8, |
2014 | vf->index + 1); |
2015 | } |
2016 | } |
2017 | |
2018 | vf->index = VF_BUF_NUM; |
2019 | kfifo_put(&newframe_q, |
2020 | (const struct vframe_s *)vf); |
2021 | } |
2022 | } |
2023 | } |
2024 | |
2025 | if (vh264_stream_switching_state != SWITCHING_STATE_OFF) { |
2026 | while (!kfifo_is_empty(&recycle_q)) { |
2027 | struct vframe_s *vf; |
2028 | |
2029 | if (kfifo_get(&recycle_q, &vf)) { |
2030 | if ((vf->index >= 0 && |
2031 | (vf->index < VF_BUF_NUM))) { |
2032 | vf->index = VF_BUF_NUM; |
2033 | kfifo_put(&newframe_q, |
2034 | (const struct vframe_s *)vf); |
2035 | } |
2036 | } |
2037 | } |
2038 | |
2039 | WRITE_VREG(AV_SCRATCH_7, 0); |
2040 | WRITE_VREG(AV_SCRATCH_8, 0); |
2041 | |
2042 | if (kfifo_len(&newframe_q) == VF_POOL_SIZE) |
2043 | stream_switching_done(); |
2044 | } |
2045 | |
2046 | if (ucode_type != UCODE_IP_ONLY_PARAM && |
2047 | (clk_adj_frame_count > VDEC_CLOCK_ADJUST_FRAME) && |
2048 | frame_dur > 0 && saved_resolution != |
2049 | frame_width * frame_height * (96000 / frame_dur)) { |
2050 | int fps = 96000 / frame_dur; |
2051 | |
2052 | if (frame_dur < 10) /*dur is too small ,think it errors fps*/ |
2053 | fps = 60; |
2054 | saved_resolution = frame_width * frame_height * fps; |
2055 | vdec_source_changed(VFORMAT_H264, |
2056 | frame_width, frame_height, fps); |
2057 | } |
2058 | exit: |
2059 | timer->expires = jiffies + PUT_INTERVAL; |
2060 | |
2061 | add_timer(timer); |
2062 | } |
2063 | |
2064 | int vh264_dec_status(struct vdec_s *vdec, struct vdec_status *vstatus) |
2065 | { |
2066 | vstatus->width = frame_width; |
2067 | vstatus->height = frame_height; |
2068 | if (frame_dur != 0) |
2069 | vstatus->fps = 96000 / frame_dur; |
2070 | else |
2071 | vstatus->fps = -1; |
2072 | vstatus->error_count = READ_VREG(AV_SCRATCH_D); |
2073 | vstatus->status = stat; |
2074 | if (fatal_error_reset) |
2075 | vstatus->status |= fatal_error_flag; |
2076 | return 0; |
2077 | } |
2078 | |
2079 | int vh264_set_trickmode(struct vdec_s *vdec, unsigned long trickmode) |
2080 | { |
2081 | if (trickmode == TRICKMODE_I) { |
2082 | WRITE_VREG(AV_SCRATCH_F, |
2083 | (READ_VREG(AV_SCRATCH_F) & 0xfffffffc) | 2); |
2084 | trickmode_i = 1; |
2085 | } else if (trickmode == TRICKMODE_NONE) { |
2086 | WRITE_VREG(AV_SCRATCH_F, READ_VREG(AV_SCRATCH_F) & 0xfffffffc); |
2087 | trickmode_i = 0; |
2088 | } |
2089 | |
2090 | return 0; |
2091 | } |
2092 | |
2093 | static void vh264_prot_init(void) |
2094 | { |
2095 | |
2096 | while (READ_VREG(DCAC_DMA_CTRL) & 0x8000) |
2097 | ; |
2098 | while (READ_VREG(LMEM_DMA_CTRL) & 0x8000) |
2099 | ; /* reg address is 0x350 */ |
2100 | |
2101 | #if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */ |
2102 | WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4)); |
2103 | WRITE_VREG(DOS_SW_RESET0, 0); |
2104 | |
2105 | READ_VREG(DOS_SW_RESET0); |
2106 | READ_VREG(DOS_SW_RESET0); |
2107 | READ_VREG(DOS_SW_RESET0); |
2108 | |
2109 | WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4)); |
2110 | WRITE_VREG(DOS_SW_RESET0, 0); |
2111 | |
2112 | WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8)); |
2113 | WRITE_VREG(DOS_SW_RESET0, 0); |
2114 | |
2115 | READ_VREG(DOS_SW_RESET0); |
2116 | READ_VREG(DOS_SW_RESET0); |
2117 | READ_VREG(DOS_SW_RESET0); |
2118 | |
2119 | #else |
2120 | WRITE_MPEG_REG(RESET0_REGISTER, |
2121 | RESET_IQIDCT | RESET_MC | RESET_VLD_PART); |
2122 | READ_MPEG_REG(RESET0_REGISTER); |
2123 | WRITE_MPEG_REG(RESET0_REGISTER, |
2124 | RESET_IQIDCT | RESET_MC | RESET_VLD_PART); |
2125 | |
2126 | WRITE_MPEG_REG(RESET2_REGISTER, RESET_PIC_DC | RESET_DBLK); |
2127 | #endif |
2128 | |
2129 | WRITE_VREG(POWER_CTL_VLD, |
2130 | READ_VREG(POWER_CTL_VLD) | |
2131 | (0 << 10) | (1 << 9) | (1 << 6)); |
2132 | |
2133 | /* disable PSCALE for hardware sharing */ |
2134 | WRITE_VREG(PSCALE_CTRL, 0); |
2135 | |
2136 | WRITE_VREG(AV_SCRATCH_0, 0); |
2137 | WRITE_VREG(AV_SCRATCH_1, buf_offset); |
2138 | WRITE_VREG(AV_SCRATCH_G, mc_dma_handle); |
2139 | WRITE_VREG(AV_SCRATCH_7, 0); |
2140 | WRITE_VREG(AV_SCRATCH_8, 0); |
2141 | WRITE_VREG(AV_SCRATCH_9, 0); |
2142 | |
2143 | error_recovery_mode_use = |
2144 | (error_recovery_mode != |
2145 | 0) ? error_recovery_mode : error_recovery_mode_in; |
2146 | WRITE_VREG(AV_SCRATCH_F, |
2147 | (READ_VREG(AV_SCRATCH_F) & 0xffffffc3) | |
2148 | (READ_VREG(AV_SCRATCH_F) & 0xffffff43) | |
2149 | ((error_recovery_mode_use & 0x1) << 4)); |
2150 | if (dec_control & DEC_CONTROL_FLAG_DISABLE_FAST_POC) |
2151 | SET_VREG_MASK(AV_SCRATCH_F, 1 << 7); |
2152 | /* clear mailbox interrupt */ |
2153 | WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1); |
2154 | |
2155 | /* enable mailbox interrupt */ |
2156 | WRITE_VREG(ASSIST_MBOX1_MASK, 1); |
2157 | |
2158 | SET_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17); |
2159 | if (ucode_type == UCODE_IP_ONLY_PARAM) |
2160 | SET_VREG_MASK(AV_SCRATCH_F, 1 << 6); |
2161 | else |
2162 | CLEAR_VREG_MASK(AV_SCRATCH_F, 1 << 6); |
2163 | |
2164 | WRITE_VREG(AV_SCRATCH_I, (u32)(sei_data_buffer_phys - buf_offset)); |
2165 | WRITE_VREG(AV_SCRATCH_J, 0); |
2166 | /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */ |
2167 | if ((get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) && !is_meson_mtvd_cpu()) { |
2168 | /* pr_info("vh264 meson8 prot init\n"); */ |
2169 | WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa); |
2170 | } |
2171 | /* #endif */ |
2172 | } |
2173 | |
2174 | static void vh264_local_init(void) |
2175 | { |
2176 | int i; |
2177 | |
2178 | vh264_ratio = vh264_amstream_dec_info.ratio; |
2179 | /* vh264_ratio = 0x100; */ |
2180 | |
2181 | vh264_rotation = (((unsigned long) vh264_amstream_dec_info.param) |
2182 | >> 16) & 0xffff; |
2183 | |
2184 | frame_buffer_size = AVIL_DPB_BUFF_SIZE + buf_size - DEFAULT_MEM_SIZE; |
2185 | frame_prog = 0; |
2186 | frame_width = vh264_amstream_dec_info.width; |
2187 | frame_height = vh264_amstream_dec_info.height; |
2188 | frame_dur = vh264_amstream_dec_info.rate; |
2189 | pts_outside = ((unsigned long) vh264_amstream_dec_info.param) & 0x01; |
2190 | sync_outside = ((unsigned long) vh264_amstream_dec_info.param & 0x02) |
2191 | >> 1; |
2192 | use_idr_framerate = ((unsigned long) vh264_amstream_dec_info.param |
2193 | & 0x04) >> 2; |
2194 | max_refer_buf = !(((unsigned long) vh264_amstream_dec_info.param |
2195 | & 0x10) >> 4); |
2196 | |
2197 | pr_info |
2198 | ("H264 sysinfo: %dx%d duration=%d, pts_outside=%d, ", |
2199 | frame_width, frame_height, frame_dur, pts_outside); |
2200 | pr_debug("sync_outside=%d, use_idr_framerate=%d\n", |
2201 | sync_outside, use_idr_framerate); |
2202 | |
2203 | if ((unsigned long) vh264_amstream_dec_info.param & 0x08) |
2204 | ucode_type = UCODE_IP_ONLY_PARAM; |
2205 | else |
2206 | ucode_type = 0; |
2207 | |
2208 | if ((unsigned long) vh264_amstream_dec_info.param & 0x20) |
2209 | error_recovery_mode_in = 1; |
2210 | else |
2211 | error_recovery_mode_in = 3; |
2212 | |
2213 | if (!vh264_running) { |
2214 | last_mb_width = 0; |
2215 | last_mb_height = 0; |
2216 | } |
2217 | |
2218 | for (i = 0; i < VF_BUF_NUM; i++) |
2219 | vfbuf_use[i] = 0; |
2220 | |
2221 | INIT_KFIFO(display_q); |
2222 | INIT_KFIFO(delay_display_q); |
2223 | INIT_KFIFO(recycle_q); |
2224 | INIT_KFIFO(newframe_q); |
2225 | |
2226 | for (i = 0; i < VF_POOL_SIZE; i++) { |
2227 | const struct vframe_s *vf = &vfpool[i]; |
2228 | |
2229 | vfpool[i].index = VF_BUF_NUM; |
2230 | vfpool[i].bufWidth = 1920; |
2231 | kfifo_put(&newframe_q, vf); |
2232 | } |
2233 | |
2234 | #ifdef DROP_B_FRAME_FOR_1080P_50_60FPS |
2235 | last_interlaced = 1; |
2236 | #endif |
2237 | h264_first_pts_ready = 0; |
2238 | h264_first_valid_pts_ready = false; |
2239 | h264pts1 = 0; |
2240 | h264pts2 = 0; |
2241 | h264_pts_count = 0; |
2242 | duration_from_pts_done = 0; |
2243 | vh264_error_count = READ_VREG(AV_SCRATCH_D); |
2244 | |
2245 | p_last_vf = NULL; |
2246 | check_pts_discontinue = false; |
2247 | last_pts = 0; |
2248 | wait_buffer_counter = 0; |
2249 | vh264_no_disp_count = 0; |
2250 | fatal_error_flag = 0; |
2251 | vh264_stream_switching_state = SWITCHING_STATE_OFF; |
2252 | #ifdef DEBUG_PTS |
2253 | pts_missed = 0; |
2254 | pts_hit = 0; |
2255 | #endif |
2256 | pts_discontinue = false; |
2257 | no_idr_error_count = 0; |
2258 | } |
2259 | |
2260 | static s32 vh264_init(void) |
2261 | { |
2262 | int trickmode_fffb = 0; |
2263 | int firmwareloaded = 0; |
2264 | int i; |
2265 | |
2266 | /* pr_info("\nvh264_init\n"); */ |
2267 | init_timer(&recycle_timer); |
2268 | |
2269 | stat |= STAT_TIMER_INIT; |
2270 | |
2271 | vh264_running = 0;/* init here to reset last_mb_width&last_mb_height */ |
2272 | vh264_eos = 0; |
2273 | duration_on_correcting = 0; |
2274 | first_pts = 0; |
2275 | first_pts64 = 0; |
2276 | first_offset = 0; |
2277 | first_pts_cached = false; |
2278 | fixed_frame_rate_check_count = 0; |
2279 | saved_resolution = 0; |
2280 | iponly_early_mode = 0; |
2281 | vh264_local_init(); |
2282 | |
2283 | query_video_status(0, &trickmode_fffb); |
2284 | |
2285 | #if 0 |
2286 | if (!trickmode_fffb) { |
2287 | void __iomem *p = |
2288 | ioremap_nocache(ucode_map_start, V_BUF_ADDR_OFFSET); |
2289 | if (p != NULL) { |
2290 | memset(p, 0, V_BUF_ADDR_OFFSET); |
2291 | iounmap(p); |
2292 | } |
2293 | } |
2294 | #endif |
2295 | |
2296 | amvdec_enable(); |
2297 | |
2298 | /* -- ucode loading (amrisc and swap code) */ |
2299 | mc_cpu_addr = |
2300 | dma_alloc_coherent(amports_get_dma_device(), MC_TOTAL_SIZE, |
2301 | &mc_dma_handle, GFP_KERNEL); |
2302 | if (!mc_cpu_addr) { |
2303 | amvdec_disable(); |
2304 | |
2305 | pr_err("vh264_init: Can not allocate mc memory.\n"); |
2306 | return -ENOMEM; |
2307 | } |
2308 | |
2309 | pr_debug("264 ucode swap area: phyaddr %p, cpu vaddr %p\n", |
2310 | (void *)mc_dma_handle, mc_cpu_addr); |
2311 | if (debugfirmware) { |
2312 | int r0, r1, r2, r3, r4, r5; |
2313 | char firmwarename[32]; |
2314 | |
2315 | pr_debug("start load debug %d firmware ...\n", debugfirmware); |
2316 | |
2317 | snprintf(firmwarename, 32, "%s%d", "vh264_mc", debugfirmware); |
2318 | r0 = amvdec_loadmc_ex(VFORMAT_H264, firmwarename, NULL); |
2319 | |
2320 | #define DEBUGGET_FW(t, name, buf, size, ret)\ |
2321 | do {\ |
2322 | snprintf(firmwarename, 32, "%s%d", name,\ |
2323 | debugfirmware);\ |
2324 | ret = get_decoder_firmware_data(t,\ |
2325 | firmwarename, buf, size);\ |
2326 | } while (0) |
2327 | /*memcpy((u8 *) mc_cpu_addr + MC_OFFSET_HEADER, vh264_header_mc, |
2328 | *MC_SWAP_SIZE); |
2329 | */ |
2330 | DEBUGGET_FW(VFORMAT_H264, "vh264_header_mc", |
2331 | (u8 *) mc_cpu_addr + MC_OFFSET_HEADER, |
2332 | MC_SWAP_SIZE, r1); |
2333 | |
2334 | /*memcpy((u8 *) mc_cpu_addr + MC_OFFSET_DATA, vh264_data_mc, |
2335 | *MC_SWAP_SIZE); |
2336 | */ |
2337 | DEBUGGET_FW(VFORMAT_H264, "vh264_data_mc", |
2338 | (u8 *) mc_cpu_addr + MC_OFFSET_DATA, MC_SWAP_SIZE, r2); |
2339 | /*memcpy((u8 *) mc_cpu_addr + MC_OFFSET_MMCO, vh264_mmco_mc, |
2340 | *MC_SWAP_SIZE); |
2341 | */ |
2342 | DEBUGGET_FW(VFORMAT_H264, "vh264_mmco_mc", |
2343 | (u8 *) mc_cpu_addr + MC_OFFSET_MMCO, MC_SWAP_SIZE, r3); |
2344 | /*memcpy((u8 *) mc_cpu_addr + MC_OFFSET_LIST, vh264_list_mc, |
2345 | *MC_SWAP_SIZE); |
2346 | */ |
2347 | DEBUGGET_FW(VFORMAT_H264, "vh264_list_mc", |
2348 | (u8 *) mc_cpu_addr + MC_OFFSET_LIST, MC_SWAP_SIZE, r4); |
2349 | /*memcpy((u8 *) mc_cpu_addr + MC_OFFSET_SLICE, vh264_slice_mc, |
2350 | *MC_SWAP_SIZE); |
2351 | */ |
2352 | DEBUGGET_FW(VFORMAT_H264, "vh264_slice_mc", |
2353 | (u8 *) mc_cpu_addr + MC_OFFSET_SLICE, MC_SWAP_SIZE, r5); |
2354 | |
2355 | if (r0 < 0 || r1 < 0 || r2 < 0 || r3 < 0 || r4 < 0 || r5 < 0) { |
2356 | pr_err("264 load debugfirmware err %d,%d,%d,%d,%d,%d\n", |
2357 | r0, r1, r2, r3, r4, r5); |
2358 | amvdec_disable(); |
2359 | if (mc_cpu_addr) { |
2360 | dma_free_coherent(amports_get_dma_device(), |
2361 | MC_TOTAL_SIZE, mc_cpu_addr, |
2362 | mc_dma_handle); |
2363 | mc_cpu_addr = NULL; |
2364 | } |
2365 | return -EBUSY; |
2366 | } |
2367 | firmwareloaded = 1; |
2368 | } else { |
2369 | int ret = -1, size = -1; |
2370 | char *buf = vmalloc(0x1000 * 8); |
2371 | |
2372 | size = get_firmware_data(VIDEO_DEC_H264, buf); |
2373 | if (size < 0) { |
2374 | pr_err("get firmware fail."); |
2375 | vfree(buf); |
2376 | return -1; |
2377 | } |
2378 | |
2379 | ret = amvdec_loadmc_ex(VFORMAT_H264, NULL, buf); |
2380 | memcpy((u8 *) mc_cpu_addr + MC_OFFSET_HEADER, |
2381 | buf + 0x4000, MC_SWAP_SIZE); |
2382 | memcpy((u8 *) mc_cpu_addr + MC_OFFSET_DATA, |
2383 | buf + 0x2000, MC_SWAP_SIZE); |
2384 | memcpy((u8 *) mc_cpu_addr + MC_OFFSET_MMCO, |
2385 | buf + 0x6000, MC_SWAP_SIZE); |
2386 | memcpy((u8 *) mc_cpu_addr + MC_OFFSET_LIST, |
2387 | buf + 0x3000, MC_SWAP_SIZE); |
2388 | memcpy((u8 *) mc_cpu_addr + MC_OFFSET_SLICE, |
2389 | buf + 0x5000, MC_SWAP_SIZE); |
2390 | |
2391 | vfree(buf); |
2392 | |
2393 | if (ret < 0) { |
2394 | pr_err("h264 load orignal firmware error %d.\n", ret); |
2395 | amvdec_disable(); |
2396 | if (mc_cpu_addr) { |
2397 | dma_free_coherent(amports_get_dma_device(), |
2398 | MC_TOTAL_SIZE, mc_cpu_addr, |
2399 | mc_dma_handle); |
2400 | mc_cpu_addr = NULL; |
2401 | } |
2402 | return -EBUSY; |
2403 | } |
2404 | } |
2405 | |
2406 | stat |= STAT_MC_LOAD; |
2407 | |
2408 | for (i = 0; i < ARRAY_SIZE(fense_buffer_spec); i++) { |
2409 | struct buffer_spec_s *s = &fense_buffer_spec[i]; |
2410 | |
2411 | if (!codec_mm_enough_for_size(3 * SZ_1M, 1)) |
2412 | return -ENOMEM; |
2413 | |
2414 | s->alloc_count = 3 * SZ_1M / PAGE_SIZE; |
2415 | s->phy_addr = codec_mm_alloc_for_dma(MEM_NAME, |
2416 | s->alloc_count, |
2417 | 4 + PAGE_SHIFT, |
2418 | CODEC_MM_FLAGS_CMA_CLEAR | CODEC_MM_FLAGS_FOR_VDECODER); |
2419 | s->y_canvas_index = 2 * i; |
2420 | s->u_canvas_index = 2 * i + 1; |
2421 | s->v_canvas_index = 2 * i + 1; |
2422 | } |
2423 | |
2424 | /* enable AMRISC side protocol */ |
2425 | vh264_prot_init(); |
2426 | |
2427 | #ifdef HANDLE_H264_IRQ |
2428 | /*TODO irq */ |
2429 | |
2430 | if (vdec_request_irq(VDEC_IRQ_1, vh264_isr, |
2431 | "vh264-irq", (void *)vh264_dec_id)) { |
2432 | pr_err("vh264 irq register error.\n"); |
2433 | amvdec_disable(); |
2434 | return -ENOENT; |
2435 | } |
2436 | #endif |
2437 | |
2438 | stat |= STAT_ISR_REG; |
2439 | |
2440 | #ifdef CONFIG_POST_PROCESS_MANAGER |
2441 | vf_provider_init(&vh264_vf_prov, PROVIDER_NAME, &vh264_vf_provider_ops, |
2442 | NULL); |
2443 | vf_reg_provider(&vh264_vf_prov); |
2444 | vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL); |
2445 | #else |
2446 | vf_provider_init(&vh264_vf_prov, PROVIDER_NAME, &vh264_vf_provider_ops, |
2447 | NULL); |
2448 | vf_reg_provider(&vh264_vf_prov); |
2449 | #endif |
2450 | |
2451 | vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_FR_HINT, |
2452 | (void *)((unsigned long)frame_dur)); |
2453 | |
2454 | stat |= STAT_VF_HOOK; |
2455 | |
2456 | recycle_timer.data = (ulong) &recycle_timer; |
2457 | recycle_timer.function = vh264_put_timer_func; |
2458 | recycle_timer.expires = jiffies + PUT_INTERVAL; |
2459 | |
2460 | add_timer(&recycle_timer); |
2461 | |
2462 | stat |= STAT_TIMER_ARM; |
2463 | |
2464 | vh264_stream_switching_state = SWITCHING_STATE_OFF; |
2465 | |
2466 | stat |= STAT_VDEC_RUN; |
2467 | wmb(); /* Ensure fetchbuf contents visible */ |
2468 | |
2469 | /* -- start decoder */ |
2470 | amvdec_start(); |
2471 | |
2472 | init_userdata_fifo(); |
2473 | |
2474 | return 0; |
2475 | } |
2476 | |
2477 | static int vh264_stop(int mode) |
2478 | { |
2479 | int i; |
2480 | |
2481 | if (stat & STAT_VDEC_RUN) { |
2482 | amvdec_stop(); |
2483 | stat &= ~STAT_VDEC_RUN; |
2484 | } |
2485 | |
2486 | if (stat & STAT_ISR_REG) { |
2487 | WRITE_VREG(ASSIST_MBOX1_MASK, 0); |
2488 | /*TODO irq */ |
2489 | |
2490 | vdec_free_irq(VDEC_IRQ_1, (void *)vh264_dec_id); |
2491 | |
2492 | stat &= ~STAT_ISR_REG; |
2493 | } |
2494 | |
2495 | if (stat & STAT_TIMER_ARM) { |
2496 | del_timer_sync(&recycle_timer); |
2497 | stat &= ~STAT_TIMER_ARM; |
2498 | } |
2499 | |
2500 | if (stat & STAT_VF_HOOK) { |
2501 | if (mode == MODE_FULL) { |
2502 | vf_notify_receiver(PROVIDER_NAME, |
2503 | VFRAME_EVENT_PROVIDER_FR_END_HINT, |
2504 | NULL); |
2505 | } |
2506 | |
2507 | vf_unreg_provider(&vh264_vf_prov); |
2508 | stat &= ~STAT_VF_HOOK; |
2509 | } |
2510 | |
2511 | if (stat & STAT_MC_LOAD) { |
2512 | if (mc_cpu_addr != NULL) { |
2513 | dma_free_coherent(amports_get_dma_device(), |
2514 | MC_TOTAL_SIZE, mc_cpu_addr, |
2515 | mc_dma_handle); |
2516 | mc_cpu_addr = NULL; |
2517 | } |
2518 | } |
2519 | if (sei_data_buffer != NULL) { |
2520 | dma_free_coherent( |
2521 | amports_get_dma_device(), |
2522 | USER_DATA_SIZE, |
2523 | sei_data_buffer, |
2524 | sei_data_buffer_phys); |
2525 | sei_data_buffer = NULL; |
2526 | sei_data_buffer_phys = 0; |
2527 | } |
2528 | amvdec_disable(); |
2529 | |
2530 | for (i = 0; i < ARRAY_SIZE(fense_buffer_spec); i++) { |
2531 | if (fense_buffer_spec[i].phy_addr) { |
2532 | codec_mm_free_for_dma(MEM_NAME, |
2533 | fense_buffer_spec[i].phy_addr); |
2534 | fense_buffer_spec[i].phy_addr = 0; |
2535 | fense_buffer_spec[i].alloc_count = 0; |
2536 | } |
2537 | } |
2538 | |
2539 | for (i = 0; i < ARRAY_SIZE(buffer_spec); i++) { |
2540 | if (buffer_spec[i].phy_addr) { |
2541 | if (is_4k && !get_blackout_policy()) |
2542 | pr_info("Skip releasing CMA buffer %d\n", i); |
2543 | else { |
2544 | codec_mm_free_for_dma(MEM_NAME, |
2545 | buffer_spec[i].phy_addr); |
2546 | buffer_spec[i].phy_addr = 0; |
2547 | buffer_spec[i].alloc_count = 0; |
2548 | } |
2549 | } |
2550 | } |
2551 | return 0; |
2552 | } |
2553 | |
2554 | static void error_do_work(struct work_struct *work) |
2555 | { |
2556 | mutex_lock(&vh264_mutex); |
2557 | |
2558 | /* |
2559 | * we need to lock vh264_stop/vh264_init. |
2560 | * because we will call amvdec_h264_remove on this step; |
2561 | * then we may call more than once on |
2562 | * free_irq/deltimer/..and some other. |
2563 | */ |
2564 | if (atomic_read(&vh264_active)) { |
2565 | amvdec_stop(); |
2566 | vh264_reset = 1; |
2567 | #ifdef CONFIG_POST_PROCESS_MANAGER |
2568 | vh264_ppmgr_reset(); |
2569 | #else |
2570 | vf_light_unreg_provider(&vh264_vf_prov); |
2571 | |
2572 | vh264_local_init(); |
2573 | |
2574 | vf_reg_provider(&vh264_vf_prov); |
2575 | #endif |
2576 | msleep(30); |
2577 | vh264_local_init(); |
2578 | vh264_prot_init(); |
2579 | |
2580 | amvdec_start(); |
2581 | vh264_reset = 0; |
2582 | } |
2583 | |
2584 | mutex_unlock(&vh264_mutex); |
2585 | } |
2586 | |
2587 | static void stream_switching_done(void) |
2588 | { |
2589 | int state = vh264_stream_switching_state; |
2590 | |
2591 | WRITE_VREG(AV_SCRATCH_7, 0); |
2592 | WRITE_VREG(AV_SCRATCH_8, 0); |
2593 | WRITE_VREG(AV_SCRATCH_9, 0); |
2594 | |
2595 | if (state == SWITCHING_STATE_ON_CMD1) { |
2596 | pr_info("Enter set parameter cmd1 switching_state %x.\n", |
2597 | vh264_stream_switching_state); |
2598 | schedule_work(&set_parameter_work); |
2599 | return; |
2600 | } else if (state == SWITCHING_STATE_ON_CMD1_PENDING) |
2601 | return; |
2602 | |
2603 | vh264_stream_switching_state = SWITCHING_STATE_OFF; |
2604 | |
2605 | wmb(); /* Ensure fetchbuf contents visible */ |
2606 | |
2607 | if (state == SWITCHING_STATE_ON_CMD3) |
2608 | WRITE_VREG(AV_SCRATCH_0, 0); |
2609 | |
2610 | pr_info("Leaving switching mode.\n"); |
2611 | } |
2612 | |
2613 | /* construt a new frame as a copy of last frame so frame receiver can |
2614 | * release all buffer resources to decoder. |
2615 | */ |
2616 | static void stream_switching_do(struct work_struct *work) |
2617 | { |
2618 | int mb_total_num, mb_width_num, mb_height_num, i = 0; |
2619 | struct vframe_s *vf = NULL; |
2620 | u32 y_index, u_index, src_index, des_index, y_desindex, u_desindex; |
2621 | struct canvas_s csy, csu, cyd; |
2622 | unsigned long flags; |
2623 | bool delay = true; |
2624 | |
2625 | if (!atomic_read(&vh264_active)) |
2626 | return; |
2627 | |
2628 | if (vh264_stream_switching_state == SWITCHING_STATE_OFF) |
2629 | return; |
2630 | |
2631 | spin_lock_irqsave(&prepare_lock, flags); |
2632 | |
2633 | block_display_q = true; |
2634 | |
2635 | spin_unlock_irqrestore(&prepare_lock, flags); |
2636 | |
2637 | mb_total_num = mb_total; |
2638 | mb_width_num = mb_width; |
2639 | mb_height_num = mb_height; |
2640 | |
2641 | while (is_4k || kfifo_len(&delay_display_q) > 2) { |
2642 | if (kfifo_get(&delay_display_q, &vf)) { |
2643 | kfifo_put(&display_q, |
2644 | (const struct vframe_s *)vf); |
2645 | vf_notify_receiver(PROVIDER_NAME, |
2646 | VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); |
2647 | } else |
2648 | break; |
2649 | } |
2650 | |
2651 | if (!kfifo_get(&delay_display_q, &vf)) { |
2652 | vf = p_last_vf; |
2653 | delay = false; |
2654 | } |
2655 | |
2656 | while (vf) { |
2657 | int buffer_index; |
2658 | |
2659 | buffer_index = vf->index & 0xff; |
2660 | |
2661 | /* construct a clone of the frame from last frame */ |
2662 | #if 0 |
2663 | pr_info("src yaddr[0x%x] index[%d] width[%d] heigth[%d]\n", |
2664 | buffer_spec[buffer_index].y_addr, |
2665 | buffer_spec[buffer_index].y_canvas_index, |
2666 | buffer_spec[buffer_index].y_canvas_width, |
2667 | buffer_spec[buffer_index].y_canvas_height); |
2668 | |
2669 | pr_info("src uaddr[0x%x] index[%d] width[%d] heigth[%d]\n", |
2670 | buffer_spec[buffer_index].u_addr, |
2671 | buffer_spec[buffer_index].u_canvas_index, |
2672 | buffer_spec[buffer_index].u_canvas_width, |
2673 | buffer_spec[buffer_index].u_canvas_height); |
2674 | #endif |
2675 | if (!is_4k) { |
2676 | y_index = buffer_spec[buffer_index].y_canvas_index; |
2677 | u_index = buffer_spec[buffer_index].u_canvas_index; |
2678 | |
2679 | canvas_read(y_index, &csy); |
2680 | canvas_read(u_index, &csu); |
2681 | |
2682 | canvas_config(fense_buffer_spec[i].y_canvas_index, |
2683 | fense_buffer_spec[i].phy_addr, |
2684 | mb_width_num << 4, mb_height_num << 4, |
2685 | CANVAS_ADDR_NOWRAP, |
2686 | CANVAS_BLKMODE_LINEAR); |
2687 | canvas_config(fense_buffer_spec[i].u_canvas_index, |
2688 | fense_buffer_spec[i].phy_addr + |
2689 | (mb_total_num << 8), |
2690 | mb_width_num << 4, mb_height_num << 3, |
2691 | CANVAS_ADDR_NOWRAP, |
2692 | CANVAS_BLKMODE_LINEAR); |
2693 | |
2694 | y_desindex = fense_buffer_spec[i].y_canvas_index; |
2695 | u_desindex = fense_buffer_spec[i].u_canvas_index; |
2696 | |
2697 | canvas_read(y_desindex, &cyd); |
2698 | |
2699 | src_index = ((y_index & 0xff) | |
2700 | ((u_index << 8) & 0x0000ff00)); |
2701 | des_index = ((y_desindex & 0xff) | |
2702 | ((u_desindex << 8) & 0x0000ff00)); |
2703 | #if 0 |
2704 | ge2d_canvas_dup(&csy, &csu, &cyd, |
2705 | GE2D_FORMAT_M24_NV21, |
2706 | src_index, |
2707 | des_index); |
2708 | #endif/*mask*/ |
2709 | } |
2710 | fense_vf[i] = *vf; |
2711 | fense_vf[i].index = -1; |
2712 | |
2713 | if (!is_4k) |
2714 | fense_vf[i].canvas0Addr = |
2715 | spec2canvas(&fense_buffer_spec[i]); |
2716 | else |
2717 | fense_vf[i].flag |= VFRAME_FLAG_SWITCHING_FENSE; |
2718 | |
2719 | /* send clone to receiver */ |
2720 | kfifo_put(&display_q, |
2721 | (const struct vframe_s *)&fense_vf[i]); |
2722 | |
2723 | /* early recycle frames for last session */ |
2724 | if (delay) |
2725 | vh264_vf_put(vf, NULL); |
2726 | |
2727 | vf_notify_receiver(PROVIDER_NAME, |
2728 | VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); |
2729 | |
2730 | i++; |
2731 | |
2732 | if (!kfifo_get(&delay_display_q, &vf)) |
2733 | break; |
2734 | } |
2735 | |
2736 | block_display_q = false; |
2737 | |
2738 | pr_info("Switching fense frame post\n"); |
2739 | } |
2740 | |
2741 | static int amvdec_h264_probe(struct platform_device *pdev) |
2742 | { |
2743 | struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data; |
2744 | |
2745 | mutex_lock(&vh264_mutex); |
2746 | |
2747 | if (pdata == NULL) { |
2748 | pr_info("\namvdec_h264 memory resource undefined.\n"); |
2749 | mutex_unlock(&vh264_mutex); |
2750 | return -EFAULT; |
2751 | } |
2752 | |
2753 | ucode_map_start = pdata->mem_start; |
2754 | buf_size = pdata->mem_end - pdata->mem_start + 1; |
2755 | if (buf_size < DEFAULT_MEM_SIZE) { |
2756 | pr_info("\namvdec_h264 memory size not enough.\n"); |
2757 | mutex_unlock(&vh264_mutex); |
2758 | return -ENOMEM; |
2759 | } |
2760 | |
2761 | buf_offset = pdata->mem_start - DEF_BUF_START_ADDR; |
2762 | if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) |
2763 | buf_start = V_BUF_ADDR_OFFSET_NEW + pdata->mem_start; |
2764 | else |
2765 | buf_start = V_BUF_ADDR_OFFSET + pdata->mem_start; |
2766 | buf_end = pdata->mem_end; |
2767 | if (pdata->sys_info) |
2768 | vh264_amstream_dec_info = *pdata->sys_info; |
2769 | if (sei_data_buffer == NULL) { |
2770 | sei_data_buffer = |
2771 | dma_alloc_coherent(amports_get_dma_device(), |
2772 | USER_DATA_SIZE, |
2773 | &sei_data_buffer_phys, GFP_KERNEL); |
2774 | if (!sei_data_buffer) { |
2775 | pr_info("%s: Can not allocate sei_data_buffer\n", |
2776 | __func__); |
2777 | mutex_unlock(&vh264_mutex); |
2778 | return -ENOMEM; |
2779 | } |
2780 | /* pr_info("buffer 0x%x, phys 0x%x, remap 0x%x\n", |
2781 | * sei_data_buffer, sei_data_buffer_phys, |
2782 | * (u32)sei_data_buffer_remap); |
2783 | */ |
2784 | } |
2785 | pr_debug("amvdec_h264 mem-addr=%lx,buff_offset=%x,buf_start=%lx buf_size %x\n", |
2786 | pdata->mem_start, buf_offset, buf_start, buf_size); |
2787 | pdata->dec_status = vh264_dec_status; |
2788 | pdata->set_trickmode = vh264_set_trickmode; |
2789 | |
2790 | if (vh264_init() < 0) { |
2791 | pr_info("\namvdec_h264 init failed.\n"); |
2792 | mutex_unlock(&vh264_mutex); |
2793 | return -ENODEV; |
2794 | } |
2795 | |
2796 | INIT_WORK(&error_wd_work, error_do_work); |
2797 | INIT_WORK(&stream_switching_work, stream_switching_do); |
2798 | INIT_WORK(&set_parameter_work, vh264_set_params); |
2799 | |
2800 | atomic_set(&vh264_active, 1); |
2801 | |
2802 | mutex_unlock(&vh264_mutex); |
2803 | |
2804 | return 0; |
2805 | } |
2806 | |
2807 | static int amvdec_h264_remove(struct platform_device *pdev) |
2808 | { |
2809 | atomic_set(&vh264_active, 0); |
2810 | cancel_work_sync(&set_parameter_work); |
2811 | cancel_work_sync(&error_wd_work); |
2812 | cancel_work_sync(&stream_switching_work); |
2813 | mutex_lock(&vh264_mutex); |
2814 | vh264_stop(MODE_FULL); |
2815 | vdec_source_changed(VFORMAT_H264, 0, 0, 0); |
2816 | atomic_set(&vh264_active, 0); |
2817 | #ifdef DEBUG_PTS |
2818 | pr_info |
2819 | ("pts missed %ld, pts hit %ld, pts_outside %d, duration %d, ", |
2820 | pts_missed, pts_hit, pts_outside, frame_dur); |
2821 | pr_info("sync_outside %d, use_idr_framerate %d\n", |
2822 | sync_outside, use_idr_framerate); |
2823 | #endif |
2824 | mutex_unlock(&vh264_mutex); |
2825 | return 0; |
2826 | } |
2827 | |
2828 | /****************************************/ |
2829 | |
2830 | static struct platform_driver amvdec_h264_driver = { |
2831 | .probe = amvdec_h264_probe, |
2832 | .remove = amvdec_h264_remove, |
2833 | #ifdef CONFIG_PM |
2834 | .suspend = amvdec_suspend, |
2835 | .resume = amvdec_resume, |
2836 | #endif |
2837 | .driver = { |
2838 | .name = DRIVER_NAME, |
2839 | } |
2840 | }; |
2841 | |
2842 | static struct codec_profile_t amvdec_h264_profile = { |
2843 | .name = "h264", |
2844 | .profile = "" |
2845 | }; |
2846 | |
2847 | static int __init amvdec_h264_driver_init_module(void) |
2848 | { |
2849 | pr_debug("amvdec_h264 module init\n"); |
2850 | |
2851 | /*ge2d_videoh264task_init();mask*/ |
2852 | |
2853 | if (platform_driver_register(&amvdec_h264_driver)) { |
2854 | pr_err("failed to register amvdec_h264 driver\n"); |
2855 | return -ENODEV; |
2856 | } |
2857 | if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXTVBB) |
2858 | amvdec_h264_profile.profile = "4k"; |
2859 | vcodec_profile_register(&amvdec_h264_profile); |
2860 | return 0; |
2861 | } |
2862 | |
2863 | static void __exit amvdec_h264_driver_remove_module(void) |
2864 | { |
2865 | pr_debug("amvdec_h264 module remove.\n"); |
2866 | |
2867 | platform_driver_unregister(&amvdec_h264_driver); |
2868 | |
2869 | /*ge2d_videoh264task_release();mask*/ |
2870 | } |
2871 | |
2872 | /****************************************/ |
2873 | |
2874 | module_param(stat, uint, 0664); |
2875 | MODULE_PARM_DESC(stat, "\n amvdec_h264 stat\n"); |
2876 | module_param(error_recovery_mode, uint, 0664); |
2877 | MODULE_PARM_DESC(error_recovery_mode, "\n amvdec_h264 error_recovery_mode\n"); |
2878 | module_param(sync_outside, uint, 0664); |
2879 | MODULE_PARM_DESC(sync_outside, "\n amvdec_h264 sync_outside\n"); |
2880 | module_param(dec_control, uint, 0664); |
2881 | MODULE_PARM_DESC(dec_control, "\n amvdec_h264 decoder control\n"); |
2882 | module_param(fatal_error_reset, uint, 0664); |
2883 | MODULE_PARM_DESC(fatal_error_reset, |
2884 | "\n amvdec_h264 decoder reset when fatal error happens\n"); |
2885 | module_param(max_refer_buf, uint, 0664); |
2886 | MODULE_PARM_DESC(max_refer_buf, |
2887 | "\n amvdec_h264 dec buffering or not for reference frame\n"); |
2888 | module_param(ucode_type, uint, 0664); |
2889 | MODULE_PARM_DESC(ucode_type, |
2890 | "\n amvdec_h264 dec buffering or not for reference frame\n"); |
2891 | module_param(debugfirmware, uint, 0664); |
2892 | MODULE_PARM_DESC(debugfirmware, "\n amvdec_h264 debug load firmware\n"); |
2893 | module_param(fixed_frame_rate_flag, uint, 0664); |
2894 | MODULE_PARM_DESC(fixed_frame_rate_flag, |
2895 | "\n amvdec_h264 fixed_frame_rate_flag\n"); |
2896 | module_param(decoder_debug_flag, uint, 0664); |
2897 | MODULE_PARM_DESC(decoder_debug_flag, |
2898 | "\n amvdec_h264 decoder_debug_flag\n"); |
2899 | |
2900 | module_param(decoder_force_reset, uint, 0664); |
2901 | MODULE_PARM_DESC(decoder_force_reset, |
2902 | "\n amvdec_h264 decoder force reset\n"); |
2903 | module_param(no_idr_error_max, uint, 0664); |
2904 | MODULE_PARM_DESC(no_idr_error_max, |
2905 | "\n print no_idr_error_max\n"); |
2906 | |
2907 | |
2908 | module_init(amvdec_h264_driver_init_module); |
2909 | module_exit(amvdec_h264_driver_remove_module); |
2910 | |
2911 | MODULE_DESCRIPTION("AMLOGIC H264 Video Decoder Driver"); |
2912 | MODULE_LICENSE("GPL"); |
2913 | MODULE_AUTHOR("Chen Zhang <chen.zhang@amlogic.com>"); |
2914 |