summaryrefslogtreecommitdiff
path: root/drivers/frame_provider/decoder/h264/vh264_mvc.c (plain)
blob: 821b3c11061d3af569da30cdcad0fd65cfa29316
1/*
2 * drivers/amlogic/amports/vh264mvc.c
3 *
4 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 */
17
18#include <linux/kernel.h>
19#include <linux/types.h>
20#include <linux/errno.h>
21#include <linux/interrupt.h>
22#include <linux/timer.h>
23#include <linux/platform_device.h>
24#include <linux/amlogic/media/utils/amstream.h>
25#include <linux/amlogic/media/frame_sync/ptsserv.h>
26#include <linux/amlogic/media/canvas/canvas.h>
27#include <linux/amlogic/media/vfm/vframe.h>
28#include <linux/amlogic/media/vfm/vframe_provider.h>
29#include <linux/amlogic/media/vfm/vframe_receiver.h>
30#include <linux/amlogic/media/utils/vformat.h>
31#include <linux/workqueue.h>
32#include <linux/dma-mapping.h>
33#include <linux/atomic.h>
34#include <linux/amlogic/tee.h>
35
36#include <linux/module.h>
37#include <linux/slab.h>
38
39#include <linux/amlogic/media/utils/vdec_reg.h>
40#include "../../../stream_input/amports/amports_priv.h"
41#include "../utils/vdec.h"
42#include "../utils/amvdec.h"
43#include "../utils/decoder_mmu_box.h"
44#include "../utils/decoder_bmmu_box.h"
45#include <linux/amlogic/media/codec_mm/codec_mm.h>
46#include <linux/amlogic/media/codec_mm/configs.h>
47#include "../utils/firmware.h"
48#include <linux/amlogic/tee.h>
49#include "../utils/config_parser.h"
50
51#define TIME_TASK_PRINT_ENABLE 0x100
52#define PUT_PRINT_ENABLE 0x200
53
54#define DRIVER_NAME "amvdec_h264mvc"
55#define MODULE_NAME "amvdec_h264mvc"
56
57#define HANDLE_h264mvc_IRQ
58
59#define DEBUG_PTS
60#define DEBUG_SKIP
61
62#define PUT_INTERVAL (HZ/100)
63
64#define STAT_TIMER_INIT 0x01
65#define STAT_MC_LOAD 0x02
66#define STAT_ISR_REG 0x04
67#define STAT_VF_HOOK 0x08
68#define STAT_TIMER_ARM 0x10
69#define STAT_VDEC_RUN 0x20
70
71#define DROPPING_THREAD_HOLD 4
72#define DROPPING_FIRST_WAIT 16
73#define DISPLAY_INVALID_POS -65536
74
75#define INIT_DROP_FRAME_CNT 8
76
77static int vh264mvc_vf_states(struct vframe_states *states, void *);
78static struct vframe_s *vh264mvc_vf_peek(void *);
79static struct vframe_s *vh264mvc_vf_get(void *);
80static void vh264mvc_vf_put(struct vframe_s *, void *);
81static int vh264mvc_event_cb(int type, void *data, void *private_data);
82
83static void vh264mvc_prot_init(void);
84static int vh264mvc_local_init(void);
85static void vh264mvc_put_timer_func(unsigned long arg);
86
87static const char vh264mvc_dec_id[] = "vh264mvc-dev";
88
89#define PROVIDER_NAME "decoder.h264mvc"
90
91static struct vdec_info *gvs;
92static struct work_struct alloc_work;
93static struct work_struct set_clk_work;
94
95static DEFINE_MUTEX(vh264_mvc_mutex);
96
97static const struct vframe_operations_s vh264mvc_vf_provider = {
98 .peek = vh264mvc_vf_peek,
99 .get = vh264mvc_vf_get,
100 .put = vh264mvc_vf_put,
101 .event_cb = vh264mvc_event_cb,
102 .vf_states = vh264mvc_vf_states,
103};
104
105static struct vframe_provider_s vh264mvc_vf_prov;
106
107static u32 frame_width, frame_height, frame_dur;
108static u32 saved_resolution;
109static struct timer_list recycle_timer;
110static u32 stat;
111static u32 pts_outside;
112static u32 sync_outside;
113static u32 vh264mvc_ratio;
114static u32 h264mvc_ar;
115static u32 no_dropping_cnt;
116static s32 init_drop_cnt;
117
118#ifdef DEBUG_SKIP
119static unsigned long view_total, view_dropped;
120#endif
121
122#ifdef DEBUG_PTS
123static unsigned long pts_missed, pts_hit;
124#endif
125
126static atomic_t vh264mvc_active = ATOMIC_INIT(0);
127static struct work_struct error_wd_work;
128
129static struct dec_sysinfo vh264mvc_amstream_dec_info;
130static dma_addr_t mc_dma_handle;
131static void *mc_cpu_addr;
132
133static DEFINE_SPINLOCK(lock);
134
135static int vh264mvc_stop(void);
136static s32 vh264mvc_init(void);
137
138/***************************
139 * new
140 **************************
141 */
142
143/* bit[3:0] command : */
144/* 0 - command finished */
145/* (DATA0 - {level_idc_mmco, max_reference_frame_num, width, height} */
146/* 1 - alloc view_0 display_buffer and reference_data_area */
147/* 2 - alloc view_1 display_buffer and reference_data_area */
148#define MAILBOX_COMMAND AV_SCRATCH_0
149#define MAILBOX_DATA_0 AV_SCRATCH_1
150#define MAILBOX_DATA_1 AV_SCRATCH_2
151#define MAILBOX_DATA_2 AV_SCRATCH_3
152#define CANVAS_START AV_SCRATCH_6
153#define BUFFER_RECYCLE AV_SCRATCH_7
154#define DROP_CONTROL AV_SCRATCH_8
155#define PICTURE_COUNT AV_SCRATCH_9
156#define DECODE_STATUS AV_SCRATCH_A
157#define SPS_STATUS AV_SCRATCH_B
158#define PPS_STATUS AV_SCRATCH_C
159#define SIM_RESERV_D AV_SCRATCH_D
160#define WORKSPACE_START AV_SCRATCH_E
161#define SIM_RESERV_F AV_SCRATCH_F
162#define DECODE_ERROR_CNT AV_SCRATCH_G
163#define CURRENT_UCODE AV_SCRATCH_H
164#define CURRENT_SPS_PPS AV_SCRATCH_I/* bit[15:9]-SPS, bit[8:0]-PPS */
165#define DECODE_SKIP_PICTURE AV_SCRATCH_J
166#define UCODE_START_ADDR AV_SCRATCH_K
167#define SIM_RESERV_L AV_SCRATCH_L
168#define REF_START_VIEW_0 AV_SCRATCH_M
169#define REF_START_VIEW_1 AV_SCRATCH_N
170
171/********************************************
172 * Mailbox command
173 ********************************************/
174#define CMD_FINISHED 0
175#define CMD_ALLOC_VIEW_0 1
176#define CMD_ALLOC_VIEW_1 2
177#define CMD_FRAME_DISPLAY 3
178#define CMD_FATAL_ERROR 4
179
180#define CANVAS_INDEX_START 0x78
181/* /AMVDEC_H264MVC_CANVAS_INDEX */
182
183#define MC_TOTAL_SIZE (28*SZ_1K)
184#define MC_SWAP_SIZE (4*SZ_1K)
185
186unsigned int DECODE_BUFFER_START = 0x00200000;
187unsigned int DECODE_BUFFER_END = 0x05000000;
188
189/* #define DISPLAY_BUFFER_NUM 4 */
190static unsigned int dynamic_buf_num_margin = 8;
191
192#define DECODE_BUFFER_NUM_MAX 16
193#define MAX_BMMU_BUFFER_NUM (DECODE_BUFFER_NUM_MAX + dynamic_buf_num_margin)
194#define TOTAL_BMMU_BUFF_NUM (MAX_BMMU_BUFFER_NUM * 2 + 3)
195#define VF_BUFFER_IDX(n) (2 + n)
196
197#define DECODER_WORK_SPACE_SIZE 0xa0000
198
199
200static unsigned int ANC_CANVAS_ADDR;
201static unsigned int index;
202static unsigned long ref_start_addr[2];
203static unsigned int max_dec_frame_buffering[2];
204static unsigned int total_dec_frame_buffering[2];
205
206static unsigned int dpb_size, ref_size;
207
208static int display_buff_id;
209static int display_view_id;
210static int display_POC;
211static int stream_offset;
212
213#define video_domain_addr(adr) (adr&0x7fffffff)
214static unsigned long work_space_adr;
215
216struct buffer_spec_s {
217 unsigned int y_addr;
218 unsigned int u_addr;
219 unsigned int v_addr;
220
221 int y_canvas_index;
222 int u_canvas_index;
223 int v_canvas_index;
224
225 struct page *alloc_pages;
226 unsigned long phy_addr;
227 int alloc_count;
228};
229/*
230static struct buffer_spec_s buffer_spec0[MAX_BMMU_BUFFER_NUM];
231static struct buffer_spec_s buffer_spec1[MAX_BMMU_BUFFER_NUM];
232*/
233static struct buffer_spec_s *buffer_spec0;
234static struct buffer_spec_s *buffer_spec1;
235static void *mm_blk_handle;
236
237/*
238 * dbg_mode:
239 * bit 0: 1, print debug information
240 * bit 4: 1, recycle buffer without displaying;
241 * bit 5: 1, buffer single frame step , set dbg_cmd to 1 to step
242 *
243 */
244static int dbg_mode;
245static int dbg_cmd;
246static int view_mode =
247 3; /* 0, left; 1 ,right ; 2, left<->right 3, right<->left */
248static int drop_rate = 2;
249static int drop_thread_hold;
250/**/
251
252struct mvc_buf_s {
253 struct list_head list;
254 struct vframe_s vframe;
255 int display_POC;
256 int view0_buff_id;
257 int view1_buff_id;
258 int view0_drop;
259 int view1_drop;
260 int stream_offset;
261 unsigned int pts;
262} /*mvc_buf_t */;
263
264#define spec2canvas(x) \
265 (((x)->v_canvas_index << 16) | \
266 ((x)->u_canvas_index << 8) | \
267 ((x)->y_canvas_index << 0))
268
269#define to_mvcbuf(vf) \
270 container_of(vf, struct mvc_buf_s, vframe)
271
272static int vf_buf_init_flag;
273
274static void init_vf_buf(void)
275{
276
277 vf_buf_init_flag = 1;
278}
279
280static void uninit_vf_buf(void)
281{
282
283}
284
285/* #define QUEUE_SUPPORT */
286
287struct mvc_info_s {
288 int view0_buf_id;
289 int view1_buf_id;
290 int view0_drop;
291 int view1_drop;
292 int display_pos;
293 int used;
294 int slot;
295 unsigned int stream_offset;
296};
297
298#define VF_POOL_SIZE 20
299static struct vframe_s vfpool[VF_POOL_SIZE];
300static struct mvc_info_s vfpool_idx[VF_POOL_SIZE];
301static s32 view0_vfbuf_use[DECODE_BUFFER_NUM_MAX];
302static s32 view1_vfbuf_use[DECODE_BUFFER_NUM_MAX];
303
304static s32 fill_ptr, get_ptr, putting_ptr, put_ptr;
305static s32 dirty_frame_num;
306static s32 enable_recycle;
307
308static s32 init_drop_frame_id[INIT_DROP_FRAME_CNT];
309#define INCPTR(p) ptr_atomic_wrap_inc(&p)
310static inline void ptr_atomic_wrap_inc(u32 *ptr)
311{
312 u32 i = *ptr;
313
314 i++;
315
316 if (i >= VF_POOL_SIZE)
317 i = 0;
318
319 *ptr = i;
320}
321
322static void set_frame_info(struct vframe_s *vf)
323{
324 unsigned int ar = 0;
325
326 vf->width = frame_width;
327 vf->height = frame_height;
328 vf->duration = frame_dur;
329 vf->duration_pulldown = 0;
330
331 if (vh264mvc_ratio == 0) {
332 /* always stretch to 16:9 */
333 vf->ratio_control |= (0x90 <<
334 DISP_RATIO_ASPECT_RATIO_BIT);
335 } else {
336 /* h264mvc_ar = ((float)frame_height/frame_width)
337 *customer_ratio;
338 */
339 ar = min_t(u32, h264mvc_ar, DISP_RATIO_ASPECT_RATIO_MAX);
340
341 vf->ratio_control = (ar << DISP_RATIO_ASPECT_RATIO_BIT);
342 }
343}
344
345static int vh264mvc_vf_states(struct vframe_states *states, void *op_arg)
346{
347 unsigned long flags;
348 int i;
349
350 spin_lock_irqsave(&lock, flags);
351 states->vf_pool_size = VF_POOL_SIZE;
352
353 i = put_ptr - fill_ptr;
354 if (i < 0)
355 i += VF_POOL_SIZE;
356 states->buf_free_num = i;
357
358 i = putting_ptr - put_ptr;
359 if (i < 0)
360 i += VF_POOL_SIZE;
361 states->buf_recycle_num = i;
362
363 i = fill_ptr - get_ptr;
364 if (i < 0)
365 i += VF_POOL_SIZE;
366 states->buf_avail_num = i;
367
368 spin_unlock_irqrestore(&lock, flags);
369 return 0;
370}
371
372void send_drop_cmd(void)
373{
374 int ready_cnt = 0;
375 int temp_get_ptr = get_ptr;
376 int temp_fill_ptr = fill_ptr;
377
378 while (temp_get_ptr != temp_fill_ptr) {
379 if ((vfpool_idx[temp_get_ptr].view0_buf_id >= 0)
380 && (vfpool_idx[temp_get_ptr].view1_buf_id >= 0)
381 && (vfpool_idx[temp_get_ptr].view0_drop == 0)
382 && (vfpool_idx[temp_get_ptr].view1_drop == 0))
383 ready_cnt++;
384 INCPTR(temp_get_ptr);
385 }
386 if (dbg_mode & 0x40) {
387 pr_info("ready_cnt is %d ; no_dropping_cnt is %d\n", ready_cnt,
388 no_dropping_cnt);
389 }
390 if ((no_dropping_cnt >= DROPPING_FIRST_WAIT)
391 && (ready_cnt < drop_thread_hold))
392 WRITE_VREG(DROP_CONTROL, (1 << 31) | (drop_rate));
393 else
394 WRITE_VREG(DROP_CONTROL, 0);
395}
396
397#if 0
398int get_valid_frame(void)
399{
400 int ready_cnt = 0;
401 int temp_get_ptr = get_ptr;
402 int temp_fill_ptr = fill_ptr;
403
404 while (temp_get_ptr != temp_fill_ptr) {
405 if ((vfpool_idx[temp_get_ptr].view0_buf_id >= 0)
406 && (vfpool_idx[temp_get_ptr].view1_buf_id >= 0)
407 && (vfpool_idx[temp_get_ptr].view0_drop == 0)
408 && (vfpool_idx[temp_get_ptr].view1_drop == 0))
409 ready_cnt++;
410 INCPTR(temp_get_ptr);
411 }
412 return ready_cnt;
413}
414#endif
415static struct vframe_s *vh264mvc_vf_peek(void *op_arg)
416{
417
418 if (get_ptr == fill_ptr)
419 return NULL;
420 send_drop_cmd();
421 return &vfpool[get_ptr];
422
423}
424
425static struct vframe_s *vh264mvc_vf_get(void *op_arg)
426{
427
428 struct vframe_s *vf;
429 int view0_buf_id;
430 int view1_buf_id;
431
432 if (get_ptr == fill_ptr)
433 return NULL;
434
435 view0_buf_id = vfpool_idx[get_ptr].view0_buf_id;
436 view1_buf_id = vfpool_idx[get_ptr].view1_buf_id;
437 vf = &vfpool[get_ptr];
438
439 if ((view0_buf_id >= 0) && (view1_buf_id >= 0)) {
440 if (view_mode == 0 || view_mode == 1) {
441 vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
442 vf->canvas0Addr = vf->canvas1Addr =
443 (view_mode ==
444 0) ? spec2canvas(&buffer_spec0[view0_buf_id]) :
445 spec2canvas(&buffer_spec1[view1_buf_id]);
446 } else {
447 vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_MVC;
448
449 vf->left_eye.start_x = 0;
450 vf->left_eye.start_y = 0;
451 vf->left_eye.width = vf->width;
452 vf->left_eye.height = vf->height;
453 vf->right_eye.start_x = 0;
454 vf->right_eye.start_y = 0;
455 vf->right_eye.width = vf->width;
456 vf->right_eye.height = vf->height;
457 vf->trans_fmt = TVIN_TFMT_3D_TB;
458
459 if (view_mode == 2) {
460 vf->canvas0Addr =
461 spec2canvas(&buffer_spec1[
462 view1_buf_id]);
463 vf->canvas1Addr =
464 spec2canvas(&buffer_spec0[
465 view0_buf_id]);
466 } else {
467 vf->canvas0Addr =
468 spec2canvas(&buffer_spec0[
469 view0_buf_id]);
470 vf->canvas1Addr =
471 spec2canvas(&buffer_spec1[
472 view1_buf_id]);
473 }
474 }
475 }
476 vf->type_original = vf->type;
477 if (((vfpool_idx[get_ptr].view0_drop != 0)
478 || (vfpool_idx[get_ptr].view1_drop != 0))
479 && ((no_dropping_cnt >= DROPPING_FIRST_WAIT)))
480 vf->frame_dirty = 1;
481 else
482 vf->frame_dirty = 0;
483
484 INCPTR(get_ptr);
485
486 if (frame_width == 0)
487 frame_width = vh264mvc_amstream_dec_info.width;
488 if (frame_height == 0)
489 frame_height = vh264mvc_amstream_dec_info.height;
490
491 vf->width = frame_width;
492 vf->height = frame_height;
493
494 if ((no_dropping_cnt < DROPPING_FIRST_WAIT) && (vf->frame_dirty == 0))
495 no_dropping_cnt++;
496 return vf;
497
498}
499
500static void vh264mvc_vf_put(struct vframe_s *vf, void *op_arg)
501{
502
503 if (vf_buf_init_flag == 0)
504 return;
505 if (vf->frame_dirty) {
506
507 vf->frame_dirty = 0;
508 dirty_frame_num++;
509 enable_recycle = 0;
510 if (dbg_mode & PUT_PRINT_ENABLE) {
511 pr_info("invalid: dirty_frame_num is !!! %d\n",
512 dirty_frame_num);
513 }
514 } else {
515 INCPTR(putting_ptr);
516 while (dirty_frame_num > 0) {
517 INCPTR(putting_ptr);
518 dirty_frame_num--;
519 }
520 enable_recycle = 1;
521 if (dbg_mode & PUT_PRINT_ENABLE) {
522 pr_info("valid: dirty_frame_num is @@@ %d\n",
523 dirty_frame_num);
524 }
525 /* send_drop_cmd(); */
526 }
527
528}
529
530static int vh264mvc_event_cb(int type, void *data, void *private_data)
531{
532 if (type & VFRAME_EVENT_RECEIVER_RESET) {
533 unsigned long flags;
534
535 amvdec_stop();
536#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
537 vf_light_unreg_provider(&vh264mvc_vf_prov);
538#endif
539 spin_lock_irqsave(&lock, flags);
540 vh264mvc_local_init();
541 vh264mvc_prot_init();
542 spin_unlock_irqrestore(&lock, flags);
543#ifndef CONFIG_AMLOGIC_POST_PROCESS_MANAGER
544 vf_reg_provider(&vh264mvc_vf_prov);
545#endif
546 amvdec_start();
547 }
548 return 0;
549}
550
551/**/
552static long init_canvas(int view_index, int refbuf_size, long dpb_size,
553 int dpb_number, int mb_width, int mb_height,
554 struct buffer_spec_s *buffer_spec)
555{
556
557 unsigned long addr;
558 int i, j, bmmu_index;
559 int mb_total, ret = -1;
560 /* cav_con canvas; */
561 mb_total = mb_width * mb_height;
562 mutex_lock(&vh264_mvc_mutex);
563
564 for (j = 0; j < (dpb_number + 1); j++) {
565 int page_count;
566 if (j == 0) {
567 if (!view_index)
568 bmmu_index = 1;
569 else
570 bmmu_index = dpb_number + 2;
571
572 ret = decoder_bmmu_box_alloc_buf_phy(mm_blk_handle,
573 bmmu_index, refbuf_size, DRIVER_NAME,
574 &ref_start_addr[view_index]);
575
576 if (ret < 0) {
577 mutex_unlock(&vh264_mvc_mutex);
578 return ret;
579 }
580
581 continue;
582 }
583 /* canvas buf */
584 WRITE_VREG(ANC_CANVAS_ADDR,
585 index | ((index + 1) << 8) |
586 ((index + 2) << 16));
587 ANC_CANVAS_ADDR++;
588
589 i = j - 1;
590 if (!view_index)
591 bmmu_index = VF_BUFFER_IDX(i);
592 else
593 bmmu_index = VF_BUFFER_IDX(i) + dpb_number + 1;
594#ifdef DOUBLE_WRITE
595 page_count = PAGE_ALIGN((mb_total << 8) + (mb_total << 7) +
596 (mb_total << 6) + (mb_total << 5)) / PAGE_SIZE;
597#else
598 page_count = PAGE_ALIGN((mb_total << 8) +
599 (mb_total << 7)) / PAGE_SIZE;
600#endif
601
602 ret = decoder_bmmu_box_alloc_buf_phy(mm_blk_handle,
603 bmmu_index, page_count << PAGE_SHIFT,
604 DRIVER_NAME, &buffer_spec[i].phy_addr);
605
606 if (ret < 0) {
607 buffer_spec[i].alloc_count = 0;
608 mutex_unlock(&vh264_mvc_mutex);
609 return ret;
610 }
611
612 addr = buffer_spec[i].phy_addr;
613 buffer_spec[i].alloc_count = page_count;
614 buffer_spec[i].y_addr = addr;
615 buffer_spec[i].y_canvas_index = index;
616 canvas_config(index, addr,
617 mb_width << 4, mb_height << 4,
618 CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
619
620 addr += mb_total << 8;
621 index++;
622 buffer_spec[i].u_addr = addr;
623 buffer_spec[i].u_canvas_index = index;
624 canvas_config(index, addr, mb_width << 3, mb_height << 3,
625 CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
626
627 addr += mb_total << 6;
628 index++;
629 buffer_spec[i].v_addr = addr;
630 buffer_spec[i].v_canvas_index = index;
631 canvas_config(index, addr, mb_width << 3, mb_height << 3,
632 CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_32X32);
633
634 index++;
635 }
636 mutex_unlock(&vh264_mvc_mutex);
637 return 0;
638}
639
640static int get_max_dec_frame_buf_size(int level_idc,
641 int max_reference_frame_num, int mb_width,
642 int mb_height)
643{
644 int pic_size = mb_width * mb_height * 384;
645
646 int size = 0;
647
648 switch (level_idc) {
649 case 9:
650 size = 152064;
651 break;
652 case 10:
653 size = 152064;
654 break;
655 case 11:
656 size = 345600;
657 break;
658 case 12:
659 size = 912384;
660 break;
661 case 13:
662 size = 912384;
663 break;
664 case 20:
665 size = 912384;
666 break;
667 case 21:
668 size = 1824768;
669 break;
670 case 22:
671 size = 3110400;
672 break;
673 case 30:
674 size = 3110400;
675 break;
676 case 31:
677 size = 6912000;
678 break;
679 case 32:
680 size = 7864320;
681 break;
682 case 40:
683 size = 12582912;
684 break;
685 case 41:
686 size = 12582912;
687 break;
688 case 42:
689 size = 13369344;
690 break;
691 case 50:
692 size = 42393600;
693 break;
694 case 51:
695 size = 70778880;
696 break;
697 default:
698 break;
699 }
700
701 size /= pic_size;
702 size = size + 1; /* For MVC need onr more buffer */
703 if (max_reference_frame_num > size)
704 size = max_reference_frame_num;
705 if (size > DECODE_BUFFER_NUM_MAX)
706 size = DECODE_BUFFER_NUM_MAX;
707
708 return size;
709}
710
711int check_in_list(int pos, int *slot)
712{
713 int i;
714 int ret = 0;
715
716 for (i = 0; i < VF_POOL_SIZE; i++) {
717 if ((vfpool_idx[i].display_pos == pos)
718 && (vfpool_idx[i].used == 0)) {
719 ret = 1;
720 *slot = vfpool_idx[i].slot;
721 break;
722 }
723 }
724 return ret;
725}
726
727static void do_alloc_work(struct work_struct *work)
728{
729 int level_idc, max_reference_frame_num, mb_width, mb_height;
730 int refbuf_size;
731 int ret = READ_VREG(MAILBOX_COMMAND);
732
733 switch (ret & 0xff) {
734 case CMD_ALLOC_VIEW_0:
735 if (dbg_mode & 0x1) {
736 pr_info
737 ("Start H264 display buffer for view 0\n");
738 }
739
740 ret = READ_VREG(MAILBOX_DATA_0);
741 level_idc = (ret >> 24) & 0xff;
742 max_reference_frame_num = (ret >> 16) & 0xff;
743 mb_width = (ret >> 8) & 0xff;
744 mb_height = (ret >> 0) & 0xff;
745 max_dec_frame_buffering[0] =
746 get_max_dec_frame_buf_size(level_idc,
747 max_reference_frame_num,
748 mb_width, mb_height);
749
750 total_dec_frame_buffering[0] =
751 max_dec_frame_buffering[0] + dynamic_buf_num_margin;
752
753 mb_width = (mb_width + 3) & 0xfffffffc;
754 mb_height = (mb_height + 3) & 0xfffffffc;
755
756 dpb_size = mb_width * mb_height * 384;
757 ref_size = mb_width * mb_height * 96;
758
759 if (dbg_mode & 0x1) {
760 pr_info("dpb_size: 0x%x\n", dpb_size);
761 pr_info("ref_size: 0x%x\n", ref_size);
762 pr_info("total_dec_frame_buffering[0] : 0x%x\n",
763 total_dec_frame_buffering[0]);
764 pr_info("max_reference_frame_num: 0x%x\n",
765 max_reference_frame_num);
766 }
767 refbuf_size
768 = ref_size * (max_reference_frame_num + 1) * 2;
769
770 index = CANVAS_INDEX_START;
771 ANC_CANVAS_ADDR = ANC0_CANVAS_ADDR;
772
773 ret =
774 init_canvas(0, refbuf_size, dpb_size,
775 total_dec_frame_buffering[0], mb_width,
776 mb_height, buffer_spec0);
777
778 if (ret < 0) {
779 pr_info(" Un-expected memory alloc problem\n");
780 return;
781 }
782
783 WRITE_VREG(REF_START_VIEW_0,
784 video_domain_addr(ref_start_addr[0]));
785 WRITE_VREG(MAILBOX_DATA_0,
786 (max_dec_frame_buffering[0] << 8) |
787 (total_dec_frame_buffering[0] << 0));
788 WRITE_VREG(MAILBOX_DATA_1, ref_size);
789 WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED);
790
791 if (dbg_mode & 0x1) {
792 pr_info
793 ("End H264 display buffer for view 0\n");
794 }
795 if (frame_width == 0) {
796 if (vh264mvc_amstream_dec_info.width)
797 frame_width = vh264mvc_amstream_dec_info.width;
798 else
799 frame_width = mb_width << 4;
800 }
801 if (frame_height == 0) {
802 frame_height = mb_height << 4;
803 if (frame_height == 1088)
804 frame_height = 1080;
805 }
806 break;
807 case CMD_ALLOC_VIEW_1:
808 if (dbg_mode & 0x1) {
809 pr_info
810 ("Start H264 display buffer for view 1\n");
811 }
812
813 ret = READ_VREG(MAILBOX_DATA_0);
814 level_idc = (ret >> 24) & 0xff;
815 max_reference_frame_num = (ret >> 16) & 0xff;
816 mb_width = (ret >> 8) & 0xff;
817 mb_height = (ret >> 0) & 0xff;
818 max_dec_frame_buffering[1] =
819 get_max_dec_frame_buf_size(level_idc,
820 max_reference_frame_num,
821 mb_width, mb_height);
822 if (max_dec_frame_buffering[1] != max_dec_frame_buffering[0]) {
823 pr_info
824 (" Warning: view0/1 max_dec_frame_buffering ");
825 pr_info("different : 0x%x/0x%x, Use View0\n",
826 max_dec_frame_buffering[0],
827 max_dec_frame_buffering[1]);
828 max_dec_frame_buffering[1] = max_dec_frame_buffering[0];
829 }
830
831 total_dec_frame_buffering[1] =
832 max_dec_frame_buffering[1] + dynamic_buf_num_margin;
833
834 mb_width = (mb_width + 3) & 0xfffffffc;
835 mb_height = (mb_height + 3) & 0xfffffffc;
836
837 dpb_size = mb_width * mb_height * 384;
838 ref_size = mb_width * mb_height * 96;
839 refbuf_size = ref_size * (max_reference_frame_num + 1) * 2;
840 if (dbg_mode & 0x1) {
841 pr_info("dpb_size: 0x%x\n", dpb_size);
842 pr_info("ref_size: 0x%x\n", ref_size);
843 pr_info("total_dec_frame_buffering[1] : 0x%x\n",
844 total_dec_frame_buffering[1]);
845 pr_info("max_reference_frame_num: 0x%x\n",
846 max_reference_frame_num);
847 }
848
849 index = CANVAS_INDEX_START + total_dec_frame_buffering[0] * 3;
850 ANC_CANVAS_ADDR =
851 ANC0_CANVAS_ADDR + total_dec_frame_buffering[0];
852
853 ret = init_canvas(1, refbuf_size, dpb_size,
854 total_dec_frame_buffering[1], mb_width,
855 mb_height, buffer_spec1);
856
857 if (ret < 0) {
858 pr_info(" Un-expected memory alloc problem\n");
859 return;
860 }
861
862 WRITE_VREG(REF_START_VIEW_1,
863 video_domain_addr(ref_start_addr[1]));
864 WRITE_VREG(MAILBOX_DATA_0,
865 (max_dec_frame_buffering[1] << 8) |
866 (total_dec_frame_buffering[1] << 0));
867 WRITE_VREG(MAILBOX_DATA_1, ref_size);
868 WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED);
869
870 if (dbg_mode & 0x1) {
871 pr_info
872 ("End H264 buffer allocation for view 1\n");
873 }
874 if (frame_width == 0) {
875 if (vh264mvc_amstream_dec_info.width)
876 frame_width = vh264mvc_amstream_dec_info.width;
877 else
878 frame_width = mb_width << 4;
879 }
880 if (frame_height == 0) {
881 frame_height = mb_height << 4;
882 if (frame_height == 1088)
883 frame_height = 1080;
884 }
885 break;
886 }
887
888}
889
890
891#ifdef HANDLE_h264mvc_IRQ
892static irqreturn_t vh264mvc_isr(int irq, void *dev_id)
893#else
894static void vh264mvc_isr(void)
895#endif
896{
897 int drop_status;
898 struct vframe_s *vf;
899 unsigned int pts, pts_valid = 0;
900 u64 pts_us64;
901 u32 frame_size;
902 int ret = READ_VREG(MAILBOX_COMMAND);
903 /* pr_info("vh264mvc_isr, cmd =%x\n", ret); */
904 switch (ret & 0xff) {
905 case CMD_ALLOC_VIEW_0:
906 case CMD_ALLOC_VIEW_1:
907 schedule_work(&alloc_work);
908 break;
909 case CMD_FRAME_DISPLAY:
910 ret = READ_VREG(MAILBOX_DATA_0);
911 display_buff_id = (ret >> 0) & 0x3f;
912 display_view_id = (ret >> 6) & 0x3;
913 drop_status = (ret >> 8) & 0x1;
914 display_POC = READ_VREG(MAILBOX_DATA_1);
915 stream_offset = READ_VREG(MAILBOX_DATA_2);
916 /* if (display_view_id == 0) */
917 WRITE_VREG(MAILBOX_COMMAND, CMD_FINISHED);
918
919#ifdef DEBUG_SKIP
920 view_total++;
921 if (drop_status)
922 view_dropped++;
923#endif
924 if (dbg_mode & 0x1) {
925 pr_info
926 (" H264 display frame ready - View : %x, Buffer : %x\n",
927 display_view_id, display_buff_id);
928 pr_info
929 (" H264 display frame POC -- Buffer : %x, POC : %x\n",
930 display_buff_id, display_POC);
931 pr_info("H264 display frame ready\n");
932 }
933 if (dbg_mode & 0x10) {
934 if ((dbg_mode & 0x20) == 0) {
935 while (READ_VREG(BUFFER_RECYCLE) != 0)
936 ;
937 WRITE_VREG(BUFFER_RECYCLE,
938 (display_view_id << 8) |
939 (display_buff_id + 1));
940 display_buff_id = -1;
941 display_view_id = -1;
942 display_POC = -1;
943 }
944 } else {
945 unsigned char in_list_flag = 0;
946
947 int slot = 0;
948
949 in_list_flag = check_in_list(display_POC, &slot);
950
951 if ((dbg_mode & 0x40) && (drop_status)) {
952 pr_info
953 ("drop_status:%dview_id=%d,buff_id=%d,",
954 drop_status, display_view_id, display_buff_id);
955 pr_info
956 ("offset=%d, display_POC = %d,fill_ptr=0x%x\n",
957 stream_offset, display_POC, fill_ptr);
958 }
959
960 if ((in_list_flag) && (stream_offset != 0)) {
961 pr_info
962 ("error case ,display_POC is %d, slot is %d\n",
963 display_POC, slot);
964 in_list_flag = 0;
965 }
966 if (!in_list_flag) {
967 if (display_view_id == 0) {
968 vfpool_idx[fill_ptr].view0_buf_id =
969 display_buff_id;
970 view0_vfbuf_use[display_buff_id]++;
971 vfpool_idx[fill_ptr].stream_offset =
972 stream_offset;
973 vfpool_idx[fill_ptr].view0_drop =
974 drop_status;
975 }
976 if (display_view_id == 1) {
977 vfpool_idx[fill_ptr].view1_buf_id =
978 display_buff_id;
979 vfpool_idx[fill_ptr].view1_drop =
980 drop_status;
981 view1_vfbuf_use[display_buff_id]++;
982 }
983 vfpool_idx[fill_ptr].slot = fill_ptr;
984 vfpool_idx[fill_ptr].display_pos = display_POC;
985
986 } else {
987 if (display_view_id == 0) {
988 vfpool_idx[slot].view0_buf_id =
989 display_buff_id;
990 view0_vfbuf_use[display_buff_id]++;
991 vfpool_idx[slot].stream_offset =
992 stream_offset;
993 vfpool_idx[slot].view0_drop =
994 drop_status;
995
996 }
997 if (display_view_id == 1) {
998 vfpool_idx[slot].view1_buf_id =
999 display_buff_id;
1000 view1_vfbuf_use[display_buff_id]++;
1001 vfpool_idx[slot].view1_drop =
1002 drop_status;
1003 }
1004 vf = &vfpool[slot];
1005
1006 if (display_view_id == 0) {
1007 vf->mem_handle =
1008 decoder_bmmu_box_get_mem_handle(
1009 mm_blk_handle,
1010 VF_BUFFER_IDX(display_buff_id));
1011
1012 } else if (display_view_id == 1) {
1013 vf->mem_head_handle =
1014 decoder_bmmu_box_get_mem_handle(
1015 mm_blk_handle,
1016 VF_BUFFER_IDX(display_buff_id));
1017
1018 vf->mem_handle =
1019 decoder_bmmu_box_get_mem_handle(
1020 mm_blk_handle,
1021 VF_BUFFER_IDX(display_buff_id)
1022 + total_dec_frame_buffering[0]
1023 + 1);
1024 }
1025
1026
1027
1028 if (vfpool_idx[slot].stream_offset == 0) {
1029 pr_info
1030 ("error case, invalid stream offset\n");
1031 }
1032 if (pts_lookup_offset_us64
1033 (PTS_TYPE_VIDEO,
1034 vfpool_idx[slot].stream_offset, &pts,
1035 &frame_size,
1036 0x10000, &pts_us64) == 0)
1037 pts_valid = 1;
1038 else
1039 pts_valid = 0;
1040 vf->pts = (pts_valid) ? pts : 0;
1041 vf->pts_us64 = (pts_valid) ? pts_us64 : 0;
1042 /* vf->pts = vf->pts_us64 ? vf->pts_us64
1043 * : vf->pts ;
1044 */
1045 /* vf->pts = vf->pts_us64; */
1046 if (dbg_mode & 0x80)
1047 pr_info("vf->pts:%d\n", vf->pts);
1048 vfpool_idx[slot].used = 1;
1049 INCPTR(fill_ptr);
1050 set_frame_info(vf);
1051
1052 gvs->frame_dur = frame_dur;
1053 vdec_count_info(gvs, 0,
1054 vfpool_idx[slot].stream_offset);
1055
1056 vf_notify_receiver(PROVIDER_NAME,
1057 VFRAME_EVENT_PROVIDER_VFRAME_READY,
1058 NULL);
1059
1060 }
1061 }
1062 break;
1063 case CMD_FATAL_ERROR:
1064 pr_info("fatal error !!!\n");
1065 schedule_work(&error_wd_work);
1066 break;
1067 default:
1068 break;
1069 }
1070#ifdef HANDLE_h264mvc_IRQ
1071 return IRQ_HANDLED;
1072#else
1073 return;
1074#endif
1075}
1076
1077static void vh264_mvc_set_clk(struct work_struct *work)
1078{
1079 if (frame_dur > 0 && saved_resolution !=
1080 frame_width * frame_height * (96000 / frame_dur)) {
1081 int fps = 96000 / frame_dur;
1082
1083 saved_resolution = frame_width * frame_height * fps;
1084 vdec_source_changed(VFORMAT_H264MVC,
1085 frame_width, frame_height, fps * 2);
1086 }
1087}
1088
1089static void vh264mvc_put_timer_func(unsigned long arg)
1090{
1091 struct timer_list *timer = (struct timer_list *)arg;
1092
1093 int valid_frame = 0;
1094
1095 if (enable_recycle == 0) {
1096 if (dbg_mode & TIME_TASK_PRINT_ENABLE) {
1097 /* valid_frame = get_valid_frame(); */
1098 pr_info("dirty_frame_num is %d , valid frame is %d\n",
1099 dirty_frame_num, valid_frame);
1100
1101 }
1102 /* goto RESTART; */
1103 }
1104
1105 while ((putting_ptr != put_ptr) && (READ_VREG(BUFFER_RECYCLE) == 0)) {
1106 int view0_buf_id = vfpool_idx[put_ptr].view0_buf_id;
1107 int view1_buf_id = vfpool_idx[put_ptr].view1_buf_id;
1108
1109 if ((view0_buf_id >= 0) &&
1110 (view0_vfbuf_use[view0_buf_id] == 1)) {
1111 if (dbg_mode & 0x100) {
1112 pr_info
1113 ("round 0: put_ptr is %d ;view0_buf_id is %d\n",
1114 put_ptr, view0_buf_id);
1115 }
1116 WRITE_VREG(BUFFER_RECYCLE,
1117 (0 << 8) | (view0_buf_id + 1));
1118 view0_vfbuf_use[view0_buf_id] = 0;
1119 vfpool_idx[put_ptr].view0_buf_id = -1;
1120 vfpool_idx[put_ptr].view0_drop = 0;
1121 } else if ((view1_buf_id >= 0)
1122 && (view1_vfbuf_use[view1_buf_id] == 1)) {
1123 if (dbg_mode & 0x100) {
1124 pr_info
1125 ("round 1: put_ptr is %d ;view1_buf_id %d==\n",
1126 put_ptr, view1_buf_id);
1127 }
1128 WRITE_VREG(BUFFER_RECYCLE,
1129 (1 << 8) | (view1_buf_id + 1));
1130 view1_vfbuf_use[view1_buf_id] = 0;
1131 vfpool_idx[put_ptr].display_pos = DISPLAY_INVALID_POS;
1132 vfpool_idx[put_ptr].view1_buf_id = -1;
1133 vfpool_idx[put_ptr].view1_drop = 0;
1134 vfpool_idx[put_ptr].used = 0;
1135 INCPTR(put_ptr);
1136 }
1137 }
1138
1139 schedule_work(&set_clk_work);
1140
1141 /* RESTART: */
1142 timer->expires = jiffies + PUT_INTERVAL;
1143
1144 add_timer(timer);
1145}
1146
1147int vh264mvc_dec_status(struct vdec_s *vdec, struct vdec_info *vstatus)
1148{
1149 vstatus->frame_width = frame_width;
1150 vstatus->frame_height = frame_height;
1151 if (frame_dur != 0)
1152 vstatus->frame_rate = 96000 / frame_dur;
1153 else
1154 vstatus->frame_rate = -1;
1155 vstatus->error_count = READ_VREG(AV_SCRATCH_D);
1156 vstatus->status = stat;
1157 vstatus->bit_rate = gvs->bit_rate;
1158 vstatus->frame_dur = frame_dur;
1159 vstatus->frame_data = gvs->frame_data;
1160 vstatus->total_data = gvs->total_data;
1161 vstatus->frame_count = gvs->frame_count;
1162 vstatus->error_frame_count = gvs->error_frame_count;
1163 vstatus->drop_frame_count = gvs->drop_frame_count;
1164 vstatus->total_data = gvs->total_data;
1165 vstatus->samp_cnt = gvs->samp_cnt;
1166 vstatus->offset = gvs->offset;
1167 snprintf(vstatus->vdec_name, sizeof(vstatus->vdec_name),
1168 "%s", DRIVER_NAME);
1169
1170 return 0;
1171}
1172
1173static int vh264mvc_vdec_info_init(void)
1174{
1175 gvs = kzalloc(sizeof(struct vdec_info), GFP_KERNEL);
1176 if (NULL == gvs) {
1177 pr_info("the struct of vdec status malloc failed.\n");
1178 return -ENOMEM;
1179 }
1180 return 0;
1181}
1182
1183int vh264mvc_set_trickmode(struct vdec_s *vdec, unsigned long trickmode)
1184{
1185 if (trickmode == TRICKMODE_I) {
1186 WRITE_VREG(AV_SCRATCH_F,
1187 (READ_VREG(AV_SCRATCH_F) & 0xfffffffc) | 2);
1188 trickmode_i = 1;
1189 } else if (trickmode == TRICKMODE_NONE) {
1190 WRITE_VREG(AV_SCRATCH_F, READ_VREG(AV_SCRATCH_F) & 0xfffffffc);
1191 trickmode_i = 0;
1192 }
1193
1194 return 0;
1195}
1196
1197static void H264_DECODE_INIT(void)
1198{
1199 int i;
1200
1201 i = READ_VREG(DECODE_SKIP_PICTURE);
1202
1203#if 1 /* /MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
1204 WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
1205 WRITE_VREG(DOS_SW_RESET0, 0);
1206
1207 READ_VREG(DOS_SW_RESET0);
1208 READ_VREG(DOS_SW_RESET0);
1209 READ_VREG(DOS_SW_RESET0);
1210
1211 WRITE_VREG(DOS_SW_RESET0, (1 << 7) | (1 << 6) | (1 << 4));
1212 WRITE_VREG(DOS_SW_RESET0, 0);
1213
1214 WRITE_VREG(DOS_SW_RESET0, (1 << 9) | (1 << 8));
1215 WRITE_VREG(DOS_SW_RESET0, 0);
1216
1217 READ_VREG(DOS_SW_RESET0);
1218 READ_VREG(DOS_SW_RESET0);
1219 READ_VREG(DOS_SW_RESET0);
1220
1221#else
1222 WRITE_RESET_REG(RESET0_REGISTER,
1223 RESET_IQIDCT | RESET_MC | RESET_VLD_PART);
1224 READ_RESET_REG(RESET0_REGISTER);
1225 WRITE_RESET_REG(RESET0_REGISTER,
1226 RESET_IQIDCT | RESET_MC | RESET_VLD_PART);
1227 WRITE_RESET_REG(RESET2_REGISTER, RESET_PIC_DC | RESET_DBLK);
1228#endif
1229
1230 /* Wait for some time for RESET */
1231 READ_VREG(DECODE_SKIP_PICTURE);
1232 READ_VREG(DECODE_SKIP_PICTURE);
1233
1234 WRITE_VREG(DECODE_SKIP_PICTURE, i);
1235
1236 /* fill_weight_pred */
1237 WRITE_VREG(MC_MPORT_CTRL, 0x0300);
1238 for (i = 0; i < 192; i++)
1239 WRITE_VREG(MC_MPORT_DAT, 0x100);
1240 WRITE_VREG(MC_MPORT_CTRL, 0);
1241
1242 WRITE_VREG(MB_WIDTH, 0xff); /* invalid mb_width */
1243
1244 /* set slice start to 0x000000 or 0x000001 for check more_rbsp_data */
1245 WRITE_VREG(SLICE_START_BYTE_01, 0x00000000);
1246 WRITE_VREG(SLICE_START_BYTE_23, 0x01010000);
1247 /* set to mpeg2 to enable mismatch logic */
1248 WRITE_VREG(MPEG1_2_REG, 1);
1249 /* disable COEF_GT_64 , error_m4_table and voff_rw_err */
1250 WRITE_VREG(VLD_ERROR_MASK, 0x1011);
1251
1252 /* Config MCPU Amrisc interrupt */
1253 WRITE_VREG(ASSIST_AMR1_INT0, 0x1); /* viu_vsync_int */
1254 WRITE_VREG(ASSIST_AMR1_INT1, 0x5); /* mbox_isr */
1255 WRITE_VREG(ASSIST_AMR1_INT2, 0x8); /* vld_isr */
1256 WRITE_VREG(ASSIST_AMR1_INT3, 0x15); /* vififo_empty */
1257 WRITE_VREG(ASSIST_AMR1_INT4, 0xd); /* rv_ai_mb_finished_int */
1258 WRITE_VREG(ASSIST_AMR1_INT7, 0x14); /* dcac_dma_done */
1259
1260 /* Config MCPU Amrisc interrupt */
1261 WRITE_VREG(ASSIST_AMR1_INT5, 0x9); /* MCPU interrupt */
1262 WRITE_VREG(ASSIST_AMR1_INT6, 0x17); /* CCPU interrupt */
1263
1264 WRITE_VREG(CPC_P, 0xc00); /* CCPU Code will start from 0xc00 */
1265 WRITE_VREG(CINT_VEC_BASE, (0xc20 >> 5));
1266#if 0
1267 WRITE_VREG(POWER_CTL_VLD,
1268 READ_VREG(POWER_CTL_VLD) | (0 << 10) |
1269 (1 << 9) | (1 << 6));
1270#else
1271 WRITE_VREG(POWER_CTL_VLD, ((1 << 10) | /* disable cabac_step_2 */
1272 (1 << 9) | /* viff_drop_flag_en */
1273 (1 << 6) /* h264_000003_en */
1274 )
1275 );
1276#endif
1277 WRITE_VREG(M4_CONTROL_REG, (1 << 13)); /* H264_DECODE_INFO - h264_en */
1278
1279 WRITE_VREG(CANVAS_START, CANVAS_INDEX_START);
1280#if 1
1281 /* Start Address of Workspace (UCODE, temp_data...) */
1282 WRITE_VREG(WORKSPACE_START,
1283 video_domain_addr(work_space_adr));
1284#else
1285 /* Start Address of Workspace (UCODE, temp_data...) */
1286 WRITE_VREG(WORKSPACE_START,
1287 0x05000000);
1288#endif
1289 /* Clear all sequence parameter set available */
1290 WRITE_VREG(SPS_STATUS, 0);
1291 /* Clear all picture parameter set available */
1292 WRITE_VREG(PPS_STATUS, 0);
1293 /* Set current microcode to NULL */
1294 WRITE_VREG(CURRENT_UCODE, 0xff);
1295 /* Set current SPS/PPS to NULL */
1296 WRITE_VREG(CURRENT_SPS_PPS, 0xffff);
1297 /* Set decode status to DECODE_START_HEADER */
1298 WRITE_VREG(DECODE_STATUS, 1);
1299}
1300
1301static void vh264mvc_prot_init(void)
1302{
1303 while (READ_VREG(DCAC_DMA_CTRL) & 0x8000)
1304 ;
1305 while (READ_VREG(LMEM_DMA_CTRL) & 0x8000)
1306 ; /* reg address is 0x350 */
1307 /* clear mailbox interrupt */
1308 WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);
1309
1310 /* enable mailbox interrupt */
1311 WRITE_VREG(ASSIST_MBOX1_MASK, 1);
1312
1313 /* disable PSCALE for hardware sharing */
1314 WRITE_VREG(PSCALE_CTRL, 0);
1315
1316 H264_DECODE_INIT();
1317
1318#if 1 /* /MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
1319 WRITE_VREG(DOS_SW_RESET0, (1 << 11));
1320 WRITE_VREG(DOS_SW_RESET0, 0);
1321
1322 READ_VREG(DOS_SW_RESET0);
1323 READ_VREG(DOS_SW_RESET0);
1324 READ_VREG(DOS_SW_RESET0);
1325
1326#else
1327 WRITE_RESET_REG(RESET0_REGISTER, 0x80); /* RESET MCPU */
1328#endif
1329
1330 WRITE_VREG(MAILBOX_COMMAND, 0);
1331 WRITE_VREG(BUFFER_RECYCLE, 0);
1332 WRITE_VREG(DROP_CONTROL, 0);
1333 CLEAR_VREG_MASK(MDEC_PIC_DC_CTRL, 1 << 17);
1334#if 1 /* /MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
1335 WRITE_VREG(MDEC_PIC_DC_THRESH, 0x404038aa);
1336#endif
1337}
1338
1339static int vh264mvc_local_init(void)
1340{
1341 int i, size, ret;
1342 display_buff_id = -1;
1343 display_view_id = -1;
1344 display_POC = -1;
1345 no_dropping_cnt = 0;
1346 init_drop_cnt = INIT_DROP_FRAME_CNT;
1347
1348 for (i = 0; i < INIT_DROP_FRAME_CNT; i++)
1349 init_drop_frame_id[i] = 0;
1350
1351#ifdef DEBUG_PTS
1352 pts_missed = 0;
1353 pts_hit = 0;
1354#endif
1355
1356#ifdef DEBUG_SKIP
1357 view_total = 0;
1358 view_dropped = 0;
1359#endif
1360
1361 /* vh264mvc_ratio = vh264mvc_amstream_dec_info.ratio; */
1362 vh264mvc_ratio = 0x100;
1363
1364 /* frame_width = vh264mvc_amstream_dec_info.width; */
1365 /* frame_height = vh264mvc_amstream_dec_info.height; */
1366 frame_dur = vh264mvc_amstream_dec_info.rate;
1367 if (frame_dur == 0)
1368 frame_dur = 96000 / 24;
1369
1370 pts_outside = ((unsigned long) vh264mvc_amstream_dec_info.param) & 0x01;
1371 sync_outside = ((unsigned long) vh264mvc_amstream_dec_info.param & 0x02)
1372 >> 1;
1373 INIT_WORK(&alloc_work, do_alloc_work);
1374
1375 max_dec_frame_buffering[0] = -1;
1376 max_dec_frame_buffering[1] = -1;
1377 fill_ptr = get_ptr = put_ptr = putting_ptr = 0;
1378 dirty_frame_num = 0;
1379
1380 for (i = 0; i < DECODE_BUFFER_NUM_MAX; i++) {
1381 view0_vfbuf_use[i] = 0;
1382 view1_vfbuf_use[i] = 0;
1383 }
1384
1385 for (i = 0; i < VF_POOL_SIZE; i++) {
1386 vfpool_idx[i].display_pos = -1;
1387 vfpool_idx[i].view0_buf_id = DISPLAY_INVALID_POS;
1388 vfpool_idx[i].view1_buf_id = -1;
1389 vfpool_idx[i].view0_drop = 0;
1390 vfpool_idx[i].view1_drop = 0;
1391 vfpool_idx[i].used = 0;
1392 }
1393 for (i = 0; i < VF_POOL_SIZE; i++) {
1394 memset(&vfpool[i], 0, sizeof(struct vframe_s));
1395 vfpool[i].index = i;
1396 }
1397 init_vf_buf();
1398
1399 if (mm_blk_handle) {
1400 decoder_bmmu_box_free(mm_blk_handle);
1401 mm_blk_handle = NULL;
1402 }
1403
1404 mm_blk_handle = decoder_bmmu_box_alloc_box(
1405 DRIVER_NAME,
1406 0,
1407 TOTAL_BMMU_BUFF_NUM,
1408 4 + PAGE_SHIFT,
1409 CODEC_MM_FLAGS_CMA_CLEAR |
1410 CODEC_MM_FLAGS_FOR_VDECODER);
1411
1412 size = DECODER_WORK_SPACE_SIZE;
1413 ret = decoder_bmmu_box_alloc_buf_phy(mm_blk_handle, 0,
1414 size, DRIVER_NAME, &work_space_adr);
1415
1416 return ret;
1417}
1418
1419static s32 vh264mvc_init(void)
1420{
1421 int ret = -1;
1422 char *buf = vmalloc(0x1000 * 16);
1423 if (buf == NULL)
1424 return -ENOMEM;
1425
1426 pr_info("\nvh264mvc_init\n");
1427 init_timer(&recycle_timer);
1428
1429 stat |= STAT_TIMER_INIT;
1430
1431 ret = vh264mvc_vdec_info_init();
1432 if (0 != ret) {
1433 vfree(buf);
1434 return -ret;
1435 }
1436
1437 ret = vh264mvc_local_init();
1438 if (ret < 0) {
1439 vfree(buf);
1440 return ret;
1441 }
1442
1443 amvdec_enable();
1444
1445 if (tee_enabled()) {
1446 ret = amvdec_loadmc_ex(VFORMAT_H264MVC, NULL, buf);
1447 if (ret != 0) {
1448 amvdec_disable();
1449 vfree(buf);
1450 pr_err("H264_MVC: the %s fw loading failed, err: %x\n",
1451 tee_enabled() ? "TEE" : "local", ret);
1452 return -1;
1453 }
1454 } else {
1455 /* -- ucode loading (amrisc and swap code) */
1456 mc_cpu_addr = dma_alloc_coherent(amports_get_dma_device(),
1457 MC_TOTAL_SIZE, &mc_dma_handle, GFP_KERNEL);
1458 if (!mc_cpu_addr) {
1459 amvdec_disable();
1460 vfree(buf);
1461 pr_err("vh264_mvc init: Can not allocate mc memory.\n");
1462 return -ENOMEM;
1463 }
1464
1465 WRITE_VREG(UCODE_START_ADDR, mc_dma_handle);
1466
1467 if (get_firmware_data(VIDEO_DEC_H264_MVC, buf) < 0) {
1468 pr_err("get firmware fail.");
1469 vfree(buf);
1470 return -1;
1471 }
1472
1473 ret = amvdec_loadmc_ex(VFORMAT_H264MVC, NULL, buf);
1474
1475 /*header*/
1476 memcpy((u8 *) mc_cpu_addr, buf + 0x1000, 0x1000);
1477 /*mmco*/
1478 memcpy((u8 *) mc_cpu_addr + 0x1000, buf + 0x2000, 0x2000);
1479 /*slice*/
1480 memcpy((u8 *) mc_cpu_addr + 0x3000, buf + 0x4000, 0x3000);
1481
1482 if (ret < 0) {
1483 amvdec_disable();
1484
1485 dma_free_coherent(amports_get_dma_device(),
1486 MC_TOTAL_SIZE,
1487 mc_cpu_addr, mc_dma_handle);
1488 mc_cpu_addr = NULL;
1489 return -EBUSY;
1490 }
1491 }
1492 vfree(buf);
1493
1494 stat |= STAT_MC_LOAD;
1495
1496 /* enable AMRISC side protocol */
1497 vh264mvc_prot_init();
1498
1499#ifdef HANDLE_h264mvc_IRQ
1500 if (vdec_request_irq(VDEC_IRQ_1, vh264mvc_isr,
1501 "vh264mvc-irq", (void *)vh264mvc_dec_id)) {
1502 pr_info("vh264mvc irq register error.\n");
1503 amvdec_disable();
1504 return -ENOENT;
1505 }
1506#endif
1507
1508 stat |= STAT_ISR_REG;
1509
1510 vf_provider_init(&vh264mvc_vf_prov, PROVIDER_NAME,
1511 &vh264mvc_vf_provider, NULL);
1512 vf_reg_provider(&vh264mvc_vf_prov);
1513 vf_notify_receiver(PROVIDER_NAME, VFRAME_EVENT_PROVIDER_START, NULL);
1514
1515 stat |= STAT_VF_HOOK;
1516
1517 recycle_timer.data = (ulong) (&recycle_timer);
1518 recycle_timer.function = vh264mvc_put_timer_func;
1519 recycle_timer.expires = jiffies + PUT_INTERVAL;
1520
1521 add_timer(&recycle_timer);
1522
1523 stat |= STAT_TIMER_ARM;
1524
1525 amvdec_start();
1526
1527 stat |= STAT_VDEC_RUN;
1528
1529 return 0;
1530}
1531
1532static int vh264mvc_stop(void)
1533{
1534 if (stat & STAT_VDEC_RUN) {
1535 amvdec_stop();
1536 stat &= ~STAT_VDEC_RUN;
1537 }
1538
1539 if (stat & STAT_ISR_REG) {
1540 WRITE_VREG(ASSIST_MBOX1_MASK, 0);
1541#ifdef HANDLE_h264mvc_IRQ
1542 vdec_free_irq(VDEC_IRQ_1, (void *)vh264mvc_dec_id);
1543#endif
1544 stat &= ~STAT_ISR_REG;
1545 }
1546
1547 if (stat & STAT_TIMER_ARM) {
1548 del_timer_sync(&recycle_timer);
1549 stat &= ~STAT_TIMER_ARM;
1550 }
1551
1552 if (stat & STAT_VF_HOOK) {
1553 ulong flags;
1554
1555 spin_lock_irqsave(&lock, flags);
1556 spin_unlock_irqrestore(&lock, flags);
1557 vf_unreg_provider(&vh264mvc_vf_prov);
1558 stat &= ~STAT_VF_HOOK;
1559 }
1560
1561 if (stat & STAT_MC_LOAD) {
1562 if (mc_cpu_addr != NULL) {
1563 dma_free_coherent(amports_get_dma_device(),
1564 MC_TOTAL_SIZE, mc_cpu_addr, mc_dma_handle);
1565 mc_cpu_addr = NULL;
1566 }
1567
1568 stat &= ~STAT_MC_LOAD;
1569 }
1570
1571 amvdec_disable();
1572
1573 if (mm_blk_handle) {
1574 decoder_bmmu_box_free(mm_blk_handle);
1575 mm_blk_handle = NULL;
1576 }
1577 uninit_vf_buf();
1578 return 0;
1579}
1580
1581static void error_do_work(struct work_struct *work)
1582{
1583 if (atomic_read(&vh264mvc_active)) {
1584 vh264mvc_stop();
1585 vh264mvc_init();
1586 }
1587}
1588
1589static int amvdec_h264mvc_probe(struct platform_device *pdev)
1590{
1591 struct vdec_s *pdata = *(struct vdec_s **)pdev->dev.platform_data;
1592 int config_val = 0;
1593
1594 pr_info("amvdec_h264mvc probe start.\n");
1595 mutex_lock(&vh264_mvc_mutex);
1596
1597#if 0
1598 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1599 if (!mem) {
1600 pr_info("\namvdec_h264mvc memory resource undefined.\n");
1601 return -EFAULT;
1602 }
1603#endif
1604
1605 if (pdata == NULL) {
1606 mutex_unlock(&vh264_mvc_mutex);
1607 pr_info("\namvdec_h264mvc memory resource undefined.\n");
1608 return -EFAULT;
1609 }
1610
1611 if (pdata->sys_info)
1612 vh264mvc_amstream_dec_info = *pdata->sys_info;
1613
1614 if (pdata->config_len) {
1615 pr_info("pdata->config: %s\n", pdata->config);
1616 if (get_config_int(pdata->config, "parm_v4l_buffer_margin",
1617 &config_val) == 0)
1618 dynamic_buf_num_margin = config_val;
1619 }
1620
1621 pdata->dec_status = vh264mvc_dec_status;
1622 /* pdata->set_trickmode = vh264mvc_set_trickmode; */
1623
1624 buffer_spec0 = (struct buffer_spec_s *)vzalloc(
1625 sizeof(struct buffer_spec_s) * MAX_BMMU_BUFFER_NUM * 2);
1626 if (NULL == buffer_spec0)
1627 return -ENOMEM;
1628 buffer_spec1 = &buffer_spec0[MAX_BMMU_BUFFER_NUM];
1629
1630 if (vh264mvc_init() < 0) {
1631 pr_info("\namvdec_h264mvc init failed.\n");
1632 kfree(gvs);
1633 gvs = NULL;
1634 vfree(buffer_spec0);
1635 buffer_spec0 = NULL;
1636 mutex_unlock(&vh264_mvc_mutex);
1637 return -ENODEV;
1638 }
1639
1640 INIT_WORK(&error_wd_work, error_do_work);
1641 INIT_WORK(&set_clk_work, vh264_mvc_set_clk);
1642
1643 atomic_set(&vh264mvc_active, 1);
1644
1645 mutex_unlock(&vh264_mvc_mutex);
1646
1647 pr_info("amvdec_h264mvc probe end.\n");
1648
1649 return 0;
1650}
1651
1652static int amvdec_h264mvc_remove(struct platform_device *pdev)
1653{
1654 pr_info("amvdec_h264mvc_remove\n");
1655 cancel_work_sync(&alloc_work);
1656 cancel_work_sync(&error_wd_work);
1657 cancel_work_sync(&set_clk_work);
1658 vh264mvc_stop();
1659 frame_width = 0;
1660 frame_height = 0;
1661 vdec_source_changed(VFORMAT_H264MVC, 0, 0, 0);
1662 atomic_set(&vh264mvc_active, 0);
1663
1664#ifdef DEBUG_PTS
1665 pr_info
1666 ("pts missed %ld, pts hit %ld, pts_outside %d, ",
1667 pts_missed, pts_hit, pts_outside);
1668 pr_info("duration %d, sync_outside %d\n",
1669 frame_dur, sync_outside);
1670#endif
1671
1672#ifdef DEBUG_SKIP
1673 pr_info("view_total = %ld, dropped %ld\n", view_total, view_dropped);
1674#endif
1675 vfree(buffer_spec0);
1676 buffer_spec0 = NULL;
1677 kfree(gvs);
1678 gvs = NULL;
1679
1680 return 0;
1681}
1682
1683/****************************************/
1684#ifdef CONFIG_PM
1685static int h264mvc_suspend(struct device *dev)
1686{
1687 amvdec_suspend(to_platform_device(dev), dev->power.power_state);
1688 return 0;
1689}
1690
1691static int h264mvc_resume(struct device *dev)
1692{
1693 amvdec_resume(to_platform_device(dev));
1694 return 0;
1695}
1696
1697static const struct dev_pm_ops h264mvc_pm_ops = {
1698 SET_SYSTEM_SLEEP_PM_OPS(h264mvc_suspend, h264mvc_resume)
1699};
1700#endif
1701
1702static struct platform_driver amvdec_h264mvc_driver = {
1703 .probe = amvdec_h264mvc_probe,
1704 .remove = amvdec_h264mvc_remove,
1705 .driver = {
1706 .name = DRIVER_NAME,
1707#ifdef CONFIG_PM
1708 .pm = &h264mvc_pm_ops,
1709#endif
1710 }
1711};
1712
1713static struct codec_profile_t amvdec_hmvc_profile = {
1714 .name = "hmvc",
1715 .profile = ""
1716};
1717static struct codec_profile_t amvdec_hmvc_profile_single;
1718
1719static struct mconfig h264mvc_configs[] = {
1720 MC_PU32("stat", &stat),
1721 MC_PU32("dbg_mode", &dbg_mode),
1722 MC_PU32("view_mode", &view_mode),
1723 MC_PU32("dbg_cmd", &dbg_cmd),
1724 MC_PU32("drop_rate", &drop_rate),
1725 MC_PU32("drop_thread_hold", &drop_thread_hold),
1726};
1727static struct mconfig_node h264mvc_node;
1728
1729static int __init amvdec_h264mvc_driver_init_module(void)
1730{
1731 pr_debug("amvdec_h264mvc module init\n");
1732
1733 if (platform_driver_register(&amvdec_h264mvc_driver)) {
1734 pr_err("failed to register amvdec_h264mvc driver\n");
1735 return -ENODEV;
1736 }
1737
1738 vcodec_profile_register(&amvdec_hmvc_profile);
1739 amvdec_hmvc_profile_single = amvdec_hmvc_profile;
1740 amvdec_hmvc_profile_single.name = "h264mvc";
1741 vcodec_profile_register(&amvdec_hmvc_profile_single);
1742 INIT_REG_NODE_CONFIGS("media.decoder", &h264mvc_node,
1743 "h264mvc", h264mvc_configs, CONFIG_FOR_RW);
1744 return 0;
1745}
1746
1747static void __exit amvdec_h264mvc_driver_remove_module(void)
1748{
1749 pr_debug("amvdec_h264mvc module remove.\n");
1750
1751 platform_driver_unregister(&amvdec_h264mvc_driver);
1752}
1753
1754/****************************************/
1755
1756module_param(stat, uint, 0664);
1757MODULE_PARM_DESC(stat, "\n amvdec_h264mvc stat\n");
1758
1759module_param(dbg_mode, uint, 0664);
1760MODULE_PARM_DESC(dbg_mode, "\n amvdec_h264mvc dbg mode\n");
1761
1762module_param(dynamic_buf_num_margin, uint, 0664);
1763MODULE_PARM_DESC(dynamic_buf_num_margin, "\n amvdec_h264mvc dynamic_buf_num_margin\n");
1764
1765module_param(view_mode, uint, 0664);
1766MODULE_PARM_DESC(view_mode, "\n amvdec_h264mvc view mode\n");
1767
1768module_param(dbg_cmd, uint, 0664);
1769MODULE_PARM_DESC(dbg_cmd, "\n amvdec_h264mvc cmd mode\n");
1770
1771module_param(drop_rate, uint, 0664);
1772MODULE_PARM_DESC(drop_rate, "\n amvdec_h264mvc drop rate\n");
1773
1774module_param(drop_thread_hold, uint, 0664);
1775MODULE_PARM_DESC(drop_thread_hold, "\n amvdec_h264mvc drop thread hold\n");
1776module_init(amvdec_h264mvc_driver_init_module);
1777module_exit(amvdec_h264mvc_driver_remove_module);
1778
1779MODULE_DESCRIPTION("AMLOGIC h264mvc Video Decoder Driver");
1780MODULE_LICENSE("GPL");
1781MODULE_AUTHOR("Chen Zhang <chen.zhang@amlogic.com>");
1782