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